Merge branch 'i2c/cht-wc-fusb302-immutable' into i2c/for-4.15
This commit is contained in:
Коммит
9b09342f5c
|
@ -14,3 +14,11 @@ Description:
|
|||
Show or set the gain boost of the amp, from 0-31 range.
|
||||
18 = indoors (default)
|
||||
14 = outdoors
|
||||
|
||||
What /sys/bus/iio/devices/iio:deviceX/noise_level_tripped
|
||||
Date: May 2017
|
||||
KernelVersion: 4.13
|
||||
Contact: Matt Ranostay <matt.ranostay@konsulko.com>
|
||||
Description:
|
||||
When 1 the noise level is over the trip level and not reporting
|
||||
valid data
|
||||
|
|
|
@ -352,44 +352,30 @@ Read-Copy Update (RCU)
|
|||
----------------------
|
||||
|
||||
.. kernel-doc:: include/linux/rcupdate.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/rcupdate_wait.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/rcutree.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/tree.c
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/tree_plugin.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/tree_exp.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/update.c
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/srcu.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/srcutree.c
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/rculist_bl.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/rculist.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/rculist_nulls.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: include/linux/rcu_sync.h
|
||||
:external:
|
||||
|
||||
.. kernel-doc:: kernel/rcu/sync.c
|
||||
:external:
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@ Optional properties:
|
|||
- ams,tuning-capacitor-pf: Calibration tuning capacitor stepping
|
||||
value 0 - 120pF. This will require using the calibration data from
|
||||
the manufacturer.
|
||||
- ams,nflwdth: Set the noise and watchdog threshold register on
|
||||
startup. This will need to set according to the noise from the
|
||||
MCU board, and possibly the local environment. Refer to the
|
||||
datasheet for the threshold settings.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -27,4 +31,5 @@ as3935@0 {
|
|||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <16 1>;
|
||||
ams,tuning-capacitor-pf = <80>;
|
||||
ams,nflwdth = <0x44>;
|
||||
};
|
||||
|
|
|
@ -99,7 +99,7 @@ Examples:
|
|||
compatible = "arm,gic-v3-its";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
reg = <0x0 0x2c200000 0 0x200000>;
|
||||
reg = <0x0 0x2c200000 0 0x20000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -124,14 +124,14 @@ Examples:
|
|||
compatible = "arm,gic-v3-its";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
reg = <0x0 0x2c200000 0 0x200000>;
|
||||
reg = <0x0 0x2c200000 0 0x20000>;
|
||||
};
|
||||
|
||||
gic-its@2c400000 {
|
||||
compatible = "arm,gic-v3-its";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
reg = <0x0 0x2c400000 0 0x200000>;
|
||||
reg = <0x0 0x2c400000 0 0x20000>;
|
||||
};
|
||||
|
||||
ppi-partitions {
|
||||
|
|
|
@ -25,6 +25,7 @@ Below are the essential guides that every developer should read.
|
|||
submitting-patches
|
||||
coding-style
|
||||
email-clients
|
||||
kernel-enforcement-statement
|
||||
|
||||
Other guides to the community that are of interest to most developers are:
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
Linux Kernel Enforcement Statement
|
||||
----------------------------------
|
||||
|
||||
As developers of the Linux kernel, we have a keen interest in how our software
|
||||
is used and how the license for our software is enforced. Compliance with the
|
||||
reciprocal sharing obligations of GPL-2.0 is critical to the long-term
|
||||
sustainability of our software and community.
|
||||
|
||||
Although there is a right to enforce the separate copyright interests in the
|
||||
contributions made to our community, we share an interest in ensuring that
|
||||
individual enforcement actions are conducted in a manner that benefits our
|
||||
community and do not have an unintended negative impact on the health and
|
||||
growth of our software ecosystem. In order to deter unhelpful enforcement
|
||||
actions, we agree that it is in the best interests of our development
|
||||
community to undertake the following commitment to users of the Linux kernel
|
||||
on behalf of ourselves and any successors to our copyright interests:
|
||||
|
||||
Notwithstanding the termination provisions of the GPL-2.0, we agree that
|
||||
it is in the best interests of our development community to adopt the
|
||||
following provisions of GPL-3.0 as additional permissions under our
|
||||
license with respect to any non-defensive assertion of rights under the
|
||||
license.
|
||||
|
||||
However, if you cease all violation of this License, then your license
|
||||
from a particular copyright holder is reinstated (a) provisionally,
|
||||
unless and until the copyright holder explicitly and finally
|
||||
terminates your license, and (b) permanently, if the copyright holder
|
||||
fails to notify you of the violation by some reasonable means prior to
|
||||
60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Our intent in providing these assurances is to encourage more use of the
|
||||
software. We want companies and individuals to use, modify and distribute
|
||||
this software. We want to work with users in an open and transparent way to
|
||||
eliminate any uncertainty about our expectations regarding compliance or
|
||||
enforcement that might limit adoption of our software. We view legal action
|
||||
as a last resort, to be initiated only when other community efforts have
|
||||
failed to resolve the problem.
|
||||
|
||||
Finally, once a non-compliance issue is resolved, we hope the user will feel
|
||||
welcome to join us in our efforts on this project. Working together, we will
|
||||
be stronger.
|
||||
|
||||
Except where noted below, we speak only for ourselves, and not for any company
|
||||
we might work for today, have in the past, or will in the future.
|
||||
|
||||
- Bjorn Andersson (Linaro)
|
||||
- Andrea Arcangeli (Red Hat)
|
||||
- Neil Armstrong
|
||||
- Jens Axboe
|
||||
- Pablo Neira Ayuso
|
||||
- Khalid Aziz
|
||||
- Ralf Baechle
|
||||
- Felipe Balbi
|
||||
- Arnd Bergmann
|
||||
- Ard Biesheuvel
|
||||
- Paolo Bonzini (Red Hat)
|
||||
- Christian Borntraeger
|
||||
- Mark Brown (Linaro)
|
||||
- Paul Burton
|
||||
- Javier Martinez Canillas
|
||||
- Rob Clark
|
||||
- Jonathan Corbet
|
||||
- Vivien Didelot (Savoir-faire Linux)
|
||||
- Hans de Goede (Red Hat)
|
||||
- Mel Gorman (SUSE)
|
||||
- Sven Eckelmann
|
||||
- Alex Elder (Linaro)
|
||||
- Fabio Estevam
|
||||
- Larry Finger
|
||||
- Bhumika Goyal
|
||||
- Andy Gross
|
||||
- Juergen Gross
|
||||
- Shawn Guo
|
||||
- Ulf Hansson
|
||||
- Tejun Heo
|
||||
- Rob Herring
|
||||
- Masami Hiramatsu
|
||||
- Michal Hocko
|
||||
- Simon Horman
|
||||
- Johan Hovold (Hovold Consulting AB)
|
||||
- Christophe JAILLET
|
||||
- Olof Johansson
|
||||
- Lee Jones (Linaro)
|
||||
- Heiner Kallweit
|
||||
- Srinivas Kandagatla
|
||||
- Jan Kara
|
||||
- Shuah Khan (Samsung)
|
||||
- David Kershner
|
||||
- Jaegeuk Kim
|
||||
- Namhyung Kim
|
||||
- Colin Ian King
|
||||
- Jeff Kirsher
|
||||
- Greg Kroah-Hartman (Linux Foundation)
|
||||
- Christian König
|
||||
- Vinod Koul
|
||||
- Krzysztof Kozlowski
|
||||
- Viresh Kumar
|
||||
- Aneesh Kumar K.V
|
||||
- Julia Lawall
|
||||
- Doug Ledford (Red Hat)
|
||||
- Chuck Lever (Oracle)
|
||||
- Daniel Lezcano
|
||||
- Shaohua Li
|
||||
- Xin Long (Red Hat)
|
||||
- Tony Luck
|
||||
- Mike Marshall
|
||||
- Chris Mason
|
||||
- Paul E. McKenney
|
||||
- David S. Miller
|
||||
- Ingo Molnar
|
||||
- Kuninori Morimoto
|
||||
- Borislav Petkov
|
||||
- Jiri Pirko
|
||||
- Josh Poimboeuf
|
||||
- Sebastian Reichel (Collabora)
|
||||
- Guenter Roeck
|
||||
- Joerg Roedel
|
||||
- Leon Romanovsky
|
||||
- Steven Rostedt (VMware)
|
||||
- Ivan Safonov
|
||||
- Ivan Safonov
|
||||
- Anna Schumaker
|
||||
- Jes Sorensen
|
||||
- K.Y. Srinivasan
|
||||
- Heiko Stuebner
|
||||
- Jiri Kosina (SUSE)
|
||||
- Dmitry Torokhov
|
||||
- Linus Torvalds
|
||||
- Thierry Reding
|
||||
- Rik van Riel
|
||||
- Geert Uytterhoeven (Glider bvba)
|
||||
- Daniel Vetter
|
||||
- Linus Walleij
|
||||
- Richard Weinberger
|
||||
- Dan Williams
|
||||
- Rafael J. Wysocki
|
||||
- Arvind Yadav
|
||||
- Masahiro Yamada
|
||||
- Wei Yongjun
|
||||
- Lv Zheng
|
|
@ -9213,7 +9213,6 @@ F: include/linux/isicom.h
|
|||
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
|
||||
M: Bin Liu <b-liu@ti.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
|
||||
S: Maintained
|
||||
F: drivers/usb/musb/
|
||||
|
||||
|
@ -10560,6 +10559,8 @@ M: Peter Zijlstra <peterz@infradead.org>
|
|||
M: Ingo Molnar <mingo@redhat.com>
|
||||
M: Arnaldo Carvalho de Melo <acme@kernel.org>
|
||||
R: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
R: Jiri Olsa <jolsa@redhat.com>
|
||||
R: Namhyung Kim <namhyung@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
|
||||
S: Supported
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Fearless Coyote
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -131,7 +131,7 @@ endif
|
|||
KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
|
||||
KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
|
||||
|
||||
CHECKFLAGS += -D__arm__
|
||||
CHECKFLAGS += -D__arm__ -m32
|
||||
|
||||
#Default value
|
||||
head-y := arch/arm/kernel/head$(MMUEXT).o
|
||||
|
|
|
@ -23,7 +23,11 @@ ENTRY(putc)
|
|||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
THUMB( bkpt #0xab )
|
||||
#else
|
||||
THUMB( svc #0xab )
|
||||
#endif
|
||||
mov pc, lr
|
||||
.align 2
|
||||
1: .word _GLOBAL_OFFSET_TABLE_ - .
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
};
|
||||
|
||||
i2c0: i2c@11000 {
|
||||
compatible = "marvell,mv64xxx-i2c";
|
||||
compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c";
|
||||
reg = <0x11000 0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -189,7 +189,7 @@
|
|||
};
|
||||
|
||||
i2c1: i2c@11100 {
|
||||
compatible = "marvell,mv64xxx-i2c";
|
||||
compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c";
|
||||
reg = <0x11100 0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
pinctrl-0 = <&pinctrl_macb0_default>;
|
||||
phy-mode = "rmii";
|
||||
|
||||
ethernet-phy@1 {
|
||||
reg = <0x1>;
|
||||
ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
interrupt-parent = <&pioA>;
|
||||
interrupts = <PIN_PD31 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
|
|
|
@ -309,7 +309,7 @@
|
|||
vddana-supply = <&vdd_3v3_lp_reg>;
|
||||
vref-supply = <&vdd_3v3_lp_reg>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_adc_default>;
|
||||
pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -340,6 +340,20 @@
|
|||
bias-disable;
|
||||
};
|
||||
|
||||
/*
|
||||
* The ADTRG pin can work on any edge type.
|
||||
* In here it's being pulled up, so need to
|
||||
* connect it to ground to get an edge e.g.
|
||||
* Trigger can be configured on falling, rise
|
||||
* or any edge, and the pull-up can be changed
|
||||
* to pull-down or left floating according to
|
||||
* needs.
|
||||
*/
|
||||
pinctrl_adtrg_default: adtrg_default {
|
||||
pinmux = <PIN_PD31__ADTRG>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
pinctrl_charger_chglev: charger_chglev {
|
||||
pinmux = <PIN_PA12__GPIO>;
|
||||
bias-disable;
|
||||
|
|
|
@ -18,12 +18,9 @@
|
|||
compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
|
||||
model = "Raspberry Pi Zero W";
|
||||
|
||||
/* Needed by firmware to properly init UARTs */
|
||||
aliases {
|
||||
uart0 = "/soc/serial@7e201000";
|
||||
uart1 = "/soc/serial@7e215040";
|
||||
serial0 = "/soc/serial@7e201000";
|
||||
serial1 = "/soc/serial@7e215040";
|
||||
chosen {
|
||||
/* 8250 auxiliary UART instead of pl011 */
|
||||
stdout-path = "serial1:115200n8";
|
||||
};
|
||||
|
||||
leds {
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
|
||||
model = "Raspberry Pi 3 Model B";
|
||||
|
||||
chosen {
|
||||
/* 8250 auxiliary UART instead of pl011 */
|
||||
stdout-path = "serial1:115200n8";
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = <0 0x40000000>;
|
||||
};
|
||||
|
|
|
@ -20,8 +20,13 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
serial1 = &uart1;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "earlyprintk console=ttyAMA0";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
|
|
|
@ -145,11 +145,12 @@
|
|||
};
|
||||
|
||||
watchdog@41000000 {
|
||||
compatible = "cortina,gemini-watchdog";
|
||||
compatible = "cortina,gemini-watchdog", "faraday,ftwdt010";
|
||||
reg = <0x41000000 0x1000>;
|
||||
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&syscon GEMINI_RESET_WDOG>;
|
||||
clocks = <&syscon GEMINI_CLK_APB>;
|
||||
clock-names = "PCLK";
|
||||
};
|
||||
|
||||
uart0: serial@42000000 {
|
||||
|
|
|
@ -144,10 +144,10 @@
|
|||
interrupt-names = "msi";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
|
||||
<&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
|
||||
<&clks IMX7D_PCIE_PHY_ROOT_CLK>;
|
||||
|
|
|
@ -87,9 +87,10 @@
|
|||
};
|
||||
|
||||
watchdog: watchdog@98500000 {
|
||||
compatible = "moxa,moxart-watchdog";
|
||||
compatible = "moxa,moxart-watchdog", "faraday,ftwdt010";
|
||||
reg = <0x98500000 0x10>;
|
||||
clocks = <&clk_apb>;
|
||||
clock-names = "PCLK";
|
||||
};
|
||||
|
||||
sdhci: sdhci@98e00000 {
|
||||
|
|
|
@ -1430,6 +1430,7 @@
|
|||
atmel,min-sample-rate-hz = <200000>;
|
||||
atmel,max-sample-rate-hz = <20000000>;
|
||||
atmel,startup-time-ms = <4>;
|
||||
atmel,trigger-edge-type = <IRQ_TYPE_EDGE_RISING>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -311,8 +311,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
tcon1_in_drc1: endpoint@0 {
|
||||
reg = <0>;
|
||||
tcon1_in_drc1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&drc1_out_tcon1>;
|
||||
};
|
||||
};
|
||||
|
@ -1012,8 +1012,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
be1_out_drc1: endpoint@0 {
|
||||
reg = <0>;
|
||||
be1_out_drc1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&drc1_in_be1>;
|
||||
};
|
||||
};
|
||||
|
@ -1042,8 +1042,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
drc1_in_be1: endpoint@0 {
|
||||
reg = <0>;
|
||||
drc1_in_be1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&be1_out_drc1>;
|
||||
};
|
||||
};
|
||||
|
@ -1053,8 +1053,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
drc1_out_tcon1: endpoint@0 {
|
||||
reg = <0>;
|
||||
drc1_out_tcon1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon1_in_drc1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -115,7 +115,11 @@ ENTRY(printascii)
|
|||
mov r1, r0
|
||||
mov r0, #0x04 @ SYS_WRITE0
|
||||
ARM( svc #0x123456 )
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
THUMB( bkpt #0xab )
|
||||
#else
|
||||
THUMB( svc #0xab )
|
||||
#endif
|
||||
ret lr
|
||||
ENDPROC(printascii)
|
||||
|
||||
|
@ -124,7 +128,11 @@ ENTRY(printch)
|
|||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
THUMB( bkpt #0xab )
|
||||
#else
|
||||
THUMB( svc #0xab )
|
||||
#endif
|
||||
ret lr
|
||||
ENDPROC(printch)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "db8500-regs.h"
|
||||
#include "pm_domains.h"
|
||||
|
||||
static int __init ux500_l2x0_unlock(void)
|
||||
{
|
||||
|
@ -157,6 +158,9 @@ static const struct of_device_id u8500_local_bus_nodes[] = {
|
|||
|
||||
static void __init u8500_init_machine(void)
|
||||
{
|
||||
/* Initialize ux500 power domains */
|
||||
ux500_pm_domains_init();
|
||||
|
||||
/* automatically probe child nodes of dbx5x0 devices */
|
||||
if (of_machine_is_compatible("st-ericsson,u8540"))
|
||||
of_platform_populate(NULL, u8500_local_bus_nodes,
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/of_address.h>
|
||||
|
||||
#include "db8500-regs.h"
|
||||
#include "pm_domains.h"
|
||||
|
||||
/* ARM WFI Standby signal register */
|
||||
#define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130)
|
||||
|
@ -203,7 +202,4 @@ void __init ux500_pm_init(u32 phy_base, u32 size)
|
|||
|
||||
/* Set up ux500 suspend callbacks. */
|
||||
suspend_set_ops(UX500_SUSPEND_OPS);
|
||||
|
||||
/* Initialize ux500 power domains */
|
||||
ux500_pm_domains_init();
|
||||
}
|
||||
|
|
|
@ -344,6 +344,11 @@ void __init arm_mm_memblock_reserve(void)
|
|||
* reserved here.
|
||||
*/
|
||||
#endif
|
||||
/*
|
||||
* In any case, always ensure address 0 is never used as many things
|
||||
* get very confused if 0 is returned as a legitimate address.
|
||||
*/
|
||||
memblock_reserve(0, 1);
|
||||
}
|
||||
|
||||
void __init adjust_lowmem_bounds(void)
|
||||
|
|
|
@ -61,13 +61,6 @@
|
|||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
reg_vcc3v3: vcc3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
|
@ -91,7 +84,7 @@
|
|||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
|
||||
cd-inverted;
|
||||
disable-wp;
|
||||
|
|
|
@ -336,7 +336,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cpm_clk 1 13>;
|
||||
|
@ -362,7 +362,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf7000000 0 0xf7000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
@ -389,7 +389,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf8000000 0 0xf8000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
|
|
@ -335,7 +335,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cps_clk 1 13>;
|
||||
|
@ -361,7 +361,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
@ -388,7 +388,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
brightness-levels = <256 128 64 16 8 4 0>;
|
||||
default-brightness-level = <6>;
|
||||
|
||||
power-supply = <®_12v>;
|
||||
enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
|
@ -83,6 +84,15 @@
|
|||
regulator-always-on;
|
||||
};
|
||||
|
||||
reg_12v: regulator2 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-12V";
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
rsnd_ak4613: sound {
|
||||
compatible = "simple-audio-card";
|
||||
|
||||
|
|
|
@ -582,7 +582,7 @@
|
|||
vop_mmu: iommu@ff373f00 {
|
||||
compatible = "rockchip,iommu";
|
||||
reg = <0x0 0xff373f00 0x0 0x100>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "vop_mmu";
|
||||
#iommu-cells = <0>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -740,7 +740,7 @@
|
|||
iep_mmu: iommu@ff900800 {
|
||||
compatible = "rockchip,iommu";
|
||||
reg = <0x0 0xff900800 0x0 0x100>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "iep_mmu";
|
||||
#iommu-cells = <0>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -371,10 +371,10 @@
|
|||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -325,12 +325,12 @@
|
|||
vcc_sd: LDO_REG4 {
|
||||
regulator-name = "vcc_sd";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -315,10 +315,10 @@
|
|||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ EXPORT_SYMBOL(memset);
|
|||
EXPORT_SYMBOL(__xchg8);
|
||||
EXPORT_SYMBOL(__xchg32);
|
||||
EXPORT_SYMBOL(__cmpxchg_u32);
|
||||
EXPORT_SYMBOL(__cmpxchg_u64);
|
||||
#ifdef CONFIG_SMP
|
||||
EXPORT_SYMBOL(__atomic_hash);
|
||||
#endif
|
||||
#ifdef CONFIG_64BIT
|
||||
EXPORT_SYMBOL(__xchg64);
|
||||
EXPORT_SYMBOL(__cmpxchg_u64);
|
||||
#endif
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
|
|
@ -742,7 +742,7 @@ lws_compare_and_swap_2:
|
|||
10: ldd 0(%r25), %r25
|
||||
11: ldd 0(%r24), %r24
|
||||
#else
|
||||
/* Load new value into r22/r23 - high/low */
|
||||
/* Load old value into r22/r23 - high/low */
|
||||
10: ldw 0(%r25), %r22
|
||||
11: ldw 4(%r25), %r23
|
||||
/* Load new value into fr4 for atomic store later */
|
||||
|
@ -834,11 +834,11 @@ cas2_action:
|
|||
copy %r0, %r28
|
||||
#else
|
||||
/* Compare first word */
|
||||
19: ldw,ma 0(%r26), %r29
|
||||
19: ldw 0(%r26), %r29
|
||||
sub,= %r29, %r22, %r0
|
||||
b,n cas2_end
|
||||
/* Compare second word */
|
||||
20: ldw,ma 4(%r26), %r29
|
||||
20: ldw 4(%r26), %r29
|
||||
sub,= %r29, %r23, %r0
|
||||
b,n cas2_end
|
||||
/* Perform the store */
|
||||
|
|
|
@ -253,7 +253,10 @@ static int __init init_cr16_clocksource(void)
|
|||
cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)
|
||||
if (cpu == 0)
|
||||
continue;
|
||||
if ((cpu0_loc != 0) &&
|
||||
(cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
|
||||
continue;
|
||||
|
||||
clocksource_cr16.name = "cr16_unstable";
|
||||
|
|
|
@ -27,6 +27,7 @@ CONFIG_NET=y
|
|||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
# CONFIG_BLK_DEV_XPRAM is not set
|
||||
# CONFIG_DCSSBLK is not set
|
||||
# CONFIG_DASD is not set
|
||||
|
@ -59,6 +60,7 @@ CONFIG_CONFIGFS_FS=y
|
|||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
|
|
|
@ -293,7 +293,10 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
|
|||
lc->lpp = LPP_MAGIC;
|
||||
lc->current_pid = tsk->pid;
|
||||
lc->user_timer = tsk->thread.user_timer;
|
||||
lc->guest_timer = tsk->thread.guest_timer;
|
||||
lc->system_timer = tsk->thread.system_timer;
|
||||
lc->hardirq_timer = tsk->thread.hardirq_timer;
|
||||
lc->softirq_timer = tsk->thread.softirq_timer;
|
||||
lc->steal_timer = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,10 @@ build_mmio_write(__writeq, "q", unsigned long, "r", )
|
|||
|
||||
#endif
|
||||
|
||||
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
|
||||
extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
|
||||
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
|
||||
|
||||
/**
|
||||
* virt_to_phys - map virtual addresses to physical
|
||||
* @address: address to remap
|
||||
|
|
|
@ -82,12 +82,21 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
|
|||
#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If tlb_use_lazy_mode is true, then we try to avoid switching CR3 to point
|
||||
* to init_mm when we switch to a kernel thread (e.g. the idle thread). If
|
||||
* it's false, then we immediately switch CR3 when entering a kernel thread.
|
||||
*/
|
||||
DECLARE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
|
||||
static inline bool tlb_defer_switch_to_init_mm(void)
|
||||
{
|
||||
/*
|
||||
* If we have PCID, then switching to init_mm is reasonably
|
||||
* fast. If we don't have PCID, then switching to init_mm is
|
||||
* quite slow, so we try to defer it in the hopes that we can
|
||||
* avoid it entirely. The latter approach runs the risk of
|
||||
* receiving otherwise unnecessary IPIs.
|
||||
*
|
||||
* This choice is just a heuristic. The tlb code can handle this
|
||||
* function returning true or false regardless of whether we have
|
||||
* PCID.
|
||||
*/
|
||||
return !static_cpu_has(X86_FEATURE_PCID);
|
||||
}
|
||||
|
||||
/*
|
||||
* 6 because 6 should be plenty and struct tlb_state will fit in
|
||||
|
|
|
@ -831,7 +831,6 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
|
|||
} else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
|
||||
unsigned int apicid, nshared, first, last;
|
||||
|
||||
this_leaf = this_cpu_ci->info_list + index;
|
||||
nshared = base->eax.split.num_threads_sharing + 1;
|
||||
apicid = cpu_data(cpu).apicid;
|
||||
first = apicid - (apicid % nshared);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/microcode_intel.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -918,6 +919,18 @@ static int get_ucode_fw(void *to, const void *from, size_t n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_blacklisted(unsigned int cpu)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) {
|
||||
pr_err_once("late loading on model 79 is disabled.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum ucode_state request_microcode_fw(int cpu, struct device *device,
|
||||
bool refresh_fw)
|
||||
{
|
||||
|
@ -926,6 +939,9 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device,
|
|||
const struct firmware *firmware;
|
||||
enum ucode_state ret;
|
||||
|
||||
if (is_blacklisted(cpu))
|
||||
return UCODE_NFOUND;
|
||||
|
||||
sprintf(name, "intel-ucode/%02x-%02x-%02x",
|
||||
c->x86, c->x86_model, c->x86_mask);
|
||||
|
||||
|
@ -950,6 +966,9 @@ static int get_ucode_user(void *to, const void *from, size_t n)
|
|||
static enum ucode_state
|
||||
request_microcode_user(int cpu, const void __user *buf, size_t size)
|
||||
{
|
||||
if (is_blacklisted(cpu))
|
||||
return UCODE_NFOUND;
|
||||
|
||||
return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,11 @@ static void __init i386_default_early_setup(void)
|
|||
|
||||
asmlinkage __visible void __init i386_start_kernel(void)
|
||||
{
|
||||
cr4_init_shadow();
|
||||
|
||||
/* Make sure IDT is set up before any exception happens */
|
||||
idt_setup_early_handler();
|
||||
|
||||
cr4_init_shadow();
|
||||
|
||||
sanitize_boot_params(&boot_params);
|
||||
|
||||
x86_early_init_platform_quirks();
|
||||
|
|
|
@ -174,3 +174,15 @@ const char *arch_vma_name(struct vm_area_struct *vma)
|
|||
return "[mpx]";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int valid_phys_addr_range(phys_addr_t addr, size_t count)
|
||||
{
|
||||
return addr + count <= __pa(high_memory);
|
||||
}
|
||||
|
||||
int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
|
||||
{
|
||||
phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT;
|
||||
|
||||
return valid_phys_addr_range(addr, count);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
|
||||
|
||||
DEFINE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
|
||||
|
||||
static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
|
||||
u16 *new_asid, bool *need_flush)
|
||||
|
@ -147,8 +146,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
|||
this_cpu_write(cpu_tlbstate.is_lazy, false);
|
||||
|
||||
if (real_prev == next) {
|
||||
VM_BUG_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
|
||||
next->context.ctx_id);
|
||||
VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
|
||||
next->context.ctx_id);
|
||||
|
||||
/*
|
||||
* We don't currently support having a real mm loaded without
|
||||
|
@ -213,6 +212,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
|||
}
|
||||
|
||||
/*
|
||||
* Please ignore the name of this function. It should be called
|
||||
* switch_to_kernel_thread().
|
||||
*
|
||||
* enter_lazy_tlb() is a hint from the scheduler that we are entering a
|
||||
* kernel thread or other context without an mm. Acceptable implementations
|
||||
* include doing nothing whatsoever, switching to init_mm, or various clever
|
||||
|
@ -227,7 +229,7 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
|||
if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
|
||||
return;
|
||||
|
||||
if (static_branch_unlikely(&tlb_use_lazy_mode)) {
|
||||
if (tlb_defer_switch_to_init_mm()) {
|
||||
/*
|
||||
* There's a significant optimization that may be possible
|
||||
* here. We have accurate enough TLB flush tracking that we
|
||||
|
@ -626,57 +628,3 @@ static int __init create_tlb_single_page_flush_ceiling(void)
|
|||
return 0;
|
||||
}
|
||||
late_initcall(create_tlb_single_page_flush_ceiling);
|
||||
|
||||
static ssize_t tlblazy_read_file(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
buf[0] = static_branch_likely(&tlb_use_lazy_mode) ? '1' : '0';
|
||||
buf[1] = '\n';
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
|
||||
}
|
||||
|
||||
static ssize_t tlblazy_write_file(struct file *file,
|
||||
const char __user *user_buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
bool val;
|
||||
|
||||
if (kstrtobool_from_user(user_buf, count, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
static_branch_enable(&tlb_use_lazy_mode);
|
||||
else
|
||||
static_branch_disable(&tlb_use_lazy_mode);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tlblazy = {
|
||||
.read = tlblazy_read_file,
|
||||
.write = tlblazy_write_file,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int __init init_tlb_use_lazy_mode(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_PCID)) {
|
||||
/*
|
||||
* Heuristic: with PCID on, switching to and from
|
||||
* init_mm is reasonably fast, but remote flush IPIs
|
||||
* as expensive as ever, so turn off lazy TLB mode.
|
||||
*
|
||||
* We can't do this in setup_pcid() because static keys
|
||||
* haven't been initialized yet, and it would blow up
|
||||
* badly.
|
||||
*/
|
||||
static_branch_disable(&tlb_use_lazy_mode);
|
||||
}
|
||||
|
||||
debugfs_create_file("tlb_use_lazy_mode", S_IRUSR | S_IWUSR,
|
||||
arch_debugfs_dir, NULL, &fops_tlblazy);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(init_tlb_use_lazy_mode);
|
||||
|
|
|
@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring,
|
|||
char *req, *p;
|
||||
int len;
|
||||
|
||||
BUG_ON(!id_0 && !id_1);
|
||||
|
||||
if (id_0) {
|
||||
lookup = id_0->data;
|
||||
len = id_0->len;
|
||||
|
@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring,
|
|||
if (id_0 && id_1) {
|
||||
const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
|
||||
|
||||
if (!kids->id[0]) {
|
||||
if (!kids->id[1]) {
|
||||
pr_debug("First ID matches, but second is missing\n");
|
||||
goto reject;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
|
|||
bool want = false;
|
||||
|
||||
sinfo = msg->signed_infos;
|
||||
if (!sinfo)
|
||||
goto inconsistent;
|
||||
|
||||
if (sinfo->authattrs) {
|
||||
want = true;
|
||||
msg->have_authattrs = true;
|
||||
|
|
|
@ -3662,12 +3662,6 @@ static void binder_stat_br(struct binder_proc *proc,
|
|||
}
|
||||
}
|
||||
|
||||
static int binder_has_thread_work(struct binder_thread *thread)
|
||||
{
|
||||
return !binder_worklist_empty(thread->proc, &thread->todo) ||
|
||||
thread->looper_need_return;
|
||||
}
|
||||
|
||||
static int binder_put_node_cmd(struct binder_proc *proc,
|
||||
struct binder_thread *thread,
|
||||
void __user **ptrp,
|
||||
|
@ -4297,12 +4291,9 @@ static unsigned int binder_poll(struct file *filp,
|
|||
|
||||
binder_inner_proc_unlock(thread->proc);
|
||||
|
||||
if (binder_has_work(thread, wait_for_proc_work))
|
||||
return POLLIN;
|
||||
|
||||
poll_wait(filp, &thread->wait, wait);
|
||||
|
||||
if (binder_has_thread_work(thread))
|
||||
if (binder_has_work(thread, wait_for_proc_work))
|
||||
return POLLIN;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
|
|||
}
|
||||
}
|
||||
|
||||
if (!vma && need_mm)
|
||||
mm = get_task_mm(alloc->tsk);
|
||||
if (!vma && need_mm && mmget_not_zero(alloc->vma_vm_mm))
|
||||
mm = alloc->vma_vm_mm;
|
||||
|
||||
if (mm) {
|
||||
down_write(&mm->mmap_sem);
|
||||
vma = alloc->vma;
|
||||
if (vma && mm != alloc->vma_vm_mm) {
|
||||
pr_err("%d: vma mm and task mm mismatch\n",
|
||||
alloc->pid);
|
||||
vma = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vma && need_mm) {
|
||||
|
@ -565,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc,
|
|||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
|
||||
"%d: merge free, buffer %pK do not share page with %pK or %pK\n",
|
||||
alloc->pid, buffer->data,
|
||||
prev->data, next->data);
|
||||
prev->data, next ? next->data : NULL);
|
||||
binder_update_page_range(alloc, 0, buffer_start_page(buffer),
|
||||
buffer_start_page(buffer) + PAGE_SIZE,
|
||||
NULL);
|
||||
|
@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
|
|||
barrier();
|
||||
alloc->vma = vma;
|
||||
alloc->vma_vm_mm = vma->vm_mm;
|
||||
mmgrab(alloc->vma_vm_mm);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
|
|||
vfree(alloc->buffer);
|
||||
}
|
||||
mutex_unlock(&alloc->mutex);
|
||||
if (alloc->vma_vm_mm)
|
||||
mmdrop(alloc->vma_vm_mm);
|
||||
|
||||
binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE,
|
||||
"%s: %d buffers %d, pages %d\n",
|
||||
|
@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
|
|||
void binder_alloc_vma_close(struct binder_alloc *alloc)
|
||||
{
|
||||
WRITE_ONCE(alloc->vma, NULL);
|
||||
WRITE_ONCE(alloc->vma_vm_mm, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
|||
page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
|
||||
vma = alloc->vma;
|
||||
if (vma) {
|
||||
mm = get_task_mm(alloc->tsk);
|
||||
if (!mm)
|
||||
goto err_get_task_mm_failed;
|
||||
if (!mmget_not_zero(alloc->vma_vm_mm))
|
||||
goto err_mmget;
|
||||
mm = alloc->vma_vm_mm;
|
||||
if (!down_write_trylock(&mm->mmap_sem))
|
||||
goto err_down_write_mmap_sem_failed;
|
||||
}
|
||||
|
@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
|||
|
||||
err_down_write_mmap_sem_failed:
|
||||
mmput_async(mm);
|
||||
err_get_task_mm_failed:
|
||||
err_mmget:
|
||||
err_page_already_freed:
|
||||
mutex_unlock(&alloc->mutex);
|
||||
err_get_alloc_mutex_failed:
|
||||
|
@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = {
|
|||
*/
|
||||
void binder_alloc_init(struct binder_alloc *alloc)
|
||||
{
|
||||
alloc->tsk = current->group_leader;
|
||||
alloc->pid = current->group_leader->pid;
|
||||
mutex_init(&alloc->mutex);
|
||||
INIT_LIST_HEAD(&alloc->buffers);
|
||||
|
|
|
@ -100,7 +100,6 @@ struct binder_lru_page {
|
|||
*/
|
||||
struct binder_alloc {
|
||||
struct mutex mutex;
|
||||
struct task_struct *tsk;
|
||||
struct vm_area_struct *vma;
|
||||
struct mm_struct *vma_vm_mm;
|
||||
void *buffer;
|
||||
|
|
|
@ -243,7 +243,6 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize,
|
|||
struct nbd_config *config = nbd->config;
|
||||
config->blksize = blocksize;
|
||||
config->bytesize = blocksize * nr_blocks;
|
||||
nbd_size_update(nbd);
|
||||
}
|
||||
|
||||
static void nbd_complete_rq(struct request *req)
|
||||
|
@ -1094,6 +1093,7 @@ static int nbd_start_device(struct nbd_device *nbd)
|
|||
args->index = i;
|
||||
queue_work(recv_workqueue, &args->work);
|
||||
}
|
||||
nbd_size_update(nbd);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -2604,7 +2604,7 @@ static void *skd_alloc_dma(struct skd_device *skdev, struct kmem_cache *s,
|
|||
return NULL;
|
||||
*dma_handle = dma_map_single(dev, buf, s->size, dir);
|
||||
if (dma_mapping_error(dev, *dma_handle)) {
|
||||
kfree(buf);
|
||||
kmem_cache_free(s, buf);
|
||||
buf = NULL;
|
||||
}
|
||||
return buf;
|
||||
|
|
|
@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
|
|||
if (mbus->hw_io_coherency)
|
||||
w->mbus_attr |= ATTR_HW_COHERENCY;
|
||||
w->base = base & DDR_BASE_CS_LOW_MASK;
|
||||
w->size = (size | ~DDR_SIZE_MASK) + 1;
|
||||
w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
|
||||
}
|
||||
}
|
||||
mvebu_mbus_dram_info.num_cs = cs;
|
||||
|
|
|
@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
|
|||
/* Turn off the clock (and clear the event) */
|
||||
disable_timer(cs5535_event_clock);
|
||||
|
||||
if (clockevent_state_shutdown(&cs5535_clockevent))
|
||||
if (clockevent_state_detached(&cs5535_clockevent) ||
|
||||
clockevent_state_shutdown(&cs5535_clockevent))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
/* Clear the counter */
|
||||
|
|
|
@ -344,7 +344,7 @@ msgdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,
|
|||
|
||||
spin_lock_irqsave(&mdev->lock, irqflags);
|
||||
if (desc_cnt > mdev->desc_free_cnt) {
|
||||
spin_unlock_bh(&mdev->lock);
|
||||
spin_unlock_irqrestore(&mdev->lock, irqflags);
|
||||
dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ msgdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
|
|||
|
||||
spin_lock_irqsave(&mdev->lock, irqflags);
|
||||
if (desc_cnt > mdev->desc_free_cnt) {
|
||||
spin_unlock_bh(&mdev->lock);
|
||||
spin_unlock_irqrestore(&mdev->lock, irqflags);
|
||||
dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -205,32 +205,17 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
|
|||
struct amd_sched_entity *entity)
|
||||
{
|
||||
struct amd_sched_rq *rq = entity->rq;
|
||||
int r;
|
||||
|
||||
if (!amd_sched_entity_is_initialized(sched, entity))
|
||||
return;
|
||||
|
||||
/**
|
||||
* The client will not queue more IBs during this fini, consume existing
|
||||
* queued IBs or discard them on SIGKILL
|
||||
* queued IBs
|
||||
*/
|
||||
if ((current->flags & PF_SIGNALED) && current->exit_code == SIGKILL)
|
||||
r = -ERESTARTSYS;
|
||||
else
|
||||
r = wait_event_killable(sched->job_scheduled,
|
||||
amd_sched_entity_is_idle(entity));
|
||||
wait_event(sched->job_scheduled, amd_sched_entity_is_idle(entity));
|
||||
|
||||
amd_sched_rq_remove_entity(rq, entity);
|
||||
if (r) {
|
||||
struct amd_sched_job *job;
|
||||
|
||||
/* Park the kernel for a moment to make sure it isn't processing
|
||||
* our enity.
|
||||
*/
|
||||
kthread_park(sched->thread);
|
||||
kthread_unpark(sched->thread);
|
||||
while (kfifo_out(&entity->job_queue, &job, sizeof(job)))
|
||||
sched->ops->free_job(job);
|
||||
|
||||
}
|
||||
kfifo_free(&entity->job_queue);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = {
|
|||
static int exynos_drm_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||
struct exynos_drm_private *private;
|
||||
|
||||
if (pm_runtime_suspended(dev) || !drm_dev)
|
||||
return 0;
|
||||
|
||||
private = drm_dev->dev_private;
|
||||
|
||||
drm_kms_helper_poll_disable(drm_dev);
|
||||
exynos_drm_fbdev_suspend(drm_dev);
|
||||
private->suspend_state = drm_atomic_helper_suspend(drm_dev);
|
||||
|
@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev)
|
|||
static int exynos_drm_resume(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||
struct exynos_drm_private *private;
|
||||
|
||||
if (pm_runtime_suspended(dev) || !drm_dev)
|
||||
return 0;
|
||||
|
||||
private = drm_dev->dev_private;
|
||||
drm_atomic_helper_resume(drm_dev, private->suspend_state);
|
||||
exynos_drm_fbdev_resume(drm_dev);
|
||||
drm_kms_helper_poll_enable(drm_dev);
|
||||
|
@ -427,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev)
|
|||
|
||||
kfree(drm->dev_private);
|
||||
drm->dev_private = NULL;
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
drm_dev_unref(drm);
|
||||
}
|
||||
|
|
|
@ -308,20 +308,8 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu)
|
|||
|
||||
static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler;
|
||||
int ring_id;
|
||||
|
||||
kfree(vgpu->sched_data);
|
||||
vgpu->sched_data = NULL;
|
||||
|
||||
spin_lock_bh(&scheduler->mmio_context_lock);
|
||||
for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
|
||||
if (scheduler->engine_owner[ring_id] == vgpu) {
|
||||
intel_gvt_switch_mmio(vgpu, NULL, ring_id);
|
||||
scheduler->engine_owner[ring_id] = NULL;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&scheduler->mmio_context_lock);
|
||||
}
|
||||
|
||||
static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
|
||||
|
@ -388,6 +376,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
|
|||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler =
|
||||
&vgpu->gvt->scheduler;
|
||||
int ring_id;
|
||||
|
||||
gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id);
|
||||
|
||||
|
@ -401,4 +390,13 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
|
|||
scheduler->need_reschedule = true;
|
||||
scheduler->current_vgpu = NULL;
|
||||
}
|
||||
|
||||
spin_lock_bh(&scheduler->mmio_context_lock);
|
||||
for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
|
||||
if (scheduler->engine_owner[ring_id] == vgpu) {
|
||||
intel_gvt_switch_mmio(vgpu, NULL, ring_id);
|
||||
scheduler->engine_owner[ring_id] = NULL;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&scheduler->mmio_context_lock);
|
||||
}
|
||||
|
|
|
@ -2657,6 +2657,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
|
|||
if (READ_ONCE(obj->mm.pages))
|
||||
return -ENODEV;
|
||||
|
||||
if (obj->mm.madv != I915_MADV_WILLNEED)
|
||||
return -EFAULT;
|
||||
|
||||
/* Before the pages are instantiated the object is treated as being
|
||||
* in the CPU domain. The pages will be clflushed as required before
|
||||
* use, and we can freely write into the pages directly. If userspace
|
||||
|
|
|
@ -33,21 +33,20 @@
|
|||
#include "intel_drv.h"
|
||||
#include "i915_trace.h"
|
||||
|
||||
static bool ggtt_is_idle(struct drm_i915_private *dev_priv)
|
||||
static bool ggtt_is_idle(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
|
||||
for_each_engine(engine, dev_priv, id) {
|
||||
struct intel_timeline *tl;
|
||||
if (i915->gt.active_requests)
|
||||
return false;
|
||||
|
||||
tl = &ggtt->base.timeline.engine[engine->id];
|
||||
if (i915_gem_active_isset(&tl->last_request))
|
||||
return false;
|
||||
}
|
||||
for_each_engine(engine, i915, id) {
|
||||
if (engine->last_retired_context != i915->kernel_context)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ggtt_flush(struct drm_i915_private *i915)
|
||||
|
@ -157,7 +156,8 @@ i915_gem_evict_something(struct i915_address_space *vm,
|
|||
min_size, alignment, cache_level,
|
||||
start, end, mode);
|
||||
|
||||
/* Retire before we search the active list. Although we have
|
||||
/*
|
||||
* Retire before we search the active list. Although we have
|
||||
* reasonable accuracy in our retirement lists, we may have
|
||||
* a stray pin (preventing eviction) that can only be resolved by
|
||||
* retiring.
|
||||
|
@ -182,7 +182,8 @@ search_again:
|
|||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
/* Can we unpin some objects such as idle hw contents,
|
||||
/*
|
||||
* Can we unpin some objects such as idle hw contents,
|
||||
* or pending flips? But since only the GGTT has global entries
|
||||
* such as scanouts, rinbuffers and contexts, we can skip the
|
||||
* purge when inspecting per-process local address spaces.
|
||||
|
@ -190,19 +191,33 @@ search_again:
|
|||
if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
|
||||
return -ENOSPC;
|
||||
|
||||
if (ggtt_is_idle(dev_priv)) {
|
||||
/* If we still have pending pageflip completions, drop
|
||||
* back to userspace to give our workqueues time to
|
||||
* acquire our locks and unpin the old scanouts.
|
||||
*/
|
||||
return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
|
||||
/*
|
||||
* Not everything in the GGTT is tracked via VMA using
|
||||
* i915_vma_move_to_active(), otherwise we could evict as required
|
||||
* with minimal stalling. Instead we are forced to idle the GPU and
|
||||
* explicitly retire outstanding requests which will then remove
|
||||
* the pinning for active objects such as contexts and ring,
|
||||
* enabling us to evict them on the next iteration.
|
||||
*
|
||||
* To ensure that all user contexts are evictable, we perform
|
||||
* a switch to the perma-pinned kernel context. This all also gives
|
||||
* us a termination condition, when the last retired context is
|
||||
* the kernel's there is no more we can evict.
|
||||
*/
|
||||
if (!ggtt_is_idle(dev_priv)) {
|
||||
ret = ggtt_flush(dev_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
goto search_again;
|
||||
}
|
||||
|
||||
ret = ggtt_flush(dev_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
goto search_again;
|
||||
/*
|
||||
* If we still have pending pageflip completions, drop
|
||||
* back to userspace to give our workqueues time to
|
||||
* acquire our locks and unpin the old scanouts.
|
||||
*/
|
||||
return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
|
||||
|
||||
found:
|
||||
/* drm_mm doesn't allow any other other operations while
|
||||
|
|
|
@ -6998,6 +6998,7 @@ enum {
|
|||
*/
|
||||
#define L3_GENERAL_PRIO_CREDITS(x) (((x) >> 1) << 19)
|
||||
#define L3_HIGH_PRIO_CREDITS(x) (((x) >> 1) << 14)
|
||||
#define L3_PRIO_CREDITS_MASK ((0x1f << 19) | (0x1f << 14))
|
||||
|
||||
#define GEN7_L3CNTLREG1 _MMIO(0xB01C)
|
||||
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C
|
||||
|
|
|
@ -664,8 +664,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
|
|||
int *n_entries)
|
||||
{
|
||||
if (IS_BROADWELL(dev_priv)) {
|
||||
*n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
|
||||
return hsw_ddi_translations_fdi;
|
||||
*n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi);
|
||||
return bdw_ddi_translations_fdi;
|
||||
} else if (IS_HASWELL(dev_priv)) {
|
||||
*n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
|
||||
return hsw_ddi_translations_fdi;
|
||||
|
@ -2102,8 +2102,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
|
|||
* register writes.
|
||||
*/
|
||||
val = I915_READ(DPCLKA_CFGCR0);
|
||||
val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) |
|
||||
DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port));
|
||||
val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
|
||||
I915_WRITE(DPCLKA_CFGCR0, val);
|
||||
} else if (IS_GEN9_BC(dev_priv)) {
|
||||
/* DDI -> PLL mapping */
|
||||
|
|
|
@ -1996,7 +1996,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
|
|||
|
||||
/* 3. Configure DPLL_CFGCR0 */
|
||||
/* Avoid touch CFGCR1 if HDMI mode is not enabled */
|
||||
if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) {
|
||||
if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
|
||||
val = pll->state.hw_state.cfgcr1;
|
||||
I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val);
|
||||
/* 4. Reab back to ensure writes completed */
|
||||
|
|
|
@ -1048,9 +1048,12 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine)
|
|||
}
|
||||
|
||||
/* WaProgramL3SqcReg1DefaultForPerf:bxt */
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
|
||||
I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
|
||||
L3_HIGH_PRIO_CREDITS(2));
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
|
||||
u32 val = I915_READ(GEN8_L3SQCREG1);
|
||||
val &= ~L3_PRIO_CREDITS_MASK;
|
||||
val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
|
||||
I915_WRITE(GEN8_L3SQCREG1, val);
|
||||
}
|
||||
|
||||
/* WaToEnableHwFixForPushConstHWBug:bxt */
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
|
||||
|
|
|
@ -8245,14 +8245,17 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
|
|||
int high_prio_credits)
|
||||
{
|
||||
u32 misccpctl;
|
||||
u32 val;
|
||||
|
||||
/* WaTempDisableDOPClkGating:bdw */
|
||||
misccpctl = I915_READ(GEN7_MISCCPCTL);
|
||||
I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
|
||||
|
||||
I915_WRITE(GEN8_L3SQCREG1,
|
||||
L3_GENERAL_PRIO_CREDITS(general_prio_credits) |
|
||||
L3_HIGH_PRIO_CREDITS(high_prio_credits));
|
||||
val = I915_READ(GEN8_L3SQCREG1);
|
||||
val &= ~L3_PRIO_CREDITS_MASK;
|
||||
val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
|
||||
val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
|
||||
I915_WRITE(GEN8_L3SQCREG1, val);
|
||||
|
||||
/*
|
||||
* Wait at least 100 clocks before re-enabling clock gating.
|
||||
|
|
|
@ -223,7 +223,7 @@ void
|
|||
nouveau_fbcon_accel_save_disable(struct drm_device *dev)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
if (drm->fbcon) {
|
||||
if (drm->fbcon && drm->fbcon->helper.fbdev) {
|
||||
drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
|
||||
drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ void
|
|||
nouveau_fbcon_accel_restore(struct drm_device *dev)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
if (drm->fbcon) {
|
||||
if (drm->fbcon && drm->fbcon->helper.fbdev) {
|
||||
drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +245,8 @@ nouveau_fbcon_accel_fini(struct drm_device *dev)
|
|||
struct nouveau_fbdev *fbcon = drm->fbcon;
|
||||
if (fbcon && drm->channel) {
|
||||
console_lock();
|
||||
fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
if (fbcon->helper.fbdev)
|
||||
fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
console_unlock();
|
||||
nouveau_channel_idle(drm->channel);
|
||||
nvif_object_fini(&fbcon->twod);
|
||||
|
|
|
@ -3265,11 +3265,14 @@ nv50_mstm = {
|
|||
void
|
||||
nv50_mstm_service(struct nv50_mstm *mstm)
|
||||
{
|
||||
struct drm_dp_aux *aux = mstm->mgr.aux;
|
||||
struct drm_dp_aux *aux = mstm ? mstm->mgr.aux : NULL;
|
||||
bool handled = true;
|
||||
int ret;
|
||||
u8 esi[8] = {};
|
||||
|
||||
if (!aux)
|
||||
return;
|
||||
|
||||
while (handled) {
|
||||
ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8);
|
||||
if (ret != 8) {
|
||||
|
|
|
@ -39,5 +39,5 @@ int
|
|||
g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
|
||||
{
|
||||
return nvkm_xtensa_new_(&g84_bsp, device, index,
|
||||
true, 0x103000, pengine);
|
||||
device->chipset != 0x92, 0x103000, pengine);
|
||||
}
|
||||
|
|
|
@ -241,6 +241,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde)
|
|||
mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem);
|
||||
}
|
||||
|
||||
mmu->func->flush(vm);
|
||||
|
||||
nvkm_memory_del(&pgt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
|
|||
{
|
||||
BUG_ON(!is_hvsock_channel(channel));
|
||||
|
||||
channel->rescind = true;
|
||||
/* We always get a rescind msg when a connection is closed. */
|
||||
while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind))
|
||||
msleep(1);
|
||||
|
||||
vmbus_device_unregister(channel->device_obj);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
|
||||
|
|
|
@ -198,6 +198,11 @@ config I2C_CHT_WC
|
|||
SMBus controller found in the Intel Cherry Trail Whiskey Cove PMIC
|
||||
found on some Intel Cherry Trail systems.
|
||||
|
||||
Note this controller is hooked up to a TI bq24292i charger-IC,
|
||||
combined with a FUSB302 Type-C port-controller as such it is advised
|
||||
to also select CONFIG_CHARGER_BQ24190=m and CONFIG_TYPEC_FUSB302=m
|
||||
(the fusb302 driver currently is in drivers/staging).
|
||||
|
||||
config I2C_NFORCE2
|
||||
tristate "Nvidia nForce2, nForce3 and nForce4"
|
||||
depends on PCI
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include <linux/mfd/intel_soc_pmic.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power/bq24190_charger.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define CHT_WC_I2C_CTRL 0x5e24
|
||||
|
@ -232,13 +234,35 @@ static const struct irq_chip cht_wc_i2c_irq_chip = {
|
|||
.name = "cht_wc_ext_chrg_irq_chip",
|
||||
};
|
||||
|
||||
static const char * const bq24190_suppliers[] = { "fusb302-typec-source" };
|
||||
|
||||
static const struct property_entry bq24190_props[] = {
|
||||
PROPERTY_ENTRY_STRING("extcon-name", "cht_wcove_pwrsrc"),
|
||||
PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_suppliers),
|
||||
PROPERTY_ENTRY_BOOL("omit-battery-class"),
|
||||
PROPERTY_ENTRY_BOOL("disable-reset"),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply fusb302_consumer = {
|
||||
.supply = "vbus",
|
||||
/* Must match fusb302 dev_name in intel_cht_int33fe.c */
|
||||
.dev_name = "i2c-fusb302",
|
||||
};
|
||||
|
||||
static const struct regulator_init_data bq24190_vbus_init_data = {
|
||||
.constraints = {
|
||||
/* The name is used in intel_cht_int33fe.c do not change. */
|
||||
.name = "cht_wc_usb_typec_vbus",
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.consumer_supplies = &fusb302_consumer,
|
||||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static struct bq24190_platform_data bq24190_pdata = {
|
||||
.regulator_init_data = &bq24190_vbus_init_data,
|
||||
};
|
||||
|
||||
static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
|
||||
|
@ -246,7 +270,9 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
|
|||
struct i2c_board_info board_info = {
|
||||
.type = "bq24190",
|
||||
.addr = 0x6b,
|
||||
.dev_name = "bq24190",
|
||||
.properties = bq24190_props,
|
||||
.platform_data = &bq24190_pdata,
|
||||
};
|
||||
int ret, reg, irq;
|
||||
|
||||
|
@ -314,11 +340,21 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto remove_irq_domain;
|
||||
|
||||
board_info.irq = adap->client_irq;
|
||||
adap->client = i2c_new_device(&adap->adapter, &board_info);
|
||||
if (!adap->client) {
|
||||
ret = -ENOMEM;
|
||||
goto del_adapter;
|
||||
/*
|
||||
* Normally the Whiskey Cove PMIC is paired with a TI bq24292i charger,
|
||||
* connected to this i2c bus, and a max17047 fuel-gauge and a fusb302
|
||||
* USB Type-C controller connected to another i2c bus. In this setup
|
||||
* the max17047 and fusb302 devices are enumerated through an INT33FE
|
||||
* ACPI device. If this device is present register an i2c-client for
|
||||
* the TI bq24292i charger.
|
||||
*/
|
||||
if (acpi_dev_present("INT33FE", NULL, -1)) {
|
||||
board_info.irq = adap->client_irq;
|
||||
adap->client = i2c_new_device(&adap->adapter, &board_info);
|
||||
if (!adap->client) {
|
||||
ret = -ENOMEM;
|
||||
goto del_adapter;
|
||||
}
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, adap);
|
||||
|
@ -335,7 +371,8 @@ static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
|
||||
|
||||
i2c_unregister_device(adap->client);
|
||||
if (adap->client)
|
||||
i2c_unregister_device(adap->client);
|
||||
i2c_del_adapter(&adap->adapter);
|
||||
irq_domain_remove(adap->irq_domain);
|
||||
|
||||
|
|
|
@ -1021,7 +1021,7 @@ static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
|
|||
}
|
||||
|
||||
dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
|
||||
rinfo->sda_gpio, rinfo->scl_gpio);
|
||||
rinfo->scl_gpio, rinfo->sda_gpio);
|
||||
|
||||
rinfo->prepare_recovery = i2c_imx_prepare_recovery;
|
||||
rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
|
||||
|
@ -1100,7 +1100,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* Request IRQ */
|
||||
ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
|
||||
ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED,
|
||||
pdev->name, i2c_imx);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "can't claim irq %d\n", irq);
|
||||
|
|
|
@ -340,12 +340,15 @@ static int ismt_process_desc(const struct ismt_desc *desc,
|
|||
data->word = dma_buffer[0] | (dma_buffer[1] << 8);
|
||||
break;
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
if (desc->rxbytes != dma_buffer[0] + 1)
|
||||
return -EMSGSIZE;
|
||||
|
||||
memcpy(data->block, dma_buffer, desc->rxbytes);
|
||||
break;
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
memcpy(&data->block[1], dma_buffer, desc->rxbytes);
|
||||
data->block[0] = desc->rxbytes;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -360,6 +360,7 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
|
|||
unsigned long fclk_rate = 12000000;
|
||||
unsigned long internal_clk = 0;
|
||||
struct clk *fclk;
|
||||
int error;
|
||||
|
||||
if (omap->rev >= OMAP_I2C_REV_ON_3430_3530) {
|
||||
/*
|
||||
|
@ -378,6 +379,13 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
|
|||
* do this bit unconditionally.
|
||||
*/
|
||||
fclk = clk_get(omap->dev, "fck");
|
||||
if (IS_ERR(fclk)) {
|
||||
error = PTR_ERR(fclk);
|
||||
dev_err(omap->dev, "could not get fck: %i\n", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
fclk_rate = clk_get_rate(fclk);
|
||||
clk_put(fclk);
|
||||
|
||||
|
@ -410,6 +418,12 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
|
|||
else
|
||||
internal_clk = 4000;
|
||||
fclk = clk_get(omap->dev, "fck");
|
||||
if (IS_ERR(fclk)) {
|
||||
error = PTR_ERR(fclk);
|
||||
dev_err(omap->dev, "could not get fck: %i\n", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
fclk_rate = clk_get_rate(fclk) / 1000;
|
||||
clk_put(fclk);
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
/* SB800 constants */
|
||||
#define SB800_PIIX4_SMB_IDX 0xcd6
|
||||
|
||||
#define KERNCZ_IMC_IDX 0x3e
|
||||
#define KERNCZ_IMC_DATA 0x3f
|
||||
|
||||
/*
|
||||
* SB800 port is selected by bits 2:1 of the smb_en register (0x2c)
|
||||
* or the smb_sel register (0x2e), depending on bit 0 of register 0x2f.
|
||||
|
@ -94,6 +97,12 @@
|
|||
#define SB800_PIIX4_PORT_IDX_ALT 0x2e
|
||||
#define SB800_PIIX4_PORT_IDX_SEL 0x2f
|
||||
#define SB800_PIIX4_PORT_IDX_MASK 0x06
|
||||
#define SB800_PIIX4_PORT_IDX_SHIFT 1
|
||||
|
||||
/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
|
||||
#define SB800_PIIX4_PORT_IDX_KERNCZ 0x02
|
||||
#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18
|
||||
#define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3
|
||||
|
||||
/* insmod parameters */
|
||||
|
||||
|
@ -149,6 +158,8 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
|
|||
*/
|
||||
static DEFINE_MUTEX(piix4_mutex_sb800);
|
||||
static u8 piix4_port_sel_sb800;
|
||||
static u8 piix4_port_mask_sb800;
|
||||
static u8 piix4_port_shift_sb800;
|
||||
static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
|
||||
" port 0", " port 2", " port 3", " port 4"
|
||||
};
|
||||
|
@ -159,6 +170,7 @@ struct i2c_piix4_adapdata {
|
|||
|
||||
/* SB800 */
|
||||
bool sb800_main;
|
||||
bool notify_imc;
|
||||
u8 port; /* Port number, shifted */
|
||||
};
|
||||
|
||||
|
@ -347,7 +359,19 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|||
|
||||
/* Find which register is used for port selection */
|
||||
if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) {
|
||||
piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
|
||||
switch (PIIX4_dev->device) {
|
||||
case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS:
|
||||
piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ;
|
||||
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ;
|
||||
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ;
|
||||
break;
|
||||
case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS:
|
||||
default:
|
||||
piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
|
||||
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
|
||||
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&piix4_mutex_sb800);
|
||||
outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX);
|
||||
|
@ -355,6 +379,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|||
piix4_port_sel_sb800 = (port_sel & 0x01) ?
|
||||
SB800_PIIX4_PORT_IDX_ALT :
|
||||
SB800_PIIX4_PORT_IDX;
|
||||
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
|
||||
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
|
||||
mutex_unlock(&piix4_mutex_sb800);
|
||||
}
|
||||
|
||||
|
@ -572,6 +598,67 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t piix4_imc_read(uint8_t idx)
|
||||
{
|
||||
outb_p(idx, KERNCZ_IMC_IDX);
|
||||
return inb_p(KERNCZ_IMC_DATA);
|
||||
}
|
||||
|
||||
static void piix4_imc_write(uint8_t idx, uint8_t value)
|
||||
{
|
||||
outb_p(idx, KERNCZ_IMC_IDX);
|
||||
outb_p(value, KERNCZ_IMC_DATA);
|
||||
}
|
||||
|
||||
static int piix4_imc_sleep(void)
|
||||
{
|
||||
int timeout = MAX_TIMEOUT;
|
||||
|
||||
if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
|
||||
return -EBUSY;
|
||||
|
||||
/* clear response register */
|
||||
piix4_imc_write(0x82, 0x00);
|
||||
/* request ownership flag */
|
||||
piix4_imc_write(0x83, 0xB4);
|
||||
/* kick off IMC Mailbox command 96 */
|
||||
piix4_imc_write(0x80, 0x96);
|
||||
|
||||
while (timeout--) {
|
||||
if (piix4_imc_read(0x82) == 0xfa) {
|
||||
release_region(KERNCZ_IMC_IDX, 2);
|
||||
return 0;
|
||||
}
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
release_region(KERNCZ_IMC_IDX, 2);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void piix4_imc_wakeup(void)
|
||||
{
|
||||
int timeout = MAX_TIMEOUT;
|
||||
|
||||
if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
|
||||
return;
|
||||
|
||||
/* clear response register */
|
||||
piix4_imc_write(0x82, 0x00);
|
||||
/* release ownership flag */
|
||||
piix4_imc_write(0x83, 0xB5);
|
||||
/* kick off IMC Mailbox command 96 */
|
||||
piix4_imc_write(0x80, 0x96);
|
||||
|
||||
while (timeout--) {
|
||||
if (piix4_imc_read(0x82) == 0xfa)
|
||||
break;
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
release_region(KERNCZ_IMC_IDX, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles access to multiple SMBus ports on the SB800.
|
||||
* The port is selected by bits 2:1 of the smb_en register (0x2c).
|
||||
|
@ -612,12 +699,47 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the IMC (Integrated Micro Controller) if required.
|
||||
* Among other responsibilities, the IMC is in charge of monitoring
|
||||
* the System fans and temperature sensors, and act accordingly.
|
||||
* All this is done through SMBus and can/will collide
|
||||
* with our transactions if they are long (BLOCK_DATA).
|
||||
* Therefore we need to request the ownership flag during those
|
||||
* transactions.
|
||||
*/
|
||||
if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) {
|
||||
int ret;
|
||||
|
||||
ret = piix4_imc_sleep();
|
||||
switch (ret) {
|
||||
case -EBUSY:
|
||||
dev_warn(&adap->dev,
|
||||
"IMC base address index region 0x%x already in use.\n",
|
||||
KERNCZ_IMC_IDX);
|
||||
break;
|
||||
case -ETIMEDOUT:
|
||||
dev_warn(&adap->dev,
|
||||
"Failed to communicate with the IMC.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If IMC communication fails do not retry */
|
||||
if (ret) {
|
||||
dev_warn(&adap->dev,
|
||||
"Continuing without IMC notification.\n");
|
||||
adapdata->notify_imc = false;
|
||||
}
|
||||
}
|
||||
|
||||
outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
|
||||
smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
|
||||
|
||||
port = adapdata->port;
|
||||
if ((smba_en_lo & SB800_PIIX4_PORT_IDX_MASK) != port)
|
||||
outb_p((smba_en_lo & ~SB800_PIIX4_PORT_IDX_MASK) | port,
|
||||
if ((smba_en_lo & piix4_port_mask_sb800) != port)
|
||||
outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port,
|
||||
SB800_PIIX4_SMB_IDX + 1);
|
||||
|
||||
retval = piix4_access(adap, addr, flags, read_write,
|
||||
|
@ -628,6 +750,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
|
|||
/* Release the semaphore */
|
||||
outb_p(smbslvcnt | 0x20, SMBSLVCNT);
|
||||
|
||||
if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc)
|
||||
piix4_imc_wakeup();
|
||||
|
||||
mutex_unlock(&piix4_mutex_sb800);
|
||||
|
||||
return retval;
|
||||
|
@ -679,7 +804,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
|
|||
static struct i2c_adapter *piix4_aux_adapter;
|
||||
|
||||
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
|
||||
bool sb800_main, u8 port,
|
||||
bool sb800_main, u8 port, bool notify_imc,
|
||||
const char *name, struct i2c_adapter **padap)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
|
@ -706,7 +831,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
|
|||
|
||||
adapdata->smba = smba;
|
||||
adapdata->sb800_main = sb800_main;
|
||||
adapdata->port = port << 1;
|
||||
adapdata->port = port << piix4_port_shift_sb800;
|
||||
adapdata->notify_imc = notify_imc;
|
||||
|
||||
/* set up the sysfs linkage to our parent device */
|
||||
adap->dev.parent = &dev->dev;
|
||||
|
@ -728,14 +854,15 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
|
||||
static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
|
||||
bool notify_imc)
|
||||
{
|
||||
struct i2c_piix4_adapdata *adapdata;
|
||||
int port;
|
||||
int retval;
|
||||
|
||||
for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
|
||||
retval = piix4_add_adapter(dev, smba, true, port,
|
||||
retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
|
||||
piix4_main_port_names_sb800[port],
|
||||
&piix4_main_adapters[port]);
|
||||
if (retval < 0)
|
||||
|
@ -769,6 +896,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
|
||||
dev->revision >= 0x40) ||
|
||||
dev->vendor == PCI_VENDOR_ID_AMD) {
|
||||
bool notify_imc = false;
|
||||
is_sb800 = true;
|
||||
|
||||
if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) {
|
||||
|
@ -778,6 +906,20 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (dev->vendor == PCI_VENDOR_ID_AMD &&
|
||||
dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) {
|
||||
u8 imc;
|
||||
|
||||
/*
|
||||
* Detect if IMC is active or not, this method is
|
||||
* described on coreboot's AMD IMC notes
|
||||
*/
|
||||
pci_bus_read_config_byte(dev->bus, PCI_DEVFN(0x14, 3),
|
||||
0x40, &imc);
|
||||
if (imc & 0x80)
|
||||
notify_imc = true;
|
||||
}
|
||||
|
||||
/* base address location etc changed in SB800 */
|
||||
retval = piix4_setup_sb800(dev, id, 0);
|
||||
if (retval < 0) {
|
||||
|
@ -789,7 +931,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
* Try to register multiplexed main SMBus adapter,
|
||||
* give up if we can't
|
||||
*/
|
||||
retval = piix4_add_adapters_sb800(dev, retval);
|
||||
retval = piix4_add_adapters_sb800(dev, retval, notify_imc);
|
||||
if (retval < 0) {
|
||||
release_region(SB800_PIIX4_SMB_IDX, 2);
|
||||
return retval;
|
||||
|
@ -800,7 +942,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
return retval;
|
||||
|
||||
/* Try to register main SMBus adapter, give up if we can't */
|
||||
retval = piix4_add_adapter(dev, retval, false, 0, "",
|
||||
retval = piix4_add_adapter(dev, retval, false, 0, false, "",
|
||||
&piix4_main_adapters[0]);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
@ -827,7 +969,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
if (retval > 0) {
|
||||
/* Try to add the aux adapter if it exists,
|
||||
* piix4_add_adapter will clean up if this fails */
|
||||
piix4_add_adapter(dev, retval, false, 0,
|
||||
piix4_add_adapter(dev, retval, false, 0, false,
|
||||
is_sb800 ? piix4_aux_port_name_sb800 : "",
|
||||
&piix4_aux_adapter);
|
||||
}
|
||||
|
|
|
@ -666,10 +666,16 @@ static void i2c_adapter_unlock_bus(struct i2c_adapter *adapter,
|
|||
}
|
||||
|
||||
static void i2c_dev_set_name(struct i2c_adapter *adap,
|
||||
struct i2c_client *client)
|
||||
struct i2c_client *client,
|
||||
struct i2c_board_info const *info)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
|
||||
|
||||
if (info && info->dev_name) {
|
||||
dev_set_name(&client->dev, "i2c-%s", info->dev_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (adev) {
|
||||
dev_set_name(&client->dev, "i2c-%s", acpi_dev_name(adev));
|
||||
return;
|
||||
|
@ -766,7 +772,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
|
|||
client->dev.of_node = info->of_node;
|
||||
client->dev.fwnode = info->fwnode;
|
||||
|
||||
i2c_dev_set_name(adap, client);
|
||||
i2c_dev_set_name(adap, client, info);
|
||||
|
||||
if (info->properties) {
|
||||
status = device_add_properties(&client->dev, info->properties);
|
||||
|
|
|
@ -243,6 +243,8 @@ config DA9150_GPADC
|
|||
config DLN2_ADC
|
||||
tristate "Diolan DLN-2 ADC driver support"
|
||||
depends on MFD_DLN2
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
Say yes here to build support for Diolan DLN-2 ADC.
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ struct at91_adc_trigger {
|
|||
char *name;
|
||||
unsigned int trgmod_value;
|
||||
unsigned int edge_type;
|
||||
bool hw_trig;
|
||||
};
|
||||
|
||||
struct at91_adc_state {
|
||||
|
@ -254,16 +255,25 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
|
|||
.name = "external_rising",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE,
|
||||
.edge_type = IRQ_TYPE_EDGE_RISING,
|
||||
.hw_trig = true,
|
||||
},
|
||||
{
|
||||
.name = "external_falling",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL,
|
||||
.edge_type = IRQ_TYPE_EDGE_FALLING,
|
||||
.hw_trig = true,
|
||||
},
|
||||
{
|
||||
.name = "external_any",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY,
|
||||
.edge_type = IRQ_TYPE_EDGE_BOTH,
|
||||
.hw_trig = true,
|
||||
},
|
||||
{
|
||||
.name = "software",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER,
|
||||
.edge_type = IRQ_TYPE_NONE,
|
||||
.hw_trig = false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -597,7 +607,7 @@ static int at91_adc_probe(struct platform_device *pdev)
|
|||
struct at91_adc_state *st;
|
||||
struct resource *res;
|
||||
int ret, i;
|
||||
u32 edge_type;
|
||||
u32 edge_type = IRQ_TYPE_NONE;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
|
||||
if (!indio_dev)
|
||||
|
@ -641,14 +651,14 @@ static int at91_adc_probe(struct platform_device *pdev)
|
|||
ret = of_property_read_u32(pdev->dev.of_node,
|
||||
"atmel,trigger-edge-type", &edge_type);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"invalid or missing value for atmel,trigger-edge-type\n");
|
||||
return ret;
|
||||
dev_dbg(&pdev->dev,
|
||||
"atmel,trigger-edge-type not specified, only software trigger available\n");
|
||||
}
|
||||
|
||||
st->selected_trig = NULL;
|
||||
|
||||
for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++)
|
||||
/* find the right trigger, or no trigger at all */
|
||||
for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
|
||||
if (at91_adc_trigger_list[i].edge_type == edge_type) {
|
||||
st->selected_trig = &at91_adc_trigger_list[i];
|
||||
break;
|
||||
|
@ -717,24 +727,27 @@ static int at91_adc_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
ret = at91_adc_buffer_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
}
|
||||
if (st->selected_trig->hw_trig) {
|
||||
ret = at91_adc_buffer_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
}
|
||||
|
||||
ret = at91_adc_trigger_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't setup the triggers.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
ret = at91_adc_trigger_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't setup the triggers.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
}
|
||||
}
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret < 0)
|
||||
goto per_clk_disable_unprepare;
|
||||
|
||||
dev_info(&pdev->dev, "setting up trigger as %s\n",
|
||||
st->selected_trig->name);
|
||||
if (st->selected_trig->hw_trig)
|
||||
dev_info(&pdev->dev, "setting up trigger as %s\n",
|
||||
st->selected_trig->name);
|
||||
|
||||
dev_info(&pdev->dev, "version: %x\n",
|
||||
readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
|
||||
|
|
|
@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
|
|||
st->event_en = state;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -865,7 +865,6 @@ complete:
|
|||
static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
|
||||
struct zpa2326_private *private)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val;
|
||||
long timeout;
|
||||
|
||||
|
@ -887,14 +886,11 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
|
|||
/* Timed out. */
|
||||
zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)",
|
||||
timeout);
|
||||
ret = -ETIME;
|
||||
} else if (timeout < 0) {
|
||||
zpa2326_warn(indio_dev,
|
||||
"wait for one shot interrupt cancelled");
|
||||
ret = -ERESTARTSYS;
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return ret;
|
||||
zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled");
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
static int zpa2326_init_managed_irq(struct device *parent,
|
||||
|
|
|
@ -39,8 +39,12 @@
|
|||
#define AS3935_AFE_GAIN_MAX 0x1F
|
||||
#define AS3935_AFE_PWR_BIT BIT(0)
|
||||
|
||||
#define AS3935_NFLWDTH 0x01
|
||||
#define AS3935_NFLWDTH_MASK 0x7f
|
||||
|
||||
#define AS3935_INT 0x03
|
||||
#define AS3935_INT_MASK 0x0f
|
||||
#define AS3935_DISTURB_INT BIT(2)
|
||||
#define AS3935_EVENT_INT BIT(3)
|
||||
#define AS3935_NOISE_INT BIT(0)
|
||||
|
||||
|
@ -48,6 +52,7 @@
|
|||
#define AS3935_DATA_MASK 0x3F
|
||||
|
||||
#define AS3935_TUNE_CAP 0x08
|
||||
#define AS3935_DEFAULTS 0x3C
|
||||
#define AS3935_CALIBRATE 0x3D
|
||||
|
||||
#define AS3935_READ_DATA BIT(14)
|
||||
|
@ -62,7 +67,9 @@ struct as3935_state {
|
|||
struct mutex lock;
|
||||
struct delayed_work work;
|
||||
|
||||
unsigned long noise_tripped;
|
||||
u32 tune_cap;
|
||||
u32 nflwdth_reg;
|
||||
u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
|
||||
u8 buf[2] ____cacheline_aligned;
|
||||
};
|
||||
|
@ -145,12 +152,29 @@ static ssize_t as3935_sensor_sensitivity_store(struct device *dev,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t as3935_noise_level_tripped_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||
int ret;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
ret = sprintf(buf, "%d\n", !time_after(jiffies, st->noise_tripped + HZ));
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
|
||||
as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);
|
||||
|
||||
static IIO_DEVICE_ATTR(noise_level_tripped, S_IRUGO,
|
||||
as3935_noise_level_tripped_show, NULL, 0);
|
||||
|
||||
static struct attribute *as3935_attributes[] = {
|
||||
&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
|
||||
&iio_dev_attr_noise_level_tripped.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -246,7 +270,11 @@ static void as3935_event_work(struct work_struct *work)
|
|||
case AS3935_EVENT_INT:
|
||||
iio_trigger_poll_chained(st->trig);
|
||||
break;
|
||||
case AS3935_DISTURB_INT:
|
||||
case AS3935_NOISE_INT:
|
||||
mutex_lock(&st->lock);
|
||||
st->noise_tripped = jiffies;
|
||||
mutex_unlock(&st->lock);
|
||||
dev_warn(&st->spi->dev, "noise level is too high\n");
|
||||
break;
|
||||
}
|
||||
|
@ -269,15 +297,14 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private)
|
|||
|
||||
static void calibrate_as3935(struct as3935_state *st)
|
||||
{
|
||||
/* mask disturber interrupt bit */
|
||||
as3935_write(st, AS3935_INT, BIT(5));
|
||||
|
||||
as3935_write(st, AS3935_DEFAULTS, 0x96);
|
||||
as3935_write(st, AS3935_CALIBRATE, 0x96);
|
||||
as3935_write(st, AS3935_TUNE_CAP,
|
||||
BIT(5) | (st->tune_cap / TUNE_CAP_DIV));
|
||||
|
||||
mdelay(2);
|
||||
as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
|
||||
as3935_write(st, AS3935_NFLWDTH, st->nflwdth_reg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -370,6 +397,15 @@ static int as3935_probe(struct spi_device *spi)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np,
|
||||
"ams,nflwdth", &st->nflwdth_reg);
|
||||
if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) {
|
||||
dev_err(&spi->dev,
|
||||
"invalid nflwdth setting of %d\n",
|
||||
st->nflwdth_reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
indio_dev->dev.parent = &spi->dev;
|
||||
indio_dev->name = spi_get_device_id(spi)->name;
|
||||
indio_dev->channels = as3935_channels;
|
||||
|
@ -384,6 +420,7 @@ static int as3935_probe(struct spi_device *spi)
|
|||
return -ENOMEM;
|
||||
|
||||
st->trig = trig;
|
||||
st->noise_tripped = jiffies - HZ;
|
||||
trig->dev.parent = indio_dev->dev.parent;
|
||||
iio_trigger_set_drvdata(trig, indio_dev);
|
||||
trig->ops = &iio_interrupt_trigger_ops;
|
||||
|
|
|
@ -933,58 +933,52 @@ int input_set_keycode(struct input_dev *dev,
|
|||
}
|
||||
EXPORT_SYMBOL(input_set_keycode);
|
||||
|
||||
bool input_match_device_id(const struct input_dev *dev,
|
||||
const struct input_device_id *id)
|
||||
{
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
|
||||
if (id->bustype != dev->id.bustype)
|
||||
return false;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
|
||||
if (id->vendor != dev->id.vendor)
|
||||
return false;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
|
||||
if (id->product != dev->id.product)
|
||||
return false;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
|
||||
if (id->version != dev->id.version)
|
||||
return false;
|
||||
|
||||
if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX) ||
|
||||
!bitmap_subset(id->keybit, dev->keybit, KEY_MAX) ||
|
||||
!bitmap_subset(id->relbit, dev->relbit, REL_MAX) ||
|
||||
!bitmap_subset(id->absbit, dev->absbit, ABS_MAX) ||
|
||||
!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX) ||
|
||||
!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) ||
|
||||
!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) ||
|
||||
!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) ||
|
||||
!bitmap_subset(id->swbit, dev->swbit, SW_MAX) ||
|
||||
!bitmap_subset(id->propbit, dev->propbit, INPUT_PROP_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(input_match_device_id);
|
||||
|
||||
static const struct input_device_id *input_match_device(struct input_handler *handler,
|
||||
struct input_dev *dev)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
|
||||
for (id = handler->id_table; id->flags || id->driver_info; id++) {
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
|
||||
if (id->bustype != dev->id.bustype)
|
||||
continue;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
|
||||
if (id->vendor != dev->id.vendor)
|
||||
continue;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
|
||||
if (id->product != dev->id.product)
|
||||
continue;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
|
||||
if (id->version != dev->id.version)
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX))
|
||||
continue;
|
||||
|
||||
if (!handler->match || handler->match(handler, dev))
|
||||
if (input_match_device_id(dev, id) &&
|
||||
(!handler->match || handler->match(handler, dev))) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -747,6 +747,68 @@ static void joydev_cleanup(struct joydev *joydev)
|
|||
input_close_device(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* These codes are copied from from hid-ids.h, unfortunately there is no common
|
||||
* usb_ids/bt_ids.h header.
|
||||
*/
|
||||
#define USB_VENDOR_ID_SONY 0x054c
|
||||
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
|
||||
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
|
||||
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc
|
||||
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0
|
||||
|
||||
#define USB_VENDOR_ID_THQ 0x20d6
|
||||
#define USB_DEVICE_ID_THQ_PS3_UDRAW 0xcb17
|
||||
|
||||
#define ACCEL_DEV(vnd, prd) \
|
||||
{ \
|
||||
.flags = INPUT_DEVICE_ID_MATCH_VENDOR | \
|
||||
INPUT_DEVICE_ID_MATCH_PRODUCT | \
|
||||
INPUT_DEVICE_ID_MATCH_PROPBIT, \
|
||||
.vendor = (vnd), \
|
||||
.product = (prd), \
|
||||
.propbit = { BIT_MASK(INPUT_PROP_ACCELEROMETER) }, \
|
||||
}
|
||||
|
||||
static const struct input_device_id joydev_blacklist[] = {
|
||||
/* Avoid touchpads and touchscreens */
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_KEYBIT,
|
||||
.evbit = { BIT_MASK(EV_KEY) },
|
||||
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
|
||||
},
|
||||
/* Avoid tablets, digitisers and similar devices */
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_KEYBIT,
|
||||
.evbit = { BIT_MASK(EV_KEY) },
|
||||
.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
|
||||
},
|
||||
/* Disable accelerometers on composite devices */
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
|
||||
ACCEL_DEV(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static bool joydev_dev_is_blacklisted(struct input_dev *dev)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
|
||||
for (id = joydev_blacklist; id->flags; id++) {
|
||||
if (input_match_device_id(dev, id)) {
|
||||
dev_dbg(&dev->dev,
|
||||
"joydev: blacklisting '%s'\n", dev->name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
|
||||
{
|
||||
DECLARE_BITMAP(jd_scratch, KEY_CNT);
|
||||
|
@ -807,12 +869,8 @@ static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
|
|||
|
||||
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
|
||||
{
|
||||
/* Avoid touchpads and touchscreens */
|
||||
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
|
||||
return false;
|
||||
|
||||
/* Avoid tablets, digitisers and similar devices */
|
||||
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
|
||||
/* Disable blacklisted devices */
|
||||
if (joydev_dev_is_blacklisted(dev))
|
||||
return false;
|
||||
|
||||
/* Avoid absolute mice */
|
||||
|
|
|
@ -234,14 +234,7 @@ static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
|
|||
static int tca8418_configure(struct tca8418_keypad *keypad_data,
|
||||
u32 rows, u32 cols)
|
||||
{
|
||||
int reg, error;
|
||||
|
||||
/* Write config register, if this fails assume device not present */
|
||||
error = tca8418_write_byte(keypad_data, REG_CFG,
|
||||
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
|
||||
if (error < 0)
|
||||
return -ENODEV;
|
||||
|
||||
int reg, error = 0;
|
||||
|
||||
/* Assemble a mask for row and column registers */
|
||||
reg = ~(~0 << rows);
|
||||
|
@ -257,6 +250,12 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
|
|||
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
|
||||
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = tca8418_write_byte(keypad_data, REG_CFG,
|
||||
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -268,6 +267,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||
struct input_dev *input;
|
||||
u32 rows = 0, cols = 0;
|
||||
int error, row_shift, max_keys;
|
||||
u8 reg;
|
||||
|
||||
/* Check i2c driver capabilities */
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
|
||||
|
@ -301,10 +301,10 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||
keypad_data->client = client;
|
||||
keypad_data->row_shift = row_shift;
|
||||
|
||||
/* Initialize the chip or fail if chip isn't present */
|
||||
error = tca8418_configure(keypad_data, rows, cols);
|
||||
if (error < 0)
|
||||
return error;
|
||||
/* Read key lock register, if this fails assume device not present */
|
||||
error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, ®);
|
||||
if (error)
|
||||
return -ENODEV;
|
||||
|
||||
/* Configure input device */
|
||||
input = devm_input_allocate_device(dev);
|
||||
|
@ -340,6 +340,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||
return error;
|
||||
}
|
||||
|
||||
/* Initialize the chip */
|
||||
error = tca8418_configure(keypad_data, rows, cols);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(dev, "Unable to register input device, error: %d\n",
|
||||
|
|
|
@ -403,6 +403,7 @@ static const struct platform_device_id axp_pek_id_match[] = {
|
|||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, axp_pek_id_match);
|
||||
|
||||
static struct platform_driver axp20x_pek_driver = {
|
||||
.probe = axp20x_pek_probe,
|
||||
|
@ -417,4 +418,3 @@ module_platform_driver(axp20x_pek_driver);
|
|||
MODULE_DESCRIPTION("axp20x Power Button");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:axp20x-pek");
|
||||
|
|
|
@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
while (buflen > 0) {
|
||||
while (buflen >= sizeof(*union_desc)) {
|
||||
union_desc = (struct usb_cdc_union_desc *)buf;
|
||||
|
||||
if (union_desc->bLength > buflen) {
|
||||
dev_err(&intf->dev, "Too large descriptor\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
|
||||
union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
|
||||
dev_dbg(&intf->dev, "Found union header\n");
|
||||
return union_desc;
|
||||
|
||||
if (union_desc->bLength >= sizeof(*union_desc))
|
||||
return union_desc;
|
||||
|
||||
dev_err(&intf->dev,
|
||||
"Union descriptor to short (%d vs %zd\n)",
|
||||
union_desc->bLength, sizeof(*union_desc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buflen -= union_desc->bLength;
|
||||
|
|
|
@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse,
|
|||
.sensor_pdata = {
|
||||
.sensor_type = rmi_sensor_touchpad,
|
||||
.axis_align.flip_y = true,
|
||||
/* to prevent cursors jumps: */
|
||||
.kernel_tracking = true,
|
||||
.kernel_tracking = false,
|
||||
.topbuttonpad = topbuttonpad,
|
||||
},
|
||||
.f30_data = {
|
||||
|
|
|
@ -72,6 +72,9 @@ struct goodix_ts_data {
|
|||
#define GOODIX_REG_CONFIG_DATA 0x8047
|
||||
#define GOODIX_REG_ID 0x8140
|
||||
|
||||
#define GOODIX_BUFFER_STATUS_READY BIT(7)
|
||||
#define GOODIX_BUFFER_STATUS_TIMEOUT 20
|
||||
|
||||
#define RESOLUTION_LOC 1
|
||||
#define MAX_CONTACTS_LOC 5
|
||||
#define TRIGGER_LOC 6
|
||||
|
@ -195,35 +198,53 @@ static int goodix_get_cfg_len(u16 id)
|
|||
|
||||
static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
||||
{
|
||||
unsigned long max_timeout;
|
||||
int touch_num;
|
||||
int error;
|
||||
|
||||
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data,
|
||||
GOODIX_CONTACT_SIZE + 1);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!(data[0] & 0x80))
|
||||
return -EAGAIN;
|
||||
|
||||
touch_num = data[0] & 0x0f;
|
||||
if (touch_num > ts->max_touch_num)
|
||||
return -EPROTO;
|
||||
|
||||
if (touch_num > 1) {
|
||||
data += 1 + GOODIX_CONTACT_SIZE;
|
||||
error = goodix_i2c_read(ts->client,
|
||||
GOODIX_READ_COOR_ADDR +
|
||||
1 + GOODIX_CONTACT_SIZE,
|
||||
data,
|
||||
GOODIX_CONTACT_SIZE * (touch_num - 1));
|
||||
if (error)
|
||||
/*
|
||||
* The 'buffer status' bit, which indicates that the data is valid, is
|
||||
* not set as soon as the interrupt is raised, but slightly after.
|
||||
* This takes around 10 ms to happen, so we poll for 20 ms.
|
||||
*/
|
||||
max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
|
||||
do {
|
||||
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
|
||||
data, GOODIX_CONTACT_SIZE + 1);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev, "I2C transfer error: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return touch_num;
|
||||
if (data[0] & GOODIX_BUFFER_STATUS_READY) {
|
||||
touch_num = data[0] & 0x0f;
|
||||
if (touch_num > ts->max_touch_num)
|
||||
return -EPROTO;
|
||||
|
||||
if (touch_num > 1) {
|
||||
data += 1 + GOODIX_CONTACT_SIZE;
|
||||
error = goodix_i2c_read(ts->client,
|
||||
GOODIX_READ_COOR_ADDR +
|
||||
1 + GOODIX_CONTACT_SIZE,
|
||||
data,
|
||||
GOODIX_CONTACT_SIZE *
|
||||
(touch_num - 1));
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return touch_num;
|
||||
}
|
||||
|
||||
usleep_range(1000, 2000); /* Poll every 1 - 2 ms */
|
||||
} while (time_before(jiffies, max_timeout));
|
||||
|
||||
/*
|
||||
* The Goodix panel will send spurious interrupts after a
|
||||
* 'finger up' event, which will always cause a timeout.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
||||
|
|
|
@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_client *client,
|
|||
sdata->input->open = stmfts_input_open;
|
||||
sdata->input->close = stmfts_input_close;
|
||||
|
||||
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
|
||||
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
|
||||
touchscreen_parse_properties(sdata->input, true, &sdata->prop);
|
||||
|
||||
input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
|
||||
sdata->prop.max_x, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
|
||||
sdata->prop.max_y, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
|
||||
|
|
|
@ -161,7 +161,7 @@ static void titsc_step_config(struct titsc *ts_dev)
|
|||
break;
|
||||
case 5:
|
||||
config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
|
||||
ts_dev->bit_xn | ts_dev->bit_yp;
|
||||
STEPCONFIG_XNP | STEPCONFIG_YPN;
|
||||
break;
|
||||
case 8:
|
||||
config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
|
||||
|
|
|
@ -107,6 +107,10 @@ struct its_node {
|
|||
|
||||
#define ITS_ITT_ALIGN SZ_256
|
||||
|
||||
/* The maximum number of VPEID bits supported by VLPI commands */
|
||||
#define ITS_MAX_VPEID_BITS (16)
|
||||
#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS))
|
||||
|
||||
/* Convert page order to size in bytes */
|
||||
#define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o))
|
||||
|
||||
|
@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
|
|||
|
||||
static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
|
||||
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
|
||||
}
|
||||
|
||||
static void its_encode_valid(struct its_cmd_block *cmd, int valid)
|
||||
|
@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
|
|||
|
||||
static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
|
||||
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
|
||||
}
|
||||
|
||||
static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
|
||||
|
@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
|
|||
|
||||
static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
|
||||
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
|
||||
}
|
||||
|
||||
static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
|
||||
|
@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
|||
u64 val = its_read_baser(its, baser);
|
||||
u64 esz = GITS_BASER_ENTRY_SIZE(val);
|
||||
u64 type = GITS_BASER_TYPE(val);
|
||||
u64 baser_phys, tmp;
|
||||
u32 alloc_pages;
|
||||
void *base;
|
||||
u64 tmp;
|
||||
|
||||
retry_alloc_baser:
|
||||
alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
|
||||
|
@ -1496,8 +1500,24 @@ retry_alloc_baser:
|
|||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
baser_phys = virt_to_phys(base);
|
||||
|
||||
/* Check if the physical address of the memory is above 48bits */
|
||||
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
|
||||
|
||||
/* 52bit PA is supported only when PageSize=64K */
|
||||
if (psz != SZ_64K) {
|
||||
pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
|
||||
free_pages((unsigned long)base, order);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Convert 52bit PA to 48bit field */
|
||||
baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
|
||||
}
|
||||
|
||||
retry_baser:
|
||||
val = (virt_to_phys(base) |
|
||||
val = (baser_phys |
|
||||
(type << GITS_BASER_TYPE_SHIFT) |
|
||||
((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
|
||||
((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) |
|
||||
|
@ -1582,13 +1602,12 @@ retry_baser:
|
|||
|
||||
static bool its_parse_indirect_baser(struct its_node *its,
|
||||
struct its_baser *baser,
|
||||
u32 psz, u32 *order)
|
||||
u32 psz, u32 *order, u32 ids)
|
||||
{
|
||||
u64 tmp = its_read_baser(its, baser);
|
||||
u64 type = GITS_BASER_TYPE(tmp);
|
||||
u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
|
||||
u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
|
||||
u32 ids = its->device_ids;
|
||||
u32 new_order = *order;
|
||||
bool indirect = false;
|
||||
|
||||
|
@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its)
|
|||
continue;
|
||||
|
||||
case GITS_BASER_TYPE_DEVICE:
|
||||
indirect = its_parse_indirect_baser(its, baser,
|
||||
psz, &order,
|
||||
its->device_ids);
|
||||
case GITS_BASER_TYPE_VCPU:
|
||||
indirect = its_parse_indirect_baser(its, baser,
|
||||
psz, &order);
|
||||
psz, &order,
|
||||
ITS_MAX_VPEID_BITS);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = {
|
|||
|
||||
static int its_vpe_id_alloc(void)
|
||||
{
|
||||
return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
|
||||
return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void its_vpe_id_free(u16 id)
|
||||
|
@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
BUG_ON(entries != vpe_proxy.dev->nr_ites);
|
||||
BUG_ON(entries > vpe_proxy.dev->nr_ites);
|
||||
|
||||
raw_spin_lock_init(&vpe_proxy.lock);
|
||||
vpe_proxy.next_victim = 0;
|
||||
|
|
|
@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc,
|
|||
for (i = 0; i < 2; i++) {
|
||||
ct[i].chip.irq_ack = irq_gc_ack_set_bit;
|
||||
ct[i].chip.irq_mask = irq_gc_mask_disable_reg;
|
||||
ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack;
|
||||
ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set;
|
||||
ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg;
|
||||
ct[i].chip.irq_set_type = tangox_irq_set_type;
|
||||
ct[i].chip.name = gc->domain->name;
|
||||
|
|
|
@ -1797,12 +1797,19 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
*/
|
||||
switch (msg->msg[1]) {
|
||||
case CEC_MSG_GET_CEC_VERSION:
|
||||
case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
|
||||
case CEC_MSG_ABORT:
|
||||
case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
|
||||
case CEC_MSG_GIVE_PHYSICAL_ADDR:
|
||||
case CEC_MSG_GIVE_OSD_NAME:
|
||||
/*
|
||||
* These messages reply with a directed message, so ignore if
|
||||
* the initiator is Unregistered.
|
||||
*/
|
||||
if (!adap->passthrough && from_unregistered)
|
||||
return 0;
|
||||
/* Fall through */
|
||||
case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
|
||||
case CEC_MSG_GIVE_FEATURES:
|
||||
case CEC_MSG_GIVE_PHYSICAL_ADDR:
|
||||
/*
|
||||
* Skip processing these messages if the passthrough mode
|
||||
* is on.
|
||||
|
@ -1810,7 +1817,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
if (adap->passthrough)
|
||||
goto skip_processing;
|
||||
/* Ignore if addressing is wrong */
|
||||
if (is_broadcast || from_unregistered)
|
||||
if (is_broadcast)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
|
|
|
@ -141,22 +141,39 @@ struct dvb_frontend_private {
|
|||
static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
|
||||
void (*release)(struct dvb_frontend *fe));
|
||||
|
||||
static void dvb_frontend_free(struct kref *ref)
|
||||
static void __dvb_frontend_free(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dvb_frontend *fe =
|
||||
container_of(ref, struct dvb_frontend, refcount);
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
|
||||
if (!fepriv)
|
||||
return;
|
||||
|
||||
dvb_free_device(fepriv->dvbdev);
|
||||
|
||||
dvb_frontend_invoke_release(fe, fe->ops.release);
|
||||
|
||||
kfree(fepriv);
|
||||
fe->frontend_priv = NULL;
|
||||
}
|
||||
|
||||
static void dvb_frontend_free(struct kref *ref)
|
||||
{
|
||||
struct dvb_frontend *fe =
|
||||
container_of(ref, struct dvb_frontend, refcount);
|
||||
|
||||
__dvb_frontend_free(fe);
|
||||
}
|
||||
|
||||
static void dvb_frontend_put(struct dvb_frontend *fe)
|
||||
{
|
||||
kref_put(&fe->refcount, dvb_frontend_free);
|
||||
/*
|
||||
* Check if the frontend was registered, as otherwise
|
||||
* kref was not initialized yet.
|
||||
*/
|
||||
if (fe->frontend_priv)
|
||||
kref_put(&fe->refcount, dvb_frontend_free);
|
||||
else
|
||||
__dvb_frontend_free(fe);
|
||||
}
|
||||
|
||||
static void dvb_frontend_get(struct dvb_frontend *fe)
|
||||
|
|
|
@ -55,29 +55,57 @@ struct dib3000mc_state {
|
|||
|
||||
static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
|
||||
{
|
||||
u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
|
||||
u8 rb[2];
|
||||
struct i2c_msg msg[2] = {
|
||||
{ .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
|
||||
{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
|
||||
{ .addr = state->i2c_addr >> 1, .flags = 0, .len = 2 },
|
||||
{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .len = 2 },
|
||||
};
|
||||
u16 word;
|
||||
u8 *b;
|
||||
|
||||
b = kmalloc(4, GFP_KERNEL);
|
||||
if (!b)
|
||||
return 0;
|
||||
|
||||
b[0] = (reg >> 8) | 0x80;
|
||||
b[1] = reg;
|
||||
b[2] = 0;
|
||||
b[3] = 0;
|
||||
|
||||
msg[0].buf = b;
|
||||
msg[1].buf = b + 2;
|
||||
|
||||
if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
|
||||
dprintk("i2c read error on %d\n",reg);
|
||||
|
||||
return (rb[0] << 8) | rb[1];
|
||||
word = (b[2] << 8) | b[3];
|
||||
kfree(b);
|
||||
|
||||
return word;
|
||||
}
|
||||
|
||||
static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
|
||||
{
|
||||
u8 b[4] = {
|
||||
(reg >> 8) & 0xff, reg & 0xff,
|
||||
(val >> 8) & 0xff, val & 0xff,
|
||||
};
|
||||
struct i2c_msg msg = {
|
||||
.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
|
||||
.addr = state->i2c_addr >> 1, .flags = 0, .len = 4
|
||||
};
|
||||
return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
|
||||
int rc;
|
||||
u8 *b;
|
||||
|
||||
b = kmalloc(4, GFP_KERNEL);
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
|
||||
b[0] = reg >> 8;
|
||||
b[1] = reg;
|
||||
b[2] = val >> 8;
|
||||
b[3] = val;
|
||||
|
||||
msg.buf = b;
|
||||
|
||||
rc = i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
|
||||
kfree(b);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dib3000mc_identify(struct dib3000mc_state *state)
|
||||
|
|
|
@ -753,13 +753,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
|
|||
struct i2c_adapter *i2c,
|
||||
unsigned int pll_desc_id)
|
||||
{
|
||||
u8 b1 [] = { 0 };
|
||||
struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
|
||||
.buf = b1, .len = 1 };
|
||||
u8 *b1;
|
||||
struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .len = 1 };
|
||||
struct dvb_pll_priv *priv = NULL;
|
||||
int ret;
|
||||
const struct dvb_pll_desc *desc;
|
||||
|
||||
b1 = kmalloc(1, GFP_KERNEL);
|
||||
if (!b1)
|
||||
return NULL;
|
||||
|
||||
b1[0] = 0;
|
||||
msg.buf = b1;
|
||||
|
||||
if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
|
||||
(id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
|
||||
pll_desc_id = id[dvb_pll_devcount];
|
||||
|
@ -773,15 +779,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
|
|||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
ret = i2c_transfer (i2c, &msg, 1);
|
||||
if (ret != 1)
|
||||
if (ret != 1) {
|
||||
kfree(b1);
|
||||
return NULL;
|
||||
}
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
}
|
||||
|
||||
priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
if (!priv) {
|
||||
kfree(b1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
priv->pll_i2c_address = pll_addr;
|
||||
priv->i2c = i2c;
|
||||
|
@ -811,6 +821,8 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
|
|||
"insmod option" : "autodetected");
|
||||
}
|
||||
|
||||
kfree(b1);
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_pll_attach);
|
||||
|
|
|
@ -112,7 +112,7 @@ config VIDEO_PXA27x
|
|||
|
||||
config VIDEO_QCOM_CAMSS
|
||||
tristate "Qualcomm 8x16 V4L2 Camera Subsystem driver"
|
||||
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
|
||||
depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
|
||||
select VIDEOBUF2_DMA_SG
|
||||
select V4L2_FWNODE
|
||||
|
|
|
@ -2660,7 +2660,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd,
|
|||
*
|
||||
* Return -EINVAL or zero on success
|
||||
*/
|
||||
int vfe_set_selection(struct v4l2_subdev *sd,
|
||||
static int vfe_set_selection(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_selection *sel)
|
||||
{
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче