mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge tag 'v5.4.274' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroid-5.4.y
This is the 5.4.274 stable release Change-Id: Ib2138240a9a1c66f3974b971e9bd15902b3b7f7e
This commit is contained in:
@@ -484,11 +484,14 @@ Spectre variant 2
|
||||
|
||||
Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
|
||||
boot, by setting the IBRS bit, and they're automatically protected against
|
||||
Spectre v2 variant attacks, including cross-thread branch target injections
|
||||
on SMT systems (STIBP). In other words, eIBRS enables STIBP too.
|
||||
Spectre v2 variant attacks.
|
||||
|
||||
Legacy IBRS systems clear the IBRS bit on exit to userspace and
|
||||
therefore explicitly enable STIBP for that
|
||||
On Intel's enhanced IBRS systems, this includes cross-thread branch target
|
||||
injections on SMT systems (STIBP). In other words, Intel eIBRS enables
|
||||
STIBP, too.
|
||||
|
||||
AMD Automatic IBRS does not protect userspace, and Legacy IBRS systems clear
|
||||
the IBRS bit on exit to userspace, therefore both explicitly enable STIBP.
|
||||
|
||||
The retpoline mitigation is turned on by default on vulnerable
|
||||
CPUs. It can be forced on or off by the administrator
|
||||
@@ -622,9 +625,10 @@ kernel command line.
|
||||
retpoline,generic Retpolines
|
||||
retpoline,lfence LFENCE; indirect branch
|
||||
retpoline,amd alias for retpoline,lfence
|
||||
eibrs enhanced IBRS
|
||||
eibrs,retpoline enhanced IBRS + Retpolines
|
||||
eibrs,lfence enhanced IBRS + LFENCE
|
||||
eibrs Enhanced/Auto IBRS
|
||||
eibrs,retpoline Enhanced/Auto IBRS + Retpolines
|
||||
eibrs,lfence Enhanced/Auto IBRS + LFENCE
|
||||
ibrs use IBRS to protect kernel
|
||||
|
||||
Not specifying this option is equivalent to
|
||||
spectre_v2=auto.
|
||||
|
||||
@@ -4600,9 +4600,9 @@
|
||||
retpoline,generic - Retpolines
|
||||
retpoline,lfence - LFENCE; indirect branch
|
||||
retpoline,amd - alias for retpoline,lfence
|
||||
eibrs - enhanced IBRS
|
||||
eibrs,retpoline - enhanced IBRS + Retpolines
|
||||
eibrs,lfence - enhanced IBRS + LFENCE
|
||||
eibrs - Enhanced/Auto IBRS
|
||||
eibrs,retpoline - Enhanced/Auto IBRS + Retpolines
|
||||
eibrs,lfence - Enhanced/Auto IBRS + LFENCE
|
||||
ibrs - use IBRS to protect kernel
|
||||
|
||||
Not specifying this option is equivalent to
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 273
|
||||
SUBLEVEL = 274
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
|
||||
@@ -19,176 +19,174 @@
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x08000000>;
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
apb@d4000000 {
|
||||
uart3: uart@d4018000 {
|
||||
status = "okay";
|
||||
};
|
||||
twsi1: i2c@d4011000 {
|
||||
status = "okay";
|
||||
pmic: max8925@3c {
|
||||
compatible = "maxium,max8925";
|
||||
reg = <0x3c>;
|
||||
interrupts = <1>;
|
||||
interrupt-parent = <&intcmux4>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
maxim,tsc-irq = <0>;
|
||||
&uart3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
regulators {
|
||||
SDV1 {
|
||||
regulator-min-microvolt = <637500>;
|
||||
regulator-max-microvolt = <1425000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
SDV2 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2225000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
SDV3 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO1 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO2 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO3 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO4 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO5 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO6 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO7 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO8 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO9 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO10 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
};
|
||||
LDO11 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO12 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO13 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO14 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO15 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO16 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO17 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO18 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO19 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO20 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
backlight {
|
||||
maxim,max8925-dual-string = <0>;
|
||||
};
|
||||
charger {
|
||||
batt-detect = <0>;
|
||||
topoff-threshold = <1>;
|
||||
fast-charge = <7>;
|
||||
no-temp-support = <0>;
|
||||
no-insert-detect = <0>;
|
||||
};
|
||||
};
|
||||
&twsi1 {
|
||||
status = "okay";
|
||||
pmic: max8925@3c {
|
||||
compatible = "maxim,max8925";
|
||||
reg = <0x3c>;
|
||||
interrupts = <1>;
|
||||
interrupt-parent = <&intcmux4>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
maxim,tsc-irq = <0>;
|
||||
|
||||
regulators {
|
||||
SDV1 {
|
||||
regulator-min-microvolt = <637500>;
|
||||
regulator-max-microvolt = <1425000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
rtc: rtc@d4010000 {
|
||||
status = "okay";
|
||||
SDV2 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2225000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
SDV3 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO1 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO2 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO3 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO4 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO5 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO6 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO7 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO8 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO9 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO10 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
};
|
||||
LDO11 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO12 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO13 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO14 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO15 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO16 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO17 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO18 {
|
||||
regulator-min-microvolt = <650000>;
|
||||
regulator-max-microvolt = <2250000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO19 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
LDO20 {
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <3900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
backlight {
|
||||
maxim,max8925-dual-string = <0>;
|
||||
};
|
||||
charger {
|
||||
batt-detect = <0>;
|
||||
topoff-threshold = <1>;
|
||||
fast-charge = <7>;
|
||||
no-temp-support = <0>;
|
||||
no-insert-detect = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&rtc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -684,11 +684,20 @@
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
hdmi_in: port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
hdmi_in: port@0 {
|
||||
reg = <0>;
|
||||
|
||||
hdmi_in_vop: endpoint {
|
||||
remote-endpoint = <&vop_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
hdmi_out: port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1743,6 +1743,7 @@
|
||||
hdmi: hdmi@ff940000 {
|
||||
compatible = "rockchip,rk3399-dw-hdmi";
|
||||
reg = <0x0 0xff940000 0x0 0x20000>;
|
||||
reg-io-width = <4>;
|
||||
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
clocks = <&cru PCLK_HDMI_CTRL>,
|
||||
<&cru SCLK_HDMI_SFR>,
|
||||
@@ -1751,13 +1752,16 @@
|
||||
<&cru PLL_VPLL>;
|
||||
clock-names = "iahb", "isfr", "cec", "grf", "vpll";
|
||||
power-domains = <&power RK3399_PD_HDCP>;
|
||||
reg-io-width = <4>;
|
||||
rockchip,grf = <&grf>;
|
||||
#sound-dai-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
hdmi_in: port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
hdmi_in: port@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@@ -1770,6 +1774,10 @@
|
||||
remote-endpoint = <&vopl_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
hdmi_out: port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -42,31 +42,32 @@ extern __wsum csum_partial_copy_from_user(const void __user *src,
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
unsigned int sum;
|
||||
unsigned long t0, t1, t2;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" ldws,ma 4(%1), %0\n"
|
||||
" addib,<= -4, %2, 2f\n"
|
||||
"\n"
|
||||
" ldws 4(%1), %%r20\n"
|
||||
" ldws 8(%1), %%r21\n"
|
||||
" add %0, %%r20, %0\n"
|
||||
" ldws,ma 12(%1), %%r19\n"
|
||||
" addc %0, %%r21, %0\n"
|
||||
" addc %0, %%r19, %0\n"
|
||||
"1: ldws,ma 4(%1), %%r19\n"
|
||||
" addib,< 0, %2, 1b\n"
|
||||
" addc %0, %%r19, %0\n"
|
||||
" ldws 4(%1), %4\n"
|
||||
" ldws 8(%1), %5\n"
|
||||
" add %0, %4, %0\n"
|
||||
" ldws,ma 12(%1), %3\n"
|
||||
" addc %0, %5, %0\n"
|
||||
" addc %0, %3, %0\n"
|
||||
"1: ldws,ma 4(%1), %3\n"
|
||||
" addib,> -1, %2, 1b\n"
|
||||
" addc %0, %3, %0\n"
|
||||
"\n"
|
||||
" extru %0, 31, 16, %%r20\n"
|
||||
" extru %0, 15, 16, %%r21\n"
|
||||
" addc %%r20, %%r21, %0\n"
|
||||
" extru %0, 15, 16, %%r21\n"
|
||||
" add %0, %%r21, %0\n"
|
||||
" extru %0, 31, 16, %4\n"
|
||||
" extru %0, 15, 16, %5\n"
|
||||
" addc %4, %5, %0\n"
|
||||
" extru %0, 15, 16, %5\n"
|
||||
" add %0, %5, %0\n"
|
||||
" subi -1, %0, %0\n"
|
||||
"2:\n"
|
||||
: "=r" (sum), "=r" (iph), "=r" (ihl)
|
||||
: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (t0), "=r" (t1), "=r" (t2)
|
||||
: "1" (iph), "2" (ihl)
|
||||
: "r19", "r20", "r21", "memory");
|
||||
: "memory");
|
||||
|
||||
return (__force __sum16)sum;
|
||||
}
|
||||
@@ -126,6 +127,10 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
__u32 len, __u8 proto,
|
||||
__wsum sum)
|
||||
{
|
||||
unsigned long t0, t1, t2, t3;
|
||||
|
||||
len += proto; /* add 16-bit proto + len */
|
||||
|
||||
__asm__ __volatile__ (
|
||||
|
||||
#if BITS_PER_LONG > 32
|
||||
@@ -136,20 +141,20 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
** Try to keep 4 registers with "live" values ahead of the ALU.
|
||||
*/
|
||||
|
||||
" ldd,ma 8(%1), %%r19\n" /* get 1st saddr word */
|
||||
" ldd,ma 8(%2), %%r20\n" /* get 1st daddr word */
|
||||
" add %8, %3, %3\n"/* add 16-bit proto + len */
|
||||
" add %%r19, %0, %0\n"
|
||||
" ldd,ma 8(%1), %%r21\n" /* 2cd saddr */
|
||||
" ldd,ma 8(%2), %%r22\n" /* 2cd daddr */
|
||||
" add,dc %%r20, %0, %0\n"
|
||||
" add,dc %%r21, %0, %0\n"
|
||||
" add,dc %%r22, %0, %0\n"
|
||||
" depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */
|
||||
" ldd,ma 8(%1), %4\n" /* get 1st saddr word */
|
||||
" ldd,ma 8(%2), %5\n" /* get 1st daddr word */
|
||||
" add %4, %0, %0\n"
|
||||
" ldd,ma 8(%1), %6\n" /* 2nd saddr */
|
||||
" ldd,ma 8(%2), %7\n" /* 2nd daddr */
|
||||
" add,dc %5, %0, %0\n"
|
||||
" add,dc %6, %0, %0\n"
|
||||
" add,dc %7, %0, %0\n"
|
||||
" add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */
|
||||
" extrd,u %0, 31, 32, %%r19\n" /* copy upper half down */
|
||||
" depdi 0, 31, 32, %0\n" /* clear upper half */
|
||||
" add %%r19, %0, %0\n" /* fold into 32-bits */
|
||||
" addc 0, %0, %0\n" /* add carry */
|
||||
" extrd,u %0, 31, 32, %4\n"/* copy upper half down */
|
||||
" depdi 0, 31, 32, %0\n"/* clear upper half */
|
||||
" add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */
|
||||
" addc 0, %0, %0\n" /* add final carry */
|
||||
|
||||
#else
|
||||
|
||||
@@ -158,30 +163,30 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
** Insn stream is serialized on the carry bit here too.
|
||||
** result from the previous operation (eg r0 + x)
|
||||
*/
|
||||
|
||||
" ldw,ma 4(%1), %%r19\n" /* get 1st saddr word */
|
||||
" ldw,ma 4(%2), %%r20\n" /* get 1st daddr word */
|
||||
" add %8, %3, %3\n" /* add 16-bit proto + len */
|
||||
" add %%r19, %0, %0\n"
|
||||
" ldw,ma 4(%1), %%r21\n" /* 2cd saddr */
|
||||
" addc %%r20, %0, %0\n"
|
||||
" ldw,ma 4(%2), %%r22\n" /* 2cd daddr */
|
||||
" addc %%r21, %0, %0\n"
|
||||
" ldw,ma 4(%1), %%r19\n" /* 3rd saddr */
|
||||
" addc %%r22, %0, %0\n"
|
||||
" ldw,ma 4(%2), %%r20\n" /* 3rd daddr */
|
||||
" addc %%r19, %0, %0\n"
|
||||
" ldw,ma 4(%1), %%r21\n" /* 4th saddr */
|
||||
" addc %%r20, %0, %0\n"
|
||||
" ldw,ma 4(%2), %%r22\n" /* 4th daddr */
|
||||
" addc %%r21, %0, %0\n"
|
||||
" addc %%r22, %0, %0\n"
|
||||
" addc %3, %0, %0\n" /* fold in proto+len, catch carry */
|
||||
" ldw,ma 4(%1), %4\n" /* get 1st saddr word */
|
||||
" ldw,ma 4(%2), %5\n" /* get 1st daddr word */
|
||||
" add %4, %0, %0\n"
|
||||
" ldw,ma 4(%1), %6\n" /* 2nd saddr */
|
||||
" addc %5, %0, %0\n"
|
||||
" ldw,ma 4(%2), %7\n" /* 2nd daddr */
|
||||
" addc %6, %0, %0\n"
|
||||
" ldw,ma 4(%1), %4\n" /* 3rd saddr */
|
||||
" addc %7, %0, %0\n"
|
||||
" ldw,ma 4(%2), %5\n" /* 3rd daddr */
|
||||
" addc %4, %0, %0\n"
|
||||
" ldw,ma 4(%1), %6\n" /* 4th saddr */
|
||||
" addc %5, %0, %0\n"
|
||||
" ldw,ma 4(%2), %7\n" /* 4th daddr */
|
||||
" addc %6, %0, %0\n"
|
||||
" addc %7, %0, %0\n"
|
||||
" addc %3, %0, %0\n" /* fold in proto+len */
|
||||
" addc 0, %0, %0\n" /* add carry */
|
||||
|
||||
#endif
|
||||
: "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len)
|
||||
: "0" (sum), "1" (saddr), "2" (daddr), "3" (len), "r" (proto)
|
||||
: "r19", "r20", "r21", "r22", "memory");
|
||||
: "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len),
|
||||
"=r" (t0), "=r" (t1), "=r" (t2), "=r" (t3)
|
||||
: "0" (sum), "1" (saddr), "2" (daddr), "3" (len)
|
||||
: "memory");
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,16 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
/* Performance Monitor Registers */
|
||||
#define mfpmr(rn) ({unsigned int rval; \
|
||||
asm volatile("mfpmr %0," __stringify(rn) \
|
||||
asm volatile(".machine push; " \
|
||||
".machine e300; " \
|
||||
"mfpmr %0," __stringify(rn) ";" \
|
||||
".machine pop; " \
|
||||
: "=r" (rval)); rval;})
|
||||
#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
|
||||
#define mtpmr(rn, v) asm volatile(".machine push; " \
|
||||
".machine e300; " \
|
||||
"mtpmr " __stringify(rn) ",%0; " \
|
||||
".machine pop; " \
|
||||
: : "r" (v))
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/* Freescale Book E Performance Monitor APU Registers */
|
||||
|
||||
@@ -61,6 +61,6 @@ obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
|
||||
obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
|
||||
|
||||
obj-$(CONFIG_ALTIVEC) += xor_vmx.o xor_vmx_glue.o
|
||||
CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec)
|
||||
CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec)
|
||||
|
||||
obj-$(CONFIG_PPC64) += $(obj64-y)
|
||||
|
||||
@@ -1542,6 +1542,7 @@ ENDPROC(cleanup_critical)
|
||||
.quad .Lsie_skip - .Lsie_entry
|
||||
#endif
|
||||
.section .rodata, "a"
|
||||
.balign 8
|
||||
#define SYSCALL(esame,emu) .quad __s390x_ ## esame
|
||||
.globl sys_call_table
|
||||
sys_call_table:
|
||||
|
||||
@@ -274,7 +274,7 @@ static int __init setup_nmi_watchdog(char *str)
|
||||
if (!strncmp(str, "panic", 5))
|
||||
panic_on_timeout = 1;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
__setup("nmi_watchdog=", setup_nmi_watchdog);
|
||||
|
||||
|
||||
@@ -449,9 +449,8 @@ static __init int vdso_setup(char *s)
|
||||
unsigned long val;
|
||||
|
||||
err = kstrtoul(s, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
vdso_enabled = val;
|
||||
return 0;
|
||||
if (!err)
|
||||
vdso_enabled = val;
|
||||
return 1;
|
||||
}
|
||||
__setup("vdso=", vdso_setup);
|
||||
|
||||
@@ -92,8 +92,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
|
||||
REQUIRED_MASK_CHECK || \
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 21))
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 22))
|
||||
|
||||
#define DISABLED_MASK_BIT_SET(feature_bit) \
|
||||
( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
|
||||
@@ -117,8 +118,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
|
||||
DISABLED_MASK_CHECK || \
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 21))
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 22))
|
||||
|
||||
#define cpu_has(c, bit) \
|
||||
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/*
|
||||
* Defines x86 CPU feature bits
|
||||
*/
|
||||
#define NCAPINTS 21 /* N 32-bit words worth of info */
|
||||
#define NCAPINTS 22 /* N 32-bit words worth of info */
|
||||
#define NBUGINTS 2 /* N 32-bit bug flags */
|
||||
|
||||
/*
|
||||
@@ -382,6 +382,8 @@
|
||||
#define X86_FEATURE_SEV_ES (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */
|
||||
#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */
|
||||
|
||||
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */
|
||||
|
||||
/*
|
||||
* BUG word(s)
|
||||
*/
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#define DISABLED_MASK18 0
|
||||
#define DISABLED_MASK19 0
|
||||
#define DISABLED_MASK20 0
|
||||
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
|
||||
#define DISABLED_MASK21 0
|
||||
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
|
||||
|
||||
#endif /* _ASM_X86_DISABLED_FEATURES_H */
|
||||
|
||||
@@ -379,6 +379,15 @@ static inline temp_mm_state_t use_temporary_mm(struct mm_struct *mm)
|
||||
temp_mm_state_t temp_state;
|
||||
|
||||
lockdep_assert_irqs_disabled();
|
||||
|
||||
/*
|
||||
* Make sure not to be in TLB lazy mode, as otherwise we'll end up
|
||||
* with a stale address space WITHOUT being in lazy mode after
|
||||
* restoring the previous mm.
|
||||
*/
|
||||
if (this_cpu_read(cpu_tlbstate.is_lazy))
|
||||
leave_mm(smp_processor_id());
|
||||
|
||||
temp_state.mm = this_cpu_read(cpu_tlbstate.loaded_mm);
|
||||
switch_mm_irqs_off(NULL, mm, current);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define _EFER_SVME 12 /* Enable virtualization */
|
||||
#define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */
|
||||
#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */
|
||||
#define _EFER_AUTOIBRS 21 /* Enable Automatic IBRS */
|
||||
|
||||
#define EFER_SCE (1<<_EFER_SCE)
|
||||
#define EFER_LME (1<<_EFER_LME)
|
||||
@@ -38,6 +39,7 @@
|
||||
#define EFER_SVME (1<<_EFER_SVME)
|
||||
#define EFER_LMSLE (1<<_EFER_LMSLE)
|
||||
#define EFER_FFXSR (1<<_EFER_FFXSR)
|
||||
#define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS)
|
||||
|
||||
/* Intel MSRs. Some also available on other CPUs */
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <asm/unwind_hints.h>
|
||||
#include <asm/percpu.h>
|
||||
|
||||
#include <linux/frame.h>
|
||||
#include <asm/unwind_hints.h>
|
||||
/*
|
||||
* This should be used immediately before a retpoline alternative. It tells
|
||||
* objtool where the retpolines are so that it can make sense of the control
|
||||
@@ -51,14 +53,18 @@
|
||||
#define __FILL_RETURN_BUFFER(reg, nr, sp) \
|
||||
mov $(nr/2), reg; \
|
||||
771: \
|
||||
ANNOTATE_INTRA_FUNCTION_CALL; \
|
||||
call 772f; \
|
||||
773: /* speculation trap */ \
|
||||
UNWIND_HINT_EMPTY; \
|
||||
pause; \
|
||||
lfence; \
|
||||
jmp 773b; \
|
||||
772: \
|
||||
ANNOTATE_INTRA_FUNCTION_CALL; \
|
||||
call 774f; \
|
||||
775: /* speculation trap */ \
|
||||
UNWIND_HINT_EMPTY; \
|
||||
pause; \
|
||||
lfence; \
|
||||
jmp 775b; \
|
||||
@@ -152,6 +158,7 @@
|
||||
.endm
|
||||
|
||||
.macro ISSUE_UNBALANCED_RET_GUARD
|
||||
ANNOTATE_INTRA_FUNCTION_CALL;
|
||||
call .Lunbalanced_ret_guard_\@
|
||||
int3
|
||||
.Lunbalanced_ret_guard_\@:
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
#define REQUIRED_MASK18 0
|
||||
#define REQUIRED_MASK19 0
|
||||
#define REQUIRED_MASK20 0
|
||||
#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
|
||||
#define REQUIRED_MASK21 0
|
||||
#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
|
||||
|
||||
#endif /* _ASM_X86_REQUIRED_FEATURES_H */
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
".popsection\n\t"
|
||||
|
||||
#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE, 0)
|
||||
|
||||
#define UNWIND_HINT_EMPTY
|
||||
#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE, 0)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
@@ -998,11 +998,11 @@ static bool cpu_has_zenbleed_microcode(void)
|
||||
u32 good_rev = 0;
|
||||
|
||||
switch (boot_cpu_data.x86_model) {
|
||||
case 0x30 ... 0x3f: good_rev = 0x0830107a; break;
|
||||
case 0x60 ... 0x67: good_rev = 0x0860010b; break;
|
||||
case 0x68 ... 0x6f: good_rev = 0x08608105; break;
|
||||
case 0x70 ... 0x7f: good_rev = 0x08701032; break;
|
||||
case 0xa0 ... 0xaf: good_rev = 0x08a00008; break;
|
||||
case 0x30 ... 0x3f: good_rev = 0x0830107b; break;
|
||||
case 0x60 ... 0x67: good_rev = 0x0860010c; break;
|
||||
case 0x68 ... 0x6f: good_rev = 0x08608107; break;
|
||||
case 0x70 ... 0x7f: good_rev = 0x08701033; break;
|
||||
case 0xa0 ... 0xaf: good_rev = 0x08a00009; break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -1153,19 +1153,21 @@ spectre_v2_user_select_mitigation(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP
|
||||
* If no STIBP, Intel enhanced IBRS is enabled, or SMT impossible, STIBP
|
||||
* is not required.
|
||||
*
|
||||
* Enhanced IBRS also protects against cross-thread branch target
|
||||
* Intel's Enhanced IBRS also protects against cross-thread branch target
|
||||
* injection in user-mode as the IBRS bit remains always set which
|
||||
* implicitly enables cross-thread protections. However, in legacy IBRS
|
||||
* mode, the IBRS bit is set only on kernel entry and cleared on return
|
||||
* to userspace. This disables the implicit cross-thread protection,
|
||||
* so allow for STIBP to be selected in that case.
|
||||
* to userspace. AMD Automatic IBRS also does not protect userspace.
|
||||
* These modes therefore disable the implicit cross-thread protection,
|
||||
* so allow for STIBP to be selected in those cases.
|
||||
*/
|
||||
if (!boot_cpu_has(X86_FEATURE_STIBP) ||
|
||||
!smt_possible ||
|
||||
spectre_v2_in_eibrs_mode(spectre_v2_enabled))
|
||||
(spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
|
||||
!boot_cpu_has(X86_FEATURE_AUTOIBRS)))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -1187,9 +1189,9 @@ static const char * const spectre_v2_strings[] = {
|
||||
[SPECTRE_V2_NONE] = "Vulnerable",
|
||||
[SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines",
|
||||
[SPECTRE_V2_LFENCE] = "Mitigation: LFENCE",
|
||||
[SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS",
|
||||
[SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE",
|
||||
[SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines",
|
||||
[SPECTRE_V2_EIBRS] = "Mitigation: Enhanced / Automatic IBRS",
|
||||
[SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced / Automatic IBRS + LFENCE",
|
||||
[SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced / Automatic IBRS + Retpolines",
|
||||
[SPECTRE_V2_IBRS] = "Mitigation: IBRS",
|
||||
};
|
||||
|
||||
@@ -1258,7 +1260,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
|
||||
cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
|
||||
cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
|
||||
!boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) {
|
||||
pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n",
|
||||
pr_err("%s selected but CPU doesn't have Enhanced or Automatic IBRS. Switching to AUTO select\n",
|
||||
mitigation_options[i].option);
|
||||
return SPECTRE_V2_CMD_AUTO;
|
||||
}
|
||||
@@ -1436,8 +1438,12 @@ static void __init spectre_v2_select_mitigation(void)
|
||||
pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
|
||||
|
||||
if (spectre_v2_in_ibrs_mode(mode)) {
|
||||
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
|
||||
update_spec_ctrl(x86_spec_ctrl_base);
|
||||
if (boot_cpu_has(X86_FEATURE_AUTOIBRS)) {
|
||||
msr_set_bit(MSR_EFER, _EFER_AUTOIBRS);
|
||||
} else {
|
||||
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
|
||||
update_spec_ctrl(x86_spec_ctrl_base);
|
||||
}
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
@@ -1521,8 +1527,8 @@ static void __init spectre_v2_select_mitigation(void)
|
||||
/*
|
||||
* Retpoline protects the kernel, but doesn't protect firmware. IBRS
|
||||
* and Enhanced IBRS protect firmware too, so enable IBRS around
|
||||
* firmware calls only when IBRS / Enhanced IBRS aren't otherwise
|
||||
* enabled.
|
||||
* firmware calls only when IBRS / Enhanced / Automatic IBRS aren't
|
||||
* otherwise enabled.
|
||||
*
|
||||
* Use "mode" to check Enhanced IBRS instead of boot_cpu_has(), because
|
||||
* the user might select retpoline on the kernel command line and if
|
||||
@@ -2144,69 +2150,69 @@ static const char * const l1tf_vmx_states[] = {
|
||||
static ssize_t l1tf_show_state(char *buf)
|
||||
{
|
||||
if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_AUTO)
|
||||
return sprintf(buf, "%s\n", L1TF_DEFAULT_MSG);
|
||||
return sysfs_emit(buf, "%s\n", L1TF_DEFAULT_MSG);
|
||||
|
||||
if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_EPT_DISABLED ||
|
||||
(l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_NEVER &&
|
||||
sched_smt_active())) {
|
||||
return sprintf(buf, "%s; VMX: %s\n", L1TF_DEFAULT_MSG,
|
||||
l1tf_vmx_states[l1tf_vmx_mitigation]);
|
||||
return sysfs_emit(buf, "%s; VMX: %s\n", L1TF_DEFAULT_MSG,
|
||||
l1tf_vmx_states[l1tf_vmx_mitigation]);
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s; VMX: %s, SMT %s\n", L1TF_DEFAULT_MSG,
|
||||
l1tf_vmx_states[l1tf_vmx_mitigation],
|
||||
sched_smt_active() ? "vulnerable" : "disabled");
|
||||
return sysfs_emit(buf, "%s; VMX: %s, SMT %s\n", L1TF_DEFAULT_MSG,
|
||||
l1tf_vmx_states[l1tf_vmx_mitigation],
|
||||
sched_smt_active() ? "vulnerable" : "disabled");
|
||||
}
|
||||
|
||||
static ssize_t itlb_multihit_show_state(char *buf)
|
||||
{
|
||||
if (itlb_multihit_kvm_mitigation)
|
||||
return sprintf(buf, "KVM: Mitigation: Split huge pages\n");
|
||||
return sysfs_emit(buf, "KVM: Mitigation: Split huge pages\n");
|
||||
else
|
||||
return sprintf(buf, "KVM: Vulnerable\n");
|
||||
return sysfs_emit(buf, "KVM: Vulnerable\n");
|
||||
}
|
||||
#else
|
||||
static ssize_t l1tf_show_state(char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", L1TF_DEFAULT_MSG);
|
||||
return sysfs_emit(buf, "%s\n", L1TF_DEFAULT_MSG);
|
||||
}
|
||||
|
||||
static ssize_t itlb_multihit_show_state(char *buf)
|
||||
{
|
||||
return sprintf(buf, "Processor vulnerable\n");
|
||||
return sysfs_emit(buf, "Processor vulnerable\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t mds_show_state(char *buf)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
|
||||
return sprintf(buf, "%s; SMT Host state unknown\n",
|
||||
mds_strings[mds_mitigation]);
|
||||
return sysfs_emit(buf, "%s; SMT Host state unknown\n",
|
||||
mds_strings[mds_mitigation]);
|
||||
}
|
||||
|
||||
if (boot_cpu_has(X86_BUG_MSBDS_ONLY)) {
|
||||
return sprintf(buf, "%s; SMT %s\n", mds_strings[mds_mitigation],
|
||||
(mds_mitigation == MDS_MITIGATION_OFF ? "vulnerable" :
|
||||
sched_smt_active() ? "mitigated" : "disabled"));
|
||||
return sysfs_emit(buf, "%s; SMT %s\n", mds_strings[mds_mitigation],
|
||||
(mds_mitigation == MDS_MITIGATION_OFF ? "vulnerable" :
|
||||
sched_smt_active() ? "mitigated" : "disabled"));
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s; SMT %s\n", mds_strings[mds_mitigation],
|
||||
sched_smt_active() ? "vulnerable" : "disabled");
|
||||
return sysfs_emit(buf, "%s; SMT %s\n", mds_strings[mds_mitigation],
|
||||
sched_smt_active() ? "vulnerable" : "disabled");
|
||||
}
|
||||
|
||||
static ssize_t tsx_async_abort_show_state(char *buf)
|
||||
{
|
||||
if ((taa_mitigation == TAA_MITIGATION_TSX_DISABLED) ||
|
||||
(taa_mitigation == TAA_MITIGATION_OFF))
|
||||
return sprintf(buf, "%s\n", taa_strings[taa_mitigation]);
|
||||
return sysfs_emit(buf, "%s\n", taa_strings[taa_mitigation]);
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
|
||||
return sprintf(buf, "%s; SMT Host state unknown\n",
|
||||
taa_strings[taa_mitigation]);
|
||||
return sysfs_emit(buf, "%s; SMT Host state unknown\n",
|
||||
taa_strings[taa_mitigation]);
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s; SMT %s\n", taa_strings[taa_mitigation],
|
||||
sched_smt_active() ? "vulnerable" : "disabled");
|
||||
return sysfs_emit(buf, "%s; SMT %s\n", taa_strings[taa_mitigation],
|
||||
sched_smt_active() ? "vulnerable" : "disabled");
|
||||
}
|
||||
|
||||
static ssize_t mmio_stale_data_show_state(char *buf)
|
||||
@@ -2228,7 +2234,8 @@ static ssize_t mmio_stale_data_show_state(char *buf)
|
||||
|
||||
static char *stibp_state(void)
|
||||
{
|
||||
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
|
||||
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
|
||||
!boot_cpu_has(X86_FEATURE_AUTOIBRS))
|
||||
return "";
|
||||
|
||||
switch (spectre_v2_user_stibp) {
|
||||
@@ -2274,33 +2281,33 @@ static char *pbrsb_eibrs_state(void)
|
||||
static ssize_t spectre_v2_show_state(char *buf)
|
||||
{
|
||||
if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
|
||||
return sprintf(buf, "Vulnerable: LFENCE\n");
|
||||
return sysfs_emit(buf, "Vulnerable: LFENCE\n");
|
||||
|
||||
if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
|
||||
return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n");
|
||||
return sysfs_emit(buf, "Vulnerable: eIBRS with unprivileged eBPF\n");
|
||||
|
||||
if (sched_smt_active() && unprivileged_ebpf_enabled() &&
|
||||
spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
|
||||
return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
|
||||
return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
|
||||
|
||||
return sprintf(buf, "%s%s%s%s%s%s%s\n",
|
||||
spectre_v2_strings[spectre_v2_enabled],
|
||||
ibpb_state(),
|
||||
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
|
||||
stibp_state(),
|
||||
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
|
||||
pbrsb_eibrs_state(),
|
||||
spectre_v2_module_string());
|
||||
return sysfs_emit(buf, "%s%s%s%s%s%s%s\n",
|
||||
spectre_v2_strings[spectre_v2_enabled],
|
||||
ibpb_state(),
|
||||
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
|
||||
stibp_state(),
|
||||
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
|
||||
pbrsb_eibrs_state(),
|
||||
spectre_v2_module_string());
|
||||
}
|
||||
|
||||
static ssize_t srbds_show_state(char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
|
||||
return sysfs_emit(buf, "%s\n", srbds_strings[srbds_mitigation]);
|
||||
}
|
||||
|
||||
static ssize_t retbleed_show_state(char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
|
||||
return sysfs_emit(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
|
||||
}
|
||||
|
||||
static ssize_t gds_show_state(char *buf)
|
||||
@@ -2312,26 +2319,26 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
||||
char *buf, unsigned int bug)
|
||||
{
|
||||
if (!boot_cpu_has_bug(bug))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
return sysfs_emit(buf, "Not affected\n");
|
||||
|
||||
switch (bug) {
|
||||
case X86_BUG_CPU_MELTDOWN:
|
||||
if (boot_cpu_has(X86_FEATURE_PTI))
|
||||
return sprintf(buf, "Mitigation: PTI\n");
|
||||
return sysfs_emit(buf, "Mitigation: PTI\n");
|
||||
|
||||
if (hypervisor_is_type(X86_HYPER_XEN_PV))
|
||||
return sprintf(buf, "Unknown (XEN PV detected, hypervisor mitigation required)\n");
|
||||
return sysfs_emit(buf, "Unknown (XEN PV detected, hypervisor mitigation required)\n");
|
||||
|
||||
break;
|
||||
|
||||
case X86_BUG_SPECTRE_V1:
|
||||
return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
|
||||
return sysfs_emit(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
|
||||
|
||||
case X86_BUG_SPECTRE_V2:
|
||||
return spectre_v2_show_state(buf);
|
||||
|
||||
case X86_BUG_SPEC_STORE_BYPASS:
|
||||
return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
|
||||
return sysfs_emit(buf, "%s\n", ssb_strings[ssb_mode]);
|
||||
|
||||
case X86_BUG_L1TF:
|
||||
if (boot_cpu_has(X86_FEATURE_L1TF_PTEINV))
|
||||
@@ -2364,7 +2371,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
||||
break;
|
||||
}
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
return sysfs_emit(buf, "Vulnerable\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
||||
@@ -1100,8 +1100,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
||||
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
|
||||
|
||||
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
|
||||
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
|
||||
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
|
||||
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
|
||||
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
|
||||
|
||||
/* Zhaoxin Family 7 */
|
||||
VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_MMIO),
|
||||
@@ -1220,8 +1220,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
||||
!cpu_has(c, X86_FEATURE_AMD_SSB_NO))
|
||||
setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
|
||||
|
||||
if (ia32_cap & ARCH_CAP_IBRS_ALL)
|
||||
/*
|
||||
* AMD's AutoIBRS is equivalent to Intel's eIBRS - use the Intel feature
|
||||
* flag and protect from vendor-specific bugs via the whitelist.
|
||||
*/
|
||||
if ((ia32_cap & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) {
|
||||
setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
|
||||
if (!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
|
||||
!(ia32_cap & ARCH_CAP_PBRSB_NO))
|
||||
setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
|
||||
}
|
||||
|
||||
if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) &&
|
||||
!(ia32_cap & ARCH_CAP_MDS_NO)) {
|
||||
@@ -1283,11 +1291,6 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
||||
setup_force_cpu_bug(X86_BUG_RETBLEED);
|
||||
}
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_IBRS_ENHANCED) &&
|
||||
!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
|
||||
!(ia32_cap & ARCH_CAP_PBRSB_NO))
|
||||
setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
|
||||
|
||||
/*
|
||||
* Check if CPU is vulnerable to GDS. If running in a virtual machine on
|
||||
* an affected processor, the VMM may have disabled the use of GATHER by
|
||||
|
||||
@@ -2228,12 +2228,14 @@ static ssize_t set_bank(struct device *s, struct device_attribute *attr,
|
||||
return -EINVAL;
|
||||
|
||||
b = &per_cpu(mce_banks_array, s->id)[bank];
|
||||
|
||||
if (!b->init)
|
||||
return -ENODEV;
|
||||
|
||||
b->ctl = new;
|
||||
|
||||
mutex_lock(&mce_sysfs_mutex);
|
||||
mce_restart();
|
||||
mutex_unlock(&mce_sysfs_mutex);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -26,31 +26,18 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page,
|
||||
for (; addr < end; addr = next) {
|
||||
pud_t *pud = pud_page + pud_index(addr);
|
||||
pmd_t *pmd;
|
||||
bool use_gbpage;
|
||||
|
||||
next = (addr & PUD_MASK) + PUD_SIZE;
|
||||
if (next > end)
|
||||
next = end;
|
||||
|
||||
/* if this is already a gbpage, this portion is already mapped */
|
||||
if (pud_large(*pud))
|
||||
continue;
|
||||
|
||||
/* Is using a gbpage allowed? */
|
||||
use_gbpage = info->direct_gbpages;
|
||||
|
||||
/* Don't use gbpage if it maps more than the requested region. */
|
||||
/* at the begining: */
|
||||
use_gbpage &= ((addr & ~PUD_MASK) == 0);
|
||||
/* ... or at the end: */
|
||||
use_gbpage &= ((next & ~PUD_MASK) == 0);
|
||||
|
||||
/* Never overwrite existing mappings */
|
||||
use_gbpage &= !pud_present(*pud);
|
||||
|
||||
if (use_gbpage) {
|
||||
if (info->direct_gbpages) {
|
||||
pud_t pudval;
|
||||
|
||||
if (pud_present(*pud))
|
||||
continue;
|
||||
|
||||
addr &= PUD_MASK;
|
||||
pudval = __pud((addr - info->offset) | info->page_flag);
|
||||
set_pud(pud, pudval);
|
||||
continue;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "pat_internal.h"
|
||||
#include "mm_internal.h"
|
||||
#include "../../mm/internal.h" /* is_cow_mapping() */
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "" fmt
|
||||
@@ -955,6 +956,38 @@ static void free_pfn_range(u64 paddr, unsigned long size)
|
||||
free_memtype(paddr, paddr + size);
|
||||
}
|
||||
|
||||
static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
|
||||
pgprot_t *pgprot)
|
||||
{
|
||||
unsigned long prot;
|
||||
|
||||
VM_WARN_ON_ONCE(!(vma->vm_flags & VM_PAT));
|
||||
|
||||
/*
|
||||
* We need the starting PFN and cachemode used for track_pfn_remap()
|
||||
* that covered the whole VMA. For most mappings, we can obtain that
|
||||
* information from the page tables. For COW mappings, we might now
|
||||
* suddenly have anon folios mapped and follow_phys() will fail.
|
||||
*
|
||||
* Fallback to using vma->vm_pgoff, see remap_pfn_range_notrack(), to
|
||||
* detect the PFN. If we need the cachemode as well, we're out of luck
|
||||
* for now and have to fail fork().
|
||||
*/
|
||||
if (!follow_phys(vma, vma->vm_start, 0, &prot, paddr)) {
|
||||
if (pgprot)
|
||||
*pgprot = __pgprot(prot);
|
||||
return 0;
|
||||
}
|
||||
if (is_cow_mapping(vma->vm_flags)) {
|
||||
if (pgprot)
|
||||
return -EINVAL;
|
||||
*paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
WARN_ON_ONCE(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* track_pfn_copy is called when vma that is covering the pfnmap gets
|
||||
* copied through copy_page_range().
|
||||
@@ -965,20 +998,13 @@ static void free_pfn_range(u64 paddr, unsigned long size)
|
||||
int track_pfn_copy(struct vm_area_struct *vma)
|
||||
{
|
||||
resource_size_t paddr;
|
||||
unsigned long prot;
|
||||
unsigned long vma_size = vma->vm_end - vma->vm_start;
|
||||
pgprot_t pgprot;
|
||||
|
||||
if (vma->vm_flags & VM_PAT) {
|
||||
/*
|
||||
* reserve the whole chunk covered by vma. We need the
|
||||
* starting address and protection from pte.
|
||||
*/
|
||||
if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
|
||||
WARN_ON_ONCE(1);
|
||||
if (get_pat_info(vma, &paddr, &pgprot))
|
||||
return -EINVAL;
|
||||
}
|
||||
pgprot = __pgprot(prot);
|
||||
/* reserve the whole chunk covered by vma. */
|
||||
return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
|
||||
}
|
||||
|
||||
@@ -1053,7 +1079,6 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
|
||||
unsigned long size)
|
||||
{
|
||||
resource_size_t paddr;
|
||||
unsigned long prot;
|
||||
|
||||
if (vma && !(vma->vm_flags & VM_PAT))
|
||||
return;
|
||||
@@ -1061,11 +1086,8 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
|
||||
/* free the chunk starting from pfn or the whole chunk */
|
||||
paddr = (resource_size_t)pfn << PAGE_SHIFT;
|
||||
if (!paddr && !size) {
|
||||
if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
|
||||
WARN_ON_ONCE(1);
|
||||
if (get_pat_info(vma, &paddr, NULL))
|
||||
return;
|
||||
}
|
||||
|
||||
size = vma->vm_end - vma->vm_start;
|
||||
}
|
||||
free_pfn_range(paddr, size);
|
||||
|
||||
@@ -28,7 +28,7 @@ void blk_rq_stat_init(struct blk_rq_stat *stat)
|
||||
/* src is a per-cpu stat, mean isn't initialized */
|
||||
void blk_rq_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src)
|
||||
{
|
||||
if (!src->nr_samples)
|
||||
if (dst->nr_samples + src->nr_samples <= dst->nr_samples)
|
||||
return;
|
||||
|
||||
dst->min = min(dst->min, src->min);
|
||||
|
||||
@@ -382,18 +382,6 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* ASUS B1400CEAE hangs on resume from suspend (see
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=215742).
|
||||
*/
|
||||
{
|
||||
.callback = init_default_s3,
|
||||
.ident = "ASUS B1400CEAE",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK B1400CEAE"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
@@ -626,11 +626,6 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
|
||||
static void ahci_pci_save_initial_config(struct pci_dev *pdev,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) {
|
||||
dev_info(&pdev->dev, "ASM1166 has only six ports\n");
|
||||
hpriv->saved_port_map = 0x3f;
|
||||
}
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
|
||||
dev_info(&pdev->dev, "JMB361 has only one port\n");
|
||||
hpriv->force_port_map = 1;
|
||||
|
||||
@@ -783,37 +783,6 @@ static const struct ata_port_info mv_port_info[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct pci_device_id mv_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
|
||||
{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
|
||||
/* RocketRAID 1720/174x have different identifiers */
|
||||
{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
|
||||
{ PCI_VDEVICE(TTI, 0x1740), chip_6042 },
|
||||
{ PCI_VDEVICE(TTI, 0x1742), chip_6042 },
|
||||
|
||||
{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
|
||||
|
||||
{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
|
||||
|
||||
/* Adaptec 1430SA */
|
||||
{ PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 },
|
||||
|
||||
/* Marvell 7042 support */
|
||||
{ PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
|
||||
|
||||
/* Highpoint RocketRAID PCIe series */
|
||||
{ PCI_VDEVICE(TTI, 0x2300), chip_7042 },
|
||||
{ PCI_VDEVICE(TTI, 0x2310), chip_7042 },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
static const struct mv_hw_ops mv5xxx_ops = {
|
||||
.phy_errata = mv5_phy_errata,
|
||||
.enable_leds = mv5_enable_leds,
|
||||
@@ -4307,6 +4276,36 @@ static int mv_pci_init_one(struct pci_dev *pdev,
|
||||
static int mv_pci_device_resume(struct pci_dev *pdev);
|
||||
#endif
|
||||
|
||||
static const struct pci_device_id mv_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
|
||||
{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
|
||||
/* RocketRAID 1720/174x have different identifiers */
|
||||
{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
|
||||
{ PCI_VDEVICE(TTI, 0x1740), chip_6042 },
|
||||
{ PCI_VDEVICE(TTI, 0x1742), chip_6042 },
|
||||
|
||||
{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
|
||||
{ PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
|
||||
|
||||
{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
|
||||
|
||||
/* Adaptec 1430SA */
|
||||
{ PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 },
|
||||
|
||||
/* Marvell 7042 support */
|
||||
{ PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
|
||||
|
||||
/* Highpoint RocketRAID PCIe series */
|
||||
{ PCI_VDEVICE(TTI, 0x2300), chip_7042 },
|
||||
{ PCI_VDEVICE(TTI, 0x2310), chip_7042 },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
static struct pci_driver mv_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
@@ -4319,6 +4318,7 @@ static struct pci_driver mv_pci_driver = {
|
||||
#endif
|
||||
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
|
||||
|
||||
/**
|
||||
* mv_print_info - Dump key info to kernel log for perusal.
|
||||
@@ -4491,7 +4491,6 @@ static void __exit mv_exit(void)
|
||||
MODULE_AUTHOR("Brett Russ");
|
||||
MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
|
||||
|
||||
@@ -1004,8 +1004,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
|
||||
|
||||
offset -= (idx * window_size);
|
||||
idx++;
|
||||
dist = ((long) (window_size - (offset + size))) >= 0 ? size :
|
||||
(long) (window_size - offset);
|
||||
dist = min(size, window_size - offset);
|
||||
memcpy_fromio(psource, dimm_mmio + offset / 4, dist);
|
||||
|
||||
psource += dist;
|
||||
@@ -1053,8 +1052,7 @@ static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
|
||||
readl(mmio + PDC_DIMM_WINDOW_CTLR);
|
||||
offset -= (idx * window_size);
|
||||
idx++;
|
||||
dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size :
|
||||
(long) (window_size - offset);
|
||||
dist = min(size, window_size - offset);
|
||||
memcpy_toio(dimm_mmio + offset / 4, psource, dist);
|
||||
writel(0x01, mmio + PDC_GENERAL_CTLR);
|
||||
readl(mmio + PDC_GENERAL_CTLR);
|
||||
|
||||
@@ -365,8 +365,10 @@ void dev_pm_enable_wake_irq_complete(struct device *dev)
|
||||
return;
|
||||
|
||||
if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
|
||||
wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
|
||||
wirq->status & WAKE_IRQ_DEDICATED_REVERSE) {
|
||||
enable_irq(wirq->irq);
|
||||
wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -226,24 +226,30 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
|
||||
blk_mq_unfreeze_queue(lo->lo_queue);
|
||||
}
|
||||
|
||||
static int
|
||||
/**
|
||||
* loop_set_size() - sets device size and notifies userspace
|
||||
* @lo: struct loop_device to set the size for
|
||||
* @size: new size of the loop device
|
||||
*
|
||||
* Callers must validate that the size passed into this function fits into
|
||||
* a sector_t, eg using loop_validate_size()
|
||||
*/
|
||||
static void loop_set_size(struct loop_device *lo, loff_t size)
|
||||
{
|
||||
struct block_device *bdev = lo->lo_device;
|
||||
|
||||
set_capacity(lo->lo_disk, size);
|
||||
bd_set_size(bdev, size << SECTOR_SHIFT);
|
||||
/* let user-space know about the new size */
|
||||
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
static void
|
||||
figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)
|
||||
{
|
||||
loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);
|
||||
sector_t x = (sector_t)size;
|
||||
struct block_device *bdev = lo->lo_device;
|
||||
|
||||
if (unlikely((loff_t)x != size))
|
||||
return -EFBIG;
|
||||
if (lo->lo_offset != offset)
|
||||
lo->lo_offset = offset;
|
||||
if (lo->lo_sizelimit != sizelimit)
|
||||
lo->lo_sizelimit = sizelimit;
|
||||
set_capacity(lo->lo_disk, x);
|
||||
bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9);
|
||||
/* let user-space know about the new size */
|
||||
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
|
||||
return 0;
|
||||
loop_set_size(lo, size);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -1002,10 +1008,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
||||
!file->f_op->write_iter)
|
||||
lo_flags |= LO_FLAGS_READ_ONLY;
|
||||
|
||||
error = -EFBIG;
|
||||
size = get_loop_size(lo, file);
|
||||
if ((loff_t)(sector_t)size != size)
|
||||
goto out_unlock;
|
||||
|
||||
error = loop_prepare_queue(lo);
|
||||
if (error)
|
||||
goto out_unlock;
|
||||
@@ -1039,11 +1043,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
||||
|
||||
loop_update_rotational(lo);
|
||||
loop_update_dio(lo);
|
||||
set_capacity(lo->lo_disk, size);
|
||||
bd_set_size(bdev, size << 9);
|
||||
loop_sysfs_init(lo);
|
||||
/* let user-space know about the new size */
|
||||
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
|
||||
loop_set_size(lo, size);
|
||||
|
||||
set_blocksize(bdev, S_ISBLK(inode->i_mode) ?
|
||||
block_size(inode->i_bdev) : PAGE_SIZE);
|
||||
@@ -1257,82 +1258,50 @@ static int loop_clr_fd(struct loop_device *lo)
|
||||
return __loop_clr_fd(lo, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* loop_set_status_from_info - configure device from loop_info
|
||||
* @lo: struct loop_device to configure
|
||||
* @info: struct loop_info64 to configure the device with
|
||||
*
|
||||
* Configures the loop device parameters according to the passed
|
||||
* in loop_info64 configuration.
|
||||
*/
|
||||
static int
|
||||
loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
loop_set_status_from_info(struct loop_device *lo,
|
||||
const struct loop_info64 *info)
|
||||
{
|
||||
int err;
|
||||
struct loop_func_table *xfer;
|
||||
kuid_t uid = current_uid();
|
||||
struct block_device *bdev;
|
||||
bool partscan = false;
|
||||
|
||||
err = mutex_lock_killable(&loop_ctl_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
if (lo->lo_encrypt_key_size &&
|
||||
!uid_eq(lo->lo_key_owner, uid) &&
|
||||
!capable(CAP_SYS_ADMIN)) {
|
||||
err = -EPERM;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (lo->lo_state != Lo_bound) {
|
||||
err = -ENXIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) {
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (lo->lo_offset != info->lo_offset ||
|
||||
lo->lo_sizelimit != info->lo_sizelimit) {
|
||||
sync_blockdev(lo->lo_device);
|
||||
invalidate_bdev(lo->lo_device);
|
||||
}
|
||||
|
||||
/* I/O need to be drained during transfer transition */
|
||||
blk_mq_freeze_queue(lo->lo_queue);
|
||||
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
err = loop_release_xfer(lo);
|
||||
if (err)
|
||||
goto out_unfreeze;
|
||||
return err;
|
||||
|
||||
if (info->lo_encrypt_type) {
|
||||
unsigned int type = info->lo_encrypt_type;
|
||||
|
||||
if (type >= MAX_LO_CRYPT) {
|
||||
err = -EINVAL;
|
||||
goto out_unfreeze;
|
||||
}
|
||||
if (type >= MAX_LO_CRYPT)
|
||||
return -EINVAL;
|
||||
xfer = xfer_funcs[type];
|
||||
if (xfer == NULL) {
|
||||
err = -EINVAL;
|
||||
goto out_unfreeze;
|
||||
}
|
||||
if (xfer == NULL)
|
||||
return -EINVAL;
|
||||
} else
|
||||
xfer = NULL;
|
||||
|
||||
err = loop_init_xfer(lo, xfer, info);
|
||||
if (err)
|
||||
goto out_unfreeze;
|
||||
return err;
|
||||
|
||||
if (lo->lo_offset != info->lo_offset ||
|
||||
lo->lo_sizelimit != info->lo_sizelimit) {
|
||||
/* kill_bdev should have truncated all the pages */
|
||||
if (lo->lo_device->bd_inode->i_mapping->nrpages) {
|
||||
err = -EAGAIN;
|
||||
pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
|
||||
__func__, lo->lo_number, lo->lo_file_name,
|
||||
lo->lo_device->bd_inode->i_mapping->nrpages);
|
||||
goto out_unfreeze;
|
||||
}
|
||||
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
|
||||
err = -EFBIG;
|
||||
goto out_unfreeze;
|
||||
}
|
||||
}
|
||||
/* Avoid assigning overflow values */
|
||||
if (info->lo_offset > LLONG_MAX || info->lo_sizelimit > LLONG_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
loop_config_discard(lo);
|
||||
lo->lo_offset = info->lo_offset;
|
||||
lo->lo_sizelimit = info->lo_sizelimit;
|
||||
|
||||
memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
|
||||
memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
|
||||
@@ -1357,6 +1326,63 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
lo->lo_key_owner = uid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
{
|
||||
int err;
|
||||
struct block_device *bdev;
|
||||
kuid_t uid = current_uid();
|
||||
bool partscan = false;
|
||||
bool size_changed = false;
|
||||
|
||||
err = mutex_lock_killable(&loop_ctl_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
if (lo->lo_encrypt_key_size &&
|
||||
!uid_eq(lo->lo_key_owner, uid) &&
|
||||
!capable(CAP_SYS_ADMIN)) {
|
||||
err = -EPERM;
|
||||
goto out_unlock;
|
||||
}
|
||||
if (lo->lo_state != Lo_bound) {
|
||||
err = -ENXIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (lo->lo_offset != info->lo_offset ||
|
||||
lo->lo_sizelimit != info->lo_sizelimit) {
|
||||
size_changed = true;
|
||||
sync_blockdev(lo->lo_device);
|
||||
invalidate_bdev(lo->lo_device);
|
||||
}
|
||||
|
||||
/* I/O need to be drained during transfer transition */
|
||||
blk_mq_freeze_queue(lo->lo_queue);
|
||||
|
||||
if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) {
|
||||
/* If any pages were dirtied after invalidate_bdev(), try again */
|
||||
err = -EAGAIN;
|
||||
pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
|
||||
__func__, lo->lo_number, lo->lo_file_name,
|
||||
lo->lo_device->bd_inode->i_mapping->nrpages);
|
||||
goto out_unfreeze;
|
||||
}
|
||||
|
||||
err = loop_set_status_from_info(lo, info);
|
||||
if (err)
|
||||
goto out_unfreeze;
|
||||
|
||||
if (size_changed) {
|
||||
loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit,
|
||||
lo->lo_backing_file);
|
||||
loop_set_size(lo, new_size);
|
||||
}
|
||||
|
||||
loop_config_discard(lo);
|
||||
|
||||
/* update dio if lo_offset or transfer is changed */
|
||||
__loop_update_dio(lo, lo->use_dio);
|
||||
|
||||
@@ -1397,11 +1423,6 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
|
||||
info->lo_number = lo->lo_number;
|
||||
info->lo_offset = lo->lo_offset;
|
||||
info->lo_sizelimit = lo->lo_sizelimit;
|
||||
|
||||
/* loff_t vars have been assigned __u64 */
|
||||
if (lo->lo_offset < 0 || lo->lo_sizelimit < 0)
|
||||
return -EOVERFLOW;
|
||||
|
||||
info->lo_flags = lo->lo_flags;
|
||||
memcpy(info->lo_file_name, lo->lo_file_name, LO_NAME_SIZE);
|
||||
memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
|
||||
@@ -1537,7 +1558,9 @@ static int loop_set_capacity(struct loop_device *lo)
|
||||
if (unlikely(lo->lo_state != Lo_bound))
|
||||
return -ENXIO;
|
||||
|
||||
return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
|
||||
figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loop_set_dio(struct loop_device *lo, unsigned long arg)
|
||||
|
||||
@@ -346,7 +346,7 @@ int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*ver)) {
|
||||
if (!skb || skb->len != sizeof(*ver)) {
|
||||
bt_dev_err(hdev, "Intel version event size mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EILSEQ;
|
||||
|
||||
@@ -972,6 +972,7 @@ static struct clk_rcg2 pcie0_axi_clk_src = {
|
||||
|
||||
static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
|
||||
F(19200000, P_XO, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 pcie0_aux_clk_src = {
|
||||
@@ -1077,6 +1078,7 @@ static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = {
|
||||
F(19200000, P_XO, 1, 0, 0),
|
||||
F(160000000, P_GPLL0, 5, 0, 0),
|
||||
F(308570000, P_GPLL6, 3.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 sdcc1_ice_core_clk_src = {
|
||||
|
||||
@@ -3646,3 +3646,4 @@ module_exit(gcc_sdm845_exit);
|
||||
MODULE_DESCRIPTION("QTI GCC SDM845 Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:gcc-sdm845");
|
||||
MODULE_SOFTDEP("pre: rpmhpd");
|
||||
|
||||
@@ -333,6 +333,7 @@ static struct freq_tbl ftbl_mmss_axi_clk[] = {
|
||||
F(333430000, P_MMPLL1, 3.5, 0, 0),
|
||||
F(400000000, P_MMPLL0, 2, 0, 0),
|
||||
F(466800000, P_MMPLL1, 2.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 mmss_axi_clk_src = {
|
||||
@@ -357,6 +358,7 @@ static struct freq_tbl ftbl_ocmemnoc_clk[] = {
|
||||
F(150000000, P_GPLL0, 4, 0, 0),
|
||||
F(228570000, P_MMPLL0, 3.5, 0, 0),
|
||||
F(320000000, P_MMPLL0, 2.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 ocmemnoc_clk_src = {
|
||||
|
||||
@@ -283,6 +283,7 @@ static struct freq_tbl ftbl_mmss_axi_clk[] = {
|
||||
F(291750000, P_MMPLL1, 4, 0, 0),
|
||||
F(400000000, P_MMPLL0, 2, 0, 0),
|
||||
F(466800000, P_MMPLL1, 2.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 mmss_axi_clk_src = {
|
||||
@@ -307,6 +308,7 @@ static struct freq_tbl ftbl_ocmemnoc_clk[] = {
|
||||
F(150000000, P_GPLL0, 4, 0, 0),
|
||||
F(291750000, P_MMPLL1, 4, 0, 0),
|
||||
F(400000000, P_MMPLL0, 2, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 ocmemnoc_clk_src = {
|
||||
|
||||
@@ -139,18 +139,28 @@ static void adf_device_reset_worker(struct work_struct *work)
|
||||
if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) {
|
||||
/* The device hanged and we can't restart it so stop here */
|
||||
dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
|
||||
kfree(reset_data);
|
||||
if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
|
||||
completion_done(&reset_data->compl))
|
||||
kfree(reset_data);
|
||||
WARN(1, "QAT: device restart failed. Device is unusable\n");
|
||||
return;
|
||||
}
|
||||
adf_dev_restarted_notify(accel_dev);
|
||||
clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
|
||||
|
||||
/* The dev is back alive. Notify the caller if in sync mode */
|
||||
if (reset_data->mode == ADF_DEV_RESET_SYNC)
|
||||
complete(&reset_data->compl);
|
||||
else
|
||||
/*
|
||||
* The dev is back alive. Notify the caller if in sync mode
|
||||
*
|
||||
* If device restart will take a more time than expected,
|
||||
* the schedule_reset() function can timeout and exit. This can be
|
||||
* detected by calling the completion_done() function. In this case
|
||||
* the reset_data structure needs to be freed here.
|
||||
*/
|
||||
if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
|
||||
completion_done(&reset_data->compl))
|
||||
kfree(reset_data);
|
||||
else
|
||||
complete(&reset_data->compl);
|
||||
}
|
||||
|
||||
static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
|
||||
@@ -183,8 +193,9 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
|
||||
dev_err(&GET_DEV(accel_dev),
|
||||
"Reset device timeout expired\n");
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
kfree(reset_data);
|
||||
}
|
||||
kfree(reset_data);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -427,7 +427,7 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
|
||||
void *data, bool duplicates, struct list_head *head)
|
||||
{
|
||||
const struct efivar_operations *ops;
|
||||
unsigned long variable_name_size = 1024;
|
||||
unsigned long variable_name_size = 512;
|
||||
efi_char16_t *variable_name;
|
||||
efi_status_t status;
|
||||
efi_guid_t vendor_guid;
|
||||
@@ -450,12 +450,13 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
|
||||
}
|
||||
|
||||
/*
|
||||
* Per EFI spec, the maximum storage allocated for both
|
||||
* the variable name and variable data is 1024 bytes.
|
||||
* A small set of old UEFI implementations reject sizes
|
||||
* above a certain threshold, the lowest seen in the wild
|
||||
* is 512.
|
||||
*/
|
||||
|
||||
do {
|
||||
variable_name_size = 1024;
|
||||
variable_name_size = 512;
|
||||
|
||||
status = ops->get_next_variable(&variable_name_size,
|
||||
variable_name,
|
||||
@@ -499,9 +500,13 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
|
||||
break;
|
||||
case EFI_NOT_FOUND:
|
||||
break;
|
||||
case EFI_BUFFER_TOO_SMALL:
|
||||
pr_warn("efivars: Variable name size exceeds maximum (%lu > 512)\n",
|
||||
variable_name_size);
|
||||
status = EFI_NOT_FOUND;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
|
||||
status);
|
||||
pr_warn("efivars: get_next_variable: status=%lx\n", status);
|
||||
status = EFI_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -54,8 +54,6 @@ struct meson_sm_firmware {
|
||||
void __iomem *sm_shmem_out_base;
|
||||
};
|
||||
|
||||
static struct meson_sm_firmware fw;
|
||||
|
||||
static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
|
||||
unsigned int cmd_index)
|
||||
{
|
||||
@@ -90,6 +88,7 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
|
||||
/**
|
||||
* meson_sm_call - generic SMC32 call to the secure-monitor
|
||||
*
|
||||
* @fw: Pointer to secure-monitor firmware
|
||||
* @cmd_index: Index of the SMC32 function ID
|
||||
* @ret: Returned value
|
||||
* @arg0: SMC32 Argument 0
|
||||
@@ -100,15 +99,15 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
|
||||
*
|
||||
* Return: 0 on success, a negative value on error
|
||||
*/
|
||||
int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0,
|
||||
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
|
||||
u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
{
|
||||
u32 cmd, lret;
|
||||
|
||||
if (!fw.chip)
|
||||
if (!fw->chip)
|
||||
return -ENOENT;
|
||||
|
||||
cmd = meson_sm_get_cmd(fw.chip, cmd_index);
|
||||
cmd = meson_sm_get_cmd(fw->chip, cmd_index);
|
||||
if (!cmd)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -124,6 +123,7 @@ EXPORT_SYMBOL(meson_sm_call);
|
||||
/**
|
||||
* meson_sm_call_read - retrieve data from secure-monitor
|
||||
*
|
||||
* @fw: Pointer to secure-monitor firmware
|
||||
* @buffer: Buffer to store the retrieved data
|
||||
* @bsize: Size of the buffer
|
||||
* @cmd_index: Index of the SMC32 function ID
|
||||
@@ -137,22 +137,23 @@ EXPORT_SYMBOL(meson_sm_call);
|
||||
* When 0 is returned there is no guarantee about the amount of
|
||||
* data read and bsize bytes are copied in buffer.
|
||||
*/
|
||||
int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
|
||||
u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
|
||||
unsigned int bsize, unsigned int cmd_index, u32 arg0,
|
||||
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
{
|
||||
u32 size;
|
||||
int ret;
|
||||
|
||||
if (!fw.chip)
|
||||
if (!fw->chip)
|
||||
return -ENOENT;
|
||||
|
||||
if (!fw.chip->cmd_shmem_out_base)
|
||||
if (!fw->chip->cmd_shmem_out_base)
|
||||
return -EINVAL;
|
||||
|
||||
if (bsize > fw.chip->shmem_size)
|
||||
if (bsize > fw->chip->shmem_size)
|
||||
return -EINVAL;
|
||||
|
||||
if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
|
||||
if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (size > bsize)
|
||||
@@ -164,7 +165,7 @@ int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
|
||||
size = bsize;
|
||||
|
||||
if (buffer)
|
||||
memcpy(buffer, fw.sm_shmem_out_base, size);
|
||||
memcpy(buffer, fw->sm_shmem_out_base, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -173,6 +174,7 @@ EXPORT_SYMBOL(meson_sm_call_read);
|
||||
/**
|
||||
* meson_sm_call_write - send data to secure-monitor
|
||||
*
|
||||
* @fw: Pointer to secure-monitor firmware
|
||||
* @buffer: Buffer containing data to send
|
||||
* @size: Size of the data to send
|
||||
* @cmd_index: Index of the SMC32 function ID
|
||||
@@ -184,23 +186,24 @@ EXPORT_SYMBOL(meson_sm_call_read);
|
||||
*
|
||||
* Return: size of sent data on success, a negative value on error
|
||||
*/
|
||||
int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
|
||||
u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
|
||||
unsigned int size, unsigned int cmd_index, u32 arg0,
|
||||
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
{
|
||||
u32 written;
|
||||
|
||||
if (!fw.chip)
|
||||
if (!fw->chip)
|
||||
return -ENOENT;
|
||||
|
||||
if (size > fw.chip->shmem_size)
|
||||
if (size > fw->chip->shmem_size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!fw.chip->cmd_shmem_in_base)
|
||||
if (!fw->chip->cmd_shmem_in_base)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(fw.sm_shmem_in_base, buffer, size);
|
||||
memcpy(fw->sm_shmem_in_base, buffer, size);
|
||||
|
||||
if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
|
||||
if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!written)
|
||||
@@ -210,6 +213,24 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
|
||||
}
|
||||
EXPORT_SYMBOL(meson_sm_call_write);
|
||||
|
||||
/**
|
||||
* meson_sm_get - get pointer to meson_sm_firmware structure.
|
||||
*
|
||||
* @sm_node: Pointer to the secure-monitor Device Tree node.
|
||||
*
|
||||
* Return: NULL is the secure-monitor device is not ready.
|
||||
*/
|
||||
struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
|
||||
{
|
||||
struct platform_device *pdev = of_find_device_by_node(sm_node);
|
||||
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
|
||||
return platform_get_drvdata(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(meson_sm_get);
|
||||
|
||||
#define SM_CHIP_ID_LENGTH 119
|
||||
#define SM_CHIP_ID_OFFSET 4
|
||||
#define SM_CHIP_ID_SIZE 12
|
||||
@@ -217,14 +238,18 @@ EXPORT_SYMBOL(meson_sm_call_write);
|
||||
static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct meson_sm_firmware *fw;
|
||||
uint8_t *id_buf;
|
||||
int ret;
|
||||
|
||||
fw = platform_get_drvdata(pdev);
|
||||
|
||||
id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
|
||||
if (!id_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
|
||||
ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
|
||||
0, 0, 0, 0, 0);
|
||||
if (ret < 0) {
|
||||
kfree(id_buf);
|
||||
@@ -268,25 +293,36 @@ static const struct of_device_id meson_sm_ids[] = {
|
||||
|
||||
static int __init meson_sm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct meson_sm_chip *chip;
|
||||
struct meson_sm_firmware *fw;
|
||||
|
||||
chip = of_match_device(meson_sm_ids, &pdev->dev)->data;
|
||||
fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
|
||||
if (!fw)
|
||||
return -ENOMEM;
|
||||
|
||||
chip = of_match_device(meson_sm_ids, dev)->data;
|
||||
if (!chip)
|
||||
return -EINVAL;
|
||||
|
||||
if (chip->cmd_shmem_in_base) {
|
||||
fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
|
||||
chip->shmem_size);
|
||||
if (WARN_ON(!fw.sm_shmem_in_base))
|
||||
fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
|
||||
chip->shmem_size);
|
||||
if (WARN_ON(!fw->sm_shmem_in_base))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (chip->cmd_shmem_out_base) {
|
||||
fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
|
||||
chip->shmem_size);
|
||||
if (WARN_ON(!fw.sm_shmem_out_base))
|
||||
fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
|
||||
chip->shmem_size);
|
||||
if (WARN_ON(!fw->sm_shmem_out_base))
|
||||
goto out_in_base;
|
||||
}
|
||||
|
||||
fw.chip = chip;
|
||||
fw->chip = chip;
|
||||
|
||||
platform_set_drvdata(pdev, fw);
|
||||
|
||||
pr_info("secure-monitor enabled\n");
|
||||
|
||||
if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
|
||||
@@ -295,7 +331,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
out_in_base:
|
||||
iounmap(fw.sm_shmem_in_base);
|
||||
iounmap(fw->sm_shmem_in_base);
|
||||
out:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -938,8 +938,8 @@ static int kfd_ioctl_get_process_apertures_new(struct file *filp,
|
||||
* nodes, but not more than args->num_of_nodes as that is
|
||||
* the amount of memory allocated by user
|
||||
*/
|
||||
pa = kzalloc((sizeof(struct kfd_process_device_apertures) *
|
||||
args->num_of_nodes), GFP_KERNEL);
|
||||
pa = kcalloc(args->num_of_nodes, sizeof(struct kfd_process_device_apertures),
|
||||
GFP_KERNEL);
|
||||
if (!pa)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -51,10 +51,10 @@ void mod_stats_update_event(struct mod_stats *mod_stats,
|
||||
unsigned int length);
|
||||
|
||||
void mod_stats_update_flip(struct mod_stats *mod_stats,
|
||||
unsigned long timestamp_in_ns);
|
||||
unsigned long long timestamp_in_ns);
|
||||
|
||||
void mod_stats_update_vupdate(struct mod_stats *mod_stats,
|
||||
unsigned long timestamp_in_ns);
|
||||
unsigned long long timestamp_in_ns);
|
||||
|
||||
void mod_stats_update_freesync(struct mod_stats *mod_stats,
|
||||
unsigned int v_total_min,
|
||||
|
||||
@@ -308,14 +308,14 @@ static int vidi_get_modes(struct drm_connector *connector)
|
||||
*/
|
||||
if (!ctx->raw_edid) {
|
||||
DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n");
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
|
||||
edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
|
||||
if (!edid) {
|
||||
DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n");
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_connector_update_edid_property(connector, edid);
|
||||
|
||||
@@ -1096,11 +1096,11 @@ static int hdmi_get_modes(struct drm_connector *connector)
|
||||
int ret;
|
||||
|
||||
if (!hdata->ddc_adpt)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
|
||||
edid = drm_get_edid(connector, hdata->ddc_adpt);
|
||||
if (!edid)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
|
||||
if (gdvi_mode)
|
||||
hdata->dvi_mode = true;
|
||||
|
||||
@@ -145,9 +145,6 @@ static int __engine_park(struct intel_wakeref *wf)
|
||||
intel_engine_disarm_breadcrumbs(engine);
|
||||
intel_engine_pool_park(&engine->pool);
|
||||
|
||||
/* Must be reset upon idling, or we may miss the busy wakeup. */
|
||||
GEM_BUG_ON(engine->execlists.queue_priority_hint != INT_MIN);
|
||||
|
||||
if (engine->park)
|
||||
engine->park(engine);
|
||||
|
||||
|
||||
@@ -2992,6 +2992,9 @@ static u32 *gen11_emit_fini_breadcrumb_rcs(struct i915_request *request,
|
||||
static void execlists_park(struct intel_engine_cs *engine)
|
||||
{
|
||||
del_timer(&engine->execlists.timer);
|
||||
|
||||
/* Reset upon idling, or we may delay the busy wakeup. */
|
||||
WRITE_ONCE(engine->execlists.queue_priority_hint, INT_MIN);
|
||||
}
|
||||
|
||||
void intel_execlists_set_default_submission(struct intel_engine_cs *engine)
|
||||
|
||||
@@ -63,14 +63,14 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
|
||||
int ret;
|
||||
|
||||
if (!mode)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
ret = of_get_drm_display_mode(np, &imxpd->mode,
|
||||
&imxpd->bus_flags,
|
||||
OF_USE_NATIVE_MODE);
|
||||
if (ret) {
|
||||
drm_mode_destroy(connector->dev, mode);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_mode_copy(mode, &imxpd->mode);
|
||||
|
||||
@@ -236,7 +236,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
|
||||
edid = drm_get_edid(connector, vc4->hdmi->ddc);
|
||||
cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
|
||||
if (!edid)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
|
||||
vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ static void vkms_release(struct drm_device *dev)
|
||||
struct vkms_device *vkms = container_of(dev, struct vkms_device, drm);
|
||||
|
||||
platform_device_unregister(vkms->platform);
|
||||
drm_atomic_helper_shutdown(&vkms->drm);
|
||||
drm_mode_config_cleanup(&vkms->drm);
|
||||
drm_dev_fini(&vkms->drm);
|
||||
destroy_workqueue(vkms->output.composer_workq);
|
||||
@@ -194,6 +193,7 @@ static void __exit vkms_exit(void)
|
||||
}
|
||||
|
||||
drm_dev_unregister(&vkms_device->drm);
|
||||
drm_atomic_helper_shutdown(&vkms_device->drm);
|
||||
drm_dev_put(&vkms_device->drm);
|
||||
|
||||
kfree(vkms_device);
|
||||
|
||||
@@ -935,10 +935,21 @@ static const struct i2c_device_id amc6821_id[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, amc6821_id);
|
||||
|
||||
static const struct of_device_id __maybe_unused amc6821_of_match[] = {
|
||||
{
|
||||
.compatible = "ti,amc6821",
|
||||
.data = (void *)amc6821,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, amc6821_of_match);
|
||||
|
||||
static struct i2c_driver amc6821_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "amc6821",
|
||||
.of_match_table = of_match_ptr(amc6821_of_match),
|
||||
},
|
||||
.probe = amc6821_probe,
|
||||
.id_table = amc6821_id,
|
||||
|
||||
@@ -1196,7 +1196,11 @@ static int rmi_driver_probe(struct device *dev)
|
||||
}
|
||||
rmi_driver_set_input_params(rmi_dev, data->input);
|
||||
data->input->phys = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s/input0", dev_name(dev));
|
||||
"%s/input0", dev_name(dev));
|
||||
if (!data->input->phys) {
|
||||
retval = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
retval = rmi_init_functions(data);
|
||||
|
||||
@@ -3755,7 +3755,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||
} else if (sscanf(opt_string, "sectors_per_bit:%llu%c", &llval, &dummy) == 1) {
|
||||
log2_sectors_per_bitmap_bit = !llval ? 0 : __ilog2_u64(llval);
|
||||
} else if (sscanf(opt_string, "bitmap_flush_interval:%u%c", &val, &dummy) == 1) {
|
||||
if (val >= (uint64_t)UINT_MAX * 1000 / HZ) {
|
||||
if ((uint64_t)val >= (uint64_t)UINT_MAX * 1000 / HZ) {
|
||||
r = -EINVAL;
|
||||
ti->error = "Invalid bitmap_flush_interval argument";
|
||||
goto bad;
|
||||
|
||||
@@ -4027,7 +4027,9 @@ static void raid_resume(struct dm_target *ti)
|
||||
* Take this opportunity to check whether any failed
|
||||
* devices are reachable again.
|
||||
*/
|
||||
mddev_lock_nointr(mddev);
|
||||
attempt_restore_of_faulty_devices(rs);
|
||||
mddev_unlock(mddev);
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
|
||||
|
||||
@@ -685,8 +685,10 @@ static void dm_exception_table_exit(struct dm_exception_table *et,
|
||||
for (i = 0; i < size; i++) {
|
||||
slot = et->table + i;
|
||||
|
||||
hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list)
|
||||
hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) {
|
||||
kmem_cache_free(mem, ex);
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
vfree(et->table);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/raid/pq.h>
|
||||
#include <linux/async_tx.h>
|
||||
@@ -6334,7 +6335,18 @@ static void raid5d(struct md_thread *thread)
|
||||
spin_unlock_irq(&conf->device_lock);
|
||||
md_check_recovery(mddev);
|
||||
spin_lock_irq(&conf->device_lock);
|
||||
|
||||
/*
|
||||
* Waiting on MD_SB_CHANGE_PENDING below may deadlock
|
||||
* seeing md_check_recovery() is needed to clear
|
||||
* the flag when using mdmon.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
wait_event_lock_irq(mddev->sb_wait,
|
||||
!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags),
|
||||
conf->device_lock);
|
||||
}
|
||||
pr_debug("%d stripes handled\n", handled);
|
||||
|
||||
|
||||
@@ -760,7 +760,7 @@ static const struct video_device video_dev_template = {
|
||||
/**
|
||||
* vip_irq - interrupt routine
|
||||
* @irq: Number of interrupt ( not used, correct number is assumed )
|
||||
* @vip: local data structure containing all information
|
||||
* @data: local data structure containing all information
|
||||
*
|
||||
* check for both frame interrupts set ( top and bottom ).
|
||||
* check FIFO overflow, but limit number of log messages after open.
|
||||
@@ -770,8 +770,9 @@ static const struct video_device video_dev_template = {
|
||||
*
|
||||
* IRQ_HANDLED, interrupt done.
|
||||
*/
|
||||
static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
|
||||
static irqreturn_t vip_irq(int irq, void *data)
|
||||
{
|
||||
struct sta2x11_vip *vip = data;
|
||||
unsigned int status;
|
||||
|
||||
status = reg_read(vip, DVP_ITS);
|
||||
@@ -1053,9 +1054,7 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev,
|
||||
|
||||
spin_lock_init(&vip->slock);
|
||||
|
||||
ret = request_irq(pdev->irq,
|
||||
(irq_handler_t) vip_irq,
|
||||
IRQF_SHARED, KBUILD_MODNAME, vip);
|
||||
ret = request_irq(pdev->irq, vip_irq, IRQF_SHARED, KBUILD_MODNAME, vip);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "request_irq failed\n");
|
||||
ret = -ENODEV;
|
||||
|
||||
@@ -1517,10 +1517,10 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
|
||||
{
|
||||
struct xc4000_priv *priv = fe->tuner_priv;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
*freq = priv->freq_hz + priv->freq_offset;
|
||||
|
||||
if (debug) {
|
||||
mutex_lock(&priv->lock);
|
||||
if ((priv->cur_fw.type
|
||||
& (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
|
||||
u16 snr = 0;
|
||||
@@ -1531,8 +1531,8 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
dprintk(1, "%s()\n", __func__);
|
||||
|
||||
|
||||
@@ -234,7 +234,8 @@ static int dg_dispatch_as_host(u32 context_id, struct vmci_datagram *dg)
|
||||
|
||||
dg_info->in_dg_host_queue = true;
|
||||
dg_info->entry = dst_entry;
|
||||
memcpy(&dg_info->msg, dg, dg_size);
|
||||
dg_info->msg = *dg;
|
||||
memcpy(&dg_info->msg_payload, dg + 1, dg->payload_size);
|
||||
|
||||
INIT_WORK(&dg_info->work, dg_delayed_dispatch);
|
||||
schedule_work(&dg_info->work);
|
||||
@@ -377,7 +378,8 @@ int vmci_datagram_invoke_guest_handler(struct vmci_datagram *dg)
|
||||
|
||||
dg_info->in_dg_host_queue = false;
|
||||
dg_info->entry = dst_entry;
|
||||
memcpy(&dg_info->msg, dg, VMCI_DG_SIZE(dg));
|
||||
dg_info->msg = *dg;
|
||||
memcpy(&dg_info->msg_payload, dg + 1, dg->payload_size);
|
||||
|
||||
INIT_WORK(&dg_info->work, dg_delayed_dispatch);
|
||||
schedule_work(&dg_info->work);
|
||||
|
||||
@@ -358,7 +358,7 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
|
||||
struct mmc_blk_ioc_data *idata;
|
||||
int err;
|
||||
|
||||
idata = kmalloc(sizeof(*idata), GFP_KERNEL);
|
||||
idata = kzalloc(sizeof(*idata), GFP_KERNEL);
|
||||
if (!idata) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
@@ -511,7 +511,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
|
||||
if (idata->flags & MMC_BLK_IOC_DROP)
|
||||
return 0;
|
||||
|
||||
if (idata->flags & MMC_BLK_IOC_SBC)
|
||||
if (idata->flags & MMC_BLK_IOC_SBC && i > 0)
|
||||
prev_idata = idatas[i - 1];
|
||||
|
||||
/*
|
||||
@@ -873,10 +873,11 @@ static const struct block_device_operations mmc_bdops = {
|
||||
static int mmc_blk_part_switch_pre(struct mmc_card *card,
|
||||
unsigned int part_type)
|
||||
{
|
||||
const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
|
||||
const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
|
||||
const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
|
||||
int ret = 0;
|
||||
|
||||
if ((part_type & mask) == mask) {
|
||||
if ((part_type & mask) == rpmb) {
|
||||
if (card->ext_csd.cmdq_en) {
|
||||
ret = mmc_cmdq_disable(card);
|
||||
if (ret)
|
||||
@@ -891,10 +892,11 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card,
|
||||
static int mmc_blk_part_switch_post(struct mmc_card *card,
|
||||
unsigned int part_type)
|
||||
{
|
||||
const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
|
||||
const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
|
||||
const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
|
||||
int ret = 0;
|
||||
|
||||
if ((part_type & mask) == mask) {
|
||||
if ((part_type & mask) == rpmb) {
|
||||
mmc_retune_unpause(card->host);
|
||||
if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
|
||||
ret = mmc_cmdq_enable(card);
|
||||
|
||||
@@ -217,6 +217,8 @@ static void tmio_mmc_reset_work(struct work_struct *work)
|
||||
else
|
||||
mrq->cmd->error = -ETIMEDOUT;
|
||||
|
||||
/* No new calls yet, but disallow concurrent tmio_mmc_done_work() */
|
||||
host->mrq = ERR_PTR(-EBUSY);
|
||||
host->cmd = NULL;
|
||||
host->data = NULL;
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \
|
||||
( \
|
||||
(cmd_dir) | \
|
||||
((ran) << 19) | \
|
||||
(ran) | \
|
||||
((bch) << 14) | \
|
||||
((short_mode) << 13) | \
|
||||
(((page_size) & 0x7f) << 6) | \
|
||||
|
||||
@@ -86,9 +86,10 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi)
|
||||
sizeof(struct ubi_fm_scan_pool) +
|
||||
sizeof(struct ubi_fm_scan_pool) +
|
||||
(ubi->peb_count * sizeof(struct ubi_fm_ec)) +
|
||||
(sizeof(struct ubi_fm_eba) +
|
||||
(ubi->peb_count * sizeof(__be32))) +
|
||||
sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
|
||||
((sizeof(struct ubi_fm_eba) +
|
||||
sizeof(struct ubi_fm_volhdr)) *
|
||||
(UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT)) +
|
||||
(ubi->peb_count * sizeof(__be32));
|
||||
return roundup(size, ubi->leb_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -791,6 +791,12 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
|
||||
* The number of supported volumes is limited by the eraseblock size
|
||||
* and by the UBI_MAX_VOLUMES constant.
|
||||
*/
|
||||
|
||||
if (ubi->leb_size < UBI_VTBL_RECORD_SIZE) {
|
||||
ubi_err(ubi, "LEB size too small for a volume record");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE;
|
||||
if (ubi->vtbl_slots > UBI_MAX_VOLUMES)
|
||||
ubi->vtbl_slots = UBI_MAX_VOLUMES;
|
||||
|
||||
@@ -1534,8 +1534,8 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
{
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
struct i40e_vf *vf;
|
||||
int i, v;
|
||||
u32 reg;
|
||||
int i;
|
||||
|
||||
/* If we don't have any VFs, then there is nothing to reset */
|
||||
if (!pf->num_alloc_vfs)
|
||||
@@ -1546,11 +1546,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
return false;
|
||||
|
||||
/* Begin reset on all VFs at once */
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++) {
|
||||
vf = &pf->vf[v];
|
||||
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
|
||||
/* If VF is being reset no need to trigger reset again */
|
||||
if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
i40e_trigger_vf_reset(&pf->vf[v], flr);
|
||||
i40e_trigger_vf_reset(vf, flr);
|
||||
}
|
||||
|
||||
/* HW requires some time to make sure it can flush the FIFO for a VF
|
||||
@@ -1559,14 +1558,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
* the VFs using a simple iterator that increments once that VF has
|
||||
* finished resetting.
|
||||
*/
|
||||
for (i = 0, v = 0; i < 10 && v < pf->num_alloc_vfs; i++) {
|
||||
for (i = 0, vf = &pf->vf[0]; i < 10 && vf < &pf->vf[pf->num_alloc_vfs]; ++i) {
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
/* Check each VF in sequence, beginning with the VF to fail
|
||||
* the previous check.
|
||||
*/
|
||||
while (v < pf->num_alloc_vfs) {
|
||||
vf = &pf->vf[v];
|
||||
while (vf < &pf->vf[pf->num_alloc_vfs]) {
|
||||
if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
|
||||
reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
|
||||
if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
|
||||
@@ -1576,7 +1574,7 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
/* If the current VF has finished resetting, move on
|
||||
* to the next VF in sequence.
|
||||
*/
|
||||
v++;
|
||||
++vf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1586,39 +1584,39 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
/* Display a warning if at least one VF didn't manage to reset in
|
||||
* time, but continue on with the operation.
|
||||
*/
|
||||
if (v < pf->num_alloc_vfs)
|
||||
if (vf < &pf->vf[pf->num_alloc_vfs])
|
||||
dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
|
||||
pf->vf[v].vf_id);
|
||||
vf->vf_id);
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
/* Begin disabling all the rings associated with VFs, but do not wait
|
||||
* between each VF.
|
||||
*/
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++) {
|
||||
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
|
||||
/* On initial reset, we don't have any queues to disable */
|
||||
if (pf->vf[v].lan_vsi_idx == 0)
|
||||
if (vf->lan_vsi_idx == 0)
|
||||
continue;
|
||||
|
||||
/* If VF is reset in another thread just continue */
|
||||
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
|
||||
i40e_vsi_stop_rings_no_wait(pf->vsi[vf->lan_vsi_idx]);
|
||||
}
|
||||
|
||||
/* Now that we've notified HW to disable all of the VF rings, wait
|
||||
* until they finish.
|
||||
*/
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++) {
|
||||
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
|
||||
/* On initial reset, we don't have any queues to disable */
|
||||
if (pf->vf[v].lan_vsi_idx == 0)
|
||||
if (vf->lan_vsi_idx == 0)
|
||||
continue;
|
||||
|
||||
/* If VF is reset in another thread just continue */
|
||||
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
|
||||
i40e_vsi_wait_queues_disabled(pf->vsi[vf->lan_vsi_idx]);
|
||||
}
|
||||
|
||||
/* Hw may need up to 50ms to finish disabling the RX queues. We
|
||||
@@ -1627,12 +1625,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
mdelay(50);
|
||||
|
||||
/* Finish the reset on each VF */
|
||||
for (v = 0; v < pf->num_alloc_vfs; v++) {
|
||||
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
|
||||
/* If VF is reset in another thread just continue */
|
||||
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
||||
continue;
|
||||
|
||||
i40e_cleanup_reset_vf(&pf->vf[v]);
|
||||
i40e_cleanup_reset_vf(vf);
|
||||
}
|
||||
|
||||
i40e_flush(hw);
|
||||
|
||||
@@ -909,7 +909,13 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
xs = kzalloc(sizeof(*xs), GFP_KERNEL);
|
||||
algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1);
|
||||
if (unlikely(!algo)) {
|
||||
err = -ENOENT;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
xs = kzalloc(sizeof(*xs), GFP_ATOMIC);
|
||||
if (unlikely(!xs)) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
@@ -925,14 +931,8 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
|
||||
memcpy(&xs->id.daddr.a4, sam->addr, sizeof(xs->id.daddr.a4));
|
||||
xs->xso.dev = adapter->netdev;
|
||||
|
||||
algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1);
|
||||
if (unlikely(!algo)) {
|
||||
err = -ENOENT;
|
||||
goto err_xs;
|
||||
}
|
||||
|
||||
aead_len = sizeof(*xs->aead) + IXGBE_IPSEC_KEY_BITS / 8;
|
||||
xs->aead = kzalloc(aead_len, GFP_KERNEL);
|
||||
xs->aead = kzalloc(aead_len, GFP_ATOMIC);
|
||||
if (unlikely(!xs->aead)) {
|
||||
err = -ENOMEM;
|
||||
goto err_xs;
|
||||
|
||||
@@ -1874,9 +1874,12 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif)
|
||||
|
||||
napi_enable(&qcq->napi);
|
||||
|
||||
if (qcq->flags & IONIC_QCQ_F_INTR)
|
||||
if (qcq->flags & IONIC_QCQ_F_INTR) {
|
||||
irq_set_affinity_hint(qcq->intr.vector,
|
||||
&qcq->intr.affinity_mask);
|
||||
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
|
||||
IONIC_INTR_MASK_CLEAR);
|
||||
}
|
||||
|
||||
qcq->flags |= IONIC_QCQ_F_INITED;
|
||||
|
||||
|
||||
@@ -6851,6 +6851,15 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
|
||||
struct mii_bus *new_bus;
|
||||
int ret;
|
||||
|
||||
/* On some boards with this chip version the BIOS is buggy and misses
|
||||
* to reset the PHY page selector. This results in the PHY ID read
|
||||
* accessing registers on a different page, returning a more or
|
||||
* less random value. Fix this by resetting the page selector first.
|
||||
*/
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_25 ||
|
||||
tp->mac_version == RTL_GIGA_MAC_VER_26)
|
||||
r8169_mdio_write(tp, 0x1f, 0);
|
||||
|
||||
new_bus = devm_mdiobus_alloc(&pdev->dev);
|
||||
if (!new_bus)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -911,12 +911,12 @@ static int ravb_poll(struct napi_struct *napi, int budget)
|
||||
int q = napi - priv->napi;
|
||||
int mask = BIT(q);
|
||||
int quota = budget;
|
||||
bool unmask;
|
||||
|
||||
/* Processing RX Descriptor Ring */
|
||||
/* Clear RX interrupt */
|
||||
ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
|
||||
if (ravb_rx(ndev, "a, q))
|
||||
goto out;
|
||||
unmask = !ravb_rx(ndev, "a, q);
|
||||
|
||||
/* Processing RX Descriptor Ring */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
@@ -926,6 +926,9 @@ static int ravb_poll(struct napi_struct *napi, int budget)
|
||||
netif_wake_subqueue(ndev, q);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
if (!unmask)
|
||||
goto out;
|
||||
|
||||
napi_complete(napi);
|
||||
|
||||
/* Re-enable RX/TX interrupts */
|
||||
|
||||
@@ -75,19 +75,41 @@ static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
|
||||
u32 prio, u32 queue)
|
||||
{
|
||||
void __iomem *ioaddr = hw->pcsr;
|
||||
u32 base_register;
|
||||
u32 value;
|
||||
u32 clear_mask = 0;
|
||||
u32 ctrl2, ctrl3;
|
||||
int i;
|
||||
|
||||
base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
|
||||
if (queue >= 4)
|
||||
ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
|
||||
ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
|
||||
|
||||
/* The software must ensure that the same priority
|
||||
* is not mapped to multiple Rx queues
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
clear_mask |= ((prio << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
|
||||
GMAC_RXQCTRL_PSRQX_MASK(i));
|
||||
|
||||
ctrl2 &= ~clear_mask;
|
||||
ctrl3 &= ~clear_mask;
|
||||
|
||||
/* First assign new priorities to a queue, then
|
||||
* clear them from others queues
|
||||
*/
|
||||
if (queue < 4) {
|
||||
ctrl2 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
|
||||
GMAC_RXQCTRL_PSRQX_MASK(queue);
|
||||
|
||||
writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
|
||||
writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
|
||||
} else {
|
||||
queue -= 4;
|
||||
|
||||
value = readl(ioaddr + base_register);
|
||||
|
||||
value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
|
||||
value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
|
||||
ctrl3 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
|
||||
GMAC_RXQCTRL_PSRQX_MASK(queue);
|
||||
writel(value, ioaddr + base_register);
|
||||
|
||||
writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
|
||||
writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
|
||||
}
|
||||
}
|
||||
|
||||
static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
|
||||
|
||||
@@ -96,17 +96,41 @@ static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
|
||||
u32 queue)
|
||||
{
|
||||
void __iomem *ioaddr = hw->pcsr;
|
||||
u32 value, reg;
|
||||
u32 clear_mask = 0;
|
||||
u32 ctrl2, ctrl3;
|
||||
int i;
|
||||
|
||||
reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
|
||||
if (queue >= 4)
|
||||
ctrl2 = readl(ioaddr + XGMAC_RXQ_CTRL2);
|
||||
ctrl3 = readl(ioaddr + XGMAC_RXQ_CTRL3);
|
||||
|
||||
/* The software must ensure that the same priority
|
||||
* is not mapped to multiple Rx queues
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
clear_mask |= ((prio << XGMAC_PSRQ_SHIFT(i)) &
|
||||
XGMAC_PSRQ(i));
|
||||
|
||||
ctrl2 &= ~clear_mask;
|
||||
ctrl3 &= ~clear_mask;
|
||||
|
||||
/* First assign new priorities to a queue, then
|
||||
* clear them from others queues
|
||||
*/
|
||||
if (queue < 4) {
|
||||
ctrl2 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
|
||||
XGMAC_PSRQ(queue);
|
||||
|
||||
writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
|
||||
writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
|
||||
} else {
|
||||
queue -= 4;
|
||||
|
||||
value = readl(ioaddr + reg);
|
||||
value &= ~XGMAC_PSRQ(queue);
|
||||
value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
|
||||
ctrl3 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
|
||||
XGMAC_PSRQ(queue);
|
||||
|
||||
writel(value, ioaddr + reg);
|
||||
writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
|
||||
writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
|
||||
}
|
||||
}
|
||||
|
||||
static void dwxgmac2_tx_queue_prio(struct mac_device_info *hw, u32 prio,
|
||||
|
||||
@@ -643,7 +643,7 @@ static void ath_ant_try_scan(struct ath_ant_comb *antcomb,
|
||||
conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
} else if (antcomb->rssi_sub >
|
||||
antcomb->rssi_lna1) {
|
||||
antcomb->rssi_lna2) {
|
||||
/* set to A-B */
|
||||
conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
|
||||
@@ -710,8 +710,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
|
||||
scan_request = cfg->scan_request;
|
||||
cfg->scan_request = NULL;
|
||||
|
||||
if (timer_pending(&cfg->escan_timeout))
|
||||
del_timer_sync(&cfg->escan_timeout);
|
||||
timer_delete_sync(&cfg->escan_timeout);
|
||||
|
||||
if (fw_abort) {
|
||||
/* Do a scan abort to stop the driver's scan engine */
|
||||
@@ -7240,6 +7239,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
|
||||
brcmf_btcoex_detach(cfg);
|
||||
wiphy_unregister(cfg->wiphy);
|
||||
wl_deinit_priv(cfg);
|
||||
cancel_work_sync(&cfg->escan_timeout_work);
|
||||
brcmf_free_wiphy(cfg->wiphy);
|
||||
kfree(cfg);
|
||||
}
|
||||
|
||||
@@ -17,14 +17,18 @@
|
||||
static int meson_efuse_read(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset,
|
||||
struct meson_sm_firmware *fw = context;
|
||||
|
||||
return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
|
||||
bytes, 0, 0, 0);
|
||||
}
|
||||
|
||||
static int meson_efuse_write(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset,
|
||||
struct meson_sm_firmware *fw = context;
|
||||
|
||||
return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
|
||||
bytes, 0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -37,35 +41,29 @@ MODULE_DEVICE_TABLE(of, meson_efuse_match);
|
||||
static int meson_efuse_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct meson_sm_firmware *fw;
|
||||
struct device_node *sm_np;
|
||||
struct nvmem_device *nvmem;
|
||||
struct nvmem_config *econfig;
|
||||
struct clk *clk;
|
||||
unsigned int size;
|
||||
int ret;
|
||||
|
||||
clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get efuse gate");
|
||||
return ret;
|
||||
sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
|
||||
if (!sm_np) {
|
||||
dev_err(&pdev->dev, "no secure-monitor node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable gate");
|
||||
return ret;
|
||||
}
|
||||
fw = meson_sm_get(sm_np);
|
||||
of_node_put(sm_np);
|
||||
if (!fw)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
ret = devm_add_action_or_reset(dev,
|
||||
(void(*)(void *))clk_disable_unprepare,
|
||||
clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add disable callback");
|
||||
return ret;
|
||||
}
|
||||
clk = devm_clk_get_enabled(dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk), "failed to get efuse gate");
|
||||
|
||||
if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
|
||||
if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
|
||||
dev_err(dev, "failed to get max user");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -81,6 +79,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
|
||||
econfig->reg_read = meson_efuse_read;
|
||||
econfig->reg_write = meson_efuse_write;
|
||||
econfig->size = size;
|
||||
econfig->priv = fw;
|
||||
|
||||
nvmem = devm_nvmem_register(&pdev->dev, econfig);
|
||||
|
||||
|
||||
@@ -439,16 +439,21 @@ static int pci_device_remove(struct device *dev)
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct pci_driver *drv = pci_dev->driver;
|
||||
|
||||
if (drv) {
|
||||
if (drv->remove) {
|
||||
pm_runtime_get_sync(dev);
|
||||
drv->remove(pci_dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
}
|
||||
pcibios_free_irq(pci_dev);
|
||||
pci_dev->driver = NULL;
|
||||
pci_iov_remove(pci_dev);
|
||||
if (drv->remove) {
|
||||
pm_runtime_get_sync(dev);
|
||||
/*
|
||||
* If the driver provides a .runtime_idle() callback and it has
|
||||
* started to run already, it may continue to run in parallel
|
||||
* with the code below, so wait until all of the runtime PM
|
||||
* activity has completed.
|
||||
*/
|
||||
pm_runtime_barrier(dev);
|
||||
drv->remove(pci_dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
}
|
||||
pcibios_free_irq(pci_dev);
|
||||
pci_dev->driver = NULL;
|
||||
pci_iov_remove(pci_dev);
|
||||
|
||||
/* Undo the runtime PM settings in local_pci_probe() */
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
@@ -574,6 +574,7 @@ static inline struct zcrypt_queue *zcrypt_pick_queue(struct zcrypt_card *zc,
|
||||
{
|
||||
if (!zq || !try_module_get(zq->queue->ap_dev.drv->driver.owner))
|
||||
return NULL;
|
||||
zcrypt_card_get(zc);
|
||||
zcrypt_queue_get(zq);
|
||||
get_device(&zq->queue->ap_dev.device);
|
||||
atomic_add(weight, &zc->load);
|
||||
@@ -593,6 +594,7 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
|
||||
atomic_sub(weight, &zq->load);
|
||||
put_device(&zq->queue->ap_dev.device);
|
||||
zcrypt_queue_put(zq);
|
||||
zcrypt_card_put(zc);
|
||||
module_put(mod);
|
||||
}
|
||||
|
||||
|
||||
@@ -331,12 +331,13 @@ static void scsi_host_dev_release(struct device *dev)
|
||||
|
||||
if (shost->shost_state == SHOST_CREATED) {
|
||||
/*
|
||||
* Free the shost_dev device name here if scsi_host_alloc()
|
||||
* and scsi_host_put() have been called but neither
|
||||
* Free the shost_dev device name and remove the proc host dir
|
||||
* here if scsi_host_{alloc,put}() have been called but neither
|
||||
* scsi_host_add() nor scsi_host_remove() has been called.
|
||||
* This avoids that the memory allocated for the shost_dev
|
||||
* name is leaked.
|
||||
* name as well as the proc dir structure are leaked.
|
||||
*/
|
||||
scsi_proc_hostdir_rm(shost->hostt);
|
||||
kfree(dev_name(&shost->shost_dev));
|
||||
}
|
||||
|
||||
|
||||
@@ -781,8 +781,10 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
/* Save the ELS cmd */
|
||||
elsiocb->drvrTimeout = cmd;
|
||||
|
||||
lpfc_sli4_resume_rpi(ndlp,
|
||||
lpfc_mbx_cmpl_resume_rpi, elsiocb);
|
||||
if (lpfc_sli4_resume_rpi(ndlp,
|
||||
lpfc_mbx_cmpl_resume_rpi,
|
||||
elsiocb))
|
||||
kfree(elsiocb);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1392,7 +1392,7 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba)
|
||||
wqe = &nvmewqe->wqe;
|
||||
|
||||
/* Initialize WQE */
|
||||
memset(wqe, 0, sizeof(union lpfc_wqe));
|
||||
memset(wqe, 0, sizeof(*wqe));
|
||||
|
||||
ctx_buf->iocbq->context1 = NULL;
|
||||
spin_lock(&phba->sli4_hba.sgl_list_lock);
|
||||
|
||||
@@ -1803,9 +1803,9 @@ static ssize_t raid_state_show(struct device *dev,
|
||||
|
||||
name = myrb_devstate_name(ldev_info->state);
|
||||
if (name)
|
||||
ret = snprintf(buf, 32, "%s\n", name);
|
||||
ret = snprintf(buf, 64, "%s\n", name);
|
||||
else
|
||||
ret = snprintf(buf, 32, "Invalid (%02X)\n",
|
||||
ret = snprintf(buf, 64, "Invalid (%02X)\n",
|
||||
ldev_info->state);
|
||||
} else {
|
||||
struct myrb_pdev_state *pdev_info = sdev->hostdata;
|
||||
@@ -1824,9 +1824,9 @@ static ssize_t raid_state_show(struct device *dev,
|
||||
else
|
||||
name = myrb_devstate_name(pdev_info->state);
|
||||
if (name)
|
||||
ret = snprintf(buf, 32, "%s\n", name);
|
||||
ret = snprintf(buf, 64, "%s\n", name);
|
||||
else
|
||||
ret = snprintf(buf, 32, "Invalid (%02X)\n",
|
||||
ret = snprintf(buf, 64, "Invalid (%02X)\n",
|
||||
pdev_info->state);
|
||||
}
|
||||
return ret;
|
||||
@@ -1914,11 +1914,11 @@ static ssize_t raid_level_show(struct device *dev,
|
||||
|
||||
name = myrb_raidlevel_name(ldev_info->raid_level);
|
||||
if (!name)
|
||||
return snprintf(buf, 32, "Invalid (%02X)\n",
|
||||
return snprintf(buf, 64, "Invalid (%02X)\n",
|
||||
ldev_info->state);
|
||||
return snprintf(buf, 32, "%s\n", name);
|
||||
return snprintf(buf, 64, "%s\n", name);
|
||||
}
|
||||
return snprintf(buf, 32, "Physical Drive\n");
|
||||
return snprintf(buf, 64, "Physical Drive\n");
|
||||
}
|
||||
static DEVICE_ATTR_RO(raid_level);
|
||||
|
||||
@@ -1931,15 +1931,15 @@ static ssize_t rebuild_show(struct device *dev,
|
||||
unsigned char status;
|
||||
|
||||
if (sdev->channel < myrb_logical_channel(sdev->host))
|
||||
return snprintf(buf, 32, "physical device - not rebuilding\n");
|
||||
return snprintf(buf, 64, "physical device - not rebuilding\n");
|
||||
|
||||
status = myrb_get_rbld_progress(cb, &rbld_buf);
|
||||
|
||||
if (rbld_buf.ldev_num != sdev->id ||
|
||||
status != MYRB_STATUS_SUCCESS)
|
||||
return snprintf(buf, 32, "not rebuilding\n");
|
||||
return snprintf(buf, 64, "not rebuilding\n");
|
||||
|
||||
return snprintf(buf, 32, "rebuilding block %u of %u\n",
|
||||
return snprintf(buf, 64, "rebuilding block %u of %u\n",
|
||||
rbld_buf.ldev_size - rbld_buf.blocks_left,
|
||||
rbld_buf.ldev_size);
|
||||
}
|
||||
|
||||
@@ -950,9 +950,9 @@ static ssize_t raid_state_show(struct device *dev,
|
||||
|
||||
name = myrs_devstate_name(ldev_info->dev_state);
|
||||
if (name)
|
||||
ret = snprintf(buf, 32, "%s\n", name);
|
||||
ret = snprintf(buf, 64, "%s\n", name);
|
||||
else
|
||||
ret = snprintf(buf, 32, "Invalid (%02X)\n",
|
||||
ret = snprintf(buf, 64, "Invalid (%02X)\n",
|
||||
ldev_info->dev_state);
|
||||
} else {
|
||||
struct myrs_pdev_info *pdev_info;
|
||||
@@ -961,9 +961,9 @@ static ssize_t raid_state_show(struct device *dev,
|
||||
pdev_info = sdev->hostdata;
|
||||
name = myrs_devstate_name(pdev_info->dev_state);
|
||||
if (name)
|
||||
ret = snprintf(buf, 32, "%s\n", name);
|
||||
ret = snprintf(buf, 64, "%s\n", name);
|
||||
else
|
||||
ret = snprintf(buf, 32, "Invalid (%02X)\n",
|
||||
ret = snprintf(buf, 64, "Invalid (%02X)\n",
|
||||
pdev_info->dev_state);
|
||||
}
|
||||
return ret;
|
||||
@@ -1069,13 +1069,13 @@ static ssize_t raid_level_show(struct device *dev,
|
||||
ldev_info = sdev->hostdata;
|
||||
name = myrs_raid_level_name(ldev_info->raid_level);
|
||||
if (!name)
|
||||
return snprintf(buf, 32, "Invalid (%02X)\n",
|
||||
return snprintf(buf, 64, "Invalid (%02X)\n",
|
||||
ldev_info->dev_state);
|
||||
|
||||
} else
|
||||
name = myrs_raid_level_name(MYRS_RAID_PHYSICAL);
|
||||
|
||||
return snprintf(buf, 32, "%s\n", name);
|
||||
return snprintf(buf, 64, "%s\n", name);
|
||||
}
|
||||
static DEVICE_ATTR_RO(raid_level);
|
||||
|
||||
@@ -1089,7 +1089,7 @@ static ssize_t rebuild_show(struct device *dev,
|
||||
unsigned char status;
|
||||
|
||||
if (sdev->channel < cs->ctlr_info->physchan_present)
|
||||
return snprintf(buf, 32, "physical device - not rebuilding\n");
|
||||
return snprintf(buf, 64, "physical device - not rebuilding\n");
|
||||
|
||||
ldev_info = sdev->hostdata;
|
||||
ldev_num = ldev_info->ldev_num;
|
||||
@@ -1101,11 +1101,11 @@ static ssize_t rebuild_show(struct device *dev,
|
||||
return -EIO;
|
||||
}
|
||||
if (ldev_info->rbld_active) {
|
||||
return snprintf(buf, 32, "rebuilding block %zu of %zu\n",
|
||||
return snprintf(buf, 64, "rebuilding block %zu of %zu\n",
|
||||
(size_t)ldev_info->rbld_lba,
|
||||
(size_t)ldev_info->cfg_devsize);
|
||||
} else
|
||||
return snprintf(buf, 32, "not rebuilding\n");
|
||||
return snprintf(buf, 64, "not rebuilding\n");
|
||||
}
|
||||
|
||||
static ssize_t rebuild_store(struct device *dev,
|
||||
@@ -1194,7 +1194,7 @@ static ssize_t consistency_check_show(struct device *dev,
|
||||
unsigned char status;
|
||||
|
||||
if (sdev->channel < cs->ctlr_info->physchan_present)
|
||||
return snprintf(buf, 32, "physical device - not checking\n");
|
||||
return snprintf(buf, 64, "physical device - not checking\n");
|
||||
|
||||
ldev_info = sdev->hostdata;
|
||||
if (!ldev_info)
|
||||
@@ -1202,11 +1202,11 @@ static ssize_t consistency_check_show(struct device *dev,
|
||||
ldev_num = ldev_info->ldev_num;
|
||||
status = myrs_get_ldev_info(cs, ldev_num, ldev_info);
|
||||
if (ldev_info->cc_active)
|
||||
return snprintf(buf, 32, "checking block %zu of %zu\n",
|
||||
return snprintf(buf, 64, "checking block %zu of %zu\n",
|
||||
(size_t)ldev_info->cc_lba,
|
||||
(size_t)ldev_info->cfg_devsize);
|
||||
else
|
||||
return snprintf(buf, 32, "not checking\n");
|
||||
return snprintf(buf, 64, "not checking\n");
|
||||
}
|
||||
|
||||
static ssize_t consistency_check_store(struct device *dev,
|
||||
|
||||
@@ -1040,6 +1040,16 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
"%s: sess %p logout completed\n", __func__, sess);
|
||||
}
|
||||
|
||||
/* check for any straggling io left behind */
|
||||
if (!(sess->flags & FCF_FCP2_DEVICE) &&
|
||||
qla2x00_eh_wait_for_pending_commands(sess->vha, sess->d_id.b24, 0, WAIT_TARGET)) {
|
||||
ql_log(ql_log_warn, vha, 0x3027,
|
||||
"IO not return. Resetting.\n");
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
qla2x00_wait_for_chip_reset(vha);
|
||||
}
|
||||
|
||||
if (sess->logo_ack_needed) {
|
||||
sess->logo_ack_needed = 0;
|
||||
qla24xx_async_notify_ack(vha, sess,
|
||||
|
||||
@@ -439,8 +439,8 @@ static int slim_device_alloc_laddr(struct slim_device *sbdev,
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
} else if (report_present) {
|
||||
ret = ida_simple_get(&ctrl->laddr_ida,
|
||||
0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
|
||||
ret = ida_alloc_max(&ctrl->laddr_ida,
|
||||
SLIM_LA_MANAGER - 1, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
|
||||
@@ -996,7 +996,7 @@ struct qman_portal {
|
||||
/* linked-list of CSCN handlers. */
|
||||
struct list_head cgr_cbs;
|
||||
/* list lock */
|
||||
spinlock_t cgr_lock;
|
||||
raw_spinlock_t cgr_lock;
|
||||
struct work_struct congestion_work;
|
||||
struct work_struct mr_work;
|
||||
char irqname[MAX_IRQNAME];
|
||||
@@ -1286,7 +1286,7 @@ static int qman_create_portal(struct qman_portal *portal,
|
||||
/* if the given mask is NULL, assume all CGRs can be seen */
|
||||
qman_cgrs_fill(&portal->cgrs[0]);
|
||||
INIT_LIST_HEAD(&portal->cgr_cbs);
|
||||
spin_lock_init(&portal->cgr_lock);
|
||||
raw_spin_lock_init(&portal->cgr_lock);
|
||||
INIT_WORK(&portal->congestion_work, qm_congestion_task);
|
||||
INIT_WORK(&portal->mr_work, qm_mr_process_task);
|
||||
portal->bits = 0;
|
||||
@@ -1461,11 +1461,14 @@ static void qm_congestion_task(struct work_struct *work)
|
||||
union qm_mc_result *mcr;
|
||||
struct qman_cgr *cgr;
|
||||
|
||||
spin_lock(&p->cgr_lock);
|
||||
/*
|
||||
* FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
|
||||
*/
|
||||
raw_spin_lock_irq(&p->cgr_lock);
|
||||
qm_mc_start(&p->p);
|
||||
qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
|
||||
if (!qm_mc_result_timeout(&p->p, &mcr)) {
|
||||
spin_unlock(&p->cgr_lock);
|
||||
raw_spin_unlock_irq(&p->cgr_lock);
|
||||
dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
|
||||
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
|
||||
return;
|
||||
@@ -1481,7 +1484,7 @@ static void qm_congestion_task(struct work_struct *work)
|
||||
list_for_each_entry(cgr, &p->cgr_cbs, node)
|
||||
if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
|
||||
cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
|
||||
spin_unlock(&p->cgr_lock);
|
||||
raw_spin_unlock_irq(&p->cgr_lock);
|
||||
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
|
||||
}
|
||||
|
||||
@@ -2438,7 +2441,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
|
||||
preempt_enable();
|
||||
|
||||
cgr->chan = p->config->channel;
|
||||
spin_lock(&p->cgr_lock);
|
||||
raw_spin_lock_irq(&p->cgr_lock);
|
||||
|
||||
if (opts) {
|
||||
struct qm_mcc_initcgr local_opts = *opts;
|
||||
@@ -2475,12 +2478,28 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
|
||||
qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
|
||||
cgr->cb(p, cgr, 1);
|
||||
out:
|
||||
spin_unlock(&p->cgr_lock);
|
||||
raw_spin_unlock_irq(&p->cgr_lock);
|
||||
put_affine_portal();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(qman_create_cgr);
|
||||
|
||||
static struct qman_portal *qman_cgr_get_affine_portal(struct qman_cgr *cgr)
|
||||
{
|
||||
struct qman_portal *p = get_affine_portal();
|
||||
|
||||
if (cgr->chan != p->config->channel) {
|
||||
/* attempt to delete from other portal than creator */
|
||||
dev_err(p->config->dev, "CGR not owned by current portal");
|
||||
dev_dbg(p->config->dev, " create 0x%x, delete 0x%x\n",
|
||||
cgr->chan, p->config->channel);
|
||||
put_affine_portal();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
@@ -2488,19 +2507,13 @@ int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
struct qm_mcc_initcgr local_opts;
|
||||
int ret = 0;
|
||||
struct qman_cgr *i;
|
||||
struct qman_portal *p = get_affine_portal();
|
||||
struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
|
||||
|
||||
if (cgr->chan != p->config->channel) {
|
||||
/* attempt to delete from other portal than creator */
|
||||
dev_err(p->config->dev, "CGR not owned by current portal");
|
||||
dev_dbg(p->config->dev, " create 0x%x, delete 0x%x\n",
|
||||
cgr->chan, p->config->channel);
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
ret = -EINVAL;
|
||||
goto put_portal;
|
||||
}
|
||||
memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
|
||||
spin_lock_irqsave(&p->cgr_lock, irqflags);
|
||||
raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
|
||||
list_del(&cgr->node);
|
||||
/*
|
||||
* If there are no other CGR objects for this CGRID in the list,
|
||||
@@ -2525,8 +2538,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
|
||||
/* add back to the list */
|
||||
list_add(&cgr->node, &p->cgr_cbs);
|
||||
release_lock:
|
||||
spin_unlock_irqrestore(&p->cgr_lock, irqflags);
|
||||
put_portal:
|
||||
raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
|
||||
put_affine_portal();
|
||||
return ret;
|
||||
}
|
||||
@@ -2557,6 +2569,54 @@ void qman_delete_cgr_safe(struct qman_cgr *cgr)
|
||||
}
|
||||
EXPORT_SYMBOL(qman_delete_cgr_safe);
|
||||
|
||||
static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
|
||||
{
|
||||
int ret;
|
||||
unsigned long irqflags;
|
||||
struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
|
||||
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
|
||||
ret = qm_modify_cgr(cgr, 0, opts);
|
||||
raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
|
||||
put_affine_portal();
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct update_cgr_params {
|
||||
struct qman_cgr *cgr;
|
||||
struct qm_mcc_initcgr *opts;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static void qman_update_cgr_smp_call(void *p)
|
||||
{
|
||||
struct update_cgr_params *params = p;
|
||||
|
||||
params->ret = qman_update_cgr(params->cgr, params->opts);
|
||||
}
|
||||
|
||||
int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
|
||||
{
|
||||
struct update_cgr_params params = {
|
||||
.cgr = cgr,
|
||||
.opts = opts,
|
||||
};
|
||||
|
||||
preempt_disable();
|
||||
if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id())
|
||||
smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
|
||||
qman_update_cgr_smp_call, ¶ms,
|
||||
true);
|
||||
else
|
||||
params.ret = qman_update_cgr(cgr, opts);
|
||||
preempt_enable();
|
||||
return params.ret;
|
||||
}
|
||||
EXPORT_SYMBOL(qman_update_cgr_safe);
|
||||
|
||||
/* Cleanup FQs */
|
||||
|
||||
static int _qm_mr_consume_and_match_verb(struct qm_portal *p, int v)
|
||||
|
||||
@@ -87,6 +87,8 @@ struct waveform_private {
|
||||
struct comedi_device *dev; /* parent comedi device */
|
||||
u64 ao_last_scan_time; /* time of previous AO scan in usec */
|
||||
unsigned int ao_scan_period; /* AO scan period in usec */
|
||||
bool ai_timer_enable:1; /* should AI timer be running? */
|
||||
bool ao_timer_enable:1; /* should AO timer be running? */
|
||||
unsigned short ao_loopbacks[N_CHANS];
|
||||
};
|
||||
|
||||
@@ -236,8 +238,12 @@ static void waveform_ai_timer(struct timer_list *t)
|
||||
time_increment = devpriv->ai_convert_time - now;
|
||||
else
|
||||
time_increment = 1;
|
||||
mod_timer(&devpriv->ai_timer,
|
||||
jiffies + usecs_to_jiffies(time_increment));
|
||||
spin_lock(&dev->spinlock);
|
||||
if (devpriv->ai_timer_enable) {
|
||||
mod_timer(&devpriv->ai_timer,
|
||||
jiffies + usecs_to_jiffies(time_increment));
|
||||
}
|
||||
spin_unlock(&dev->spinlock);
|
||||
}
|
||||
|
||||
overrun:
|
||||
@@ -393,9 +399,12 @@ static int waveform_ai_cmd(struct comedi_device *dev,
|
||||
* Seem to need an extra jiffy here, otherwise timer expires slightly
|
||||
* early!
|
||||
*/
|
||||
spin_lock_bh(&dev->spinlock);
|
||||
devpriv->ai_timer_enable = true;
|
||||
devpriv->ai_timer.expires =
|
||||
jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1;
|
||||
add_timer(&devpriv->ai_timer);
|
||||
spin_unlock_bh(&dev->spinlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -404,6 +413,9 @@ static int waveform_ai_cancel(struct comedi_device *dev,
|
||||
{
|
||||
struct waveform_private *devpriv = dev->private;
|
||||
|
||||
spin_lock_bh(&dev->spinlock);
|
||||
devpriv->ai_timer_enable = false;
|
||||
spin_unlock_bh(&dev->spinlock);
|
||||
if (in_softirq()) {
|
||||
/* Assume we were called from the timer routine itself. */
|
||||
del_timer(&devpriv->ai_timer);
|
||||
@@ -495,8 +507,12 @@ static void waveform_ao_timer(struct timer_list *t)
|
||||
unsigned int time_inc = devpriv->ao_last_scan_time +
|
||||
devpriv->ao_scan_period - now;
|
||||
|
||||
mod_timer(&devpriv->ao_timer,
|
||||
jiffies + usecs_to_jiffies(time_inc));
|
||||
spin_lock(&dev->spinlock);
|
||||
if (devpriv->ao_timer_enable) {
|
||||
mod_timer(&devpriv->ao_timer,
|
||||
jiffies + usecs_to_jiffies(time_inc));
|
||||
}
|
||||
spin_unlock(&dev->spinlock);
|
||||
}
|
||||
|
||||
underrun:
|
||||
@@ -517,9 +533,12 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev,
|
||||
async->inttrig = NULL;
|
||||
|
||||
devpriv->ao_last_scan_time = ktime_to_us(ktime_get());
|
||||
spin_lock_bh(&dev->spinlock);
|
||||
devpriv->ao_timer_enable = true;
|
||||
devpriv->ao_timer.expires =
|
||||
jiffies + usecs_to_jiffies(devpriv->ao_scan_period);
|
||||
add_timer(&devpriv->ao_timer);
|
||||
spin_unlock_bh(&dev->spinlock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -604,6 +623,9 @@ static int waveform_ao_cancel(struct comedi_device *dev,
|
||||
struct waveform_private *devpriv = dev->private;
|
||||
|
||||
s->async->inttrig = NULL;
|
||||
spin_lock_bh(&dev->spinlock);
|
||||
devpriv->ao_timer_enable = false;
|
||||
spin_unlock_bh(&dev->spinlock);
|
||||
if (in_softirq()) {
|
||||
/* Assume we were called from the timer routine itself. */
|
||||
del_timer(&devpriv->ao_timer);
|
||||
|
||||
@@ -1115,6 +1115,11 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
|
||||
struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
|
||||
|
||||
/* Initialize subdev media entity */
|
||||
imgu_sd->subdev.entity.ops = &imgu_media_ops;
|
||||
for (i = 0; i < IMGU_NODE_NUM; i++) {
|
||||
imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
|
||||
MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
|
||||
}
|
||||
r = media_entity_pads_init(&imgu_sd->subdev.entity, IMGU_NODE_NUM,
|
||||
imgu_sd->subdev_pads);
|
||||
if (r) {
|
||||
@@ -1122,11 +1127,6 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
|
||||
"failed initialize subdev media entity (%d)\n", r);
|
||||
return r;
|
||||
}
|
||||
imgu_sd->subdev.entity.ops = &imgu_media_ops;
|
||||
for (i = 0; i < IMGU_NODE_NUM; i++) {
|
||||
imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
|
||||
MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
|
||||
}
|
||||
|
||||
/* Initialize subdev */
|
||||
v4l2_subdev_init(&imgu_sd->subdev, &imgu_subdev_ops);
|
||||
@@ -1221,15 +1221,15 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe,
|
||||
}
|
||||
|
||||
/* Initialize media entities */
|
||||
node->vdev_pad.flags = node->output ?
|
||||
MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
|
||||
vdev->entity.ops = NULL;
|
||||
r = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad);
|
||||
if (r) {
|
||||
dev_err(dev, "failed initialize media entity (%d)\n", r);
|
||||
mutex_destroy(&node->lock);
|
||||
return r;
|
||||
}
|
||||
node->vdev_pad.flags = node->output ?
|
||||
MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
|
||||
vdev->entity.ops = NULL;
|
||||
|
||||
/* Initialize vbq */
|
||||
vbq->type = node->vdev_fmt.type;
|
||||
|
||||
@@ -208,8 +208,10 @@ void spk_do_flush(void)
|
||||
wake_up_process(speakup_task);
|
||||
}
|
||||
|
||||
void synth_write(const char *buf, size_t count)
|
||||
void synth_write(const char *_buf, size_t count)
|
||||
{
|
||||
const unsigned char *buf = (const unsigned char *) _buf;
|
||||
|
||||
while (count--)
|
||||
synth_buffer_add(*buf++);
|
||||
synth_start();
|
||||
|
||||
@@ -31,8 +31,11 @@
|
||||
#define USE_VCHIQ_ARM
|
||||
#include "interface/vchi/vchi.h"
|
||||
|
||||
/* maximum number of components supported */
|
||||
#define VCHIQ_MMAL_MAX_COMPONENTS 4
|
||||
/*
|
||||
* maximum number of components supported.
|
||||
* This matches the maximum permitted by default on the VPU
|
||||
*/
|
||||
#define VCHIQ_MMAL_MAX_COMPONENTS 64
|
||||
|
||||
/*#define FULL_MSG_DUMP 1*/
|
||||
|
||||
@@ -167,8 +170,6 @@ struct vchiq_mmal_instance {
|
||||
/* protect accesses to context_map */
|
||||
struct mutex context_map_lock;
|
||||
|
||||
/* component to use next */
|
||||
int component_idx;
|
||||
struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS];
|
||||
|
||||
/* ordered workqueue to process all bulk operations */
|
||||
@@ -927,9 +928,10 @@ static int create_component(struct vchiq_mmal_instance *instance,
|
||||
|
||||
/* build component create message */
|
||||
m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE;
|
||||
m.u.component_create.client_component = (u32)(unsigned long)component;
|
||||
strncpy(m.u.component_create.name, name,
|
||||
sizeof(m.u.component_create.name));
|
||||
m.u.component_create.client_component = component->client_component;
|
||||
strscpy_pad(m.u.component_create.name, name,
|
||||
sizeof(m.u.component_create.name));
|
||||
m.u.component_create.pid = 0;
|
||||
|
||||
ret = send_synchronous_mmal_msg(instance, &m,
|
||||
sizeof(m.u.component_create),
|
||||
@@ -1616,17 +1618,29 @@ int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
|
||||
{
|
||||
int ret;
|
||||
int idx; /* port index */
|
||||
struct vchiq_mmal_component *component;
|
||||
struct vchiq_mmal_component *component = NULL;
|
||||
|
||||
if (mutex_lock_interruptible(&instance->vchiq_mutex))
|
||||
return -EINTR;
|
||||
|
||||
if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) {
|
||||
for (idx = 0; idx < VCHIQ_MMAL_MAX_COMPONENTS; idx++) {
|
||||
if (!instance->component[idx].in_use) {
|
||||
component = &instance->component[idx];
|
||||
component->in_use = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!component) {
|
||||
ret = -EINVAL; /* todo is this correct error? */
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
component = &instance->component[instance->component_idx];
|
||||
/* We need a handle to reference back to our component structure.
|
||||
* Use the array index in instance->component rather than rolling
|
||||
* another IDR.
|
||||
*/
|
||||
component->client_component = idx;
|
||||
|
||||
ret = create_component(instance, component, name);
|
||||
if (ret < 0) {
|
||||
@@ -1678,8 +1692,6 @@ int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
|
||||
goto release_component;
|
||||
}
|
||||
|
||||
instance->component_idx++;
|
||||
|
||||
*component_out = component;
|
||||
|
||||
mutex_unlock(&instance->vchiq_mutex);
|
||||
@@ -1689,6 +1701,8 @@ int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
|
||||
release_component:
|
||||
destroy_component(instance, component);
|
||||
unlock:
|
||||
if (component)
|
||||
component->in_use = 0;
|
||||
mutex_unlock(&instance->vchiq_mutex);
|
||||
|
||||
return ret;
|
||||
@@ -1710,6 +1724,8 @@ int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance,
|
||||
|
||||
ret = destroy_component(instance, component);
|
||||
|
||||
component->in_use = 0;
|
||||
|
||||
mutex_unlock(&instance->vchiq_mutex);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -82,6 +82,7 @@ struct vchiq_mmal_port {
|
||||
};
|
||||
|
||||
struct vchiq_mmal_component {
|
||||
u32 in_use:1;
|
||||
u32 enabled:1;
|
||||
u32 handle; /* VideoCore handle for component */
|
||||
u32 inputs; /* Number of input ports */
|
||||
@@ -91,6 +92,7 @@ struct vchiq_mmal_component {
|
||||
struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */
|
||||
struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */
|
||||
struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */
|
||||
u32 client_component; /* Used to ref back to client struct */
|
||||
};
|
||||
|
||||
int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance);
|
||||
|
||||
@@ -2567,6 +2567,9 @@ static int gsmld_open(struct tty_struct *tty)
|
||||
struct gsm_mux *gsm;
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (tty->ops->write == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -2025,9 +2025,12 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
UARTCTRL);
|
||||
|
||||
lpuart32_serial_setbrg(sport, baud);
|
||||
lpuart32_write(&sport->port, modem, UARTMODIR);
|
||||
lpuart32_write(&sport->port, ctrl, UARTCTRL);
|
||||
/* disable CTS before enabling UARTCTRL_TE to avoid pending idle preamble */
|
||||
lpuart32_write(&sport->port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
|
||||
/* restore control register */
|
||||
lpuart32_write(&sport->port, ctrl, UARTCTRL);
|
||||
/* re-enable the CTS if needed */
|
||||
lpuart32_write(&sport->port, modem, UARTMODIR);
|
||||
|
||||
if (old && sport->lpuart_dma_rx_use) {
|
||||
if (!lpuart_start_rx_dma(sport))
|
||||
|
||||
@@ -1636,13 +1636,16 @@ static unsigned short max310x_i2c_slave_addr(unsigned short addr,
|
||||
|
||||
static int max310x_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct max310x_devtype *devtype =
|
||||
device_get_match_data(&client->dev);
|
||||
const struct max310x_devtype *devtype;
|
||||
struct i2c_client *port_client;
|
||||
struct regmap *regmaps[4];
|
||||
unsigned int i;
|
||||
u8 port_addr;
|
||||
|
||||
devtype = device_get_match_data(&client->dev);
|
||||
if (!devtype)
|
||||
return dev_err_probe(&client->dev, -ENODEV, "Failed to match device\n");
|
||||
|
||||
if (client->addr < devtype->slave_addr.min ||
|
||||
client->addr > devtype->slave_addr.max)
|
||||
return dev_err_probe(&client->dev, -EINVAL,
|
||||
|
||||
@@ -405,7 +405,7 @@ static void vc_uniscr_delete(struct vc_data *vc, unsigned int nr)
|
||||
char32_t *ln = uniscr->lines[vc->vc_y];
|
||||
unsigned int x = vc->vc_x, cols = vc->vc_cols;
|
||||
|
||||
memcpy(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln));
|
||||
memmove(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln));
|
||||
memset32(&ln[cols - nr], ' ', nr);
|
||||
}
|
||||
}
|
||||
@@ -855,7 +855,7 @@ static void delete_char(struct vc_data *vc, unsigned int nr)
|
||||
unsigned short *p = (unsigned short *) vc->vc_pos;
|
||||
|
||||
vc_uniscr_delete(vc, nr);
|
||||
scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
|
||||
scr_memmovew(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
|
||||
scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
|
||||
nr * 2);
|
||||
vc->vc_need_wrap = 0;
|
||||
|
||||
@@ -471,6 +471,7 @@ out_free_mem:
|
||||
static int service_outstanding_interrupt(struct wdm_device *desc)
|
||||
{
|
||||
int rv = 0;
|
||||
int used;
|
||||
|
||||
/* submit read urb only if the device is waiting for it */
|
||||
if (!desc->resp_count || !--desc->resp_count)
|
||||
@@ -485,7 +486,10 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
set_bit(WDM_RESPONDING, &desc->flags);
|
||||
used = test_and_set_bit(WDM_RESPONDING, &desc->flags);
|
||||
if (used)
|
||||
goto out;
|
||||
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
rv = usb_submit_urb(desc->response, GFP_KERNEL);
|
||||
spin_lock_irq(&desc->iuspin);
|
||||
|
||||
@@ -450,7 +450,7 @@ static int match_location(struct usb_device *peer_hdev, void *p)
|
||||
struct usb_hub *peer_hub = usb_hub_to_struct_hub(peer_hdev);
|
||||
struct usb_device *hdev = to_usb_device(port_dev->dev.parent->parent);
|
||||
|
||||
if (!peer_hub)
|
||||
if (!peer_hub || port_dev->connect_type == USB_PORT_NOT_USED)
|
||||
return 0;
|
||||
|
||||
hcd = bus_to_hcd(hdev->bus);
|
||||
@@ -461,7 +461,8 @@ static int match_location(struct usb_device *peer_hdev, void *p)
|
||||
|
||||
for (port1 = 1; port1 <= peer_hdev->maxchild; port1++) {
|
||||
peer = peer_hub->ports[port1 - 1];
|
||||
if (peer && peer->location == port_dev->location) {
|
||||
if (peer && peer->connect_type != USB_PORT_NOT_USED &&
|
||||
peer->location == port_dev->location) {
|
||||
link_peers_report(port_dev, peer);
|
||||
return 1; /* done */
|
||||
}
|
||||
|
||||
@@ -1190,14 +1190,24 @@ static ssize_t interface_authorized_store(struct device *dev,
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(dev);
|
||||
bool val;
|
||||
struct kernfs_node *kn;
|
||||
|
||||
if (strtobool(buf, &val) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
if (val) {
|
||||
usb_authorize_interface(intf);
|
||||
else
|
||||
usb_deauthorize_interface(intf);
|
||||
} else {
|
||||
/*
|
||||
* Prevent deadlock if another process is concurrently
|
||||
* trying to unregister intf.
|
||||
*/
|
||||
kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
|
||||
if (kn) {
|
||||
usb_deauthorize_interface(intf);
|
||||
sysfs_unbreak_active_protection(kn);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -743,8 +743,14 @@ struct dwc2_dregs_backup {
|
||||
* struct dwc2_hregs_backup - Holds host registers state before
|
||||
* entering partial power down
|
||||
* @hcfg: Backup of HCFG register
|
||||
* @hflbaddr: Backup of HFLBADDR register
|
||||
* @haintmsk: Backup of HAINTMSK register
|
||||
* @hcchar: Backup of HCCHAR register
|
||||
* @hcsplt: Backup of HCSPLT register
|
||||
* @hcintmsk: Backup of HCINTMSK register
|
||||
* @hctsiz: Backup of HCTSIZ register
|
||||
* @hdma: Backup of HCDMA register
|
||||
* @hcdmab: Backup of HCDMAB register
|
||||
* @hprt0: Backup of HPTR0 register
|
||||
* @hfir: Backup of HFIR register
|
||||
* @hptxfsiz: Backup of HPTXFSIZ register
|
||||
@@ -752,8 +758,14 @@ struct dwc2_dregs_backup {
|
||||
*/
|
||||
struct dwc2_hregs_backup {
|
||||
u32 hcfg;
|
||||
u32 hflbaddr;
|
||||
u32 haintmsk;
|
||||
u32 hcchar[MAX_EPS_CHANNELS];
|
||||
u32 hcsplt[MAX_EPS_CHANNELS];
|
||||
u32 hcintmsk[MAX_EPS_CHANNELS];
|
||||
u32 hctsiz[MAX_EPS_CHANNELS];
|
||||
u32 hcidma[MAX_EPS_CHANNELS];
|
||||
u32 hcidmab[MAX_EPS_CHANNELS];
|
||||
u32 hprt0;
|
||||
u32 hfir;
|
||||
u32 hptxfsiz;
|
||||
@@ -1087,6 +1099,7 @@ struct dwc2_hsotg {
|
||||
bool needs_byte_swap;
|
||||
|
||||
/* DWC OTG HW Release versions */
|
||||
#define DWC2_CORE_REV_4_30a 0x4f54430a
|
||||
#define DWC2_CORE_REV_2_71a 0x4f54271a
|
||||
#define DWC2_CORE_REV_2_72a 0x4f54272a
|
||||
#define DWC2_CORE_REV_2_80a 0x4f54280a
|
||||
@@ -1321,6 +1334,7 @@ int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg);
|
||||
int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg);
|
||||
|
||||
void dwc2_enable_acg(struct dwc2_hsotg *hsotg);
|
||||
void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg, bool remotewakeup);
|
||||
|
||||
/* This function should be called on every hardware interrupt. */
|
||||
irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
|
||||
|
||||
@@ -349,10 +349,11 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
|
||||
* @hsotg: Programming view of DWC_otg controller
|
||||
*
|
||||
*/
|
||||
static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg)
|
||||
void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg, bool remotewakeup)
|
||||
{
|
||||
u32 glpmcfg;
|
||||
u32 i = 0;
|
||||
u32 pcgctl;
|
||||
u32 dctl;
|
||||
|
||||
if (hsotg->lx_state != DWC2_L1) {
|
||||
dev_err(hsotg->dev, "Core isn't in DWC2_L1 state\n");
|
||||
@@ -361,37 +362,57 @@ static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg)
|
||||
|
||||
glpmcfg = dwc2_readl(hsotg, GLPMCFG);
|
||||
if (dwc2_is_device_mode(hsotg)) {
|
||||
dev_dbg(hsotg->dev, "Exit from L1 state\n");
|
||||
dev_dbg(hsotg->dev, "Exit from L1 state, remotewakeup=%d\n", remotewakeup);
|
||||
glpmcfg &= ~GLPMCFG_ENBLSLPM;
|
||||
glpmcfg &= ~GLPMCFG_HIRD_THRES_EN;
|
||||
glpmcfg &= ~GLPMCFG_HIRD_THRES_MASK;
|
||||
dwc2_writel(hsotg, glpmcfg, GLPMCFG);
|
||||
|
||||
do {
|
||||
glpmcfg = dwc2_readl(hsotg, GLPMCFG);
|
||||
pcgctl = dwc2_readl(hsotg, PCGCTL);
|
||||
pcgctl &= ~PCGCTL_ENBL_SLEEP_GATING;
|
||||
dwc2_writel(hsotg, pcgctl, PCGCTL);
|
||||
|
||||
if (!(glpmcfg & (GLPMCFG_COREL1RES_MASK |
|
||||
GLPMCFG_L1RESUMEOK | GLPMCFG_SLPSTS)))
|
||||
break;
|
||||
glpmcfg = dwc2_readl(hsotg, GLPMCFG);
|
||||
if (glpmcfg & GLPMCFG_ENBESL) {
|
||||
glpmcfg |= GLPMCFG_RSTRSLPSTS;
|
||||
dwc2_writel(hsotg, glpmcfg, GLPMCFG);
|
||||
}
|
||||
|
||||
udelay(1);
|
||||
} while (++i < 200);
|
||||
if (remotewakeup) {
|
||||
if (dwc2_hsotg_wait_bit_set(hsotg, GLPMCFG, GLPMCFG_L1RESUMEOK, 1000)) {
|
||||
dev_warn(hsotg->dev, "%s: timeout GLPMCFG_L1RESUMEOK\n", __func__);
|
||||
goto fail;
|
||||
return;
|
||||
}
|
||||
|
||||
if (i == 200) {
|
||||
dev_err(hsotg->dev, "Failed to exit L1 sleep state in 200us.\n");
|
||||
dctl = dwc2_readl(hsotg, DCTL);
|
||||
dctl |= DCTL_RMTWKUPSIG;
|
||||
dwc2_writel(hsotg, dctl, DCTL);
|
||||
|
||||
if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, GINTSTS_WKUPINT, 1000)) {
|
||||
dev_warn(hsotg->dev, "%s: timeout GINTSTS_WKUPINT\n", __func__);
|
||||
goto fail;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glpmcfg = dwc2_readl(hsotg, GLPMCFG);
|
||||
if (glpmcfg & GLPMCFG_COREL1RES_MASK || glpmcfg & GLPMCFG_SLPSTS ||
|
||||
glpmcfg & GLPMCFG_L1RESUMEOK) {
|
||||
goto fail;
|
||||
return;
|
||||
}
|
||||
dwc2_gadget_init_lpm(hsotg);
|
||||
|
||||
/* Inform gadget to exit from L1 */
|
||||
call_gadget(hsotg, resume);
|
||||
/* Change to L0 state */
|
||||
hsotg->lx_state = DWC2_L0;
|
||||
hsotg->bus_suspended = false;
|
||||
fail: dwc2_gadget_init_lpm(hsotg);
|
||||
} else {
|
||||
/* TODO */
|
||||
dev_err(hsotg->dev, "Host side LPM is not supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Change to L0 state */
|
||||
hsotg->lx_state = DWC2_L0;
|
||||
|
||||
/* Inform gadget to exit from L1 */
|
||||
call_gadget(hsotg, resume);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -412,7 +433,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
|
||||
dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
|
||||
|
||||
if (hsotg->lx_state == DWC2_L1) {
|
||||
dwc2_wakeup_from_lpm_l1(hsotg);
|
||||
dwc2_wakeup_from_lpm_l1(hsotg, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1416,6 +1416,10 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
|
||||
ep->name, req, req->length, req->buf, req->no_interrupt,
|
||||
req->zero, req->short_not_ok);
|
||||
|
||||
if (hs->lx_state == DWC2_L1) {
|
||||
dwc2_wakeup_from_lpm_l1(hs, true);
|
||||
}
|
||||
|
||||
/* Prevent new request submission when controller is suspended */
|
||||
if (hs->lx_state != DWC2_L0) {
|
||||
dev_dbg(hs->dev, "%s: submit request only in active state\n",
|
||||
|
||||
@@ -2736,8 +2736,11 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
||||
hsotg->available_host_channels--;
|
||||
}
|
||||
qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
|
||||
if (dwc2_assign_and_init_hc(hsotg, qh))
|
||||
if (dwc2_assign_and_init_hc(hsotg, qh)) {
|
||||
if (hsotg->params.uframe_sched)
|
||||
hsotg->available_host_channels++;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the QH from the periodic ready schedule to the
|
||||
@@ -2770,8 +2773,11 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
|
||||
hsotg->available_host_channels--;
|
||||
}
|
||||
|
||||
if (dwc2_assign_and_init_hc(hsotg, qh))
|
||||
if (dwc2_assign_and_init_hc(hsotg, qh)) {
|
||||
if (hsotg->params.uframe_sched)
|
||||
hsotg->available_host_channels++;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the QH from the non-periodic inactive schedule to the
|
||||
@@ -4125,6 +4131,8 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
|
||||
urb->actual_length);
|
||||
|
||||
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
|
||||
if (!hsotg->params.dma_desc_enable)
|
||||
urb->start_frame = qtd->qh->start_active_frame;
|
||||
urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb);
|
||||
for (i = 0; i < urb->number_of_packets; ++i) {
|
||||
urb->iso_frame_desc[i].actual_length =
|
||||
@@ -5319,9 +5327,16 @@ int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
|
||||
/* Backup Host regs */
|
||||
hr = &hsotg->hr_backup;
|
||||
hr->hcfg = dwc2_readl(hsotg, HCFG);
|
||||
hr->hflbaddr = dwc2_readl(hsotg, HFLBADDR);
|
||||
hr->haintmsk = dwc2_readl(hsotg, HAINTMSK);
|
||||
for (i = 0; i < hsotg->params.host_channels; ++i)
|
||||
for (i = 0; i < hsotg->params.host_channels; ++i) {
|
||||
hr->hcchar[i] = dwc2_readl(hsotg, HCCHAR(i));
|
||||
hr->hcsplt[i] = dwc2_readl(hsotg, HCSPLT(i));
|
||||
hr->hcintmsk[i] = dwc2_readl(hsotg, HCINTMSK(i));
|
||||
hr->hctsiz[i] = dwc2_readl(hsotg, HCTSIZ(i));
|
||||
hr->hcidma[i] = dwc2_readl(hsotg, HCDMA(i));
|
||||
hr->hcidmab[i] = dwc2_readl(hsotg, HCDMAB(i));
|
||||
}
|
||||
|
||||
hr->hprt0 = dwc2_read_hprt0(hsotg);
|
||||
hr->hfir = dwc2_readl(hsotg, HFIR);
|
||||
@@ -5355,10 +5370,17 @@ int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
|
||||
hr->valid = false;
|
||||
|
||||
dwc2_writel(hsotg, hr->hcfg, HCFG);
|
||||
dwc2_writel(hsotg, hr->hflbaddr, HFLBADDR);
|
||||
dwc2_writel(hsotg, hr->haintmsk, HAINTMSK);
|
||||
|
||||
for (i = 0; i < hsotg->params.host_channels; ++i)
|
||||
for (i = 0; i < hsotg->params.host_channels; ++i) {
|
||||
dwc2_writel(hsotg, hr->hcchar[i], HCCHAR(i));
|
||||
dwc2_writel(hsotg, hr->hcsplt[i], HCSPLT(i));
|
||||
dwc2_writel(hsotg, hr->hcintmsk[i], HCINTMSK(i));
|
||||
dwc2_writel(hsotg, hr->hctsiz[i], HCTSIZ(i));
|
||||
dwc2_writel(hsotg, hr->hcidma[i], HCDMA(i));
|
||||
dwc2_writel(hsotg, hr->hcidmab[i], HCDMAB(i));
|
||||
}
|
||||
|
||||
dwc2_writel(hsotg, hr->hprt0, HPRT0);
|
||||
dwc2_writel(hsotg, hr->hfir, HFIR);
|
||||
@@ -5523,10 +5545,12 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
|
||||
dwc2_writel(hsotg, hr->hcfg, HCFG);
|
||||
|
||||
/* De-assert Wakeup Logic */
|
||||
gpwrdn = dwc2_readl(hsotg, GPWRDN);
|
||||
gpwrdn &= ~GPWRDN_PMUACTV;
|
||||
dwc2_writel(hsotg, gpwrdn, GPWRDN);
|
||||
udelay(10);
|
||||
if (!(rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) {
|
||||
gpwrdn = dwc2_readl(hsotg, GPWRDN);
|
||||
gpwrdn &= ~GPWRDN_PMUACTV;
|
||||
dwc2_writel(hsotg, gpwrdn, GPWRDN);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
hprt0 = hr->hprt0;
|
||||
hprt0 |= HPRT0_PWR;
|
||||
@@ -5551,6 +5575,13 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
|
||||
hprt0 |= HPRT0_RES;
|
||||
dwc2_writel(hsotg, hprt0, HPRT0);
|
||||
|
||||
/* De-assert Wakeup Logic */
|
||||
if ((rem_wakeup && hsotg->hw_params.snpsid >= DWC2_CORE_REV_4_30a)) {
|
||||
gpwrdn = dwc2_readl(hsotg, GPWRDN);
|
||||
gpwrdn &= ~GPWRDN_PMUACTV;
|
||||
dwc2_writel(hsotg, gpwrdn, GPWRDN);
|
||||
udelay(10);
|
||||
}
|
||||
/* Wait for Resume time and then program HPRT again */
|
||||
mdelay(100);
|
||||
hprt0 &= ~HPRT0_RES;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user