Re: Linux 6.18.32
From: Greg Kroah-Hartman
Date: Sun May 17 2026 - 11:43:28 EST
diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
index 96b6c8938768..d0bce8bfb1b1 100644
--- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml
@@ -27,16 +27,20 @@ properties:
reg:
minItems: 1
- items:
- - description: The function configuration registers base
- - description: The link table configuration registers base
- - description: The cache configuration registers base
+ maxItems: 3
reg-names:
- items:
- - const: function
- - const: link
- - const: cache
+ oneOf:
+ - items:
+ - const: link
+ - const: function
+ - const: cache
+ - items:
+ - const: function
+ - const: link
+ - const: cache
+ deprecated: true
+ description: Use link,function,cache block order instead.
interrupts:
maxItems: 1
@@ -122,6 +126,8 @@ allOf:
minItems: 5
reset-names:
minItems: 5
+ required:
+ - reg-names
else:
properties:
reg:
diff --git a/Makefile b/Makefile
index 89c614db5240..d1fcec7cf956 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 18
-SUBLEVEL = 31
+SUBLEVEL = 32
EXTRAVERSION =
NAME = Baby Opossum Posse
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
index 7de24d60bcd1..127be0fc27c2 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
@@ -35,3 +35,17 @@ &gio_aon {
"PMIC_SCL", // AON_SGPIO_04
"PMIC_SDA"; // AON_SGPIO_05
};
+
+&pinctrl {
+ compatible = "brcm,bcm2712d0-pinctrl";
+ reg = <0x7d504100 0x20>;
+};
+
+&pinctrl_aon {
+ compatible = "brcm,bcm2712d0-aon-pinctrl";
+ reg = <0x7d510700 0x1c>;
+};
+
+&uart10 {
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
index eec2cd6c6d32..7f6e39e27ce5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
@@ -162,6 +162,8 @@ rtc@51 {
};
&fspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspi_data74_pins>, <&fspi_data30_pins>, <&fspi_dqs_sck_cs10_pins>;
status = "okay";
flash@0 {
@@ -177,6 +179,11 @@ flash@0 {
};
};
+&pinmux_i2crv {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio0_14_12_pins>;
+};
+
&usb0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
index af6258b2fe82..580ee9b3026e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
@@ -89,6 +89,8 @@ &emdio2 {
};
&esdhc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&esdhc0_cd_wp_pins>, <&esdhc0_cmd_data30_clk_vsel_pins>;
sd-uhs-sdr104;
sd-uhs-sdr50;
sd-uhs-sdr25;
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index c9541403bcd8..bc1d34f1cd54 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -1717,6 +1717,10 @@ i2c1_scl_gpio: i2c1-scl-gpio-pins {
pinctrl-single,bits = <0x0 0x1 0x7>;
};
+ esdhc0_cd_wp_pins: iic2-sdhc-pins {
+ pinctrl-single,bits = <0x0 0x6 0x7>;
+ };
+
i2c2_scl: i2c2-scl-pins {
pinctrl-single,bits = <0x0 0 (0x7 << 3)>;
};
@@ -1749,6 +1753,26 @@ i2c5_scl_gpio: i2c5-scl-gpio-pins {
pinctrl-single,bits = <0x0 (0x1 << 12) (0x7 << 12)>;
};
+ fspi_data74_pins: xspi1-data74-pins {
+ pinctrl-single,bits = <0x0 0x0 (0x7 << 15)>;
+ };
+
+ fspi_data30_pins: xspi1-data30-pins {
+ pinctrl-single,bits = <0x0 0x0 (0x7 << 18)>;
+ };
+
+ fspi_dqs_sck_cs10_pins: xspi1-base-pins {
+ pinctrl-single,bits = <0x0 0x0 (0x7 << 21)>;
+ };
+
+ esdhc0_cmd_data30_clk_vsel_pins: sdhc1-base-sdhc-vsel-pins {
+ pinctrl-single,bits = <0x0 0x0 (0x7 << 24)>;
+ };
+
+ gpio0_14_12_pins: sdhc1-dir-gpio-pins {
+ pinctrl-single,bits = <0x0 (0x1 << 27) (0x7 << 27)>;
+ };
+
i2c6_scl: i2c6-scl-pins {
pinctrl-single,bits = <0x4 0x2 0x7>;
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
index eafef8718a0f..8920326a0673 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
@@ -223,6 +223,8 @@ ethernet_phy8: ethernet-phy@15 {
};
&esdhc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&esdhc0_cd_wp_pins>, <&esdhc0_cmd_data30_clk_vsel_pins>;
sd-uhs-sdr104;
sd-uhs-sdr50;
sd-uhs-sdr25;
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
index e914291e63a1..e1344942eaae 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
@@ -30,6 +30,8 @@ &esdhc1 {
};
&fspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspi_data74_pins>, <&fspi_data30_pins>, <&fspi_dqs_sck_cs10_pins>;
status = "okay";
flash@0 {
@@ -80,3 +82,8 @@ rtc@6f {
reg = <0x6f>;
};
};
+
+&pinmux_i2crv {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio0_14_12_pins>;
+};
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index c2d2200d845b..530dc1e832b7 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -1563,7 +1563,7 @@ i2c20: i2c@898000 {
reg = <0x0 0x898000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <0>;
- interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 833 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
clock-names = "se";
pinctrl-0 = <&qup_i2c20_default>;
@@ -1590,7 +1590,7 @@ spi20: spi@898000 {
reg = <0x0 0x898000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <0>;
- interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 833 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
clock-names = "se";
pinctrl-0 = <&qup_spi20_default>;
@@ -1615,7 +1615,7 @@ &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
uart20: serial@898000 {
compatible = "qcom,geni-uart";
reg = <0x0 0x00898000 0x0 0x4000>;
- interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 833 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
clock-names = "se";
pinctrl-0 = <&qup_uart20_default>;
@@ -2561,7 +2561,7 @@ i2c13: i2c@a98000 {
reg = <0x0 0xa98000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <0>;
- interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
clock-names = "se";
pinctrl-0 = <&qup_i2c13_default>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index af591fe6ae4f..b41d8dd159ad 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -394,7 +394,7 @@ AM62AX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C15) UART0_RTSn.GPIO1_23 */
vddshv_sdio_pins_default: vddshv-sdio-default-pins {
pinctrl-single,pins = <
- AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
+ AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (N22) GPMC0_CLK.GPIO0_31 */
>;
};
diff --git a/arch/loongarch/Kbuild b/arch/loongarch/Kbuild
index beb8499dd8ed..1c7a0dbe5e72 100644
--- a/arch/loongarch/Kbuild
+++ b/arch/loongarch/Kbuild
@@ -3,7 +3,7 @@ obj-y += mm/
obj-y += net/
obj-y += vdso/
-obj-$(CONFIG_KVM) += kvm/
+obj-$(subst m,y,$(CONFIG_KVM)) += kvm/
# for cleaning
subdir- += boot
diff --git a/arch/loongarch/include/asm/asm-prototypes.h b/arch/loongarch/include/asm/asm-prototypes.h
index 704066b4f736..de0c17f3f49c 100644
--- a/arch/loongarch/include/asm/asm-prototypes.h
+++ b/arch/loongarch/include/asm/asm-prototypes.h
@@ -20,3 +20,23 @@ asmlinkage void noinstr __no_stack_protector ret_from_kernel_thread(struct task_
struct pt_regs *regs,
int (*fn)(void *),
void *fn_arg);
+
+struct kvm_run;
+struct kvm_vcpu;
+struct loongarch_fpu;
+
+void kvm_exc_entry(void);
+int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
+
+void kvm_save_fpu(struct loongarch_fpu *fpu);
+void kvm_restore_fpu(struct loongarch_fpu *fpu);
+
+#ifdef CONFIG_CPU_HAS_LSX
+void kvm_save_lsx(struct loongarch_fpu *fpu);
+void kvm_restore_lsx(struct loongarch_fpu *fpu);
+#endif
+
+#ifdef CONFIG_CPU_HAS_LASX
+void kvm_save_lasx(struct loongarch_fpu *fpu);
+void kvm_restore_lasx(struct loongarch_fpu *fpu);
+#endif
diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index 0cecbd038bb3..377d7fb04bda 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -85,7 +85,6 @@ struct kvm_context {
struct kvm_world_switch {
int (*exc_entry)(void);
int (*enter_guest)(struct kvm_run *run, struct kvm_vcpu *vcpu);
- unsigned long page_order;
};
#define MAX_PGTABLE_LEVELS 4
@@ -339,8 +338,6 @@ void kvm_exc_entry(void);
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
extern unsigned long vpid_mask;
-extern const unsigned long kvm_exception_size;
-extern const unsigned long kvm_enter_guest_size;
extern struct kvm_world_switch *kvm_loongarch_ops;
#define SW_GCSR (1 << 0)
diff --git a/arch/loongarch/kvm/Makefile b/arch/loongarch/kvm/Makefile
index cb41d9265662..f32a170c1838 100644
--- a/arch/loongarch/kvm/Makefile
+++ b/arch/loongarch/kvm/Makefile
@@ -7,11 +7,12 @@ include $(srctree)/virt/kvm/Makefile.kvm
obj-$(CONFIG_KVM) += kvm.o
+obj-y += switch.o
+
kvm-y += exit.o
kvm-y += interrupt.o
kvm-y += main.o
kvm-y += mmu.o
-kvm-y += switch.o
kvm-y += timer.o
kvm-y += tlb.o
kvm-y += vcpu.o
diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index 80ea63d465b8..67d234540ed4 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -340,8 +340,7 @@ void kvm_arch_disable_virtualization_cpu(void)
static int kvm_loongarch_env_init(void)
{
- int cpu, order, ret;
- void *addr;
+ int cpu, ret;
struct kvm_context *context;
vmcs = alloc_percpu(struct kvm_context);
@@ -357,30 +356,8 @@ static int kvm_loongarch_env_init(void)
return -ENOMEM;
}
- /*
- * PGD register is shared between root kernel and kvm hypervisor.
- * So world switch entry should be in DMW area rather than TLB area
- * to avoid page fault reenter.
- *
- * In future if hardware pagetable walking is supported, we won't
- * need to copy world switch code to DMW area.
- */
- order = get_order(kvm_exception_size + kvm_enter_guest_size);
- addr = (void *)__get_free_pages(GFP_KERNEL, order);
- if (!addr) {
- free_percpu(vmcs);
- vmcs = NULL;
- kfree(kvm_loongarch_ops);
- kvm_loongarch_ops = NULL;
- return -ENOMEM;
- }
-
- memcpy(addr, kvm_exc_entry, kvm_exception_size);
- memcpy(addr + kvm_exception_size, kvm_enter_guest, kvm_enter_guest_size);
- flush_icache_range((unsigned long)addr, (unsigned long)addr + kvm_exception_size + kvm_enter_guest_size);
- kvm_loongarch_ops->exc_entry = addr;
- kvm_loongarch_ops->enter_guest = addr + kvm_exception_size;
- kvm_loongarch_ops->page_order = order;
+ kvm_loongarch_ops->exc_entry = (void *)kvm_exc_entry;
+ kvm_loongarch_ops->enter_guest = (void *)kvm_enter_guest;
vpid_mask = read_csr_gstat();
vpid_mask = (vpid_mask & CSR_GSTAT_GIDBIT) >> CSR_GSTAT_GIDBIT_SHIFT;
@@ -414,16 +391,10 @@ static int kvm_loongarch_env_init(void)
static void kvm_loongarch_env_exit(void)
{
- unsigned long addr;
-
if (vmcs)
free_percpu(vmcs);
if (kvm_loongarch_ops) {
- if (kvm_loongarch_ops->exc_entry) {
- addr = (unsigned long)kvm_loongarch_ops->exc_entry;
- free_pages(addr, kvm_loongarch_ops->page_order);
- }
kfree(kvm_loongarch_ops);
}
diff --git a/arch/loongarch/kvm/switch.S b/arch/loongarch/kvm/switch.S
index 9eaad5dbed91..281daf0b7810 100644
--- a/arch/loongarch/kvm/switch.S
+++ b/arch/loongarch/kvm/switch.S
@@ -4,9 +4,11 @@
*/
#include <linux/linkage.h>
+#include <linux/kvm_types.h>
#include <asm/asm.h>
#include <asm/asmmacro.h>
#include <asm/loongarch.h>
+#include <asm/page.h>
#include <asm/regdef.h>
#include <asm/unwind_hints.h>
@@ -100,8 +102,13 @@
* - is still in guest mode, such as pgd table/vmid registers etc,
* - will fix with hw page walk enabled in future
* load kvm_vcpu from reserved CSR KVM_VCPU_KS, and save a2 to KVM_TEMP_KS
+ *
+ * PGD register is shared between root kernel and kvm hypervisor.
+ * So world switch entry should be in DMW area rather than TLB area
+ * to avoid page fault re-enter.
*/
.text
+ .p2align PAGE_SHIFT
.cfi_sections .debug_frame
SYM_CODE_START(kvm_exc_entry)
UNWIND_HINT_END_OF_STACK
@@ -190,8 +197,8 @@ ret_to_host:
kvm_restore_host_gpr a2
jr ra
-SYM_INNER_LABEL(kvm_exc_entry_end, SYM_L_LOCAL)
SYM_CODE_END(kvm_exc_entry)
+EXPORT_SYMBOL_GPL(kvm_exc_entry)
/*
* int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu)
@@ -215,8 +222,8 @@ SYM_FUNC_START(kvm_enter_guest)
/* Save kvm_vcpu to kscratch */
csrwr a1, KVM_VCPU_KS
kvm_switch_to_guest
-SYM_INNER_LABEL(kvm_enter_guest_end, SYM_L_LOCAL)
SYM_FUNC_END(kvm_enter_guest)
+EXPORT_SYMBOL_GPL(kvm_enter_guest)
SYM_FUNC_START(kvm_save_fpu)
fpu_save_csr a0 t1
@@ -224,6 +231,7 @@ SYM_FUNC_START(kvm_save_fpu)
fpu_save_cc a0 t1 t2
jr ra
SYM_FUNC_END(kvm_save_fpu)
+EXPORT_SYMBOL_GPL(kvm_save_fpu)
SYM_FUNC_START(kvm_restore_fpu)
fpu_restore_double a0 t1
@@ -231,6 +239,7 @@ SYM_FUNC_START(kvm_restore_fpu)
fpu_restore_cc a0 t1 t2
jr ra
SYM_FUNC_END(kvm_restore_fpu)
+EXPORT_SYMBOL_GPL(kvm_restore_fpu)
#ifdef CONFIG_CPU_HAS_LSX
SYM_FUNC_START(kvm_save_lsx)
@@ -239,6 +248,7 @@ SYM_FUNC_START(kvm_save_lsx)
lsx_save_data a0 t1
jr ra
SYM_FUNC_END(kvm_save_lsx)
+EXPORT_SYMBOL_GPL(kvm_save_lsx)
SYM_FUNC_START(kvm_restore_lsx)
lsx_restore_data a0 t1
@@ -246,6 +256,7 @@ SYM_FUNC_START(kvm_restore_lsx)
fpu_restore_csr a0 t1 t2
jr ra
SYM_FUNC_END(kvm_restore_lsx)
+EXPORT_SYMBOL_GPL(kvm_restore_lsx)
#endif
#ifdef CONFIG_CPU_HAS_LASX
@@ -255,6 +266,7 @@ SYM_FUNC_START(kvm_save_lasx)
lasx_save_data a0 t1
jr ra
SYM_FUNC_END(kvm_save_lasx)
+EXPORT_SYMBOL_GPL(kvm_save_lasx)
SYM_FUNC_START(kvm_restore_lasx)
lasx_restore_data a0 t1
@@ -262,10 +274,8 @@ SYM_FUNC_START(kvm_restore_lasx)
fpu_restore_csr a0 t1 t2
jr ra
SYM_FUNC_END(kvm_restore_lasx)
+EXPORT_SYMBOL_GPL(kvm_restore_lasx)
#endif
- .section ".rodata"
-SYM_DATA(kvm_exception_size, .quad kvm_exc_entry_end - kvm_exc_entry)
-SYM_DATA(kvm_enter_guest_size, .quad kvm_enter_guest_end - kvm_enter_guest)
#ifdef CONFIG_CPU_HAS_LBT
STACK_FRAME_NON_STANDARD kvm_restore_fpu
diff --git a/arch/powerpc/platforms/pseries/papr-hvpipe.c b/arch/powerpc/platforms/pseries/papr-hvpipe.c
index 431f6a3da4c5..a238db095b4e 100644
--- a/arch/powerpc/platforms/pseries/papr-hvpipe.c
+++ b/arch/powerpc/platforms/pseries/papr-hvpipe.c
@@ -449,13 +449,14 @@ static int papr_hvpipe_handle_release(struct inode *inode,
struct file *file)
{
struct hvpipe_source_info *src_info;
+ unsigned long flags;
/*
* Hold the lock, remove source from src_list, reset the
* hvpipe status and release the lock to prevent any race
* with message event IRQ.
*/
- spin_lock(&hvpipe_src_list_lock);
+ spin_lock_irqsave(&hvpipe_src_list_lock, flags);
src_info = file->private_data;
list_del(&src_info->list);
file->private_data = NULL;
@@ -466,10 +467,10 @@ static int papr_hvpipe_handle_release(struct inode *inode,
*/
if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) {
src_info->hvpipe_status = 0;
- spin_unlock(&hvpipe_src_list_lock);
+ spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
hvpipe_rtas_recv_msg(NULL, 0);
} else
- spin_unlock(&hvpipe_src_list_lock);
+ spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
kfree(src_info);
return 0;
@@ -484,24 +485,22 @@ static const struct file_operations papr_hvpipe_handle_ops = {
static int papr_hvpipe_dev_create_handle(u32 srcID)
{
- struct hvpipe_source_info *src_info;
- struct file *file;
- long err;
- int fd;
+ struct hvpipe_source_info *src_info __free(kfree) = NULL;
+ unsigned long flags;
- spin_lock(&hvpipe_src_list_lock);
+ spin_lock_irqsave(&hvpipe_src_list_lock, flags);
/*
* Do not allow more than one process communicates with
* each source.
*/
src_info = hvpipe_find_source(srcID);
if (src_info) {
- spin_unlock(&hvpipe_src_list_lock);
+ spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
pr_err("pid(%d) is already using the source(%d)\n",
src_info->tsk->pid, srcID);
return -EALREADY;
}
- spin_unlock(&hvpipe_src_list_lock);
+ spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
src_info = kzalloc(sizeof(*src_info), GFP_KERNEL_ACCOUNT);
if (!src_info)
@@ -511,44 +510,26 @@ static int papr_hvpipe_dev_create_handle(u32 srcID)
src_info->tsk = current;
init_waitqueue_head(&src_info->recv_wqh);
- fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
- if (fd < 0) {
- err = fd;
- goto free_buf;
- }
+ FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC,
+ anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,
+ (void *)src_info, O_RDWR));
+ if (fdf.err)
+ return fdf.err;
- file = anon_inode_getfile("[papr-hvpipe]",
- &papr_hvpipe_handle_ops, (void *)src_info,
- O_RDWR);
- if (IS_ERR(file)) {
- err = PTR_ERR(file);
- goto free_fd;
- }
-
- spin_lock(&hvpipe_src_list_lock);
+ retain_and_null_ptr(src_info);
+ spin_lock_irqsave(&hvpipe_src_list_lock, flags);
/*
* If two processes are executing ioctl() for the same
* source ID concurrently, prevent the second process to
* acquire FD.
*/
if (hvpipe_find_source(srcID)) {
- spin_unlock(&hvpipe_src_list_lock);
- err = -EALREADY;
- goto free_file;
+ spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
+ return -EALREADY;
}
list_add(&src_info->list, &hvpipe_src_list);
- spin_unlock(&hvpipe_src_list_lock);
-
- fd_install(fd, file);
- return fd;
-
-free_file:
- fput(file);
-free_fd:
- put_unused_fd(fd);
-free_buf:
- kfree(src_info);
- return err;
+ spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
+ return fd_publish(fdf);
}
/*
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index e98bd9ad0232..59b7a1d14af5 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -83,17 +83,17 @@ static inline unsigned int disk_zone_wplugs_hash_size(struct gendisk *disk)
* being executed or the zone write plug bio list is not empty.
* - BLK_ZONE_WPLUG_NEED_WP_UPDATE: Indicates that we lost track of a zone
* write pointer offset and need to update it.
- * - BLK_ZONE_WPLUG_UNHASHED: Indicates that the zone write plug was removed
- * from the disk hash table and that the initial reference to the zone
- * write plug set when the plug was first added to the hash table has been
- * dropped. This flag is set when a zone is reset, finished or become full,
- * to prevent new references to the zone write plug to be taken for
- * newly incoming BIOs. A zone write plug flagged with this flag will be
- * freed once all remaining references from BIOs or functions are dropped.
+ * - BLK_ZONE_WPLUG_DEAD: Indicates that the zone write plug will be
+ * removed from the disk hash table of zone write plugs when the last
+ * reference on the zone write plug is dropped. If set, this flag also
+ * indicates that the initial extra reference on the zone write plug was
+ * dropped, meaning that the reference count indicates the current number of
+ * active users (code context or BIOs and requests in flight). This flag is
+ * set when a zone is reset, finished or becomes full.
*/
#define BLK_ZONE_WPLUG_PLUGGED (1U << 0)
#define BLK_ZONE_WPLUG_NEED_WP_UPDATE (1U << 1)
-#define BLK_ZONE_WPLUG_UNHASHED (1U << 2)
+#define BLK_ZONE_WPLUG_DEAD (1U << 2)
/**
* blk_zone_cond_str - Return string XXX in BLK_ZONE_COND_XXX.
@@ -467,67 +467,42 @@ static void disk_free_zone_wplug_rcu(struct rcu_head *rcu_head)
mempool_free(zwplug, zwplug->disk->zone_wplugs_pool);
}
-static inline void disk_put_zone_wplug(struct blk_zone_wplug *zwplug)
+static void disk_free_zone_wplug(struct blk_zone_wplug *zwplug)
{
- if (refcount_dec_and_test(&zwplug->ref)) {
- WARN_ON_ONCE(!bio_list_empty(&zwplug->bio_list));
- WARN_ON_ONCE(zwplug->flags & BLK_ZONE_WPLUG_PLUGGED);
- WARN_ON_ONCE(!(zwplug->flags & BLK_ZONE_WPLUG_UNHASHED));
-
- call_rcu(&zwplug->rcu_head, disk_free_zone_wplug_rcu);
- }
-}
-
-static inline bool disk_should_remove_zone_wplug(struct gendisk *disk,
- struct blk_zone_wplug *zwplug)
-{
- lockdep_assert_held(&zwplug->lock);
-
- /* If the zone write plug was already removed, we are done. */
- if (zwplug->flags & BLK_ZONE_WPLUG_UNHASHED)
- return false;
+ struct gendisk *disk = zwplug->disk;
+ unsigned long flags;
- /* If the zone write plug is still plugged, it cannot be removed. */
- if (zwplug->flags & BLK_ZONE_WPLUG_PLUGGED)
- return false;
+ WARN_ON_ONCE(!(zwplug->flags & BLK_ZONE_WPLUG_DEAD));
+ WARN_ON_ONCE(zwplug->flags & BLK_ZONE_WPLUG_PLUGGED);
+ WARN_ON_ONCE(!bio_list_empty(&zwplug->bio_list));
- /*
- * Completions of BIOs with blk_zone_write_plug_bio_endio() may
- * happen after handling a request completion with
- * blk_zone_write_plug_finish_request() (e.g. with split BIOs
- * that are chained). In such case, disk_zone_wplug_unplug_bio()
- * should not attempt to remove the zone write plug until all BIO
- * completions are seen. Check by looking at the zone write plug
- * reference count, which is 2 when the plug is unused (one reference
- * taken when the plug was allocated and another reference taken by the
- * caller context).
- */
- if (refcount_read(&zwplug->ref) > 2)
- return false;
+ spin_lock_irqsave(&disk->zone_wplugs_lock, flags);
+ hlist_del_init_rcu(&zwplug->node);
+ atomic_dec(&disk->nr_zone_wplugs);
+ spin_unlock_irqrestore(&disk->zone_wplugs_lock, flags);
- /* We can remove zone write plugs for zones that are empty or full. */
- return !zwplug->wp_offset || disk_zone_wplug_is_full(disk, zwplug);
+ call_rcu(&zwplug->rcu_head, disk_free_zone_wplug_rcu);
}
-static void disk_remove_zone_wplug(struct gendisk *disk,
- struct blk_zone_wplug *zwplug)
+static inline void disk_put_zone_wplug(struct blk_zone_wplug *zwplug)
{
- unsigned long flags;
+ if (refcount_dec_and_test(&zwplug->ref))
+ disk_free_zone_wplug(zwplug);
+}
- /* If the zone write plug was already removed, we have nothing to do. */
- if (zwplug->flags & BLK_ZONE_WPLUG_UNHASHED)
- return;
+/*
+ * Flag the zone write plug as dead and drop the initial reference we got when
+ * the zone write plug was added to the hash table. The zone write plug will be
+ * unhashed when its last reference is dropped.
+ */
+static void disk_mark_zone_wplug_dead(struct blk_zone_wplug *zwplug)
+{
+ lockdep_assert_held(&zwplug->lock);
- /*
- * Mark the zone write plug as unhashed and drop the extra reference we
- * took when the plug was inserted in the hash table.
- */
- zwplug->flags |= BLK_ZONE_WPLUG_UNHASHED;
- spin_lock_irqsave(&disk->zone_wplugs_lock, flags);
- hlist_del_init_rcu(&zwplug->node);
- atomic_dec(&disk->nr_zone_wplugs);
- spin_unlock_irqrestore(&disk->zone_wplugs_lock, flags);
- disk_put_zone_wplug(zwplug);
+ if (!(zwplug->flags & BLK_ZONE_WPLUG_DEAD)) {
+ zwplug->flags |= BLK_ZONE_WPLUG_DEAD;
+ disk_put_zone_wplug(zwplug);
+ }
}
static void blk_zone_wplug_bio_work(struct work_struct *work);
@@ -547,18 +522,7 @@ static struct blk_zone_wplug *disk_get_and_lock_zone_wplug(struct gendisk *disk,
again:
zwplug = disk_get_zone_wplug(disk, sector);
if (zwplug) {
- /*
- * Check that a BIO completion or a zone reset or finish
- * operation has not already removed the zone write plug from
- * the hash table and dropped its reference count. In such case,
- * we need to get a new plug so start over from the beginning.
- */
spin_lock_irqsave(&zwplug->lock, *flags);
- if (zwplug->flags & BLK_ZONE_WPLUG_UNHASHED) {
- spin_unlock_irqrestore(&zwplug->lock, *flags);
- disk_put_zone_wplug(zwplug);
- goto again;
- }
return zwplug;
}
@@ -645,14 +609,8 @@ static void disk_zone_wplug_set_wp_offset(struct gendisk *disk,
zwplug->flags &= ~BLK_ZONE_WPLUG_NEED_WP_UPDATE;
zwplug->wp_offset = wp_offset;
disk_zone_wplug_abort(zwplug);
-
- /*
- * The zone write plug now has no BIO plugged: remove it from the
- * hash table so that it cannot be seen. The plug will be freed
- * when the last reference is dropped.
- */
- if (disk_should_remove_zone_wplug(disk, zwplug))
- disk_remove_zone_wplug(disk, zwplug);
+ if (!zwplug->wp_offset || disk_zone_wplug_is_full(disk, zwplug))
+ disk_mark_zone_wplug_dead(zwplug);
}
static unsigned int blk_zone_wp_offset(struct blk_zone *zone)
@@ -1068,6 +1026,19 @@ static bool blk_zone_wplug_handle_write(struct bio *bio, unsigned int nr_segs)
return true;
}
+ /*
+ * If we got a zone write plug marked as dead, then the user is issuing
+ * writes to a full zone, or without synchronizing with zone reset or
+ * zone finish operations. In such case, fail the BIO to signal this
+ * invalid usage.
+ */
+ if (zwplug->flags & BLK_ZONE_WPLUG_DEAD) {
+ spin_unlock_irqrestore(&zwplug->lock, flags);
+ disk_put_zone_wplug(zwplug);
+ bio_io_error(bio);
+ return true;
+ }
+
/* Indicate that this BIO is being handled using zone write plugging. */
bio_set_flag(bio, BIO_ZONE_WRITE_PLUGGING);
@@ -1136,7 +1107,7 @@ static void blk_zone_wplug_handle_native_zone_append(struct bio *bio)
disk->disk_name, zwplug->zone_no);
disk_zone_wplug_abort(zwplug);
}
- disk_remove_zone_wplug(disk, zwplug);
+ disk_mark_zone_wplug_dead(zwplug);
spin_unlock_irqrestore(&zwplug->lock, flags);
disk_put_zone_wplug(zwplug);
@@ -1239,14 +1210,8 @@ static void disk_zone_wplug_unplug_bio(struct gendisk *disk,
}
zwplug->flags &= ~BLK_ZONE_WPLUG_PLUGGED;
-
- /*
- * If the zone is full (it was fully written or finished, or empty
- * (it was reset), remove its zone write plug from the hash table.
- */
- if (disk_should_remove_zone_wplug(disk, zwplug))
- disk_remove_zone_wplug(disk, zwplug);
-
+ if (!zwplug->wp_offset || disk_zone_wplug_is_full(disk, zwplug))
+ disk_mark_zone_wplug_dead(zwplug);
spin_unlock_irqrestore(&zwplug->lock, flags);
}
@@ -1457,9 +1422,9 @@ static void disk_destroy_zone_wplugs_hash_table(struct gendisk *disk)
while (!hlist_empty(&disk->zone_wplugs_hash[i])) {
zwplug = hlist_entry(disk->zone_wplugs_hash[i].first,
struct blk_zone_wplug, node);
- refcount_inc(&zwplug->ref);
- disk_remove_zone_wplug(disk, zwplug);
- disk_put_zone_wplug(zwplug);
+ spin_lock_irq(&zwplug->lock);
+ disk_mark_zone_wplug_dead(zwplug);
+ spin_unlock_irq(&zwplug->lock);
}
}
diff --git a/drivers/edac/versalnet_edac.c b/drivers/edac/versalnet_edac.c
index f90723bc93d5..4053ee2e0bee 100644
--- a/drivers/edac/versalnet_edac.c
+++ b/drivers/edac/versalnet_edac.c
@@ -765,9 +765,9 @@ static int init_versalnet(struct mc_priv *priv, struct platform_device *pdev)
u32 num_chans, rank, dwidth, config;
struct edac_mc_layer layers[2];
struct mem_ctl_info *mci;
+ char name[32];
struct device *dev;
enum dev_type dt;
- char *name;
int rc, i;
for (i = 0; i < NUM_CONTROLLERS; i++) {
@@ -814,7 +814,6 @@ static int init_versalnet(struct mc_priv *priv, struct platform_device *pdev)
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
dev->release = versal_edac_release;
- name = kmalloc(32, GFP_KERNEL);
sprintf(name, "versal-net-ddrmc5-edac-%d", i);
dev->init_name = name;
rc = device_register(dev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d3f541d3108c..0ab85d0a6a43 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1717,7 +1717,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
alloc_flags = 0;
} else {
- alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
+ alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE |
+ AMDGPU_GEM_CREATE_VRAM_CLEARED;
alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ?
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index 83f3b94ed975..3392bd930c91 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -262,12 +262,19 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev)
*/
int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
{
+ int r;
+
if (adev->gart.bo != NULL)
return 0;
- return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.bo,
- NULL, (void *)&adev->gart.ptr);
+ r = amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.bo,
+ NULL, (void *)&adev->gart.ptr);
+ if (r)
+ return r;
+
+ memset_io(adev->gart.ptr, adev->gart.gart_pte_flags, adev->gart.table_size);
+ return 0;
}
/**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 1e3b8a506d1b..b8613888c5c3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -737,6 +737,12 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
return 0;
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) {
+
+ if (!adev->gmc.gmc_funcs->flush_gpu_tlb_pasid) {
+ r = 0;
+ goto error_unlock_reset;
+ }
+
if (adev->gmc.flush_tlb_needs_extra_type_2)
adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
2, all_hub,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 4b46e3c26ff3..0098b1eadfc8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -547,15 +547,18 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
int amdgpu_ring_init_mqd(struct amdgpu_ring *ring);
-static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx)
+static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, uint32_t idx)
{
- return ib->ptr[idx];
+ if (idx < ib->length_dw)
+ return ib->ptr[idx];
+ return 0;
}
-static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx,
+static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, uint32_t idx,
uint32_t value)
{
- ib->ptr[idx] = value;
+ if (idx < ib->length_dw)
+ ib->ptr[idx] = value;
}
int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index ce318f5de047..3b9a9010ed35 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -656,6 +656,9 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, struct amdgpu_ib *ib,
uint64_t addr;
int r;
+ if (lo >= ib->length_dw || hi >= ib->length_dw)
+ return -EINVAL;
+
if (index == 0xffffffff)
index = 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 69080e373489..0d7c48927f39 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1066,9 +1066,10 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params,
}
/* Prepare a TLB flush fence to be attached to PTs */
- if (!params->unlocked &&
- /* SI doesn't support pasid or KIQ/MES */
- params->adev->family > AMDGPU_FAMILY_SI) {
+ /* The check for need_tlb_fence should be dropped once we
+ * sort out the issues with KIQ/MES TLB invalidation timeouts.
+ */
+ if (!params->unlocked && vm->need_tlb_fence) {
amdgpu_vm_tlb_fence_create(params->adev, vm, fence);
/* Makes sure no PD/PT is freed before the flush */
@@ -2586,6 +2587,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
ttm_lru_bulk_move_init(&vm->lru_bulk_move);
vm->is_compute_context = false;
+ vm->need_tlb_fence = amdgpu_userq_enabled(&adev->ddev);
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
AMDGPU_VM_USE_CPU_FOR_GFX);
@@ -2723,6 +2725,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
dma_fence_put(vm->last_update);
vm->last_update = dma_fence_get_stub();
vm->is_compute_context = true;
+ vm->need_tlb_fence = true;
unreserve_bo:
amdgpu_bo_unreserve(vm->root.bo);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 70fec516a290..076d9a3a5e62 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -439,6 +439,8 @@ struct amdgpu_vm {
struct ttm_lru_bulk_move lru_bulk_move;
/* Flag to indicate if VM is used for compute */
bool is_compute_context;
+ /* Flag to indicate if VM needs a TLB fence (KFD or KGD) */
+ bool need_tlb_fence;
/* Memory partition number, -1 means any partition */
int8_t mem_id;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
index 22e2e5b47341..f078db3fef79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
@@ -21,6 +21,8 @@
*/
#include "amdgpu_vm.h"
+#include "amdgpu.h"
+#include "amdgpu_reset.h"
#include "amdgpu_object.h"
#include "amdgpu_trace.h"
@@ -108,11 +110,19 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p,
static int amdgpu_vm_cpu_commit(struct amdgpu_vm_update_params *p,
struct dma_fence **fence)
{
+ struct amdgpu_device *adev = p->adev;
+
if (p->needs_flush)
atomic64_inc(&p->vm->tlb_seq);
mb();
- amdgpu_device_flush_hdp(p->adev, NULL);
+ /* A reset flushed the HDP anyway, so that here can be skipped when a reset is ongoing */
+ if (!down_read_trylock(&adev->reset_domain->sem))
+ return 0;
+
+ amdgpu_device_flush_hdp(adev, NULL);
+ up_read(&adev->reset_domain->sem);
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 1dd9fd486eec..feb56b6b31c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -64,6 +64,11 @@
#define regPC_CONFIG_CNTL_1 0x194d
#define regPC_CONFIG_CNTL_1_BASE_IDX 1
+#define regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0 0x0030
+#define regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0_BASE_IDX 1
+#define regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0 0x0031
+#define regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0_BASE_IDX 1
+
#define regCP_GFX_MQD_CONTROL_DEFAULT 0x00000100
#define regCP_GFX_HQD_VMID_DEFAULT 0x00000000
#define regCP_GFX_HQD_QUEUE_PRIORITY_DEFAULT 0x00000000
@@ -5174,11 +5179,27 @@ static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev)
amdgpu_gfx_off_ctrl(adev, true);
} else {
preempt_disable();
- clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER);
- clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER);
- clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER);
- if (clock_counter_hi_pre != clock_counter_hi_after)
- clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER);
+ if (amdgpu_ip_version(adev, SMUIO_HWIP, 0) < IP_VERSION(15, 0, 0)) {
+ clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER);
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER);
+ clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER);
+ if (clock_counter_hi_pre != clock_counter_hi_after)
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER);
+ } else {
+ clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0);
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0);
+ clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0);
+ if (clock_counter_hi_pre != clock_counter_hi_after)
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0);
+ }
preempt_enable();
}
clock = clock_counter_lo | (clock_counter_hi_after << 32ULL);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 7d0a2d239b78..f589457f6018 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -5640,9 +5640,6 @@ static void gfx_v9_0_ring_emit_fence_kiq(struct amdgpu_ring *ring, u64 addr,
{
struct amdgpu_device *adev = ring->adev;
- /* we only allocate 32bit for each seq wb address */
- BUG_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
-
/* write fence seq to the "addr" */
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index f38004e6064e..4d0dc58c9045 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -890,7 +890,7 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
/* write the fence */
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
/* zero in first two bits */
- BUG_ON(addr & 0x3);
+ WARN_ON(addr & 0x3);
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, lower_32_bits(seq));
@@ -900,7 +900,7 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
addr += 4;
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
/* zero in first two bits */
- BUG_ON(addr & 0x3);
+ WARN_ON(addr & 0x3);
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(seq));
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
index d9cf8f0feeb3..8b226edfbea3 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
@@ -1908,7 +1908,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
{
struct ttm_operation_ctx ctx = { false, false };
struct amdgpu_bo_va_mapping *map;
- uint32_t *msg, num_buffers;
+ uint32_t *msg, num_buffers, len_dw;
struct amdgpu_bo *bo;
uint64_t start, end;
unsigned int i;
@@ -1929,6 +1929,11 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
return -EINVAL;
}
+ if (end - addr < 16) {
+ DRM_ERROR("VCN messages must be at least 4 DWORDs!\n");
+ return -EINVAL;
+ }
+
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
@@ -1945,8 +1950,8 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
msg = ptr + addr - start;
- /* Check length */
if (msg[1] > end - addr) {
+ DRM_ERROR("VCN message header does not fit in BO!\n");
r = -EINVAL;
goto out;
}
@@ -1954,9 +1959,19 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
if (msg[3] != RDECODE_MSG_CREATE)
goto out;
+ len_dw = msg[1] / 4;
num_buffers = msg[2];
+
+ /* Verify that all indices fit within the claimed length. Each index is 4 DWORDs */
+ if (num_buffers > len_dw || 6 + num_buffers * 4 > len_dw) {
+ DRM_ERROR("VCN message has too many buffers!\n");
+ r = -EINVAL;
+ goto out;
+ }
+
for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
uint32_t offset, size, *create;
+ uint64_t buf_end;
if (msg[0] != RDECODE_MESSAGE_CREATE)
continue;
@@ -1964,14 +1979,16 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
offset = msg[1];
size = msg[2];
- if (offset + size > end) {
+ if (size < 4 || check_add_overflow(offset, size, &buf_end) ||
+ buf_end > end - addr) {
+ DRM_ERROR("VCN message buffer exceeds BO bounds!\n");
r = -EINVAL;
goto out;
}
create = ptr + addr + offset - start;
- /* H246, HEVC and VP9 can run on any instance */
+ /* H264, HEVC and VP9 can run on any instance */
if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
index 3ae666522d57..64bda0e944a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
@@ -1825,7 +1825,7 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
{
struct ttm_operation_ctx ctx = { false, false };
struct amdgpu_bo_va_mapping *map;
- uint32_t *msg, num_buffers;
+ uint32_t *msg, num_buffers, len_dw;
struct amdgpu_bo *bo;
uint64_t start, end;
unsigned int i;
@@ -1846,6 +1846,11 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
return -EINVAL;
}
+ if (end - addr < 16) {
+ DRM_ERROR("VCN messages must be at least 4 DWORDs!\n");
+ return -EINVAL;
+ }
+
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
@@ -1862,8 +1867,8 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
msg = ptr + addr - start;
- /* Check length */
if (msg[1] > end - addr) {
+ DRM_ERROR("VCN message header does not fit in BO!\n");
r = -EINVAL;
goto out;
}
@@ -1871,9 +1876,19 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
if (msg[3] != RDECODE_MSG_CREATE)
goto out;
+ len_dw = msg[1] / 4;
num_buffers = msg[2];
+
+ /* Verify that all indices fit within the claimed length. Each index is 4 DWORDs */
+ if (num_buffers > len_dw || 6 + num_buffers * 4 > len_dw) {
+ DRM_ERROR("VCN message has too many buffers!\n");
+ r = -EINVAL;
+ goto out;
+ }
+
for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
uint32_t offset, size, *create;
+ uint64_t buf_end;
if (msg[0] != RDECODE_MESSAGE_CREATE)
continue;
@@ -1881,7 +1896,9 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
offset = msg[1];
size = msg[2];
- if (offset + size > end) {
+ if (size < 4 || check_add_overflow(offset, size, &buf_end) ||
+ buf_end > end - addr) {
+ DRM_ERROR("VCN message buffer exceeds BO bounds!\n");
r = -EINVAL;
goto out;
}
@@ -1912,9 +1929,10 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int start)
{
int i;
+ uint32_t len;
- for (i = start; i < ib->length_dw && ib->ptr[i] >= 8; i += ib->ptr[i] / 4) {
- if (ib->ptr[i + 1] == id)
+ for (i = start; (len = amdgpu_ib_get_value(ib, i)) >= 8; i += len / 4) {
+ if (amdgpu_ib_get_value(ib, i + 1) == id)
return i;
}
return -1;
@@ -1925,8 +1943,6 @@ static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
struct amdgpu_ib *ib)
{
struct amdgpu_ring *ring = amdgpu_job_ring(job);
- struct amdgpu_vcn_decode_buffer *decode_buffer;
- uint64_t addr;
uint32_t val;
int idx = 0, sidx;
@@ -1937,20 +1953,22 @@ static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
while ((idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO, idx)) >= 0) {
val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */
if (val == RADEON_VCN_ENGINE_TYPE_DECODE) {
- decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6];
+ uint32_t valid_buf_flag = amdgpu_ib_get_value(ib, idx + 6);
+ uint64_t msg_buffer_addr;
- if (!(decode_buffer->valid_buf_flag & 0x1))
+ if (!(valid_buf_flag & 0x1))
return 0;
- addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
- decode_buffer->msg_buffer_address_lo;
- return vcn_v4_0_dec_msg(p, job, addr);
+ msg_buffer_addr = ((u64)amdgpu_ib_get_value(ib, idx + 7)) << 32 |
+ amdgpu_ib_get_value(ib, idx + 8);
+ return vcn_v4_0_dec_msg(p, job, msg_buffer_addr);
} else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) {
sidx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT, idx);
- if (sidx >= 0 && ib->ptr[sidx + 2] == RENCODE_ENCODE_STANDARD_AV1)
+ if (sidx >= 0 &&
+ amdgpu_ib_get_value(ib, sidx + 2) == RENCODE_ENCODE_STANDARD_AV1)
return vcn_v4_0_limit_sched(p, job);
}
- idx += ib->ptr[idx] / 4;
+ idx += amdgpu_ib_get_value(ib, idx) / 4;
}
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 0f0719528bcc..0fcf150b9ffa 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/file.h>
+#include <linux/overflow.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -763,6 +764,9 @@ static int kfd_ioctl_get_process_apertures_new(struct file *filp,
goto out_unlock;
}
+ if (args->num_of_nodes > kfd_topology_get_num_devices())
+ return -EINVAL;
+
/* Fill in process-aperture information for all available
* nodes, but not more than args->num_of_nodes as that is
* the amount of memory allocated by user
@@ -1337,7 +1341,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
if (WARN_ON_ONCE(!peer_pdd))
continue;
- kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
+ kfd_flush_tlb(peer_pdd);
}
kfree(devices_arr);
@@ -1432,7 +1436,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
if (WARN_ON_ONCE(!peer_pdd))
continue;
if (flush_tlb)
- kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
+ kfd_flush_tlb(peer_pdd);
/* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */
err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);
@@ -1673,6 +1677,16 @@ static int kfd_ioctl_smi_events(struct file *filep,
return kfd_smi_event_open(pdd->dev, &args->anon_fd);
}
+static int kfd_ioctl_svm_validate(void *kdata, unsigned int usize)
+{
+ struct kfd_ioctl_svm_args *args = kdata;
+ size_t expected = struct_size(args, attrs, args->nattr);
+
+ if (expected == SIZE_MAX || usize < expected)
+ return -EINVAL;
+ return 0;
+}
+
#if IS_ENABLED(CONFIG_HSA_AMD_SVM)
static int kfd_ioctl_set_xnack_mode(struct file *filep,
@@ -3119,7 +3133,11 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
- .cmd_drv = 0, .name = #ioctl}
+ .validate = NULL, .cmd_drv = 0, .name = #ioctl}
+
+#define AMDKFD_IOCTL_DEF_V(ioctl, _func, _validate, _flags) \
+ [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
+ .validate = _validate, .cmd_drv = 0, .name = #ioctl}
/** Ioctl table */
static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
@@ -3216,7 +3234,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS,
kfd_ioctl_smi_events, 0),
- AMDKFD_IOCTL_DEF(AMDKFD_IOC_SVM, kfd_ioctl_svm, 0),
+ AMDKFD_IOCTL_DEF_V(AMDKFD_IOC_SVM, kfd_ioctl_svm,
+ kfd_ioctl_svm_validate, 0),
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_XNACK_MODE,
kfd_ioctl_set_xnack_mode, 0),
@@ -3338,6 +3357,12 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
memset(kdata, 0, usize);
}
+ if (ioctl->validate) {
+ retcode = ioctl->validate(kdata, usize);
+ if (retcode)
+ goto err_i1;
+ }
+
retcode = func(filep, process, kdata);
if (cmd & IOC_OUT)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 58c5acf50a22..51a47a91e21e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -569,7 +569,7 @@ static int allocate_vmid(struct device_queue_manager *dqm,
qpd->vmid,
qpd->page_table_base);
/* invalidate the VM context after pasid and vmid mapping is set up */
- kfd_flush_tlb(qpd_to_pdd(qpd), TLB_FLUSH_LEGACY);
+ kfd_flush_tlb(qpd_to_pdd(qpd));
if (dqm->dev->kfd2kgd->set_scratch_backing_va)
dqm->dev->kfd2kgd->set_scratch_backing_va(dqm->dev->adev,
@@ -607,7 +607,7 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
if (flush_texture_cache_nocpsch(q->device, qpd))
dev_err(dev, "Failed to flush TC\n");
- kfd_flush_tlb(qpd_to_pdd(qpd), TLB_FLUSH_LEGACY);
+ kfd_flush_tlb(qpd_to_pdd(qpd));
/* Release the vmid mapping */
set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
@@ -1282,7 +1282,7 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
dqm->dev->adev,
qpd->vmid,
qpd->page_table_base);
- kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
+ kfd_flush_tlb(pdd);
}
/* Take a safe reference to the mm_struct, which may otherwise
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 4f4eb0791138..24e85440473a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1036,10 +1036,13 @@ extern struct srcu_struct kfd_processes_srcu;
typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p,
void *data);
+typedef int amdkfd_ioctl_validate_t(void *kdata, unsigned int usize);
+
struct amdkfd_ioctl_desc {
unsigned int cmd;
int flags;
amdkfd_ioctl_t *func;
+ amdkfd_ioctl_validate_t *validate;
unsigned int cmd_drv;
const char *name;
};
@@ -1175,6 +1178,7 @@ static inline struct kfd_node *kfd_node_by_irq_ids(struct amdgpu_device *adev,
return NULL;
}
int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_node **kdev);
+uint32_t kfd_topology_get_num_devices(void);
int kfd_numa_node_to_apic_id(int numa_node_id);
/* Interrupts */
@@ -1529,13 +1533,13 @@ void kfd_signal_reset_event(struct kfd_node *dev);
void kfd_signal_poison_consumed_event(struct kfd_node *dev, u32 pasid);
-static inline void kfd_flush_tlb(struct kfd_process_device *pdd,
- enum TLB_FLUSH_TYPE type)
+static inline void kfd_flush_tlb(struct kfd_process_device *pdd)
{
struct amdgpu_device *adev = pdd->dev->adev;
struct amdgpu_vm *vm = drm_priv_to_vm(pdd->drm_priv);
- amdgpu_vm_flush_compute_tlb(adev, vm, type, pdd->dev->xcc_mask);
+ amdgpu_vm_flush_compute_tlb(adev, vm, TLB_FLUSH_HEAVYWEIGHT,
+ pdd->dev->xcc_mask);
}
static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 6daa70ace261..a24b3c00f9f0 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -1391,7 +1391,7 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
if (r)
break;
}
- kfd_flush_tlb(pdd, TLB_FLUSH_HEAVYWEIGHT);
+ kfd_flush_tlb(pdd);
}
return r;
@@ -1525,7 +1525,7 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
}
}
- kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
+ kfd_flush_tlb(pdd);
}
return r;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 3eb32d58a120..02b1860cde7d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -2295,6 +2295,17 @@ int kfd_topology_remove_device(struct kfd_node *gpu)
return res;
}
+uint32_t kfd_topology_get_num_devices(void)
+{
+ uint32_t num_devices;
+
+ down_read(&topology_lock);
+ num_devices = sys_props.num_devices;
+ up_read(&topology_lock);
+
+ return num_devices;
+}
+
/* kfd_topology_enum_kfd_devices - Enumerate through all devices in KFD
* topology. If GPU device is found @idx, then valid kfd_dev pointer is
* returned through @kdev
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index bc5dedf5f60c..a614bfe50630 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -4954,7 +4954,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
option = DITHER_OPTION_SPATIAL8;
break;
case COLOR_DEPTH_101010:
- option = DITHER_OPTION_TRUN10;
+ option = DITHER_OPTION_SPATIAL10;
break;
default:
option = DITHER_OPTION_DISABLE;
diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c
index ad1fd3150d03..0cb7eaaba384 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c
@@ -1326,12 +1326,13 @@ static int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
dev_id = adev->pdev->device;
- if ((dpm_table->mclk_table.count >= 2)
- && ((dev_id == 0x67B0) || (dev_id == 0x67B1))) {
- smu_data->smc_state_table.MemoryLevel[1].MinVddci =
- smu_data->smc_state_table.MemoryLevel[0].MinVddci;
- smu_data->smc_state_table.MemoryLevel[1].MinMvdd =
- smu_data->smc_state_table.MemoryLevel[0].MinMvdd;
+ if ((dpm_table->mclk_table.count >= 2) &&
+ ((dev_id == 0x67B0) || (dev_id == 0x67B1)) &&
+ (adev->pdev->revision == 0)) {
+ smu_data->smc_state_table.MemoryLevel[1].MinVddc =
+ smu_data->smc_state_table.MemoryLevel[0].MinVddc;
+ smu_data->smc_state_table.MemoryLevel[1].MinVddcPhases =
+ smu_data->smc_state_table.MemoryLevel[0].MinVddcPhases;
}
smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F;
CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index 470a901926f3..3924429e1120 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -2442,6 +2442,7 @@ static int smu_v14_0_2_od_restore_table_single(struct smu_context *smu, long inp
}
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
break;
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
od_table->OverDriveTable.FanZeroRpmEnable =
@@ -2470,7 +2471,8 @@ static int smu_v14_0_2_od_restore_table_single(struct smu_context *smu, long inp
od_table->OverDriveTable.FanMinimumPwm =
boot_overdrive_table->OverDriveTable.FanMinimumPwm;
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
- od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
@@ -2640,6 +2642,7 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FanLinearPwmPoints[input[0]] = input[2];
od_table->OverDriveTable.FanMode = FAN_MODE_MANUAL_LINEAR;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
break;
case PP_OD_EDIT_ACOUSTIC_LIMIT:
@@ -2709,7 +2712,7 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
break;
case PP_OD_EDIT_FAN_MINIMUM_PWM:
- if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
+ if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_LEGACY_BIT)) {
dev_warn(adev->dev, "Fan curve setting not supported!\n");
return -ENOTSUPP;
}
@@ -2727,7 +2730,8 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FanMinimumPwm = input[0];
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
- od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index e636459d9185..f90b08869267 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -1697,7 +1697,7 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
static int tda998x_get_audio_ports(struct tda998x_priv *priv,
struct device_node *np)
{
- const u32 *port_data;
+ const __be32 *port_data;
u32 size;
int i;
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 11e7141c1524..6d0d27aca518 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -969,7 +969,7 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_gem_change_handle *args = data;
- struct drm_gem_object *obj;
+ struct drm_gem_object *obj, *idrobj;
int handle, ret;
if (!drm_core_check_feature(dev, DRIVER_GEM))
@@ -992,8 +992,29 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
mutex_lock(&file_priv->prime.lock);
spin_lock(&file_priv->table_lock);
+
+ /* When create_tail allocs an obj idr, it needs to first alloc as NULL,
+ * then later replace with the correct object. This is not necessary
+ * here, because the only operations that could race are drm_prime
+ * bookkeeping, and we hold the prime lock.
+ */
ret = idr_alloc(&file_priv->object_idr, obj, handle, handle + 1,
GFP_NOWAIT);
+
+ if (ret < 0) {
+ spin_unlock(&file_priv->table_lock);
+ goto out_unlock;
+ }
+
+ idrobj = idr_replace(&file_priv->object_idr, NULL, handle);
+ if (idrobj != obj) {
+ idr_replace(&file_priv->object_idr, idrobj, handle);
+ idr_remove(&file_priv->object_idr, args->new_handle);
+ spin_unlock(&file_priv->table_lock);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
spin_unlock(&file_priv->table_lock);
if (ret < 0)
@@ -1005,6 +1026,8 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
if (ret < 0) {
spin_lock(&file_priv->table_lock);
idr_remove(&file_priv->object_idr, handle);
+ idrobj = idr_replace(&file_priv->object_idr, obj, handle);
+ WARN_ON(idrobj != NULL);
spin_unlock(&file_priv->table_lock);
goto out_unlock;
}
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 4bc89d33df59..daa5471365c4 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -171,8 +171,8 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
}
for (i = 0; i < info->num_planes; i++) {
- unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
- unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
+ unsigned int width = drm_format_info_plane_width(info, mode_cmd->width, i);
+ unsigned int height = drm_format_info_plane_height(info, mode_cmd->height, i);
unsigned int min_size;
objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
index cb906765897e..853ca57800d3 100644
--- a/drivers/gpu/drm/drm_gpusvm.c
+++ b/drivers/gpu/drm/drm_gpusvm.c
@@ -1443,6 +1443,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
return 0;
err_unmap:
+ svm_pages->flags.has_dma_mapping = true;
__drm_gpusvm_unmap_pages(gpusvm, svm_pages, num_dma_mapped);
drm_gpusvm_notifier_unlock(gpusvm);
err_free:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 29a8366513fa..e68c954ec3e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -423,7 +423,9 @@ static int exynos_mic_probe(struct platform_device *pdev)
mic->bridge.of_node = dev->of_node;
- drm_bridge_add(&mic->bridge);
+ ret = devm_drm_bridge_add(dev, &mic->bridge);
+ if (ret)
+ goto err;
pm_runtime_enable(dev);
@@ -443,12 +445,8 @@ static int exynos_mic_probe(struct platform_device *pdev)
static void exynos_mic_remove(struct platform_device *pdev)
{
- struct exynos_mic *mic = platform_get_drvdata(pdev);
-
component_del(&pdev->dev, &exynos_mic_component_ops);
pm_runtime_disable(&pdev->dev);
-
- drm_bridge_remove(&mic->bridge);
}
static const struct of_device_id exynos_mic_of_match[] = {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 504f6228bf35..1da20065ea77 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2840,7 +2840,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
return ret;
do {
- bool cursor_in_su_area;
+ bool cursor_in_su_area = false;
/*
* Adjust su area to cover cursor fully as necessary
diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c
index d5f2ee41c03f..68cd30b0bd1b 100644
--- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c
+++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c
@@ -110,8 +110,7 @@ imx_pd_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
output_fmt = imxpd->bus_format ? : MEDIA_BUS_FMT_RGB888_1X24;
/* Now make sure the requested output format is supported. */
- if ((imxpd->bus_format && imxpd->bus_format != output_fmt) ||
- !imx_pd_format_supported(output_fmt)) {
+ if (!imx_pd_format_supported(output_fmt)) {
*num_input_fmts = 0;
return NULL;
}
@@ -121,7 +120,17 @@ imx_pd_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
if (!input_fmts)
return NULL;
- input_fmts[0] = output_fmt;
+ /*
+ * Prefer bus format set via legacy "interface-pix-fmt" DT property
+ * over panel bus format. This is necessary to retain support for
+ * DTs which configure the IPUv3 parallel output as 24bit, but
+ * connect 18bit DPI panels to it with hardware swizzling.
+ */
+ if (imxpd->bus_format && imxpd->bus_format != output_fmt)
+ input_fmts[0] = imxpd->bus_format;
+ else
+ input_fmts[0] = output_fmt;
+
return input_fmts;
}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 46fd58646d32..93a491a103e0 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -80,7 +80,7 @@ static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi,
for (i = 0; i < ARRAY_SIZE(buf); i++)
hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
+ val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
val |= HDMI_INFOFRAME_CTRL0_AVI_SEND |
HDMI_INFOFRAME_CTRL0_AVI_CONT;
hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
@@ -116,7 +116,7 @@ static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi,
buffer[9] << 16 |
buffer[10] << 24);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
+ val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
val |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 7e977fec4100..94b32973cd6a 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -536,6 +536,11 @@ static int msm_ioctl_gem_info_get_metadata(struct drm_gem_object *obj,
len = msm_obj->metadata_size;
buf = kmemdup(msm_obj->metadata, len, GFP_KERNEL);
+ if (!buf) {
+ msm_gem_unlock(obj);
+ return -ENOMEM;
+ }
+
msm_gem_unlock(obj);
if (*metadata_size < len) {
@@ -548,7 +553,7 @@ static int msm_ioctl_gem_info_get_metadata(struct drm_gem_object *obj,
kfree(buf);
- return 0;
+ return ret;
}
static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index dd0605fe1243..a4377ee84c72 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -548,32 +548,30 @@ static void recover_worker(struct kthread_work *work)
msm_update_fence(ring->fctx, fence);
}
- if (msm_gpu_active(gpu)) {
- /* retire completed submits, plus the one that hung: */
- retire_submits(gpu);
+ /* retire completed submits, plus the one that hung: */
+ retire_submits(gpu);
- gpu->funcs->recover(gpu);
+ gpu->funcs->recover(gpu);
- /*
- * Replay all remaining submits starting with highest priority
- * ring
- */
- for (i = 0; i < gpu->nr_rings; i++) {
- struct msm_ringbuffer *ring = gpu->rb[i];
- unsigned long flags;
+ /*
+ * Replay all remaining submits starting with highest priority
+ * ring
+ */
+ for (i = 0; i < gpu->nr_rings; i++) {
+ struct msm_ringbuffer *ring = gpu->rb[i];
+ unsigned long flags;
- spin_lock_irqsave(&ring->submit_lock, flags);
- list_for_each_entry(submit, &ring->submits, node) {
- /*
- * If the submit uses an unusable vm make sure
- * we don't actually run it
- */
- if (to_msm_vm(submit->vm)->unusable)
- submit->nr_cmds = 0;
- gpu->funcs->submit(gpu, submit);
- }
- spin_unlock_irqrestore(&ring->submit_lock, flags);
+ spin_lock_irqsave(&ring->submit_lock, flags);
+ list_for_each_entry(submit, &ring->submits, node) {
+ /*
+ * If the submit uses an unusable vm make sure
+ * we don't actually run it
+ */
+ if (to_msm_vm(submit->vm)->unusable)
+ submit->nr_cmds = 0;
+ gpu->funcs->submit(gpu, submit);
}
+ spin_unlock_irqrestore(&ring->submit_lock, flags);
}
pm_runtime_put(&gpu->pdev->dev);
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index d5fe105bdbdd..658ce64c71eb 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1324,6 +1324,8 @@ static int boe_panel_disable(struct drm_panel *panel)
mipi_dsi_dcs_set_display_off_multi(&ctx);
mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
+ boe->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
mipi_dsi_msleep(&ctx, 150);
return ctx.accum_err;
diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c b/drivers/gpu/drm/panel/panel-himax-hx83102.c
index 4c432d207634..ebbd649c67dc 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx83102.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
@@ -850,6 +850,8 @@ static int hx83102_disable(struct drm_panel *panel)
mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
mipi_dsi_msleep(&dsi_ctx, 150);
return dsi_ctx.accum_err;
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index ba8db1d07c07..b47b91272b24 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -2461,7 +2461,8 @@ static void ci_register_patching_mc_arb(struct radeon_device *rdev,
if (patch &&
((rdev->pdev->device == 0x67B0) ||
- (rdev->pdev->device == 0x67B1))) {
+ (rdev->pdev->device == 0x67B1)) &&
+ (rdev->pdev->revision == 0)) {
if ((memory_clock > 100000) && (memory_clock <= 125000)) {
tmp2 = (((0x31 * engine_clock) / 125000) - 1) & 0xff;
*dram_timimg2 &= ~0x00ff0000;
@@ -3304,7 +3305,8 @@ static int ci_populate_all_memory_levels(struct radeon_device *rdev)
pi->smc_state_table.MemoryLevel[0].EnabledForActivity = 1;
if ((dpm_table->mclk_table.count >= 2) &&
- ((rdev->pdev->device == 0x67B0) || (rdev->pdev->device == 0x67B1))) {
+ ((rdev->pdev->device == 0x67B0) || (rdev->pdev->device == 0x67B1)) &&
+ (rdev->pdev->revision == 0)) {
pi->smc_state_table.MemoryLevel[1].MinVddc =
pi->smc_state_table.MemoryLevel[0].MinVddc;
pi->smc_state_table.MemoryLevel[1].MinVddcPhases =
@@ -4493,7 +4495,8 @@ static int ci_register_patching_mc_seq(struct radeon_device *rdev,
if (patch &&
((rdev->pdev->device == 0x67B0) ||
- (rdev->pdev->device == 0x67B1))) {
+ (rdev->pdev->device == 0x67B1)) &&
+ (rdev->pdev->revision == 0)) {
for (i = 0; i < table->last; i++) {
if (table->last >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
return -EINVAL;
diff --git a/drivers/gpu/drm/tiny/appletbdrm.c b/drivers/gpu/drm/tiny/appletbdrm.c
index 751b05753c94..f596e9637a7b 100644
--- a/drivers/gpu/drm/tiny/appletbdrm.c
+++ b/drivers/gpu/drm/tiny/appletbdrm.c
@@ -353,7 +353,7 @@ static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
frames_size +
sizeof(struct appletbdrm_fb_request_footer), 16);
- appletbdrm_state->request = kzalloc(request_size, GFP_KERNEL);
+ appletbdrm_state->request = kvzalloc(request_size, GFP_KERNEL);
if (!appletbdrm_state->request)
return -ENOMEM;
@@ -543,7 +543,7 @@ static void appletbdrm_primary_plane_destroy_state(struct drm_plane *plane,
{
struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(state);
- kfree(appletbdrm_state->request);
+ kvfree(appletbdrm_state->request);
kfree(appletbdrm_state->response);
__drm_gem_destroy_shadow_plane_state(&appletbdrm_state->base);
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index bc58991a6f14..b4c23dbcf3e3 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -285,13 +285,12 @@ static struct urb *udl_get_urb_locked(struct udl_device *udl, long timeout)
return unode->urb;
}
-#define GET_URB_TIMEOUT HZ
struct urb *udl_get_urb(struct udl_device *udl)
{
struct urb *urb;
spin_lock_irq(&udl->urbs.lock);
- urb = udl_get_urb_locked(udl, GET_URB_TIMEOUT);
+ urb = udl_get_urb_locked(udl, HZ * 2);
spin_unlock_irq(&udl->urbs.lock);
return urb;
}
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 231e829bd709..1ca073a4ecb2 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -21,6 +21,7 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -342,8 +343,10 @@ static void udl_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom
return;
urb = udl_get_urb(udl);
- if (!urb)
+ if (!urb) {
+ drm_err_ratelimited(dev, "get urb failed when enabling crtc\n");
goto out;
+ }
buf = (char *)urb->transfer_buffer;
buf = udl_vidreg_lock(buf);
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index a270aef7c498..0dabe8535139 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -2112,8 +2112,10 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
}
/* XE_BO_FLAG_GGTTx requires XE_BO_FLAG_GGTT also be set */
- if ((flags & XE_BO_FLAG_GGTT_ALL) && !(flags & XE_BO_FLAG_GGTT))
+ if ((flags & XE_BO_FLAG_GGTT_ALL) && !(flags & XE_BO_FLAG_GGTT)) {
+ xe_bo_free(bo);
return ERR_PTR(-EINVAL);
+ }
if (flags & (XE_BO_FLAG_VRAM_MASK | XE_BO_FLAG_STOLEN) &&
!(flags & XE_BO_FLAG_IGNORE_MIN_PAGE_SIZE) &&
@@ -2132,8 +2134,10 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
alignment = SZ_4K >> PAGE_SHIFT;
}
- if (type == ttm_bo_type_device && aligned_size != size)
+ if (type == ttm_bo_type_device && aligned_size != size) {
+ xe_bo_free(bo);
return ERR_PTR(-EINVAL);
+ }
if (!bo) {
bo = xe_bo_alloc();
diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index 2650c5abb365..4cef02ff1451 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -227,6 +227,13 @@ struct dma_buf *xe_gem_prime_export(struct drm_gem_object *obj, int flags)
return buf;
}
+/*
+ * Takes ownership of @storage: on success it is transferred to the returned
+ * drm_gem_object; on failure it is freed before returning the error.
+ * This matches the contract of xe_bo_init_locked() which frees @storage on
+ * its error paths, so callers need not (and must not) free @storage after
+ * this call.
+ */
static struct drm_gem_object *
xe_dma_buf_init_obj(struct drm_device *dev, struct xe_bo *storage,
struct dma_buf *dma_buf)
@@ -240,8 +247,10 @@ xe_dma_buf_init_obj(struct drm_device *dev, struct xe_bo *storage,
int ret = 0;
dummy_obj = drm_gpuvm_resv_object_alloc(&xe->drm);
- if (!dummy_obj)
+ if (!dummy_obj) {
+ xe_bo_free(storage);
return ERR_PTR(-ENOMEM);
+ }
dummy_obj->resv = resv;
xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {}, ret) {
@@ -250,6 +259,7 @@ xe_dma_buf_init_obj(struct drm_device *dev, struct xe_bo *storage,
if (ret)
break;
+ /* xe_bo_init_locked() frees storage on error */
bo = xe_bo_init_locked(xe, storage, NULL, resv, NULL, dma_buf->size,
0, /* Will require 1way or 2way for vm_bind */
ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, &exec);
@@ -337,12 +347,15 @@ struct drm_gem_object *xe_gem_prime_import(struct drm_device *dev,
goto out_err;
}
- /* Errors here will take care of freeing the bo. */
+ /*
+ * xe_dma_buf_init_obj() takes ownership of bo on both success
+ * and failure, so we must not touch bo after this call.
+ */
obj = xe_dma_buf_init_obj(dev, bo, dma_buf);
- if (IS_ERR(obj))
+ if (IS_ERR(obj)) {
+ dma_buf_detach(dma_buf, attach);
return obj;
-
-
+ }
get_dma_buf(dma_buf);
obj->import_attach = attach;
return obj;
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index 9dc801f65712..da306013a013 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -299,6 +299,45 @@ static bool madvise_args_are_sane(struct xe_device *xe, const struct drm_xe_madv
return true;
}
+static bool check_pat_args_are_sane(struct xe_device *xe,
+ struct xe_vmas_in_madvise_range *madvise_range,
+ u16 pat_index)
+{
+ u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ int i;
+
+ /*
+ * Using coh_none with CPU cached buffers is not allowed on iGPU.
+ * On iGPU the GPU shares the LLC with the CPU, so with coh_none
+ * the GPU bypasses CPU caches and reads directly from DRAM,
+ * potentially seeing stale sensitive data from previously freed
+ * pages. On dGPU this restriction does not apply, because the
+ * platform does not provide a non-coherent system memory access
+ * path that would violate the DMA coherency contract.
+ */
+ if (coh_mode != XE_COH_NONE || IS_DGFX(xe))
+ return true;
+
+ for (i = 0; i < madvise_range->num_vmas; i++) {
+ struct xe_vma *vma = madvise_range->vmas[i];
+ struct xe_bo *bo = xe_vma_bo(vma);
+
+ if (bo) {
+ /* BO with WB caching + COH_NONE is not allowed */
+ if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
+ return false;
+ /* Imported dma-buf without caching info, assume cached */
+ if (XE_IOCTL_DBG(xe, !bo->cpu_caching))
+ return false;
+ } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) ||
+ xe_vma_is_userptr(vma)))
+ /* System memory (userptr/SVM) is always CPU cached */
+ return false;
+ }
+
+ return true;
+}
+
static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas,
int num_vmas, u32 atomic_val)
{
@@ -384,6 +423,14 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
if (err || !madvise_range.num_vmas)
goto unlock_vm;
+ if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) {
+ if (!check_pat_args_are_sane(xe, &madvise_range,
+ args->pat_index.val)) {
+ err = -EINVAL;
+ goto free_vmas;
+ }
+ }
+
if (madvise_range.has_bo_vmas) {
if (args->type == DRM_XE_MEM_RANGE_ATTR_ATOMIC) {
if (!check_bo_args_are_sane(vm, madvise_range.vmas,
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
index 0b10cff465e1..c96423a531f6 100644
--- a/drivers/hid/hid-appletb-kbd.c
+++ b/drivers/hid/hid-appletb-kbd.c
@@ -17,7 +17,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/backlight.h>
-#include <linux/timer.h>
+#include <linux/workqueue.h>
#include <linux/input/sparse-keymap.h>
#include "hid-ids.h"
@@ -62,7 +62,8 @@ struct appletb_kbd {
struct input_handle kbd_handle;
struct input_handle tpd_handle;
struct backlight_device *backlight_dev;
- struct timer_list inactivity_timer;
+ struct delayed_work inactivity_work;
+ struct work_struct restore_brightness_work;
bool has_dimmed;
bool has_turned_off;
u8 saved_mode;
@@ -164,16 +165,18 @@ static int appletb_tb_key_to_slot(unsigned int code)
}
}
-static void appletb_inactivity_timer(struct timer_list *t)
+static void appletb_inactivity_work(struct work_struct *work)
{
- struct appletb_kbd *kbd = timer_container_of(kbd, t, inactivity_timer);
+ struct appletb_kbd *kbd = container_of(to_delayed_work(work),
+ struct appletb_kbd,
+ inactivity_work);
if (kbd->backlight_dev && appletb_tb_autodim) {
if (!kbd->has_dimmed) {
backlight_device_set_brightness(kbd->backlight_dev, 1);
kbd->has_dimmed = true;
- mod_timer(&kbd->inactivity_timer,
- jiffies + secs_to_jiffies(appletb_tb_idle_timeout));
+ mod_delayed_work(system_wq, &kbd->inactivity_work,
+ secs_to_jiffies(appletb_tb_idle_timeout));
} else if (!kbd->has_turned_off) {
backlight_device_set_brightness(kbd->backlight_dev, 0);
kbd->has_turned_off = true;
@@ -181,16 +184,25 @@ static void appletb_inactivity_timer(struct timer_list *t)
}
}
+static void appletb_restore_brightness_work(struct work_struct *work)
+{
+ struct appletb_kbd *kbd = container_of(work, struct appletb_kbd,
+ restore_brightness_work);
+
+ if (kbd->backlight_dev)
+ backlight_device_set_brightness(kbd->backlight_dev, 2);
+}
+
static void reset_inactivity_timer(struct appletb_kbd *kbd)
{
if (kbd->backlight_dev && appletb_tb_autodim) {
if (kbd->has_dimmed || kbd->has_turned_off) {
- backlight_device_set_brightness(kbd->backlight_dev, 2);
kbd->has_dimmed = false;
kbd->has_turned_off = false;
+ schedule_work(&kbd->restore_brightness_work);
}
- mod_timer(&kbd->inactivity_timer,
- jiffies + secs_to_jiffies(appletb_tb_dim_timeout));
+ mod_delayed_work(system_wq, &kbd->inactivity_work,
+ secs_to_jiffies(appletb_tb_dim_timeout));
}
}
@@ -408,9 +420,11 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
dev_err_probe(dev, -ENODEV, "Failed to get backlight device\n");
} else {
backlight_device_set_brightness(kbd->backlight_dev, 2);
- timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
- mod_timer(&kbd->inactivity_timer,
- jiffies + secs_to_jiffies(appletb_tb_dim_timeout));
+ INIT_DELAYED_WORK(&kbd->inactivity_work, appletb_inactivity_work);
+ INIT_WORK(&kbd->restore_brightness_work,
+ appletb_restore_brightness_work);
+ mod_delayed_work(system_wq, &kbd->inactivity_work,
+ secs_to_jiffies(appletb_tb_dim_timeout));
}
kbd->inp_handler.event = appletb_kbd_inp_event;
@@ -440,13 +454,14 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
unregister_handler:
input_unregister_handler(&kbd->inp_handler);
close_hw:
- if (kbd->backlight_dev) {
- put_device(&kbd->backlight_dev->dev);
- timer_delete_sync(&kbd->inactivity_timer);
- }
hid_hw_close(hdev);
stop_hw:
hid_hw_stop(hdev);
+ if (kbd->backlight_dev) {
+ cancel_delayed_work_sync(&kbd->inactivity_work);
+ cancel_work_sync(&kbd->restore_brightness_work);
+ put_device(&kbd->backlight_dev->dev);
+ }
return ret;
}
@@ -457,13 +472,14 @@ static void appletb_kbd_remove(struct hid_device *hdev)
appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
input_unregister_handler(&kbd->inp_handler);
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+
if (kbd->backlight_dev) {
+ cancel_delayed_work_sync(&kbd->inactivity_work);
+ cancel_work_sync(&kbd->restore_brightness_work);
put_device(&kbd->backlight_dev->dev);
- timer_delete_sync(&kbd->inactivity_timer);
}
-
- hid_hw_close(hdev);
- hid_hw_stop(hdev);
}
#ifdef CONFIG_PM
diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index 2ec6d4445e84..12fad45ac106 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -2378,7 +2378,8 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
(struct dualshock4_input_report_usb *)data;
ds4_report = &usb->common;
- num_touch_reports = usb->num_touch_reports;
+ num_touch_reports = min_t(u8, usb->num_touch_reports,
+ ARRAY_SIZE(usb->touch_reports));
touch_reports = usb->touch_reports;
} else if (hdev->bus == BUS_BLUETOOTH && report->id == DS4_INPUT_REPORT_BT &&
size == DS4_INPUT_REPORT_BT_SIZE) {
@@ -2392,7 +2393,8 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
}
ds4_report = &bt->common;
- num_touch_reports = bt->num_touch_reports;
+ num_touch_reports = min_t(u8, bt->num_touch_reports,
+ ARRAY_SIZE(bt->touch_reports));
touch_reports = bt->touch_reports;
} else if (hdev->bus == BUS_BLUETOOTH &&
report->id == DS4_INPUT_REPORT_BT_MINIMAL &&
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index 56d6af39ba81..c06b1913f5ba 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -11,6 +11,7 @@
#include "hid-pidff.h"
#include <linux/hid.h>
#include <linux/input.h>
+#include <linux/math64.h>
#include <linux/minmax.h>
#include <linux/slab.h>
#include <linux/usb.h>
@@ -325,8 +326,10 @@ static s32 pidff_clamp(s32 i, struct hid_field *field)
*/
static int pidff_rescale(int i, int max, struct hid_field *field)
{
- return i * (field->logical_maximum - field->logical_minimum) / max +
- field->logical_minimum;
+ /* 64 bits needed for big values during rescale */
+ s64 result = field->logical_maximum - field->logical_minimum;
+
+ return div_s64(result * i, max) + field->logical_minimum;
}
/*
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index b3bf2173c14e..7c30731cb9a5 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -345,6 +345,7 @@ static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
return err;
}
+ vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
/*
* Use common vm_area operations to track buffer refcount.
*/
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index d90f1b0b2051..f4e963cdb7f2 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -2695,7 +2695,7 @@ static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff)
static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
{
- s16 unit_khz_dds_val;
+ s32 unit_khz_dds_val;
u32 abs_offset_khz = abs(offset_khz);
u32 dds = state->cfg.pll->ifreq & 0x1ffffff;
u8 invert = !!(state->cfg.pll->ifreq & (1 << 25));
@@ -2716,7 +2716,7 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
dds = (1<<26) - dds;
} else {
ratio = 2;
- unit_khz_dds_val = (u16) (67108864 / state->cfg.pll->internal);
+ unit_khz_dds_val = 67108864 / state->cfg.pll->internal;
if (offset_khz < 0)
unit_khz_dds_val *= -1;
diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
index 8ab63ad8f385..1be6164c2d15 100644
--- a/drivers/media/i2c/imx283.c
+++ b/drivers/media/i2c/imx283.c
@@ -129,7 +129,8 @@
/* Master Mode Operation Control */
#define IMX283_REG_XMSTA CCI_REG8(0x3105)
-#define IMX283_XMSTA BIT(0)
+#define IMX283_XMSTA_START 0
+#define IMX283_XMSTA_STOP BIT(0)
#define IMX283_REG_SYNCDRV CCI_REG8(0x3107)
#define IMX283_SYNCDRV_XHS_XVS (0xa0 | 0x02)
@@ -1023,8 +1024,6 @@ static int imx283_standby_cancel(struct imx283 *imx283)
usleep_range(19000, 20000);
cci_write(imx283->cci, IMX283_REG_CLAMP, IMX283_CLPSQRST, &ret);
- cci_write(imx283->cci, IMX283_REG_XMSTA, 0, &ret);
- cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret);
return ret;
}
@@ -1117,6 +1116,10 @@ static int imx283_start_streaming(struct imx283 *imx283,
/* Apply customized values from controls (HMAX/VMAX/SHR) */
ret = __v4l2_ctrl_handler_setup(imx283->sd.ctrl_handler);
+ /* Start master mode */
+ cci_write(imx283->cci, IMX283_REG_XMSTA, IMX283_XMSTA_START, &ret);
+ cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret);
+
return ret;
}
@@ -1153,12 +1156,14 @@ static int imx283_disable_streams(struct v4l2_subdev *sd,
u64 streams_mask)
{
struct imx283 *imx283 = to_imx283(sd);
- int ret;
+ int ret = 0;
if (pad != IMAGE_PAD)
return -EINVAL;
- ret = cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STBLOGIC, NULL);
+ cci_write(imx283->cci, IMX283_REG_XMSTA, IMX283_XMSTA_STOP, &ret);
+ cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STANDBY, &ret);
+
if (ret)
dev_err(imx283->dev, "Failed to stop stream\n");
diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c
index 7bbd639a9ddf..5656b581a717 100644
--- a/drivers/media/i2c/imx412.c
+++ b/drivers/media/i2c/imx412.c
@@ -925,7 +925,7 @@ static int imx412_parse_hw_config(struct imx412 *imx412)
/* Request optional reset pin */
imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset",
- GPIOD_OUT_LOW);
+ GPIOD_OUT_HIGH);
if (IS_ERR(imx412->reset_gpio)) {
dev_err(imx412->dev, "failed to get reset gpio %ld\n",
PTR_ERR(imx412->reset_gpio));
diff --git a/drivers/media/i2c/ov08d10.c b/drivers/media/i2c/ov08d10.c
index 43ec2a1f2fcf..5e1b8b58b3d6 100644
--- a/drivers/media/i2c/ov08d10.c
+++ b/drivers/media/i2c/ov08d10.c
@@ -217,7 +217,7 @@ static const struct ov08d10_reg lane_2_mode_3280x2460[] = {
{0x9a, 0x30},
{0xa8, 0x02},
{0xfd, 0x02},
- {0xa1, 0x01},
+ {0xa1, 0x00},
{0xa2, 0x09},
{0xa3, 0x9c},
{0xa5, 0x00},
@@ -335,7 +335,7 @@ static const struct ov08d10_reg lane_2_mode_3264x2448[] = {
{0x9a, 0x30},
{0xa8, 0x02},
{0xfd, 0x02},
- {0xa1, 0x09},
+ {0xa1, 0x08},
{0xa2, 0x09},
{0xa3, 0x90},
{0xa5, 0x08},
@@ -467,7 +467,7 @@ static const struct ov08d10_reg lane_2_mode_1632x1224[] = {
{0xaa, 0xd0},
{0xab, 0x06},
{0xac, 0x68},
- {0xa1, 0x09},
+ {0xa1, 0x04},
{0xa2, 0x04},
{0xa3, 0xc8},
{0xa5, 0x04},
@@ -613,8 +613,8 @@ static const struct ov08d10_lane_cfg lane_cfg_2 = {
static u32 ov08d10_get_format_code(struct ov08d10 *ov08d10)
{
static const u32 codes[2][2] = {
- { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10},
- { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10},
+ { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10 },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10 },
};
return codes[ov08d10->vflip->val][ov08d10->hflip->val];
@@ -1430,6 +1430,9 @@ static int ov08d10_probe(struct i2c_client *client)
goto probe_error_v4l2_ctrl_handler_free;
}
+ pm_runtime_set_active(ov08d10->dev);
+ pm_runtime_enable(ov08d10->dev);
+
ret = v4l2_async_register_subdev_sensor(&ov08d10->sd);
if (ret < 0) {
dev_err(ov08d10->dev, "failed to register V4L2 subdev: %d",
@@ -1437,17 +1440,13 @@ static int ov08d10_probe(struct i2c_client *client)
goto probe_error_media_entity_cleanup;
}
- /*
- * Device is already turned on by i2c-core with ACPI domain PM.
- * Enable runtime PM and turn off the device.
- */
- pm_runtime_set_active(ov08d10->dev);
- pm_runtime_enable(ov08d10->dev);
pm_runtime_idle(ov08d10->dev);
return 0;
probe_error_media_entity_cleanup:
+ pm_runtime_disable(ov08d10->dev);
+ pm_runtime_set_suspended(ov08d10->dev);
media_entity_cleanup(&ov08d10->sd.entity);
probe_error_v4l2_ctrl_handler_free:
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
index e2998cfa0d18..dd01e1d515ff 100644
--- a/drivers/media/i2c/ov8856.c
+++ b/drivers/media/i2c/ov8856.c
@@ -1951,12 +1951,18 @@ static int ov8856_init_controls(struct ov8856 *ov8856)
V4L2_CID_HFLIP, 0, 1, 1, 0);
v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops,
V4L2_CID_VFLIP, 0, 1, 1, 0);
- if (ctrl_hdlr->error)
- return ctrl_hdlr->error;
+ if (ctrl_hdlr->error) {
+ ret = ctrl_hdlr->error;
+ goto err_ctrl_handler_free;
+ }
ov8856->sd.ctrl_handler = ctrl_hdlr;
return 0;
+
+err_ctrl_handler_free:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+ return ret;
}
static void ov8856_update_pad_format(struct ov8856 *ov8856,
diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c
index a2768f44017a..fab7783c664b 100644
--- a/drivers/media/pci/intel/ipu6/ipu6.c
+++ b/drivers/media/pci/intel/ipu6/ipu6.c
@@ -686,7 +686,7 @@ static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
out_ipu6_rpm_put:
pm_runtime_put_sync(&isp->psys->auxdev.dev);
out_ipu6_bus_del_devices:
- if (isp->psys) {
+ if (!IS_ERR_OR_NULL(isp->psys)) {
ipu6_cpd_free_pkg_dir(isp->psys);
ipu6_buttress_unmap_fw_image(isp->psys, &isp->psys->fw_sgt);
}
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index a8a004f28ca0..ac290f546413 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev)
return -EBUSY;
}
+static void release_resources(struct saa7164_dev *dev)
+{
+ release_mem_region(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0));
+
+ release_mem_region(pci_resource_start(dev->pci, 2),
+ pci_resource_len(dev->pci, 2));
+}
+
static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
{
struct saa7164_port *port = NULL;
@@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr);
- mutex_lock(&devlist);
- list_add_tail(&dev->devlist, &saa7164_devlist);
- mutex_unlock(&devlist);
+ scoped_guard(mutex, &devlist) {
+ list_add_tail(&dev->devlist, &saa7164_devlist);
+ }
/* board config */
dev->board = UNSET;
@@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
}
/* PCI/e allocations */
- dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0));
+ dev->lmmio = pci_ioremap_bar(dev->pci, 0);
+ if (!dev->lmmio) {
+ dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n");
+ goto err_ioremap_bar0;
+ }
- dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
- pci_resource_len(dev->pci, 2));
+ dev->lmmio2 = pci_ioremap_bar(dev->pci, 2);
+ if (!dev->lmmio2) {
+ dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n");
+ goto err_ioremap_bar2;
+ }
dev->bmmio = (u8 __iomem *)dev->lmmio;
dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
@@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
saa7164_pci_quirks(dev);
return 0;
+
+err_ioremap_bar2:
+ iounmap(dev->lmmio);
+err_ioremap_bar0:
+ release_resources(dev);
+
+ scoped_guard(mutex, &devlist) {
+ list_del(&dev->devlist);
+ }
+ saa7164_devcount--;
+
+ return -ENODEV;
}
static void saa7164_dev_unregister(struct saa7164_dev *dev)
{
dprintk(1, "%s()\n", __func__);
- release_mem_region(pci_resource_start(dev->pci, 0),
- pci_resource_len(dev->pci, 0));
-
- release_mem_region(pci_resource_start(dev->pci, 2),
- pci_resource_len(dev->pci, 2));
+ release_resources(dev);
if (!atomic_dec_and_test(&dev->refcount))
return;
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index d81facf735d9..f707bdc1fb0f 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -1373,7 +1373,7 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
if (zr->codec->type != zr->card.video_codec) {
pci_err(pdev, "%s - wrong codec\n", __func__);
- goto zr_unreg_videocodec;
+ goto zr_detach_codec;
}
}
if (zr->card.video_vfe != 0) {
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vdi.c b/drivers/media/platform/chips-media/wave5/wave5-vdi.c
index bb13267ced38..8f71920a8a35 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vdi.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vdi.c
@@ -49,6 +49,7 @@ int wave5_vdi_init(struct device *dev)
if (!PRODUCT_CODE_W_SERIES(vpu_dev->product_code)) {
WARN_ONCE(1, "unsupported product code: 0x%x\n", vpu_dev->product_code);
+ wave5_vdi_free_dma_memory(vpu_dev, &vpu_dev->common_mem);
return -EOPNOTSUPP;
}
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index cff2fa17c3f5..7a4625acc047 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -1265,13 +1265,17 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
if (vb2_is_streaming(vb->vb2_queue) && v4l2_m2m_dst_buf_is_last(m2m_ctx)) {
unsigned int i;
+ unsigned long flags;
for (i = 0; i < vb->num_planes; i++)
vb2_set_plane_payload(vb, i, 0);
vbuf->field = V4L2_FIELD_NONE;
+ spin_lock_irqsave(&inst->state_spinlock, flags);
send_eos_event(inst);
+ spin_unlock_irqrestore(&inst->state_spinlock, flags);
+
v4l2_m2m_last_buffer_done(m2m_ctx, vbuf);
} else {
v4l2_m2m_buf_queue(m2m_ctx, vbuf);
@@ -1415,8 +1419,13 @@ static int streamoff_output(struct vb2_queue *q)
inst->codec_info->dec_info.stream_rd_ptr = new_rd_ptr;
inst->codec_info->dec_info.stream_wr_ptr = new_rd_ptr;
- if (v4l2_m2m_has_stopped(m2m_ctx))
+ if (v4l2_m2m_has_stopped(m2m_ctx)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&inst->state_spinlock, flags);
send_eos_event(inst);
+ spin_unlock_irqrestore(&inst->state_spinlock, flags);
+ }
/* streamoff on output cancels any draining operation */
inst->eos = false;
@@ -1535,6 +1544,7 @@ static int initialize_sequence(struct vpu_instance *inst)
{
struct dec_initial_info initial_info;
int ret = 0;
+ unsigned long flags;
memset(&initial_info, 0, sizeof(struct dec_initial_info));
@@ -1556,7 +1566,9 @@ static int initialize_sequence(struct vpu_instance *inst)
return ret;
}
+ spin_lock_irqsave(&inst->state_spinlock, flags);
handle_dynamic_resolution_change(inst);
+ spin_unlock_irqrestore(&inst->state_spinlock, flags);
return 0;
}
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
index 13682bf6e9f8..1be3a728f32f 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
@@ -1410,7 +1410,7 @@ int mxc_isi_video_register(struct mxc_isi_pipe *pipe,
q->mem_ops = &vb2_dma_contig_memops;
q->buf_struct_size = sizeof(struct mxc_isi_buffer);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->min_queued_buffers = 2;
+ q->min_queued_buffers = 0;
q->lock = &video->lock;
q->dev = pipe->isi->dev;
diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
index 664245cf6eb0..bd059243790e 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-gen3.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
@@ -48,9 +48,9 @@
#define IS_CSID_690(csid) ((csid->camss->res->version == CAMSS_8775P) \
|| (csid->camss->res->version == CAMSS_8300))
#define CSID_BUF_DONE_IRQ_STATUS 0x8C
-#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ?\
- 1 : (IS_CSID_690(csid) ?\
- 13 : 14))
+#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ? \
+ ((IS_CSID_690(csid) ? 0 : 1)) : \
+ ((IS_CSID_690(csid) ? 13 : 14)))
#define CSID_BUF_DONE_IRQ_MASK 0x90
#define CSID_BUF_DONE_IRQ_CLEAR 0x94
#define CSID_BUF_DONE_IRQ_SET 0x98
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index fc838b3d2203..c1148f6ad6b2 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -2782,12 +2782,10 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
/* CSID2 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
- "vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
.clock_rate = {
- { 0, 0, 400000000, 400000000, 0},
- { 0, 0, 400000000, 480000000, 0}
+ { 400000000, 480000000 },
+ { 400000000, 480000000 }
},
.reg = { "csid_lite0" },
.interrupt = { "csid_lite0" },
@@ -2801,12 +2799,10 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
/* CSID3 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
- "vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
.clock_rate = {
- { 0, 0, 400000000, 400000000, 0},
- { 0, 0, 400000000, 480000000, 0}
+ { 400000000, 480000000 },
+ { 400000000, 480000000 }
},
.reg = { "csid_lite1" },
.interrupt = { "csid_lite1" },
@@ -2820,12 +2816,10 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
/* CSID4 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
- "vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
.clock_rate = {
- { 0, 0, 400000000, 400000000, 0},
- { 0, 0, 400000000, 480000000, 0}
+ { 400000000, 480000000 },
+ { 400000000, 480000000 }
},
.reg = { "csid_lite2" },
.interrupt = { "csid_lite2" },
@@ -2839,12 +2833,10 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
/* CSID5 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
- "vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
.clock_rate = {
- { 0, 0, 400000000, 400000000, 0},
- { 0, 0, 400000000, 480000000, 0}
+ { 400000000, 480000000 },
+ { 400000000, 480000000 }
},
.reg = { "csid_lite3" },
.interrupt = { "csid_lite3" },
@@ -2858,12 +2850,10 @@ static const struct camss_subdev_resources csid_res_8775p[] = {
/* CSID6 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
- "vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
.clock_rate = {
- { 0, 0, 400000000, 400000000, 0},
- { 0, 0, 400000000, 480000000, 0}
+ { 400000000, 480000000 },
+ { 400000000, 480000000 }
},
.reg = { "csid_lite4" },
.interrupt = { "csid_lite4" },
@@ -2936,15 +2926,17 @@ static const struct camss_subdev_resources vfe_res_8775p[] = {
/* VFE2 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ .clock = { "cpas_ahb", "cpas_vfe_lite", "vfe_lite_ahb",
"vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ "vfe_lite", "camnoc_axi"},
.clock_rate = {
- { 0, 0, 0, 0 },
+ { 0 },
+ { 0 },
{ 300000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 480000000, 600000000, 600000000, 600000000 },
+ { 400000000 },
},
.reg = { "vfe_lite0" },
.interrupt = { "vfe_lite0" },
@@ -2959,15 +2951,17 @@ static const struct camss_subdev_resources vfe_res_8775p[] = {
/* VFE3 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ .clock = { "cpas_ahb", "cpas_vfe_lite", "vfe_lite_ahb",
"vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ "vfe_lite", "camnoc_axi"},
.clock_rate = {
- { 0, 0, 0, 0 },
+ { 0 },
+ { 0 },
{ 300000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 480000000, 600000000, 600000000, 600000000 },
+ { 400000000 },
},
.reg = { "vfe_lite1" },
.interrupt = { "vfe_lite1" },
@@ -2982,15 +2976,17 @@ static const struct camss_subdev_resources vfe_res_8775p[] = {
/* VFE4 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ .clock = { "cpas_ahb", "cpas_vfe_lite", "vfe_lite_ahb",
"vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ "vfe_lite", "camnoc_axi"},
.clock_rate = {
- { 0, 0, 0, 0 },
+ { 0 },
+ { 0 },
{ 300000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 480000000, 600000000, 600000000, 600000000 },
+ { 400000000 },
},
.reg = { "vfe_lite2" },
.interrupt = { "vfe_lite2" },
@@ -3005,15 +3001,17 @@ static const struct camss_subdev_resources vfe_res_8775p[] = {
/* VFE5 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ .clock = { "cpas_ahb", "cpas_vfe_lite", "vfe_lite_ahb",
"vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ "vfe_lite", "camnoc_axi"},
.clock_rate = {
- { 0, 0, 0, 0 },
+ { 0 },
+ { 0 },
{ 300000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 480000000, 600000000, 600000000, 600000000 },
+ { 400000000 },
},
.reg = { "vfe_lite3" },
.interrupt = { "vfe_lite3" },
@@ -3028,15 +3026,17 @@ static const struct camss_subdev_resources vfe_res_8775p[] = {
/* VFE6 (lite) */
{
.regulators = {},
- .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ .clock = { "cpas_ahb", "cpas_vfe_lite", "vfe_lite_ahb",
"vfe_lite_csid", "vfe_lite_cphy_rx",
- "vfe_lite"},
+ "vfe_lite", "camnoc_axi"},
.clock_rate = {
- { 0, 0, 0, 0 },
+ { 0 },
+ { 0 },
{ 300000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 400000000, 400000000, 400000000, 400000000 },
{ 480000000, 600000000, 600000000, 600000000 },
+ { 400000000 },
},
.reg = { "vfe_lite4" },
.interrupt = { "vfe_lite4" },
diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platform/qcom/iris/Kconfig
index 3c803a05305a..5498f48362d1 100644
--- a/drivers/media/platform/qcom/iris/Kconfig
+++ b/drivers/media/platform/qcom/iris/Kconfig
@@ -3,7 +3,7 @@ config VIDEO_QCOM_IRIS
depends on VIDEO_DEV
depends on ARCH_QCOM || COMPILE_TEST
select V4L2_MEM2MEM_DEV
- select QCOM_MDT_LOADER if ARCH_QCOM
+ select QCOM_MDT_LOADER
select QCOM_SCM
select VIDEOBUF2_DMA_CONTIG
help
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index 006ad855a8e5..11eb205f8646 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -571,10 +571,12 @@ static int iris_release_internal_buffers(struct iris_inst *inst,
continue;
if (!(buffer->attr & BUF_ATTR_QUEUED))
continue;
+ buffer->attr |= BUF_ATTR_PENDING_RELEASE;
ret = hfi_ops->session_release_buf(inst, buffer);
- if (ret)
+ if (ret) {
+ buffer->attr &= ~BUF_ATTR_PENDING_RELEASE;
return ret;
- buffer->attr |= BUF_ATTR_PENDING_RELEASE;
+ }
}
return 0;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
index b3ed06297953..bf6db23b53e2 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
@@ -263,7 +263,7 @@ int iris_hfi_queues_init(struct iris_core *core)
GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
if (!core->sfr_vaddr) {
dev_err(core->dev, "sfr alloc and map failed\n");
- dma_free_attrs(core->dev, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr,
+ dma_free_attrs(core->dev, queue_size, core->iface_q_table_vaddr,
core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE);
return -ENOMEM;
}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
index 04f0b7400a1e..dfef180d32ed 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -61,7 +61,7 @@ struct iris_inst;
#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
#define H264_CABAC_HDR_RATIO_HD_TOT 1
#define H264_CABAC_RES_RATIO_HD_TOT 3
-#define H265D_MAX_SLICE 1200
+#define H265D_MAX_SLICE 3600
#define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T
#define H265_CABAC_HDR_RATIO_HD_TOT 2
#define H265_CABAC_RES_RATIO_HD_TOT 2
diff --git a/drivers/media/platform/qcom/venus/Kconfig b/drivers/media/platform/qcom/venus/Kconfig
index ffb731ecd48c..63ee8c78dc6d 100644
--- a/drivers/media/platform/qcom/venus/Kconfig
+++ b/drivers/media/platform/qcom/venus/Kconfig
@@ -4,7 +4,7 @@ config VIDEO_QCOM_VENUS
depends on VIDEO_DEV && QCOM_SMEM
depends on (ARCH_QCOM && ARM64 && IOMMU_API) || COMPILE_TEST
select OF_DYNAMIC if ARCH_QCOM
- select QCOM_MDT_LOADER if ARCH_QCOM
+ select QCOM_MDT_LOADER
select QCOM_SCM
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
index b619d1436a41..f9af9177e02f 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
@@ -676,8 +676,30 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
if (vin->scaler)
vin->scaler(vin);
+ /*
+ * VNIS_REG has four lowest bits always 0, i.e. the stride has to be
+ * aligned to 16 bytes. This is done in rvin_format_bytesperline().
+ */
+
fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
stride = vin->format.bytesperline / fmt->bpp;
+
+ /*
+ * RAW8 format bpp is 1, but the hardware process RAW8 format in 2 pixel
+ * units, so we need to divide the stride by 2.
+ */
+ switch (vin->format.pixelformat) {
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SGBRG8:
+ case V4L2_PIX_FMT_SGRBG8:
+ case V4L2_PIX_FMT_SRGGB8:
+ case V4L2_PIX_FMT_GREY:
+ stride /= 2;
+ break;
+ default:
+ break;
+ }
+
rvin_write(vin, stride, VNIS_REG);
}
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c b/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
index 079dbaf016c2..9d45e11898c1 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
@@ -155,6 +155,18 @@ static u32 rvin_format_bytesperline(struct rvin_dev *vin,
case V4L2_PIX_FMT_NV16:
align = 0x20;
break;
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SGBRG8:
+ case V4L2_PIX_FMT_SGRBG8:
+ case V4L2_PIX_FMT_SRGGB8:
+ case V4L2_PIX_FMT_GREY:
+ /*
+ * RAW8 format bpp is 1, but the hardware process RAW8 format in
+ * 2 pixel units, and we need to align to 32 bytes. See
+ * rvin_crop_scale_comp().
+ */
+ align = 0x20;
+ break;
default:
align = 0x10;
break;
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_drv.c b/drivers/media/platform/renesas/vsp1/vsp1_drv.c
index 6c64657fc4f3..30df9b36642d 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_drv.c
@@ -240,8 +240,12 @@ static void vsp1_destroy_entities(struct vsp1_device *vsp1)
media_device_unregister(&vsp1->media_dev);
media_device_cleanup(&vsp1->media_dev);
- if (!vsp1->info->uapi)
- vsp1_drm_cleanup(vsp1);
+ if (!vsp1->info->uapi) {
+ if (vsp1->info->version == VI6_IP_VERSION_MODEL_VSPX_GEN4)
+ vsp1_vspx_cleanup(vsp1);
+ else
+ vsp1_drm_cleanup(vsp1);
+ }
}
static int vsp1_create_entities(struct vsp1_device *vsp1)
diff --git a/drivers/media/platform/ti/omap3isp/ispvideo.c b/drivers/media/platform/ti/omap3isp/ispvideo.c
index eb33a776f27c..a0549e731fbf 100644
--- a/drivers/media/platform/ti/omap3isp/ispvideo.c
+++ b/drivers/media/platform/ti/omap3isp/ispvideo.c
@@ -1325,6 +1325,7 @@ static int isp_video_open(struct file *file)
ret = vb2_queue_init(&handle->queue);
if (ret < 0) {
+ v4l2_pipeline_pm_put(&video->video.entity);
omap3isp_put(video->isp);
goto done;
}
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index d3b48a0dd1f4..8e9b156e4300 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -219,9 +219,8 @@ static void streamzap_callback(struct urb *urb)
case -ESHUTDOWN:
/*
* this urb is terminated, clean up.
- * sz might already be invalid at this point
*/
- dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
+ dev_dbg(sz->dev, "urb terminated, status: %d\n", urb->status);
return;
default:
break;
@@ -358,11 +357,16 @@ static int streamzap_probe(struct usb_interface *intf,
usb_set_intfdata(intf, sz);
- if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
+ retval = usb_submit_urb(sz->urb_in, GFP_ATOMIC);
+ if (retval < 0) {
dev_err(sz->dev, "urb submit failed\n");
+ goto rc_submit_fail;
+ }
return 0;
-
+rc_submit_fail:
+ rc_free_device(sz->rdev);
+ usb_set_intfdata(intf, NULL);
rc_dev_fail:
usb_free_urb(sz->urb_in);
free_buf_in:
diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c
index a1572381d097..0c9c855ced72 100644
--- a/drivers/media/rc/xbox_remote.c
+++ b/drivers/media/rc/xbox_remote.c
@@ -55,7 +55,7 @@ struct xbox_remote {
struct usb_interface *interface;
struct urb *irq_urb;
- unsigned char inbuf[DATA_BUFSIZE] __aligned(sizeof(u16));
+ u8 *inbuf;
char rc_name[NAME_BUFSIZE];
char rc_phys[NAME_BUFSIZE];
@@ -218,6 +218,10 @@ static int xbox_remote_probe(struct usb_interface *interface,
if (!xbox_remote || !rc_dev)
goto exit_free_dev_rdev;
+ xbox_remote->inbuf = kzalloc(DATA_BUFSIZE, GFP_KERNEL);
+ if (!xbox_remote->inbuf)
+ goto exit_free_inbuf;
+
/* Allocate URB buffer */
xbox_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!xbox_remote->irq_urb)
@@ -262,6 +266,8 @@ static int xbox_remote_probe(struct usb_interface *interface,
usb_kill_urb(xbox_remote->irq_urb);
exit_free_buffers:
usb_free_urb(xbox_remote->irq_urb);
+exit_free_inbuf:
+ kfree(xbox_remote->inbuf);
exit_free_dev_rdev:
rc_free_device(rc_dev);
kfree(xbox_remote);
@@ -286,6 +292,7 @@ static void xbox_remote_disconnect(struct usb_interface *interface)
usb_kill_urb(xbox_remote->irq_urb);
rc_unregister_device(xbox_remote->rdev);
usb_free_urb(xbox_remote->irq_urb);
+ kfree(xbox_remote->inbuf);
kfree(xbox_remote);
}
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index e838c6c1893a..085abdb116af 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -243,7 +243,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
int ret;
queue->queue.type = type;
- queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
+ queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
queue->queue.drv_priv = queue;
queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
queue->queue.mem_ops = &vb2_vmalloc_memops;
@@ -256,7 +256,6 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
queue->queue.ops = &uvc_meta_queue_qops;
break;
default:
- queue->queue.io_modes |= VB2_DMABUF;
queue->queue.ops = &uvc_queue_qops;
break;
}
diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index 31d099bd8db4..550d4b39a92a 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -362,6 +362,11 @@ static const struct key_entry hp_wmi_keymap[] = {
{ KE_KEY, 0x21a9, { KEY_TOUCHPAD_OFF } },
{ KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } },
{ KE_KEY, 0x231b, { KEY_HELP } },
+ { KE_IGNORE, 0x21ab, }, /* FnLock on */
+ { KE_IGNORE, 0x121ab, }, /* FnLock off */
+ { KE_IGNORE, 0x30021aa, }, /* kbd backlight: level 2 -> off */
+ { KE_IGNORE, 0x33221aa, }, /* kbd backlight: off -> level 1 */
+ { KE_IGNORE, 0x36421aa, }, /* kbd backlight: level 1 -> level 2*/
{ KE_END, 0 }
};
diff --git a/drivers/regulator/act8945a-regulator.c b/drivers/regulator/act8945a-regulator.c
index 24cbdd833863..5bbe2bce740e 100644
--- a/drivers/regulator/act8945a-regulator.c
+++ b/drivers/regulator/act8945a-regulator.c
@@ -302,8 +302,9 @@ static int act8945a_pmic_probe(struct platform_device *pdev)
num_regulators = ARRAY_SIZE(act8945a_regulators);
}
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
config.dev = &pdev->dev;
- config.dev->of_node = pdev->dev.parent->of_node;
config.driver_data = act8945a;
for (i = 0; i < num_regulators; i++) {
rdev = devm_regulator_register(&pdev->dev, ®ulators[i],
diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c
index 209beabb5c37..f4de24a281b1 100644
--- a/drivers/regulator/bd9571mwv-regulator.c
+++ b/drivers/regulator/bd9571mwv-regulator.c
@@ -287,8 +287,9 @@ static int bd9571mwv_regulator_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bdreg);
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
config.dev = &pdev->dev;
- config.dev->of_node = pdev->dev.parent->of_node;
config.driver_data = bdreg;
config.regmap = bdreg->regmap;
diff --git a/drivers/regulator/bq257xx-regulator.c b/drivers/regulator/bq257xx-regulator.c
index dab8f1ab4450..711dbe045383 100644
--- a/drivers/regulator/bq257xx-regulator.c
+++ b/drivers/regulator/bq257xx-regulator.c
@@ -142,8 +142,7 @@ static int bq257xx_regulator_probe(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct regulator_config cfg = {};
- pdev->dev.of_node = pdev->dev.parent->of_node;
- pdev->dev.of_node_reused = true;
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
pdata = devm_kzalloc(&pdev->dev, sizeof(struct bq257xx_reg_data), GFP_KERNEL);
if (!pdata)
diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c
index 7368f54f046d..99293bde3358 100644
--- a/drivers/regulator/max77650-regulator.c
+++ b/drivers/regulator/max77650-regulator.c
@@ -337,7 +337,7 @@ static int max77650_regulator_probe(struct platform_device *pdev)
parent = dev->parent;
if (!dev->of_node)
- dev->of_node = parent->of_node;
+ device_set_of_node_from_dev(dev, parent);
rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
sizeof(*rdescs), GFP_KERNEL);
diff --git a/drivers/regulator/mt6357-regulator.c b/drivers/regulator/mt6357-regulator.c
index 1eb69c7a6acb..09feb454ab6b 100644
--- a/drivers/regulator/mt6357-regulator.c
+++ b/drivers/regulator/mt6357-regulator.c
@@ -410,7 +410,7 @@ static int mt6357_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
int i;
- pdev->dev.of_node = pdev->dev.parent->of_node;
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
for (i = 0; i < MT6357_MAX_REGULATOR; i++) {
config.dev = &pdev->dev;
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 1e8142479656..94cfb66ae656 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -1875,8 +1875,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
struct regmap *regmap;
int ret, i, nregulators;
- pdev->dev.of_node = pdev->dev.parent->of_node;
- pdev->dev.of_node_reused = true;
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap)
diff --git a/drivers/regulator/s2dos05-regulator.c b/drivers/regulator/s2dos05-regulator.c
index 1463585c4565..a1c394ddbaff 100644
--- a/drivers/regulator/s2dos05-regulator.c
+++ b/drivers/regulator/s2dos05-regulator.c
@@ -126,7 +126,7 @@ static int s2dos05_pmic_probe(struct platform_device *pdev)
s2dos05->regmap = iodev->regmap_pmic;
s2dos05->dev = dev;
if (!dev->of_node)
- dev->of_node = dev->parent->of_node;
+ device_set_of_node_from_dev(dev, dev->parent);
config.dev = dev;
config.driver_data = s2dos05;
diff --git a/drivers/spi/spi-amlogic-spisg.c b/drivers/spi/spi-amlogic-spisg.c
index 6045c89c37c8..56a6cf8471b9 100644
--- a/drivers/spi/spi-amlogic-spisg.c
+++ b/drivers/spi/spi-amlogic-spisg.c
@@ -801,7 +801,7 @@ static int aml_spisg_probe(struct platform_device *pdev)
goto out_clk;
}
- ret = devm_spi_register_controller(dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret) {
dev_err(&pdev->dev, "spi controller registration failed\n");
goto out_clk;
@@ -824,6 +824,8 @@ static void aml_spisg_remove(struct platform_device *pdev)
{
struct spisg_device *spisg = platform_get_drvdata(pdev);
+ spi_unregister_controller(spisg->controller);
+
if (!pm_runtime_suspended(&pdev->dev)) {
pinctrl_pm_select_sleep_state(&spisg->pdev->dev);
clk_disable_unprepare(spisg->core);
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 62a11142bd63..04eebb65cfa6 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -726,7 +726,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
return -ENOMEM;
aspi = spi_controller_get_devdata(ctlr);
- platform_set_drvdata(pdev, aspi);
+ platform_set_drvdata(pdev, ctlr);
aspi->data = data;
aspi->dev = dev;
@@ -765,7 +765,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
ctlr->num_chipselect = data->max_cs;
ctlr->dev.of_node = dev->of_node;
- ret = devm_spi_register_controller(dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret)
dev_err(&pdev->dev, "spi_register_controller failed\n");
@@ -774,7 +774,10 @@ static int aspeed_spi_probe(struct platform_device *pdev)
static void aspeed_spi_remove(struct platform_device *pdev)
{
- struct aspeed_spi *aspi = platform_get_drvdata(pdev);
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+ struct aspeed_spi *aspi = spi_controller_get_devdata(ctlr);
+
+ spi_unregister_controller(ctlr);
aspeed_spi_enable(aspi, false);
}
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c
index bbe97ce89a2f..3617f538f98e 100644
--- a/drivers/spi/spi-at91-usart.c
+++ b/drivers/spi/spi-at91-usart.c
@@ -556,7 +556,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
spin_lock_init(&aus->lock);
init_completion(&aus->xfer_completion);
- ret = devm_spi_register_controller(&pdev->dev, controller);
+ ret = spi_register_controller(controller);
if (ret)
goto at91_usart_fail_register_controller;
@@ -634,8 +634,14 @@ static void at91_usart_spi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
at91_usart_spi_release_dma(ctlr);
clk_disable_unprepare(aus->clk);
+
+ spi_controller_put(ctlr);
}
static const struct dev_pm_ops at91_usart_spi_pm_ops = {
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 89977bff76d2..586e2fd357ed 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -1655,7 +1655,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_free_dma;
@@ -1689,8 +1689,12 @@ static void atmel_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct atmel_spi *as = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
pm_runtime_get_sync(&pdev->dev);
+ spi_unregister_controller(host);
+
/* reset the hardware and block queue progress */
if (as->use_dma) {
atmel_spi_stop_dma(host);
@@ -1717,6 +1721,8 @@ static void atmel_spi_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(host);
}
static int atmel_spi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index 2e3c62f12bef..cf7eefd39839 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -603,7 +603,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
goto out_clk_disable;
/* register and we are done */
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(dev, "spi register failed\n");
goto out_clk_disable;
@@ -626,11 +626,17 @@ static void bcm63xx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* reset spi block */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
/* HW shutdown */
clk_disable_unprepare(bs->clk);
+
+ spi_controller_put(host);
}
static int bcm63xx_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c
index f16298b75236..f0f0e6b29668 100644
--- a/drivers/spi/spi-bcmbca-hsspi.c
+++ b/drivers/spi/spi-bcmbca-hsspi.c
@@ -550,7 +550,7 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
}
/* register and we are done */
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_sysgroup_disable;
@@ -572,6 +572,8 @@ static void bcmbca_hsspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
+ spi_unregister_controller(host);
+
/* reset the hardware and block queue progress */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
clk_disable_unprepare(bs->pll_clk);
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 5ae09b21d23a..7a745c2e0892 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -662,7 +662,6 @@ static int cdns_spi_probe(struct platform_device *pdev)
/* Set to default valid value */
ctlr->max_speed_hz = xspi->clk_rate / 4;
xspi->speed_hz = ctlr->max_speed_hz;
- pm_runtime_put_autosuspend(&pdev->dev);
} else {
ctlr->mode_bits |= SPI_NO_CS;
ctlr->target_abort = cdns_target_abort;
@@ -673,12 +672,17 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto clk_dis_all;
}
+ if (!spi_controller_is_target(ctlr))
+ pm_runtime_put_autosuspend(&pdev->dev);
+
return ret;
clk_dis_all:
if (!spi_controller_is_target(ctlr)) {
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
}
remove_ctlr:
spi_controller_put(ctlr);
@@ -697,15 +701,26 @@ static void cdns_spi_remove(struct platform_device *pdev)
{
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
+ int ret = 0;
- cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
+ if (!spi_controller_is_target(ctlr))
+ ret = pm_runtime_get_sync(&pdev->dev);
+
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
+ if (ret >= 0)
+ cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
if (!spi_controller_is_target(ctlr)) {
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
}
- spi_unregister_controller(ctlr);
+ spi_controller_put(ctlr);
}
/**
diff --git a/drivers/spi/spi-cavium-thunderx.c b/drivers/spi/spi-cavium-thunderx.c
index 367ae7120bb3..81142b3f7b41 100644
--- a/drivers/spi/spi-cavium-thunderx.c
+++ b/drivers/spi/spi-cavium-thunderx.c
@@ -71,7 +71,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, host);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto error;
@@ -91,8 +91,14 @@ static void thunderx_spi_remove(struct pci_dev *pdev)
if (!p)
return;
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* Put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ spi_controller_put(host);
}
static const struct pci_device_id thunderx_spi_pci_id_table[] = {
diff --git a/drivers/spi/spi-ch341.c b/drivers/spi/spi-ch341.c
index ded093566260..3eaa8f176f63 100644
--- a/drivers/spi/spi-ch341.c
+++ b/drivers/spi/spi-ch341.c
@@ -152,7 +152,7 @@ static int ch341_probe(struct usb_interface *intf,
if (ret)
return ret;
- ctrl = devm_spi_alloc_host(&udev->dev, sizeof(struct ch341_spi_dev));
+ ctrl = devm_spi_alloc_host(&intf->dev, sizeof(struct ch341_spi_dev));
if (!ctrl)
return -ENOMEM;
@@ -163,7 +163,7 @@ static int ch341_probe(struct usb_interface *intf,
ch341->read_pipe = usb_rcvbulkpipe(udev, usb_endpoint_num(in));
ch341->rx_len = usb_endpoint_maxp(in);
- ch341->rx_buf = devm_kzalloc(&udev->dev, ch341->rx_len, GFP_KERNEL);
+ ch341->rx_buf = devm_kzalloc(&intf->dev, ch341->rx_len, GFP_KERNEL);
if (!ch341->rx_buf)
return -ENOMEM;
@@ -171,8 +171,7 @@ static int ch341_probe(struct usb_interface *intf,
if (!ch341->rx_urb)
return -ENOMEM;
- ch341->tx_buf =
- devm_kzalloc(&udev->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
+ ch341->tx_buf = devm_kzalloc(&intf->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
if (!ch341->tx_buf) {
ret = -ENOMEM;
goto err_free_urb;
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
index fdf37636cb9f..b45f44de85dc 100644
--- a/drivers/spi/spi-coldfire-qspi.c
+++ b/drivers/spi/spi-coldfire-qspi.c
@@ -410,9 +410,9 @@ static int mcfqspi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
pm_runtime_enable(&pdev->dev);
- status = devm_spi_register_controller(&pdev->dev, host);
+ status = spi_register_controller(host);
if (status) {
- dev_dbg(&pdev->dev, "devm_spi_register_controller failed\n");
+ dev_dbg(&pdev->dev, "failed to register controller\n");
goto fail1;
}
@@ -436,11 +436,17 @@ static void mcfqspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
/* disable the hardware (set the baud rate to 0) */
mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
mcfqspi_cs_teardown(mcfqspi);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c
index 2013bc56ded8..7260c4b96931 100644
--- a/drivers/spi/spi-dln2.c
+++ b/drivers/spi/spi-dln2.c
@@ -761,7 +761,7 @@ static int dln2_spi_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register host\n");
goto exit_register;
@@ -786,10 +786,16 @@ static void dln2_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
if (dln2_spi_enable(dln2, false) < 0)
dev_err(&pdev->dev, "Failed to disable SPI module\n");
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index f2f1d3298e6c..cf89f36ab30b 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -719,7 +719,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret < 0)
goto err_pm;
@@ -783,7 +783,15 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
static void of_fsl_espi_remove(struct platform_device *dev)
{
+ struct spi_controller *host = platform_get_drvdata(dev);
+
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&dev->dev);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index 481a7b28aacd..a516abbb6f67 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -614,7 +614,7 @@ static struct spi_controller *fsl_spi_probe(struct device *dev,
mpc8xxx_spi_write_reg(®_base->mode, regval);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret < 0)
goto err_probe;
@@ -705,7 +705,13 @@ static void of_fsl_spi_remove(struct platform_device *ofdev)
struct spi_controller *host = platform_get_drvdata(ofdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
fsl_spi_cpm_free(mpc8xxx_spi);
+
+ spi_controller_put(host);
}
static struct platform_driver of_fsl_spi_driver = {
@@ -751,7 +757,13 @@ static void plat_mpc8xxx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
fsl_spi_cpm_free(mpc8xxx_spi);
+
+ spi_controller_put(host);
}
MODULE_ALIAS("platform:mpc8xxx_spi");
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index 168ccf51f6d4..a6d15b9ca509 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -644,7 +644,7 @@ static int img_spfi_probe(struct platform_device *pdev)
pm_runtime_set_active(spfi->dev);
pm_runtime_enable(spfi->dev);
- ret = devm_spi_register_controller(spfi->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto disable_pm;
@@ -670,6 +670,10 @@ static void img_spfi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
if (spfi->tx_ch)
dma_release_channel(spfi->tx_ch);
if (spfi->rx_ch)
@@ -680,6 +684,8 @@ static void img_spfi_remove(struct platform_device *pdev)
clk_disable_unprepare(spfi->spfi_clk);
clk_disable_unprepare(spfi->sys_clk);
}
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index dc7ffa8cb287..ce3c7aa53f19 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -1948,6 +1948,7 @@ static int spi_imx_probe(struct platform_device *pdev)
out_runtime_pm_put:
pm_runtime_dont_use_autosuspend(spi_imx->dev);
pm_runtime_disable(spi_imx->dev);
+ pm_runtime_put_noidle(spi_imx->dev);
pm_runtime_set_suspended(&pdev->dev);
clk_disable_unprepare(spi_imx->clk_ipg);
diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c
index 60849e07f674..97dbd58244b1 100644
--- a/drivers/spi/spi-lantiq-ssc.c
+++ b/drivers/spi/spi-lantiq-ssc.c
@@ -995,7 +995,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
"Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
- err = devm_spi_register_controller(dev, host);
+ err = spi_register_controller(host);
if (err) {
dev_err(dev, "failed to register spi host\n");
goto err_wq_destroy;
@@ -1017,6 +1017,10 @@ static void lantiq_ssc_remove(struct platform_device *pdev)
{
struct lantiq_ssc_spi *spi = platform_get_drvdata(pdev);
+ spi_controller_get(spi->host);
+
+ spi_unregister_controller(spi->host);
+
lantiq_ssc_writel(spi, 0, LTQ_SPI_IRNEN);
lantiq_ssc_writel(spi, 0, LTQ_SPI_CLC);
rx_fifo_flush(spi);
@@ -1025,6 +1029,8 @@ static void lantiq_ssc_remove(struct platform_device *pdev)
destroy_workqueue(spi->wq);
clk_put(spi->fpi_clk);
+
+ spi_controller_put(spi->host);
}
static struct platform_driver lantiq_ssc_driver = {
diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index c99fab392add..bb27a3b2bbc2 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -1082,7 +1082,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
}
}
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "spi registration failed\n");
goto out_host;
@@ -1100,8 +1100,14 @@ static void meson_spicc_remove(struct platform_device *pdev)
{
struct meson_spicc_device *spicc = platform_get_drvdata(pdev);
+ spi_controller_get(spicc->host);
+
+ spi_unregister_controller(spicc->host);
+
/* Disable SPI */
writel(0, spicc->base + SPICC_CONREG);
+
+ spi_controller_put(spicc->host);
}
static const struct meson_spicc_data meson_spicc_gx_data = {
diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c
index 6d4dde15ac54..84aade141606 100644
--- a/drivers/spi/spi-mpc52xx.c
+++ b/drivers/spi/spi-mpc52xx.c
@@ -501,6 +501,9 @@ static int mpc52xx_spi_probe(struct platform_device *op)
err_register:
dev_err(&ms->host->dev, "initialization failed\n");
+ free_irq(ms->irq0, ms);
+ free_irq(ms->irq1, ms);
+ cancel_work_sync(&ms->work);
err_gpio:
while (i-- > 0)
gpiod_put(ms->gpio_cs[i]);
@@ -520,15 +523,17 @@ static void mpc52xx_spi_remove(struct platform_device *op)
struct mpc52xx_spi *ms = spi_controller_get_devdata(host);
int i;
- cancel_work_sync(&ms->work);
+ spi_unregister_controller(host);
+
free_irq(ms->irq0, ms);
free_irq(ms->irq1, ms);
+ cancel_work_sync(&ms->work);
+
for (i = 0; i < ms->gpio_cs_count; i++)
gpiod_put(ms->gpio_cs[i]);
kfree(ms->gpio_cs);
- spi_unregister_controller(host);
iounmap(ms->regs);
spi_controller_put(host);
}
diff --git a/drivers/spi/spi-mpfs.c b/drivers/spi/spi-mpfs.c
index 7e9e64d8e6c8..c41e0e55b52f 100644
--- a/drivers/spi/spi-mpfs.c
+++ b/drivers/spi/spi-mpfs.c
@@ -575,7 +575,7 @@ static int mpfs_spi_probe(struct platform_device *pdev)
mpfs_spi_init(host, spi);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
mpfs_spi_disable_ints(spi);
mpfs_spi_disable(spi);
@@ -593,6 +593,8 @@ static void mpfs_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mpfs_spi *spi = spi_controller_get_devdata(host);
+ spi_unregister_controller(host);
+
mpfs_spi_disable_ints(spi);
mpfs_spi_disable(spi);
}
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 90e5813cfdc3..9522d6f23788 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -1326,7 +1326,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret) {
pm_runtime_disable(dev);
return dev_err_probe(dev, ret, "failed to register host\n");
@@ -1341,6 +1341,8 @@ static void mtk_spi_remove(struct platform_device *pdev)
struct mtk_spi *mdata = spi_controller_get_devdata(host);
int ret;
+ spi_unregister_controller(host);
+
cpu_latency_qos_remove_request(&mdata->qos_request);
if (mdata->use_spimem && !completion_done(&mdata->spimem_done))
complete(&mdata->spimem_done);
diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 5cc4632e13d7..ba41ff42f0dd 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -914,7 +914,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0)
goto err_probe;
@@ -939,6 +939,8 @@ static void mtk_nor_remove(struct platform_device *pdev)
struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
struct mtk_nor *sp = spi_controller_get_devdata(ctlr);
+ spi_unregister_controller(ctlr);
+
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
index eeaea6a5e310..eea4a588e8a0 100644
--- a/drivers/spi/spi-mxic.c
+++ b/drivers/spi/spi-mxic.c
@@ -833,9 +833,10 @@ static void mxic_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mxic_spi *mxic = spi_controller_get_devdata(host);
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
mxic_spi_mem_ecc_remove(mxic);
- spi_unregister_controller(host);
}
static const struct of_device_id mxic_spi_of_ids[] = {
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index 0ebcbdb1b1f7..d5ac5dddfbf6 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -619,7 +619,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
if (ret)
goto out_pm_runtime_put;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "Cannot register SPI host, %d\n", ret);
goto out_pm_runtime_put;
@@ -650,11 +650,17 @@ static void mxs_spi_remove(struct platform_device *pdev)
spi = spi_controller_get_devdata(host);
ssp = &spi->ssp;
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mxs_spi_runtime_suspend(&pdev->dev);
dma_release_channel(ssp->dmach);
+
+ spi_controller_put(host);
}
static struct platform_driver mxs_spi_driver = {
diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
index 98b6479b961c..ba1714923772 100644
--- a/drivers/spi/spi-npcm-pspi.c
+++ b/drivers/spi/spi-npcm-pspi.c
@@ -414,7 +414,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
/* set to default clock rate */
npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_disable_clk;
@@ -435,8 +435,14 @@ static void npcm_pspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct npcm_pspi *priv = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
npcm_pspi_reset_hw(priv);
clk_disable_unprepare(priv->clk);
+
+ spi_controller_put(host);
}
static const struct of_device_id npcm_pspi_match[] = {
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 69c2e9d9be3c..86b3d21e7761 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -1585,7 +1585,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
if (status < 0)
goto disable_pm;
- status = devm_spi_register_controller(&pdev->dev, ctlr);
+ status = spi_register_controller(ctlr);
if (status < 0)
goto disable_pm;
@@ -1606,11 +1606,17 @@ static void omap2_mcspi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr);
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
omap2_mcspi_release_dma(ctlr);
pm_runtime_dont_use_autosuspend(mcspi->dev);
pm_runtime_put_sync(mcspi->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(ctlr);
}
/* work with hotplug and coldplug */
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 43bd9f21137f..eb71043300a9 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -774,6 +774,7 @@ static int orion_spi_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
+ pm_runtime_get_noresume(&pdev->dev);
pm_runtime_enable(&pdev->dev);
status = orion_spi_reset(spi);
@@ -785,10 +786,15 @@ static int orion_spi_probe(struct platform_device *pdev)
if (status < 0)
goto out_rel_pm;
+ pm_runtime_put_autosuspend(&pdev->dev);
+
return status;
out_rel_pm:
pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
out_rel_axi_clk:
clk_disable_unprepare(spi->axi_clk);
out:
@@ -802,11 +808,19 @@ static void orion_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct orion_spi *spi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(spi->axi_clk);
- spi_unregister_controller(host);
+ spi_controller_put(host);
+
pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
}
MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c
index fa0c1ee84532..a6b5a0ed99c9 100644
--- a/drivers/spi/spi-pic32-sqi.c
+++ b/drivers/spi/spi-pic32-sqi.c
@@ -642,7 +642,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
host->prepare_transfer_hardware = pic32_sqi_prepare_hardware;
host->unprepare_transfer_hardware = pic32_sqi_unprepare_hardware;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&host->dev, "failed registering spi host\n");
free_irq(sqi->irq, sqi);
@@ -665,9 +665,15 @@ static void pic32_sqi_remove(struct platform_device *pdev)
{
struct pic32_sqi *sqi = platform_get_drvdata(pdev);
+ spi_controller_get(sqi->host);
+
+ spi_unregister_controller(sqi->host);
+
/* release resources */
free_irq(sqi->irq, sqi);
ring_desc_ring_free(sqi);
+
+ spi_controller_put(sqi->host);
}
static const struct of_device_id pic32_sqi_of_ids[] = {
diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c
index 369850d14313..70427e529945 100644
--- a/drivers/spi/spi-pic32.c
+++ b/drivers/spi/spi-pic32.c
@@ -821,7 +821,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
}
/* register host */
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&host->dev, "failed registering spi host\n");
goto err_bailout;
@@ -840,11 +840,16 @@ static int pic32_spi_probe(struct platform_device *pdev)
static void pic32_spi_remove(struct platform_device *pdev)
{
- struct pic32_spi *pic32s;
+ struct pic32_spi *pic32s = platform_get_drvdata(pdev);
+
+ spi_controller_get(pic32s->host);
+
+ spi_unregister_controller(pic32s->host);
- pic32s = platform_get_drvdata(pdev);
pic32_spi_disable(pic32s);
pic32_spi_dma_unprep(pic32s);
+
+ spi_controller_put(pic32s->host);
}
static const struct of_device_id pic32_spi_of_match[] = {
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 9e56e8774614..da00dfa734d9 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1957,7 +1957,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
/* Register with the SPI framework */
amba_set_drvdata(adev, pl022);
- status = devm_spi_register_controller(&adev->dev, host);
+ status = spi_register_controller(host);
if (status != 0) {
dev_err_probe(&adev->dev, status,
"problem registering spi host\n");
@@ -1998,6 +1998,10 @@ pl022_remove(struct amba_device *adev)
if (!pl022)
return;
+ spi_controller_get(pl022->host);
+
+ spi_unregister_controller(pl022->host);
+
/*
* undo pm_runtime_put() in probe. I assume that we're not
* accessing the primecell here.
@@ -2009,6 +2013,8 @@ pl022_remove(struct amba_device *adev)
pl022_dma_remove(pl022);
amba_release_regions(adev);
+
+ spi_controller_put(pl022->host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 7d647edf6bc3..a5c549479c7d 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -1194,7 +1194,7 @@ static int spi_qup_probe(struct platform_device *pdev)
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto disable_pm;
@@ -1321,6 +1321,10 @@ static void spi_qup_remove(struct platform_device *pdev)
struct spi_qup *controller = spi_controller_get_devdata(host);
int ret;
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
ret = pm_runtime_get_sync(&pdev->dev);
if (ret >= 0) {
@@ -1340,6 +1344,8 @@ static void spi_qup_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(host);
}
static const struct of_device_id spi_qup_dt_match[] = {
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 8e1d911b88b5..c90dfe521154 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1171,8 +1171,14 @@ static void rspi_remove(struct platform_device *pdev)
{
struct rspi_data *rspi = platform_get_drvdata(pdev);
+ spi_controller_get(rspi->ctlr);
+
+ spi_unregister_controller(rspi->ctlr);
+
rspi_release_dma(rspi->ctlr);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(rspi->ctlr);
}
static const struct spi_ops rspi_ops = {
@@ -1377,9 +1383,9 @@ static int rspi_probe(struct platform_device *pdev)
if (ret < 0)
dev_warn(&pdev->dev, "DMA not available, using PIO\n");
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
- dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
+ dev_err(&pdev->dev, "failed to register controller\n");
goto error3;
}
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 33c80daec5f6..851340f107b8 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1370,7 +1370,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
sdd->regs + S3C64XX_SPI_INT_EN);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret != 0) {
dev_err(&pdev->dev, "cannot register SPI host: %d\n", ret);
goto err_pm_put;
@@ -1400,6 +1400,8 @@ static void s3c64xx_spi_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev);
+ spi_unregister_controller(host);
+
writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
pm_runtime_put_noidle(&pdev->dev);
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c
index 93017faeb7b5..8253ab9b8838 100644
--- a/drivers/spi/spi-sh-hspi.c
+++ b/drivers/spi/spi-sh-hspi.c
@@ -258,9 +258,9 @@ static int hspi_probe(struct platform_device *pdev)
ctlr->transfer_one_message = hspi_transfer_one_message;
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
- dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
+ dev_err(&pdev->dev, "failed to register controller\n");
goto error2;
}
@@ -280,9 +280,15 @@ static void hspi_remove(struct platform_device *pdev)
{
struct hspi_priv *hspi = platform_get_drvdata(pdev);
+ spi_controller_get(hspi->ctlr);
+
+ spi_unregister_controller(hspi->ctlr);
+
pm_runtime_disable(&pdev->dev);
clk_put(hspi->clk);
+
+ spi_controller_put(hspi->ctlr);
}
static const struct of_device_id hspi_of_match[] = {
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index b695870fae8c..7f4135a3bda2 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -1290,9 +1290,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
if (ret < 0)
dev_warn(dev, "DMA not available, using PIO\n");
- ret = devm_spi_register_controller(dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
- dev_err(dev, "devm_spi_register_controller error.\n");
+ dev_err(dev, "failed to register controller\n");
goto err2;
}
@@ -1310,8 +1310,14 @@ static void sh_msiof_spi_remove(struct platform_device *pdev)
{
struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
+ spi_controller_get(p->ctlr);
+
+ spi_unregister_controller(p->ctlr);
+
sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(p->ctlr);
}
static const struct platform_device_id spi_driver_ids[] = {
diff --git a/drivers/spi/spi-slave-mt27xx.c b/drivers/spi/spi-slave-mt27xx.c
index e331df967385..c39d8e590ad7 100644
--- a/drivers/spi/spi-slave-mt27xx.c
+++ b/drivers/spi/spi-slave-mt27xx.c
@@ -454,7 +454,7 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
clk_disable_unprepare(mdata->spi_clk);
if (ret) {
dev_err(&pdev->dev,
@@ -474,7 +474,15 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
static void mtk_spi_slave_remove(struct platform_device *pdev)
{
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(ctlr);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-sprd.c b/drivers/spi/spi-sprd.c
index ad75f5f0f2bf..218c38841f05 100644
--- a/drivers/spi/spi-sprd.c
+++ b/drivers/spi/spi-sprd.c
@@ -978,7 +978,7 @@ static int sprd_spi_probe(struct platform_device *pdev)
goto err_rpm_put;
}
- ret = devm_spi_register_controller(&pdev->dev, sctlr);
+ ret = spi_register_controller(sctlr);
if (ret)
goto err_rpm_put;
@@ -1009,7 +1009,9 @@ static void sprd_spi_remove(struct platform_device *pdev)
if (ret < 0)
dev_err(ss->dev, "failed to resume SPI controller\n");
- spi_controller_suspend(sctlr);
+ spi_controller_get(sctlr);
+
+ spi_unregister_controller(sctlr);
if (ret >= 0) {
if (ss->dma.enable)
@@ -1018,6 +1020,8 @@ static void sprd_spi_remove(struct platform_device *pdev)
}
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(sctlr);
}
static int __maybe_unused sprd_spi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c
index c07c61dc4938..23a306901c0f 100644
--- a/drivers/spi/spi-st-ssc4.c
+++ b/drivers/spi/spi-st-ssc4.c
@@ -349,7 +349,7 @@ static int spi_st_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "Failed to register host\n");
goto rpm_disable;
@@ -371,10 +371,16 @@ static void spi_st_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct spi_st *spi_st = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(spi_st->clk);
+ spi_controller_put(host);
+
pinctrl_pm_select_sleep_state(&pdev->dev);
}
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 48fb11fea55f..a28597b6b80d 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -1416,7 +1416,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
}
host->dev.of_node = pdev->dev.of_node;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "can not register to host err %d\n", ret);
goto exit_free_irq;
@@ -1442,6 +1442,10 @@ static void tegra_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_spi_data *tspi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
free_irq(tspi->irq, tspi);
if (tspi->tx_dma_chan)
@@ -1453,6 +1457,8 @@ static void tegra_spi_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_spi_runtime_suspend(&pdev->dev);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c
index d5c8ee20b8e5..dc3fcab5faa9 100644
--- a/drivers/spi/spi-tegra20-sflash.c
+++ b/drivers/spi/spi-tegra20-sflash.c
@@ -506,7 +506,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
pm_runtime_put(&pdev->dev);
host->dev.of_node = pdev->dev.of_node;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "can not register to host err %d\n", ret);
goto exit_pm_disable;
@@ -529,11 +529,17 @@ static void tegra_sflash_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_sflash_data *tsd = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
free_irq(tsd->irq, tsd);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_sflash_runtime_suspend(&pdev->dev);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index ff2142f87277..75b7a0d3f865 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -666,28 +666,24 @@ static int uniphier_spi_probe(struct platform_device *pdev)
}
priv->base_dma_addr = res->start;
- priv->clk = devm_clk_get(&pdev->dev, NULL);
+ priv->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
ret = PTR_ERR(priv->clk);
goto out_host_put;
}
- ret = clk_prepare_enable(priv->clk);
- if (ret)
- goto out_host_put;
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
- goto out_disable_clk;
+ goto out_host_put;
}
ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
0, "uniphier-spi", priv);
if (ret) {
dev_err(&pdev->dev, "failed to request IRQ\n");
- goto out_disable_clk;
+ goto out_host_put;
}
init_completion(&priv->xfer_done);
@@ -717,7 +713,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
if (IS_ERR_OR_NULL(host->dma_tx)) {
if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
- goto out_disable_clk;
+ goto out_host_put;
}
host->dma_tx = NULL;
dma_tx_burst = INT_MAX;
@@ -751,7 +747,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_release_dma;
@@ -767,9 +763,6 @@ static int uniphier_spi_probe(struct platform_device *pdev)
host->dma_tx = NULL;
}
-out_disable_clk:
- clk_disable_unprepare(priv->clk);
-
out_host_put:
spi_controller_put(host);
return ret;
@@ -778,14 +771,17 @@ static int uniphier_spi_probe(struct platform_device *pdev)
static void uniphier_spi_remove(struct platform_device *pdev)
{
struct spi_controller *host = platform_get_drvdata(pdev);
- struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
if (host->dma_tx)
dma_release_channel(host->dma_tx);
if (host->dma_rx)
dma_release_channel(host->dma_rx);
- clk_disable_unprepare(priv->clk);
+ spi_controller_put(host);
}
static const struct of_device_id uniphier_spi_match[] = {
diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index 5232483c4a3a..406fd9d5337e 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -381,21 +381,10 @@ static int zynq_qspi_setup_op(struct spi_device *spi)
{
struct spi_controller *ctlr = spi->controller;
struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
- int ret;
if (ctlr->busy)
return -EBUSY;
- ret = clk_enable(qspi->refclk);
- if (ret)
- return ret;
-
- ret = clk_enable(qspi->pclk);
- if (ret) {
- clk_disable(qspi->refclk);
- return ret;
- }
-
zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
ZYNQ_QSPI_ENABLE_ENABLE_MASK);
@@ -654,14 +643,14 @@ static int zynq_qspi_probe(struct platform_device *pdev)
xqspi = spi_controller_get_devdata(ctlr);
xqspi->dev = dev;
- platform_set_drvdata(pdev, xqspi);
+ platform_set_drvdata(pdev, ctlr);
xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(xqspi->regs)) {
ret = PTR_ERR(xqspi->regs);
goto remove_ctlr;
}
- xqspi->pclk = devm_clk_get(&pdev->dev, "pclk");
+ xqspi->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
if (IS_ERR(xqspi->pclk)) {
dev_err(&pdev->dev, "pclk clock not found.\n");
ret = PTR_ERR(xqspi->pclk);
@@ -670,36 +659,24 @@ static int zynq_qspi_probe(struct platform_device *pdev)
init_completion(&xqspi->data_completion);
- xqspi->refclk = devm_clk_get(&pdev->dev, "ref_clk");
+ xqspi->refclk = devm_clk_get_enabled(&pdev->dev, "ref_clk");
if (IS_ERR(xqspi->refclk)) {
dev_err(&pdev->dev, "ref_clk clock not found.\n");
ret = PTR_ERR(xqspi->refclk);
goto remove_ctlr;
}
- ret = clk_prepare_enable(xqspi->pclk);
- if (ret) {
- dev_err(&pdev->dev, "Unable to enable APB clock.\n");
- goto remove_ctlr;
- }
-
- ret = clk_prepare_enable(xqspi->refclk);
- if (ret) {
- dev_err(&pdev->dev, "Unable to enable device clock.\n");
- goto clk_dis_pclk;
- }
-
xqspi->irq = platform_get_irq(pdev, 0);
if (xqspi->irq < 0) {
ret = xqspi->irq;
- goto clk_dis_all;
+ goto remove_ctlr;
}
ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq,
0, pdev->name, xqspi);
if (ret != 0) {
ret = -ENXIO;
dev_err(&pdev->dev, "request_irq failed\n");
- goto clk_dis_all;
+ goto remove_ctlr;
}
ret = of_property_read_u32(np, "num-cs",
@@ -709,7 +686,7 @@ static int zynq_qspi_probe(struct platform_device *pdev)
} else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) {
ret = -EINVAL;
dev_err(&pdev->dev, "only 2 chip selects are available\n");
- goto clk_dis_all;
+ goto remove_ctlr;
} else {
ctlr->num_chipselect = num_cs;
}
@@ -725,18 +702,14 @@ static int zynq_qspi_probe(struct platform_device *pdev)
/* QSPI controller initializations */
zynq_qspi_init_hw(xqspi, ctlr->num_chipselect);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret) {
- dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
- goto clk_dis_all;
+ dev_err(&pdev->dev, "failed to register controller\n");
+ goto remove_ctlr;
}
return ret;
-clk_dis_all:
- clk_disable_unprepare(xqspi->refclk);
-clk_dis_pclk:
- clk_disable_unprepare(xqspi->pclk);
remove_ctlr:
spi_controller_put(ctlr);
@@ -755,12 +728,16 @@ static int zynq_qspi_probe(struct platform_device *pdev)
*/
static void zynq_qspi_remove(struct platform_device *pdev)
{
- struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+ struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
+
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
- clk_disable_unprepare(xqspi->refclk);
- clk_disable_unprepare(xqspi->pclk);
+ spi_controller_put(ctlr);
}
static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index bb8b2f2213b0..2907ef2a37ed 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -1357,6 +1357,10 @@ static int atomisp_s_parm(struct file *file, void *fh,
static long atomisp_vidioc_default(struct file *file, void *fh,
bool valid_prio, unsigned int cmd, void *arg)
{
+ /* Disable all private IOCTLs for now! */
+ if (cmd)
+ return -EINVAL;
+
struct video_device *vdev = video_devdata(file);
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
int err;
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index fd7e37d803e7..55a7d8f38465 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -97,9 +97,6 @@ struct csi_priv {
/* the mipi virtual channel number at link validate */
int vc_num;
- /* media bus config of the upstream subdevice CSI is receiving from */
- struct v4l2_mbus_config mbus_cfg;
-
spinlock_t irqlock; /* protect eof_irq handler */
struct timer_list eof_timeout_timer;
int eof_irq;
@@ -403,7 +400,8 @@ static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
}
/* init the SMFC IDMAC channel */
-static int csi_idmac_setup_channel(struct csi_priv *priv)
+static int csi_idmac_setup_channel(struct csi_priv *priv,
+ struct v4l2_mbus_config *mbus_cfg)
{
struct imx_media_video_dev *vdev = priv->vdev;
const struct imx_media_pixfmt *incc;
@@ -432,7 +430,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
image.phys0 = phys[0];
image.phys1 = phys[1];
- passthrough = requires_passthrough(&priv->mbus_cfg, infmt, incc);
+ passthrough = requires_passthrough(mbus_cfg, infmt, incc);
passthrough_cycles = 1;
/*
@@ -572,11 +570,12 @@ static void csi_idmac_unsetup(struct csi_priv *priv,
csi_idmac_unsetup_vb2_buf(priv, state);
}
-static int csi_idmac_setup(struct csi_priv *priv)
+static int csi_idmac_setup(struct csi_priv *priv,
+ struct v4l2_mbus_config *mbus_cfg)
{
int ret;
- ret = csi_idmac_setup_channel(priv);
+ ret = csi_idmac_setup_channel(priv, mbus_cfg);
if (ret)
return ret;
@@ -595,7 +594,8 @@ static int csi_idmac_setup(struct csi_priv *priv)
return 0;
}
-static int csi_idmac_start(struct csi_priv *priv)
+static int csi_idmac_start(struct csi_priv *priv,
+ struct v4l2_mbus_config *mbus_cfg)
{
struct imx_media_video_dev *vdev = priv->vdev;
int ret;
@@ -619,7 +619,7 @@ static int csi_idmac_start(struct csi_priv *priv)
priv->last_eof = false;
priv->nfb4eof = false;
- ret = csi_idmac_setup(priv);
+ ret = csi_idmac_setup(priv, mbus_cfg);
if (ret) {
v4l2_err(&priv->sd, "csi_idmac_setup failed: %d\n", ret);
goto out_free_dma_buf;
@@ -701,7 +701,8 @@ static void csi_idmac_stop(struct csi_priv *priv)
}
/* Update the CSI whole sensor and active windows */
-static int csi_setup(struct csi_priv *priv)
+static int csi_setup(struct csi_priv *priv,
+ struct v4l2_mbus_config *mbus_cfg)
{
struct v4l2_mbus_framefmt *infmt, *outfmt;
const struct imx_media_pixfmt *incc;
@@ -719,7 +720,7 @@ static int csi_setup(struct csi_priv *priv)
* if cycles is set, we need to handle this over multiple cycles as
* generic/bayer data
*/
- if (is_parallel_bus(&priv->mbus_cfg) && incc->cycles) {
+ if (is_parallel_bus(mbus_cfg) && incc->cycles) {
if_fmt.width *= incc->cycles;
crop.width *= incc->cycles;
}
@@ -730,7 +731,7 @@ static int csi_setup(struct csi_priv *priv)
priv->crop.width == 2 * priv->compose.width,
priv->crop.height == 2 * priv->compose.height);
- ipu_csi_init_interface(priv->csi, &priv->mbus_cfg, &if_fmt, outfmt);
+ ipu_csi_init_interface(priv->csi, mbus_cfg, &if_fmt, outfmt);
ipu_csi_set_dest(priv->csi, priv->dest);
@@ -745,9 +746,17 @@ static int csi_setup(struct csi_priv *priv)
static int csi_start(struct csi_priv *priv)
{
+ struct v4l2_mbus_config mbus_cfg = { .type = 0 };
struct v4l2_fract *input_fi, *output_fi;
int ret;
+ ret = csi_get_upstream_mbus_config(priv, &mbus_cfg);
+ if (ret) {
+ v4l2_err(&priv->sd,
+ "failed to get upstream media bus configuration\n");
+ return ret;
+ }
+
input_fi = &priv->frame_interval[CSI_SINK_PAD];
output_fi = &priv->frame_interval[priv->active_output_pad];
@@ -758,7 +767,7 @@ static int csi_start(struct csi_priv *priv)
return ret;
/* Skip first few frames from a BT.656 source */
- if (priv->mbus_cfg.type == V4L2_MBUS_BT656) {
+ if (mbus_cfg.type == V4L2_MBUS_BT656) {
u32 delay_usec, bad_frames = 20;
delay_usec = DIV_ROUND_UP_ULL((u64)USEC_PER_SEC *
@@ -769,12 +778,12 @@ static int csi_start(struct csi_priv *priv)
}
if (priv->dest == IPU_CSI_DEST_IDMAC) {
- ret = csi_idmac_start(priv);
+ ret = csi_idmac_start(priv, &mbus_cfg);
if (ret)
goto stop_upstream;
}
- ret = csi_setup(priv);
+ ret = csi_setup(priv, &mbus_cfg);
if (ret)
goto idmac_stop;
@@ -1138,7 +1147,6 @@ static int csi_link_validate(struct v4l2_subdev *sd,
mutex_lock(&priv->lock);
- priv->mbus_cfg = mbus_cfg;
is_csi2 = !is_parallel_bus(&mbus_cfg);
if (is_csi2) {
/*
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c6b7df5682b4..a1f99c3b5f37 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -114,23 +114,23 @@ void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
int i;
for (i = 0; i < dwc->num_usb3_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB3PIPECTL(i));
if (enable && !dwc->dis_u3_susphy_quirk)
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
else
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB3PIPECTL(i), reg);
}
for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i));
if (enable && !dwc->dis_u2_susphy_quirk)
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
else
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg);
}
}
@@ -139,7 +139,7 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
unsigned int hw_mode;
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
/*
* For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE and
@@ -154,7 +154,7 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
reg |= DWC3_GCTL_PRTCAPDIR(mode);
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
dwc->current_dr_role = mode;
trace_dwc3_set_prtcap(mode);
@@ -214,9 +214,9 @@ static void __dwc3_set_mode(struct work_struct *work)
if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg |= DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
/*
* Wait for internal clocks to synchronized. DWC_usb31 and
@@ -226,9 +226,9 @@ static void __dwc3_set_mode(struct work_struct *work)
*/
msleep(100);
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg &= ~DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
}
spin_lock_irqsave(&dwc->lock, flags);
@@ -252,9 +252,9 @@ static void __dwc3_set_mode(struct work_struct *work)
phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST);
if (dwc->dis_split_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg = dwc3_readl(dwc, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_SPLITDISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_writel(dwc, DWC3_GUCTL3, reg);
}
}
break;
@@ -305,11 +305,11 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
struct dwc3 *dwc = dep->dwc;
u32 reg;
- dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE,
- DWC3_GDBGFIFOSPACE_NUM(dep->number) |
- DWC3_GDBGFIFOSPACE_TYPE(type));
+ dwc3_writel(dwc, DWC3_GDBGFIFOSPACE,
+ DWC3_GDBGFIFOSPACE_NUM(dep->number) |
+ DWC3_GDBGFIFOSPACE_TYPE(type));
- reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE);
+ reg = dwc3_readl(dwc, DWC3_GDBGFIFOSPACE);
return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg);
}
@@ -331,7 +331,7 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
return 0;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg |= DWC3_DCTL_CSFTRST;
reg &= ~DWC3_DCTL_RUN_STOP;
dwc3_gadget_dctl_write_safe(dwc, reg);
@@ -346,7 +346,7 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)
retries = 10;
do {
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (!(reg & DWC3_DCTL_CSFTRST))
goto done;
@@ -386,12 +386,12 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
if (dwc->fladj == 0)
return;
- reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+ reg = dwc3_readl(dwc, DWC3_GFLADJ);
dft = reg & DWC3_GFLADJ_30MHZ_MASK;
if (dft != dwc->fladj) {
reg &= ~DWC3_GFLADJ_30MHZ_MASK;
reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
- dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ dwc3_writel(dwc, DWC3_GFLADJ, reg);
}
}
@@ -423,10 +423,10 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
return;
}
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+ reg = dwc3_readl(dwc, DWC3_GUCTL);
reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
reg |= FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, period);
- dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+ dwc3_writel(dwc, DWC3_GUCTL, reg);
if (DWC3_VER_IS_PRIOR(DWC3, 250A))
return;
@@ -454,7 +454,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
*/
decr = 480000000 / rate;
- reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+ reg = dwc3_readl(dwc, DWC3_GFLADJ);
reg &= ~DWC3_GFLADJ_REFCLK_FLADJ_MASK
& ~DWC3_GFLADJ_240MHZDECR
& ~DWC3_GFLADJ_240MHZDECR_PLS1;
@@ -465,7 +465,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
if (dwc->gfladj_refclk_lpm_sel)
reg |= DWC3_GFLADJ_REFCLK_LPM_SEL;
- dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ dwc3_writel(dwc, DWC3_GFLADJ, reg);
}
/**
@@ -568,16 +568,16 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
evt = dwc->ev_buf;
evt->lpos = 0;
- dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
- lower_32_bits(evt->dma));
- dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
- upper_32_bits(evt->dma));
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
- DWC3_GEVNTSIZ_SIZE(evt->length));
+ dwc3_writel(dwc, DWC3_GEVNTADRLO(0),
+ lower_32_bits(evt->dma));
+ dwc3_writel(dwc, DWC3_GEVNTADRHI(0),
+ upper_32_bits(evt->dma));
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
+ DWC3_GEVNTSIZ_SIZE(evt->length));
/* Clear any stale event */
- reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
+ reg = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), reg);
return 0;
}
@@ -592,7 +592,7 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
* Exynos platforms may not be able to access event buffer if the
* controller failed to halt on dwc3_core_exit().
*/
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
if (!(reg & DWC3_DSTS_DEVCTRLHLT))
return;
@@ -600,14 +600,14 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
evt->lpos = 0;
- dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
+ dwc3_writel(dwc, DWC3_GEVNTADRLO(0), 0);
+ dwc3_writel(dwc, DWC3_GEVNTADRHI(0), 0);
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
| DWC3_GEVNTSIZ_SIZE(0));
/* Clear any stale event */
- reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
+ reg = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), reg);
}
static void dwc3_core_num_eps(struct dwc3 *dwc)
@@ -621,18 +621,18 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
{
struct dwc3_hwparams *parms = &dwc->hwparams;
- parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
- parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
- parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
- parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
- parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
- parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
- parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
- parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
- parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
+ parms->hwparams0 = dwc3_readl(dwc, DWC3_GHWPARAMS0);
+ parms->hwparams1 = dwc3_readl(dwc, DWC3_GHWPARAMS1);
+ parms->hwparams2 = dwc3_readl(dwc, DWC3_GHWPARAMS2);
+ parms->hwparams3 = dwc3_readl(dwc, DWC3_GHWPARAMS3);
+ parms->hwparams4 = dwc3_readl(dwc, DWC3_GHWPARAMS4);
+ parms->hwparams5 = dwc3_readl(dwc, DWC3_GHWPARAMS5);
+ parms->hwparams6 = dwc3_readl(dwc, DWC3_GHWPARAMS6);
+ parms->hwparams7 = dwc3_readl(dwc, DWC3_GHWPARAMS7);
+ parms->hwparams8 = dwc3_readl(dwc, DWC3_GHWPARAMS8);
if (DWC3_IP_IS(DWC32))
- parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
+ parms->hwparams9 = dwc3_readl(dwc, DWC3_GHWPARAMS9);
}
static void dwc3_config_soc_bus(struct dwc3 *dwc)
@@ -640,10 +640,10 @@ static void dwc3_config_soc_bus(struct dwc3 *dwc)
if (dwc->gsbuscfg0_reqinfo != DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED) {
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
+ reg = dwc3_readl(dwc, DWC3_GSBUSCFG0);
reg &= ~DWC3_GSBUSCFG0_REQINFO(~0);
reg |= DWC3_GSBUSCFG0_REQINFO(dwc->gsbuscfg0_reqinfo);
- dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
+ dwc3_writel(dwc, DWC3_GSBUSCFG0, reg);
}
}
@@ -667,7 +667,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(index));
+ reg = dwc3_readl(dwc, DWC3_GUSB3PIPECTL(index));
/*
* Make sure UX_EXIT_PX is cleared as that causes issues with some
@@ -705,7 +705,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index)
if (dwc->dis_del_phy_power_chg_quirk)
reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(index), reg);
+ dwc3_writel(dwc, DWC3_GUSB3PIPECTL(index), reg);
return 0;
}
@@ -714,7 +714,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(index));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(index));
/* Select the HS PHY interface */
switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
@@ -726,7 +726,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
} else if (dwc->hsphy_interface &&
!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg);
} else {
/* Relying on default value. */
if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
@@ -776,7 +776,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
if (dwc->ulpi_ext_vbus_drv)
reg |= DWC3_GUSB2PHYCFG_ULPIEXTVBUSDRV;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg);
return 0;
}
@@ -989,7 +989,7 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
+ reg = dwc3_readl(dwc, DWC3_GSNPSID);
dwc->ip = DWC3_GSNPS_ID(reg);
if (dwc->ip == DWC4_IP)
dwc->ip = DWC32_IP;
@@ -998,8 +998,8 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)
if (DWC3_IP_IS(DWC3)) {
dwc->revision = reg;
} else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) {
- dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
- dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE);
+ dwc->revision = dwc3_readl(dwc, DWC3_VER_NUMBER);
+ dwc->version_type = dwc3_readl(dwc, DWC3_VER_TYPE);
} else {
return false;
}
@@ -1013,7 +1013,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
unsigned int hw_mode;
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
power_opt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1);
@@ -1091,7 +1091,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
if (DWC3_VER_IS_PRIOR(DWC3, 190A))
reg |= DWC3_GCTL_U2RSTECN;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
}
static int dwc3_core_get_phy(struct dwc3 *dwc);
@@ -1111,7 +1111,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
int ret;
int i;
- cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
+ cfg = dwc3_readl(dwc, DWC3_GSBUSCFG0);
/*
* Handle property "snps,incr-burst-type-adjustment".
@@ -1186,7 +1186,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
break;
}
- dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg);
+ dwc3_writel(dwc, DWC3_GSBUSCFG0, cfg);
}
static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc)
@@ -1211,12 +1211,12 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc)
* (3x or more) to be within the requirement.
*/
scale = DIV_ROUND_UP(clk_get_rate(dwc->susp_clk), 16000);
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
if ((reg & DWC3_GCTL_PWRDNSCALE_MASK) < DWC3_GCTL_PWRDNSCALE(scale) ||
(reg & DWC3_GCTL_PWRDNSCALE_MASK) > DWC3_GCTL_PWRDNSCALE(scale*3)) {
reg &= ~(DWC3_GCTL_PWRDNSCALE_MASK);
reg |= DWC3_GCTL_PWRDNSCALE(scale);
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
}
}
@@ -1239,7 +1239,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
tx_maxburst = dwc->tx_max_burst_prd;
if (rx_thr_num && rx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
reg |= DWC31_RXTHRNUMPKTSEL_PRD;
reg &= ~DWC31_RXTHRNUMPKT_PRD(~0);
@@ -1248,11 +1248,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0);
reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
}
if (tx_thr_num && tx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GTXTHRCFG);
reg |= DWC31_TXTHRNUMPKTSEL_PRD;
reg &= ~DWC31_TXTHRNUMPKT_PRD(~0);
@@ -1261,7 +1261,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0);
reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GTXTHRCFG, reg);
}
}
@@ -1272,7 +1272,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
if (DWC3_IP_IS(DWC3)) {
if (rx_thr_num && rx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
reg |= DWC3_GRXTHRCFG_PKTCNTSEL;
reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0);
@@ -1281,11 +1281,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0);
reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
}
if (tx_thr_num && tx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GTXTHRCFG);
reg |= DWC3_GTXTHRCFG_PKTCNTSEL;
reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0);
@@ -1294,11 +1294,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0);
reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GTXTHRCFG, reg);
}
} else {
if (rx_thr_num && rx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
reg |= DWC31_GRXTHRCFG_PKTCNTSEL;
reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0);
@@ -1307,11 +1307,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0);
reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
}
if (tx_thr_num && tx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GTXTHRCFG);
reg |= DWC31_GTXTHRCFG_PKTCNTSEL;
reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0);
@@ -1320,7 +1320,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0);
reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GTXTHRCFG, reg);
}
}
}
@@ -1339,12 +1339,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
- /*
- * Write Linux Version Code to our GUID register so it's easy to figure
- * out which kernel version a bug was found.
- */
- dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
-
ret = dwc3_phy_setup(dwc);
if (ret)
return ret;
@@ -1376,6 +1370,12 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (ret)
goto err_exit_phy;
+ /*
+ * Write Linux Version Code to our GUID register so it's easy to figure
+ * out which kernel version a bug was found.
+ */
+ dwc3_writel(dwc, DWC3_GUID, LINUX_VERSION_CODE);
+
dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);
@@ -1408,9 +1408,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
* DWC_usb31 controller.
*/
if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
+ reg = dwc3_readl(dwc, DWC3_GUCTL2);
reg |= DWC3_GUCTL2_RST_ACTBITLATER;
- dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
+ dwc3_writel(dwc, DWC3_GUCTL2, reg);
}
/*
@@ -1423,9 +1423,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
* setting GUCTL2[19] by default; instead, use GUCTL2[19] = 0.
*/
if (DWC3_VER_IS(DWC3, 320A)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
+ reg = dwc3_readl(dwc, DWC3_GUCTL2);
reg &= ~DWC3_GUCTL2_LC_TIMER;
- dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
+ dwc3_writel(dwc, DWC3_GUCTL2, reg);
}
/*
@@ -1438,13 +1438,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
* legacy ULPI PHYs.
*/
if (dwc->resume_hs_terminations) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+ reg = dwc3_readl(dwc, DWC3_GUCTL1);
reg |= DWC3_GUCTL1_RESUME_OPMODE_HS_HOST;
- dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
+ dwc3_writel(dwc, DWC3_GUCTL1, reg);
}
if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+ reg = dwc3_readl(dwc, DWC3_GUCTL1);
/*
* Enable hardware control of sending remote wakeup
@@ -1479,7 +1479,7 @@ static int dwc3_core_init(struct dwc3 *dwc)
reg &= ~DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK;
}
- dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
+ dwc3_writel(dwc, DWC3_GUCTL1, reg);
}
dwc3_config_threshold(dwc);
@@ -1494,9 +1494,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
int i;
for (i = 0; i < dwc->num_usb3_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_LLUCTL(i));
+ reg = dwc3_readl(dwc, DWC3_LLUCTL(i));
reg |= DWC3_LLUCTL_FORCE_GEN1;
- dwc3_writel(dwc->regs, DWC3_LLUCTL(i), reg);
+ dwc3_writel(dwc, DWC3_LLUCTL(i), reg);
}
}
@@ -1515,9 +1515,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
* function is available only from version 1.70a.
*/
if (DWC3_VER_IS_WITHIN(DWC31, 170A, 180A)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg = dwc3_readl(dwc, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_USB20_RETRY_DISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_writel(dwc, DWC3_GUCTL3, reg);
}
return 0;
@@ -2447,9 +2447,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
int ret;
if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) {
- dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) &
+ dwc->susphy_state = (dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)) &
DWC3_GUSB2PHYCFG_SUSPHY) ||
- (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) &
+ (dwc3_readl(dwc, DWC3_GUSB3PIPECTL(0)) &
DWC3_GUSB3PIPECTL_SUSPHY);
/*
* TI AM62 platform requires SUSPHY to be
@@ -2479,10 +2479,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
if (dwc->dis_u2_susphy_quirk ||
dwc->dis_enblslpm_quirk) {
for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i));
reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg);
}
/* Give some time for USB2 PHY to suspend */
@@ -2542,14 +2542,14 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
}
/* Restore GUSB2PHYCFG bits that were modified in suspend */
for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i));
if (dwc->dis_u2_susphy_quirk)
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg);
}
for (i = 0; i < dwc->num_usb2_ports; i++)
@@ -2732,9 +2732,9 @@ void dwc3_pm_complete(struct dwc3 *dwc)
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST &&
dwc->dis_split_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg = dwc3_readl(dwc, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_SPLITDISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_writel(dwc, DWC3_GUCTL3, reg);
}
}
EXPORT_SYMBOL_GPL(dwc3_pm_complete);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 9cfc36d4bc25..a35b3db1f9f3 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -165,10 +165,10 @@
#define DWC3_DCFG1 0xc740 /* DWC_usb32 only */
#define DWC3_DEP_BASE(n) (0xc800 + ((n) * 0x10))
-#define DWC3_DEPCMDPAR2 0x00
-#define DWC3_DEPCMDPAR1 0x04
-#define DWC3_DEPCMDPAR0 0x08
-#define DWC3_DEPCMD 0x0c
+#define DWC3_DEPCMDPAR2(n) (DWC3_DEP_BASE(n) + 0x00)
+#define DWC3_DEPCMDPAR1(n) (DWC3_DEP_BASE(n) + 0x04)
+#define DWC3_DEPCMDPAR0(n) (DWC3_DEP_BASE(n) + 0x08)
+#define DWC3_DEPCMD(n) (DWC3_DEP_BASE(n) + 0x0c)
#define DWC3_DEV_IMOD(n) (0xca00 + ((n) * 0x4))
@@ -749,8 +749,6 @@ struct dwc3_ep {
struct list_head pending_list;
struct list_head started_list;
- void __iomem *regs;
-
struct dwc3_trb *trb_pool;
dma_addr_t trb_pool_dma;
struct dwc3 *dwc;
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index d18bf5e32cc8..ffb1101f55c7 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -36,23 +36,19 @@
#define dump_ep_register_set(n) \
{ \
.name = "DEPCMDPAR2("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMDPAR2, \
+ .offset = DWC3_DEPCMDPAR2(n), \
}, \
{ \
.name = "DEPCMDPAR1("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMDPAR1, \
+ .offset = DWC3_DEPCMDPAR1(n), \
}, \
{ \
.name = "DEPCMDPAR0("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMDPAR0, \
+ .offset = DWC3_DEPCMDPAR0(n), \
}, \
{ \
.name = "DEPCMD("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMD, \
+ .offset = DWC3_DEPCMD(n), \
}
@@ -300,14 +296,14 @@ static void dwc3_host_lsp(struct seq_file *s)
reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel);
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
- val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
+ val = dwc3_readl(dwc, DWC3_GDBGLSP);
seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val);
if (dbc_enabled && sel < 256) {
reg |= DWC3_GDBGLSPMUX_ENDBC;
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
- val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
+ val = dwc3_readl(dwc, DWC3_GDBGLSP);
seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val);
}
}
@@ -320,8 +316,8 @@ static void dwc3_gadget_lsp(struct seq_file *s)
for (i = 0; i < 16; i++) {
reg = DWC3_GDBGLSPMUX_DEVSELECT(i);
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
- reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
+ reg = dwc3_readl(dwc, DWC3_GDBGLSP);
seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg);
}
}
@@ -339,7 +335,7 @@ static int dwc3_lsp_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GSTS);
+ reg = dwc3_readl(dwc, DWC3_GSTS);
current_mode = DWC3_GSTS_CURMOD(reg);
switch (current_mode) {
@@ -410,7 +406,7 @@ static int dwc3_mode_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
spin_unlock_irqrestore(&dwc->lock, flags);
mode = DWC3_GCTL_PRTCAP(reg);
@@ -482,7 +478,7 @@ static int dwc3_testmode_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= DWC3_DCTL_TSTCTRL_MASK;
reg >>= 1;
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -581,7 +577,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GSTS);
+ reg = dwc3_readl(dwc, DWC3_GSTS);
if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
seq_puts(s, "Not available\n");
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -589,7 +585,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
return 0;
}
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
state = DWC3_DSTS_USBLNKST(reg);
speed = reg & DWC3_DSTS_CONNECTSPD;
@@ -643,14 +639,14 @@ static ssize_t dwc3_link_state_write(struct file *file,
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GSTS);
+ reg = dwc3_readl(dwc, DWC3_GSTS);
if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
spin_unlock_irqrestore(&dwc->lock, flags);
pm_runtime_put_sync(dwc->dev);
return -EINVAL;
}
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
speed = reg & DWC3_DSTS_CONNECTSPD;
if (speed < DWC3_DSTS_SUPERSPEED &&
@@ -946,10 +942,10 @@ static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
spin_lock_irqsave(&dwc->lock, flags);
reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
- lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0);
- upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1);
+ lower_32_bits = dwc3_readl(dwc, DWC3_GDBGEPINFO0);
+ upper_32_bits = dwc3_readl(dwc, DWC3_GDBGEPINFO1);
ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
seq_printf(s, "0x%016llx\n", ep_info);
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index 4c91240eb429..b229fb1fd932 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -18,25 +18,25 @@
static void dwc3_otg_disable_events(struct dwc3 *dwc, u32 disable_mask)
{
- u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
+ u32 reg = dwc3_readl(dwc, DWC3_OEVTEN);
reg &= ~(disable_mask);
- dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+ dwc3_writel(dwc, DWC3_OEVTEN, reg);
}
static void dwc3_otg_enable_events(struct dwc3 *dwc, u32 enable_mask)
{
- u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
+ u32 reg = dwc3_readl(dwc, DWC3_OEVTEN);
reg |= (enable_mask);
- dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+ dwc3_writel(dwc, DWC3_OEVTEN, reg);
}
static void dwc3_otg_clear_events(struct dwc3 *dwc)
{
- u32 reg = dwc3_readl(dwc->regs, DWC3_OEVT);
+ u32 reg = dwc3_readl(dwc, DWC3_OEVT);
- dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+ dwc3_writel(dwc, DWC3_OEVTEN, reg);
}
#define DWC3_OTG_ALL_EVENTS (DWC3_OEVTEN_XHCIRUNSTPSETEN | \
@@ -72,18 +72,18 @@ static irqreturn_t dwc3_otg_irq(int irq, void *_dwc)
struct dwc3 *dwc = _dwc;
irqreturn_t ret = IRQ_NONE;
- reg = dwc3_readl(dwc->regs, DWC3_OEVT);
+ reg = dwc3_readl(dwc, DWC3_OEVT);
if (reg) {
/* ignore non OTG events, we can't disable them in OEVTEN */
if (!(reg & DWC3_OTG_ALL_EVENTS)) {
- dwc3_writel(dwc->regs, DWC3_OEVT, reg);
+ dwc3_writel(dwc, DWC3_OEVT, reg);
return IRQ_NONE;
}
if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST &&
!(reg & DWC3_OEVT_DEVICEMODE))
dwc->otg_restart_host = true;
- dwc3_writel(dwc->regs, DWC3_OEVT, reg);
+ dwc3_writel(dwc, DWC3_OEVT, reg);
ret = IRQ_WAKE_THREAD;
}
@@ -100,23 +100,23 @@ static void dwc3_otgregs_init(struct dwc3 *dwc)
* the signal outputs sent to the PHY, the OTG FSM logic of the
* core and also the resets to the VBUS filters inside the core.
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
reg |= DWC3_OCFG_SFTRSTMASK;
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/* Disable hibernation for simplicity */
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
/*
* Initialize OTG registers as per
* Figure 11-4 OTG Driver Overall Programming Flow
*/
/* OCFG.SRPCap = 0, OCFG.HNPCap = 0 */
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/* OEVT = FFFF */
dwc3_otg_clear_events(dwc);
/* OEVTEN = 0 */
@@ -127,11 +127,11 @@ static void dwc3_otgregs_init(struct dwc3 *dwc)
* OCTL.PeriMode = 1, OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0,
* OCTL.HNPReq = 0
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg |= DWC3_OCTL_PERIMODE;
reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN |
DWC3_OCTL_HNPREQ);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
static int dwc3_otg_get_irq(struct dwc3 *dwc)
@@ -175,9 +175,9 @@ void dwc3_otg_init(struct dwc3 *dwc)
/* GCTL.PrtCapDir=2'b11 */
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true);
/* GUSB2PHYCFG0.SusPHY=0 */
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
/* Initialize OTG registers */
dwc3_otgregs_init(dwc);
@@ -203,17 +203,17 @@ void dwc3_otg_host_init(struct dwc3 *dwc)
* OCTL.PeriMode=0, OCTL.TermSelDLPulse = 0,
* OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg &= ~(DWC3_OCTL_PERIMODE | DWC3_OCTL_TERMSELIDPULSE |
DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
/*
* OCFG.DisPrtPwrCutoff = 0/1
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
reg &= ~DWC3_OCFG_DISPWRCUTTOFF;
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/*
* OCFG.SRPCap = 1, OCFG.HNPCap = GHWPARAMS6.HNP_CAP
@@ -229,15 +229,15 @@ void dwc3_otg_host_init(struct dwc3 *dwc)
/* GUSB2PHYCFG.ULPIAutoRes = 1/0, GUSB2PHYCFG.SusPHY = 1 */
if (!dwc->dis_u2_susphy_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
/* Set Port Power to enable VBUS: OCTL.PrtPwrCtl = 1 */
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg |= DWC3_OCTL_PRTPWRCTL;
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
/* should be called after Host controller driver is stopped */
@@ -258,9 +258,9 @@ static void dwc3_otg_host_exit(struct dwc3 *dwc)
*/
/* OCTL.HstSetHNPEn = 0, OCTL.PrtPwrCtl=0 */
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg &= ~(DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_PRTPWRCTL);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
/* should be called before the gadget controller driver is started */
@@ -274,27 +274,27 @@ static void dwc3_otg_device_init(struct dwc3 *dwc)
* OCFG.HNPCap = GHWPARAMS6.HNP_CAP, OCFG.SRPCap = 1
* but we keep them 0 for simple dual-role operation.
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
/* OCFG.OTGSftRstMsk = 0/1 */
reg |= DWC3_OCFG_SFTRSTMASK;
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/*
* OCTL.PeriMode = 1
* OCTL.TermSelDLPulse = 0/1, OCTL.HNPReq = 0
* OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg |= DWC3_OCTL_PERIMODE;
reg &= ~(DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_HNPREQ |
DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
/* OEVTEN.OTGBDevSesVldDetEvntEn = 1 */
dwc3_otg_enable_events(dwc, DWC3_OEVTEN_BDEVSESSVLDDETEN);
/* GUSB2PHYCFG.ULPIAutoRes = 0, GUSB2PHYCFG0.SusPHY = 1 */
if (!dwc->dis_u2_susphy_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
/* GCTL.GblHibernationEn = 0. Already 0. */
}
@@ -319,10 +319,10 @@ static void dwc3_otg_device_exit(struct dwc3 *dwc)
DWC3_OEVTEN_BDEVBHOSTENDEN);
/* OCTL.DevSetHNPEn = 0, OCTL.HNPReq = 0, OCTL.PeriMode=1 */
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HNPREQ);
reg |= DWC3_OCTL_PERIMODE;
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
@@ -341,7 +341,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
return;
if (!ignore_idstatus) {
- reg = dwc3_readl(dwc->regs, DWC3_OSTS);
+ reg = dwc3_readl(dwc, DWC3_OSTS);
id = !!(reg & DWC3_OSTS_CONIDSTS);
dwc->desired_otg_role = id ? DWC3_OTG_ROLE_DEVICE :
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index e0bad5708664..a8ff8db610d3 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -361,7 +361,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
if ((dwc->speed == DWC3_DSTS_SUPERSPEED) ||
(dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (reg & DWC3_DCTL_INITU1ENA)
usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
if (reg & DWC3_DCTL_INITU2ENA)
@@ -417,12 +417,12 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
if (set && dwc->dis_u1_entry_quirk)
return -EINVAL;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU1ENA;
else
reg &= ~DWC3_DCTL_INITU1ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
return 0;
}
@@ -441,12 +441,12 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
if (set && dwc->dis_u2_entry_quirk)
return -EINVAL;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU2ENA;
else
reg &= ~DWC3_DCTL_INITU2ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
return 0;
}
@@ -612,10 +612,10 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
return -EINVAL;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~(DWC3_DCFG_DEVADDR_MASK);
reg |= DWC3_DCFG_DEVADDR(addr);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
if (addr)
usb_gadget_set_state(dwc->gadget, USB_STATE_ADDRESS);
@@ -672,12 +672,12 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
* Enable transition to U1/U2 state when
* nothing is pending from application.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (!dwc->dis_u1_entry_quirk)
reg |= DWC3_DCTL_ACCEPTU1ENA;
if (!dwc->dis_u2_entry_quirk)
reg |= DWC3_DCTL_ACCEPTU2ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
}
break;
@@ -717,7 +717,7 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req)
dwc->u2sel = le16_to_cpu(timing.u2sel);
dwc->u2pel = le16_to_cpu(timing.u2pel);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (reg & DWC3_DCTL_INITU2ENA)
param = dwc->u2pel;
if (reg & DWC3_DCTL_INITU1ENA)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index db5e5b77b1ea..89963cd77daa 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -42,7 +42,7 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_TSTCTRL_MASK;
switch (mode) {
@@ -73,7 +73,7 @@ int dwc3_gadget_get_link_state(struct dwc3 *dwc)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
return DWC3_DSTS_USBLNKST(reg);
}
@@ -97,7 +97,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
*/
if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) {
while (--retries) {
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
if (reg & DWC3_DSTS_DCNRD)
udelay(5);
else
@@ -108,15 +108,15 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
return -ETIMEDOUT;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
/* set no action before sending new link state change */
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
/* set requested state */
reg |= DWC3_DCTL_ULSTCHNGREQ(state);
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
/*
* The following code is racy when called from dwc3_gadget_wakeup,
@@ -128,7 +128,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
/* wait for a change in DSTS */
retries = 10000;
while (--retries) {
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
if (DWC3_DSTS_USBLNKST(reg) == state)
return 0;
@@ -260,11 +260,11 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd,
int ret = 0;
u32 reg;
- dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
- dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
+ dwc3_writel(dwc, DWC3_DGCMDPAR, param);
+ dwc3_writel(dwc, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
do {
- reg = dwc3_readl(dwc->regs, DWC3_DGCMD);
+ reg = dwc3_readl(dwc, DWC3_DGCMD);
if (!(reg & DWC3_DGCMD_CMDACT)) {
status = DWC3_DGCMD_STATUS(reg);
if (status)
@@ -320,6 +320,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
int cmd_status = 0;
int ret = -EINVAL;
+ u8 epnum = dep->number;
/*
* When operating in USB 2.0 speeds (HS/FS), if GUSB2PHYCFG.ENBLSLPM or
@@ -333,7 +334,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
*/
if (dwc->gadget->speed <= USB_SPEED_HIGH ||
DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
@@ -345,7 +346,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
}
if (saved_config)
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
/*
@@ -355,9 +356,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
* improve performance.
*/
if (DWC3_DEPCMD_CMD(cmd) != DWC3_DEPCMD_UPDATETRANSFER) {
- dwc3_writel(dep->regs, DWC3_DEPCMDPAR0, params->param0);
- dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1);
- dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2);
+ dwc3_writel(dwc, DWC3_DEPCMDPAR0(epnum), params->param0);
+ dwc3_writel(dwc, DWC3_DEPCMDPAR1(epnum), params->param1);
+ dwc3_writel(dwc, DWC3_DEPCMDPAR2(epnum), params->param2);
}
/*
@@ -381,7 +382,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
else
cmd |= DWC3_DEPCMD_CMDACT;
- dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
+ dwc3_writel(dwc, DWC3_DEPCMD(epnum), cmd);
if (!(cmd & DWC3_DEPCMD_CMDACT) ||
(DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER &&
@@ -391,7 +392,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
}
do {
- reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
+ reg = dwc3_readl(dwc, DWC3_DEPCMD(epnum));
if (!(reg & DWC3_DEPCMD_CMDACT)) {
cmd_status = DWC3_DEPCMD_STATUS(reg);
@@ -447,9 +448,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
mdelay(1);
if (saved_config) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= saved_config;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
return ret;
@@ -726,7 +727,7 @@ static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc)
u32 reg;
/* Check if TXFIFOs start at non-zero addr */
- reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
+ reg = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0));
fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg);
ram_depth -= (fifo_0_start >> 16);
@@ -754,7 +755,7 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
/* Read ep0IN related TXFIFO size */
dep = dwc->eps[1];
- size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
+ size = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0));
if (DWC3_IP_IS(DWC3))
fifo_depth = DWC3_GTXFIFOSIZ_TXFDEP(size);
else
@@ -769,10 +770,10 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
/* Don't change TXFRAMNUM on usb31 version */
size = DWC3_IP_IS(DWC3) ? 0 :
- dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
+ dwc3_readl(dwc, DWC3_GTXFIFOSIZ(num >> 1)) &
DWC31_GTXFIFOSIZ_TXFRAMNUM;
- dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1), size);
+ dwc3_writel(dwc, DWC3_GTXFIFOSIZ(num >> 1), size);
dep->flags &= ~DWC3_EP_TXFIFO_RESIZED;
}
dwc->num_ep_resized = 0;
@@ -875,7 +876,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
fifo_size++;
/* Check if TXFIFOs start at non-zero addr */
- tmp = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
+ tmp = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0));
fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(tmp);
fifo_size |= (fifo_0_start + (dwc->last_fifo_depth << 16));
@@ -898,7 +899,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
return -ENOMEM;
}
- dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size);
+ dwc3_writel(dwc, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size);
dep->flags |= DWC3_EP_TXFIFO_RESIZED;
dwc->num_ep_resized++;
@@ -942,9 +943,9 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
dep->type = usb_endpoint_type(desc);
dep->flags |= DWC3_EP_ENABLED;
- reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
+ reg = dwc3_readl(dwc, DWC3_DALEPENA);
reg |= DWC3_DALEPENA_EP(dep->number);
- dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ dwc3_writel(dwc, DWC3_DALEPENA, reg);
dep->trb_dequeue = 0;
dep->trb_enqueue = 0;
@@ -1079,9 +1080,9 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
if (dep->flags & DWC3_EP_STALL)
__dwc3_gadget_ep_set_halt(dep, 0, false);
- reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
+ reg = dwc3_readl(dwc, DWC3_DALEPENA);
reg &= ~DWC3_DALEPENA_EP(dep->number);
- dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ dwc3_writel(dwc, DWC3_DALEPENA, reg);
dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
@@ -1742,7 +1743,7 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
return DWC3_DSTS_SOFFN(reg);
}
@@ -2350,13 +2351,13 @@ static void dwc3_gadget_enable_linksts_evts(struct dwc3 *dwc, bool set)
if (DWC3_VER_IS_PRIOR(DWC3, 250A))
return;
- reg = dwc3_readl(dwc->regs, DWC3_DEVTEN);
+ reg = dwc3_readl(dwc, DWC3_DEVTEN);
if (set)
reg |= DWC3_DEVTEN_ULSTCNGEN;
else
reg &= ~DWC3_DEVTEN_ULSTCNGEN;
- dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
+ dwc3_writel(dwc, DWC3_DEVTEN, reg);
}
static int dwc3_gadget_get_frame(struct usb_gadget *g)
@@ -2379,7 +2380,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
*
* We can check that via USB Link State bits in DSTS register.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
link_state = DWC3_DSTS_USBLNKST(reg);
@@ -2407,9 +2408,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
/* Recent versions do this automatically */
if (DWC3_VER_IS_PRIOR(DWC3, 194A)) {
/* write zeroes to Link Change Request */
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
}
/*
@@ -2529,7 +2530,7 @@ static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc)
if (ssp_rate == USB_SSP_GEN_UNKNOWN)
ssp_rate = dwc->max_ssp_rate;
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~DWC3_DCFG_SPEED_MASK;
reg &= ~DWC3_DCFG_NUMLANES(~0);
@@ -2542,7 +2543,7 @@ static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc)
dwc->max_ssp_rate != USB_SSP_GEN_2x1)
reg |= DWC3_DCFG_NUMLANES(1);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
@@ -2560,7 +2561,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
return;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~(DWC3_DCFG_SPEED_MASK);
/*
@@ -2611,7 +2612,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
speed < USB_SPEED_SUPER_PLUS)
reg &= ~DWC3_DCFG_NUMLANES(~0);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
@@ -2636,7 +2637,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
* mentioned in the dwc3 programming guide. It has been tested on an
* Exynos platforms.
*/
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
@@ -2648,9 +2649,9 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
}
if (saved_config)
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (is_on) {
if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
reg &= ~DWC3_DCTL_TRGTULST_MASK;
@@ -2674,14 +2675,14 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
do {
usleep_range(1000, 2000);
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
reg &= DWC3_DSTS_DEVCTRLHLT;
} while (--timeout && !(!is_on ^ !reg));
if (saved_config) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= saved_config;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
if (!timeout)
@@ -2857,13 +2858,13 @@ static void dwc3_gadget_enable_irq(struct dwc3 *dwc)
if (!DWC3_VER_IS_PRIOR(DWC3, 230A))
reg |= DWC3_DEVTEN_U3L2L1SUSPEN;
- dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
+ dwc3_writel(dwc, DWC3_DEVTEN, reg);
}
static void dwc3_gadget_disable_irq(struct dwc3 *dwc)
{
/* mask all interrupts */
- dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
+ dwc3_writel(dwc, DWC3_DEVTEN, 0x00);
}
static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
@@ -2904,10 +2905,10 @@ static void dwc3_gadget_setup_nump(struct dwc3 *dwc)
nump = min_t(u32, nump, 16);
/* update NumP */
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~DWC3_DCFG_NUMP_MASK;
reg |= nump << DWC3_DCFG_NUMP_SHIFT;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static int __dwc3_gadget_start(struct dwc3 *dwc)
@@ -2921,10 +2922,10 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
* the core supports IMOD, disable it.
*/
if (dwc->imod_interval) {
- dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
+ dwc3_writel(dwc, DWC3_DEV_IMOD(0), dwc->imod_interval);
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
} else if (dwc3_has_imod(dwc)) {
- dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), 0);
+ dwc3_writel(dwc, DWC3_DEV_IMOD(0), 0);
}
/*
@@ -2934,13 +2935,13 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
* This way, we maximize the chances that we'll be able to get several
* bursts of data without going through any sort of endpoint throttling.
*/
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
if (DWC3_IP_IS(DWC3))
reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL;
else
reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL;
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
dwc3_gadget_setup_nump(dwc);
@@ -2951,15 +2952,15 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
* ACK with NumP=0 and PP=0 (for IN direction). This slightly improves
* the stream performance.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg |= DWC3_DCFG_IGNSTRMPP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
/* Enable MST by default if the device is capable of MST */
if (DWC3_MST_CAPABLE(&dwc->hwparams)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG1);
+ reg = dwc3_readl(dwc, DWC3_DCFG1);
reg &= ~DWC3_DCFG1_DIS_MST_ENH;
- dwc3_writel(dwc->regs, DWC3_DCFG1, reg);
+ dwc3_writel(dwc, DWC3_DCFG1, reg);
}
/* Start with SuperSpeed Default */
@@ -3237,7 +3238,7 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
/* MDWIDTH is represented in bits, we need it in bytes */
mdwidth /= 8;
- size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
+ size = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(dep->number >> 1));
if (DWC3_IP_IS(DWC3))
size = DWC3_GTXFIFOSIZ_TXFDEP(size);
else
@@ -3286,7 +3287,7 @@ static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
mdwidth /= 8;
/* All OUT endpoints share a single RxFIFO space */
- size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
+ size = dwc3_readl(dwc, DWC3_GRXFIFOSIZ(0));
if (DWC3_IP_IS(DWC3))
size = DWC3_GRXFIFOSIZ_RXFDEP(size);
else
@@ -3379,7 +3380,6 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
dep->dwc = dwc;
dep->number = epnum;
dep->direction = direction;
- dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
dwc->eps[epnum] = dep;
dep->combo_num = 0;
dep->start_cmd_status = 0;
@@ -3740,9 +3740,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
return no_started_trb;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg |= dwc->u1u2;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
dwc->u1u2 = 0;
}
@@ -4072,7 +4072,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RX_DET);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_INITU1ENA;
reg &= ~DWC3_DCTL_INITU2ENA;
dwc3_gadget_dctl_write_safe(dwc, reg);
@@ -4161,7 +4161,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
dwc3_stop_active_transfers(dwc);
dwc->connected = true;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_TSTCTRL_MASK;
dwc3_gadget_dctl_write_safe(dwc, reg);
dwc->test_mode = false;
@@ -4170,9 +4170,9 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
dwc3_clear_stall_all_ep(dwc);
/* Reset device address to zero */
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~(DWC3_DCFG_DEVADDR_MASK);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
@@ -4186,7 +4186,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
if (!dwc->softconnect)
return;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
speed = reg & DWC3_DSTS_CONNECTSPD;
dwc->speed = speed;
@@ -4261,11 +4261,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
!dwc->usb2_gadget_lpm_disable &&
(speed != DWC3_DSTS_SUPERSPEED) &&
(speed != DWC3_DSTS_SUPERSPEED_PLUS)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg |= DWC3_DCFG_LPM_CAP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold |
@@ -4288,12 +4288,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
dwc3_gadget_dctl_write_safe(dwc, reg);
} else {
if (dwc->usb2_gadget_lpm_disable) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~DWC3_DCFG_LPM_CAP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_HIRD_THRES_MASK;
dwc3_gadget_dctl_write_safe(dwc, reg);
}
@@ -4399,7 +4399,7 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
switch (dwc->link_state) {
case DWC3_LINK_STATE_U1:
case DWC3_LINK_STATE_U2:
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
u1u2 = reg & (DWC3_DCTL_INITU2ENA
| DWC3_DCTL_ACCEPTU2ENA
| DWC3_DCTL_INITU1ENA
@@ -4556,7 +4556,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
ret = IRQ_HANDLED;
/* Unmask interrupt */
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
DWC3_GEVNTSIZ_SIZE(evt->length));
evt->flags &= ~DWC3_EVENT_PENDING;
@@ -4567,8 +4567,8 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
wmb();
if (dwc->imod_interval) {
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
- dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
+ dwc3_writel(dwc, DWC3_DEV_IMOD(0), dwc->imod_interval);
}
return ret;
@@ -4617,7 +4617,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
if (evt->flags & DWC3_EVENT_PENDING)
return IRQ_HANDLED;
- count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
+ count = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
count &= DWC3_GEVNTCOUNT_MASK;
if (!count)
return IRQ_NONE;
@@ -4632,7 +4632,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
evt->flags |= DWC3_EVENT_PENDING;
/* Mask interrupt */
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(evt->length));
amount = min(count, evt->length - evt->lpos);
@@ -4641,7 +4641,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
if (amount < count)
memcpy(evt->cache, evt->buf, count - amount);
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), count);
return IRQ_WAKE_THREAD;
}
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index d73e735e4081..45f113b3c146 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -132,7 +132,7 @@ static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep)
{
u32 res_id;
- res_id = dwc3_readl(dep->regs, DWC3_DEPCMD);
+ res_id = dwc3_readl(dep->dwc, DWC3_DEPCMD(dep->number));
dep->resource_index = DWC3_DEPCMD_GET_RSC_IDX(res_id);
}
@@ -147,7 +147,7 @@ static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep)
static inline void dwc3_gadget_dctl_write_safe(struct dwc3 *dwc, u32 value)
{
value &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
- dwc3_writel(dwc->regs, DWC3_DCTL, value);
+ dwc3_writel(dwc, DWC3_DCTL, value);
}
#endif /* __DRIVERS_USB_DWC3_GADGET_H */
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 1e96ea339d48..7dd0c1e0cf74 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -16,9 +16,10 @@
#include "debug.h"
#include "core.h"
-static inline u32 dwc3_readl(void __iomem *base, u32 offset)
+static inline u32 dwc3_readl(struct dwc3 *dwc, u32 offset)
{
u32 value;
+ void __iomem *base = dwc->regs;
/*
* We requested the mem region starting from the Globals address
@@ -37,8 +38,10 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset)
return value;
}
-static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
+static inline void dwc3_writel(struct dwc3 *dwc, u32 offset, u32 value)
{
+ void __iomem *base = dwc->regs;
+
/*
* We requested the mem region starting from the Globals address
* space, see dwc3_probe in core.c.
diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c
index f23f4c9a557e..57daad15f502 100644
--- a/drivers/usb/dwc3/ulpi.c
+++ b/drivers/usb/dwc3/ulpi.c
@@ -33,13 +33,13 @@ static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read)
if (read)
ns += DWC3_ULPI_BASE_DELAY;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY)
usleep_range(1000, 1200);
while (count--) {
ndelay(ns);
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYACC(0));
if (reg & DWC3_GUSB2PHYACC_DONE)
return 0;
cpu_relax();
@@ -55,13 +55,13 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr)
int ret;
reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYACC(0), reg);
ret = dwc3_ulpi_busyloop(dwc, addr, true);
if (ret)
return ret;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYACC(0));
return DWC3_GUSB2PHYACC_DATA(reg);
}
@@ -73,7 +73,7 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val)
reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
reg |= DWC3_GUSB2PHYACC_WRITE | val;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYACC(0), reg);
return dwc3_ulpi_busyloop(dwc, addr, false);
}
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index fe5a04f4cf14..336a0de9a911 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -5526,6 +5526,8 @@ static void run_state_machine(struct tcpm_port *port)
usb_power_delivery_unregister_capabilities(port->partner_source_caps);
port->partner_source_caps = NULL;
tcpm_pd_send_control(port, PD_CTRL_ACCEPT, TCPC_TX_SOP);
+ port->vdm_sm_running = false;
+ port->explicit_contract = false;
tcpm_ams_finish(port);
if (port->pwr_role == TYPEC_SOURCE) {
port->upcoming_state = SRC_SEND_CAPABILITIES;
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index dc5ad3fcc7be..bed8ba18222b 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -261,10 +261,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
int fg, int bg)
{
struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
- int y = real_y(ops->p, vc->state.y);
+ int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1;
char *src;
@@ -278,10 +278,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
- if (ops->cursor_state.image.data != src ||
- ops->cursor_reset) {
- ops->cursor_state.image.data = src;
- cursor.set |= FB_CUR_SETIMAGE;
+ if (par->cursor_state.image.data != src ||
+ par->cursor_reset) {
+ par->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
@@ -290,46 +290,46 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
dst = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
if (!dst)
return;
- kfree(ops->cursor_data);
- ops->cursor_data = dst;
+ kfree(par->cursor_data);
+ par->cursor_data = dst;
update_attr(dst, src, attribute, vc);
src = dst;
}
- if (ops->cursor_state.image.fg_color != fg ||
- ops->cursor_state.image.bg_color != bg ||
- ops->cursor_reset) {
- ops->cursor_state.image.fg_color = fg;
- ops->cursor_state.image.bg_color = bg;
+ if (par->cursor_state.image.fg_color != fg ||
+ par->cursor_state.image.bg_color != bg ||
+ par->cursor_reset) {
+ par->cursor_state.image.fg_color = fg;
+ par->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
- if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) ||
- (ops->cursor_state.image.dy != (vc->vc_font.height * y)) ||
- ops->cursor_reset) {
- ops->cursor_state.image.dx = vc->vc_font.width * vc->state.x;
- ops->cursor_state.image.dy = vc->vc_font.height * y;
+ if ((par->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) ||
+ (par->cursor_state.image.dy != (vc->vc_font.height * y)) ||
+ par->cursor_reset) {
+ par->cursor_state.image.dx = vc->vc_font.width * vc->state.x;
+ par->cursor_state.image.dy = vc->vc_font.height * y;
cursor.set |= FB_CUR_SETPOS;
}
- if (ops->cursor_state.image.height != vc->vc_font.height ||
- ops->cursor_state.image.width != vc->vc_font.width ||
- ops->cursor_reset) {
- ops->cursor_state.image.height = vc->vc_font.height;
- ops->cursor_state.image.width = vc->vc_font.width;
+ if (par->cursor_state.image.height != vc->vc_font.height ||
+ par->cursor_state.image.width != vc->vc_font.width ||
+ par->cursor_reset) {
+ par->cursor_state.image.height = vc->vc_font.height;
+ par->cursor_state.image.width = vc->vc_font.width;
cursor.set |= FB_CUR_SETSIZE;
}
- if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
- ops->cursor_reset) {
- ops->cursor_state.hot.x = cursor.hot.y = 0;
+ if (par->cursor_state.hot.x || par->cursor_state.hot.y ||
+ par->cursor_reset) {
+ par->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
- vc->vc_cursor_type != ops->p->cursor_shape ||
- ops->cursor_state.mask == NULL ||
- ops->cursor_reset) {
+ vc->vc_cursor_type != par->p->cursor_shape ||
+ par->cursor_state.mask == NULL ||
+ par->cursor_reset) {
char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
int cur_height, size, i = 0;
u8 msk = 0xff;
@@ -337,13 +337,13 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
if (!mask)
return;
- kfree(ops->cursor_state.mask);
- ops->cursor_state.mask = mask;
+ kfree(par->cursor_state.mask);
+ par->cursor_state.mask = mask;
- ops->p->cursor_shape = vc->vc_cursor_type;
+ par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
- switch (CUR_SIZE(ops->p->cursor_shape)) {
+ switch (CUR_SIZE(par->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;
@@ -372,19 +372,19 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
mask[i++] = msk;
}
- ops->cursor_state.enable = enable && !use_sw;
+ par->cursor_state.enable = enable && !use_sw;
cursor.image.data = src;
- cursor.image.fg_color = ops->cursor_state.image.fg_color;
- cursor.image.bg_color = ops->cursor_state.image.bg_color;
- cursor.image.dx = ops->cursor_state.image.dx;
- cursor.image.dy = ops->cursor_state.image.dy;
- cursor.image.height = ops->cursor_state.image.height;
- cursor.image.width = ops->cursor_state.image.width;
- cursor.hot.x = ops->cursor_state.hot.x;
- cursor.hot.y = ops->cursor_state.hot.y;
- cursor.mask = ops->cursor_state.mask;
- cursor.enable = ops->cursor_state.enable;
+ cursor.image.fg_color = par->cursor_state.image.fg_color;
+ cursor.image.bg_color = par->cursor_state.image.bg_color;
+ cursor.image.dx = par->cursor_state.image.dx;
+ cursor.image.dy = par->cursor_state.image.dy;
+ cursor.image.height = par->cursor_state.image.height;
+ cursor.image.width = par->cursor_state.image.width;
+ cursor.hot.x = par->cursor_state.hot.x;
+ cursor.hot.y = par->cursor_state.hot.y;
+ cursor.mask = par->cursor_state.mask;
+ cursor.enable = par->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
@@ -394,31 +394,31 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
if (err)
soft_cursor(info, &cursor);
- ops->cursor_reset = 0;
+ par->cursor_reset = 0;
}
static int bit_update_start(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int err;
- err = fb_pan_display(info, &ops->var);
- ops->var.xoffset = info->var.xoffset;
- ops->var.yoffset = info->var.yoffset;
- ops->var.vmode = info->var.vmode;
+ err = fb_pan_display(info, &par->var);
+ par->var.xoffset = info->var.xoffset;
+ par->var.yoffset = info->var.yoffset;
+ par->var.vmode = info->var.vmode;
return err;
}
-void fbcon_set_bitops(struct fbcon_ops *ops)
+void fbcon_set_bitops(struct fbcon_par *par)
{
- ops->bmove = bit_bmove;
- ops->clear = bit_clear;
- ops->putcs = bit_putcs;
- ops->clear_margins = bit_clear_margins;
- ops->cursor = bit_cursor;
- ops->update_start = bit_update_start;
- ops->rotate_font = NULL;
-
- if (ops->rotate)
- fbcon_set_rotate(ops);
+ par->bmove = bit_bmove;
+ par->clear = bit_clear;
+ par->putcs = bit_putcs;
+ par->clear_margins = bit_clear_margins;
+ par->cursor = bit_cursor;
+ par->update_start = bit_update_start;
+ par->rotate_font = NULL;
+
+ if (par->rotate)
+ fbcon_set_rotate(par);
}
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 7453377f3433..8baad7ec1b85 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -200,27 +200,27 @@ static struct device *fbcon_device;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
static inline void fbcon_set_rotation(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
- ops->p->con_rotate < 4)
- ops->rotate = ops->p->con_rotate;
+ par->p->con_rotate < 4)
+ par->rotate = par->p->con_rotate;
else
- ops->rotate = 0;
+ par->rotate = 0;
}
static void fbcon_rotate(struct fb_info *info, u32 rotate)
{
- struct fbcon_ops *ops= info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_info *fb_info;
- if (!ops || ops->currcon == -1)
+ if (!par || par->currcon == -1)
return;
- fb_info = fbcon_info_from_console(ops->currcon);
+ fb_info = fbcon_info_from_console(par->currcon);
if (info == fb_info) {
- struct fbcon_display *p = &fb_display[ops->currcon];
+ struct fbcon_display *p = &fb_display[par->currcon];
if (rotate < 4)
p->con_rotate = rotate;
@@ -233,12 +233,12 @@ static void fbcon_rotate(struct fb_info *info, u32 rotate)
static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct vc_data *vc;
struct fbcon_display *p;
int i;
- if (!ops || ops->currcon < 0 || rotate > 3)
+ if (!par || par->currcon < 0 || rotate > 3)
return;
for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -256,9 +256,9 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
#else
static inline void fbcon_set_rotation(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- ops->rotate = FB_ROTATE_UR;
+ par->rotate = FB_ROTATE_UR;
}
static void fbcon_rotate(struct fb_info *info, u32 rotate)
@@ -274,9 +274,9 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
static int fbcon_get_rotate(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- return (ops) ? ops->rotate : 0;
+ return (par) ? par->rotate : 0;
}
static bool fbcon_skip_panic(struct fb_info *info)
@@ -286,10 +286,10 @@ static bool fbcon_skip_panic(struct fb_info *info)
static inline bool fbcon_is_active(struct vc_data *vc, struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
return info->state == FBINFO_STATE_RUNNING &&
- vc->vc_mode == KD_TEXT && !ops->graphics && !fbcon_skip_panic(info);
+ vc->vc_mode == KD_TEXT && !par->graphics && !fbcon_skip_panic(info);
}
static int get_color(struct vc_data *vc, struct fb_info *info,
@@ -371,7 +371,7 @@ static int get_bg_color(struct vc_data *vc, struct fb_info *info, u16 c)
static void fb_flashcursor(struct work_struct *work)
{
- struct fbcon_ops *ops = container_of(work, struct fbcon_ops, cursor_work.work);
+ struct fbcon_par *par = container_of(work, struct fbcon_par, cursor_work.work);
struct fb_info *info;
struct vc_data *vc = NULL;
int c;
@@ -386,10 +386,10 @@ static void fb_flashcursor(struct work_struct *work)
return;
/* protected by console_lock */
- info = ops->info;
+ info = par->info;
- if (ops->currcon != -1)
- vc = vc_cons[ops->currcon].d;
+ if (par->currcon != -1)
+ vc = vc_cons[par->currcon].d;
if (!vc || !con_is_visible(vc) ||
fbcon_info_from_console(vc->vc_num) != info ||
@@ -399,30 +399,30 @@ static void fb_flashcursor(struct work_struct *work)
}
c = scr_readw((u16 *) vc->vc_pos);
- enable = ops->cursor_flash && !ops->cursor_state.enable;
- ops->cursor(vc, info, enable,
+ enable = par->cursor_flash && !par->cursor_state.enable;
+ par->cursor(vc, info, enable,
get_fg_color(vc, info, c),
get_bg_color(vc, info, c));
console_unlock();
- queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
- ops->cur_blink_jiffies);
+ queue_delayed_work(system_power_efficient_wq, &par->cursor_work,
+ par->cur_blink_jiffies);
}
static void fbcon_add_cursor_work(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
if (fbcon_cursor_blink)
- queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
- ops->cur_blink_jiffies);
+ queue_delayed_work(system_power_efficient_wq, &par->cursor_work,
+ par->cur_blink_jiffies);
}
static void fbcon_del_cursor_work(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- cancel_delayed_work_sync(&ops->cursor_work);
+ cancel_delayed_work_sync(&par->cursor_work);
}
#ifndef MODULE
@@ -582,7 +582,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
int cols, int rows, int new_cols, int new_rows)
{
/* Need to make room for the logo */
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int cnt, erase = vc->vc_video_erase_char, step;
unsigned short *save = NULL, *r, *q;
int logo_height;
@@ -598,7 +598,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
*/
if (fb_get_color_depth(&info->var, &info->fix) == 1)
erase &= ~0x400;
- logo_height = fb_prepare_logo(info, ops->rotate);
+ logo_height = fb_prepare_logo(info, par->rotate);
logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height);
q = (unsigned short *) (vc->vc_origin +
vc->vc_size_row * rows);
@@ -670,15 +670,15 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
#ifdef CONFIG_FB_TILEBLITTING
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- ops->p = &fb_display[vc->vc_num];
+ par->p = &fb_display[vc->vc_num];
if ((info->flags & FBINFO_MISC_TILEBLITTING))
fbcon_set_tileops(vc, info);
else {
fbcon_set_rotation(info);
- fbcon_set_bitops(ops);
+ fbcon_set_bitops(par);
}
}
@@ -695,12 +695,12 @@ static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
#else
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
info->flags &= ~FBINFO_MISC_TILEBLITTING;
- ops->p = &fb_display[vc->vc_num];
+ par->p = &fb_display[vc->vc_num];
fbcon_set_rotation(info);
- fbcon_set_bitops(ops);
+ fbcon_set_bitops(par);
}
static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
@@ -720,13 +720,13 @@ static void fbcon_release(struct fb_info *info)
module_put(info->fbops->owner);
if (info->fbcon_par) {
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
fbcon_del_cursor_work(info);
- kfree(ops->cursor_state.mask);
- kfree(ops->cursor_data);
- kfree(ops->cursor_src);
- kfree(ops->fontbuffer);
+ kfree(par->cursor_state.mask);
+ kfree(par->cursor_data);
+ kfree(par->cursor_src);
+ kfree(par->fontbuffer);
kfree(info->fbcon_par);
info->fbcon_par = NULL;
}
@@ -734,7 +734,7 @@ static void fbcon_release(struct fb_info *info)
static int fbcon_open(struct fb_info *info)
{
- struct fbcon_ops *ops;
+ struct fbcon_par *par;
if (!try_module_get(info->fbops->owner))
return -ENODEV;
@@ -748,16 +748,16 @@ static int fbcon_open(struct fb_info *info)
}
unlock_fb_info(info);
- ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
- if (!ops) {
+ par = kzalloc(sizeof(*par), GFP_KERNEL);
+ if (!par) {
fbcon_release(info);
return -ENOMEM;
}
- INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor);
- ops->info = info;
- info->fbcon_par = ops;
- ops->cur_blink_jiffies = HZ / 5;
+ INIT_DELAYED_WORK(&par->cursor_work, fb_flashcursor);
+ par->info = info;
+ info->fbcon_par = par;
+ par->cur_blink_jiffies = HZ / 5;
return 0;
}
@@ -804,12 +804,12 @@ static void con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
int unit, int show_logo)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int ret;
- ops->currcon = fg_console;
+ par->currcon = fg_console;
- if (info->fbops->fb_set_par && !ops->initialized) {
+ if (info->fbops->fb_set_par && !par->initialized) {
ret = info->fbops->fb_set_par(info);
if (ret)
@@ -818,8 +818,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
"error code %d\n", ret);
}
- ops->initialized = true;
- ops->graphics = 0;
+ par->initialized = true;
+ par->graphics = 0;
fbcon_set_disp(info, &info->var, unit);
if (show_logo) {
@@ -956,7 +956,7 @@ static const char *fbcon_startup(void)
struct vc_data *vc = vc_cons[fg_console].d;
const struct font_desc *font = NULL;
struct fb_info *info = NULL;
- struct fbcon_ops *ops;
+ struct fbcon_par *par;
int rows, cols;
/*
@@ -976,10 +976,10 @@ static const char *fbcon_startup(void)
if (fbcon_open(info))
return NULL;
- ops = info->fbcon_par;
- ops->currcon = -1;
- ops->graphics = 1;
- ops->cur_rotate = -1;
+ par = info->fbcon_par;
+ par->currcon = -1;
+ par->graphics = 1;
+ par->cur_rotate = -1;
p->con_rotate = initial_rotation;
if (p->con_rotate == -1)
@@ -1002,8 +1002,8 @@ static const char *fbcon_startup(void)
vc->vc_font.charcount = font->charcount;
}
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(par->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
@@ -1021,7 +1021,7 @@ static const char *fbcon_startup(void)
static void fbcon_init(struct vc_data *vc, bool init)
{
struct fb_info *info;
- struct fbcon_ops *ops;
+ struct fbcon_par *par;
struct vc_data **default_mode = vc->vc_display_fg;
struct vc_data *svc = *default_mode;
struct fbcon_display *t, *p = &fb_display[vc->vc_num];
@@ -1096,8 +1096,8 @@ static void fbcon_init(struct vc_data *vc, bool init)
if (!*vc->uni_pagedict_loc)
con_copy_unimap(vc, svc);
- ops = info->fbcon_par;
- ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
+ par = info->fbcon_par;
+ par->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
p->con_rotate = initial_rotation;
if (p->con_rotate == -1)
@@ -1109,8 +1109,8 @@ static void fbcon_init(struct vc_data *vc, bool init)
cols = vc->vc_cols;
rows = vc->vc_rows;
- new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ new_cols = FBCON_SWAP(par->rotate, info->var.xres, info->var.yres);
+ new_rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
new_cols /= vc->vc_font.width;
new_rows /= vc->vc_font.height;
@@ -1122,7 +1122,7 @@ static void fbcon_init(struct vc_data *vc, bool init)
* We need to do it in fbcon_init() to prevent screen corruption.
*/
if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
- if (info->fbops->fb_set_par && !ops->initialized) {
+ if (info->fbops->fb_set_par && !par->initialized) {
ret = info->fbops->fb_set_par(info);
if (ret)
@@ -1131,10 +1131,10 @@ static void fbcon_init(struct vc_data *vc, bool init)
"error code %d\n", ret);
}
- ops->initialized = true;
+ par->initialized = true;
}
- ops->graphics = 0;
+ par->graphics = 0;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
if ((info->flags & FBINFO_HWACCEL_COPYAREA) &&
@@ -1158,12 +1158,12 @@ static void fbcon_init(struct vc_data *vc, bool init)
if (logo)
fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
- if (ops->rotate_font && ops->rotate_font(info, vc)) {
- ops->rotate = FB_ROTATE_UR;
+ if (par->rotate_font && par->rotate_font(info, vc)) {
+ par->rotate = FB_ROTATE_UR;
set_blitting_type(vc, info);
}
- ops->p = &fb_display[fg_console];
+ par->p = &fb_display[fg_console];
}
static void fbcon_free_font(struct fbcon_display *p)
@@ -1201,7 +1201,7 @@ static void fbcon_deinit(struct vc_data *vc)
{
struct fbcon_display *p = &fb_display[vc->vc_num];
struct fb_info *info;
- struct fbcon_ops *ops;
+ struct fbcon_par *par;
int idx;
fbcon_free_font(p);
@@ -1215,15 +1215,15 @@ static void fbcon_deinit(struct vc_data *vc)
if (!info)
goto finished;
- ops = info->fbcon_par;
+ par = info->fbcon_par;
- if (!ops)
+ if (!par)
goto finished;
if (con_is_visible(vc))
fbcon_del_cursor_work(info);
- ops->initialized = false;
+ par->initialized = false;
finished:
fbcon_free_font(p);
@@ -1270,7 +1270,7 @@ static void __fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
unsigned int height, unsigned int width)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int fg, bg;
struct fbcon_display *p = &fb_display[vc->vc_num];
u_int y_break;
@@ -1285,7 +1285,7 @@ static void __fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
vc->vc_top = 0;
/*
* If the font dimensions are not an integral of the display
- * dimensions then the ops->clear below won't end up clearing
+ * dimensions then the par->clear below won't end up clearing
* the margins. Call clear_margins here in case the logo
* bitmap stretched into the margin area.
*/
@@ -1299,11 +1299,10 @@ static void __fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
y_break = p->vrows - p->yscroll;
if (sy < y_break && sy + height - 1 >= y_break) {
u_int b = y_break - sy;
- ops->clear(vc, info, real_y(p, sy), sx, b, width, fg, bg);
- ops->clear(vc, info, real_y(p, sy + b), sx, height - b,
- width, fg, bg);
+ par->clear(vc, info, real_y(p, sy), sx, b, width, fg, bg);
+ par->clear(vc, info, real_y(p, sy + b), sx, height - b, width, fg, bg);
} else
- ops->clear(vc, info, real_y(p, sy), sx, height, width, fg, bg);
+ par->clear(vc, info, real_y(p, sy), sx, height, width, fg, bg);
}
static void fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx,
@@ -1317,10 +1316,10 @@ static void fbcon_putcs(struct vc_data *vc, const u16 *s, unsigned int count,
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
struct fbcon_display *p = &fb_display[vc->vc_num];
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
if (fbcon_is_active(vc, info))
- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
+ par->putcs(vc, info, s, count, real_y(p, ypos), xpos,
get_fg_color(vc, info, scr_readw(s)),
get_bg_color(vc, info, scr_readw(s)));
}
@@ -1328,19 +1327,19 @@ static void fbcon_putcs(struct vc_data *vc, const u16 *s, unsigned int count,
static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
if (fbcon_is_active(vc, info))
- ops->clear_margins(vc, info, margin_color, bottom_only);
+ par->clear_margins(vc, info, margin_color, bottom_only);
}
static void fbcon_cursor(struct vc_data *vc, bool enable)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int c = scr_readw((u16 *) vc->vc_pos);
- ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
+ par->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
if (!fbcon_is_active(vc, info) || vc->vc_deccm != 1)
return;
@@ -1350,12 +1349,12 @@ static void fbcon_cursor(struct vc_data *vc, bool enable)
else
fbcon_add_cursor_work(info);
- ops->cursor_flash = enable;
+ par->cursor_flash = enable;
- if (!ops->cursor)
+ if (!par->cursor)
return;
- ops->cursor(vc, info, enable,
+ par->cursor(vc, info, enable,
get_fg_color(vc, info, c),
get_bg_color(vc, info, c));
}
@@ -1370,7 +1369,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
struct fbcon_display *p, *t;
struct vc_data **default_mode, *vc;
struct vc_data *svc;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int rows, cols;
unsigned long ret = 0;
@@ -1403,7 +1402,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
var->yoffset = info->var.yoffset;
var->xoffset = info->var.xoffset;
fb_set_var(info, var);
- ops->var = info->var;
+ par->var = info->var;
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (vc->vc_font.charcount == 256) {
@@ -1419,8 +1418,8 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
if (!*vc->uni_pagedict_loc)
con_copy_unimap(vc, svc);
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(par->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
ret = vc_resize(vc, cols, rows);
@@ -1432,16 +1431,16 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
static __inline__ void ywrap_up(struct vc_data *vc, int count)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
p->yscroll += count;
if (p->yscroll >= p->vrows) /* Deal with wrap */
p->yscroll -= p->vrows;
- ops->var.xoffset = 0;
- ops->var.yoffset = p->yscroll * vc->vc_font.height;
- ops->var.vmode |= FB_VMODE_YWRAP;
- ops->update_start(info);
+ par->var.xoffset = 0;
+ par->var.yoffset = p->yscroll * vc->vc_font.height;
+ par->var.vmode |= FB_VMODE_YWRAP;
+ par->update_start(info);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
scrollback_max = scrollback_phys_max;
@@ -1451,16 +1450,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
static __inline__ void ywrap_down(struct vc_data *vc, int count)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
p->yscroll -= count;
if (p->yscroll < 0) /* Deal with wrap */
p->yscroll += p->vrows;
- ops->var.xoffset = 0;
- ops->var.yoffset = p->yscroll * vc->vc_font.height;
- ops->var.vmode |= FB_VMODE_YWRAP;
- ops->update_start(info);
+ par->var.xoffset = 0;
+ par->var.yoffset = p->yscroll * vc->vc_font.height;
+ par->var.vmode |= FB_VMODE_YWRAP;
+ par->update_start(info);
scrollback_max -= count;
if (scrollback_max < 0)
scrollback_max = 0;
@@ -1471,19 +1470,19 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
struct fbcon_display *p = &fb_display[vc->vc_num];
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
p->yscroll += count;
if (p->yscroll > p->vrows - vc->vc_rows) {
- ops->bmove(vc, info, p->vrows - vc->vc_rows,
+ par->bmove(vc, info, p->vrows - vc->vc_rows,
0, 0, 0, vc->vc_rows, vc->vc_cols);
p->yscroll -= p->vrows - vc->vc_rows;
}
- ops->var.xoffset = 0;
- ops->var.yoffset = p->yscroll * vc->vc_font.height;
- ops->var.vmode &= ~FB_VMODE_YWRAP;
- ops->update_start(info);
+ par->var.xoffset = 0;
+ par->var.yoffset = p->yscroll * vc->vc_font.height;
+ par->var.vmode &= ~FB_VMODE_YWRAP;
+ par->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
@@ -1494,7 +1493,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
p->yscroll += count;
@@ -1504,10 +1503,10 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
}
- ops->var.xoffset = 0;
- ops->var.yoffset = p->yscroll * vc->vc_font.height;
- ops->var.vmode &= ~FB_VMODE_YWRAP;
- ops->update_start(info);
+ par->var.xoffset = 0;
+ par->var.yoffset = p->yscroll * vc->vc_font.height;
+ par->var.vmode &= ~FB_VMODE_YWRAP;
+ par->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max += count;
if (scrollback_max > scrollback_phys_max)
@@ -1519,19 +1518,19 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
struct fbcon_display *p = &fb_display[vc->vc_num];
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
p->yscroll -= count;
if (p->yscroll < 0) {
- ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
+ par->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
0, vc->vc_rows, vc->vc_cols);
p->yscroll += p->vrows - vc->vc_rows;
}
- ops->var.xoffset = 0;
- ops->var.yoffset = p->yscroll * vc->vc_font.height;
- ops->var.vmode &= ~FB_VMODE_YWRAP;
- ops->update_start(info);
+ par->var.xoffset = 0;
+ par->var.yoffset = p->yscroll * vc->vc_font.height;
+ par->var.vmode &= ~FB_VMODE_YWRAP;
+ par->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max -= count;
if (scrollback_max < 0)
@@ -1542,7 +1541,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
p->yscroll -= count;
@@ -1552,10 +1551,10 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
}
- ops->var.xoffset = 0;
- ops->var.yoffset = p->yscroll * vc->vc_font.height;
- ops->var.vmode &= ~FB_VMODE_YWRAP;
- ops->update_start(info);
+ par->var.xoffset = 0;
+ par->var.yoffset = p->yscroll * vc->vc_font.height;
+ par->var.vmode &= ~FB_VMODE_YWRAP;
+ par->update_start(info);
fbcon_clear_margins(vc, 1);
scrollback_max -= count;
if (scrollback_max < 0)
@@ -1604,7 +1603,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
unsigned short *d = (unsigned short *)
(vc->vc_origin + vc->vc_size_row * line);
unsigned short *s = d + offset;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
while (count--) {
unsigned short *start = s;
@@ -1617,8 +1616,8 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
if (c == scr_readw(d)) {
if (s > start) {
- ops->bmove(vc, info, line + ycount, x,
- line, x, 1, s-start);
+ par->bmove(vc, info, line + ycount, x,
+ line, x, 1, s - start);
x += s - start + 1;
start = s + 1;
} else {
@@ -1633,8 +1632,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
d++;
} while (s < le);
if (s > start)
- ops->bmove(vc, info, line + ycount, x, line, x, 1,
- s-start);
+ par->bmove(vc, info, line + ycount, x, line, x, 1, s - start);
console_conditional_schedule();
if (ycount > 0)
line++;
@@ -1705,7 +1703,7 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy,
int dy, int dx, int height, int width, u_int y_break)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u_int b;
if (sy < y_break && sy + height > y_break) {
@@ -1739,8 +1737,7 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy,
}
return;
}
- ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
- height, width);
+ par->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
}
static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
@@ -1967,15 +1964,13 @@ static void updatescrollmode_accel(struct fbcon_display *p,
struct vc_data *vc)
{
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int cap = info->flags;
u16 t = 0;
- int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
- info->fix.xpanstep);
- int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
- int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
- int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
- info->var.xres_virtual);
+ int ypan = FBCON_SWAP(par->rotate, info->fix.ypanstep, info->fix.xpanstep);
+ int ywrap = FBCON_SWAP(par->rotate, info->fix.ywrapstep, t);
+ int yres = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
+ int vyres = FBCON_SWAP(par->rotate, info->var.yres_virtual, info->var.xres_virtual);
int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
divides(ypan, vc->vc_font.height) && vyres > yres;
int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
@@ -2008,11 +2003,10 @@ static void updatescrollmode(struct fbcon_display *p,
struct fb_info *info,
struct vc_data *vc)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int fh = vc->vc_font.height;
- int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
- int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
- info->var.xres_virtual);
+ int yres = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
+ int vyres = FBCON_SWAP(par->rotate, info->var.yres_virtual, info->var.xres_virtual);
p->vrows = vyres/fh;
if (yres > (fh * (vc->vc_rows + 1)))
@@ -2031,7 +2025,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
unsigned int height, bool from_user)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var = info->var;
int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
@@ -2054,12 +2048,10 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
return -EINVAL;
}
- virt_w = FBCON_SWAP(ops->rotate, width, height);
- virt_h = FBCON_SWAP(ops->rotate, height, width);
- virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
- vc->vc_font.height);
- virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
- vc->vc_font.width);
+ virt_w = FBCON_SWAP(par->rotate, width, height);
+ virt_h = FBCON_SWAP(par->rotate, height, width);
+ virt_fw = FBCON_SWAP(par->rotate, vc->vc_font.width, vc->vc_font.height);
+ virt_fh = FBCON_SWAP(par->rotate, vc->vc_font.height, vc->vc_font.width);
var.xres = virt_w * virt_fw;
var.yres = virt_h * virt_fh;
x_diff = info->var.xres - var.xres;
@@ -2085,7 +2077,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
fb_set_var(info, &var);
}
var_to_display(p, &info->var, info);
- ops->var = info->var;
+ par->var = info->var;
}
updatescrollmode(p, info, vc);
return 0;
@@ -2094,13 +2086,13 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
static bool fbcon_switch(struct vc_data *vc)
{
struct fb_info *info, *old_info = NULL;
- struct fbcon_ops *ops;
+ struct fbcon_par *par;
struct fbcon_display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var;
int i, ret, prev_console;
info = fbcon_info_from_console(vc->vc_num);
- ops = info->fbcon_par;
+ par = info->fbcon_par;
if (logo_shown >= 0) {
struct vc_data *conp2 = vc_cons[logo_shown].d;
@@ -2111,7 +2103,7 @@ static bool fbcon_switch(struct vc_data *vc)
logo_shown = FBCON_LOGO_CANSHOW;
}
- prev_console = ops->currcon;
+ prev_console = par->currcon;
if (prev_console != -1)
old_info = fbcon_info_from_console(prev_console);
/*
@@ -2124,9 +2116,9 @@ static bool fbcon_switch(struct vc_data *vc)
*/
fbcon_for_each_registered_fb(i) {
if (fbcon_registered_fb[i]->fbcon_par) {
- struct fbcon_ops *o = fbcon_registered_fb[i]->fbcon_par;
+ struct fbcon_par *par = fbcon_registered_fb[i]->fbcon_par;
- o->currcon = vc->vc_num;
+ par->currcon = vc->vc_num;
}
}
memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -2140,7 +2132,7 @@ static bool fbcon_switch(struct vc_data *vc)
info->var.activate = var.activate;
var.vmode |= info->var.vmode & ~FB_VMODE_MASK;
fb_set_var(info, &var);
- ops->var = info->var;
+ par->var = info->var;
if (old_info != NULL && (old_info != info ||
info->flags & FBINFO_MISC_ALWAYS_SETPAR)) {
@@ -2157,17 +2149,16 @@ static bool fbcon_switch(struct vc_data *vc)
fbcon_del_cursor_work(old_info);
}
- if (!fbcon_is_active(vc, info) ||
- ops->blank_state != FB_BLANK_UNBLANK)
+ if (!fbcon_is_active(vc, info) || par->blank_state != FB_BLANK_UNBLANK)
fbcon_del_cursor_work(info);
else
fbcon_add_cursor_work(info);
set_blitting_type(vc, info);
- ops->cursor_reset = 1;
+ par->cursor_reset = 1;
- if (ops->rotate_font && ops->rotate_font(info, vc)) {
- ops->rotate = FB_ROTATE_UR;
+ if (par->rotate_font && par->rotate_font(info, vc)) {
+ par->rotate = FB_ROTATE_UR;
set_blitting_type(vc, info);
}
@@ -2198,8 +2189,8 @@ static bool fbcon_switch(struct vc_data *vc)
scrollback_current = 0;
if (fbcon_is_active(vc, info)) {
- ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
- ops->update_start(info);
+ par->var.xoffset = par->var.yoffset = p->yscroll = 0;
+ par->update_start(info);
}
fbcon_set_palette(vc, color_table);
@@ -2208,7 +2199,7 @@ static bool fbcon_switch(struct vc_data *vc)
if (logo_shown == FBCON_LOGO_DRAW) {
logo_shown = fg_console;
- fb_show_logo(info, ops->rotate);
+ fb_show_logo(info, par->rotate);
update_region(vc,
vc->vc_origin + vc->vc_size_row * vc->vc_top,
vc->vc_size_row * (vc->vc_bottom -
@@ -2237,27 +2228,27 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank,
bool mode_switch)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
if (mode_switch) {
struct fb_var_screeninfo var = info->var;
- ops->graphics = 1;
+ par->graphics = 1;
if (!blank) {
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE |
FB_ACTIVATE_KD_TEXT;
fb_set_var(info, &var);
- ops->graphics = 0;
- ops->var = info->var;
+ par->graphics = 0;
+ par->var = info->var;
}
}
if (fbcon_is_active(vc, info)) {
- if (ops->blank_state != blank) {
- ops->blank_state = blank;
+ if (par->blank_state != blank) {
+ par->blank_state = blank;
fbcon_cursor(vc, !blank);
- ops->cursor_flash = (!blank);
+ par->cursor_flash = (!blank);
if (fb_blank(info, blank))
fbcon_generic_blank(vc, info, blank);
@@ -2267,8 +2258,7 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank,
update_screen(vc);
}
- if (mode_switch || !fbcon_is_active(vc, info) ||
- ops->blank_state != FB_BLANK_UNBLANK)
+ if (mode_switch || !fbcon_is_active(vc, info) || par->blank_state != FB_BLANK_UNBLANK)
fbcon_del_cursor_work(info);
else
fbcon_add_cursor_work(info);
@@ -2279,10 +2269,10 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank,
static void fbcon_debug_enter(struct vc_data *vc)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- ops->save_graphics = ops->graphics;
- ops->graphics = 0;
+ par->save_graphics = par->graphics;
+ par->graphics = 0;
if (info->fbops->fb_debug_enter)
info->fbops->fb_debug_enter(info);
fbcon_set_palette(vc, color_table);
@@ -2291,9 +2281,9 @@ static void fbcon_debug_enter(struct vc_data *vc)
static void fbcon_debug_leave(struct vc_data *vc)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- ops->graphics = ops->save_graphics;
+ par->graphics = par->save_graphics;
if (info->fbops->fb_debug_leave)
info->fbops->fb_debug_leave(info);
}
@@ -2428,7 +2418,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
const u8 * data, int userfont)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
int resize, ret, old_userfont, old_width, old_height, old_charcount;
u8 *old_data = vc->vc_font.data;
@@ -2454,8 +2444,8 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
if (resize) {
int cols, rows;
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(par->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
cols /= w;
rows /= h;
ret = vc_resize(vc, cols, rows);
@@ -2654,11 +2644,11 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
void fbcon_suspended(struct fb_info *info)
{
struct vc_data *vc = NULL;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- if (!ops || ops->currcon < 0)
+ if (!par || par->currcon < 0)
return;
- vc = vc_cons[ops->currcon].d;
+ vc = vc_cons[par->currcon].d;
/* Clear cursor, restore saved data */
fbcon_cursor(vc, false);
@@ -2667,27 +2657,27 @@ void fbcon_suspended(struct fb_info *info)
void fbcon_resumed(struct fb_info *info)
{
struct vc_data *vc;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- if (!ops || ops->currcon < 0)
+ if (!par || par->currcon < 0)
return;
- vc = vc_cons[ops->currcon].d;
+ vc = vc_cons[par->currcon].d;
update_screen(vc);
}
static void fbcon_modechanged(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct vc_data *vc;
struct fbcon_display *p;
int rows, cols;
- if (!ops || ops->currcon < 0)
+ if (!par || par->currcon < 0)
return;
- vc = vc_cons[ops->currcon].d;
+ vc = vc_cons[par->currcon].d;
if (vc->vc_mode != KD_TEXT ||
- fbcon_info_from_console(ops->currcon) != info)
+ fbcon_info_from_console(par->currcon) != info)
return;
p = &fb_display[vc->vc_num];
@@ -2695,8 +2685,8 @@ static void fbcon_modechanged(struct fb_info *info)
if (con_is_visible(vc)) {
var_to_display(p, &info->var, info);
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(par->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
@@ -2705,8 +2695,8 @@ static void fbcon_modechanged(struct fb_info *info)
scrollback_current = 0;
if (fbcon_is_active(vc, info)) {
- ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
- ops->update_start(info);
+ par->var.xoffset = par->var.yoffset = p->yscroll = 0;
+ par->update_start(info);
}
fbcon_set_palette(vc, color_table);
@@ -2716,12 +2706,12 @@ static void fbcon_modechanged(struct fb_info *info)
static void fbcon_set_all_vcs(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct vc_data *vc;
struct fbcon_display *p;
int i, rows, cols, fg = -1;
- if (!ops || ops->currcon < 0)
+ if (!par || par->currcon < 0)
return;
for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -2738,8 +2728,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
p = &fb_display[vc->vc_num];
set_blitting_type(vc, info);
var_to_display(p, &info->var, info);
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(par->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(par->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
@@ -2762,13 +2752,13 @@ EXPORT_SYMBOL(fbcon_update_vcs);
/* let fbcon check if it supports a new screen resolution */
int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct vc_data *vc;
unsigned int i;
WARN_CONSOLE_UNLOCKED();
- if (!ops)
+ if (!par)
return 0;
/* prevent setting a screen size which is smaller than font size */
@@ -3066,15 +3056,14 @@ int fbcon_fb_registered(struct fb_info *info)
void fbcon_fb_blanked(struct fb_info *info, int blank)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct vc_data *vc;
- if (!ops || ops->currcon < 0)
+ if (!par || par->currcon < 0)
return;
- vc = vc_cons[ops->currcon].d;
- if (vc->vc_mode != KD_TEXT ||
- fbcon_info_from_console(ops->currcon) != info)
+ vc = vc_cons[par->currcon].d;
+ if (vc->vc_mode != KD_TEXT || fbcon_info_from_console(par->currcon) != info)
return;
if (con_is_visible(vc)) {
@@ -3083,7 +3072,7 @@ void fbcon_fb_blanked(struct fb_info *info, int blank)
else
do_unblank_screen(0);
}
- ops->blank_state = blank;
+ par->blank_state = blank;
}
void fbcon_new_modelist(struct fb_info *info)
@@ -3273,7 +3262,7 @@ static ssize_t cursor_blink_show(struct device *device,
struct device_attribute *attr, char *buf)
{
struct fb_info *info;
- struct fbcon_ops *ops;
+ struct fbcon_par *par;
int idx, blink = -1;
console_lock();
@@ -3283,12 +3272,12 @@ static ssize_t cursor_blink_show(struct device *device,
goto err;
info = fbcon_registered_fb[idx];
- ops = info->fbcon_par;
+ par = info->fbcon_par;
- if (!ops)
+ if (!par)
goto err;
- blink = delayed_work_pending(&ops->cursor_work);
+ blink = delayed_work_pending(&par->cursor_work);
err:
console_unlock();
return sysfs_emit(buf, "%d\n", blink);
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 7e21c8b33669..b22c33e278c1 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -50,7 +50,7 @@ struct fbcon_display {
const struct fb_videomode *mode;
};
-struct fbcon_ops {
+struct fbcon_par {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
@@ -185,7 +185,7 @@ static inline u_short fb_scrollmode(struct fbcon_display *fb)
#ifdef CONFIG_FB_TILEBLITTING
extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
#endif
-extern void fbcon_set_bitops(struct fbcon_ops *ops);
+extern void fbcon_set_bitops(struct fbcon_par *par);
extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
#define FBCON_ATTRIBUTE_UNDERLINE 1
@@ -224,7 +224,7 @@ static inline int get_attribute(struct fb_info *info, u16 c)
(i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
-extern void fbcon_set_rotate(struct fbcon_ops *ops);
+extern void fbcon_set_rotate(struct fbcon_par *par);
#else
#define fbcon_set_rotate(x) do {} while(0)
#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 89ef4ba7e867..2ba8ec4c3e2b 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -63,9 +63,9 @@ static void ccw_update_attr(u8 *dst, u8 *src, int attribute,
static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_copyarea area;
- u32 vyres = GETVYRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
area.sx = sy * vc->vc_font.height;
area.sy = vyres - ((sx + width) * vc->vc_font.width);
@@ -80,9 +80,9 @@ static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width, int fg, int bg)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_fillrect region;
- u32 vyres = GETVYRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
region.color = bg;
region.dx = sy * vc->vc_font.height;
@@ -99,13 +99,13 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = (vc->vc_font.height + 7) >> 3;
u8 *src;
while (cnt--) {
- src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
+ src = par->fontbuffer + (scr_readw(s--) & charmask) * cellsize;
if (attr) {
ccw_update_attr(buf, src, attr, vc);
@@ -130,7 +130,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
int fg, int bg)
{
struct fb_image image;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u32 width = (vc->vc_font.height + 7)/8;
u32 cellsize = width * vc->vc_font.width;
u32 maxcnt = info->pixmap.size/cellsize;
@@ -139,9 +139,9 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
u32 cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
- u32 vyres = GETVYRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
- if (!ops->fontbuffer)
+ if (!par->fontbuffer)
return;
image.fg_color = fg;
@@ -221,28 +221,28 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
int fg, int bg)
{
struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.height + 7) >> 3, c;
- int y = real_y(ops->p, vc->state.y);
+ int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
char *src;
- u32 vyres = GETVYRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
- if (!ops->fontbuffer)
+ if (!par->fontbuffer)
return;
cursor.set = 0;
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
+ src = par->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
- if (ops->cursor_state.image.data != src ||
- ops->cursor_reset) {
- ops->cursor_state.image.data = src;
- cursor.set |= FB_CUR_SETIMAGE;
+ if (par->cursor_state.image.data != src ||
+ par->cursor_reset) {
+ par->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
@@ -251,49 +251,49 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
dst = kmalloc_array(w, vc->vc_font.width, GFP_ATOMIC);
if (!dst)
return;
- kfree(ops->cursor_data);
- ops->cursor_data = dst;
+ kfree(par->cursor_data);
+ par->cursor_data = dst;
ccw_update_attr(dst, src, attribute, vc);
src = dst;
}
- if (ops->cursor_state.image.fg_color != fg ||
- ops->cursor_state.image.bg_color != bg ||
- ops->cursor_reset) {
- ops->cursor_state.image.fg_color = fg;
- ops->cursor_state.image.bg_color = bg;
+ if (par->cursor_state.image.fg_color != fg ||
+ par->cursor_state.image.bg_color != bg ||
+ par->cursor_reset) {
+ par->cursor_state.image.fg_color = fg;
+ par->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
- if (ops->cursor_state.image.height != vc->vc_font.width ||
- ops->cursor_state.image.width != vc->vc_font.height ||
- ops->cursor_reset) {
- ops->cursor_state.image.height = vc->vc_font.width;
- ops->cursor_state.image.width = vc->vc_font.height;
+ if (par->cursor_state.image.height != vc->vc_font.width ||
+ par->cursor_state.image.width != vc->vc_font.height ||
+ par->cursor_reset) {
+ par->cursor_state.image.height = vc->vc_font.width;
+ par->cursor_state.image.width = vc->vc_font.height;
cursor.set |= FB_CUR_SETSIZE;
}
dx = y * vc->vc_font.height;
dy = vyres - ((vc->state.x + 1) * vc->vc_font.width);
- if (ops->cursor_state.image.dx != dx ||
- ops->cursor_state.image.dy != dy ||
- ops->cursor_reset) {
- ops->cursor_state.image.dx = dx;
- ops->cursor_state.image.dy = dy;
+ if (par->cursor_state.image.dx != dx ||
+ par->cursor_state.image.dy != dy ||
+ par->cursor_reset) {
+ par->cursor_state.image.dx = dx;
+ par->cursor_state.image.dy = dy;
cursor.set |= FB_CUR_SETPOS;
}
- if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
- ops->cursor_reset) {
- ops->cursor_state.hot.x = cursor.hot.y = 0;
+ if (par->cursor_state.hot.x || par->cursor_state.hot.y ||
+ par->cursor_reset) {
+ par->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
- vc->vc_cursor_type != ops->p->cursor_shape ||
- ops->cursor_state.mask == NULL ||
- ops->cursor_reset) {
+ vc->vc_cursor_type != par->p->cursor_shape ||
+ par->cursor_state.mask == NULL ||
+ par->cursor_reset) {
char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
GFP_ATOMIC);
int cur_height, size, i = 0;
@@ -309,13 +309,13 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
return;
}
- kfree(ops->cursor_state.mask);
- ops->cursor_state.mask = mask;
+ kfree(par->cursor_state.mask);
+ par->cursor_state.mask = mask;
- ops->p->cursor_shape = vc->vc_cursor_type;
+ par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
- switch (CUR_SIZE(ops->p->cursor_shape)) {
+ switch (CUR_SIZE(par->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;
@@ -348,19 +348,19 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
kfree(tmp);
}
- ops->cursor_state.enable = enable && !use_sw;
+ par->cursor_state.enable = enable && !use_sw;
cursor.image.data = src;
- cursor.image.fg_color = ops->cursor_state.image.fg_color;
- cursor.image.bg_color = ops->cursor_state.image.bg_color;
- cursor.image.dx = ops->cursor_state.image.dx;
- cursor.image.dy = ops->cursor_state.image.dy;
- cursor.image.height = ops->cursor_state.image.height;
- cursor.image.width = ops->cursor_state.image.width;
- cursor.hot.x = ops->cursor_state.hot.x;
- cursor.hot.y = ops->cursor_state.hot.y;
- cursor.mask = ops->cursor_state.mask;
- cursor.enable = ops->cursor_state.enable;
+ cursor.image.fg_color = par->cursor_state.image.fg_color;
+ cursor.image.bg_color = par->cursor_state.image.bg_color;
+ cursor.image.dx = par->cursor_state.image.dx;
+ cursor.image.dy = par->cursor_state.image.dy;
+ cursor.image.height = par->cursor_state.image.height;
+ cursor.image.width = par->cursor_state.image.width;
+ cursor.hot.x = par->cursor_state.hot.x;
+ cursor.hot.y = par->cursor_state.hot.y;
+ cursor.mask = par->cursor_state.mask;
+ cursor.enable = par->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
@@ -370,32 +370,32 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
if (err)
soft_cursor(info, &cursor);
- ops->cursor_reset = 0;
+ par->cursor_reset = 0;
}
static int ccw_update_start(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u32 yoffset;
- u32 vyres = GETVYRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
int err;
- yoffset = (vyres - info->var.yres) - ops->var.xoffset;
- ops->var.xoffset = ops->var.yoffset;
- ops->var.yoffset = yoffset;
- err = fb_pan_display(info, &ops->var);
- ops->var.xoffset = info->var.xoffset;
- ops->var.yoffset = info->var.yoffset;
- ops->var.vmode = info->var.vmode;
+ yoffset = (vyres - info->var.yres) - par->var.xoffset;
+ par->var.xoffset = par->var.yoffset;
+ par->var.yoffset = yoffset;
+ err = fb_pan_display(info, &par->var);
+ par->var.xoffset = info->var.xoffset;
+ par->var.yoffset = info->var.yoffset;
+ par->var.vmode = info->var.vmode;
return err;
}
-void fbcon_rotate_ccw(struct fbcon_ops *ops)
+void fbcon_rotate_ccw(struct fbcon_par *par)
{
- ops->bmove = ccw_bmove;
- ops->clear = ccw_clear;
- ops->putcs = ccw_putcs;
- ops->clear_margins = ccw_clear_margins;
- ops->cursor = ccw_cursor;
- ops->update_start = ccw_update_start;
+ par->bmove = ccw_bmove;
+ par->clear = ccw_clear;
+ par->putcs = ccw_putcs;
+ par->clear_margins = ccw_clear_margins;
+ par->cursor = ccw_cursor;
+ par->update_start = ccw_update_start;
}
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index b9dac7940fb7..4bd22d5ee5f4 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -48,9 +48,9 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute,
static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_copyarea area;
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vxres = GETVXRES(par->p, info);
area.sx = vxres - ((sy + height) * vc->vc_font.height);
area.sy = sx * vc->vc_font.width;
@@ -65,9 +65,9 @@ static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width, int fg, int bg)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_fillrect region;
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vxres = GETVXRES(par->p, info);
region.color = bg;
region.dx = vxres - ((sy + height) * vc->vc_font.height);
@@ -84,13 +84,13 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = (vc->vc_font.height + 7) >> 3;
u8 *src;
while (cnt--) {
- src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
+ src = par->fontbuffer + (scr_readw(s++) & charmask) * cellsize;
if (attr) {
cw_update_attr(buf, src, attr, vc);
@@ -115,7 +115,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
int fg, int bg)
{
struct fb_image image;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u32 width = (vc->vc_font.height + 7)/8;
u32 cellsize = width * vc->vc_font.width;
u32 maxcnt = info->pixmap.size/cellsize;
@@ -124,9 +124,9 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
u32 cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vxres = GETVXRES(par->p, info);
- if (!ops->fontbuffer)
+ if (!par->fontbuffer)
return;
image.fg_color = fg;
@@ -204,28 +204,28 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
int fg, int bg)
{
struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.height + 7) >> 3, c;
- int y = real_y(ops->p, vc->state.y);
+ int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
char *src;
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vxres = GETVXRES(par->p, info);
- if (!ops->fontbuffer)
+ if (!par->fontbuffer)
return;
cursor.set = 0;
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
+ src = par->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
- if (ops->cursor_state.image.data != src ||
- ops->cursor_reset) {
- ops->cursor_state.image.data = src;
- cursor.set |= FB_CUR_SETIMAGE;
+ if (par->cursor_state.image.data != src ||
+ par->cursor_reset) {
+ par->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
@@ -234,49 +234,49 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
dst = kmalloc_array(w, vc->vc_font.width, GFP_ATOMIC);
if (!dst)
return;
- kfree(ops->cursor_data);
- ops->cursor_data = dst;
+ kfree(par->cursor_data);
+ par->cursor_data = dst;
cw_update_attr(dst, src, attribute, vc);
src = dst;
}
- if (ops->cursor_state.image.fg_color != fg ||
- ops->cursor_state.image.bg_color != bg ||
- ops->cursor_reset) {
- ops->cursor_state.image.fg_color = fg;
- ops->cursor_state.image.bg_color = bg;
+ if (par->cursor_state.image.fg_color != fg ||
+ par->cursor_state.image.bg_color != bg ||
+ par->cursor_reset) {
+ par->cursor_state.image.fg_color = fg;
+ par->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
- if (ops->cursor_state.image.height != vc->vc_font.width ||
- ops->cursor_state.image.width != vc->vc_font.height ||
- ops->cursor_reset) {
- ops->cursor_state.image.height = vc->vc_font.width;
- ops->cursor_state.image.width = vc->vc_font.height;
+ if (par->cursor_state.image.height != vc->vc_font.width ||
+ par->cursor_state.image.width != vc->vc_font.height ||
+ par->cursor_reset) {
+ par->cursor_state.image.height = vc->vc_font.width;
+ par->cursor_state.image.width = vc->vc_font.height;
cursor.set |= FB_CUR_SETSIZE;
}
dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
dy = vc->state.x * vc->vc_font.width;
- if (ops->cursor_state.image.dx != dx ||
- ops->cursor_state.image.dy != dy ||
- ops->cursor_reset) {
- ops->cursor_state.image.dx = dx;
- ops->cursor_state.image.dy = dy;
+ if (par->cursor_state.image.dx != dx ||
+ par->cursor_state.image.dy != dy ||
+ par->cursor_reset) {
+ par->cursor_state.image.dx = dx;
+ par->cursor_state.image.dy = dy;
cursor.set |= FB_CUR_SETPOS;
}
- if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
- ops->cursor_reset) {
- ops->cursor_state.hot.x = cursor.hot.y = 0;
+ if (par->cursor_state.hot.x || par->cursor_state.hot.y ||
+ par->cursor_reset) {
+ par->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
- vc->vc_cursor_type != ops->p->cursor_shape ||
- ops->cursor_state.mask == NULL ||
- ops->cursor_reset) {
+ vc->vc_cursor_type != par->p->cursor_shape ||
+ par->cursor_state.mask == NULL ||
+ par->cursor_reset) {
char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
GFP_ATOMIC);
int cur_height, size, i = 0;
@@ -292,13 +292,13 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
return;
}
- kfree(ops->cursor_state.mask);
- ops->cursor_state.mask = mask;
+ kfree(par->cursor_state.mask);
+ par->cursor_state.mask = mask;
- ops->p->cursor_shape = vc->vc_cursor_type;
+ par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
- switch (CUR_SIZE(ops->p->cursor_shape)) {
+ switch (CUR_SIZE(par->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;
@@ -331,19 +331,19 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
kfree(tmp);
}
- ops->cursor_state.enable = enable && !use_sw;
+ par->cursor_state.enable = enable && !use_sw;
cursor.image.data = src;
- cursor.image.fg_color = ops->cursor_state.image.fg_color;
- cursor.image.bg_color = ops->cursor_state.image.bg_color;
- cursor.image.dx = ops->cursor_state.image.dx;
- cursor.image.dy = ops->cursor_state.image.dy;
- cursor.image.height = ops->cursor_state.image.height;
- cursor.image.width = ops->cursor_state.image.width;
- cursor.hot.x = ops->cursor_state.hot.x;
- cursor.hot.y = ops->cursor_state.hot.y;
- cursor.mask = ops->cursor_state.mask;
- cursor.enable = ops->cursor_state.enable;
+ cursor.image.fg_color = par->cursor_state.image.fg_color;
+ cursor.image.bg_color = par->cursor_state.image.bg_color;
+ cursor.image.dx = par->cursor_state.image.dx;
+ cursor.image.dy = par->cursor_state.image.dy;
+ cursor.image.height = par->cursor_state.image.height;
+ cursor.image.width = par->cursor_state.image.width;
+ cursor.hot.x = par->cursor_state.hot.x;
+ cursor.hot.y = par->cursor_state.hot.y;
+ cursor.mask = par->cursor_state.mask;
+ cursor.enable = par->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
@@ -353,32 +353,32 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
if (err)
soft_cursor(info, &cursor);
- ops->cursor_reset = 0;
+ par->cursor_reset = 0;
}
static int cw_update_start(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
- u32 vxres = GETVXRES(ops->p, info);
+ struct fbcon_par *par = info->fbcon_par;
+ u32 vxres = GETVXRES(par->p, info);
u32 xoffset;
int err;
- xoffset = vxres - (info->var.xres + ops->var.yoffset);
- ops->var.yoffset = ops->var.xoffset;
- ops->var.xoffset = xoffset;
- err = fb_pan_display(info, &ops->var);
- ops->var.xoffset = info->var.xoffset;
- ops->var.yoffset = info->var.yoffset;
- ops->var.vmode = info->var.vmode;
+ xoffset = vxres - (info->var.xres + par->var.yoffset);
+ par->var.yoffset = par->var.xoffset;
+ par->var.xoffset = xoffset;
+ err = fb_pan_display(info, &par->var);
+ par->var.xoffset = info->var.xoffset;
+ par->var.yoffset = info->var.yoffset;
+ par->var.vmode = info->var.vmode;
return err;
}
-void fbcon_rotate_cw(struct fbcon_ops *ops)
+void fbcon_rotate_cw(struct fbcon_par *par)
{
- ops->bmove = cw_bmove;
- ops->clear = cw_clear;
- ops->putcs = cw_putcs;
- ops->clear_margins = cw_clear_margins;
- ops->cursor = cw_cursor;
- ops->update_start = cw_update_start;
+ par->bmove = cw_bmove;
+ par->clear = cw_clear;
+ par->putcs = cw_putcs;
+ par->clear_margins = cw_clear_margins;
+ par->cursor = cw_cursor;
+ par->update_start = cw_update_start;
}
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index ec3c883400f7..a3f507825eed 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -20,32 +20,36 @@
static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int len, err = 0;
int s_cellsize, d_cellsize, i;
const u8 *src;
u8 *dst;
- if (vc->vc_font.data == ops->fontdata &&
- ops->p->con_rotate == ops->cur_rotate)
+ if (vc->vc_font.data == par->fontdata &&
+ par->p->con_rotate == par->cur_rotate)
goto finished;
- src = ops->fontdata = vc->vc_font.data;
- ops->cur_rotate = ops->p->con_rotate;
+ src = par->fontdata = vc->vc_font.data;
+ par->cur_rotate = par->p->con_rotate;
len = vc->vc_font.charcount;
s_cellsize = ((vc->vc_font.width + 7)/8) *
vc->vc_font.height;
d_cellsize = s_cellsize;
- if (ops->rotate == FB_ROTATE_CW ||
- ops->rotate == FB_ROTATE_CCW)
+ if (par->rotate == FB_ROTATE_CW ||
+ par->rotate == FB_ROTATE_CCW)
d_cellsize = ((vc->vc_font.height + 7)/8) *
vc->vc_font.width;
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
- if (ops->fd_size < d_cellsize * len) {
+ if (par->fd_size < d_cellsize * len) {
+ kfree(par->fontbuffer);
+ par->fontbuffer = NULL;
+ par->fd_size = 0;
+
dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
if (dst == NULL) {
@@ -53,15 +57,14 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
goto finished;
}
- ops->fd_size = d_cellsize * len;
- kfree(ops->fontbuffer);
- ops->fontbuffer = dst;
+ par->fd_size = d_cellsize * len;
+ par->fontbuffer = dst;
}
- dst = ops->fontbuffer;
- memset(dst, 0, ops->fd_size);
+ dst = par->fontbuffer;
+ memset(dst, 0, par->fd_size);
- switch (ops->rotate) {
+ switch (par->rotate) {
case FB_ROTATE_UD:
for (i = len; i--; ) {
rotate_ud(src, dst, vc->vc_font.width,
@@ -93,19 +96,19 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
return err;
}
-void fbcon_set_rotate(struct fbcon_ops *ops)
+void fbcon_set_rotate(struct fbcon_par *par)
{
- ops->rotate_font = fbcon_rotate_font;
+ par->rotate_font = fbcon_rotate_font;
- switch(ops->rotate) {
+ switch (par->rotate) {
case FB_ROTATE_CW:
- fbcon_rotate_cw(ops);
+ fbcon_rotate_cw(par);
break;
case FB_ROTATE_UD:
- fbcon_rotate_ud(ops);
+ fbcon_rotate_ud(par);
break;
case FB_ROTATE_CCW:
- fbcon_rotate_ccw(ops);
+ fbcon_rotate_ccw(par);
break;
}
}
diff --git a/drivers/video/fbdev/core/fbcon_rotate.h b/drivers/video/fbdev/core/fbcon_rotate.h
index 01cbe303b8a2..48305e1a0763 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.h
+++ b/drivers/video/fbdev/core/fbcon_rotate.h
@@ -90,7 +90,7 @@ static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
}
}
-extern void fbcon_rotate_cw(struct fbcon_ops *ops);
-extern void fbcon_rotate_ud(struct fbcon_ops *ops);
-extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
+extern void fbcon_rotate_cw(struct fbcon_par *par);
+extern void fbcon_rotate_ud(struct fbcon_par *par);
+extern void fbcon_rotate_ccw(struct fbcon_par *par);
#endif
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index 0af7913a2abd..14b40e2bf323 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -48,10 +48,10 @@ static void ud_update_attr(u8 *dst, u8 *src, int attribute,
static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_copyarea area;
- u32 vyres = GETVYRES(ops->p, info);
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
+ u32 vxres = GETVXRES(par->p, info);
area.sy = vyres - ((sy + height) * vc->vc_font.height);
area.sx = vxres - ((sx + width) * vc->vc_font.width);
@@ -66,10 +66,10 @@ static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width, int fg, int bg)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
struct fb_fillrect region;
- u32 vyres = GETVYRES(ops->p, info);
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
+ u32 vxres = GETVXRES(par->p, info);
region.color = bg;
region.dy = vyres - ((sy + height) * vc->vc_font.height);
@@ -86,13 +86,13 @@ static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
while (cnt--) {
- src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
+ src = par->fontbuffer + (scr_readw(s--) & charmask) * cellsize;
if (attr) {
ud_update_attr(buf, src, attr, vc);
@@ -119,7 +119,7 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,
struct fb_image *image, u8 *buf,
u8 *dst)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
u32 shift_low = 0, mod = vc->vc_font.width % 8;
u32 shift_high = 8;
@@ -127,7 +127,7 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,
u8 *src;
while (cnt--) {
- src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
+ src = par->fontbuffer + (scr_readw(s--) & charmask) * cellsize;
if (attr) {
ud_update_attr(buf, src, attr, vc);
@@ -152,7 +152,7 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
int fg, int bg)
{
struct fb_image image;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
u32 width = (vc->vc_font.width + 7)/8;
u32 cellsize = width * vc->vc_font.height;
u32 maxcnt = info->pixmap.size/cellsize;
@@ -161,10 +161,10 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
u32 attribute = get_attribute(info, scr_readw(s));
u8 *dst, *buf = NULL;
- u32 vyres = GETVYRES(ops->p, info);
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
+ u32 vxres = GETVXRES(par->p, info);
- if (!ops->fontbuffer)
+ if (!par->fontbuffer)
return;
image.fg_color = fg;
@@ -251,29 +251,29 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
int fg, int bg)
{
struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.width + 7) >> 3, c;
- int y = real_y(ops->p, vc->state.y);
+ int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
char *src;
- u32 vyres = GETVYRES(ops->p, info);
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
+ u32 vxres = GETVXRES(par->p, info);
- if (!ops->fontbuffer)
+ if (!par->fontbuffer)
return;
cursor.set = 0;
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
+ src = par->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
- if (ops->cursor_state.image.data != src ||
- ops->cursor_reset) {
- ops->cursor_state.image.data = src;
- cursor.set |= FB_CUR_SETIMAGE;
+ if (par->cursor_state.image.data != src ||
+ par->cursor_reset) {
+ par->cursor_state.image.data = src;
+ cursor.set |= FB_CUR_SETIMAGE;
}
if (attribute) {
@@ -282,49 +282,49 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
dst = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
if (!dst)
return;
- kfree(ops->cursor_data);
- ops->cursor_data = dst;
+ kfree(par->cursor_data);
+ par->cursor_data = dst;
ud_update_attr(dst, src, attribute, vc);
src = dst;
}
- if (ops->cursor_state.image.fg_color != fg ||
- ops->cursor_state.image.bg_color != bg ||
- ops->cursor_reset) {
- ops->cursor_state.image.fg_color = fg;
- ops->cursor_state.image.bg_color = bg;
+ if (par->cursor_state.image.fg_color != fg ||
+ par->cursor_state.image.bg_color != bg ||
+ par->cursor_reset) {
+ par->cursor_state.image.fg_color = fg;
+ par->cursor_state.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
- if (ops->cursor_state.image.height != vc->vc_font.height ||
- ops->cursor_state.image.width != vc->vc_font.width ||
- ops->cursor_reset) {
- ops->cursor_state.image.height = vc->vc_font.height;
- ops->cursor_state.image.width = vc->vc_font.width;
+ if (par->cursor_state.image.height != vc->vc_font.height ||
+ par->cursor_state.image.width != vc->vc_font.width ||
+ par->cursor_reset) {
+ par->cursor_state.image.height = vc->vc_font.height;
+ par->cursor_state.image.width = vc->vc_font.width;
cursor.set |= FB_CUR_SETSIZE;
}
dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
dx = vxres - ((vc->state.x * vc->vc_font.width) + vc->vc_font.width);
- if (ops->cursor_state.image.dx != dx ||
- ops->cursor_state.image.dy != dy ||
- ops->cursor_reset) {
- ops->cursor_state.image.dx = dx;
- ops->cursor_state.image.dy = dy;
+ if (par->cursor_state.image.dx != dx ||
+ par->cursor_state.image.dy != dy ||
+ par->cursor_reset) {
+ par->cursor_state.image.dx = dx;
+ par->cursor_state.image.dy = dy;
cursor.set |= FB_CUR_SETPOS;
}
- if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
- ops->cursor_reset) {
- ops->cursor_state.hot.x = cursor.hot.y = 0;
+ if (par->cursor_state.hot.x || par->cursor_state.hot.y ||
+ par->cursor_reset) {
+ par->cursor_state.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if (cursor.set & FB_CUR_SETSIZE ||
- vc->vc_cursor_type != ops->p->cursor_shape ||
- ops->cursor_state.mask == NULL ||
- ops->cursor_reset) {
+ vc->vc_cursor_type != par->p->cursor_shape ||
+ par->cursor_state.mask == NULL ||
+ par->cursor_reset) {
char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
int cur_height, size, i = 0;
u8 msk = 0xff;
@@ -332,13 +332,13 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
if (!mask)
return;
- kfree(ops->cursor_state.mask);
- ops->cursor_state.mask = mask;
+ kfree(par->cursor_state.mask);
+ par->cursor_state.mask = mask;
- ops->p->cursor_shape = vc->vc_cursor_type;
+ par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
- switch (CUR_SIZE(ops->p->cursor_shape)) {
+ switch (CUR_SIZE(par->p->cursor_shape)) {
case CUR_NONE:
cur_height = 0;
break;
@@ -371,19 +371,19 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
mask[i++] = ~msk;
}
- ops->cursor_state.enable = enable && !use_sw;
+ par->cursor_state.enable = enable && !use_sw;
cursor.image.data = src;
- cursor.image.fg_color = ops->cursor_state.image.fg_color;
- cursor.image.bg_color = ops->cursor_state.image.bg_color;
- cursor.image.dx = ops->cursor_state.image.dx;
- cursor.image.dy = ops->cursor_state.image.dy;
- cursor.image.height = ops->cursor_state.image.height;
- cursor.image.width = ops->cursor_state.image.width;
- cursor.hot.x = ops->cursor_state.hot.x;
- cursor.hot.y = ops->cursor_state.hot.y;
- cursor.mask = ops->cursor_state.mask;
- cursor.enable = ops->cursor_state.enable;
+ cursor.image.fg_color = par->cursor_state.image.fg_color;
+ cursor.image.bg_color = par->cursor_state.image.bg_color;
+ cursor.image.dx = par->cursor_state.image.dx;
+ cursor.image.dy = par->cursor_state.image.dy;
+ cursor.image.height = par->cursor_state.image.height;
+ cursor.image.width = par->cursor_state.image.width;
+ cursor.hot.x = par->cursor_state.hot.x;
+ cursor.hot.y = par->cursor_state.hot.y;
+ cursor.mask = par->cursor_state.mask;
+ cursor.enable = par->cursor_state.enable;
cursor.image.depth = 1;
cursor.rop = ROP_XOR;
@@ -393,36 +393,36 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
if (err)
soft_cursor(info, &cursor);
- ops->cursor_reset = 0;
+ par->cursor_reset = 0;
}
static int ud_update_start(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int xoffset, yoffset;
- u32 vyres = GETVYRES(ops->p, info);
- u32 vxres = GETVXRES(ops->p, info);
+ u32 vyres = GETVYRES(par->p, info);
+ u32 vxres = GETVXRES(par->p, info);
int err;
- xoffset = vxres - info->var.xres - ops->var.xoffset;
- yoffset = vyres - info->var.yres - ops->var.yoffset;
+ xoffset = vxres - info->var.xres - par->var.xoffset;
+ yoffset = vyres - info->var.yres - par->var.yoffset;
if (yoffset < 0)
yoffset += vyres;
- ops->var.xoffset = xoffset;
- ops->var.yoffset = yoffset;
- err = fb_pan_display(info, &ops->var);
- ops->var.xoffset = info->var.xoffset;
- ops->var.yoffset = info->var.yoffset;
- ops->var.vmode = info->var.vmode;
+ par->var.xoffset = xoffset;
+ par->var.yoffset = yoffset;
+ err = fb_pan_display(info, &par->var);
+ par->var.xoffset = info->var.xoffset;
+ par->var.yoffset = info->var.yoffset;
+ par->var.vmode = info->var.vmode;
return err;
}
-void fbcon_rotate_ud(struct fbcon_ops *ops)
+void fbcon_rotate_ud(struct fbcon_par *par)
{
- ops->bmove = ud_bmove;
- ops->clear = ud_clear;
- ops->putcs = ud_putcs;
- ops->clear_margins = ud_clear_margins;
- ops->cursor = ud_cursor;
- ops->update_start = ud_update_start;
+ par->bmove = ud_bmove;
+ par->clear = ud_clear;
+ par->putcs = ud_putcs;
+ par->clear_margins = ud_clear_margins;
+ par->cursor = ud_cursor;
+ par->update_start = ud_update_start;
}
diff --git a/drivers/video/fbdev/core/softcursor.c b/drivers/video/fbdev/core/softcursor.c
index 29e5b21cf373..900788c05915 100644
--- a/drivers/video/fbdev/core/softcursor.c
+++ b/drivers/video/fbdev/core/softcursor.c
@@ -21,7 +21,7 @@
int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
unsigned int scan_align = info->pixmap.scan_align - 1;
unsigned int buf_align = info->pixmap.buf_align - 1;
unsigned int i, size, dsize, s_pitch, d_pitch;
@@ -34,19 +34,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
s_pitch = (cursor->image.width + 7) >> 3;
dsize = s_pitch * cursor->image.height;
- if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
- kfree(ops->cursor_src);
- ops->cursor_size = dsize + sizeof(struct fb_image);
+ if (dsize + sizeof(struct fb_image) != par->cursor_size) {
+ kfree(par->cursor_src);
+ par->cursor_size = dsize + sizeof(struct fb_image);
- ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
- if (!ops->cursor_src) {
- ops->cursor_size = 0;
+ par->cursor_src = kmalloc(par->cursor_size, GFP_ATOMIC);
+ if (!par->cursor_src) {
+ par->cursor_size = 0;
return -ENOMEM;
}
}
- src = ops->cursor_src + sizeof(struct fb_image);
- image = (struct fb_image *)ops->cursor_src;
+ src = par->cursor_src + sizeof(struct fb_image);
+ image = (struct fb_image *)par->cursor_src;
*image = cursor->image;
d_pitch = (s_pitch + scan_align) & ~scan_align;
diff --git a/drivers/video/fbdev/core/tileblit.c b/drivers/video/fbdev/core/tileblit.c
index d342b90c42b7..4428f2bcd3f8 100644
--- a/drivers/video/fbdev/core/tileblit.c
+++ b/drivers/video/fbdev/core/tileblit.c
@@ -151,34 +151,34 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
static int tile_update_start(struct fb_info *info)
{
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
int err;
- err = fb_pan_display(info, &ops->var);
- ops->var.xoffset = info->var.xoffset;
- ops->var.yoffset = info->var.yoffset;
- ops->var.vmode = info->var.vmode;
+ err = fb_pan_display(info, &par->var);
+ par->var.xoffset = info->var.xoffset;
+ par->var.yoffset = info->var.yoffset;
+ par->var.vmode = info->var.vmode;
return err;
}
void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info)
{
struct fb_tilemap map;
- struct fbcon_ops *ops = info->fbcon_par;
+ struct fbcon_par *par = info->fbcon_par;
- ops->bmove = tile_bmove;
- ops->clear = tile_clear;
- ops->putcs = tile_putcs;
- ops->clear_margins = tile_clear_margins;
- ops->cursor = tile_cursor;
- ops->update_start = tile_update_start;
+ par->bmove = tile_bmove;
+ par->clear = tile_clear;
+ par->putcs = tile_putcs;
+ par->clear_margins = tile_clear_margins;
+ par->cursor = tile_cursor;
+ par->update_start = tile_update_start;
- if (ops->p) {
+ if (par->p) {
map.width = vc->vc_font.width;
map.height = vc->vc_font.height;
map.depth = 1;
map.length = vc->vc_font.charcount;
- map.data = ops->p->fontdata;
+ map.data = par->p->fontdata;
info->tileops->fb_settile(info, &map);
}
}
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index bfe253c2849a..c0691e93e0a5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3025,7 +3025,7 @@ static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info,
return -ENOMEM;
space_args.total_spaces = 0;
- dest = kmalloc(alloc_size, GFP_KERNEL);
+ dest = kzalloc(alloc_size, GFP_KERNEL);
if (!dest)
return -ENOMEM;
dest_orig = dest;
@@ -3081,7 +3081,8 @@ static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info,
user_dest = (struct btrfs_ioctl_space_info __user *)
(arg + sizeof(struct btrfs_ioctl_space_args));
- if (copy_to_user(user_dest, dest_orig, alloc_size))
+ if (copy_to_user(user_dest, dest_orig,
+ space_args.total_spaces * sizeof(*dest_orig)))
ret = -EFAULT;
kfree(dest_orig);
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
index a815308e2db9..b3ff2e1da89b 100644
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -275,11 +275,9 @@ static int create_space_info_sub_group(struct btrfs_space_info *parent, u64 flag
sub_group->parent = parent;
sub_group->subgroup_id = id;
- ret = btrfs_sysfs_add_space_info_type(fs_info, sub_group);
- if (ret) {
- kfree(sub_group);
+ ret = btrfs_sysfs_add_space_info_type(sub_group);
+ if (ret)
parent->sub_group[index] = NULL;
- }
return ret;
}
@@ -309,7 +307,7 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags)
goto out_free;
}
- ret = btrfs_sysfs_add_space_info_type(info, space_info);
+ ret = btrfs_sysfs_add_space_info_type(space_info);
if (ret)
return ret;
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index 81f52c1f55ce..d66681ce2b3d 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -1981,13 +1981,12 @@ static const char *alloc_name(struct btrfs_space_info *space_info)
* Create a sysfs entry for a space info type at path
* /sys/fs/btrfs/UUID/allocation/TYPE
*/
-int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
- struct btrfs_space_info *space_info)
+int btrfs_sysfs_add_space_info_type(struct btrfs_space_info *space_info)
{
int ret;
ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype,
- fs_info->space_info_kobj, "%s",
+ space_info->fs_info->space_info_kobj, "%s",
alloc_name(space_info));
if (ret) {
kobject_put(&space_info->kobj);
diff --git a/fs/btrfs/sysfs.h b/fs/btrfs/sysfs.h
index 0f94ae923210..05498e5346c3 100644
--- a/fs/btrfs/sysfs.h
+++ b/fs/btrfs/sysfs.h
@@ -37,8 +37,7 @@ void __cold btrfs_exit_sysfs(void);
int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info);
void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
void btrfs_sysfs_add_block_group_type(struct btrfs_block_group *cache);
-int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
- struct btrfs_space_info *space_info);
+int btrfs_sysfs_add_space_info_type(struct btrfs_space_info *space_info);
void btrfs_sysfs_remove_space_info(struct btrfs_space_info *space_info);
void btrfs_sysfs_update_devid(struct btrfs_device *device);
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 6fe6f7fcf83d..d90238195090 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -949,6 +949,7 @@ bool damon_initialized(void);
int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive);
int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);
bool damon_is_running(struct damon_ctx *ctx);
+int damon_kdamond_pid(struct damon_ctx *ctx);
int damon_call(struct damon_ctx *ctx, struct damon_call_control *control);
int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control);
diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h
index 7964db96e41a..0a3bcd1718f3 100644
--- a/include/linux/fprobe.h
+++ b/include/linux/fprobe.h
@@ -7,6 +7,7 @@
#include <linux/ftrace.h>
#include <linux/rcupdate.h>
#include <linux/refcount.h>
+#include <linux/rhashtable.h>
#include <linux/slab.h>
struct fprobe;
@@ -26,7 +27,7 @@ typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
* @fp: The fprobe which owns this.
*/
struct fprobe_hlist_node {
- struct hlist_node hlist;
+ struct rhlist_head hlist;
unsigned long addr;
struct fprobe *fp;
};
diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h
index d82b7a9b0658..9848aeab2786 100644
--- a/include/linux/sched/ext.h
+++ b/include/linux/sched/ext.h
@@ -228,6 +228,7 @@ struct scx_task_group {
u64 bw_period_us;
u64 bw_quota_us;
u64 bw_burst_us;
+ bool idle;
#endif
};
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index d17ff07779de..b768f43f0fd1 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -696,9 +696,10 @@ static void io_zcrx_return_niov_freelist(struct net_iov *niov)
{
struct io_zcrx_area *area = io_zcrx_iov_to_area(niov);
- spin_lock_bh(&area->freelist_lock);
+ guard(spinlock_bh)(&area->freelist_lock);
+ if (WARN_ON_ONCE(area->free_count >= area->nia.num_niovs))
+ return;
area->freelist[area->free_count++] = net_iov_idx(niov);
- spin_unlock_bh(&area->freelist_lock);
}
static void io_zcrx_return_niov(struct net_iov *niov)
@@ -829,7 +830,8 @@ static void io_zcrx_refill_slow(struct page_pool *pp, struct io_zcrx_ifq *ifq)
{
struct io_zcrx_area *area = ifq->area;
- spin_lock_bh(&area->freelist_lock);
+ guard(spinlock_bh)(&area->freelist_lock);
+
while (area->free_count && pp->alloc.count < PP_ALLOC_CACHE_REFILL) {
struct net_iov *niov = __io_zcrx_get_free_niov(area);
netmem_ref netmem = net_iov_to_netmem(niov);
@@ -838,7 +840,6 @@ static void io_zcrx_refill_slow(struct page_pool *pp, struct io_zcrx_ifq *ifq)
io_zcrx_sync_for_device(pp, niov);
net_mp_netmem_place_in_cache(pp, netmem);
}
- spin_unlock_bh(&area->freelist_lock);
}
static netmem_ref io_pp_zc_alloc_netmems(struct page_pool *pp, gfp_t gfp)
@@ -975,10 +976,10 @@ static struct net_iov *io_alloc_fallback_niov(struct io_zcrx_ifq *ifq)
if (area->mem.is_dmabuf)
return NULL;
- spin_lock_bh(&area->freelist_lock);
- if (area->free_count)
- niov = __io_zcrx_get_free_niov(area);
- spin_unlock_bh(&area->freelist_lock);
+ scoped_guard(spinlock_bh, &area->freelist_lock) {
+ if (area->free_count)
+ niov = __io_zcrx_get_free_niov(area);
+ }
if (niov)
page_pool_fragment_netmem(net_iov_to_netmem(niov), 1);
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index ee031ba877d9..177bbf31116d 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -3118,6 +3118,7 @@ void scx_tg_init(struct task_group *tg)
tg->scx.weight = CGROUP_WEIGHT_DFL;
tg->scx.bw_period_us = default_bw_period_us();
tg->scx.bw_quota_us = RUNTIME_INF;
+ tg->scx.idle = false;
}
int scx_tg_online(struct task_group *tg)
@@ -3250,9 +3251,10 @@ void scx_cgroup_cancel_attach(struct cgroup_taskset *tset)
void scx_group_set_weight(struct task_group *tg, unsigned long weight)
{
- struct scx_sched *sch = scx_root;
+ struct scx_sched *sch;
percpu_down_read(&scx_cgroup_ops_rwsem);
+ sch = scx_root;
if (scx_cgroup_enabled && SCX_HAS_OP(sch, cgroup_set_weight) &&
tg->scx.weight != weight)
@@ -3266,15 +3268,28 @@ void scx_group_set_weight(struct task_group *tg, unsigned long weight)
void scx_group_set_idle(struct task_group *tg, bool idle)
{
- /* TODO: Implement ops->cgroup_set_idle() */
+ struct scx_sched *sch;
+
+ percpu_down_read(&scx_cgroup_ops_rwsem);
+ sch = scx_root;
+
+ if (scx_cgroup_enabled && SCX_HAS_OP(sch, cgroup_set_idle))
+ SCX_CALL_OP(sch, SCX_KF_UNLOCKED, cgroup_set_idle, NULL,
+ tg_cgrp(tg), idle);
+
+ /* Update the task group's idle state */
+ tg->scx.idle = idle;
+
+ percpu_up_read(&scx_cgroup_ops_rwsem);
}
void scx_group_set_bandwidth(struct task_group *tg,
u64 period_us, u64 quota_us, u64 burst_us)
{
- struct scx_sched *sch = scx_root;
+ struct scx_sched *sch;
percpu_down_read(&scx_cgroup_ops_rwsem);
+ sch = scx_root;
if (scx_cgroup_enabled && SCX_HAS_OP(sch, cgroup_set_bandwidth) &&
(tg->scx.bw_period_us != period_us ||
@@ -5126,6 +5141,7 @@ static void sched_ext_ops__cgroup_move(struct task_struct *p, struct cgroup *fro
static void sched_ext_ops__cgroup_cancel_move(struct task_struct *p, struct cgroup *from, struct cgroup *to) {}
static void sched_ext_ops__cgroup_set_weight(struct cgroup *cgrp, u32 weight) {}
static void sched_ext_ops__cgroup_set_bandwidth(struct cgroup *cgrp, u64 period_us, u64 quota_us, u64 burst_us) {}
+static void sched_ext_ops__cgroup_set_idle(struct cgroup *cgrp, bool idle) {}
#endif
static void sched_ext_ops__cpu_online(s32 cpu) {}
static void sched_ext_ops__cpu_offline(s32 cpu) {}
@@ -5164,6 +5180,7 @@ static struct sched_ext_ops __bpf_ops_sched_ext_ops = {
.cgroup_cancel_move = sched_ext_ops__cgroup_cancel_move,
.cgroup_set_weight = sched_ext_ops__cgroup_set_weight,
.cgroup_set_bandwidth = sched_ext_ops__cgroup_set_bandwidth,
+ .cgroup_set_idle = sched_ext_ops__cgroup_set_idle,
#endif
.cpu_online = sched_ext_ops__cpu_online,
.cpu_offline = sched_ext_ops__cpu_offline,
diff --git a/kernel/sched/ext_internal.h b/kernel/sched/ext_internal.h
index 8039a750490f..5b2dd105fa92 100644
--- a/kernel/sched/ext_internal.h
+++ b/kernel/sched/ext_internal.h
@@ -697,12 +697,23 @@ struct sched_ext_ops {
* 2_500_000. @cgrp is entitled to 2.5 CPUs. @burst_us can be
* interpreted in the same fashion and specifies how much @cgrp can
* burst temporarily. The specific control mechanism and thus the
- * interpretation of @period_us and burstiness is upto to the BPF
+ * interpretation of @period_us and burstiness is up to the BPF
* scheduler.
*/
void (*cgroup_set_bandwidth)(struct cgroup *cgrp,
u64 period_us, u64 quota_us, u64 burst_us);
+ /**
+ * @cgroup_set_idle: A cgroup's idle state is being changed
+ * @cgrp: cgroup whose idle state is being updated
+ * @idle: whether the cgroup is entering or exiting idle state
+ *
+ * Update @cgrp's idle state to @idle. This callback is invoked when
+ * a cgroup transitions between idle and non-idle states, allowing the
+ * BPF scheduler to adjust its behavior accordingly.
+ */
+ void (*cgroup_set_idle)(struct cgroup *cgrp, bool idle);
+
#endif /* CONFIG_EXT_GROUP_SCHED */
/*
diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
index 43b27f07730c..8fa5bff2c26f 100644
--- a/kernel/trace/fprobe.c
+++ b/kernel/trace/fprobe.c
@@ -11,6 +11,7 @@
#include <linux/kprobes.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/rhashtable.h>
#include <linux/slab.h>
#include <linux/sort.h>
@@ -42,60 +43,74 @@
* - RCU hlist traversal under disabling preempt
*/
static struct hlist_head fprobe_table[FPROBE_TABLE_SIZE];
-static struct hlist_head fprobe_ip_table[FPROBE_IP_TABLE_SIZE];
+static struct rhltable fprobe_ip_table;
static DEFINE_MUTEX(fprobe_mutex);
-/*
- * Find first fprobe in the hlist. It will be iterated twice in the entry
- * probe, once for correcting the total required size, the second time is
- * calling back the user handlers.
- * Thus the hlist in the fprobe_table must be sorted and new probe needs to
- * be added *before* the first fprobe.
- */
-static struct fprobe_hlist_node *find_first_fprobe_node(unsigned long ip)
+static u32 fprobe_node_hashfn(const void *data, u32 len, u32 seed)
{
- struct fprobe_hlist_node *node;
- struct hlist_head *head;
+ return hash_ptr(*(unsigned long **)data, 32);
+}
- head = &fprobe_ip_table[hash_ptr((void *)ip, FPROBE_IP_HASH_BITS)];
- hlist_for_each_entry_rcu(node, head, hlist,
- lockdep_is_held(&fprobe_mutex)) {
- if (node->addr == ip)
- return node;
- }
- return NULL;
+static int fprobe_node_cmp(struct rhashtable_compare_arg *arg,
+ const void *ptr)
+{
+ unsigned long key = *(unsigned long *)arg->key;
+ const struct fprobe_hlist_node *n = ptr;
+
+ return n->addr != key;
}
-NOKPROBE_SYMBOL(find_first_fprobe_node);
+
+static u32 fprobe_node_obj_hashfn(const void *data, u32 len, u32 seed)
+{
+ const struct fprobe_hlist_node *n = data;
+
+ return hash_ptr((void *)n->addr, 32);
+}
+
+static const struct rhashtable_params fprobe_rht_params = {
+ .head_offset = offsetof(struct fprobe_hlist_node, hlist),
+ .key_offset = offsetof(struct fprobe_hlist_node, addr),
+ .key_len = sizeof_field(struct fprobe_hlist_node, addr),
+ .hashfn = fprobe_node_hashfn,
+ .obj_hashfn = fprobe_node_obj_hashfn,
+ .obj_cmpfn = fprobe_node_cmp,
+ .automatic_shrinking = true,
+};
/* Node insertion and deletion requires the fprobe_mutex */
-static void insert_fprobe_node(struct fprobe_hlist_node *node)
+static int insert_fprobe_node(struct fprobe_hlist_node *node, struct fprobe *fp)
{
- unsigned long ip = node->addr;
- struct fprobe_hlist_node *next;
- struct hlist_head *head;
+ int ret;
lockdep_assert_held(&fprobe_mutex);
- next = find_first_fprobe_node(ip);
- if (next) {
- hlist_add_before_rcu(&node->hlist, &next->hlist);
- return;
- }
- head = &fprobe_ip_table[hash_ptr((void *)ip, FPROBE_IP_HASH_BITS)];
- hlist_add_head_rcu(&node->hlist, head);
+ ret = rhltable_insert(&fprobe_ip_table, &node->hlist, fprobe_rht_params);
+ /* Set the fprobe pointer if insertion was successful. */
+ if (!ret)
+ WRITE_ONCE(node->fp, fp);
+ return ret;
}
/* Return true if there are synonims */
static bool delete_fprobe_node(struct fprobe_hlist_node *node)
{
+ bool ret;
+
lockdep_assert_held(&fprobe_mutex);
- /* Avoid double deleting */
+ /* Avoid double deleting and non-inserted nodes */
if (READ_ONCE(node->fp) != NULL) {
WRITE_ONCE(node->fp, NULL);
- hlist_del_rcu(&node->hlist);
+ rhltable_remove(&fprobe_ip_table, &node->hlist,
+ fprobe_rht_params);
}
- return !!find_first_fprobe_node(node->addr);
+
+ rcu_read_lock();
+ ret = !!rhltable_lookup(&fprobe_ip_table, &node->addr,
+ fprobe_rht_params);
+ rcu_read_unlock();
+
+ return ret;
}
/* Check existence of the fprobe */
@@ -244,12 +259,112 @@ static inline int __fprobe_kprobe_handler(unsigned long ip, unsigned long parent
return ret;
}
-static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
- struct ftrace_regs *fregs)
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+/* ftrace_ops callback, this processes fprobes which have only entry_handler. */
+static void fprobe_ftrace_entry(unsigned long ip, unsigned long parent_ip,
+ struct ftrace_ops *ops, struct ftrace_regs *fregs)
+{
+ struct fprobe_hlist_node *node;
+ struct rhlist_head *head, *pos;
+ struct fprobe *fp;
+ int bit;
+
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
+ if (bit < 0)
+ return;
+
+ /*
+ * ftrace_test_recursion_trylock() disables preemption, but
+ * rhltable_lookup() checks whether rcu_read_lcok is held.
+ * So we take rcu_read_lock() here.
+ */
+ rcu_read_lock();
+ head = rhltable_lookup(&fprobe_ip_table, &ip, fprobe_rht_params);
+
+ rhl_for_each_entry_rcu(node, pos, head, hlist) {
+ if (node->addr != ip)
+ break;
+ fp = READ_ONCE(node->fp);
+ if (unlikely(!fp || fprobe_disabled(fp) || fp->exit_handler))
+ continue;
+
+ if (fprobe_shared_with_kprobes(fp))
+ __fprobe_kprobe_handler(ip, parent_ip, fp, fregs, NULL);
+ else
+ __fprobe_handler(ip, parent_ip, fp, fregs, NULL);
+ }
+ rcu_read_unlock();
+ ftrace_test_recursion_unlock(bit);
+}
+NOKPROBE_SYMBOL(fprobe_ftrace_entry);
+
+static struct ftrace_ops fprobe_ftrace_ops = {
+ .func = fprobe_ftrace_entry,
+ .flags = FTRACE_OPS_FL_SAVE_REGS,
+};
+static int fprobe_ftrace_active;
+
+static int fprobe_ftrace_add_ips(unsigned long *addrs, int num)
+{
+ int ret;
+
+ lockdep_assert_held(&fprobe_mutex);
+
+ ret = ftrace_set_filter_ips(&fprobe_ftrace_ops, addrs, num, 0, 0);
+ if (ret)
+ return ret;
+
+ if (!fprobe_ftrace_active) {
+ ret = register_ftrace_function(&fprobe_ftrace_ops);
+ if (ret) {
+ ftrace_free_filter(&fprobe_ftrace_ops);
+ return ret;
+ }
+ }
+ fprobe_ftrace_active++;
+ return 0;
+}
+
+static void fprobe_ftrace_remove_ips(unsigned long *addrs, int num)
+{
+ lockdep_assert_held(&fprobe_mutex);
+
+ fprobe_ftrace_active--;
+ if (!fprobe_ftrace_active) {
+ unregister_ftrace_function(&fprobe_ftrace_ops);
+ ftrace_free_filter(&fprobe_ftrace_ops);
+ } else if (num)
+ ftrace_set_filter_ips(&fprobe_ftrace_ops, addrs, num, 1, 0);
+}
+
+static bool fprobe_is_ftrace(struct fprobe *fp)
+{
+ return !fp->exit_handler;
+}
+#else
+static int fprobe_ftrace_add_ips(unsigned long *addrs, int num)
+{
+ return -ENOENT;
+}
+
+static void fprobe_ftrace_remove_ips(unsigned long *addrs, int num)
+{
+}
+
+static bool fprobe_is_ftrace(struct fprobe *fp)
+{
+ return false;
+}
+#endif
+
+/* fgraph_ops callback, this processes fprobes which have exit_handler. */
+static int fprobe_fgraph_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
+ struct ftrace_regs *fregs)
{
- struct fprobe_hlist_node *node, *first;
unsigned long *fgraph_data = NULL;
unsigned long func = trace->func;
+ struct fprobe_hlist_node *node;
+ struct rhlist_head *head, *pos;
unsigned long ret_ip;
int reserved_words;
struct fprobe *fp;
@@ -258,14 +373,11 @@ static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
if (WARN_ON_ONCE(!fregs))
return 0;
- first = node = find_first_fprobe_node(func);
- if (unlikely(!first))
- return 0;
-
+ head = rhltable_lookup(&fprobe_ip_table, &func, fprobe_rht_params);
reserved_words = 0;
- hlist_for_each_entry_from_rcu(node, hlist) {
+ rhl_for_each_entry_rcu(node, pos, head, hlist) {
if (node->addr != func)
- break;
+ continue;
fp = READ_ONCE(node->fp);
if (!fp || !fp->exit_handler)
continue;
@@ -276,15 +388,14 @@ static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
reserved_words +=
FPROBE_HEADER_SIZE_IN_LONG + SIZE_IN_LONG(fp->entry_data_size);
}
- node = first;
if (reserved_words) {
fgraph_data = fgraph_reserve_data(gops->idx, reserved_words * sizeof(long));
if (unlikely(!fgraph_data)) {
- hlist_for_each_entry_from_rcu(node, hlist) {
+ rhl_for_each_entry_rcu(node, pos, head, hlist) {
if (node->addr != func)
- break;
+ continue;
fp = READ_ONCE(node->fp);
- if (fp && !fprobe_disabled(fp))
+ if (fp && !fprobe_disabled(fp) && !fprobe_is_ftrace(fp))
fp->nmissed++;
}
return 0;
@@ -297,14 +408,14 @@ static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
*/
ret_ip = ftrace_regs_get_return_address(fregs);
used = 0;
- hlist_for_each_entry_from_rcu(node, hlist) {
+ rhl_for_each_entry_rcu(node, pos, head, hlist) {
int data_size;
void *data;
if (node->addr != func)
- break;
+ continue;
fp = READ_ONCE(node->fp);
- if (!fp || fprobe_disabled(fp))
+ if (unlikely(!fp || fprobe_disabled(fp) || fprobe_is_ftrace(fp)))
continue;
data_size = fp->entry_data_size;
@@ -332,7 +443,7 @@ static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
/* If any exit_handler is set, data must be used. */
return used != 0;
}
-NOKPROBE_SYMBOL(fprobe_entry);
+NOKPROBE_SYMBOL(fprobe_fgraph_entry);
static void fprobe_return(struct ftrace_graph_ret *trace,
struct fgraph_ops *gops,
@@ -371,7 +482,7 @@ static void fprobe_return(struct ftrace_graph_ret *trace,
NOKPROBE_SYMBOL(fprobe_return);
static struct fgraph_ops fprobe_graph_ops = {
- .entryfunc = fprobe_entry,
+ .entryfunc = fprobe_fgraph_entry,
.retfunc = fprobe_return,
};
static int fprobe_graph_active;
@@ -405,10 +516,10 @@ static void fprobe_graph_remove_ips(unsigned long *addrs, int num)
fprobe_graph_active--;
/* Q: should we unregister it ? */
- if (!fprobe_graph_active)
+ if (!fprobe_graph_active) {
unregister_ftrace_graph(&fprobe_graph_ops);
-
- if (num)
+ ftrace_free_filter(&fprobe_graph_ops.ops);
+ } else if (num)
ftrace_set_filter_ips(&fprobe_graph_ops.ops, addrs, num, 1, 0);
}
@@ -447,25 +558,21 @@ static int fprobe_addr_list_add(struct fprobe_addr_list *alist, unsigned long ad
return 0;
}
-static void fprobe_remove_node_in_module(struct module *mod, struct hlist_head *head,
- struct fprobe_addr_list *alist)
+static void fprobe_remove_node_in_module(struct module *mod, struct fprobe_hlist_node *node,
+ struct fprobe_addr_list *alist)
{
- struct fprobe_hlist_node *node;
int ret = 0;
- hlist_for_each_entry_rcu(node, head, hlist,
- lockdep_is_held(&fprobe_mutex)) {
- if (!within_module(node->addr, mod))
- continue;
- if (delete_fprobe_node(node))
- continue;
- /*
- * If failed to update alist, just continue to update hlist.
- * Therefore, at list user handler will not hit anymore.
- */
- if (!ret)
- ret = fprobe_addr_list_add(alist, node->addr);
- }
+ if (!within_module(node->addr, mod))
+ return;
+ if (delete_fprobe_node(node))
+ return;
+ /*
+ * If failed to update alist, just continue to update hlist.
+ * Therefore, at list user handler will not hit anymore.
+ */
+ if (!ret)
+ ret = fprobe_addr_list_add(alist, node->addr);
}
/* Handle module unloading to manage fprobe_ip_table. */
@@ -473,8 +580,9 @@ static int fprobe_module_callback(struct notifier_block *nb,
unsigned long val, void *data)
{
struct fprobe_addr_list alist = {.size = FPROBE_IPS_BATCH_INIT};
+ struct fprobe_hlist_node *node;
+ struct rhashtable_iter iter;
struct module *mod = data;
- int i;
if (val != MODULE_STATE_GOING)
return NOTIFY_DONE;
@@ -485,12 +593,25 @@ static int fprobe_module_callback(struct notifier_block *nb,
return NOTIFY_DONE;
mutex_lock(&fprobe_mutex);
- for (i = 0; i < FPROBE_IP_TABLE_SIZE; i++)
- fprobe_remove_node_in_module(mod, &fprobe_ip_table[i], &alist);
+ rhltable_walk_enter(&fprobe_ip_table, &iter);
+ do {
+ rhashtable_walk_start(&iter);
+
+ while ((node = rhashtable_walk_next(&iter)) && !IS_ERR(node))
+ fprobe_remove_node_in_module(mod, node, &alist);
+
+ rhashtable_walk_stop(&iter);
+ } while (node == ERR_PTR(-EAGAIN));
+ rhashtable_walk_exit(&iter);
- if (alist.index > 0)
+ if (alist.index > 0) {
ftrace_set_filter_ips(&fprobe_graph_ops.ops,
alist.addrs, alist.index, 1, 0);
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+ ftrace_set_filter_ips(&fprobe_ftrace_ops,
+ alist.addrs, alist.index, 1, 0);
+#endif
+ }
mutex_unlock(&fprobe_mutex);
kfree(alist.addrs);
@@ -634,7 +755,6 @@ static int fprobe_init(struct fprobe *fp, unsigned long *addrs, int num)
fp->hlist_array = hlist_array;
hlist_array->fp = fp;
for (i = 0; i < num; i++) {
- hlist_array->array[i].fp = fp;
addr = ftrace_location(addrs[i]);
if (!addr) {
fprobe_fail_cleanup(fp);
@@ -698,6 +818,8 @@ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter
}
EXPORT_SYMBOL_GPL(register_fprobe);
+static int unregister_fprobe_nolock(struct fprobe *fp);
+
/**
* register_fprobe_ips() - Register fprobe to ftrace by address.
* @fp: A fprobe data structure to be registered.
@@ -724,16 +846,25 @@ int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num)
if (ret)
return ret;
- hlist_array = fp->hlist_array;
- ret = fprobe_graph_add_ips(addrs, num);
- if (!ret) {
- add_fprobe_hash(fp);
- for (i = 0; i < hlist_array->size; i++)
- insert_fprobe_node(&hlist_array->array[i]);
+ if (fprobe_is_ftrace(fp))
+ ret = fprobe_ftrace_add_ips(addrs, num);
+ else
+ ret = fprobe_graph_add_ips(addrs, num);
+ if (ret) {
+ fprobe_fail_cleanup(fp);
+ return ret;
}
- if (ret)
- fprobe_fail_cleanup(fp);
+ hlist_array = fp->hlist_array;
+ ret = add_fprobe_hash(fp);
+ for (i = 0; i < hlist_array->size && !ret; i++)
+ ret = insert_fprobe_node(&hlist_array->array[i], fp);
+
+ if (ret) {
+ unregister_fprobe_nolock(fp);
+ /* In error case, wait for clean up safely. */
+ synchronize_rcu();
+ }
return ret;
}
@@ -777,50 +908,63 @@ bool fprobe_is_registered(struct fprobe *fp)
return true;
}
-/**
- * unregister_fprobe() - Unregister fprobe.
- * @fp: A fprobe data structure to be unregistered.
- *
- * Unregister fprobe (and remove ftrace hooks from the function entries).
- *
- * Return 0 if @fp is unregistered successfully, -errno if not.
- */
-int unregister_fprobe(struct fprobe *fp)
+static int unregister_fprobe_nolock(struct fprobe *fp)
{
- struct fprobe_hlist *hlist_array;
+ struct fprobe_hlist *hlist_array = fp->hlist_array;
unsigned long *addrs = NULL;
- int ret = 0, i, count;
-
- mutex_lock(&fprobe_mutex);
- if (!fp || !fprobe_registered(fp)) {
- ret = -EINVAL;
- goto out;
- }
+ int i, count;
- hlist_array = fp->hlist_array;
addrs = kcalloc(hlist_array->size, sizeof(unsigned long), GFP_KERNEL);
- if (!addrs) {
- ret = -ENOMEM; /* TODO: Fallback to one-by-one loop */
- goto out;
- }
+ /*
+ * This will remove fprobe_hash_node from the hash table even if
+ * memory allocation fails. However, ftrace_ops will not be updated.
+ * Anyway, when the last fprobe is unregistered, ftrace_ops is also
+ * unregistered.
+ */
+ if (!addrs)
+ pr_warn("Failed to allocate working array. ftrace_ops may not sync.\n");
/* Remove non-synonim ips from table and hash */
count = 0;
for (i = 0; i < hlist_array->size; i++) {
- if (!delete_fprobe_node(&hlist_array->array[i]))
+ if (!delete_fprobe_node(&hlist_array->array[i]) && addrs)
addrs[count++] = hlist_array->array[i].addr;
}
del_fprobe_hash(fp);
- fprobe_graph_remove_ips(addrs, count);
+ if (fprobe_is_ftrace(fp))
+ fprobe_ftrace_remove_ips(addrs, count);
+ else
+ fprobe_graph_remove_ips(addrs, count);
kfree_rcu(hlist_array, rcu);
fp->hlist_array = NULL;
+ kfree(addrs);
-out:
- mutex_unlock(&fprobe_mutex);
+ return 0;
+}
- kfree(addrs);
- return ret;
+/**
+ * unregister_fprobe() - Unregister fprobe.
+ * @fp: A fprobe data structure to be unregistered.
+ *
+ * Unregister fprobe (and remove ftrace hooks from the function entries).
+ *
+ * Return 0 if @fp is unregistered successfully, -errno if not.
+ */
+int unregister_fprobe(struct fprobe *fp)
+{
+ guard(mutex)(&fprobe_mutex);
+ if (!fp || !fprobe_registered(fp))
+ return -EINVAL;
+
+ return unregister_fprobe_nolock(fp);
}
EXPORT_SYMBOL_GPL(unregister_fprobe);
+
+static int __init fprobe_initcall(void)
+{
+ rhltable_init(&fprobe_ip_table, &fprobe_rht_params);
+ return 0;
+}
+late_initcall(fprobe_initcall);
diff --git a/mm/damon/core.c b/mm/damon/core.c
index c46236b73b2d..00c80b7c8c3f 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -1436,6 +1436,23 @@ bool damon_is_running(struct damon_ctx *ctx)
return running;
}
+/**
+ * damon_kdamond_pid() - Return pid of a given DAMON context's worker thread.
+ * @ctx: The DAMON context of the question.
+ *
+ * Return: pid if @ctx is running, negative error code otherwise.
+ */
+int damon_kdamond_pid(struct damon_ctx *ctx)
+{
+ int pid = -EINVAL;
+
+ mutex_lock(&ctx->kdamond_lock);
+ if (ctx->kdamond)
+ pid = ctx->kdamond->pid;
+ mutex_unlock(&ctx->kdamond_lock);
+ return pid;
+}
+
/**
* damon_call() - Invoke a given function on DAMON worker thread (kdamond).
* @ctx: DAMON context to call the function for.
@@ -2118,7 +2135,8 @@ static unsigned long damos_quota_score(struct damos_quota *quota)
/*
* Called only if quota->ms, or quota->sz are set, or quota->goals is not empty
*/
-static void damos_set_effective_quota(struct damos_quota *quota)
+static void damos_set_effective_quota(struct damos_quota *quota,
+ struct damon_ctx *ctx)
{
unsigned long throughput;
unsigned long esz = ULONG_MAX;
@@ -2144,6 +2162,7 @@ static void damos_set_effective_quota(struct damos_quota *quota)
else
throughput = PAGE_SIZE * 1024;
esz = min(throughput * quota->ms, esz);
+ esz = max(ctx->min_sz_region, esz);
}
if (quota->sz && quota->sz < esz)
@@ -2180,7 +2199,7 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
/* First charge window */
if (!quota->total_charged_sz && !quota->charged_from) {
quota->charged_from = jiffies;
- damos_set_effective_quota(quota);
+ damos_set_effective_quota(quota, c);
}
/* New charge window starts */
@@ -2194,7 +2213,7 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
quota->charged_sz = 0;
if (trace_damos_esz_enabled())
cached_esz = quota->esz;
- damos_set_effective_quota(quota);
+ damos_set_effective_quota(quota, c);
if (trace_damos_esz_enabled() && quota->esz != cached_esz)
damos_trace_esz(c, s, quota);
}
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 42b9a656f9de..0c2274fefd76 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -118,15 +118,6 @@ module_param(monitor_region_end, ulong, 0600);
*/
static unsigned long addr_unit __read_mostly = 1;
-/*
- * PID of the DAMON thread
- *
- * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread.
- * Else, -1.
- */
-static int kdamond_pid __read_mostly = -1;
-module_param(kdamond_pid, int, 0400);
-
static struct damos_stat damon_lru_sort_hot_stat;
DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_hot_stat,
lru_sort_tried_hot_regions, lru_sorted_hot_regions,
@@ -288,12 +279,8 @@ static int damon_lru_sort_turn(bool on)
{
int err;
- if (!on) {
- err = damon_stop(&ctx, 1);
- if (!err)
- kdamond_pid = -1;
- return err;
- }
+ if (!on)
+ return damon_stop(&ctx, 1);
err = damon_lru_sort_apply_parameters();
if (err)
@@ -302,7 +289,6 @@ static int damon_lru_sort_turn(bool on)
err = damon_start(&ctx, 1, true);
if (err)
return err;
- kdamond_pid = ctx->kdamond->pid;
return damon_call(ctx, &call_control);
}
@@ -330,42 +316,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &addr_unit, 0600);
MODULE_PARM_DESC(addr_unit,
"Scale factor for DAMON_LRU_SORT to ops address conversion (default: 1)");
+static bool damon_lru_sort_enabled(void)
+{
+ if (!ctx)
+ return false;
+ return damon_is_running(ctx);
+}
+
static int damon_lru_sort_enabled_store(const char *val,
const struct kernel_param *kp)
{
- bool is_enabled = enabled;
- bool enable;
int err;
- err = kstrtobool(val, &enable);
+ err = kstrtobool(val, &enabled);
if (err)
return err;
- if (is_enabled == enable)
+ if (damon_lru_sort_enabled() == enabled)
return 0;
/* Called before init function. The function will handle this. */
if (!damon_initialized())
- goto set_param_out;
+ return 0;
- err = damon_lru_sort_turn(enable);
- if (err)
- return err;
+ return damon_lru_sort_turn(enabled);
+}
-set_param_out:
- enabled = enable;
- return err;
+static int damon_lru_sort_enabled_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ return sprintf(buffer, "%c\n", damon_lru_sort_enabled() ? 'Y' : 'N');
}
static const struct kernel_param_ops enabled_param_ops = {
.set = damon_lru_sort_enabled_store,
- .get = param_get_bool,
+ .get = damon_lru_sort_enabled_load,
};
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
MODULE_PARM_DESC(enabled,
"Enable or disable DAMON_LRU_SORT (default: disabled)");
+static int damon_lru_sort_kdamond_pid_store(const char *val,
+ const struct kernel_param *kp)
+{
+ /*
+ * kdamond_pid is read-only, but kernel command line could write it.
+ * Do nothing here.
+ */
+ return 0;
+}
+
+static int damon_lru_sort_kdamond_pid_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ int kdamond_pid = -1;
+
+ if (ctx) {
+ kdamond_pid = damon_kdamond_pid(ctx);
+ if (kdamond_pid < 0)
+ kdamond_pid = -1;
+ }
+ return sprintf(buffer, "%d\n", kdamond_pid);
+}
+
+static const struct kernel_param_ops kdamond_pid_param_ops = {
+ .set = damon_lru_sort_kdamond_pid_store,
+ .get = damon_lru_sort_kdamond_pid_load,
+};
+
+/*
+ * PID of the DAMON thread
+ *
+ * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread.
+ * Else, -1.
+ */
+module_param_cb(kdamond_pid, &kdamond_pid_param_ops, NULL, 0400);
+
static int __init damon_lru_sort_init(void)
{
int err;
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index 7ba3d0f9a19a..9446e7a1b476 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -144,15 +144,6 @@ static unsigned long addr_unit __read_mostly = 1;
static bool skip_anon __read_mostly;
module_param(skip_anon, bool, 0600);
-/*
- * PID of the DAMON thread
- *
- * If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread.
- * Else, -1.
- */
-static int kdamond_pid __read_mostly = -1;
-module_param(kdamond_pid, int, 0400);
-
static struct damos_stat damon_reclaim_stat;
DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_reclaim_stat,
reclaim_tried_regions, reclaimed_regions, quota_exceeds);
@@ -292,12 +283,8 @@ static int damon_reclaim_turn(bool on)
{
int err;
- if (!on) {
- err = damon_stop(&ctx, 1);
- if (!err)
- kdamond_pid = -1;
- return err;
- }
+ if (!on)
+ return damon_stop(&ctx, 1);
err = damon_reclaim_apply_parameters();
if (err)
@@ -306,7 +293,6 @@ static int damon_reclaim_turn(bool on)
err = damon_start(&ctx, 1, true);
if (err)
return err;
- kdamond_pid = ctx->kdamond->pid;
return damon_call(ctx, &call_control);
}
@@ -334,42 +320,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &addr_unit, 0600);
MODULE_PARM_DESC(addr_unit,
"Scale factor for DAMON_RECLAIM to ops address conversion (default: 1)");
+static bool damon_reclaim_enabled(void)
+{
+ if (!ctx)
+ return false;
+ return damon_is_running(ctx);
+}
+
static int damon_reclaim_enabled_store(const char *val,
const struct kernel_param *kp)
{
- bool is_enabled = enabled;
- bool enable;
int err;
- err = kstrtobool(val, &enable);
+ err = kstrtobool(val, &enabled);
if (err)
return err;
- if (is_enabled == enable)
+ if (damon_reclaim_enabled() == enabled)
return 0;
/* Called before init function. The function will handle this. */
if (!damon_initialized())
- goto set_param_out;
+ return 0;
- err = damon_reclaim_turn(enable);
- if (err)
- return err;
+ return damon_reclaim_turn(enabled);
+}
-set_param_out:
- enabled = enable;
- return err;
+static int damon_reclaim_enabled_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ return sprintf(buffer, "%c\n", damon_reclaim_enabled() ? 'Y' : 'N');
}
static const struct kernel_param_ops enabled_param_ops = {
.set = damon_reclaim_enabled_store,
- .get = param_get_bool,
+ .get = damon_reclaim_enabled_load,
};
module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
MODULE_PARM_DESC(enabled,
"Enable or disable DAMON_RECLAIM (default: disabled)");
+static int damon_reclaim_kdamond_pid_store(const char *val,
+ const struct kernel_param *kp)
+{
+ /*
+ * kdamond_pid is read-only, but kernel command line could write it.
+ * Do nothing here.
+ */
+ return 0;
+}
+
+static int damon_reclaim_kdamond_pid_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ int kdamond_pid = -1;
+
+ if (ctx) {
+ kdamond_pid = damon_kdamond_pid(ctx);
+ if (kdamond_pid < 0)
+ kdamond_pid = -1;
+ }
+ return sprintf(buffer, "%d\n", kdamond_pid);
+}
+
+static const struct kernel_param_ops kdamond_pid_param_ops = {
+ .set = damon_reclaim_kdamond_pid_store,
+ .get = damon_reclaim_kdamond_pid_load,
+};
+
+/*
+ * PID of the DAMON thread
+ *
+ * If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread.
+ * Else, -1.
+ */
+module_param_cb(kdamond_pid, &kdamond_pid_param_ops, NULL, 0400);
+
static int __init damon_reclaim_init(void)
{
int err;
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f28e9cbf8ad5..74ef7dc2b2f9 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -173,19 +173,12 @@ batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const u8 *neigh_addr,
- struct batadv_orig_node *orig_node,
- struct batadv_orig_node *orig_neigh)
+ struct batadv_orig_node *orig_node)
{
struct batadv_neigh_node *neigh_node;
neigh_node = batadv_neigh_node_get_or_create(orig_node,
hard_iface, neigh_addr);
- if (!neigh_node)
- goto out;
-
- neigh_node->orig_node = orig_neigh;
-
-out:
return neigh_node;
}
@@ -335,7 +328,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
const char *fwd_str;
u8 packet_num;
- s16 buff_pos;
+ int buff_pos;
struct batadv_ogm_packet *batadv_ogm_packet;
struct sk_buff *skb;
u8 *packet_pos;
@@ -906,6 +899,31 @@ static u8 batadv_iv_orig_ifinfo_sum(struct batadv_orig_node *orig_node,
return sum;
}
+/**
+ * batadv_iv_ogm_neigh_ifinfo_sum() - Get bcast_own sum for a last-hop neighbor
+ * @bat_priv: the bat priv with all the mesh interface information
+ * @neigh_node: last-hop neighbor of an originator
+ *
+ * Return: Number of replied (rebroadcasted) OGMs for the originator currently
+ * announced by the neighbor. Returns 0 if the neighbor's originator entry is
+ * not available anymore.
+ */
+static u8 batadv_iv_ogm_neigh_ifinfo_sum(struct batadv_priv *bat_priv,
+ const struct batadv_neigh_node *neigh_node)
+{
+ struct batadv_orig_node *orig_neigh;
+ u8 sum;
+
+ orig_neigh = batadv_orig_hash_find(bat_priv, neigh_node->addr);
+ if (!orig_neigh)
+ return 0;
+
+ sum = batadv_iv_orig_ifinfo_sum(orig_neigh, neigh_node->if_incoming);
+ batadv_orig_node_put(orig_neigh);
+
+ return sum;
+}
+
/**
* batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
* originator
@@ -975,17 +993,9 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
}
if (!neigh_node) {
- struct batadv_orig_node *orig_tmp;
-
- orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
- if (!orig_tmp)
- goto unlock;
-
neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
ethhdr->h_source,
- orig_node, orig_tmp);
-
- batadv_orig_node_put(orig_tmp);
+ orig_node);
if (!neigh_node)
goto unlock;
} else {
@@ -1037,10 +1047,9 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
*/
if (router_ifinfo &&
neigh_ifinfo->bat_iv.tq_avg == router_ifinfo->bat_iv.tq_avg) {
- sum_orig = batadv_iv_orig_ifinfo_sum(router->orig_node,
- router->if_incoming);
- sum_neigh = batadv_iv_orig_ifinfo_sum(neigh_node->orig_node,
- neigh_node->if_incoming);
+ sum_orig = batadv_iv_ogm_neigh_ifinfo_sum(bat_priv, router);
+ sum_neigh = batadv_iv_ogm_neigh_ifinfo_sum(bat_priv,
+ neigh_node);
if (sum_orig >= sum_neigh)
goto out;
}
@@ -1106,7 +1115,6 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
if (!neigh_node)
neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
orig_neigh_node->orig,
- orig_neigh_node,
orig_neigh_node);
if (!neigh_node)
@@ -1302,6 +1310,32 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
return ret;
}
+/**
+ * batadv_orig_to_direct_router() - get direct next hop neighbor to an orig address
+ * @bat_priv: the bat priv with all the mesh interface information
+ * @orig_addr: the originator MAC address to search the best next hop router for
+ * @if_outgoing: the interface where the OGM should be sent to
+ *
+ * Return: A neighbor node which is the best router towards the given originator
+ * address. Bonding candidates are ignored.
+ */
+static struct batadv_neigh_node *
+batadv_orig_to_direct_router(struct batadv_priv *bat_priv, u8 *orig_addr,
+ struct batadv_hard_iface *if_outgoing)
+{
+ struct batadv_neigh_node *neigh_node;
+ struct batadv_orig_node *orig_node;
+
+ orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
+ if (!orig_node)
+ return NULL;
+
+ neigh_node = batadv_orig_router_get(orig_node, if_outgoing);
+ batadv_orig_node_put(orig_node);
+
+ return neigh_node;
+}
+
/**
* batadv_iv_ogm_process_per_outif() - process a batman iv OGM for an outgoing
* interface
@@ -1372,8 +1406,9 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
router = batadv_orig_router_get(orig_node, if_outgoing);
if (router) {
- router_router = batadv_orig_router_get(router->orig_node,
- if_outgoing);
+ router_router = batadv_orig_to_direct_router(bat_priv,
+ router->addr,
+ if_outgoing);
router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
}
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index d4f4e97a27f1..2d7971424aa0 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -319,8 +319,8 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
if (claim->backbone_gw != backbone_gw)
continue;
- batadv_claim_put(claim);
hlist_del_rcu(&claim->hash_entry);
+ batadv_claim_put(claim);
}
spin_unlock_bh(list_lock);
}
@@ -724,6 +724,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
if (unlikely(hash_added != 0)) {
/* only local changes happened. */
+ batadv_backbone_gw_put(backbone_gw);
kfree(claim);
return;
}
@@ -1289,6 +1290,13 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
rcu_read_lock();
hlist_for_each_entry_rcu(claim, head, hash_entry) {
+ /* only purge claims not currently in the process of being released.
+ * Such claims could otherwise have a NULL-ptr backbone_gw set because
+ * they already went through batadv_claim_release()
+ */
+ if (!kref_get_unless_zero(&claim->refcount))
+ continue;
+
backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
if (now)
goto purge_now;
@@ -1314,6 +1322,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
claim->addr, claim->vid);
skip:
batadv_backbone_gw_put(backbone_gw);
+ batadv_claim_put(claim);
}
rcu_read_unlock();
}
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 3a35aadd8b41..a4d33ee0fda5 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -249,6 +249,7 @@ void batadv_mesh_free(struct net_device *mesh_iface)
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
batadv_purge_outstanding_packets(bat_priv, NULL);
+ batadv_tp_stop_all(bat_priv);
batadv_gw_node_free(bat_priv);
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 350b149e48be..76ece4014384 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -12,6 +12,7 @@
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>
+#include <linux/completion.h>
#include <linux/container_of.h>
#include <linux/err.h>
#include <linux/etherdevice.h>
@@ -365,23 +366,38 @@ static void batadv_tp_vars_put(struct batadv_tp_vars *tp_vars)
}
/**
- * batadv_tp_sender_cleanup() - cleanup sender data and drop and timer
- * @bat_priv: the bat priv with all the mesh interface information
- * @tp_vars: the private data of the current TP meter session to cleanup
+ * batadv_tp_list_detach() - remove tp session from mesh session list once
+ * @tp_vars: the private data of the current TP meter session
*/
-static void batadv_tp_sender_cleanup(struct batadv_priv *bat_priv,
- struct batadv_tp_vars *tp_vars)
+static void batadv_tp_list_detach(struct batadv_tp_vars *tp_vars)
{
- cancel_delayed_work(&tp_vars->finish_work);
+ bool detached = false;
spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
- hlist_del_rcu(&tp_vars->list);
+ if (!hlist_unhashed(&tp_vars->list)) {
+ hlist_del_init_rcu(&tp_vars->list);
+ detached = true;
+ }
spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
+ if (!detached)
+ return;
+
+ atomic_dec(&tp_vars->bat_priv->tp_num);
+
/* drop list reference */
batadv_tp_vars_put(tp_vars);
+}
- atomic_dec(&tp_vars->bat_priv->tp_num);
+/**
+ * batadv_tp_sender_cleanup() - cleanup sender data and drop and timer
+ * @tp_vars: the private data of the current TP meter session to cleanup
+ */
+static void batadv_tp_sender_cleanup(struct batadv_tp_vars *tp_vars)
+{
+ cancel_delayed_work_sync(&tp_vars->finish_work);
+
+ batadv_tp_list_detach(tp_vars);
/* kill the timer and remove its reference */
timer_delete_sync(&tp_vars->timer);
@@ -886,7 +902,8 @@ static int batadv_tp_send(void *arg)
batadv_orig_node_put(orig_node);
batadv_tp_sender_end(bat_priv, tp_vars);
- batadv_tp_sender_cleanup(bat_priv, tp_vars);
+ batadv_tp_sender_cleanup(tp_vars);
+ complete(&tp_vars->finished);
batadv_tp_vars_put(tp_vars);
@@ -918,7 +935,8 @@ static void batadv_tp_start_kthread(struct batadv_tp_vars *tp_vars)
batadv_tp_vars_put(tp_vars);
/* cleanup of failed tp meter variables */
- batadv_tp_sender_cleanup(bat_priv, tp_vars);
+ batadv_tp_sender_cleanup(tp_vars);
+ complete(&tp_vars->finished);
return;
}
@@ -947,6 +965,13 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
/* look for an already existing test towards this node */
spin_lock_bh(&bat_priv->tp_list_lock);
+ if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) {
+ spin_unlock_bh(&bat_priv->tp_list_lock);
+ batadv_tp_batctl_error_notify(BATADV_TP_REASON_DST_UNREACHABLE,
+ dst, bat_priv, session_cookie);
+ return;
+ }
+
tp_vars = batadv_tp_list_find(bat_priv, dst);
if (tp_vars) {
spin_unlock_bh(&bat_priv->tp_list_lock);
@@ -969,6 +994,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
if (!tp_vars) {
+ atomic_dec(&bat_priv->tp_num);
spin_unlock_bh(&bat_priv->tp_list_lock);
batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
"Meter: %s cannot allocate list elements\n",
@@ -1017,6 +1043,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
tp_vars->start_time = jiffies;
init_waitqueue_head(&tp_vars->more_bytes);
+ init_completion(&tp_vars->finished);
spin_lock_init(&tp_vars->unacked_lock);
INIT_LIST_HEAD(&tp_vars->unacked_list);
@@ -1119,14 +1146,7 @@ static void batadv_tp_receiver_shutdown(struct timer_list *t)
"Shutting down for inactivity (more than %dms) from %pM\n",
BATADV_TP_RECV_TIMEOUT, tp_vars->other_end);
- spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
- hlist_del_rcu(&tp_vars->list);
- spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
-
- /* drop list reference */
- batadv_tp_vars_put(tp_vars);
-
- atomic_dec(&bat_priv->tp_num);
+ batadv_tp_list_detach(tp_vars);
spin_lock_bh(&tp_vars->unacked_lock);
list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
@@ -1329,9 +1349,12 @@ static struct batadv_tp_vars *
batadv_tp_init_recv(struct batadv_priv *bat_priv,
const struct batadv_icmp_tp_packet *icmp)
{
- struct batadv_tp_vars *tp_vars;
+ struct batadv_tp_vars *tp_vars = NULL;
spin_lock_bh(&bat_priv->tp_list_lock);
+ if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
+ goto out_unlock;
+
tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
icmp->session);
if (tp_vars)
@@ -1344,8 +1367,10 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
}
tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
- if (!tp_vars)
+ if (!tp_vars) {
+ atomic_dec(&bat_priv->tp_num);
goto out_unlock;
+ }
ether_addr_copy(tp_vars->other_end, icmp->orig);
tp_vars->role = BATADV_TP_RECEIVER;
@@ -1464,6 +1489,9 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
{
struct batadv_icmp_tp_packet *icmp;
+ if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
+ goto out;
+
icmp = (struct batadv_icmp_tp_packet *)skb->data;
switch (icmp->subtype) {
@@ -1478,9 +1506,57 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
"Received unknown TP Metric packet type %u\n",
icmp->subtype);
}
+
+out:
consume_skb(skb);
}
+/**
+ * batadv_tp_stop_all() - stop all currently running tp meter sessions
+ * @bat_priv: the bat priv with all the mesh interface information
+ */
+void batadv_tp_stop_all(struct batadv_priv *bat_priv)
+{
+ struct batadv_tp_vars *tp_vars[BATADV_TP_MAX_NUM];
+ struct batadv_tp_vars *tp_var;
+ size_t count = 0;
+ size_t i;
+
+ spin_lock_bh(&bat_priv->tp_list_lock);
+ hlist_for_each_entry(tp_var, &bat_priv->tp_list, list) {
+ if (WARN_ON_ONCE(count >= BATADV_TP_MAX_NUM))
+ break;
+
+ if (!kref_get_unless_zero(&tp_var->refcount))
+ continue;
+
+ tp_vars[count++] = tp_var;
+ }
+ spin_unlock_bh(&bat_priv->tp_list_lock);
+
+ for (i = 0; i < count; i++) {
+ tp_var = tp_vars[i];
+
+ switch (tp_var->role) {
+ case BATADV_TP_SENDER:
+ batadv_tp_sender_shutdown(tp_var,
+ BATADV_TP_REASON_CANCEL);
+ wake_up(&tp_var->more_bytes);
+ wait_for_completion(&tp_var->finished);
+ break;
+ case BATADV_TP_RECEIVER:
+ batadv_tp_list_detach(tp_var);
+ if (timer_shutdown_sync(&tp_var->timer))
+ batadv_tp_vars_put(tp_var);
+ break;
+ }
+
+ batadv_tp_vars_put(tp_var);
+ }
+
+ synchronize_net();
+}
+
/**
* batadv_tp_meter_init() - initialize global tp_meter structures
*/
diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h
index f0046d366eac..4e97cd10cd02 100644
--- a/net/batman-adv/tp_meter.h
+++ b/net/batman-adv/tp_meter.h
@@ -17,6 +17,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
u32 test_length, u32 *cookie);
void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
u8 return_value);
+void batadv_tp_stop_all(struct batadv_priv *bat_priv);
void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb);
#endif /* _NET_BATMAN_ADV_TP_METER_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index ae1d7a8dc480..41c1d19f786b 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -14,6 +14,7 @@
#include <linux/average.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
+#include <linux/completion.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/kref.h>
@@ -1328,6 +1329,9 @@ struct batadv_tp_vars {
/** @finish_work: work item for the finishing procedure */
struct delayed_work finish_work;
+ /** @finished: completion signaled when a sender thread exits */
+ struct completion finished;
+
/** @test_length: test length in milliseconds */
u32 test_length;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 71a24be2a6d6..1b63bc2753a2 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -2113,6 +2113,9 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
u32 flags = 0;
int err;
+ if (!hci_conn_valid(hdev, conn))
+ return -ECANCELED;
+
if (qos->bcast.out.phy == 0x02)
flags |= MGMT_ADV_FLAG_SEC_2M;
@@ -2188,11 +2191,24 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "conn %p", conn);
+ if (err == -ECANCELED)
+ goto done;
+
+ hci_dev_lock(hdev);
+
+ if (!hci_conn_valid(hdev, conn))
+ goto unlock;
+
if (err) {
bt_dev_err(hdev, "Unable to create BIG: %d", err);
hci_connect_cfm(conn, err);
hci_conn_del(conn);
}
+
+unlock:
+ hci_dev_unlock(hdev);
+done:
+ hci_conn_put(conn);
}
struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
@@ -2309,10 +2325,11 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
BT_BOUND, &data);
/* Queue start periodic advertising and create BIG */
- err = hci_cmd_sync_queue(hdev, create_big_sync, conn,
+ err = hci_cmd_sync_queue(hdev, create_big_sync, hci_conn_get(conn),
create_big_complete);
if (err < 0) {
hci_conn_drop(conn);
+ hci_conn_put(conn);
return ERR_PTR(err);
}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d190e75e4645..c57a53192bee 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1985,6 +1985,15 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
goto out_unlock;
iov_iter_revert(&msg->msg_iter, err);
+
+ /* sctp_sendmsg_to_asoc() may have released the socket
+ * lock (sctp_wait_for_sndbuf), during which other
+ * associations on ep->asocs could have been peeled
+ * off or freed. @asoc itself is revalidated by the
+ * base.dead and base.sk checks in sctp_wait_for_sndbuf,
+ * so re-derive the cached cursor from it.
+ */
+ tmp = list_next_entry(asoc, asocs);
}
goto out_unlock;
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index cbd649bf0145..9d0e1915abbe 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1846,12 +1846,12 @@ static void vsock_update_buffer_size(struct vsock_sock *vsk,
const struct vsock_transport *transport,
u64 val)
{
- if (val > vsk->buffer_max_size)
- val = vsk->buffer_max_size;
-
if (val < vsk->buffer_min_size)
val = vsk->buffer_min_size;
+ if (val > vsk->buffer_max_size)
+ val = vsk->buffer_max_size;
+
if (val != vsk->buffer_size &&
transport && transport->notify_buffer_size)
transport->notify_buffer_size(vsk, &val);
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index d3e26025ef58..41be06c4bd7f 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -139,27 +139,6 @@ static void virtio_transport_init_hdr(struct sk_buff *skb,
hdr->fwd_cnt = cpu_to_le32(0);
}
-static void virtio_transport_copy_nonlinear_skb(const struct sk_buff *skb,
- void *dst,
- size_t len)
-{
- struct iov_iter iov_iter = { 0 };
- struct kvec kvec;
- size_t to_copy;
-
- kvec.iov_base = dst;
- kvec.iov_len = len;
-
- iov_iter.iter_type = ITER_KVEC;
- iov_iter.kvec = &kvec;
- iov_iter.nr_segs = 1;
-
- to_copy = min_t(size_t, len, skb->len);
-
- skb_copy_datagram_iter(skb, VIRTIO_VSOCK_SKB_CB(skb)->offset,
- &iov_iter, to_copy);
-}
-
/* Packet capture */
static struct sk_buff *virtio_transport_build_skb(void *opaque)
{
@@ -169,12 +148,12 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
struct sk_buff *skb;
size_t payload_len;
- /* A packet could be split to fit the RX buffer, so we can retrieve
- * the payload length from the header and the buffer pointer taking
- * care of the offset in the original packet.
+ /* A packet could be split to fit the RX buffer, so we use
+ * the payload length from the header, which has been updated
+ * by the sender to reflect the fragment size.
*/
pkt_hdr = virtio_vsock_hdr(pkt);
- payload_len = pkt->len;
+ payload_len = le32_to_cpu(pkt_hdr->len);
skb = alloc_skb(sizeof(*hdr) + sizeof(*pkt_hdr) + payload_len,
GFP_ATOMIC);
@@ -217,12 +196,18 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
skb_put_data(skb, pkt_hdr, sizeof(*pkt_hdr));
if (payload_len) {
- if (skb_is_nonlinear(pkt)) {
- void *data = skb_put(skb, payload_len);
-
- virtio_transport_copy_nonlinear_skb(pkt, data, payload_len);
- } else {
- skb_put_data(skb, pkt->data, payload_len);
+ struct iov_iter iov_iter;
+ struct kvec kvec;
+ void *data = skb_put(skb, payload_len);
+
+ kvec.iov_base = data;
+ kvec.iov_len = payload_len;
+ iov_iter_kvec(&iov_iter, ITER_DEST, &kvec, 1, payload_len);
+
+ if (skb_copy_datagram_iter(pkt, VIRTIO_VSOCK_SKB_CB(pkt)->offset,
+ &iov_iter, payload_len)) {
+ kfree_skb(skb);
+ return NULL;
}
}
@@ -546,9 +531,8 @@ virtio_transport_stream_do_peek(struct vsock_sock *vsk,
skb_queue_walk(&vvs->rx_queue, skb) {
size_t bytes;
- bytes = len - total;
- if (bytes > skb->len)
- bytes = skb->len;
+ bytes = min_t(size_t, len - total,
+ skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset);
spin_unlock_bh(&vvs->rx_lock);
@@ -1544,8 +1528,6 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb,
return -ENOMEM;
}
- sk_acceptq_added(sk);
-
lock_sock_nested(child, SINGLE_DEPTH_NESTING);
child->sk_state = TCP_ESTABLISHED;
@@ -1567,6 +1549,7 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb,
return ret;
}
+ sk_acceptq_added(sk);
if (virtio_transport_space_update(child, skb))
child->sk_write_space(child);