summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/accel/qaic/qaic_timesync.c2
-rw-r--r--drivers/accessibility/speakup/main.c18
-rw-r--r--drivers/accessibility/speakup/synth.c2
-rw-r--r--drivers/acpi/acpi_pnp.c2
-rw-r--r--drivers/acpi/acpi_video.c9
-rw-r--r--drivers/acpi/apei/ghes.c103
-rw-r--r--drivers/acpi/nfit/core.c2
-rw-r--r--drivers/acpi/numa/hmat.c44
-rw-r--r--drivers/acpi/numa/srat.c22
-rw-r--r--drivers/acpi/platform_profile.c13
-rw-r--r--drivers/acpi/processor_idle.c4
-rw-r--r--drivers/acpi/resource.c7
-rw-r--r--drivers/acpi/x86/utils.c3
-rw-r--r--drivers/ata/libata-eh.c2
-rw-r--r--drivers/atm/idt77105.c4
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/atm/lanai.c2
-rw-r--r--drivers/atm/nicstar.c2
-rw-r--r--drivers/atm/suni.c2
-rw-r--r--drivers/auxdisplay/line-display.c8
-rw-r--r--drivers/auxdisplay/panel.c4
-rw-r--r--drivers/base/devcoredump.c2
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/base/power/main.c2
-rw-r--r--drivers/base/power/wakeup.c6
-rw-r--r--drivers/block/amiflop.c10
-rw-r--r--drivers/block/aoe/aoedev.c2
-rw-r--r--drivers/block/aoe/aoemain.c2
-rw-r--r--drivers/block/ataflop.c12
-rw-r--r--drivers/block/drbd/drbd_main.c2
-rw-r--r--drivers/block/drbd/drbd_nl.c2
-rw-r--r--drivers/block/drbd/drbd_receiver.c2
-rw-r--r--drivers/block/floppy.c8
-rw-r--r--drivers/block/sunvdc.c2
-rw-r--r--drivers/block/swim3.c10
-rw-r--r--drivers/block/ublk_drv.c223
-rw-r--r--drivers/bluetooth/bluecard_cs.c4
-rw-r--r--drivers/bluetooth/hci_bcsp.c2
-rw-r--r--drivers/bluetooth/hci_h5.c6
-rw-r--r--drivers/bluetooth/hci_qca.c10
-rw-r--r--drivers/bus/fsl-mc/dpmcp.c22
-rw-r--r--drivers/bus/fsl-mc/fsl-mc-allocator.c5
-rw-r--r--drivers/bus/fsl-mc/fsl-mc-private.h6
-rw-r--r--drivers/bus/fsl-mc/mc-io.c20
-rw-r--r--drivers/bus/mhi/host/pci_generic.c8
-rw-r--r--drivers/char/dtlk.c6
-rw-r--r--drivers/char/hangcheck-timer.c2
-rw-r--r--drivers/char/hw_random/xgene-rng.c2
-rw-r--r--drivers/char/ipmi/bt-bmc.c2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c4
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c6
-rw-r--r--drivers/char/ipmi/kcs_bmc_aspeed.c4
-rw-r--r--drivers/char/ipmi/ssif_bmc.c2
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/tlclk.c4
-rw-r--r--drivers/char/tpm/tpm-dev-common.c4
-rw-r--r--drivers/clk/clkdev.c9
-rw-r--r--drivers/clocksource/timer-riscv.c6
-rw-r--r--drivers/comedi/drivers/comedi_test.c12
-rw-r--r--drivers/comedi/drivers/das16.c4
-rw-r--r--drivers/comedi/drivers/jr3_pci.c2
-rw-r--r--drivers/counter/microchip-tcb-capture.c19
-rw-r--r--drivers/counter/stm32-lptimer-cnt.c24
-rw-r--r--drivers/cpufreq/cpufreq.c6
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c4
-rw-r--r--drivers/crypto/axis/artpec6_crypto.c4
-rw-r--r--drivers/crypto/inside-secure/eip93/eip93-hash.c3
-rw-r--r--drivers/cxl/Kconfig4
-rw-r--r--drivers/cxl/core/Makefile3
-rw-r--r--drivers/cxl/core/acpi.c11
-rw-r--r--drivers/cxl/core/cdat.c102
-rw-r--r--drivers/cxl/core/core.h10
-rw-r--r--drivers/cxl/core/hdm.c382
-rw-r--r--drivers/cxl/core/mbox.c141
-rw-r--r--drivers/cxl/core/mce.c65
-rw-r--r--drivers/cxl/core/mce.h20
-rw-r--r--drivers/cxl/core/memdev.c83
-rw-r--r--drivers/cxl/core/pci.c97
-rw-r--r--drivers/cxl/core/port.c38
-rw-r--r--drivers/cxl/core/ras.c119
-rw-r--r--drivers/cxl/core/region.c336
-rw-r--r--drivers/cxl/core/trace.h81
-rw-r--r--drivers/cxl/cxl.h52
-rw-r--r--drivers/cxl/cxlmem.h77
-rw-r--r--drivers/cxl/cxlpci.h6
-rw-r--r--drivers/cxl/mem.c2
-rw-r--r--drivers/cxl/pci.c7
-rw-r--r--drivers/cxl/pmem.c81
-rw-r--r--drivers/dma-buf/st-dma-fence.c2
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/amd/ae4dma/ae4dma-pci.c6
-rw-r--r--drivers/dma/amd/ae4dma/ae4dma.h2
-rw-r--r--drivers/dma/amd/ptdma/ptdma-dmaengine.c90
-rw-r--r--drivers/dma/bcm2835-dma.c2
-rw-r--r--drivers/dma/dmaengine.c16
-rw-r--r--drivers/dma/dmatest.c6
-rw-r--r--drivers/dma/dw-edma/dw-edma-core.c6
-rw-r--r--drivers/dma/dw/pci.c8
-rw-r--r--drivers/dma/dw/platform.c8
-rw-r--r--drivers/dma/fsl-edma-main.c18
-rw-r--r--drivers/dma/idxd/init.c3
-rw-r--r--drivers/dma/img-mdc-dma.c2
-rw-r--r--drivers/dma/imx-dma.c7
-rw-r--r--drivers/dma/imx-sdma.c5
-rw-r--r--drivers/dma/ioat/dma.c2
-rw-r--r--drivers/dma/ioat/init.c4
-rw-r--r--drivers/dma/pxa_dma.c4
-rw-r--r--drivers/dma/sh/shdma-base.c2
-rw-r--r--drivers/dma/sun6i-dma.c3
-rw-r--r--drivers/dma/ti/edma.c11
-rw-r--r--drivers/dma/ti/k3-udma-glue.c15
-rw-r--r--drivers/dma/ti/k3-udma.c36
-rw-r--r--drivers/dma/xilinx/xilinx_dma.c3
-rw-r--r--drivers/firewire/core-cdev.c42
-rw-r--r--drivers/firewire/core-transaction.c2
-rw-r--r--drivers/firmware/cirrus/cs_dsp.c2
-rw-r--r--drivers/firmware/efi/cper.c6
-rw-r--r--drivers/firmware/efi/cper_cxl.c39
-rw-r--r--drivers/firmware/efi/cper_cxl.h66
-rw-r--r--drivers/firmware/psci/psci_checker.c2
-rw-r--r--drivers/gpu/drm/adp/adp_drv.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c34
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c44
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c58
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c88
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c90
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c104
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c45
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c58
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c68
-rw-r--r--drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c79
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ta_ras_if.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v12_0.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vega10_sdma_pkt_open.h70
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c43
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c7
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h114
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c2
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h7
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c3
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c2
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c15
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c55
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c3
-rw-r--r--drivers/gpu/drm/bridge/Kconfig13
-rw-r--r--drivers/gpu/drm/bridge/tda998x_drv.c2
-rw-r--r--drivers/gpu/drm/drm_vblank.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c2
-rw-r--r--drivers/gpu/drm/gud/gud_pipe.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.h2
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.c5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_execlists_submission.c6
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rps.c2
-rw-r--r--drivers/gpu/drm/i915/gt/mock_engine.c4
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_execlists.c4
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_migrate.c2
-rw-r--r--drivers/gpu/drm/i915/i915_iosf_mbi.h6
-rw-r--r--drivers/gpu/drm/i915/i915_utils.c2
-rw-r--r--drivers/gpu/drm/i915/intel_wakeref.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/lib_sw_fence.c2
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dp.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_preempt.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c4
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_preempt.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c4
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c2
-rw-r--r--drivers/gpu/drm/vgem/vgem_fence.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_msg.c2
-rw-r--r--drivers/gpu/drm/xe/Kconfig2
-rw-r--r--drivers/gpu/drm/xe/regs/xe_engine_regs.h4
-rw-r--r--drivers/gpu/drm/xe/xe_device.c17
-rw-r--r--drivers/gpu/drm/xe/xe_eu_stall.c8
-rw-r--r--drivers/gpu/drm/xe/xe_execlist.c2
-rw-r--r--drivers/gpu/drm/xe/xe_gt_clock.c54
-rw-r--r--drivers/gpu/drm/xe/xe_gt_types.h2
-rw-r--r--drivers/gpu/drm/xe/xe_hw_engine.c33
-rw-r--r--drivers/gpu/drm/xe/xe_pci.c16
-rw-r--r--drivers/gpu/drm/xe/xe_survivability_mode.c31
-rw-r--r--drivers/gpu/drm/xe/xe_survivability_mode.h1
-rw-r--r--drivers/gpu/drm/xe/xe_wa.c6
-rw-r--r--drivers/gpu/drm/xe/xe_wa_oob.rules2
-rw-r--r--drivers/greybus/operation.c2
-rw-r--r--drivers/hid/hid-apple.c4
-rw-r--r--drivers/hid/hid-appleir.c2
-rw-r--r--drivers/hid/hid-appletb-kbd.c2
-rw-r--r--drivers/hid/hid-magicmouse.c4
-rw-r--r--drivers/hid/hid-multitouch.c4
-rw-r--r--drivers/hid/hid-nvidia-shield.c2
-rw-r--r--drivers/hid/hid-prodikeys.c2
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/hid-uclogic-core.c2
-rw-r--r--drivers/hid/hid-wiimote-core.c2
-rw-r--r--drivers/hid/usbhid/hid-core.c4
-rw-r--r--drivers/hid/wacom_sys.c2
-rw-r--r--drivers/hsi/clients/ssi_protocol.c18
-rw-r--r--drivers/hte/hte-tegra194-test.c2
-rw-r--r--drivers/hwmon/pwm-fan.c2
-rw-r--r--drivers/i2c/busses/Kconfig18
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-amd-asf-plat.c8
-rw-r--r--drivers/i2c/busses/i2c-axxia.c21
-rw-r--r--drivers/i2c/busses/i2c-bcm-iproc.c13
-rw-r--r--drivers/i2c/busses/i2c-bcm-kona.c6
-rw-r--r--drivers/i2c/busses/i2c-brcmstb.c11
-rw-r--r--drivers/i2c/busses/i2c-cadence.c19
-rw-r--r--drivers/i2c/busses/i2c-designware-amdpsp.c26
-rw-r--r--drivers/i2c/busses/i2c-designware-master.c2
-rw-r--r--drivers/i2c/busses/i2c-eg20t.c28
-rw-r--r--drivers/i2c/busses/i2c-exynos5.c2
-rw-r--r--drivers/i2c/busses/i2c-i801.c271
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c14
-rw-r--r--drivers/i2c/busses/i2c-img-scb.c2
-rw-r--r--drivers/i2c/busses/i2c-k1.c602
-rw-r--r--drivers/i2c/busses/i2c-kempld.c10
-rw-r--r--drivers/i2c/busses/i2c-mlxbf.c106
-rw-r--r--drivers/i2c/busses/i2c-mt7621.c20
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c12
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.c111
-rw-r--r--drivers/i2c/busses/i2c-omap.c22
-rw-r--r--drivers/i2c/busses/i2c-pasemi-core.c40
-rw-r--r--drivers/i2c/busses/i2c-pxa.c5
-rw-r--r--drivers/i2c/busses/i2c-qcom-geni.c6
-rw-r--r--drivers/i2c/busses/i2c-qup.c36
-rw-r--r--drivers/i2c/busses/i2c-rzv2m.c15
-rw-r--r--drivers/i2c/i2c-core-of.c1
-rw-r--r--drivers/i2c/i2c-core.h9
-rw-r--r--drivers/i2c/muxes/i2c-mux-ltc4306.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-reg.c2
-rw-r--r--drivers/i3c/master.c21
-rw-r--r--drivers/i3c/master/dw-i3c-master.c2
-rw-r--r--drivers/i3c/master/i3c-master-cdns.c2
-rw-r--r--drivers/i3c/master/mipi-i3c-hci/core.c10
-rw-r--r--drivers/i3c/master/svc-i3c-master.c138
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_dev.c4
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c2
-rw-r--r--drivers/infiniband/hw/hfi1/aspm.c2
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c4
-rw-r--r--drivers/infiniband/hw/hfi1/driver.c2
-rw-r--r--drivers/infiniband/hw/hfi1/init.c2
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.c2
-rw-r--r--drivers/infiniband/hw/hfi1/tid_rdma.c8
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.c2
-rw-r--r--drivers/infiniband/hw/irdma/cm.c2
-rw-r--r--drivers/infiniband/hw/irdma/utils.c4
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_driver.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c1
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_init.c10
-rw-r--r--drivers/infiniband/hw/qib/qib_mad.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_sd7220.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.c2
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c8
-rw-r--r--drivers/infiniband/sw/rxe/rxe_qp.c4
-rw-r--r--drivers/input/ff-memless.c4
-rw-r--r--drivers/input/gameport/gameport.c4
-rw-r--r--drivers/input/input.c4
-rw-r--r--drivers/input/joystick/db9.c2
-rw-r--r--drivers/input/joystick/gamecon.c2
-rw-r--r--drivers/input/joystick/n64joy.c2
-rw-r--r--drivers/input/joystick/turbografx.c2
-rw-r--r--drivers/input/joystick/walkera0701.c3
-rw-r--r--drivers/input/keyboard/gpio_keys.c10
-rw-r--r--drivers/input/keyboard/imx_keypad.c2
-rw-r--r--drivers/input/keyboard/matrix_keypad.c8
-rw-r--r--drivers/input/keyboard/snvs_pwrkey.c2
-rw-r--r--drivers/input/keyboard/tegra-kbc.c4
-rw-r--r--drivers/input/misc/pm8941-pwrkey.c4
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/input/mouse/byd.c2
-rw-r--r--drivers/input/mouse/cyapa.c4
-rw-r--r--drivers/input/mouse/synaptics.c2
-rw-r--r--drivers/input/rmi4/rmi_f54.c2
-rw-r--r--drivers/input/serio/hil_mlc.c2
-rw-r--r--drivers/input/serio/hp_sdc.c2
-rw-r--r--drivers/input/touchscreen/Kconfig13
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ad7877.c2
-rw-r--r--drivers/input/touchscreen/ad7879.c2
-rw-r--r--drivers/input/touchscreen/apple_z2.c477
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c2
-rw-r--r--drivers/input/touchscreen/bu21029_ts.c2
-rw-r--r--drivers/input/touchscreen/exc3000.c2
-rw-r--r--drivers/input/touchscreen/goodix_berlin.h16
-rw-r--r--drivers/input/touchscreen/goodix_berlin_core.c21
-rw-r--r--drivers/input/touchscreen/goodix_berlin_i2c.c14
-rw-r--r--drivers/input/touchscreen/goodix_berlin_spi.c48
-rw-r--r--drivers/input/touchscreen/sur40.c2
-rw-r--r--drivers/input/touchscreen/sx8654.c2
-rw-r--r--drivers/input/touchscreen/tsc2007.h2
-rw-r--r--drivers/input/touchscreen/tsc2007_core.c5
-rw-r--r--drivers/input/touchscreen/tsc200x-core.c4
-rw-r--r--drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c60
-rw-r--r--drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c80
-rw-r--r--drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h36
-rw-r--r--drivers/iommu/dma-iommu.c206
-rw-r--r--drivers/iommu/dma-iommu.h14
-rw-r--r--drivers/iommu/intel/iommu.c3
-rw-r--r--drivers/iommu/intel/nested.c2
-rw-r--r--drivers/iommu/iommu-priv.h16
-rw-r--r--drivers/iommu/iommu-sva.c1
-rw-r--r--drivers/iommu/iommu.c160
-rw-r--r--drivers/iommu/iommufd/Kconfig2
-rw-r--r--drivers/iommu/iommufd/Makefile2
-rw-r--r--drivers/iommu/iommufd/device.c499
-rw-r--r--drivers/iommu/iommufd/driver.c198
-rw-r--r--drivers/iommu/iommufd/eventq.c598
-rw-r--r--drivers/iommu/iommufd/fault.c342
-rw-r--r--drivers/iommu/iommufd/hw_pagetable.c42
-rw-r--r--drivers/iommu/iommufd/iommufd_private.h156
-rw-r--r--drivers/iommu/iommufd/iommufd_test.h40
-rw-r--r--drivers/iommu/iommufd/main.c7
-rw-r--r--drivers/iommu/iommufd/selftest.c297
-rw-r--r--drivers/iommu/iommufd/viommu.c2
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c6
-rw-r--r--drivers/irqchip/irq-clps711x.c2
-rw-r--r--drivers/irqchip/irq-imx-gpcv2.c2
-rw-r--r--drivers/irqchip/irq-pic32-evic.c2
-rw-r--r--drivers/irqchip/irq-xilinx-intc.c2
-rw-r--r--drivers/irqchip/irq-xtensa-mx.c2
-rw-r--r--drivers/irqchip/irq-xtensa-pic.c4
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c6
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c14
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c10
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c6
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c8
-rw-r--r--drivers/isdn/mISDN/dsp_core.c6
-rw-r--r--drivers/isdn/mISDN/dsp_tones.c4
-rw-r--r--drivers/isdn/mISDN/fsm.c4
-rw-r--r--drivers/leds/flash/leds-rt8515.c4
-rw-r--r--drivers/leds/flash/leds-sgm3140.c6
-rw-r--r--drivers/leds/led-core.c4
-rw-r--r--drivers/leds/trigger/ledtrig-pattern.c2
-rw-r--r--drivers/leds/trigger/ledtrig-transient.c2
-rw-r--r--drivers/macintosh/adbhid.c2
-rw-r--r--drivers/mailbox/mailbox-altera.c2
-rw-r--r--drivers/md/Kconfig1
-rw-r--r--drivers/md/bcache/stats.c2
-rw-r--r--drivers/md/dm-bufio.c4
-rw-r--r--drivers/md/dm-cache-target.c96
-rw-r--r--drivers/md/dm-crypt.c41
-rw-r--r--drivers/md/dm-delay.c18
-rw-r--r--drivers/md/dm-ebs-target.c7
-rw-r--r--drivers/md/dm-integrity.c52
-rw-r--r--drivers/md/dm-mpath.c2
-rw-r--r--drivers/md/dm-raid1.c2
-rw-r--r--drivers/md/dm-stripe.c2
-rw-r--r--drivers/md/dm-table.c4
-rw-r--r--drivers/md/dm-vdo/block-map.c13
-rw-r--r--drivers/md/dm-vdo/constants.h3
-rw-r--r--drivers/md/dm-vdo/dedupe.c22
-rw-r--r--drivers/md/dm-vdo/encodings.c20
-rw-r--r--drivers/md/dm-vdo/indexer/index-layout.c5
-rw-r--r--drivers/md/dm-vdo/indexer/index-session.c6
-rw-r--r--drivers/md/dm-vdo/indexer/indexer.h53
-rw-r--r--drivers/md/dm-vdo/io-submitter.c6
-rw-r--r--drivers/md/dm-vdo/io-submitter.h18
-rw-r--r--drivers/md/dm-vdo/packer.h2
-rw-r--r--drivers/md/dm-vdo/priority-table.c2
-rw-r--r--drivers/md/dm-vdo/recovery-journal.h6
-rw-r--r--drivers/md/dm-vdo/slab-depot.c193
-rw-r--r--drivers/md/dm-vdo/slab-depot.h13
-rw-r--r--drivers/md/dm-vdo/types.h3
-rw-r--r--drivers/md/dm-vdo/vdo.c11
-rw-r--r--drivers/md/dm-vdo/vio.c54
-rw-r--r--drivers/md/dm-vdo/vio.h13
-rw-r--r--drivers/md/dm-vdo/wait-queue.c2
-rw-r--r--drivers/md/dm-verity-target.c62
-rw-r--r--drivers/md/dm-writecache.c6
-rw-r--r--drivers/md/dm.c8
-rw-r--r--drivers/md/md.c4
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c2
-rw-r--r--drivers/media/common/saa7146/saa7146_vbi.c4
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c2
-rw-r--r--drivers/media/dvb-core/dmxdev.c6
-rw-r--r--drivers/media/dvb-frontends/dib8000.c5
-rw-r--r--drivers/media/i2c/tc358743.c4
-rw-r--r--drivers/media/i2c/tvaudio.c4
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c2
-rw-r--r--drivers/media/pci/bt8xx/bttv-input.c4
-rw-r--r--drivers/media/pci/bt8xx/bttv-risc.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.c6
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.c4
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c10
-rw-r--r--drivers/media/pci/saa7134/saa7134-input.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-ts.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/pci/tw686x/tw686x-core.c2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c6
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c2
-rw-r--r--drivers/media/radio/radio-cadet.c2
-rw-r--r--drivers/media/rc/ene_ir.c2
-rw-r--r--drivers/media/rc/igorplugusb.c4
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.c4
-rw-r--r--drivers/media/rc/img-ir/img-ir-raw.c2
-rw-r--r--drivers/media/rc/imon.c2
-rw-r--r--drivers/media/rc/ir-mce_kbd-decoder.c4
-rw-r--r--drivers/media/rc/rc-ir-raw.c2
-rw-r--r--drivers/media/rc/rc-main.c6
-rw-r--r--drivers/media/rc/serial_ir.c2
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c4
-rw-r--r--drivers/media/usb/au0828/au0828-video.c12
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-encoder.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c16
-rw-r--r--drivers/memory/tegra/tegra210-emc-core.c4
-rw-r--r--drivers/memstick/core/ms_block.c4
-rw-r--r--drivers/memstick/host/jmb38x_ms.c2
-rw-r--r--drivers/memstick/host/r592.c4
-rw-r--r--drivers/memstick/host/tifm_ms.c4
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/bcm-vk/bcm_vk_tty.c4
-rw-r--r--drivers/misc/cardreader/rtsx_usb.c2
-rw-r--r--drivers/misc/cxl/Kconfig28
-rw-r--r--drivers/misc/cxl/Makefile14
-rw-r--r--drivers/misc/cxl/api.c532
-rw-r--r--drivers/misc/cxl/base.c126
-rw-r--r--drivers/misc/cxl/context.c362
-rw-r--r--drivers/misc/cxl/cxl.h1135
-rw-r--r--drivers/misc/cxl/cxllib.c271
-rw-r--r--drivers/misc/cxl/debugfs.c134
-rw-r--r--drivers/misc/cxl/fault.c341
-rw-r--r--drivers/misc/cxl/file.c699
-rw-r--r--drivers/misc/cxl/flash.c538
-rw-r--r--drivers/misc/cxl/guest.c1208
-rw-r--r--drivers/misc/cxl/hcalls.c643
-rw-r--r--drivers/misc/cxl/hcalls.h200
-rw-r--r--drivers/misc/cxl/irq.c450
-rw-r--r--drivers/misc/cxl/main.c383
-rw-r--r--drivers/misc/cxl/native.c1592
-rw-r--r--drivers/misc/cxl/of.c346
-rw-r--r--drivers/misc/cxl/pci.c2103
-rw-r--r--drivers/misc/cxl/sysfs.c771
-rw-r--r--drivers/misc/cxl/trace.c9
-rw-r--r--drivers/misc/cxl/trace.h691
-rw-r--r--drivers/misc/cxl/vphb.c309
-rw-r--r--drivers/misc/eeprom/at24.c10
-rw-r--r--drivers/misc/lkdtm/perms.c14
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c2
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c2
-rw-r--r--drivers/mmc/core/host.c4
-rw-r--r--drivers/mmc/host/atmel-mci.c8
-rw-r--r--drivers/mmc/host/dw_mmc.c16
-rw-r--r--drivers/mmc/host/jz4740_mmc.c4
-rw-r--r--drivers/mmc/host/meson-mx-sdio.c4
-rw-r--r--drivers/mmc/host/mvsdio.c4
-rw-r--r--drivers/mmc/host/mxcmmc.c4
-rw-r--r--drivers/mmc/host/omap.c10
-rw-r--r--drivers/mmc/host/sdhci.c8
-rw-r--r--drivers/mmc/host/tifm_sd.c2
-rw-r--r--drivers/mmc/host/via-sdmmc.c4
-rw-r--r--drivers/mmc/host/vub300.c6
-rw-r--r--drivers/mmc/host/wbsd.c2
-rw-r--r--drivers/most/most_usb.c4
-rw-r--r--drivers/mtd/sm_ftl.c4
-rw-r--r--drivers/net/arcnet/arcnet.c2
-rw-r--r--drivers/net/arcnet/com20020-pci.c17
-rw-r--r--drivers/net/caif/caif_serial.c2
-rw-r--r--drivers/net/can/grcan.c12
-rw-r--r--drivers/net/can/kvaser_pciefd.c6
-rw-r--r--drivers/net/can/sja1000/peak_pcmcia.c2
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c11
-rw-r--r--drivers/net/dsa/mv88e6xxx/phy.c7
-rw-r--r--drivers/net/dsa/sja1105/sja1105_ptp.c4
-rw-r--r--drivers/net/dummy.c1
-rw-r--r--drivers/net/eql.c2
-rw-r--r--drivers/net/ethernet/3com/3c515.c2
-rw-r--r--drivers/net/ethernet/3com/3c574_cs.c2
-rw-r--r--drivers/net/ethernet/3com/3c589_cs.c2
-rw-r--r--drivers/net/ethernet/3com/3c59x.c2
-rw-r--r--drivers/net/ethernet/8390/axnet_cs.c2
-rw-r--r--drivers/net/ethernet/8390/pcnet_cs.c2
-rw-r--r--drivers/net/ethernet/agere/et131x.c2
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.c31
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.h3
-rw-r--r--drivers/net/ethernet/airoha/airoha_ppe.c8
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_netdev.c6
-rw-r--r--drivers/net/ethernet/amd/a2065.c2
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c4
-rw-r--r--drivers/net/ethernet/amd/declance.c2
-rw-r--r--drivers/net/ethernet/amd/pcnet32.c2
-rw-r--r--drivers/net/ethernet/amd/sunlance.c2
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c4
-rw-r--r--drivers/net/ethernet/apple/bmac.c6
-rw-r--r--drivers/net/ethernet/apple/mace.c4
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_nic.c4
-rw-r--r--drivers/net/ethernet/atheros/ag71xx.c2
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c2
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_main.c2
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c2
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl2.c8
-rw-r--r--drivers/net/ethernet/broadcom/b44.c4
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.c6
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.c10
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c10
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c2
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc.c26
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c16
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad_ethtool.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/sge.c4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/sge.c4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/sge.c4
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_clsf.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c2
-rw-r--r--drivers/net/ethernet/dec/tulip/21142.c4
-rw-r--r--drivers/net/ethernet/dec/tulip/de2104x.c6
-rw-r--r--drivers/net/ethernet/dec/tulip/dmfe.c2
-rw-r--r--drivers/net/ethernet/dec/tulip/interrupt.c4
-rw-r--r--drivers/net/ethernet/dec/tulip/pnic2.c6
-rw-r--r--drivers/net/ethernet/dec/tulip/tulip_core.c4
-rw-r--r--drivers/net/ethernet/dec/tulip/uli526x.c2
-rw-r--r--drivers/net/ethernet/dec/tulip/winbond-840.c4
-rw-r--r--drivers/net/ethernet/dlink/dl2k.c4
-rw-r--r--drivers/net/ethernet/fealnx.c4
-rw-r--r--drivers/net/ethernet/google/gve/gve_ethtool.c6
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c8
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_enet.c2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c2
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c39
-rw-r--r--drivers/net/ethernet/intel/e100.c4
-rw-r--r--drivers/net/ethernet/intel/e1000e/defines.h3
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c80
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h4
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c8
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c4
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c4
-rw-r--r--drivers/net/ethernet/intel/idpf/idpf_main.c6
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c8
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c4
-rw-r--r--drivers/net/ethernet/intel/igc/igc.h2
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c14
-rw-r--r--drivers/net/ethernet/intel/igc/igc_xdp.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c2
-rw-r--r--drivers/net/ethernet/korina.c2
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c6
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2.h3
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c3
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c201
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu.c2
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c2
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c9
-rw-r--r--drivers/net/ethernet/marvell/pxa168_eth.c2
-rw-r--r--drivers/net/ethernet/marvell/skge.c2
-rw-r--r--drivers/net/ethernet/marvell/sky2.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/Kconfig1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/catas.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/params.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/health.c2
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c2
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_en.c46
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c2
-rw-r--r--drivers/net/ethernet/natsemi/natsemi.c4
-rw-r--r--drivers/net/ethernet/natsemi/ns83820.c2
-rw-r--r--drivers/net/ethernet/neterion/s2io.c2
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c2
-rw-r--r--drivers/net/ethernet/nvidia/forcedeth.c6
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c2
-rw-r--r--drivers/net/ethernet/packetengines/hamachi.c2
-rw-r--r--drivers/net/ethernet/packetengines/yellowfin.c2
-rw-r--r--drivers/net/ethernet/pasemi/pasemi_mac.c2
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c2
-rw-r--r--drivers/net/ethernet/qlogic/qla3xxx.c2
-rw-r--r--drivers/net/ethernet/realtek/atp.c2
-rw-r--r--drivers/net/ethernet/rocker/rocker_ofdpa.c2
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c6
-rw-r--r--drivers/net/ethernet/seeq/ether3.c6
-rw-r--r--drivers/net/ethernet/sfc/ef100_netdev.c6
-rw-r--r--drivers/net/ethernet/sfc/ef100_nic.c47
-rw-r--r--drivers/net/ethernet/sfc/falcon/falcon.c2
-rw-r--r--drivers/net/ethernet/sfc/falcon/rx.c2
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c4
-rw-r--r--drivers/net/ethernet/sfc/rx_common.c2
-rw-r--r--drivers/net/ethernet/sfc/siena/mcdi.c4
-rw-r--r--drivers/net/ethernet/sfc/siena/rx_common.c2
-rw-r--r--drivers/net/ethernet/sgi/ioc3-eth.c8
-rw-r--r--drivers/net/ethernet/sis/sis190.c4
-rw-r--r--drivers/net/ethernet/sis/sis900.c2
-rw-r--r--drivers/net/ethernet/smsc/epic100.c2
-rw-r--r--drivers/net/ethernet/smsc/smc91c92_cs.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c6
-rw-r--r--drivers/net/ethernet/sun/cassini.c2
-rw-r--r--drivers/net/ethernet/sun/ldmvsw.c6
-rw-r--r--drivers/net/ethernet/sun/niu.c6
-rw-r--r--drivers/net/ethernet/sun/sunbmac.c2
-rw-r--r--drivers/net/ethernet/sun/sungem.c8
-rw-r--r--drivers/net/ethernet/sun/sunhme.c6
-rw-r--r--drivers/net/ethernet/sun/sunvnet.c2
-rw-r--r--drivers/net/ethernet/sun/sunvnet_common.c6
-rw-r--r--drivers/net/ethernet/synopsys/dwc-xlgmac-net.c2
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-nuss.c4
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c2
-rw-r--r--drivers/net/ethernet/ti/icssg/icssg_common.c2
-rw-r--r--drivers/net/ethernet/ti/netcp_ethss.c2
-rw-r--r--drivers/net/ethernet/ti/tlan.c4
-rw-r--r--drivers/net/ethernet/tundra/tsi108_eth.c2
-rw-r--r--drivers/net/fddi/defza.c10
-rw-r--r--drivers/net/hamradio/6pack.c6
-rw-r--r--drivers/net/hamradio/scc.c26
-rw-r--r--drivers/net/hamradio/yam.c2
-rw-r--r--drivers/net/hippi/rrunner.c2
-rw-r--r--drivers/net/netdevsim/netdev.c17
-rw-r--r--drivers/net/netdevsim/netdevsim.h3
-rw-r--r--drivers/net/ntb_netdev.c2
-rw-r--r--drivers/net/phy/broadcom.c6
-rw-r--r--drivers/net/phy/phylink.c4
-rw-r--r--drivers/net/slip/slip.c14
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/usb/catc.c2
-rw-r--r--drivers/net/usb/lan78xx.c6
-rw-r--r--drivers/net/usb/rndis_host.c16
-rw-r--r--drivers/net/usb/sierra_net.c2
-rw-r--r--drivers/net/usb/usbnet.c33
-rw-r--r--drivers/net/vxlan/vxlan_core.c2
-rw-r--r--drivers/net/wan/hdlc_cisco.c2
-rw-r--r--drivers/net/wan/hdlc_fr.c2
-rw-r--r--drivers/net/wan/hdlc_ppp.c2
-rw-r--r--drivers/net/wan/lapbether.c2
-rw-r--r--drivers/net/wireguard/device.c2
-rw-r--r--drivers/net/wireguard/timers.c8
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/sdio.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/snoc.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/ahb.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.c4
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c8
-rw-r--r--drivers/net/wireless/ath/ath12k/dp.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_rx.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c6
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/recovery.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/p2p.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c6
-rw-r--r--drivers/net/wireless/atmel/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c2
-rw-r--r--drivers/net/wireless/intel/ipw2x00/libipw_crypto.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/3945-mac.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/3945-rs.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/4965-mac.c4
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/main.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/tt.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c6
-rw-r--r--drivers/net/wireless/marvell/libertas/cmdresp.c2
-rw-r--r--drivers/net/wireless/marvell/libertas/if_usb.c2
-rw-r--r--drivers/net/wireless/marvell/libertas/main.c12
-rw-r--r--drivers/net/wireless/marvell/libertas_tf/cmd.c2
-rw-r--r--drivers/net/wireless/marvell/libertas_tf/if_usb.c2
-rw-r--r--drivers/net/wireless/marvell/libertas_tf/main.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cmdevt.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/init.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_event.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/tdls.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/usb.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/main.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/main.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/main.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_core.c2
-rw-r--r--drivers/net/wireless/microchip/wilc1000/hif.c18
-rw-r--r--drivers/net/wireless/purelifi/plfxlc/usb.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c4
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_hal.c4
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c6
-rw-r--r--drivers/net/wireless/st/cw1200/main.c2
-rw-r--r--drivers/net/wireless/st/cw1200/pm.c2
-rw-r--r--drivers/net/wireless/st/cw1200/queue.c2
-rw-r--r--drivers/net/wireless/st/cw1200/sta.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c4
-rw-r--r--drivers/net/xen-netback/interface.c2
-rw-r--r--drivers/net/xen-netfront.c2
-rw-r--r--drivers/nfc/nfcmrvl/fw_dnld.c6
-rw-r--r--drivers/nfc/pn533/pn533.c4
-rw-r--r--drivers/nfc/pn533/uart.c2
-rw-r--r--drivers/nfc/st-nci/ndlc.c12
-rw-r--r--drivers/nfc/st-nci/se.c10
-rw-r--r--drivers/nfc/st21nfca/core.c4
-rw-r--r--drivers/nfc/st21nfca/se.c6
-rw-r--r--drivers/ntb/hw/amd/ntb_hw_amd.c1
-rw-r--r--drivers/ntb/hw/idt/ntb_hw_idt.c18
-rw-r--r--drivers/ntb/hw/intel/ntb_hw_gen3.c3
-rw-r--r--drivers/ntb/hw/mscc/ntb_hw_switchtec.c2
-rw-r--r--drivers/ntb/ntb_transport.c2
-rw-r--r--drivers/ntb/test/ntb_perf.c4
-rw-r--r--drivers/nvdimm/claim.c11
-rw-r--r--drivers/nvdimm/label.c3
-rw-r--r--drivers/nvdimm/nd-core.h4
-rw-r--r--drivers/nvdimm/region_devs.c41
-rw-r--r--drivers/nvme/host/Kconfig13
-rw-r--r--drivers/nvme/host/core.c2
-rw-r--r--drivers/nvme/host/ioctl.c68
-rw-r--r--drivers/nvme/host/multipath.c4
-rw-r--r--drivers/nvme/host/pci.c3
-rw-r--r--drivers/nvme/target/debugfs.c2
-rw-r--r--drivers/nvme/target/pci-epf.c63
-rw-r--r--drivers/parport/ieee1284.c2
-rw-r--r--drivers/pci/ats.c33
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c2
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c2
-rw-r--r--drivers/pcmcia/i82365.c2
-rw-r--r--drivers/pcmcia/soc_common.c4
-rw-r--r--drivers/pcmcia/tcic.c2
-rw-r--r--drivers/platform/mellanox/mlxbf-tmfifo.c2
-rw-r--r--drivers/platform/x86/gigabyte-wmi.c4
-rw-r--r--drivers/platform/x86/intel/speed_select_if/isst_if_common.c2
-rw-r--r--drivers/platform/x86/intel_ips.c2
-rw-r--r--drivers/platform/x86/sony-laptop.c2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c35
-rw-r--r--drivers/pnp/isapnp/core.c1
-rw-r--r--drivers/power/supply/ip5xxx_power.c7
-rw-r--r--drivers/pps/clients/pps-gpio.c2
-rw-r--r--drivers/pps/clients/pps-ktimer.c2
-rw-r--r--drivers/pps/generators/pps_gen-dummy.c4
-rw-r--r--drivers/pps/generators/pps_gen_tio.c4
-rw-r--r--drivers/ptp/ptp_ocp.c2
-rw-r--r--drivers/regulator/rk808-regulator.c4
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/dev.c2
-rw-r--r--drivers/rtc/rtc-ab-eoz9.c24
-rw-r--r--drivers/rtc/rtc-ab8500.c11
-rw-r--r--drivers/rtc/rtc-aspeed.c16
-rw-r--r--drivers/rtc/rtc-cros-ec.c30
-rw-r--r--drivers/rtc/rtc-ds1307.c4
-rw-r--r--drivers/rtc/rtc-ds1343.c8
-rw-r--r--drivers/rtc/rtc-ds2404.c14
-rw-r--r--drivers/rtc/rtc-ds3232.c24
-rw-r--r--drivers/rtc/rtc-ep93xx.c16
-rw-r--r--drivers/rtc/rtc-fsl-ftm-alarm.c2
-rw-r--r--drivers/rtc/rtc-ftrtc010.c17
-rw-r--r--drivers/rtc/rtc-m48t86.c14
-rw-r--r--drivers/rtc/rtc-max31335.c165
-rw-r--r--drivers/rtc/rtc-max77686.c37
-rw-r--r--drivers/rtc/rtc-meson-vrtc.c12
-rw-r--r--drivers/rtc/rtc-meson.c16
-rw-r--r--drivers/rtc/rtc-mpfs.c10
-rw-r--r--drivers/rtc/rtc-nxp-bbnsm.c29
-rw-r--r--drivers/rtc/rtc-pcf50633.c284
-rw-r--r--drivers/rtc/rtc-pcf85063.c25
-rw-r--r--drivers/rtc/rtc-pl030.c16
-rw-r--r--drivers/rtc/rtc-pl031.c8
-rw-r--r--drivers/rtc/rtc-pm8xxx.c220
-rw-r--r--drivers/rtc/rtc-renesas-rtca3.c15
-rw-r--r--drivers/rtc/rtc-rv3032.c8
-rw-r--r--drivers/rtc/rtc-rx8581.c85
-rw-r--r--drivers/rtc/rtc-rzn1.c108
-rw-r--r--drivers/rtc/rtc-s35390a.c22
-rw-r--r--drivers/rtc/rtc-s5m.c58
-rw-r--r--drivers/rtc/rtc-sd2405al.c16
-rw-r--r--drivers/rtc/rtc-sd3078.c71
-rw-r--r--drivers/rtc/rtc-stm32.c10
-rw-r--r--drivers/rtc/rtc-test.c4
-rw-r--r--drivers/s390/block/dasd.c8
-rw-r--r--drivers/s390/char/con3270.c4
-rw-r--r--drivers/s390/char/sclp.c12
-rw-r--r--drivers/s390/char/sclp_con.c2
-rw-r--r--drivers/s390/char/sclp_vt220.c4
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/tape_std.c2
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/s390/cio/eadm_sch.c2
-rw-r--r--drivers/s390/crypto/ap_queue.c2
-rw-r--r--drivers/s390/crypto/vfio_ap_ops.c72
-rw-r--r--drivers/s390/net/fsm.c4
-rw-r--r--drivers/s390/net/qeth_core_main.c2
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c4
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_tmf.c6
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c20
-rw-r--r--drivers/scsi/arm/fas216.c6
-rw-r--r--drivers/scsi/be2iscsi/be_main.c4
-rw-r--r--drivers/scsi/bfa/bfad.c10
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c4
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_tgt.c4
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c8
-rw-r--r--drivers/scsi/csiostor/csio_hw.c4
-rw-r--r--drivers/scsi/csiostor/csio_mb.c4
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/cxgb3i.c2
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/cxgb4i.c2
-rw-r--r--drivers/scsi/dc395x.c12
-rw-r--r--drivers/scsi/elx/efct/efct_driver.c2
-rw-r--r--drivers/scsi/elx/efct/efct_xport.c2
-rw-r--r--drivers/scsi/elx/libefc/efc_fabric.c2
-rw-r--r--drivers/scsi/elx/libefc/efc_node.c2
-rw-r--r--drivers/scsi/esas2r/esas2r_init.c2
-rw-r--r--drivers/scsi/fcoe/fcoe.c2
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c4
-rw-r--r--drivers/scsi/fnic/fdls_disc.c12
-rw-r--r--drivers/scsi/fnic/fip.c12
-rw-r--r--drivers/scsi/fnic/fnic_main.c12
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c6
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c14
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c4
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c16
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c6
-rw-r--r--drivers/scsi/ipr.c12
-rw-r--r--drivers/scsi/isci/host.c12
-rw-r--r--drivers/scsi/isci/isci.h8
-rw-r--r--drivers/scsi/libfc/fc_fcp.c4
-rw-r--r--drivers/scsi/libiscsi.c6
-rw-r--r--drivers/scsi/libsas/sas_expander.c2
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c10
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c10
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c2
-rw-r--r--drivers/scsi/mvsas/mv_sas.c2
-rw-r--r--drivers/scsi/pmcraid.c6
-rw-r--r--drivers/scsi/qla1280.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c2
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c2
-rw-r--r--drivers/soc/fsl/qe/qe_ic.c4
-rw-r--r--drivers/spi/Kconfig4
-rw-r--r--drivers/spi/spi-amd.c2
-rw-r--r--drivers/spi/spi-bcm2835.c18
-rw-r--r--drivers/spi/spi-cadence-quadspi.c2
-rw-r--r--drivers/spi/spi-cadence-xspi.c2
-rw-r--r--drivers/spi/spi-fsl-qspi.c31
-rw-r--r--drivers/spi/spi-qpic-snand.c2
-rw-r--r--drivers/spi/spi-rockchip.c2
-rw-r--r--drivers/staging/gpib/Kconfig5
-rw-r--r--drivers/staging/gpib/agilent_82350b/agilent_82350b.c260
-rw-r--r--drivers/staging/gpib/agilent_82350b/agilent_82350b.h50
-rw-r--r--drivers/staging/gpib/agilent_82357a/agilent_82357a.c531
-rw-r--r--drivers/staging/gpib/cb7210/Makefile1
-rw-r--r--drivers/staging/gpib/cb7210/cb7210.c287
-rw-r--r--drivers/staging/gpib/cb7210/cb7210.h45
-rw-r--r--drivers/staging/gpib/cec/cec.h29
-rw-r--r--drivers/staging/gpib/cec/cec_gpib.c96
-rw-r--r--drivers/staging/gpib/common/gpib_os.c332
-rw-r--r--drivers/staging/gpib/common/iblib.c169
-rw-r--r--drivers/staging/gpib/common/ibsys.h14
-rw-r--r--drivers/staging/gpib/eastwood/fluke_gpib.c204
-rw-r--r--drivers/staging/gpib/fmh_gpib/fmh_gpib.c280
-rw-r--r--drivers/staging/gpib/gpio/gpib_bitbang.c138
-rw-r--r--drivers/staging/gpib/hp_82335/hp82335.c83
-rw-r--r--drivers/staging/gpib/hp_82335/hp82335.h30
-rw-r--r--drivers/staging/gpib/hp_82341/hp_82341.c161
-rw-r--r--drivers/staging/gpib/hp_82341/hp_82341.h40
-rw-r--r--drivers/staging/gpib/include/gpibP.h10
-rw-r--r--drivers/staging/gpib/include/gpib_proto.h58
-rw-r--r--drivers/staging/gpib/include/gpib_types.h58
-rw-r--r--drivers/staging/gpib/include/nec7210.h60
-rw-r--r--drivers/staging/gpib/include/tms9914.h52
-rw-r--r--drivers/staging/gpib/ines/Makefile1
-rw-r--r--drivers/staging/gpib/ines/ines.h54
-rw-r--r--drivers/staging/gpib/ines/ines_gpib.c240
-rw-r--r--drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c363
-rw-r--r--drivers/staging/gpib/nec7210/nec7210.c147
-rw-r--r--drivers/staging/gpib/ni_usb/ni_usb_gpib.c619
-rw-r--r--drivers/staging/gpib/pc2/pc2_gpib.c352
-rw-r--r--drivers/staging/gpib/tms9914/tms9914.c117
-rw-r--r--drivers/staging/gpib/tnt4882/Makefile1
-rw-r--r--drivers/staging/gpib/tnt4882/mite.c17
-rw-r--r--drivers/staging/gpib/tnt4882/tnt4882_gpib.c964
-rw-r--r--drivers/staging/gpib/uapi/gpib_user.h29
-rw-r--r--drivers/staging/greybus/uart.c4
-rw-r--r--drivers/staging/media/imx/imx-ic-prpencvf.c2
-rw-r--r--drivers/staging/media/imx/imx-media-csi.c2
-rw-r--r--drivers/staging/rtl8723bs/Kconfig1
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_ap.c96
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_cmd.c2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme.c4
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme_ext.c22
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_recv.c2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_sta_mgt.c6
-rw-r--r--drivers/staging/rtl8723bs/hal/hal_com.c3
-rw-r--r--drivers/staging/rtl8723bs/hal/sdio_ops.c2
-rw-r--r--drivers/staging/rtl8723bs/include/osdep_intf.h27
-rw-r--r--drivers/staging/rtl8723bs/include/rtl8723b_hal.h1
-rw-r--r--drivers/staging/rtl8723bs/include/rtw_io.h92
-rw-r--r--drivers/staging/rtl8723bs/include/rtw_mp.h341
-rw-r--r--drivers/staging/rtl8723bs/os_dep/os_intfs.c14
-rw-r--r--drivers/staging/sm750fb/ddk750_chip.c2
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c2
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c127
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c65
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h2
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c14
-rw-r--r--drivers/target/iscsi/iscsi_target_erl0.c2
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.c2
-rw-r--r--drivers/target/iscsi/iscsi_target_util.c4
-rw-r--r--drivers/target/target_core_user.c8
-rw-r--r--drivers/thermal/broadcom/brcmstb_thermal.c11
-rw-r--r--drivers/thermal/mediatek/lvts_thermal.c103
-rw-r--r--drivers/thermal/qcom/qcom-spmi-temp-alarm.c1
-rw-r--r--drivers/thermal/qcom/tsens-v2.c178
-rw-r--r--drivers/thermal/qcom/tsens.c8
-rw-r--r--drivers/thermal/qcom/tsens.h3
-rw-r--r--drivers/thermal/qoriq_thermal.c47
-rw-r--r--drivers/thermal/renesas/rcar_gen3_thermal.c107
-rw-r--r--drivers/thermal/rockchip_thermal.c1
-rw-r--r--drivers/thunderbolt/retimer.c8
-rw-r--r--drivers/thunderbolt/tb.c16
-rw-r--r--drivers/thunderbolt/tunnel.c16
-rw-r--r--drivers/tty/Kconfig2
-rw-r--r--drivers/tty/ipwireless/hardware.c4
-rw-r--r--drivers/tty/mips_ejtag_fdc.c4
-rw-r--r--drivers/tty/moxa.c253
-rw-r--r--drivers/tty/n_gsm.c14
-rw-r--r--drivers/tty/n_tty.c212
-rw-r--r--drivers/tty/serdev/core.c11
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c9
-rw-r--r--drivers/tty/serial/8250/8250_aspeed_vuart.c2
-rw-r--r--drivers/tty/serial/8250/8250_core.c2
-rw-r--r--drivers/tty/serial/8250/8250_dma.c2
-rw-r--r--drivers/tty/serial/8250/8250_dw.c73
-rw-r--r--drivers/tty/serial/8250/8250_fsl.c8
-rw-r--r--drivers/tty/serial/8250/8250_ni.c461
-rw-r--r--drivers/tty/serial/8250/8250_omap.c2
-rw-r--r--drivers/tty/serial/8250/8250_pci.c46
-rw-r--r--drivers/tty/serial/8250/8250_port.c61
-rw-r--r--drivers/tty/serial/8250/8250_rsa.c21
-rw-r--r--drivers/tty/serial/8250/Kconfig13
-rw-r--r--drivers/tty/serial/8250/Makefile1
-rw-r--r--drivers/tty/serial/Kconfig42
-rw-r--r--drivers/tty/serial/Makefile2
-rw-r--r--drivers/tty/serial/altera_uart.c2
-rw-r--r--drivers/tty/serial/amba-pl011.c153
-rw-r--r--drivers/tty/serial/atmel_serial.c4
-rw-r--r--drivers/tty/serial/fsl_lpuart.c495
-rw-r--r--drivers/tty/serial/icom.c9
-rw-r--r--drivers/tty/serial/imx.c6
-rw-r--r--drivers/tty/serial/kgdb_nmi.c280
-rw-r--r--drivers/tty/serial/kgdboc.c8
-rw-r--r--drivers/tty/serial/liteuart.c4
-rw-r--r--drivers/tty/serial/ma35d1_serial.c2
-rw-r--r--drivers/tty/serial/max3100.c4
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c1
-rw-r--r--drivers/tty/serial/mux.c2
-rw-r--r--drivers/tty/serial/pch_uart.c1
-rw-r--r--drivers/tty/serial/sa1100.c4
-rw-r--r--drivers/tty/serial/sccnxp.c2
-rw-r--r--drivers/tty/serial/serial_core.c10
-rw-r--r--drivers/tty/serial/serial_mctrl_gpio.c62
-rw-r--r--drivers/tty/serial/serial_mctrl_gpio.h27
-rw-r--r--drivers/tty/serial/sh-sci.c100
-rw-r--r--drivers/tty/serial/stm32-usart.c6
-rw-r--r--drivers/tty/serial/sunsu.c178
-rw-r--r--drivers/tty/serial/tegra-utc.c625
-rw-r--r--drivers/tty/synclink_gt.c8
-rw-r--r--drivers/tty/sysrq.c4
-rw-r--r--drivers/tty/tty_audit.c10
-rw-r--r--drivers/tty/tty_io.c8
-rw-r--r--drivers/tty/tty_ldsem.c17
-rw-r--r--drivers/tty/vcc.c6
-rw-r--r--drivers/tty/vt/keyboard.c2
-rw-r--r--drivers/tty/vt/vt.c4
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/atm/speedtch.c8
-rw-r--r--drivers/usb/atm/usbatm.c4
-rw-r--r--drivers/usb/cdns3/cdns3-gadget.c4
-rw-r--r--drivers/usb/cdns3/cdns3-ti.c107
-rw-r--r--drivers/usb/cdns3/cdnsp-gadget.c2
-rw-r--r--drivers/usb/cdns3/core.c5
-rw-r--r--drivers/usb/cdns3/core.h2
-rw-r--r--drivers/usb/cdns3/host.c11
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c10
-rw-r--r--drivers/usb/common/usb-conn-gpio.c2
-rw-r--r--drivers/usb/core/config.c51
-rw-r--r--drivers/usb/core/hcd.c10
-rw-r--r--drivers/usb/core/hub.c6
-rw-r--r--drivers/usb/core/urb.c2
-rw-r--r--drivers/usb/dwc2/core.c1
-rw-r--r--drivers/usb/dwc2/core.h23
-rw-r--r--drivers/usb/dwc2/gadget.c116
-rw-r--r--drivers/usb/dwc2/hcd.c101
-rw-r--r--drivers/usb/dwc2/hcd_queue.c4
-rw-r--r--drivers/usb/dwc2/platform.c38
-rw-r--r--drivers/usb/dwc3/dwc3-am62.c12
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c9
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c10
-rw-r--r--drivers/usb/dwc3/dwc3-st.c2
-rw-r--r--drivers/usb/dwc3/gadget.c69
-rw-r--r--drivers/usb/gadget/function/uvc_queue.c2
-rw-r--r--drivers/usb/gadget/legacy/zero.c4
-rw-r--r--drivers/usb/gadget/udc/aspeed-vhub/dev.c3
-rw-r--r--drivers/usb/gadget/udc/omap_udc.c2
-rw-r--r--drivers/usb/gadget/udc/pxa25x_udc.c8
-rw-r--r--drivers/usb/gadget/udc/r8a66597-udc.c2
-rw-r--r--drivers/usb/gadget/udc/snps_udc_core.c4
-rw-r--r--drivers/usb/host/ehci-platform.c2
-rw-r--r--drivers/usb/host/isp1362-hcd.c2
-rw-r--r--drivers/usb/host/max3421-hcd.c7
-rw-r--r--drivers/usb/host/ohci-hcd.c2
-rw-r--r--drivers/usb/host/ohci-hub.c2
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c6
-rw-r--r--drivers/usb/host/r8a66597-hcd.c2
-rw-r--r--drivers/usb/host/sl811-hcd.c2
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-q.c2
-rw-r--r--drivers/usb/host/xen-hcd.c4
-rw-r--r--drivers/usb/host/xhci-histb.c2
-rw-r--r--drivers/usb/host/xhci-hub.c2
-rw-r--r--drivers/usb/host/xhci-mem.c34
-rw-r--r--drivers/usb/host/xhci-mtk.c4
-rw-r--r--drivers/usb/host/xhci-mvebu.c10
-rw-r--r--drivers/usb/host/xhci-mvebu.h6
-rw-r--r--drivers/usb/host/xhci-pci.c8
-rw-r--r--drivers/usb/host/xhci-plat.c13
-rw-r--r--drivers/usb/host/xhci-plat.h1
-rw-r--r--drivers/usb/host/xhci-ring.c420
-rw-r--r--drivers/usb/host/xhci-tegra.c10
-rw-r--r--drivers/usb/host/xhci.c55
-rw-r--r--drivers/usb/host/xhci.h30
-rw-r--r--drivers/usb/isp1760/isp1760-hcd.c2
-rw-r--r--drivers/usb/isp1760/isp1760-udc.c4
-rw-r--r--drivers/usb/misc/onboard_usb_dev.h9
-rw-r--r--drivers/usb/misc/usb251xb.c6
-rw-r--r--drivers/usb/misc/usbtest.c2
-rw-r--r--drivers/usb/musb/da8xx.c6
-rw-r--r--drivers/usb/musb/jz4740.c4
-rw-r--r--drivers/usb/musb/mediatek.c2
-rw-r--r--drivers/usb/musb/mpfs.c6
-rw-r--r--drivers/usb/musb/musb_core.c18
-rw-r--r--drivers/usb/musb/musb_dsps.c8
-rw-r--r--drivers/usb/musb/sunxi.c4
-rw-r--r--drivers/usb/musb/tusb6010.c8
-rw-r--r--drivers/usb/phy/phy-mv-usb.c2
-rw-r--r--drivers/usb/phy/phy-mxs-usb.c8
-rw-r--r--drivers/usb/phy/phy-ulpi.c23
-rw-r--r--drivers/usb/serial/mos7840.c13
-rw-r--r--drivers/usb/storage/alauda.c8
-rw-r--r--drivers/usb/storage/datafab.c14
-rw-r--r--drivers/usb/storage/initializers.c2
-rw-r--r--drivers/usb/storage/jumpshot.c10
-rw-r--r--drivers/usb/storage/realtek_cr.c8
-rw-r--r--drivers/usb/storage/sddr09.c14
-rw-r--r--drivers/usb/storage/sddr55.c4
-rw-r--r--drivers/usb/storage/shuttle_usbat.c2
-rw-r--r--drivers/usb/storage/transport.c2
-rw-r--r--drivers/usb/typec/altmodes/thunderbolt.c10
-rw-r--r--drivers/usb/typec/mux/Kconfig10
-rw-r--r--drivers/usb/typec/mux/Makefile1
-rw-r--r--drivers/usb/typec/mux/ps883x.c466
-rw-r--r--drivers/usb/typec/ucsi/cros_ec_ucsi.c22
-rw-r--r--drivers/usb/typec/ucsi/debugfs.c6
-rw-r--r--drivers/usb/typec/ucsi/trace.c2
-rw-r--r--drivers/usb/typec/ucsi/ucsi.c19
-rw-r--r--drivers/usb/typec/ucsi/ucsi.h10
-rw-r--r--drivers/usb/typec/ucsi/ucsi_acpi.c29
-rw-r--r--drivers/usb/typec/ucsi/ucsi_ccg.c97
-rw-r--r--drivers/vdpa/mlx5/core/mr.c7
-rw-r--r--drivers/vdpa/mlx5/net/mlx5_vnet.c3
-rw-r--r--drivers/vdpa/vdpa_user/vduse_dev.c1
-rw-r--r--drivers/vfio/device_cdev.c60
-rw-r--r--drivers/vfio/iommufd.c60
-rw-r--r--drivers/vfio/pci/vfio_pci.c6
-rw-r--r--drivers/vfio/pci/vfio_pci_config.c3
-rw-r--r--drivers/vfio/pci/vfio_pci_core.c10
-rw-r--r--drivers/vfio/pci/vfio_pci_igd.c6
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c2
-rw-r--r--drivers/vfio/pci/vfio_pci_priv.h6
-rw-r--r--drivers/vfio/pci/virtio/Kconfig6
-rw-r--r--drivers/vfio/pci/virtio/legacy_io.c4
-rw-r--r--drivers/vfio/pci/virtio/main.c5
-rw-r--r--drivers/vfio/vfio_iommu_type1.c123
-rw-r--r--drivers/vhost/Kconfig1
-rw-r--r--drivers/vhost/scsi.c547
-rw-r--r--drivers/video/fbdev/aty/radeon_backlight.c2
-rw-r--r--drivers/video/fbdev/aty/radeon_base.c4
-rw-r--r--drivers/video/fbdev/aty/radeon_pm.c2
-rw-r--r--drivers/video/fbdev/omap/hwa742.c2
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dsi.c2
-rw-r--r--drivers/virt/vboxguest/vboxguest_core.c2
-rw-r--r--drivers/virtio/virtio.c29
-rw-r--r--drivers/watchdog/Kconfig22
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/alim7101_wdt.c4
-rw-r--r--drivers/watchdog/aspeed_wdt.c81
-rw-r--r--drivers/watchdog/at91sam9_wdt.c4
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c4
-rw-r--r--drivers/watchdog/cpwd.c4
-rw-r--r--drivers/watchdog/cros_ec_wdt.c10
-rw-r--r--drivers/watchdog/lenovo_se30_wdt.c394
-rw-r--r--drivers/watchdog/lpc18xx_wdt.c4
-rw-r--r--drivers/watchdog/machzwd.c4
-rw-r--r--drivers/watchdog/mixcomwd.c4
-rw-r--r--drivers/watchdog/nic7018_wdt.c9
-rw-r--r--drivers/watchdog/npcm_wdt.c9
-rw-r--r--drivers/watchdog/pcwd.c2
-rw-r--r--drivers/watchdog/pika_wdt.c2
-rw-r--r--drivers/watchdog/s3c2410_wdt.c10
-rw-r--r--drivers/watchdog/sbc60xxwdt.c4
-rw-r--r--drivers/watchdog/sc520_wdt.c2
-rw-r--r--drivers/watchdog/shwdt.c2
-rw-r--r--drivers/watchdog/sunxi_wdt.c11
-rw-r--r--drivers/watchdog/via_wdt.c2
-rw-r--r--drivers/watchdog/w83877f_wdt.c4
-rw-r--r--drivers/watchdog/watchdog_core.c6
1163 files changed, 16760 insertions, 24641 deletions
diff --git a/drivers/accel/qaic/qaic_timesync.c b/drivers/accel/qaic/qaic_timesync.c
index 2473c66309d4..972833fabcfc 100644
--- a/drivers/accel/qaic/qaic_timesync.c
+++ b/drivers/accel/qaic/qaic_timesync.c
@@ -221,7 +221,7 @@ static void qaic_timesync_remove(struct mhi_device *mhi_dev)
{
struct mqts_dev *mqtsdev = dev_get_drvdata(&mhi_dev->dev);
- del_timer_sync(&mqtsdev->timer);
+ timer_delete_sync(&mqtsdev->timer);
mhi_unprepare_from_transfer(mqtsdev->mhi_dev);
kfree(mqtsdev->sync_msg);
kfree(mqtsdev);
diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c
index f677ad2177c2..e68cf1d83787 100644
--- a/drivers/accessibility/speakup/main.c
+++ b/drivers/accessibility/speakup/main.c
@@ -1172,13 +1172,13 @@ static void do_handle_shift(struct vc_data *vc, u_char value, char up_flag)
if (cursor_track == read_all_mode) {
switch (value) {
case KVAL(K_SHIFT):
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
spk_shut_up &= 0xfe;
spk_do_flush();
read_all_doc(vc);
break;
case KVAL(K_CTRL):
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
cursor_track = prev_cursor_track;
spk_shut_up &= 0xfe;
spk_do_flush();
@@ -1399,7 +1399,7 @@ static void start_read_all_timer(struct vc_data *vc, enum read_all_command comma
static void kbd_fakekey2(struct vc_data *vc, enum read_all_command command)
{
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
speakup_fake_down_arrow();
start_read_all_timer(vc, command);
}
@@ -1415,7 +1415,7 @@ static void read_all_doc(struct vc_data *vc)
cursor_track = read_all_mode;
spk_reset_index_count(0);
if (get_sentence_buf(vc, 0) == -1) {
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
if (!in_keyboard_notifier)
speakup_fake_down_arrow();
start_read_all_timer(vc, RA_DOWN_ARROW);
@@ -1428,7 +1428,7 @@ static void read_all_doc(struct vc_data *vc)
static void stop_read_all(struct vc_data *vc)
{
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
cursor_track = prev_cursor_track;
spk_shut_up &= 0xfe;
spk_do_flush();
@@ -1528,7 +1528,7 @@ static int pre_handle_cursor(struct vc_data *vc, u_char value, char up_flag)
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
return NOTIFY_STOP;
}
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
spk_shut_up &= 0xfe;
spk_do_flush();
start_read_all_timer(vc, value + 1);
@@ -1692,7 +1692,7 @@ static void cursor_done(struct timer_list *unused)
struct vc_data *vc = vc_cons[cursor_con].d;
unsigned long flags;
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
spin_lock_irqsave(&speakup_info.spinlock, flags);
if (cursor_con != fg_console) {
is_cursor = 0;
@@ -2333,7 +2333,7 @@ static void __exit speakup_exit(void)
speakup_unregister_devsynth();
speakup_cancel_selection();
speakup_cancel_paste();
- del_timer_sync(&cursor_timer);
+ timer_delete_sync(&cursor_timer);
kthread_stop(speakup_task);
speakup_task = NULL;
mutex_lock(&spk_mutex);
@@ -2437,7 +2437,7 @@ error_task:
error_vtnotifier:
unregister_keyboard_notifier(&keyboard_notifier_block);
- del_timer(&cursor_timer);
+ timer_delete(&cursor_timer);
error_kbdnotifier:
speakup_unregister_devsynth();
diff --git a/drivers/accessibility/speakup/synth.c b/drivers/accessibility/speakup/synth.c
index 85062e605d79..d8addbf3ad0d 100644
--- a/drivers/accessibility/speakup/synth.c
+++ b/drivers/accessibility/speakup/synth.c
@@ -521,7 +521,7 @@ void synth_release(void)
spin_lock_irqsave(&speakup_info.spinlock, flags);
pr_info("releasing synth %s\n", synth->name);
synth->alive = 0;
- del_timer(&thread_timer);
+ timer_delete(&thread_timer);
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
if (synth->attributes.name)
sysfs_remove_group(speakup_kobj, &synth->attributes);
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c
index 435ec60a9682..4ad88187dc7a 100644
--- a/drivers/acpi/acpi_pnp.c
+++ b/drivers/acpi/acpi_pnp.c
@@ -353,8 +353,10 @@ static bool acpi_pnp_match(const char *idstr, const struct acpi_device_id **matc
* device represented by it.
*/
static const struct acpi_device_id acpi_nonpnp_device_ids[] = {
+ {"INT3F0D"},
{"INTC1080"},
{"INTC1081"},
+ {"INTC1099"},
{""},
};
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index efdadc74e3f4..103f29661576 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -649,6 +649,13 @@ acpi_video_device_EDID(struct acpi_video_device *device, void **edid, int length
obj = buffer.pointer;
+ /*
+ * Some buggy implementations incorrectly return the EDID buffer in an ACPI package.
+ * In this case, extract the buffer from the package.
+ */
+ if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 1)
+ obj = &obj->package.elements[0];
+
if (obj && obj->type == ACPI_TYPE_BUFFER) {
*edid = kmemdup(obj->buffer.pointer, obj->buffer.length, GFP_KERNEL);
ret = *edid ? obj->buffer.length : -ENOMEM;
@@ -658,7 +665,7 @@ acpi_video_device_EDID(struct acpi_video_device *device, void **edid, int length
ret = -EFAULT;
}
- kfree(obj);
+ kfree(buffer.pointer);
return ret;
}
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index b72772494655..289e365f84b2 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -674,6 +674,105 @@ static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
schedule_work(&entry->work);
}
+/* Room for 8 entries */
+#define CXL_CPER_PROT_ERR_FIFO_DEPTH 8
+static DEFINE_KFIFO(cxl_cper_prot_err_fifo, struct cxl_cper_prot_err_work_data,
+ CXL_CPER_PROT_ERR_FIFO_DEPTH);
+
+/* Synchronize schedule_work() with cxl_cper_prot_err_work changes */
+static DEFINE_SPINLOCK(cxl_cper_prot_err_work_lock);
+struct work_struct *cxl_cper_prot_err_work;
+
+static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
+ int severity)
+{
+#ifdef CONFIG_ACPI_APEI_PCIEAER
+ struct cxl_cper_prot_err_work_data wd;
+ u8 *dvsec_start, *cap_start;
+
+ if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {
+ pr_err_ratelimited("CXL CPER invalid agent type\n");
+ return;
+ }
+
+ if (!(prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG)) {
+ pr_err_ratelimited("CXL CPER invalid protocol error log\n");
+ return;
+ }
+
+ if (prot_err->err_len != sizeof(struct cxl_ras_capability_regs)) {
+ pr_err_ratelimited("CXL CPER invalid RAS Cap size (%u)\n",
+ prot_err->err_len);
+ return;
+ }
+
+ if (!(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
+ pr_warn(FW_WARN "CXL CPER no device serial number\n");
+
+ guard(spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
+
+ if (!cxl_cper_prot_err_work)
+ return;
+
+ switch (prot_err->agent_type) {
+ case RCD:
+ case DEVICE:
+ case LD:
+ case FMLD:
+ case RP:
+ case DSP:
+ case USP:
+ memcpy(&wd.prot_err, prot_err, sizeof(wd.prot_err));
+
+ dvsec_start = (u8 *)(prot_err + 1);
+ cap_start = dvsec_start + prot_err->dvsec_len;
+
+ memcpy(&wd.ras_cap, cap_start, sizeof(wd.ras_cap));
+ wd.severity = cper_severity_to_aer(severity);
+ break;
+ default:
+ pr_err_ratelimited("CXL CPER invalid agent type: %d\n",
+ prot_err->agent_type);
+ return;
+ }
+
+ if (!kfifo_put(&cxl_cper_prot_err_fifo, wd)) {
+ pr_err_ratelimited("CXL CPER kfifo overflow\n");
+ return;
+ }
+
+ schedule_work(cxl_cper_prot_err_work);
+#endif
+}
+
+int cxl_cper_register_prot_err_work(struct work_struct *work)
+{
+ if (cxl_cper_prot_err_work)
+ return -EINVAL;
+
+ guard(spinlock)(&cxl_cper_prot_err_work_lock);
+ cxl_cper_prot_err_work = work;
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_cper_register_prot_err_work, "CXL");
+
+int cxl_cper_unregister_prot_err_work(struct work_struct *work)
+{
+ if (cxl_cper_prot_err_work != work)
+ return -EINVAL;
+
+ guard(spinlock)(&cxl_cper_prot_err_work_lock);
+ cxl_cper_prot_err_work = NULL;
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_prot_err_work, "CXL");
+
+int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
+{
+ return kfifo_get(&cxl_cper_prot_err_fifo, wd);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_cper_prot_err_kfifo_get, "CXL");
+
/* Room for 8 entries for each of the 4 event log queues */
#define CXL_CPER_FIFO_DEPTH 32
DEFINE_KFIFO(cxl_cper_fifo, struct cxl_cper_work_data, CXL_CPER_FIFO_DEPTH);
@@ -777,6 +876,10 @@ static bool ghes_do_proc(struct ghes *ghes,
}
else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
queued = ghes_handle_arm_hw_error(gdata, sev, sync);
+ } else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
+ struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
+
+ cxl_cper_post_prot_err(prot_err, gdata->error_severity);
} else if (guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID)) {
struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata);
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index a5d47819b3a4..ae035b93da08 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -485,7 +485,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
cmd_mask = nd_desc->cmd_mask;
if (cmd == ND_CMD_CALL && call_pkg->nd_family) {
family = call_pkg->nd_family;
- if (family > NVDIMM_BUS_FAMILY_MAX ||
+ if (call_pkg->nd_family > NVDIMM_BUS_FAMILY_MAX ||
!test_bit(family, &nd_desc->bus_family_mask))
return -EINVAL;
family = array_index_nospec(family,
diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c
index bfbb08b1e6af..9d9052258e92 100644
--- a/drivers/acpi/numa/hmat.c
+++ b/drivers/acpi/numa/hmat.c
@@ -108,6 +108,45 @@ static struct memory_target *find_mem_target(unsigned int mem_pxm)
return NULL;
}
+/**
+ * hmat_get_extended_linear_cache_size - Retrieve the extended linear cache size
+ * @backing_res: resource from the backing media
+ * @nid: node id for the memory region
+ * @cache_size: (Output) size of extended linear cache.
+ *
+ * Return: 0 on success. Errno on failure.
+ *
+ */
+int hmat_get_extended_linear_cache_size(struct resource *backing_res, int nid,
+ resource_size_t *cache_size)
+{
+ unsigned int pxm = node_to_pxm(nid);
+ struct memory_target *target;
+ struct target_cache *tcache;
+ struct resource *res;
+
+ target = find_mem_target(pxm);
+ if (!target)
+ return -ENOENT;
+
+ list_for_each_entry(tcache, &target->caches, node) {
+ if (tcache->cache_attrs.address_mode !=
+ NODE_CACHE_ADDR_MODE_EXTENDED_LINEAR)
+ continue;
+
+ res = &target->memregions;
+ if (!resource_contains(res, backing_res))
+ continue;
+
+ *cache_size = tcache->cache_attrs.size;
+ return 0;
+ }
+
+ *cache_size = 0;
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(hmat_get_extended_linear_cache_size, "CXL");
+
static struct memory_target *acpi_find_genport_target(u32 uid)
{
struct memory_target *target;
@@ -506,6 +545,11 @@ static __init int hmat_parse_cache(union acpi_subtable_headers *header,
switch ((attrs & ACPI_HMAT_CACHE_ASSOCIATIVITY) >> 8) {
case ACPI_HMAT_CA_DIRECT_MAPPED:
tcache->cache_attrs.indexing = NODE_CACHE_DIRECT_MAP;
+ /* Extended Linear mode is only valid if cache is direct mapped */
+ if (cache->address_mode == ACPI_HMAT_CACHE_MODE_EXTENDED_LINEAR) {
+ tcache->cache_attrs.address_mode =
+ NODE_CACHE_ADDR_MODE_EXTENDED_LINEAR;
+ }
break;
case ACPI_HMAT_CA_COMPLEX_CACHE_INDEXING:
tcache->cache_attrs.indexing = NODE_CACHE_INDEXED;
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index ce815d7cb8f6..0a725e46d017 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -18,6 +18,7 @@
#include <linux/nodemask.h>
#include <linux/topology.h>
#include <linux/numa_memblks.h>
+#include <linux/string_choices.h>
static nodemask_t nodes_found_map = NODE_MASK_NONE;
@@ -188,8 +189,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
pr_debug("SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
p->apic_id, p->local_sapic_eid,
p->proximity_domain_lo,
- (p->flags & ACPI_SRAT_CPU_ENABLED) ?
- "enabled" : "disabled");
+ str_enabled_disabled(p->flags & ACPI_SRAT_CPU_ENABLED));
}
break;
@@ -201,8 +201,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
(unsigned long long)p->base_address,
(unsigned long long)p->length,
p->proximity_domain,
- (p->flags & ACPI_SRAT_MEM_ENABLED) ?
- "enabled" : "disabled",
+ str_enabled_disabled(p->flags & ACPI_SRAT_MEM_ENABLED),
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
" hot-pluggable" : "",
(p->flags & ACPI_SRAT_MEM_NON_VOLATILE) ?
@@ -217,8 +216,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
pr_debug("SRAT Processor (x2apicid[0x%08x]) in proximity domain %d %s\n",
p->apic_id,
p->proximity_domain,
- (p->flags & ACPI_SRAT_CPU_ENABLED) ?
- "enabled" : "disabled");
+ str_enabled_disabled(p->flags & ACPI_SRAT_CPU_ENABLED));
}
break;
@@ -229,8 +227,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
pr_debug("SRAT Processor (acpi id[0x%04x]) in proximity domain %d %s\n",
p->acpi_processor_uid,
p->proximity_domain,
- (p->flags & ACPI_SRAT_GICC_ENABLED) ?
- "enabled" : "disabled");
+ str_enabled_disabled(p->flags & ACPI_SRAT_GICC_ENABLED));
}
break;
@@ -248,8 +245,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
*(u16 *)(&p->device_handle[0]),
*(u16 *)(&p->device_handle[2]),
p->proximity_domain,
- (p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED) ?
- "enabled" : "disabled");
+ str_enabled_disabled(p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED));
} else {
/*
* In this case we can rely on the device having a
@@ -259,8 +255,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
(char *)(&p->device_handle[0]),
(char *)(&p->device_handle[8]),
p->proximity_domain,
- (p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED) ?
- "enabled" : "disabled");
+ str_enabled_disabled(p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED));
}
}
break;
@@ -272,8 +267,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
pr_debug("SRAT Processor (acpi id[0x%04x]) in proximity domain %d %s\n",
p->acpi_processor_uid,
p->proximity_domain,
- (p->flags & ACPI_SRAT_RINTC_ENABLED) ?
- "enabled" : "disabled");
+ str_enabled_disabled(p->flags & ACPI_SRAT_RINTC_ENABLED));
}
break;
diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c
index 671407fc2bd4..ffbfd32f4cf1 100644
--- a/drivers/acpi/platform_profile.c
+++ b/drivers/acpi/platform_profile.c
@@ -245,7 +245,8 @@ static const struct class platform_profile_class = {
/**
* _aggregate_choices - Aggregate the available profile choices
* @dev: The device
- * @arg: struct aggregate_choices_data
+ * @arg: struct aggregate_choices_data, with it's aggregate member bitmap
+ * initially filled with ones
*
* Return: 0 on success, -errno on failure
*/
@@ -256,12 +257,10 @@ static int _aggregate_choices(struct device *dev, void *arg)
struct platform_profile_handler *handler;
lockdep_assert_held(&profile_lock);
+
handler = to_pprof_handler(dev);
bitmap_or(tmp, handler->choices, handler->hidden_choices, PLATFORM_PROFILE_LAST);
- if (test_bit(PLATFORM_PROFILE_LAST, data->aggregate))
- bitmap_copy(data->aggregate, tmp, PLATFORM_PROFILE_LAST);
- else
- bitmap_and(data->aggregate, tmp, data->aggregate, PLATFORM_PROFILE_LAST);
+ bitmap_and(data->aggregate, tmp, data->aggregate, PLATFORM_PROFILE_LAST);
data->count++;
return 0;
@@ -305,7 +304,6 @@ static ssize_t platform_profile_choices_show(struct kobject *kobj,
};
int err;
- set_bit(PLATFORM_PROFILE_LAST, data.aggregate);
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
err = class_for_each_device(&platform_profile_class, NULL,
&data, _aggregate_choices);
@@ -422,7 +420,7 @@ static ssize_t platform_profile_store(struct kobject *kobj,
i = sysfs_match_string(profile_names, buf);
if (i < 0 || i == PLATFORM_PROFILE_CUSTOM)
return -EINVAL;
- set_bit(PLATFORM_PROFILE_LAST, data.aggregate);
+
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
ret = class_for_each_device(&platform_profile_class, NULL,
&data, _aggregate_choices);
@@ -502,7 +500,6 @@ int platform_profile_cycle(void)
enum platform_profile_option profile = PLATFORM_PROFILE_LAST;
int err;
- set_bit(PLATFORM_PROFILE_LAST, data.aggregate);
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
err = class_for_each_device(&platform_profile_class, NULL,
&profile, _aggregate_profiles);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 586cc7d1d8aa..b181f7fc2090 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -268,6 +268,10 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
ACPI_CX_DESC_LEN, "ACPI P_LVL3 IOPORT 0x%x",
pr->power.states[ACPI_STATE_C3].address);
+ if (!pr->power.states[ACPI_STATE_C2].address &&
+ !pr->power.states[ACPI_STATE_C3].address)
+ return -ENODEV;
+
return 0;
}
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index b4cd14e7fa76..14c7bac4100b 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -441,6 +441,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
},
},
{
+ /* Asus Vivobook X1404VAP */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "X1404VAP"),
+ },
+ },
+ {
/* Asus Vivobook X1504VAP */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
index 068c1612660b..4ee30c2897a2 100644
--- a/drivers/acpi/x86/utils.c
+++ b/drivers/acpi/x86/utils.c
@@ -374,7 +374,8 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
},
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
- ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+ ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
},
{
/* Medion Lifetab S10346 */
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 16cd676eae1f..b990c1ee0b12 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -700,7 +700,7 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
ata_eh_acquire(ap);
repeat:
/* kill fast drain timer */
- del_timer_sync(&ap->fastdrain_timer);
+ timer_delete_sync(&ap->fastdrain_timer);
/* process port resume request */
ata_eh_handle_port_resume(ap);
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
index fcd70e094a2e..e6a300203e6c 100644
--- a/drivers/atm/idt77105.c
+++ b/drivers/atm/idt77105.c
@@ -366,8 +366,8 @@ EXPORT_SYMBOL(idt77105_init);
static void __exit idt77105_exit(void)
{
/* turn off timers */
- del_timer_sync(&stats_timer);
- del_timer_sync(&restart_timer);
+ timer_delete_sync(&stats_timer);
+ timer_delete_sync(&restart_timer);
}
module_exit(idt77105_exit);
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index d213adcefe33..301e697e22ad 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -3283,7 +3283,7 @@ static void __exit ia_module_exit(void)
{
pci_unregister_driver(&ia_driver);
- del_timer_sync(&ia_timer);
+ timer_delete_sync(&ia_timer);
}
module_init(ia_module_init);
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 32d7aa141d96..00fe25b5b6a3 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -1792,7 +1792,7 @@ static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)
{
- del_timer_sync(&lanai->timer);
+ timer_delete_sync(&lanai->timer);
}
/* -------------------- INTERRUPT SERVICE: */
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 27153d6bc781..45952cfea06b 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -300,7 +300,7 @@ static void __exit nicstar_cleanup(void)
{
XPRINTK("nicstar: nicstar_cleanup() called.\n");
- del_timer_sync(&ns_timer);
+ timer_delete_sync(&ns_timer);
pci_unregister_driver(&nicstar_driver);
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c
index 32802ea9521c..7d0fa729c2fe 100644
--- a/drivers/atm/suni.c
+++ b/drivers/atm/suni.c
@@ -347,7 +347,7 @@ static int suni_stop(struct atm_dev *dev)
for (walk = &sunis; *walk != PRIV(dev);
walk = &PRIV((*walk)->dev)->next);
*walk = PRIV((*walk)->dev)->next;
- if (!sunis) del_timer_sync(&poll_timer);
+ if (!sunis) timer_delete_sync(&poll_timer);
spin_unlock_irqrestore(&sunis_lock,flags);
kfree(PRIV(dev));
diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c
index fcec77f100ce..b6808c4f89b6 100644
--- a/drivers/auxdisplay/line-display.c
+++ b/drivers/auxdisplay/line-display.c
@@ -84,7 +84,7 @@ static int linedisp_display(struct linedisp *linedisp, const char *msg,
char *new_msg;
/* stop the scroll timer */
- del_timer_sync(&linedisp->timer);
+ timer_delete_sync(&linedisp->timer);
if (count == -1)
count = strlen(msg);
@@ -183,7 +183,7 @@ static ssize_t scroll_step_ms_store(struct device *dev,
linedisp->scroll_rate = msecs_to_jiffies(ms);
if (linedisp->message && linedisp->message_len > linedisp->num_chars) {
- del_timer_sync(&linedisp->timer);
+ timer_delete_sync(&linedisp->timer);
if (linedisp->scroll_rate)
linedisp_scroll(&linedisp->timer);
}
@@ -376,7 +376,7 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent,
out_del_dev:
device_del(&linedisp->dev);
out_del_timer:
- del_timer_sync(&linedisp->timer);
+ timer_delete_sync(&linedisp->timer);
out_put_device:
put_device(&linedisp->dev);
return err;
@@ -391,7 +391,7 @@ EXPORT_SYMBOL_NS_GPL(linedisp_register, "LINEDISP");
void linedisp_unregister(struct linedisp *linedisp)
{
device_del(&linedisp->dev);
- del_timer_sync(&linedisp->timer);
+ timer_delete_sync(&linedisp->timer);
put_device(&linedisp->dev);
}
EXPORT_SYMBOL_NS_GPL(linedisp_unregister, "LINEDISP");
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
index 91ccb9789d43..958c0e31e84a 100644
--- a/drivers/auxdisplay/panel.c
+++ b/drivers/auxdisplay/panel.c
@@ -1654,7 +1654,7 @@ static void panel_attach(struct parport *port)
err_lcd_unreg:
if (scan_timer.function)
- del_timer_sync(&scan_timer);
+ timer_delete_sync(&scan_timer);
if (lcd.enabled)
charlcd_unregister(lcd.charlcd);
err_unreg_device:
@@ -1675,7 +1675,7 @@ static void panel_detach(struct parport *port)
return;
}
if (scan_timer.function)
- del_timer_sync(&scan_timer);
+ timer_delete_sync(&scan_timer);
if (keypad.enabled) {
misc_deregister(&keypad_dev);
diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c
index 64840e5d5fcc..03a39c417dc4 100644
--- a/drivers/base/devcoredump.c
+++ b/drivers/base/devcoredump.c
@@ -41,7 +41,7 @@ struct devcd_entry {
* devcd_data_write()
* mod_delayed_work()
* try_to_grab_pending()
- * del_timer()
+ * timer_delete()
* debug_assert_init()
* INIT_DELAYED_WORK()
* schedule_delayed_work()
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 0ea653fa3433..cd13ef287011 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -244,12 +244,14 @@ CACHE_ATTR(size, "%llu")
CACHE_ATTR(line_size, "%u")
CACHE_ATTR(indexing, "%u")
CACHE_ATTR(write_policy, "%u")
+CACHE_ATTR(address_mode, "%#x")
static struct attribute *cache_attrs[] = {
&dev_attr_indexing.attr,
&dev_attr_size.attr,
&dev_attr_line_size.attr,
&dev_attr_write_policy.attr,
+ &dev_attr_address_mode.attr,
NULL,
};
ATTRIBUTE_GROUPS(cache);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index ac2a197c1234..c8b0a9e29ed8 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -559,7 +559,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd)
{
struct timer_list *timer = &wd->timer;
- del_timer_sync(timer);
+ timer_delete_sync(timer);
destroy_timer_on_stack(timer);
}
#else
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 752b417e8129..63bf914a4d44 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -197,7 +197,7 @@ void wakeup_source_remove(struct wakeup_source *ws)
raw_spin_unlock_irqrestore(&events_lock, flags);
synchronize_srcu(&wakeup_srcu);
- del_timer_sync(&ws->timer);
+ timer_delete_sync(&ws->timer);
/*
* Clear timer.function to make wakeup_source_not_registered() treat
* this wakeup source as not registered.
@@ -613,7 +613,7 @@ void __pm_stay_awake(struct wakeup_source *ws)
spin_lock_irqsave(&ws->lock, flags);
wakeup_source_report_event(ws, false);
- del_timer(&ws->timer);
+ timer_delete(&ws->timer);
ws->timer_expires = 0;
spin_unlock_irqrestore(&ws->lock, flags);
@@ -693,7 +693,7 @@ static void wakeup_source_deactivate(struct wakeup_source *ws)
ws->max_time = duration;
ws->last_time = now;
- del_timer(&ws->timer);
+ timer_delete(&ws->timer);
ws->timer_expires = 0;
if (ws->autosleep_enabled)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 9edd4468f755..6357d86eafdc 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -457,7 +457,7 @@ static int fd_motor_on(int nr)
{
nr &= 3;
- del_timer(motor_off_timer + nr);
+ timer_delete(motor_off_timer + nr);
if (!unit[nr].motor) {
unit[nr].motor = 1;
@@ -1393,7 +1393,7 @@ static int non_int_flush_track (unsigned long nr)
nr&=3;
writefromint = 0;
- del_timer(&post_write_timer);
+ timer_delete(&post_write_timer);
get_fdc(nr);
if (!fd_motor_on(nr)) {
writepending = 0;
@@ -1435,7 +1435,7 @@ static int get_track(int drive, int track)
}
if (unit[drive].dirty == 1) {
- del_timer (flush_track_timer + drive);
+ timer_delete(flush_track_timer + drive);
non_int_flush_track (drive);
}
errcnt = 0;
@@ -1591,7 +1591,7 @@ static int fd_locked_ioctl(struct block_device *bdev, blk_mode_t mode,
case FDDEFPRM:
return -EINVAL;
case FDFLUSH: /* unconditionally, even if not needed */
- del_timer (flush_track_timer + drive);
+ timer_delete(flush_track_timer + drive);
non_int_flush_track(drive);
break;
#ifdef RAW_IOCTL
@@ -1714,7 +1714,7 @@ static void floppy_release(struct gendisk *disk)
mutex_lock(&amiflop_mutex);
if (unit[drive].dirty == 1) {
- del_timer (flush_track_timer + drive);
+ timer_delete(flush_track_timer + drive);
non_int_flush_track (drive);
}
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 4db7f6ce8ade..141b2a0e03f2 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -274,7 +274,7 @@ freedev(struct aoedev *d)
if (!freeing)
return;
- del_timer_sync(&d->timer);
+ timer_delete_sync(&d->timer);
if (d->gd) {
aoedisk_rm_debugfs(d);
del_gendisk(d->gd);
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
index 6238c4c87cfc..cdf6e4041bb9 100644
--- a/drivers/block/aoe/aoemain.c
+++ b/drivers/block/aoe/aoemain.c
@@ -28,7 +28,7 @@ static void discover_timer(struct timer_list *t)
static void __exit
aoe_exit(void)
{
- del_timer_sync(&timer);
+ timer_delete_sync(&timer);
aoenet_exit();
unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index a81ade622a01..7fe14266c12c 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -494,7 +494,7 @@ static inline void start_timeout(void)
static inline void stop_timeout(void)
{
- del_timer(&timeout_timer);
+ timer_delete(&timeout_timer);
}
/* Select the side to use. */
@@ -784,7 +784,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
contents become invalid! */
BufferDrive = -1;
/* stop deselect timer */
- del_timer( &motor_off_timer );
+ timer_delete(&motor_off_timer);
FILL( 60 * (nsect / 9), 0x4e );
for( sect = 0; sect < nsect; ++sect ) {
@@ -1138,7 +1138,7 @@ static void fd_rwsec_done( int status )
DPRINT(("fd_rwsec_done()\n"));
if (read_track) {
- del_timer(&readtrack_timer);
+ timer_delete(&readtrack_timer);
if (!MultReadInProgress)
return;
MultReadInProgress = 0;
@@ -1356,7 +1356,7 @@ static void fd_times_out(struct timer_list *unused)
/* If the timeout occurred while the readtrack_check timer was
* active, we need to cancel it, else bad things will happen */
if (UseTrackbuffer)
- del_timer( &readtrack_timer );
+ timer_delete(&readtrack_timer);
FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
udelay( 25 );
@@ -1566,7 +1566,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
}
/* stop deselect timer */
- del_timer( &motor_off_timer );
+ timer_delete(&motor_off_timer);
ReqCnt = 0;
ReqCmd = rq_data_dir(fd_request);
@@ -2055,7 +2055,7 @@ static void atari_floppy_cleanup(void)
blk_mq_free_tag_set(&unit[i].tag_set);
}
- del_timer_sync(&fd_timer);
+ timer_delete_sync(&fd_timer);
atari_stram_free(DMABuffer);
}
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 5bbd312c3e14..ced2cc5f46f2 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3034,7 +3034,7 @@ void drbd_md_sync(struct drbd_device *device)
BUILD_BUG_ON(UI_SIZE != 4);
BUILD_BUG_ON(sizeof(struct meta_data_on_disk) != 4096);
- del_timer(&device->md_sync_timer);
+ timer_delete(&device->md_sync_timer);
/* timer may be rearmed by drbd_md_mark_dirty() now. */
if (!test_and_clear_bit(MD_DIRTY, &device->flags))
return;
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 720fc30e2ecc..e09930c2b226 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1033,7 +1033,7 @@ drbd_determine_dev_size(struct drbd_device *device, enum dds_flags flags, struct
/* We do some synchronous IO below, which may take some time.
* Clear the timer, to avoid scary "timer expired!" messages,
* "Superblock" is written out at least twice below, anyways. */
- del_timer(&device->md_sync_timer);
+ timer_delete(&device->md_sync_timer);
/* We won't change the "al-extents" setting, we just may need
* to move the on-disk location of the activity log ringbuffer.
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 0c9f54197768..e5a2e5f7887b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -5187,7 +5187,7 @@ static int drbd_disconnected(struct drbd_peer_device *peer_device)
atomic_set(&device->rs_pending_cnt, 0);
wake_up(&device->misc_wait);
- del_timer_sync(&device->resync_timer);
+ timer_delete_sync(&device->resync_timer);
resync_timer_fn(&device->resync_timer);
/* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier,
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index abf0486f0d4f..e97432032f01 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -937,7 +937,7 @@ static void floppy_off(unsigned int drive)
if (!(fdc_state[fdc].dor & (0x10 << UNIT(drive))))
return;
- del_timer(motor_off_timer + drive);
+ timer_delete(motor_off_timer + drive);
/* make spindle stop in a position which minimizes spinup time
* next time */
@@ -1918,7 +1918,7 @@ static int start_motor(void (*function)(void))
mask &= ~(0x10 << UNIT(current_drive));
/* starts motor and selects floppy */
- del_timer(motor_off_timer + current_drive);
+ timer_delete(motor_off_timer + current_drive);
set_dor(current_fdc, mask, data);
/* wait_for_completion also schedules reset if needed. */
@@ -4762,7 +4762,7 @@ out_put_disk:
for (drive = 0; drive < N_DRIVE; drive++) {
if (!disks[drive][0])
break;
- del_timer_sync(&motor_off_timer[drive]);
+ timer_delete_sync(&motor_off_timer[drive]);
put_disk(disks[drive][0]);
blk_mq_free_tag_set(&tag_sets[drive]);
}
@@ -4983,7 +4983,7 @@ static void __exit floppy_module_exit(void)
destroy_workqueue(floppy_wq);
for (drive = 0; drive < N_DRIVE; drive++) {
- del_timer_sync(&motor_off_timer[drive]);
+ timer_delete_sync(&motor_off_timer[drive]);
if (floppy_available(drive)) {
for (i = 0; i < ARRAY_SIZE(floppy_type); i++) {
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 2b33fb5b949b..b5727dea15bd 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -1070,7 +1070,7 @@ static void vdc_port_remove(struct vio_dev *vdev)
flush_work(&port->ldc_reset_work);
cancel_delayed_work_sync(&port->ldc_reset_timer_work);
- del_timer_sync(&port->vio.timer);
+ timer_delete_sync(&port->vio.timer);
del_gendisk(port->disk);
put_disk(port->disk);
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 3aedcb5add61..ee6cade70222 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -362,7 +362,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
void (*proc)(struct timer_list *t))
{
if (fs->timeout_pending)
- del_timer(&fs->timeout);
+ timer_delete(&fs->timeout);
fs->timeout.expires = jiffies + nticks;
fs->timeout.function = proc;
add_timer(&fs->timeout);
@@ -677,7 +677,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
out_8(&sw->select, RELAX);
out_8(&sw->intr_enable, 0);
- del_timer(&fs->timeout);
+ timer_delete(&fs->timeout);
fs->timeout_pending = 0;
if (sw->ctrack == 0xff) {
swim3_err("%s", "Seen sector but cyl=ff?\n");
@@ -706,7 +706,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
out_8(&sw->control_bic, DO_SEEK);
out_8(&sw->select, RELAX);
out_8(&sw->intr_enable, 0);
- del_timer(&fs->timeout);
+ timer_delete(&fs->timeout);
fs->timeout_pending = 0;
if (fs->state == seeking)
++fs->retries;
@@ -716,7 +716,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
break;
case settling:
out_8(&sw->intr_enable, 0);
- del_timer(&fs->timeout);
+ timer_delete(&fs->timeout);
fs->timeout_pending = 0;
act(fs);
break;
@@ -726,7 +726,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id)
out_8(&sw->intr_enable, 0);
out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
out_8(&sw->select, RELAX);
- del_timer(&fs->timeout);
+ timer_delete(&fs->timeout);
fs->timeout_pending = 0;
dr = fs->dma;
cp = fs->dma_cmd;
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index c060da409ed8..2fd05c1bd30b 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -74,13 +74,30 @@
#define UBLK_PARAM_TYPE_ALL \
(UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD | \
UBLK_PARAM_TYPE_DEVT | UBLK_PARAM_TYPE_ZONED | \
- UBLK_PARAM_TYPE_DMA_ALIGN)
+ UBLK_PARAM_TYPE_DMA_ALIGN | UBLK_PARAM_TYPE_SEGMENT)
struct ublk_rq_data {
struct kref ref;
};
struct ublk_uring_cmd_pdu {
+ /*
+ * Store requests in same batch temporarily for queuing them to
+ * daemon context.
+ *
+ * It should have been stored to request payload, but we do want
+ * to avoid extra pre-allocation, and uring_cmd payload is always
+ * free for us
+ */
+ union {
+ struct request *req;
+ struct request *req_list;
+ };
+
+ /*
+ * The following two are valid in this cmd whole lifetime, and
+ * setup in ublk uring_cmd handler
+ */
struct ublk_queue *ubq;
u16 tag;
};
@@ -141,10 +158,8 @@ struct ublk_queue {
unsigned long flags;
struct task_struct *ubq_daemon;
- char *io_cmd_buf;
+ struct ublksrv_io_desc *io_cmd_buf;
- unsigned long io_addr; /* mapped vm address */
- unsigned int max_io_sz;
bool force_abort;
bool timeout;
bool canceling;
@@ -582,6 +597,18 @@ static int ublk_validate_params(const struct ublk_device *ub)
return -EINVAL;
}
+ if (ub->params.types & UBLK_PARAM_TYPE_SEGMENT) {
+ const struct ublk_param_segment *p = &ub->params.seg;
+
+ if (!is_power_of_2(p->seg_boundary_mask + 1))
+ return -EINVAL;
+
+ if (p->seg_boundary_mask + 1 < UBLK_MIN_SEGMENT_SIZE)
+ return -EINVAL;
+ if (p->max_segment_size < UBLK_MIN_SEGMENT_SIZE)
+ return -EINVAL;
+ }
+
return 0;
}
@@ -598,6 +625,11 @@ static inline bool ublk_support_user_copy(const struct ublk_queue *ubq)
return ubq->flags & (UBLK_F_USER_COPY | UBLK_F_SUPPORT_ZERO_COPY);
}
+static inline bool ublk_need_map_io(const struct ublk_queue *ubq)
+{
+ return !ublk_support_user_copy(ubq);
+}
+
static inline bool ublk_need_req_ref(const struct ublk_queue *ubq)
{
/*
@@ -674,11 +706,11 @@ static inline bool ublk_rq_has_data(const struct request *rq)
static inline struct ublksrv_io_desc *ublk_get_iod(struct ublk_queue *ubq,
int tag)
{
- return (struct ublksrv_io_desc *)
- &(ubq->io_cmd_buf[tag * sizeof(struct ublksrv_io_desc)]);
+ return &ubq->io_cmd_buf[tag];
}
-static inline char *ublk_queue_cmd_buf(struct ublk_device *ub, int q_id)
+static inline struct ublksrv_io_desc *
+ublk_queue_cmd_buf(struct ublk_device *ub, int q_id)
{
return ublk_get_queue(ub, q_id)->io_cmd_buf;
}
@@ -925,7 +957,7 @@ static int ublk_map_io(const struct ublk_queue *ubq, const struct request *req,
{
const unsigned int rq_bytes = blk_rq_bytes(req);
- if (ublk_support_user_copy(ubq))
+ if (!ublk_need_map_io(ubq))
return rq_bytes;
/*
@@ -949,7 +981,7 @@ static int ublk_unmap_io(const struct ublk_queue *ubq,
{
const unsigned int rq_bytes = blk_rq_bytes(req);
- if (ublk_support_user_copy(ubq))
+ if (!ublk_need_map_io(ubq))
return rq_bytes;
if (ublk_need_unmap_req(req)) {
@@ -1037,7 +1069,7 @@ static blk_status_t ublk_setup_iod(struct ublk_queue *ubq, struct request *req)
static inline struct ublk_uring_cmd_pdu *ublk_get_uring_cmd_pdu(
struct io_uring_cmd *ioucmd)
{
- return (struct ublk_uring_cmd_pdu *)&ioucmd->pdu;
+ return io_uring_cmd_to_pdu(ioucmd, struct ublk_uring_cmd_pdu);
}
static inline bool ubq_daemon_is_dying(struct ublk_queue *ubq)
@@ -1155,14 +1187,11 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq,
blk_mq_end_request(rq, BLK_STS_IOERR);
}
-static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd,
- unsigned int issue_flags)
+static void ublk_dispatch_req(struct ublk_queue *ubq,
+ struct request *req,
+ unsigned int issue_flags)
{
- struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
- struct ublk_queue *ubq = pdu->ubq;
- int tag = pdu->tag;
- struct request *req = blk_mq_tag_to_rq(
- ubq->dev->tag_set.tags[ubq->q_id], tag);
+ int tag = req->tag;
struct ublk_io *io = &ubq->ios[tag];
unsigned int mapped_bytes;
@@ -1237,11 +1266,49 @@ static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd,
ubq_complete_io_cmd(io, UBLK_IO_RES_OK, issue_flags);
}
+static void ublk_cmd_tw_cb(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
+ struct ublk_queue *ubq = pdu->ubq;
+
+ ublk_dispatch_req(ubq, pdu->req, issue_flags);
+}
+
static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
{
- struct ublk_io *io = &ubq->ios[rq->tag];
+ struct io_uring_cmd *cmd = ubq->ios[rq->tag].cmd;
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
+
+ pdu->req = rq;
+ io_uring_cmd_complete_in_task(cmd, ublk_cmd_tw_cb);
+}
+
+static void ublk_cmd_list_tw_cb(struct io_uring_cmd *cmd,
+ unsigned int issue_flags)
+{
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
+ struct request *rq = pdu->req_list;
+ struct ublk_queue *ubq = pdu->ubq;
+ struct request *next;
+
+ do {
+ next = rq->rq_next;
+ rq->rq_next = NULL;
+ ublk_dispatch_req(ubq, rq, issue_flags);
+ rq = next;
+ } while (rq);
+}
+
+static void ublk_queue_cmd_list(struct ublk_queue *ubq, struct rq_list *l)
+{
+ struct request *rq = rq_list_peek(l);
+ struct io_uring_cmd *cmd = ubq->ios[rq->tag].cmd;
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
- io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb);
+ pdu->req_list = rq;
+ rq_list_init(l);
+ io_uring_cmd_complete_in_task(cmd, ublk_cmd_list_tw_cb);
}
static enum blk_eh_timer_return ublk_timeout(struct request *rq)
@@ -1282,21 +1349,12 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq)
return BLK_EH_RESET_TIMER;
}
-static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
- const struct blk_mq_queue_data *bd)
+static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq)
{
- struct ublk_queue *ubq = hctx->driver_data;
- struct request *rq = bd->rq;
blk_status_t res;
- if (unlikely(ubq->fail_io)) {
+ if (unlikely(ubq->fail_io))
return BLK_STS_TARGET;
- }
-
- /* fill iod to slot in io cmd buffer */
- res = ublk_setup_iod(ubq, rq);
- if (unlikely(res != BLK_STS_OK))
- return BLK_STS_IOERR;
/* With recovery feature enabled, force_abort is set in
* ublk_stop_dev() before calling del_gendisk(). We have to
@@ -1310,17 +1368,68 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort))
return BLK_STS_IOERR;
+ if (unlikely(ubq->canceling))
+ return BLK_STS_IOERR;
+
+ /* fill iod to slot in io cmd buffer */
+ res = ublk_setup_iod(ubq, rq);
+ if (unlikely(res != BLK_STS_OK))
+ return BLK_STS_IOERR;
+
+ blk_mq_start_request(rq);
+ return BLK_STS_OK;
+}
+
+static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *bd)
+{
+ struct ublk_queue *ubq = hctx->driver_data;
+ struct request *rq = bd->rq;
+ blk_status_t res;
+
+ res = ublk_prep_req(ubq, rq);
+ if (res != BLK_STS_OK)
+ return res;
+
+ /*
+ * ->canceling has to be handled after ->force_abort and ->fail_io
+ * is dealt with, otherwise this request may not be failed in case
+ * of recovery, and cause hang when deleting disk
+ */
if (unlikely(ubq->canceling)) {
__ublk_abort_rq(ubq, rq);
return BLK_STS_OK;
}
- blk_mq_start_request(bd->rq);
ublk_queue_cmd(ubq, rq);
-
return BLK_STS_OK;
}
+static void ublk_queue_rqs(struct rq_list *rqlist)
+{
+ struct rq_list requeue_list = { };
+ struct rq_list submit_list = { };
+ struct ublk_queue *ubq = NULL;
+ struct request *req;
+
+ while ((req = rq_list_pop(rqlist))) {
+ struct ublk_queue *this_q = req->mq_hctx->driver_data;
+
+ if (ubq && ubq != this_q && !rq_list_empty(&submit_list))
+ ublk_queue_cmd_list(ubq, &submit_list);
+ ubq = this_q;
+
+ if (ublk_prep_req(ubq, req) == BLK_STS_OK)
+ rq_list_add_tail(&submit_list, req);
+ else
+ rq_list_add_tail(&requeue_list, req);
+ }
+
+ if (ubq && !rq_list_empty(&submit_list))
+ ublk_queue_cmd_list(ubq, &submit_list);
+ *rqlist = requeue_list;
+}
+
static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data,
unsigned int hctx_idx)
{
@@ -1333,6 +1442,7 @@ static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data,
static const struct blk_mq_ops ublk_mq_ops = {
.queue_rq = ublk_queue_rq,
+ .queue_rqs = ublk_queue_rqs,
.init_hctx = ublk_init_hctx,
.timeout = ublk_timeout,
};
@@ -1446,17 +1556,27 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
}
}
+/* Must be called when queue is frozen */
+static bool ublk_mark_queue_canceling(struct ublk_queue *ubq)
+{
+ bool canceled;
+
+ spin_lock(&ubq->cancel_lock);
+ canceled = ubq->canceling;
+ if (!canceled)
+ ubq->canceling = true;
+ spin_unlock(&ubq->cancel_lock);
+
+ return canceled;
+}
+
static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
{
+ bool was_canceled = ubq->canceling;
struct gendisk *disk;
- spin_lock(&ubq->cancel_lock);
- if (ubq->canceling) {
- spin_unlock(&ubq->cancel_lock);
+ if (was_canceled)
return false;
- }
- ubq->canceling = true;
- spin_unlock(&ubq->cancel_lock);
spin_lock(&ub->lock);
disk = ub->ub_disk;
@@ -1468,14 +1588,23 @@ static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
if (!disk)
return false;
- /* Now we are serialized with ublk_queue_rq() */
+ /*
+ * Now we are serialized with ublk_queue_rq()
+ *
+ * Make sure that ubq->canceling is set when queue is frozen,
+ * because ublk_queue_rq() has to rely on this flag for avoiding to
+ * touch completed uring_cmd
+ */
blk_mq_quiesce_queue(disk->queue);
- /* abort queue is for making forward progress */
- ublk_abort_queue(ub, ubq);
+ was_canceled = ublk_mark_queue_canceling(ubq);
+ if (!was_canceled) {
+ /* abort queue is for making forward progress */
+ ublk_abort_queue(ub, ubq);
+ }
blk_mq_unquiesce_queue(disk->queue);
put_device(disk_to_dev(disk));
- return true;
+ return !was_canceled;
}
static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io,
@@ -1845,7 +1974,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
if (io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)
goto out;
- if (!ublk_support_user_copy(ubq)) {
+ if (ublk_need_map_io(ubq)) {
/*
* FETCH_RQ has to provide IO buffer if NEED GET
* DATA is not enabled
@@ -1867,7 +1996,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV))
goto out;
- if (!ublk_support_user_copy(ubq)) {
+ if (ublk_need_map_io(ubq)) {
/*
* COMMIT_AND_FETCH_REQ has to provide IO buffer if
* NEED GET DATA is not enabled or it is Read IO.
@@ -2343,6 +2472,12 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
if (ub->params.types & UBLK_PARAM_TYPE_DMA_ALIGN)
lim.dma_alignment = ub->params.dma.alignment;
+ if (ub->params.types & UBLK_PARAM_TYPE_SEGMENT) {
+ lim.seg_boundary_mask = ub->params.seg.seg_boundary_mask;
+ lim.max_segment_size = ub->params.seg.max_segment_size;
+ lim.max_segments = ub->params.seg.max_segments;
+ }
+
if (wait_for_completion_interruptible(&ub->completion) != 0)
return -EINTR;
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 36eabf61717f..1c7f89e134b3 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -638,7 +638,7 @@ static int bluecard_hci_close(struct hci_dev *hdev)
bluecard_hci_flush(hdev);
/* Stop LED timer */
- del_timer_sync(&(info->timer));
+ timer_delete_sync(&(info->timer));
/* Disable power LED */
outb(0x00, iobase + 0x30);
@@ -885,7 +885,7 @@ static void bluecard_release(struct pcmcia_device *link)
bluecard_close(info);
- del_timer_sync(&(info->timer));
+ timer_delete_sync(&(info->timer));
pcmcia_disable_device(link);
}
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 76878119d910..610d0e3c36d4 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -382,7 +382,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
}
if (skb_queue_empty(&bcsp->unack))
- del_timer(&bcsp->tbcsp);
+ timer_delete(&bcsp->tbcsp);
spin_unlock_irqrestore(&bcsp->unack.lock, flags);
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index c0436881a533..edafa228bf83 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -197,7 +197,7 @@ static void h5_peer_reset(struct hci_uart *hu)
h5->state = H5_UNINITIALIZED;
- del_timer(&h5->timer);
+ timer_delete(&h5->timer);
skb_queue_purge(&h5->rel);
skb_queue_purge(&h5->unrel);
@@ -254,7 +254,7 @@ static int h5_close(struct hci_uart *hu)
{
struct h5 *h5 = hu->priv;
- del_timer_sync(&h5->timer);
+ timer_delete_sync(&h5->timer);
skb_queue_purge(&h5->unack);
skb_queue_purge(&h5->rel);
@@ -318,7 +318,7 @@ static void h5_pkt_cull(struct h5 *h5)
}
if (skb_queue_empty(&h5->unack))
- del_timer(&h5->timer);
+ timer_delete(&h5->timer);
unlock:
spin_unlock_irqrestore(&h5->unack.lock, flags);
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f2558506a02c..e00590ba24fd 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -867,7 +867,7 @@ static void device_woke_up(struct hci_uart *hu)
skb_queue_tail(&qca->txq, skb);
/* Switch timers and change state to HCI_IBS_TX_AWAKE */
- del_timer(&qca->wake_retrans_timer);
+ timer_delete(&qca->wake_retrans_timer);
idle_delay = msecs_to_jiffies(qca->tx_idle_delay);
mod_timer(&qca->tx_idle_timer, jiffies + idle_delay);
qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
@@ -2239,8 +2239,8 @@ static int qca_power_off(struct hci_dev *hdev)
hu->hdev->hw_error = NULL;
hu->hdev->reset = NULL;
- del_timer_sync(&qca->wake_retrans_timer);
- del_timer_sync(&qca->tx_idle_timer);
+ timer_delete_sync(&qca->wake_retrans_timer);
+ timer_delete_sync(&qca->tx_idle_timer);
/* Stop sending shutdown command if soc crashes. */
if (soc_type != QCA_ROME
@@ -2629,10 +2629,10 @@ static int __maybe_unused qca_suspend(struct device *dev)
switch (qca->tx_ibs_state) {
case HCI_IBS_TX_WAKING:
- del_timer(&qca->wake_retrans_timer);
+ timer_delete(&qca->wake_retrans_timer);
fallthrough;
case HCI_IBS_TX_AWAKE:
- del_timer(&qca->tx_idle_timer);
+ timer_delete(&qca->tx_idle_timer);
serdev_device_write_flush(hu->serdev);
cmd = HCI_IBS_SLEEP_IND;
diff --git a/drivers/bus/fsl-mc/dpmcp.c b/drivers/bus/fsl-mc/dpmcp.c
index 5fbd0dbde24a..7816c0a728ef 100644
--- a/drivers/bus/fsl-mc/dpmcp.c
+++ b/drivers/bus/fsl-mc/dpmcp.c
@@ -75,25 +75,3 @@ int dpmcp_close(struct fsl_mc_io *mc_io,
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
-
-/**
- * dpmcp_reset() - Reset the DPMCP, returns the object to initial state.
- * @mc_io: Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @token: Token of DPMCP object
- *
- * Return: '0' on Success; Error code otherwise.
- */
-int dpmcp_reset(struct fsl_mc_io *mc_io,
- u32 cmd_flags,
- u16 token)
-{
- struct fsl_mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET,
- cmd_flags, token);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
diff --git a/drivers/bus/fsl-mc/fsl-mc-allocator.c b/drivers/bus/fsl-mc/fsl-mc-allocator.c
index b5e8c021fa1f..6c3beb82dd1b 100644
--- a/drivers/bus/fsl-mc/fsl-mc-allocator.c
+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c
@@ -656,8 +656,3 @@ int __init fsl_mc_allocator_driver_init(void)
{
return fsl_mc_driver_register(&fsl_mc_allocator_driver);
}
-
-void fsl_mc_allocator_driver_exit(void)
-{
- fsl_mc_driver_unregister(&fsl_mc_allocator_driver);
-}
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index b3520ea1b9f4..e1b7ec3ed1a7 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -66,10 +66,6 @@ int dpmcp_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
-int dpmcp_reset(struct fsl_mc_io *mc_io,
- u32 cmd_flags,
- u16 token);
-
/*
* Data Path Resource Container (DPRC) API
*/
@@ -631,8 +627,6 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
int __init fsl_mc_allocator_driver_init(void);
-void fsl_mc_allocator_driver_exit(void);
-
void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev);
void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev);
diff --git a/drivers/bus/fsl-mc/mc-io.c b/drivers/bus/fsl-mc/mc-io.c
index 95b10a6cf307..a0ad7866cbfc 100644
--- a/drivers/bus/fsl-mc/mc-io.c
+++ b/drivers/bus/fsl-mc/mc-io.c
@@ -263,23 +263,3 @@ void fsl_mc_portal_free(struct fsl_mc_io *mc_io)
dpmcp_dev->consumer_link = NULL;
}
EXPORT_SYMBOL_GPL(fsl_mc_portal_free);
-
-/**
- * fsl_mc_portal_reset - Resets the dpmcp object for a given fsl_mc_io object
- *
- * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free
- */
-int fsl_mc_portal_reset(struct fsl_mc_io *mc_io)
-{
- int error;
- struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
-
- error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle);
- if (error < 0) {
- dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error);
- return error;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fsl_mc_portal_reset);
diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
index 474f1359c997..03aa88795209 100644
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
@@ -1096,7 +1096,7 @@ static void mhi_pci_recovery_work(struct work_struct *work)
dev_warn(&pdev->dev, "device recovery started\n");
- del_timer(&mhi_pdev->health_check_timer);
+ timer_delete(&mhi_pdev->health_check_timer);
pm_runtime_forbid(&pdev->dev);
/* Clean up MHI state */
@@ -1293,7 +1293,7 @@ static void mhi_pci_remove(struct pci_dev *pdev)
struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);
struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;
- del_timer_sync(&mhi_pdev->health_check_timer);
+ timer_delete_sync(&mhi_pdev->health_check_timer);
cancel_work_sync(&mhi_pdev->recovery_work);
if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
@@ -1321,7 +1321,7 @@ static void mhi_pci_reset_prepare(struct pci_dev *pdev)
dev_info(&pdev->dev, "reset\n");
- del_timer(&mhi_pdev->health_check_timer);
+ timer_delete(&mhi_pdev->health_check_timer);
/* Clean up MHI state */
if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
@@ -1431,7 +1431,7 @@ static int __maybe_unused mhi_pci_runtime_suspend(struct device *dev)
if (test_and_set_bit(MHI_PCI_DEV_SUSPENDED, &mhi_pdev->status))
return 0;
- del_timer(&mhi_pdev->health_check_timer);
+ timer_delete(&mhi_pdev->health_check_timer);
cancel_work_sync(&mhi_pdev->recovery_work);
if (!test_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status) ||
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 27f5f9d19531..16618079298a 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -243,11 +243,11 @@ static __poll_t dtlk_poll(struct file *file, poll_table * wait)
poll_wait(file, &dtlk_process_list, wait);
if (dtlk_has_indexing && dtlk_readable()) {
- del_timer(&dtlk_timer);
+ timer_delete(&dtlk_timer);
mask = EPOLLIN | EPOLLRDNORM;
}
if (dtlk_writeable()) {
- del_timer(&dtlk_timer);
+ timer_delete(&dtlk_timer);
mask |= EPOLLOUT | EPOLLWRNORM;
}
/* there are no exception conditions */
@@ -322,7 +322,7 @@ static int dtlk_release(struct inode *inode, struct file *file)
}
TRACE_RET;
- del_timer_sync(&dtlk_timer);
+ timer_delete_sync(&dtlk_timer);
return 0;
}
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 4181bcc1c796..497fc167cb8c 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -167,7 +167,7 @@ static int __init hangcheck_init(void)
static void __exit hangcheck_exit(void)
{
- del_timer_sync(&hangcheck_ticktock);
+ timer_delete_sync(&hangcheck_ticktock);
printk("Hangcheck: Stopped hangcheck timer.\n");
}
diff --git a/drivers/char/hw_random/xgene-rng.c b/drivers/char/hw_random/xgene-rng.c
index 39acaa503fec..a1a751074f7e 100644
--- a/drivers/char/hw_random/xgene-rng.c
+++ b/drivers/char/hw_random/xgene-rng.c
@@ -93,7 +93,7 @@ static void xgene_rng_expired_timer(struct timer_list *t)
/* Clear failure counter as timer expired */
disable_irq(ctx->irq);
ctx->failure_cnt = 0;
- del_timer(&ctx->failure_timer);
+ timer_delete(&ctx->failure_timer);
enable_irq(ctx->irq);
}
diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
index 009e32033b17..77146b5c762b 100644
--- a/drivers/char/ipmi/bt-bmc.c
+++ b/drivers/char/ipmi/bt-bmc.c
@@ -465,7 +465,7 @@ static void bt_bmc_remove(struct platform_device *pdev)
misc_deregister(&bt_bmc->miscdev);
if (bt_bmc->irq < 0)
- del_timer_sync(&bt_bmc->poll_timer);
+ timer_delete_sync(&bt_bmc->poll_timer);
}
static const struct of_device_id bt_bmc_match[] = {
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 1e5313748f8b..3ba9d7e9a6c7 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -5538,7 +5538,7 @@ static void __exit cleanup_ipmi(void)
* here.
*/
atomic_set(&stop_operation, 1);
- del_timer_sync(&ipmi_timer);
+ timer_delete_sync(&ipmi_timer);
initialized = false;
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index eea23a3b966e..12b0b77eb1cc 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -859,7 +859,7 @@ restart:
if (si_sm_result == SI_SM_IDLE && smi_info->timer_running) {
/* Ok it if fails, the timer will just go off. */
- if (del_timer(&smi_info->si_timer))
+ if (timer_delete(&smi_info->si_timer))
smi_info->timer_running = false;
}
@@ -1839,7 +1839,7 @@ static inline void stop_timer_and_thread(struct smi_info *smi_info)
}
smi_info->timer_can_start = false;
- del_timer_sync(&smi_info->si_timer);
+ timer_delete_sync(&smi_info->si_timer);
}
static struct smi_info *find_dup_si(struct smi_info *info)
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 506d9988721e..0b45b07dec22 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -599,7 +599,7 @@ static void ssif_alert(struct i2c_client *client, enum i2c_alert_protocol type,
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
if (ssif_info->waiting_alert) {
ssif_info->waiting_alert = false;
- del_timer(&ssif_info->retry_timer);
+ timer_delete(&ssif_info->retry_timer);
do_get = true;
} else if (ssif_info->curr_msg) {
ssif_info->got_alert = true;
@@ -1268,8 +1268,8 @@ static void shutdown_ssif(void *send_info)
schedule_timeout(1);
ssif_info->stopping = true;
- del_timer_sync(&ssif_info->watch_timer);
- del_timer_sync(&ssif_info->retry_timer);
+ timer_delete_sync(&ssif_info->watch_timer);
+ timer_delete_sync(&ssif_info->retry_timer);
if (ssif_info->thread) {
complete(&ssif_info->wake_thread);
kthread_stop(ssif_info->thread);
diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
index c03bc1ec593a..a13a3470c17a 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -428,7 +428,7 @@ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask,
if (rc == -ETIMEDOUT)
mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD);
} else {
- del_timer(&priv->obe.timer);
+ timer_delete(&priv->obe.timer);
}
}
@@ -655,7 +655,7 @@ static void aspeed_kcs_remove(struct platform_device *pdev)
spin_lock_irq(&priv->obe.lock);
priv->obe.remove = true;
spin_unlock_irq(&priv->obe.lock);
- del_timer_sync(&priv->obe.timer);
+ timer_delete_sync(&priv->obe.timer);
}
static const struct of_device_id ast_kcs_bmc_match[] = {
diff --git a/drivers/char/ipmi/ssif_bmc.c b/drivers/char/ipmi/ssif_bmc.c
index 310f17dd9511..e4bd74585d4d 100644
--- a/drivers/char/ipmi/ssif_bmc.c
+++ b/drivers/char/ipmi/ssif_bmc.c
@@ -209,7 +209,7 @@ static ssize_t ssif_bmc_write(struct file *file, const char __user *buf, size_t
if (ret)
goto exit;
- del_timer(&ssif_bmc->response_timer);
+ timer_delete(&ssif_bmc->response_timer);
ssif_bmc->response_timer_inited = false;
memcpy(&ssif_bmc->response, &msg, count);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 92cbd24a36d8..38f2fab29c56 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1352,7 +1352,7 @@ static void __cold try_to_generate_entropy(void)
}
mix_pool_bytes(&stack->entropy, sizeof(stack->entropy));
- del_timer_sync(&stack->timer);
+ timer_delete_sync(&stack->timer);
destroy_timer_on_stack(&stack->timer);
}
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 6c1d94eda5a2..b381ea7e85d2 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -838,7 +838,7 @@ static void __exit tlclk_cleanup(void)
unregister_chrdev(tlclk_major, "telco_clock");
release_region(TLCLK_BASE, 8);
- del_timer_sync(&switchover_timer);
+ timer_delete_sync(&switchover_timer);
kfree(alarm_events);
}
@@ -856,7 +856,7 @@ static void switchover_timeout(struct timer_list *unused)
}
/* Alarm processing is done, wake up read task */
- del_timer(&switchover_timer);
+ timer_delete(&switchover_timer);
got_event = 1;
wake_up(&wq);
}
diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c
index 48ff87444f85..11deaf538e87 100644
--- a/drivers/char/tpm/tpm-dev-common.c
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -160,7 +160,7 @@ ssize_t tpm_common_read(struct file *file, char __user *buf,
out:
if (!priv->response_length) {
*off = 0;
- del_timer_sync(&priv->user_read_timer);
+ timer_delete_sync(&priv->user_read_timer);
flush_work(&priv->timeout_work);
}
mutex_unlock(&priv->buffer_mutex);
@@ -267,7 +267,7 @@ __poll_t tpm_common_poll(struct file *file, poll_table *wait)
void tpm_common_release(struct file *file, struct file_priv *priv)
{
flush_work(&priv->async_work);
- del_timer_sync(&priv->user_read_timer);
+ timer_delete_sync(&priv->user_read_timer);
flush_work(&priv->timeout_work);
file->private_data = NULL;
priv->response_length = 0;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 2f83fb97c6fb..e0bede6350e1 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -153,7 +153,7 @@ struct clk_lookup_alloc {
char con_id[MAX_CON_ID];
};
-static struct clk_lookup * __ref
+static __printf(3, 0) struct clk_lookup * __ref
vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
va_list ap)
{
@@ -215,7 +215,7 @@ fail:
return &cla->cl;
}
-static struct clk_lookup *
+static __printf(3, 0) struct clk_lookup *
vclkdev_create(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
va_list ap)
{
@@ -303,9 +303,8 @@ void clkdev_drop(struct clk_lookup *cl)
}
EXPORT_SYMBOL(clkdev_drop);
-static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
- const char *con_id,
- const char *dev_id, ...)
+static __printf(3, 4) struct clk_lookup *
+__clk_register_clkdev(struct clk_hw *hw, const char *con_id, const char *dev_id, ...)
{
struct clk_lookup *cl;
va_list ap;
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 48ce50c5f5e6..4d7cf338824a 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -126,7 +126,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu)
static int riscv_timer_dying_cpu(unsigned int cpu)
{
+ /*
+ * Stop the timer when the cpu is going to be offline otherwise
+ * the timer interrupt may be pending while performing power-down.
+ */
+ riscv_clock_event_stop();
disable_percpu_irq(riscv_clock_event_irq);
+
return 0;
}
diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c
index 05ae9122823f..da17d891f0e5 100644
--- a/drivers/comedi/drivers/comedi_test.c
+++ b/drivers/comedi/drivers/comedi_test.c
@@ -418,9 +418,9 @@ static int waveform_ai_cancel(struct comedi_device *dev,
spin_unlock_bh(&dev->spinlock);
if (in_softirq()) {
/* Assume we were called from the timer routine itself. */
- del_timer(&devpriv->ai_timer);
+ timer_delete(&devpriv->ai_timer);
} else {
- del_timer_sync(&devpriv->ai_timer);
+ timer_delete_sync(&devpriv->ai_timer);
}
return 0;
}
@@ -628,9 +628,9 @@ static int waveform_ao_cancel(struct comedi_device *dev,
spin_unlock_bh(&dev->spinlock);
if (in_softirq()) {
/* Assume we were called from the timer routine itself. */
- del_timer(&devpriv->ao_timer);
+ timer_delete(&devpriv->ao_timer);
} else {
- del_timer_sync(&devpriv->ao_timer);
+ timer_delete_sync(&devpriv->ao_timer);
}
return 0;
}
@@ -791,8 +791,8 @@ static void waveform_detach(struct comedi_device *dev)
struct waveform_private *devpriv = dev->private;
if (devpriv) {
- del_timer_sync(&devpriv->ai_timer);
- del_timer_sync(&devpriv->ao_timer);
+ timer_delete_sync(&devpriv->ai_timer);
+ timer_delete_sync(&devpriv->ao_timer);
}
}
diff --git a/drivers/comedi/drivers/das16.c b/drivers/comedi/drivers/das16.c
index 4ed56a02150e..f5ca6c0d4d0c 100644
--- a/drivers/comedi/drivers/das16.c
+++ b/drivers/comedi/drivers/das16.c
@@ -775,7 +775,7 @@ static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
/* disable SW timer */
if (devpriv->timer_running) {
devpriv->timer_running = 0;
- del_timer(&devpriv->timer);
+ timer_delete(&devpriv->timer);
}
if (devpriv->can_burst)
@@ -940,7 +940,7 @@ static void das16_free_dma(struct comedi_device *dev)
struct das16_private_struct *devpriv = dev->private;
if (devpriv) {
- del_timer_sync(&devpriv->timer);
+ timer_delete_sync(&devpriv->timer);
comedi_isadma_free(devpriv->dma);
}
}
diff --git a/drivers/comedi/drivers/jr3_pci.c b/drivers/comedi/drivers/jr3_pci.c
index 951c23fa0369..cdc842b32bab 100644
--- a/drivers/comedi/drivers/jr3_pci.c
+++ b/drivers/comedi/drivers/jr3_pci.c
@@ -758,7 +758,7 @@ static void jr3_pci_detach(struct comedi_device *dev)
struct jr3_pci_dev_private *devpriv = dev->private;
if (devpriv)
- del_timer_sync(&devpriv->timer);
+ timer_delete_sync(&devpriv->timer);
comedi_pci_detach(dev);
}
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 00a463b044b5..1de3c50b9804 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -519,6 +519,25 @@ static int mchp_tc_probe(struct platform_device *pdev)
channel);
}
+ /* Disable Quadrature Decoder and position measure */
+ ret = regmap_update_bits(regmap, ATMEL_TC_BMR, ATMEL_TC_QDEN | ATMEL_TC_POSEN, 0);
+ if (ret)
+ return ret;
+
+ /* Setup the period capture mode */
+ ret = regmap_update_bits(regmap, ATMEL_TC_REG(priv->channel[0], CMR),
+ ATMEL_TC_WAVE | ATMEL_TC_ABETRG | ATMEL_TC_CMR_MASK |
+ ATMEL_TC_TCCLKS,
+ ATMEL_TC_CMR_MASK);
+ if (ret)
+ return ret;
+
+ /* Enable clock and trigger counter */
+ ret = regmap_write(regmap, ATMEL_TC_REG(priv->channel[0], CCR),
+ ATMEL_TC_CLKEN | ATMEL_TC_SWTRG);
+ if (ret)
+ return ret;
+
priv->tc_cfg = tcb_config;
priv->regmap = regmap;
counter->name = dev_name(&pdev->dev);
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index cf73f65baf60..b249c8647639 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -58,37 +58,43 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
return 0;
}
+ ret = clk_enable(priv->clk);
+ if (ret)
+ goto disable_cnt;
+
/* LP timer must be enabled before writing CMP & ARR */
ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
if (ret)
- return ret;
+ goto disable_clk;
ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
if (ret)
- return ret;
+ goto disable_clk;
/* ensure CMP & ARR registers are properly written */
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
(val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
100, 1000);
if (ret)
- return ret;
+ goto disable_clk;
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
STM32_LPTIM_CMPOKCF_ARROKCF);
if (ret)
- return ret;
+ goto disable_clk;
- ret = clk_enable(priv->clk);
- if (ret) {
- regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
- return ret;
- }
priv->enabled = true;
/* Start LP timer in continuous mode */
return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
+
+disable_clk:
+ clk_disable(priv->clk);
+disable_cnt:
+ regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
+
+ return ret;
}
static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0cf5a320bb5e..3841c9da6cac 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2809,6 +2809,12 @@ EXPORT_SYMBOL(cpufreq_update_policy);
*/
void cpufreq_update_limits(unsigned int cpu)
{
+ struct cpufreq_policy *policy __free(put_cpufreq_policy);
+
+ policy = cpufreq_cpu_get(cpu);
+ if (!policy)
+ return;
+
if (cpufreq_driver->update_limits)
cpufreq_driver->update_limits(cpu);
else
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index 6094c530bf57..afe5abf89d33 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -802,7 +802,7 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
if (gpstate_idx != new_index)
queue_gpstate_timer(gpstates);
else
- del_timer_sync(&gpstates->timer);
+ timer_delete_sync(&gpstates->timer);
gpstates_done:
freq_data.gpstate_id = idx_to_pstate(gpstate_idx);
@@ -880,7 +880,7 @@ static void powernv_cpufreq_cpu_exit(struct cpufreq_policy *policy)
freq_data.gpstate_id = idx_to_pstate(powernv_pstate_info.min);
smp_call_function_single(policy->cpu, set_pstate, &freq_data, 1);
if (gpstates)
- del_timer_sync(&gpstates->timer);
+ timer_delete_sync(&gpstates->timer);
kfree(policy->driver_data);
}
diff --git a/drivers/crypto/axis/artpec6_crypto.c b/drivers/crypto/axis/artpec6_crypto.c
index 500b08e42282..f8d50bd227a6 100644
--- a/drivers/crypto/axis/artpec6_crypto.c
+++ b/drivers/crypto/axis/artpec6_crypto.c
@@ -2067,7 +2067,7 @@ static void artpec6_crypto_process_queue(struct artpec6_crypto *ac,
if (ac->pending_count)
mod_timer(&ac->timer, jiffies + msecs_to_jiffies(100));
else
- del_timer(&ac->timer);
+ timer_delete(&ac->timer);
}
static void artpec6_crypto_timeout(struct timer_list *t)
@@ -2963,7 +2963,7 @@ static void artpec6_crypto_remove(struct platform_device *pdev)
tasklet_disable(&ac->task);
devm_free_irq(&pdev->dev, irq, ac);
tasklet_kill(&ac->task);
- del_timer_sync(&ac->timer);
+ timer_delete_sync(&ac->timer);
artpec6_crypto_disable_hw(ac);
diff --git a/drivers/crypto/inside-secure/eip93/eip93-hash.c b/drivers/crypto/inside-secure/eip93/eip93-hash.c
index 5e9627467a42..df1b05ac5a57 100644
--- a/drivers/crypto/inside-secure/eip93/eip93-hash.c
+++ b/drivers/crypto/inside-secure/eip93/eip93-hash.c
@@ -260,7 +260,8 @@ static int eip93_send_hash_req(struct crypto_async_request *async, u8 *data,
}
again:
- ret = eip93_put_descriptor(eip93, &cdesc);
+ scoped_guard(spinlock_irqsave, &eip93->ring->write_lock)
+ ret = eip93_put_descriptor(eip93, &cdesc);
if (ret) {
usleep_range(EIP93_RING_BUSY_DELAY,
EIP93_RING_BUSY_DELAY * 2);
diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig
index 8ac1e9d70eeb..cf1ba673b8c2 100644
--- a/drivers/cxl/Kconfig
+++ b/drivers/cxl/Kconfig
@@ -158,4 +158,8 @@ config CXL_REGION_INVALIDATION_TEST
If unsure, or if this kernel is meant for production environments,
say N.
+config CXL_MCE
+ def_bool y
+ depends on X86_MCE && MEMORY_FAILURE
+
endif
diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
index b0bfbd9eac9b..086df97a0fcf 100644
--- a/drivers/cxl/core/Makefile
+++ b/drivers/cxl/core/Makefile
@@ -14,6 +14,9 @@ cxl_core-y += pci.o
cxl_core-y += hdm.o
cxl_core-y += pmu.o
cxl_core-y += cdat.o
+cxl_core-y += ras.o
+cxl_core-y += acpi.o
cxl_core-$(CONFIG_TRACING) += trace.o
cxl_core-$(CONFIG_CXL_REGION) += region.o
+cxl_core-$(CONFIG_CXL_MCE) += mce.o
cxl_core-$(CONFIG_CXL_FEATURES) += features.o
diff --git a/drivers/cxl/core/acpi.c b/drivers/cxl/core/acpi.c
new file mode 100644
index 000000000000..f13b4dae6ac5
--- /dev/null
+++ b/drivers/cxl/core/acpi.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
+#include <linux/acpi.h>
+#include "cxl.h"
+#include "core.h"
+
+int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
+ int nid, resource_size_t *size)
+{
+ return hmat_get_extended_linear_cache_size(backing_res, nid, size);
+}
diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
index 8153f8d83a16..edb4f41eeacc 100644
--- a/drivers/cxl/core/cdat.c
+++ b/drivers/cxl/core/cdat.c
@@ -258,27 +258,29 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
struct xarray *dsmas_xa)
{
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
struct device *dev = cxlds->dev;
- struct range pmem_range = {
- .start = cxlds->pmem_res.start,
- .end = cxlds->pmem_res.end,
- };
- struct range ram_range = {
- .start = cxlds->ram_res.start,
- .end = cxlds->ram_res.end,
- };
struct dsmas_entry *dent;
unsigned long index;
xa_for_each(dsmas_xa, index, dent) {
- if (resource_size(&cxlds->ram_res) &&
- range_contains(&ram_range, &dent->dpa_range))
- update_perf_entry(dev, dent, &mds->ram_perf);
- else if (resource_size(&cxlds->pmem_res) &&
- range_contains(&pmem_range, &dent->dpa_range))
- update_perf_entry(dev, dent, &mds->pmem_perf);
- else
+ bool found = false;
+
+ for (int i = 0; i < cxlds->nr_partitions; i++) {
+ struct resource *res = &cxlds->part[i].res;
+ struct range range = {
+ .start = res->start,
+ .end = res->end,
+ };
+
+ if (range_contains(&range, &dent->dpa_range)) {
+ update_perf_entry(dev, dent,
+ &cxlds->part[i].perf);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
&dent->dpa_range);
}
@@ -343,36 +345,46 @@ static int match_cxlrd_hb(struct device *dev, void *data)
return 0;
}
-static int cxl_qos_class_verify(struct cxl_memdev *cxlmd)
+static void cxl_qos_class_verify(struct cxl_memdev *cxlmd)
{
struct cxl_dev_state *cxlds = cxlmd->cxlds;
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
struct cxl_port *root_port;
- int rc;
struct cxl_root *cxl_root __free(put_cxl_root) =
find_cxl_root(cxlmd->endpoint);
+ /*
+ * No need to reset_dpa_perf() here as find_cxl_root() is guaranteed to
+ * succeed when called in the cxl_endpoint_port_probe() path.
+ */
if (!cxl_root)
- return -ENODEV;
+ return;
root_port = &cxl_root->port;
- /* Check that the QTG IDs are all sane between end device and root decoders */
- if (!cxl_qos_match(root_port, &mds->ram_perf))
- reset_dpa_perf(&mds->ram_perf);
- if (!cxl_qos_match(root_port, &mds->pmem_perf))
- reset_dpa_perf(&mds->pmem_perf);
-
- /* Check to make sure that the device's host bridge is under a root decoder */
- rc = device_for_each_child(&root_port->dev,
- cxlmd->endpoint->host_bridge, match_cxlrd_hb);
- if (!rc) {
- reset_dpa_perf(&mds->ram_perf);
- reset_dpa_perf(&mds->pmem_perf);
+ /*
+ * Save userspace from needing to check if a qos class has any matches
+ * by hiding qos class info if the memdev is not mapped by a root
+ * decoder, or the partition class does not match any root decoder
+ * class.
+ */
+ if (!device_for_each_child(&root_port->dev,
+ cxlmd->endpoint->host_bridge,
+ match_cxlrd_hb)) {
+ for (int i = 0; i < cxlds->nr_partitions; i++) {
+ struct cxl_dpa_perf *perf = &cxlds->part[i].perf;
+
+ reset_dpa_perf(perf);
+ }
+ return;
}
- return rc;
+ for (int i = 0; i < cxlds->nr_partitions; i++) {
+ struct cxl_dpa_perf *perf = &cxlds->part[i].perf;
+
+ if (!cxl_qos_match(root_port, perf))
+ reset_dpa_perf(perf);
+ }
}
static void discard_dsmas(struct xarray *xa)
@@ -570,23 +582,18 @@ static bool dpa_perf_contains(struct cxl_dpa_perf *perf,
return range_contains(&perf->dpa_range, &dpa);
}
-static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxled,
- enum cxl_decoder_mode mode)
+static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxled)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct cxl_dpa_perf *perf;
- switch (mode) {
- case CXL_DECODER_RAM:
- perf = &mds->ram_perf;
- break;
- case CXL_DECODER_PMEM:
- perf = &mds->pmem_perf;
- break;
- default:
+ if (cxled->part < 0)
+ return ERR_PTR(-EINVAL);
+ perf = &cxlds->part[cxled->part].perf;
+
+ if (!perf)
return ERR_PTR(-EINVAL);
- }
if (!dpa_perf_contains(perf, cxled->dpa_res))
return ERR_PTR(-EINVAL);
@@ -647,11 +654,10 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr,
if (cxlds->rcd)
return -ENODEV;
- perf = cxled_get_dpa_perf(cxled, cxlr->mode);
+ perf = cxled_get_dpa_perf(cxled);
if (IS_ERR(perf))
return PTR_ERR(perf);
- gp_port = to_cxl_port(parent_port->dev.parent);
*gp_is_root = is_cxl_root(gp_port);
/*
@@ -1053,7 +1059,7 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
lockdep_assert_held(&cxl_dpa_rwsem);
- perf = cxled_get_dpa_perf(cxled, cxlr->mode);
+ perf = cxled_get_dpa_perf(cxled);
if (IS_ERR(perf))
return;
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 17e99a25c29a..15699299dc11 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -74,8 +74,8 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
resource_size_t length);
struct dentry *cxl_debugfs_create_dir(const char *dir);
-int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
- enum cxl_decoder_mode mode);
+int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
+ enum cxl_partition_mode mode);
int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size);
int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled);
@@ -117,6 +117,12 @@ bool cxl_need_node_perf_attrs_update(int nid);
int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
struct access_coordinate *c);
+int cxl_ras_init(void);
+void cxl_ras_exit(void);
+int cxl_gpf_port_setup(struct device *dport_dev, struct cxl_port *port);
+int cxl_acpi_get_extended_linear_cache_size(struct resource *backing_res,
+ int nid, resource_size_t *size);
+
#ifdef CONFIG_CXL_FEATURES
size_t cxl_get_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
enum cxl_get_feat_selection selection,
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index 50e6a45b30ba..70cae4ebf8a4 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -213,16 +213,46 @@ void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds)
{
struct resource *p1, *p2;
- down_read(&cxl_dpa_rwsem);
+ guard(rwsem_read)(&cxl_dpa_rwsem);
for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) {
__cxl_dpa_debug(file, p1, 0);
for (p2 = p1->child; p2; p2 = p2->sibling)
__cxl_dpa_debug(file, p2, 1);
}
- up_read(&cxl_dpa_rwsem);
}
EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, "CXL");
+/* See request_skip() kernel-doc */
+static resource_size_t __adjust_skip(struct cxl_dev_state *cxlds,
+ const resource_size_t skip_base,
+ const resource_size_t skip_len,
+ const char *requester)
+{
+ const resource_size_t skip_end = skip_base + skip_len - 1;
+
+ for (int i = 0; i < cxlds->nr_partitions; i++) {
+ const struct resource *part_res = &cxlds->part[i].res;
+ resource_size_t adjust_start, adjust_end, size;
+
+ adjust_start = max(skip_base, part_res->start);
+ adjust_end = min(skip_end, part_res->end);
+
+ if (adjust_end < adjust_start)
+ continue;
+
+ size = adjust_end - adjust_start + 1;
+
+ if (!requester)
+ __release_region(&cxlds->dpa_res, adjust_start, size);
+ else if (!__request_region(&cxlds->dpa_res, adjust_start, size,
+ requester, 0))
+ return adjust_start - skip_base;
+ }
+
+ return skip_len;
+}
+#define release_skip(c, b, l) __adjust_skip((c), (b), (l), NULL)
+
/*
* Must be called in a context that synchronizes against this decoder's
* port ->remove() callback (like an endpoint decoder sysfs attribute)
@@ -241,7 +271,7 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
skip_start = res->start - cxled->skip;
__release_region(&cxlds->dpa_res, res->start, resource_size(res));
if (cxled->skip)
- __release_region(&cxlds->dpa_res, skip_start, cxled->skip);
+ release_skip(cxlds, skip_start, cxled->skip);
cxled->skip = 0;
cxled->dpa_res = NULL;
put_device(&cxled->cxld.dev);
@@ -250,9 +280,8 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
static void cxl_dpa_release(void *cxled)
{
- down_write(&cxl_dpa_rwsem);
+ guard(rwsem_write)(&cxl_dpa_rwsem);
__cxl_dpa_release(cxled);
- up_write(&cxl_dpa_rwsem);
}
/*
@@ -268,6 +297,58 @@ static void devm_cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
__cxl_dpa_release(cxled);
}
+/**
+ * request_skip() - Track DPA 'skip' in @cxlds->dpa_res resource tree
+ * @cxlds: CXL.mem device context that parents @cxled
+ * @cxled: Endpoint decoder establishing new allocation that skips lower DPA
+ * @skip_base: DPA < start of new DPA allocation (DPAnew)
+ * @skip_len: @skip_base + @skip_len == DPAnew
+ *
+ * DPA 'skip' arises from out-of-sequence DPA allocation events relative
+ * to free capacity across multiple partitions. It is a wasteful event
+ * as usable DPA gets thrown away, but if a deployment has, for example,
+ * a dual RAM+PMEM device, wants to use PMEM, and has unallocated RAM
+ * DPA, the free RAM DPA must be sacrificed to start allocating PMEM.
+ * See third "Implementation Note" in CXL 3.1 8.2.4.19.13 "Decoder
+ * Protection" for more details.
+ *
+ * A 'skip' always covers the last allocated DPA in a previous partition
+ * to the start of the current partition to allocate. Allocations never
+ * start in the middle of a partition, and allocations are always
+ * de-allocated in reverse order (see cxl_dpa_free(), or natural devm
+ * unwind order from forced in-order allocation).
+ *
+ * If @cxlds->nr_partitions was guaranteed to be <= 2 then the 'skip'
+ * would always be contained to a single partition. Given
+ * @cxlds->nr_partitions may be > 2 it results in cases where the 'skip'
+ * might span "tail capacity of partition[0], all of partition[1], ...,
+ * all of partition[N-1]" to support allocating from partition[N]. That
+ * in turn interacts with the partition 'struct resource' boundaries
+ * within @cxlds->dpa_res whereby 'skip' requests need to be divided by
+ * partition. I.e. this is a quirk of using a 'struct resource' tree to
+ * detect range conflicts while also tracking partition boundaries in
+ * @cxlds->dpa_res.
+ */
+static int request_skip(struct cxl_dev_state *cxlds,
+ struct cxl_endpoint_decoder *cxled,
+ const resource_size_t skip_base,
+ const resource_size_t skip_len)
+{
+ resource_size_t skipped = __adjust_skip(cxlds, skip_base, skip_len,
+ dev_name(&cxled->cxld.dev));
+
+ if (skipped == skip_len)
+ return 0;
+
+ dev_dbg(cxlds->dev,
+ "%s: failed to reserve skipped space (%pa %pa %pa)\n",
+ dev_name(&cxled->cxld.dev), &skip_base, &skip_len, &skipped);
+
+ release_skip(cxlds, skip_base, skipped);
+
+ return -EBUSY;
+}
+
static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
resource_size_t base, resource_size_t len,
resource_size_t skipped)
@@ -277,6 +358,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct device *dev = &port->dev;
struct resource *res;
+ int rc;
lockdep_assert_held_write(&cxl_dpa_rwsem);
@@ -305,14 +387,9 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
}
if (skipped) {
- res = __request_region(&cxlds->dpa_res, base - skipped, skipped,
- dev_name(&cxled->cxld.dev), 0);
- if (!res) {
- dev_dbg(dev,
- "decoder%d.%d: failed to reserve skipped space\n",
- port->id, cxled->cxld.id);
- return -EBUSY;
- }
+ rc = request_skip(cxlds, cxled, base - skipped, skipped);
+ if (rc)
+ return rc;
}
res = __request_region(&cxlds->dpa_res, base, len,
dev_name(&cxled->cxld.dev), 0);
@@ -320,28 +397,117 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
dev_dbg(dev, "decoder%d.%d: failed to reserve allocation\n",
port->id, cxled->cxld.id);
if (skipped)
- __release_region(&cxlds->dpa_res, base - skipped,
- skipped);
+ release_skip(cxlds, base - skipped, skipped);
return -EBUSY;
}
cxled->dpa_res = res;
cxled->skip = skipped;
- if (resource_contains(&cxlds->pmem_res, res))
- cxled->mode = CXL_DECODER_PMEM;
- else if (resource_contains(&cxlds->ram_res, res))
- cxled->mode = CXL_DECODER_RAM;
- else {
- dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
- port->id, cxled->cxld.id, cxled->dpa_res);
- cxled->mode = CXL_DECODER_MIXED;
- }
+ /*
+ * When allocating new capacity, ->part is already set, when
+ * discovering decoder settings at initial enumeration, ->part
+ * is not set.
+ */
+ if (cxled->part < 0)
+ for (int i = 0; cxlds->nr_partitions; i++)
+ if (resource_contains(&cxlds->part[i].res, res)) {
+ cxled->part = i;
+ break;
+ }
+
+ if (cxled->part < 0)
+ dev_warn(dev, "decoder%d.%d: %pr does not map any partition\n",
+ port->id, cxled->cxld.id, res);
port->hdm_end++;
get_device(&cxled->cxld.dev);
return 0;
}
+static int add_dpa_res(struct device *dev, struct resource *parent,
+ struct resource *res, resource_size_t start,
+ resource_size_t size, const char *type)
+{
+ int rc;
+
+ *res = (struct resource) {
+ .name = type,
+ .start = start,
+ .end = start + size - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ if (resource_size(res) == 0) {
+ dev_dbg(dev, "DPA(%s): no capacity\n", res->name);
+ return 0;
+ }
+ rc = request_resource(parent, res);
+ if (rc) {
+ dev_err(dev, "DPA(%s): failed to track %pr (%d)\n", res->name,
+ res, rc);
+ return rc;
+ }
+
+ dev_dbg(dev, "DPA(%s): %pr\n", res->name, res);
+
+ return 0;
+}
+
+static const char *cxl_mode_name(enum cxl_partition_mode mode)
+{
+ switch (mode) {
+ case CXL_PARTMODE_RAM:
+ return "ram";
+ case CXL_PARTMODE_PMEM:
+ return "pmem";
+ default:
+ return "";
+ };
+}
+
+/* if this fails the caller must destroy @cxlds, there is no recovery */
+int cxl_dpa_setup(struct cxl_dev_state *cxlds, const struct cxl_dpa_info *info)
+{
+ struct device *dev = cxlds->dev;
+
+ guard(rwsem_write)(&cxl_dpa_rwsem);
+
+ if (cxlds->nr_partitions)
+ return -EBUSY;
+
+ if (!info->size || !info->nr_partitions) {
+ cxlds->dpa_res = DEFINE_RES_MEM(0, 0);
+ cxlds->nr_partitions = 0;
+ return 0;
+ }
+
+ cxlds->dpa_res = DEFINE_RES_MEM(0, info->size);
+
+ for (int i = 0; i < info->nr_partitions; i++) {
+ const struct cxl_dpa_part_info *part = &info->part[i];
+ int rc;
+
+ cxlds->part[i].perf.qos_class = CXL_QOS_CLASS_INVALID;
+ cxlds->part[i].mode = part->mode;
+
+ /* Require ordered + contiguous partitions */
+ if (i) {
+ const struct cxl_dpa_part_info *prev = &info->part[i - 1];
+
+ if (prev->range.end + 1 != part->range.start)
+ return -EINVAL;
+ }
+ rc = add_dpa_res(dev, &cxlds->dpa_res, &cxlds->part[i].res,
+ part->range.start, range_len(&part->range),
+ cxl_mode_name(part->mode));
+ if (rc)
+ return rc;
+ cxlds->nr_partitions++;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_dpa_setup);
+
int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
resource_size_t base, resource_size_t len,
resource_size_t skipped)
@@ -362,14 +528,11 @@ EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, "CXL");
resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled)
{
- resource_size_t size = 0;
-
- down_read(&cxl_dpa_rwsem);
+ guard(rwsem_read)(&cxl_dpa_rwsem);
if (cxled->dpa_res)
- size = resource_size(cxled->dpa_res);
- up_read(&cxl_dpa_rwsem);
+ return resource_size(cxled->dpa_res);
- return size;
+ return 0;
}
resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled)
@@ -387,151 +550,136 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
{
struct cxl_port *port = cxled_to_port(cxled);
struct device *dev = &cxled->cxld.dev;
- int rc;
- down_write(&cxl_dpa_rwsem);
- if (!cxled->dpa_res) {
- rc = 0;
- goto out;
- }
+ guard(rwsem_write)(&cxl_dpa_rwsem);
+ if (!cxled->dpa_res)
+ return 0;
if (cxled->cxld.region) {
dev_dbg(dev, "decoder assigned to: %s\n",
dev_name(&cxled->cxld.region->dev));
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
dev_dbg(dev, "decoder enabled\n");
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
if (cxled->cxld.id != port->hdm_end) {
dev_dbg(dev, "expected decoder%d.%d\n", port->id,
port->hdm_end);
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
+
devm_cxl_dpa_release(cxled);
- rc = 0;
-out:
- up_write(&cxl_dpa_rwsem);
- return rc;
+ return 0;
}
-int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
- enum cxl_decoder_mode mode)
+int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
+ enum cxl_partition_mode mode)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct device *dev = &cxled->cxld.dev;
-
- switch (mode) {
- case CXL_DECODER_RAM:
- case CXL_DECODER_PMEM:
- break;
- default:
- dev_dbg(dev, "unsupported mode: %d\n", mode);
- return -EINVAL;
- }
+ int part;
guard(rwsem_write)(&cxl_dpa_rwsem);
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE)
return -EBUSY;
- /*
- * Only allow modes that are supported by the current partition
- * configuration
- */
- if (mode == CXL_DECODER_PMEM && !resource_size(&cxlds->pmem_res)) {
- dev_dbg(dev, "no available pmem capacity\n");
- return -ENXIO;
+ for (part = 0; part < cxlds->nr_partitions; part++)
+ if (cxlds->part[part].mode == mode)
+ break;
+
+ if (part >= cxlds->nr_partitions) {
+ dev_dbg(dev, "unsupported mode: %d\n", mode);
+ return -EINVAL;
}
- if (mode == CXL_DECODER_RAM && !resource_size(&cxlds->ram_res)) {
- dev_dbg(dev, "no available ram capacity\n");
+
+ if (!resource_size(&cxlds->part[part].res)) {
+ dev_dbg(dev, "no available capacity for mode: %d\n", mode);
return -ENXIO;
}
- cxled->mode = mode;
+ cxled->part = part;
return 0;
}
-int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
+static int __cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
- resource_size_t free_ram_start, free_pmem_start;
- struct cxl_port *port = cxled_to_port(cxled);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct device *dev = &cxled->cxld.dev;
- resource_size_t start, avail, skip;
+ struct resource *res, *prev = NULL;
+ resource_size_t start, avail, skip, skip_start;
struct resource *p, *last;
- int rc;
+ int part;
- down_write(&cxl_dpa_rwsem);
+ guard(rwsem_write)(&cxl_dpa_rwsem);
if (cxled->cxld.region) {
dev_dbg(dev, "decoder attached to %s\n",
dev_name(&cxled->cxld.region->dev));
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
dev_dbg(dev, "decoder enabled\n");
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
- for (p = cxlds->ram_res.child, last = NULL; p; p = p->sibling)
- last = p;
- if (last)
- free_ram_start = last->end + 1;
- else
- free_ram_start = cxlds->ram_res.start;
+ part = cxled->part;
+ if (part < 0) {
+ dev_dbg(dev, "partition not set\n");
+ return -EBUSY;
+ }
- for (p = cxlds->pmem_res.child, last = NULL; p; p = p->sibling)
+ res = &cxlds->part[part].res;
+ for (p = res->child, last = NULL; p; p = p->sibling)
last = p;
if (last)
- free_pmem_start = last->end + 1;
+ start = last->end + 1;
else
- free_pmem_start = cxlds->pmem_res.start;
-
- if (cxled->mode == CXL_DECODER_RAM) {
- start = free_ram_start;
- avail = cxlds->ram_res.end - start + 1;
- skip = 0;
- } else if (cxled->mode == CXL_DECODER_PMEM) {
- resource_size_t skip_start, skip_end;
-
- start = free_pmem_start;
- avail = cxlds->pmem_res.end - start + 1;
- skip_start = free_ram_start;
+ start = res->start;
- /*
- * If some pmem is already allocated, then that allocation
- * already handled the skip.
- */
- if (cxlds->pmem_res.child &&
- skip_start == cxlds->pmem_res.child->start)
- skip_end = skip_start - 1;
- else
- skip_end = start - 1;
- skip = skip_end - skip_start + 1;
- } else {
- dev_dbg(dev, "mode not set\n");
- rc = -EINVAL;
- goto out;
+ /*
+ * To allocate at partition N, a skip needs to be calculated for all
+ * unallocated space at lower partitions indices.
+ *
+ * If a partition has any allocations, the search can end because a
+ * previous cxl_dpa_alloc() invocation is assumed to have accounted for
+ * all previous partitions.
+ */
+ skip_start = CXL_RESOURCE_NONE;
+ for (int i = part; i; i--) {
+ prev = &cxlds->part[i - 1].res;
+ for (p = prev->child, last = NULL; p; p = p->sibling)
+ last = p;
+ if (last) {
+ skip_start = last->end + 1;
+ break;
+ }
+ skip_start = prev->start;
}
+ avail = res->end - start + 1;
+ if (skip_start == CXL_RESOURCE_NONE)
+ skip = 0;
+ else
+ skip = res->start - skip_start;
+
if (size > avail) {
dev_dbg(dev, "%pa exceeds available %s capacity: %pa\n", &size,
- cxl_decoder_mode_name(cxled->mode), &avail);
- rc = -ENOSPC;
- goto out;
+ res->name, &avail);
+ return -ENOSPC;
}
- rc = __cxl_dpa_reserve(cxled, start, size, skip);
-out:
- up_write(&cxl_dpa_rwsem);
+ return __cxl_dpa_reserve(cxled, start, size, skip);
+}
+
+int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
+{
+ struct cxl_port *port = cxled_to_port(cxled);
+ int rc;
+ rc = __cxl_dpa_alloc(cxled, size);
if (rc)
return rc;
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 78c5346e3e89..d72764056ce6 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -11,6 +11,7 @@
#include "core.h"
#include "trace.h"
+#include "mce.h"
static bool cxl_raw_allow_all;
@@ -900,7 +901,7 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
}
if (trace_cxl_general_media_enabled() || trace_cxl_dram_enabled()) {
- u64 dpa, hpa = ULLONG_MAX;
+ u64 dpa, hpa = ULLONG_MAX, hpa_alias = ULLONG_MAX;
struct cxl_region *cxlr;
/*
@@ -913,14 +914,20 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
dpa = le64_to_cpu(evt->media_hdr.phys_addr) & CXL_DPA_MASK;
cxlr = cxl_dpa_to_region(cxlmd, dpa);
- if (cxlr)
+ if (cxlr) {
+ u64 cache_size = cxlr->params.cache_size;
+
hpa = cxl_dpa_to_hpa(cxlr, cxlmd, dpa);
+ if (cache_size)
+ hpa_alias = hpa - cache_size;
+ }
if (event_type == CXL_CPER_EVENT_GEN_MEDIA)
trace_cxl_general_media(cxlmd, type, cxlr, hpa,
- &evt->gen_media);
+ hpa_alias, &evt->gen_media);
else if (event_type == CXL_CPER_EVENT_DRAM)
- trace_cxl_dram(cxlmd, type, cxlr, hpa, &evt->dram);
+ trace_cxl_dram(cxlmd, type, cxlr, hpa, hpa_alias,
+ &evt->dram);
}
}
EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, "CXL");
@@ -1126,10 +1133,6 @@ static int cxl_mem_get_partition_info(struct cxl_memdev_state *mds)
le64_to_cpu(pi.active_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
mds->active_persistent_bytes =
le64_to_cpu(pi.active_persistent_cap) * CXL_CAPACITY_MULTIPLIER;
- mds->next_volatile_bytes =
- le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
- mds->next_persistent_bytes =
- le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
return 0;
}
@@ -1251,74 +1254,54 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)
{
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
struct cxl_port *endpoint;
- int rc;
/* synchronize with cxl_mem_probe() and decoder write operations */
guard(device)(&cxlmd->dev);
endpoint = cxlmd->endpoint;
- down_read(&cxl_region_rwsem);
+ guard(rwsem_read)(&cxl_region_rwsem);
/*
* Require an endpoint to be safe otherwise the driver can not
* be sure that the device is unmapped.
*/
if (endpoint && cxl_num_decoders_committed(endpoint) == 0)
- rc = __cxl_mem_sanitize(mds, cmd);
- else
- rc = -EBUSY;
- up_read(&cxl_region_rwsem);
+ return __cxl_mem_sanitize(mds, cmd);
- return rc;
+ return -EBUSY;
}
-static int add_dpa_res(struct device *dev, struct resource *parent,
- struct resource *res, resource_size_t start,
- resource_size_t size, const char *type)
+static void add_part(struct cxl_dpa_info *info, u64 start, u64 size, enum cxl_partition_mode mode)
{
- int rc;
-
- res->name = type;
- res->start = start;
- res->end = start + size - 1;
- res->flags = IORESOURCE_MEM;
- if (resource_size(res) == 0) {
- dev_dbg(dev, "DPA(%s): no capacity\n", res->name);
- return 0;
- }
- rc = request_resource(parent, res);
- if (rc) {
- dev_err(dev, "DPA(%s): failed to track %pr (%d)\n", res->name,
- res, rc);
- return rc;
- }
+ int i = info->nr_partitions;
- dev_dbg(dev, "DPA(%s): %pr\n", res->name, res);
+ if (size == 0)
+ return;
- return 0;
+ info->part[i].range = (struct range) {
+ .start = start,
+ .end = start + size - 1,
+ };
+ info->part[i].mode = mode;
+ info->nr_partitions++;
}
-int cxl_mem_create_range_info(struct cxl_memdev_state *mds)
+int cxl_mem_dpa_fetch(struct cxl_memdev_state *mds, struct cxl_dpa_info *info)
{
struct cxl_dev_state *cxlds = &mds->cxlds;
struct device *dev = cxlds->dev;
int rc;
if (!cxlds->media_ready) {
- cxlds->dpa_res = DEFINE_RES_MEM(0, 0);
- cxlds->ram_res = DEFINE_RES_MEM(0, 0);
- cxlds->pmem_res = DEFINE_RES_MEM(0, 0);
+ info->size = 0;
return 0;
}
- cxlds->dpa_res = DEFINE_RES_MEM(0, mds->total_bytes);
+ info->size = mds->total_bytes;
if (mds->partition_align_bytes == 0) {
- rc = add_dpa_res(dev, &cxlds->dpa_res, &cxlds->ram_res, 0,
- mds->volatile_only_bytes, "ram");
- if (rc)
- return rc;
- return add_dpa_res(dev, &cxlds->dpa_res, &cxlds->pmem_res,
- mds->volatile_only_bytes,
- mds->persistent_only_bytes, "pmem");
+ add_part(info, 0, mds->volatile_only_bytes, CXL_PARTMODE_RAM);
+ add_part(info, mds->volatile_only_bytes,
+ mds->persistent_only_bytes, CXL_PARTMODE_PMEM);
+ return 0;
}
rc = cxl_mem_get_partition_info(mds);
@@ -1327,15 +1310,52 @@ int cxl_mem_create_range_info(struct cxl_memdev_state *mds)
return rc;
}
- rc = add_dpa_res(dev, &cxlds->dpa_res, &cxlds->ram_res, 0,
- mds->active_volatile_bytes, "ram");
- if (rc)
- return rc;
- return add_dpa_res(dev, &cxlds->dpa_res, &cxlds->pmem_res,
- mds->active_volatile_bytes,
- mds->active_persistent_bytes, "pmem");
+ add_part(info, 0, mds->active_volatile_bytes, CXL_PARTMODE_RAM);
+ add_part(info, mds->active_volatile_bytes, mds->active_persistent_bytes,
+ CXL_PARTMODE_PMEM);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_mem_dpa_fetch, "CXL");
+
+int cxl_get_dirty_count(struct cxl_memdev_state *mds, u32 *count)
+{
+ struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
+ struct cxl_mbox_get_health_info_out hi;
+ struct cxl_mbox_cmd mbox_cmd;
+ int rc;
+
+ mbox_cmd = (struct cxl_mbox_cmd) {
+ .opcode = CXL_MBOX_OP_GET_HEALTH_INFO,
+ .size_out = sizeof(hi),
+ .payload_out = &hi,
+ };
+
+ rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
+ if (!rc)
+ *count = le32_to_cpu(hi.dirty_shutdown_cnt);
+
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_get_dirty_count, "CXL");
+
+int cxl_arm_dirty_shutdown(struct cxl_memdev_state *mds)
+{
+ struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
+ struct cxl_mbox_cmd mbox_cmd;
+ struct cxl_mbox_set_shutdown_state_in in = {
+ .state = 1
+ };
+
+ mbox_cmd = (struct cxl_mbox_cmd) {
+ .opcode = CXL_MBOX_OP_SET_SHUTDOWN_STATE,
+ .size_in = sizeof(in),
+ .payload_in = &in,
+ };
+
+ return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
}
-EXPORT_SYMBOL_NS_GPL(cxl_mem_create_range_info, "CXL");
+EXPORT_SYMBOL_NS_GPL(cxl_arm_dirty_shutdown, "CXL");
int cxl_set_timestamp(struct cxl_memdev_state *mds)
{
@@ -1467,6 +1487,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_mailbox_init, "CXL");
struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
{
struct cxl_memdev_state *mds;
+ int rc;
mds = devm_kzalloc(dev, sizeof(*mds), GFP_KERNEL);
if (!mds) {
@@ -1480,8 +1501,12 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
mds->cxlds.cxl_mbox.host = dev;
mds->cxlds.reg_map.resource = CXL_RESOURCE_NONE;
mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
- mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
- mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
+
+ rc = devm_cxl_register_mce_notifier(dev, &mds->mce_notifier);
+ if (rc == -EOPNOTSUPP)
+ dev_warn(dev, "CXL MCE unsupported\n");
+ else if (rc)
+ return ERR_PTR(rc);
return mds;
}
diff --git a/drivers/cxl/core/mce.c b/drivers/cxl/core/mce.c
new file mode 100644
index 000000000000..ff8d078c6ca1
--- /dev/null
+++ b/drivers/cxl/core/mce.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
+#include <linux/mm.h>
+#include <linux/notifier.h>
+#include <linux/set_memory.h>
+#include <asm/mce.h>
+#include <cxlmem.h>
+#include "mce.h"
+
+static int cxl_handle_mce(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ struct cxl_memdev_state *mds = container_of(nb, struct cxl_memdev_state,
+ mce_notifier);
+ struct cxl_memdev *cxlmd = mds->cxlds.cxlmd;
+ struct cxl_port *endpoint = cxlmd->endpoint;
+ struct mce *mce = data;
+ u64 spa, spa_alias;
+ unsigned long pfn;
+
+ if (!mce || !mce_usable_address(mce))
+ return NOTIFY_DONE;
+
+ if (!endpoint)
+ return NOTIFY_DONE;
+
+ spa = mce->addr & MCI_ADDR_PHYSADDR;
+
+ pfn = spa >> PAGE_SHIFT;
+ if (!pfn_valid(pfn))
+ return NOTIFY_DONE;
+
+ spa_alias = cxl_port_get_spa_cache_alias(endpoint, spa);
+ if (spa_alias == ~0ULL)
+ return NOTIFY_DONE;
+
+ pfn = spa_alias >> PAGE_SHIFT;
+
+ /*
+ * Take down the aliased memory page. The original memory page flagged
+ * by the MCE will be taken cared of by the standard MCE handler.
+ */
+ dev_emerg(mds->cxlds.dev, "Offlining aliased SPA address0: %#llx\n",
+ spa_alias);
+ if (!memory_failure(pfn, 0))
+ set_mce_nospec(pfn);
+
+ return NOTIFY_OK;
+}
+
+static void cxl_unregister_mce_notifier(void *mce_notifier)
+{
+ mce_unregister_decode_chain(mce_notifier);
+}
+
+int devm_cxl_register_mce_notifier(struct device *dev,
+ struct notifier_block *mce_notifier)
+{
+ mce_notifier->notifier_call = cxl_handle_mce;
+ mce_notifier->priority = MCE_PRIO_UC;
+ mce_register_decode_chain(mce_notifier);
+
+ return devm_add_action_or_reset(dev, cxl_unregister_mce_notifier,
+ mce_notifier);
+}
diff --git a/drivers/cxl/core/mce.h b/drivers/cxl/core/mce.h
new file mode 100644
index 000000000000..ace73424eeb6
--- /dev/null
+++ b/drivers/cxl/core/mce.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
+#ifndef _CXL_CORE_MCE_H_
+#define _CXL_CORE_MCE_H_
+
+#include <linux/notifier.h>
+
+#ifdef CONFIG_CXL_MCE
+int devm_cxl_register_mce_notifier(struct device *dev,
+ struct notifier_block *mce_notifer);
+#else
+static inline int
+devm_cxl_register_mce_notifier(struct device *dev,
+ struct notifier_block *mce_notifier)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
+#endif
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 2e2e035abdaa..a16a5886d40a 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -75,12 +75,20 @@ static ssize_t label_storage_size_show(struct device *dev,
}
static DEVICE_ATTR_RO(label_storage_size);
+static resource_size_t cxl_ram_size(struct cxl_dev_state *cxlds)
+{
+ /* Static RAM is only expected at partition 0. */
+ if (cxlds->part[0].mode != CXL_PARTMODE_RAM)
+ return 0;
+ return resource_size(&cxlds->part[0].res);
+}
+
static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
- unsigned long long len = resource_size(&cxlds->ram_res);
+ unsigned long long len = cxl_ram_size(cxlds);
return sysfs_emit(buf, "%#llx\n", len);
}
@@ -93,7 +101,7 @@ static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
- unsigned long long len = resource_size(&cxlds->pmem_res);
+ unsigned long long len = cxl_pmem_size(cxlds);
return sysfs_emit(buf, "%#llx\n", len);
}
@@ -198,22 +206,17 @@ static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
int rc = 0;
/* CXL 3.0 Spec 8.2.9.8.4.1 Separate pmem and ram poison requests */
- if (resource_size(&cxlds->pmem_res)) {
- offset = cxlds->pmem_res.start;
- length = resource_size(&cxlds->pmem_res);
- rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
- if (rc)
- return rc;
- }
- if (resource_size(&cxlds->ram_res)) {
- offset = cxlds->ram_res.start;
- length = resource_size(&cxlds->ram_res);
+ for (int i = 0; i < cxlds->nr_partitions; i++) {
+ const struct resource *res = &cxlds->part[i].res;
+
+ offset = res->start;
+ length = resource_size(res);
rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
/*
* Invalid Physical Address is not an error for
* volatile addresses. Device support is optional.
*/
- if (rc == -EFAULT)
+ if (rc == -EFAULT && cxlds->part[i].mode == CXL_PARTMODE_RAM)
rc = 0;
}
return rc;
@@ -404,14 +407,21 @@ static struct attribute *cxl_memdev_attributes[] = {
NULL,
};
+static struct cxl_dpa_perf *to_pmem_perf(struct cxl_dev_state *cxlds)
+{
+ for (int i = 0; i < cxlds->nr_partitions; i++)
+ if (cxlds->part[i].mode == CXL_PARTMODE_PMEM)
+ return &cxlds->part[i].perf;
+ return NULL;
+}
+
static ssize_t pmem_qos_class_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
- return sysfs_emit(buf, "%d\n", mds->pmem_perf.qos_class);
+ return sysfs_emit(buf, "%d\n", to_pmem_perf(cxlds)->qos_class);
}
static struct device_attribute dev_attr_pmem_qos_class =
@@ -423,14 +433,20 @@ static struct attribute *cxl_memdev_pmem_attributes[] = {
NULL,
};
+static struct cxl_dpa_perf *to_ram_perf(struct cxl_dev_state *cxlds)
+{
+ if (cxlds->part[0].mode != CXL_PARTMODE_RAM)
+ return NULL;
+ return &cxlds->part[0].perf;
+}
+
static ssize_t ram_qos_class_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
- return sysfs_emit(buf, "%d\n", mds->ram_perf.qos_class);
+ return sysfs_emit(buf, "%d\n", to_ram_perf(cxlds)->qos_class);
}
static struct device_attribute dev_attr_ram_qos_class =
@@ -466,11 +482,11 @@ static umode_t cxl_ram_visible(struct kobject *kobj, struct attribute *a, int n)
{
struct device *dev = kobj_to_dev(kobj);
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
+ struct cxl_dpa_perf *perf = to_ram_perf(cxlmd->cxlds);
- if (a == &dev_attr_ram_qos_class.attr)
- if (mds->ram_perf.qos_class == CXL_QOS_CLASS_INVALID)
- return 0;
+ if (a == &dev_attr_ram_qos_class.attr &&
+ (!perf || perf->qos_class == CXL_QOS_CLASS_INVALID))
+ return 0;
return a->mode;
}
@@ -485,11 +501,11 @@ static umode_t cxl_pmem_visible(struct kobject *kobj, struct attribute *a, int n
{
struct device *dev = kobj_to_dev(kobj);
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
+ struct cxl_dpa_perf *perf = to_pmem_perf(cxlmd->cxlds);
- if (a == &dev_attr_pmem_qos_class.attr)
- if (mds->pmem_perf.qos_class == CXL_QOS_CLASS_INVALID)
- return 0;
+ if (a == &dev_attr_pmem_qos_class.attr &&
+ (!perf || perf->qos_class == CXL_QOS_CLASS_INVALID))
+ return 0;
return a->mode;
}
@@ -566,10 +582,9 @@ void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
{
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
- down_write(&cxl_memdev_rwsem);
+ guard(rwsem_write)(&cxl_memdev_rwsem);
bitmap_or(cxl_mbox->exclusive_cmds, cxl_mbox->exclusive_cmds,
cmds, CXL_MEM_COMMAND_ID_MAX);
- up_write(&cxl_memdev_rwsem);
}
EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL");
@@ -583,10 +598,9 @@ void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
{
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
- down_write(&cxl_memdev_rwsem);
+ guard(rwsem_write)(&cxl_memdev_rwsem);
bitmap_andnot(cxl_mbox->exclusive_cmds, cxl_mbox->exclusive_cmds,
cmds, CXL_MEM_COMMAND_ID_MAX);
- up_write(&cxl_memdev_rwsem);
}
EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, "CXL");
@@ -594,9 +608,8 @@ static void cxl_memdev_shutdown(struct device *dev)
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
- down_write(&cxl_memdev_rwsem);
+ guard(rwsem_write)(&cxl_memdev_rwsem);
cxlmd->cxlds = NULL;
- up_write(&cxl_memdev_rwsem);
}
static void cxl_memdev_unregister(void *_cxlmd)
@@ -678,15 +691,13 @@ static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
{
struct cxl_memdev *cxlmd = file->private_data;
struct cxl_dev_state *cxlds;
- int rc = -ENXIO;
- down_read(&cxl_memdev_rwsem);
+ guard(rwsem_read)(&cxl_memdev_rwsem);
cxlds = cxlmd->cxlds;
if (cxlds && cxlds->type == CXL_DEVTYPE_CLASSMEM)
- rc = __cxl_memdev_ioctl(cxlmd, cmd, arg);
- up_read(&cxl_memdev_rwsem);
+ return __cxl_memdev_ioctl(cxlmd, cmd, arg);
- return rc;
+ return -ENXIO;
}
static int cxl_memdev_open(struct inode *inode, struct file *file)
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 013b869b66cb..96fecb799cbc 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -1054,3 +1054,100 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
return 0;
}
+
+/*
+ * Set max timeout such that platforms will optimize GPF flow to avoid
+ * the implied worst-case scenario delays. On a sane platform, all
+ * devices should always complete GPF within the energy budget of
+ * the GPF flow. The kernel does not have enough information to pick
+ * anything better than "maximize timeouts and hope it works".
+ *
+ * A misbehaving device could block forward progress of GPF for all
+ * the other devices, exhausting the energy budget of the platform.
+ * However, the spec seems to assume that moving on from slow to respond
+ * devices is a virtue. It is not possible to know that, in actuality,
+ * the slow to respond device is *the* most critical device in the
+ * system to wait.
+ */
+#define GPF_TIMEOUT_BASE_MAX 2
+#define GPF_TIMEOUT_SCALE_MAX 7 /* 10 seconds */
+
+u16 cxl_gpf_get_dvsec(struct device *dev, bool is_port)
+{
+ u16 dvsec;
+
+ if (!dev_is_pci(dev))
+ return 0;
+
+ dvsec = pci_find_dvsec_capability(to_pci_dev(dev), PCI_VENDOR_ID_CXL,
+ is_port ? CXL_DVSEC_PORT_GPF : CXL_DVSEC_DEVICE_GPF);
+ if (!dvsec)
+ dev_warn(dev, "%s GPF DVSEC not present\n",
+ is_port ? "Port" : "Device");
+ return dvsec;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_gpf_get_dvsec, "CXL");
+
+static int update_gpf_port_dvsec(struct pci_dev *pdev, int dvsec, int phase)
+{
+ u64 base, scale;
+ int rc, offset;
+ u16 ctrl;
+
+ switch (phase) {
+ case 1:
+ offset = CXL_DVSEC_PORT_GPF_PHASE_1_CONTROL_OFFSET;
+ base = CXL_DVSEC_PORT_GPF_PHASE_1_TMO_BASE_MASK;
+ scale = CXL_DVSEC_PORT_GPF_PHASE_1_TMO_SCALE_MASK;
+ break;
+ case 2:
+ offset = CXL_DVSEC_PORT_GPF_PHASE_2_CONTROL_OFFSET;
+ base = CXL_DVSEC_PORT_GPF_PHASE_2_TMO_BASE_MASK;
+ scale = CXL_DVSEC_PORT_GPF_PHASE_2_TMO_SCALE_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rc = pci_read_config_word(pdev, dvsec + offset, &ctrl);
+ if (rc)
+ return rc;
+
+ if (FIELD_GET(base, ctrl) == GPF_TIMEOUT_BASE_MAX &&
+ FIELD_GET(scale, ctrl) == GPF_TIMEOUT_SCALE_MAX)
+ return 0;
+
+ ctrl = FIELD_PREP(base, GPF_TIMEOUT_BASE_MAX);
+ ctrl |= FIELD_PREP(scale, GPF_TIMEOUT_SCALE_MAX);
+
+ rc = pci_write_config_word(pdev, dvsec + offset, ctrl);
+ if (!rc)
+ pci_dbg(pdev, "Port GPF phase %d timeout: %d0 secs\n",
+ phase, GPF_TIMEOUT_BASE_MAX);
+
+ return rc;
+}
+
+int cxl_gpf_port_setup(struct device *dport_dev, struct cxl_port *port)
+{
+ struct pci_dev *pdev;
+
+ if (!port)
+ return -EINVAL;
+
+ if (!port->gpf_dvsec) {
+ int dvsec;
+
+ dvsec = cxl_gpf_get_dvsec(dport_dev, true);
+ if (!dvsec)
+ return -EINVAL;
+
+ port->gpf_dvsec = dvsec;
+ }
+
+ pdev = to_pci_dev(dport_dev);
+ update_gpf_port_dvsec(pdev, port->gpf_dvsec, 1);
+ update_gpf_port_dvsec(pdev, port->gpf_dvsec, 2);
+
+ return 0;
+}
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 78a5c2c25982..0fd6646c1a2e 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -194,25 +194,35 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ /* without @cxl_dpa_rwsem, make sure @part is not reloaded */
+ int part = READ_ONCE(cxled->part);
+ const char *desc;
+
+ if (part < 0)
+ desc = "none";
+ else
+ desc = cxlds->part[part].res.name;
- return sysfs_emit(buf, "%s\n", cxl_decoder_mode_name(cxled->mode));
+ return sysfs_emit(buf, "%s\n", desc);
}
static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
- enum cxl_decoder_mode mode;
+ enum cxl_partition_mode mode;
ssize_t rc;
if (sysfs_streq(buf, "pmem"))
- mode = CXL_DECODER_PMEM;
+ mode = CXL_PARTMODE_PMEM;
else if (sysfs_streq(buf, "ram"))
- mode = CXL_DECODER_RAM;
+ mode = CXL_PARTMODE_RAM;
else
return -EINVAL;
- rc = cxl_dpa_set_mode(cxled, mode);
+ rc = cxl_dpa_set_part(cxled, mode);
if (rc)
return rc;
@@ -549,13 +559,9 @@ static ssize_t decoders_committed_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct cxl_port *port = to_cxl_port(dev);
- int rc;
-
- down_read(&cxl_region_rwsem);
- rc = sysfs_emit(buf, "%d\n", cxl_num_decoders_committed(port));
- up_read(&cxl_region_rwsem);
- return rc;
+ guard(rwsem_read)(&cxl_region_rwsem);
+ return sysfs_emit(buf, "%d\n", cxl_num_decoders_committed(port));
}
static DEVICE_ATTR_RO(decoders_committed);
@@ -1672,6 +1678,8 @@ retry:
if (rc && rc != -EBUSY)
return rc;
+ cxl_gpf_port_setup(dport_dev, port);
+
/* Any more ports to add between this one and the root? */
if (!dev_is_cxl_root_child(&port->dev))
continue;
@@ -1899,6 +1907,7 @@ struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
return ERR_PTR(-ENOMEM);
cxled->pos = -1;
+ cxled->part = -1;
cxld = &cxled->cxld;
rc = cxl_decoder_init(port, cxld);
if (rc) {
@@ -2339,8 +2348,14 @@ static __init int cxl_core_init(void)
if (rc)
goto err_region;
+ rc = cxl_ras_init();
+ if (rc)
+ goto err_ras;
+
return 0;
+err_ras:
+ cxl_region_exit();
err_region:
bus_unregister(&cxl_bus_type);
err_bus:
@@ -2352,6 +2367,7 @@ err_wq:
static void cxl_core_exit(void)
{
+ cxl_ras_exit();
cxl_region_exit();
bus_unregister(&cxl_bus_type);
destroy_workqueue(cxl_bus_wq);
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
new file mode 100644
index 000000000000..485a831695c7
--- /dev/null
+++ b/drivers/cxl/core/ras.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2025 AMD Corporation. All rights reserved. */
+
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <cxl/event.h>
+#include <cxlmem.h>
+#include "trace.h"
+
+static void cxl_cper_trace_corr_port_prot_err(struct pci_dev *pdev,
+ struct cxl_ras_capability_regs ras_cap)
+{
+ u32 status = ras_cap.cor_status & ~ras_cap.cor_mask;
+
+ trace_cxl_port_aer_correctable_error(&pdev->dev, status);
+}
+
+static void cxl_cper_trace_uncorr_port_prot_err(struct pci_dev *pdev,
+ struct cxl_ras_capability_regs ras_cap)
+{
+ u32 status = ras_cap.uncor_status & ~ras_cap.uncor_mask;
+ u32 fe;
+
+ if (hweight32(status) > 1)
+ fe = BIT(FIELD_GET(CXL_RAS_CAP_CONTROL_FE_MASK,
+ ras_cap.cap_control));
+ else
+ fe = status;
+
+ trace_cxl_port_aer_uncorrectable_error(&pdev->dev, status, fe,
+ ras_cap.header_log);
+}
+
+static void cxl_cper_trace_corr_prot_err(struct pci_dev *pdev,
+ struct cxl_ras_capability_regs ras_cap)
+{
+ u32 status = ras_cap.cor_status & ~ras_cap.cor_mask;
+ struct cxl_dev_state *cxlds;
+
+ cxlds = pci_get_drvdata(pdev);
+ if (!cxlds)
+ return;
+
+ trace_cxl_aer_correctable_error(cxlds->cxlmd, status);
+}
+
+static void cxl_cper_trace_uncorr_prot_err(struct pci_dev *pdev,
+ struct cxl_ras_capability_regs ras_cap)
+{
+ u32 status = ras_cap.uncor_status & ~ras_cap.uncor_mask;
+ struct cxl_dev_state *cxlds;
+ u32 fe;
+
+ cxlds = pci_get_drvdata(pdev);
+ if (!cxlds)
+ return;
+
+ if (hweight32(status) > 1)
+ fe = BIT(FIELD_GET(CXL_RAS_CAP_CONTROL_FE_MASK,
+ ras_cap.cap_control));
+ else
+ fe = status;
+
+ trace_cxl_aer_uncorrectable_error(cxlds->cxlmd, status, fe,
+ ras_cap.header_log);
+}
+
+static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data)
+{
+ unsigned int devfn = PCI_DEVFN(data->prot_err.agent_addr.device,
+ data->prot_err.agent_addr.function);
+ struct pci_dev *pdev __free(pci_dev_put) =
+ pci_get_domain_bus_and_slot(data->prot_err.agent_addr.segment,
+ data->prot_err.agent_addr.bus,
+ devfn);
+ int port_type;
+
+ if (!pdev)
+ return;
+
+ guard(device)(&pdev->dev);
+
+ port_type = pci_pcie_type(pdev);
+ if (port_type == PCI_EXP_TYPE_ROOT_PORT ||
+ port_type == PCI_EXP_TYPE_DOWNSTREAM ||
+ port_type == PCI_EXP_TYPE_UPSTREAM) {
+ if (data->severity == AER_CORRECTABLE)
+ cxl_cper_trace_corr_port_prot_err(pdev, data->ras_cap);
+ else
+ cxl_cper_trace_uncorr_port_prot_err(pdev, data->ras_cap);
+
+ return;
+ }
+
+ if (data->severity == AER_CORRECTABLE)
+ cxl_cper_trace_corr_prot_err(pdev, data->ras_cap);
+ else
+ cxl_cper_trace_uncorr_prot_err(pdev, data->ras_cap);
+}
+
+static void cxl_cper_prot_err_work_fn(struct work_struct *work)
+{
+ struct cxl_cper_prot_err_work_data wd;
+
+ while (cxl_cper_prot_err_kfifo_get(&wd))
+ cxl_cper_handle_prot_err(&wd);
+}
+static DECLARE_WORK(cxl_cper_prot_err_work, cxl_cper_prot_err_work_fn);
+
+int cxl_ras_init(void)
+{
+ return cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
+}
+
+void cxl_ras_exit(void)
+{
+ cxl_cper_unregister_prot_err_work(&cxl_cper_prot_err_work);
+ cancel_work_sync(&cxl_cper_prot_err_work);
+}
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index e8d11a988fd9..c3f4dc244df7 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -144,7 +144,7 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
rc = down_read_interruptible(&cxl_region_rwsem);
if (rc)
return rc;
- if (cxlr->mode != CXL_DECODER_PMEM)
+ if (cxlr->mode != CXL_PARTMODE_PMEM)
rc = sysfs_emit(buf, "\n");
else
rc = sysfs_emit(buf, "%pUb\n", &p->uuid);
@@ -441,7 +441,7 @@ static umode_t cxl_region_visible(struct kobject *kobj, struct attribute *a,
* Support tooling that expects to find a 'uuid' attribute for all
* regions regardless of mode.
*/
- if (a == &dev_attr_uuid.attr && cxlr->mode != CXL_DECODER_PMEM)
+ if (a == &dev_attr_uuid.attr && cxlr->mode != CXL_PARTMODE_PMEM)
return 0444;
return a->mode;
}
@@ -603,8 +603,16 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct cxl_region *cxlr = to_cxl_region(dev);
+ const char *desc;
- return sysfs_emit(buf, "%s\n", cxl_decoder_mode_name(cxlr->mode));
+ if (cxlr->mode == CXL_PARTMODE_RAM)
+ desc = "ram";
+ else if (cxlr->mode == CXL_PARTMODE_PMEM)
+ desc = "pmem";
+ else
+ desc = "";
+
+ return sysfs_emit(buf, "%s\n", desc);
}
static DEVICE_ATTR_RO(mode);
@@ -630,7 +638,7 @@ static int alloc_hpa(struct cxl_region *cxlr, resource_size_t size)
/* ways, granularity and uuid (if PMEM) need to be set before HPA */
if (!p->interleave_ways || !p->interleave_granularity ||
- (cxlr->mode == CXL_DECODER_PMEM && uuid_is_null(&p->uuid)))
+ (cxlr->mode == CXL_PARTMODE_PMEM && uuid_is_null(&p->uuid)))
return -ENXIO;
div64_u64_rem(size, (u64)SZ_256M * p->interleave_ways, &remainder);
@@ -824,6 +832,21 @@ static int match_free_decoder(struct device *dev, const void *data)
return 1;
}
+static bool region_res_match_cxl_range(const struct cxl_region_params *p,
+ struct range *range)
+{
+ if (!p->res)
+ return false;
+
+ /*
+ * If an extended linear cache region then the CXL range is assumed
+ * to be fronted by the DRAM range in current known implementation.
+ * This assumption will be made until a variant implementation exists.
+ */
+ return p->res->start + p->cache_size == range->start &&
+ p->res->end == range->end;
+}
+
static int match_auto_decoder(struct device *dev, const void *data)
{
const struct cxl_region_params *p = data;
@@ -836,7 +859,7 @@ static int match_auto_decoder(struct device *dev, const void *data)
cxld = to_cxl_decoder(dev);
r = &cxld->hpa_range;
- if (p->res && p->res->start == r->start && p->res->end == r->end)
+ if (region_res_match_cxl_range(p, r))
return 1;
return 0;
@@ -1424,8 +1447,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
if (cxld->interleave_ways != iw ||
cxld->interleave_granularity != ig ||
- cxld->hpa_range.start != p->res->start ||
- cxld->hpa_range.end != p->res->end ||
+ !region_res_match_cxl_range(p, &cxld->hpa_range) ||
((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
dev_err(&cxlr->dev,
"%s:%s %s expected iw: %d ig: %d %pr\n",
@@ -1888,6 +1910,7 @@ static int cxl_region_attach(struct cxl_region *cxlr,
{
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct cxl_region_params *p = &cxlr->params;
struct cxl_port *ep_port, *root_port;
struct cxl_dport *dport;
@@ -1902,17 +1925,17 @@ static int cxl_region_attach(struct cxl_region *cxlr,
return rc;
}
- if (cxled->mode != cxlr->mode) {
- dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n",
- dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode);
- return -EINVAL;
- }
-
- if (cxled->mode == CXL_DECODER_DEAD) {
+ if (cxled->part < 0) {
dev_dbg(&cxlr->dev, "%s dead\n", dev_name(&cxled->cxld.dev));
return -ENODEV;
}
+ if (cxlds->part[cxled->part].mode != cxlr->mode) {
+ dev_dbg(&cxlr->dev, "%s region mode: %d mismatch\n",
+ dev_name(&cxled->cxld.dev), cxlr->mode);
+ return -EINVAL;
+ }
+
/* all full of members, or interleave config not established? */
if (p->state > CXL_CONFIG_INTERLEAVE_ACTIVE) {
dev_dbg(&cxlr->dev, "region already active\n");
@@ -1951,13 +1974,13 @@ static int cxl_region_attach(struct cxl_region *cxlr,
return -ENXIO;
}
- if (resource_size(cxled->dpa_res) * p->interleave_ways !=
+ if (resource_size(cxled->dpa_res) * p->interleave_ways + p->cache_size !=
resource_size(p->res)) {
dev_dbg(&cxlr->dev,
- "%s:%s: decoder-size-%#llx * ways-%d != region-size-%#llx\n",
+ "%s:%s-size-%#llx * ways-%d + cache-%#llx != region-size-%#llx\n",
dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
(u64)resource_size(cxled->dpa_res), p->interleave_ways,
- (u64)resource_size(p->res));
+ (u64)p->cache_size, (u64)resource_size(p->res));
return -EINVAL;
}
@@ -2115,7 +2138,7 @@ out:
void cxl_decoder_kill_region(struct cxl_endpoint_decoder *cxled)
{
down_write(&cxl_region_rwsem);
- cxled->mode = CXL_DECODER_DEAD;
+ cxled->part = -1;
cxl_region_detach(cxled);
up_write(&cxl_region_rwsem);
}
@@ -2471,7 +2494,7 @@ static int cxl_region_calculate_adistance(struct notifier_block *nb,
*/
static struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd,
int id,
- enum cxl_decoder_mode mode,
+ enum cxl_partition_mode mode,
enum cxl_decoder_type type)
{
struct cxl_port *port = to_cxl_port(cxlrd->cxlsd.cxld.dev.parent);
@@ -2525,13 +2548,13 @@ static ssize_t create_ram_region_show(struct device *dev,
}
static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
- enum cxl_decoder_mode mode, int id)
+ enum cxl_partition_mode mode, int id)
{
int rc;
switch (mode) {
- case CXL_DECODER_RAM:
- case CXL_DECODER_PMEM:
+ case CXL_PARTMODE_RAM:
+ case CXL_PARTMODE_PMEM:
break;
default:
dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode);
@@ -2551,7 +2574,7 @@ static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
}
static ssize_t create_region_store(struct device *dev, const char *buf,
- size_t len, enum cxl_decoder_mode mode)
+ size_t len, enum cxl_partition_mode mode)
{
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
struct cxl_region *cxlr;
@@ -2572,7 +2595,7 @@ static ssize_t create_pmem_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
- return create_region_store(dev, buf, len, CXL_DECODER_PMEM);
+ return create_region_store(dev, buf, len, CXL_PARTMODE_PMEM);
}
DEVICE_ATTR_RW(create_pmem_region);
@@ -2580,7 +2603,7 @@ static ssize_t create_ram_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
- return create_region_store(dev, buf, len, CXL_DECODER_RAM);
+ return create_region_store(dev, buf, len, CXL_PARTMODE_RAM);
}
DEVICE_ATTR_RW(create_ram_region);
@@ -2678,7 +2701,7 @@ EXPORT_SYMBOL_NS_GPL(to_cxl_pmem_region, "CXL");
struct cxl_poison_context {
struct cxl_port *port;
- enum cxl_decoder_mode mode;
+ int part;
u64 offset;
};
@@ -2686,47 +2709,45 @@ static int cxl_get_poison_unmapped(struct cxl_memdev *cxlmd,
struct cxl_poison_context *ctx)
{
struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ const struct resource *res;
+ struct resource *p, *last;
u64 offset, length;
int rc = 0;
+ if (ctx->part < 0)
+ return 0;
+
/*
- * Collect poison for the remaining unmapped resources
- * after poison is collected by committed endpoints.
- *
- * Knowing that PMEM must always follow RAM, get poison
- * for unmapped resources based on the last decoder's mode:
- * ram: scan remains of ram range, then any pmem range
- * pmem: scan remains of pmem range
+ * Collect poison for the remaining unmapped resources after
+ * poison is collected by committed endpoints decoders.
*/
-
- if (ctx->mode == CXL_DECODER_RAM) {
- offset = ctx->offset;
- length = resource_size(&cxlds->ram_res) - offset;
+ for (int i = ctx->part; i < cxlds->nr_partitions; i++) {
+ res = &cxlds->part[i].res;
+ for (p = res->child, last = NULL; p; p = p->sibling)
+ last = p;
+ if (last)
+ offset = last->end + 1;
+ else
+ offset = res->start;
+ length = res->end - offset + 1;
+ if (!length)
+ break;
rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
- if (rc == -EFAULT)
- rc = 0;
+ if (rc == -EFAULT && cxlds->part[i].mode == CXL_PARTMODE_RAM)
+ continue;
if (rc)
- return rc;
- }
- if (ctx->mode == CXL_DECODER_PMEM) {
- offset = ctx->offset;
- length = resource_size(&cxlds->dpa_res) - offset;
- if (!length)
- return 0;
- } else if (resource_size(&cxlds->pmem_res)) {
- offset = cxlds->pmem_res.start;
- length = resource_size(&cxlds->pmem_res);
- } else {
- return 0;
+ break;
}
- return cxl_mem_get_poison(cxlmd, offset, length, NULL);
+ return rc;
}
static int poison_by_decoder(struct device *dev, void *arg)
{
struct cxl_poison_context *ctx = arg;
struct cxl_endpoint_decoder *cxled;
+ enum cxl_partition_mode mode;
+ struct cxl_dev_state *cxlds;
struct cxl_memdev *cxlmd;
u64 offset, length;
int rc = 0;
@@ -2735,27 +2756,18 @@ static int poison_by_decoder(struct device *dev, void *arg)
return rc;
cxled = to_cxl_endpoint_decoder(dev);
- if (!cxled->dpa_res || !resource_size(cxled->dpa_res))
- return rc;
-
- /*
- * Regions are only created with single mode decoders: pmem or ram.
- * Linux does not support mixed mode decoders. This means that
- * reading poison per endpoint decoder adheres to the requirement
- * that poison reads of pmem and ram must be separated.
- * CXL 3.0 Spec 8.2.9.8.4.1
- */
- if (cxled->mode == CXL_DECODER_MIXED) {
- dev_dbg(dev, "poison list read unsupported in mixed mode\n");
+ if (!cxled->dpa_res)
return rc;
- }
cxlmd = cxled_to_memdev(cxled);
+ cxlds = cxlmd->cxlds;
+ mode = cxlds->part[cxled->part].mode;
+
if (cxled->skip) {
offset = cxled->dpa_res->start - cxled->skip;
length = cxled->skip;
rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
- if (rc == -EFAULT && cxled->mode == CXL_DECODER_RAM)
+ if (rc == -EFAULT && mode == CXL_PARTMODE_RAM)
rc = 0;
if (rc)
return rc;
@@ -2764,7 +2776,7 @@ static int poison_by_decoder(struct device *dev, void *arg)
offset = cxled->dpa_res->start;
length = cxled->dpa_res->end - offset + 1;
rc = cxl_mem_get_poison(cxlmd, offset, length, cxled->cxld.region);
- if (rc == -EFAULT && cxled->mode == CXL_DECODER_RAM)
+ if (rc == -EFAULT && mode == CXL_PARTMODE_RAM)
rc = 0;
if (rc)
return rc;
@@ -2772,7 +2784,7 @@ static int poison_by_decoder(struct device *dev, void *arg)
/* Iterate until commit_end is reached */
if (cxled->cxld.id == ctx->port->commit_end) {
ctx->offset = cxled->dpa_res->end + 1;
- ctx->mode = cxled->mode;
+ ctx->part = cxled->part;
return 1;
}
@@ -2785,7 +2797,8 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port)
int rc = 0;
ctx = (struct cxl_poison_context) {
- .port = port
+ .port = port,
+ .part = -1,
};
rc = device_for_each_child(&port->dev, &ctx, poison_by_decoder);
@@ -2921,7 +2934,7 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
hpa_offset |= dpa_offset & GENMASK_ULL(eig + 7, 0);
/* Apply the hpa_offset to the region base address */
- hpa = hpa_offset + p->res->start;
+ hpa = hpa_offset + p->res->start + p->cache_size;
/* Root decoder translation overrides typical modulo decode */
if (cxlrd->hpa_to_spa)
@@ -3038,17 +3051,13 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr)
struct cxl_dax_region *cxlr_dax;
struct device *dev;
- down_read(&cxl_region_rwsem);
- if (p->state != CXL_CONFIG_COMMIT) {
- cxlr_dax = ERR_PTR(-ENXIO);
- goto out;
- }
+ guard(rwsem_read)(&cxl_region_rwsem);
+ if (p->state != CXL_CONFIG_COMMIT)
+ return ERR_PTR(-ENXIO);
cxlr_dax = kzalloc(sizeof(*cxlr_dax), GFP_KERNEL);
- if (!cxlr_dax) {
- cxlr_dax = ERR_PTR(-ENOMEM);
- goto out;
- }
+ if (!cxlr_dax)
+ return ERR_PTR(-ENOMEM);
cxlr_dax->hpa_range.start = p->res->start;
cxlr_dax->hpa_range.end = p->res->end;
@@ -3061,8 +3070,6 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr)
dev->parent = &cxlr->dev;
dev->bus = &cxl_bus_type;
dev->type = &cxl_dax_region_type;
-out:
- up_read(&cxl_region_rwsem);
return cxlr_dax;
}
@@ -3208,7 +3215,6 @@ static int match_region_by_range(struct device *dev, const void *data)
struct cxl_region_params *p;
struct cxl_region *cxlr;
const struct range *r = data;
- int rc = 0;
if (!is_cxl_region(dev))
return 0;
@@ -3216,60 +3222,96 @@ static int match_region_by_range(struct device *dev, const void *data)
cxlr = to_cxl_region(dev);
p = &cxlr->params;
- down_read(&cxl_region_rwsem);
+ guard(rwsem_read)(&cxl_region_rwsem);
if (p->res && p->res->start == r->start && p->res->end == r->end)
- rc = 1;
- up_read(&cxl_region_rwsem);
+ return 1;
- return rc;
+ return 0;
}
-/* Establish an empty region covering the given HPA range */
-static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
- struct cxl_endpoint_decoder *cxled)
+static int cxl_extended_linear_cache_resize(struct cxl_region *cxlr,
+ struct resource *res)
+{
+ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
+ struct cxl_region_params *p = &cxlr->params;
+ int nid = phys_to_target_node(res->start);
+ resource_size_t size = resource_size(res);
+ resource_size_t cache_size, start;
+ int rc;
+
+ rc = cxl_acpi_get_extended_linear_cache_size(res, nid, &cache_size);
+ if (rc)
+ return rc;
+
+ if (!cache_size)
+ return 0;
+
+ if (size != cache_size) {
+ dev_warn(&cxlr->dev,
+ "Extended Linear Cache size %pa != CXL size %pa. No Support!",
+ &cache_size, &size);
+ return -ENXIO;
+ }
+
+ /*
+ * Move the start of the range to where the cache range starts. The
+ * implementation assumes that the cache range is in front of the
+ * CXL range. This is not dictated by the HMAT spec but is how the
+ * current known implementation is configured.
+ *
+ * The cache range is expected to be within the CFMWS. The adjusted
+ * res->start should not be less than cxlrd->res->start.
+ */
+ start = res->start - cache_size;
+ if (start < cxlrd->res->start)
+ return -ENXIO;
+
+ res->start = start;
+ p->cache_size = cache_size;
+
+ return 0;
+}
+
+static int __construct_region(struct cxl_region *cxlr,
+ struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled)
{
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
- struct cxl_port *port = cxlrd_to_port(cxlrd);
struct range *hpa = &cxled->cxld.hpa_range;
struct cxl_region_params *p;
- struct cxl_region *cxlr;
struct resource *res;
int rc;
- do {
- cxlr = __create_region(cxlrd, cxled->mode,
- atomic_read(&cxlrd->region_id));
- } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
-
- if (IS_ERR(cxlr)) {
- dev_err(cxlmd->dev.parent,
- "%s:%s: %s failed assign region: %ld\n",
- dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
- __func__, PTR_ERR(cxlr));
- return cxlr;
- }
-
- down_write(&cxl_region_rwsem);
+ guard(rwsem_write)(&cxl_region_rwsem);
p = &cxlr->params;
if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) {
dev_err(cxlmd->dev.parent,
"%s:%s: %s autodiscovery interrupted\n",
dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
__func__);
- rc = -EBUSY;
- goto err;
+ return -EBUSY;
}
set_bit(CXL_REGION_F_AUTO, &cxlr->flags);
res = kmalloc(sizeof(*res), GFP_KERNEL);
- if (!res) {
- rc = -ENOMEM;
- goto err;
- }
+ if (!res)
+ return -ENOMEM;
*res = DEFINE_RES_MEM_NAMED(hpa->start, range_len(hpa),
dev_name(&cxlr->dev));
+
+ rc = cxl_extended_linear_cache_resize(cxlr, res);
+ if (rc && rc != -EOPNOTSUPP) {
+ /*
+ * Failing to support extended linear cache region resize does not
+ * prevent the region from functioning. Only causes cxl list showing
+ * incorrect region size.
+ */
+ dev_warn(cxlmd->dev.parent,
+ "Extended linear cache calculation failed rc:%d\n", rc);
+ }
+
rc = insert_resource(cxlrd->res, res);
if (rc) {
/*
@@ -3289,7 +3331,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
rc = sysfs_update_group(&cxlr->dev.kobj, get_cxl_region_target_group());
if (rc)
- goto err;
+ return rc;
dev_dbg(cxlmd->dev.parent, "%s:%s: %s %s res: %pr iw: %d ig: %d\n",
dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__,
@@ -3298,14 +3340,40 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
/* ...to match put_device() in cxl_add_to_region() */
get_device(&cxlr->dev);
- up_write(&cxl_region_rwsem);
- return cxlr;
+ return 0;
+}
-err:
- up_write(&cxl_region_rwsem);
- devm_release_action(port->uport_dev, unregister_region, cxlr);
- return ERR_PTR(rc);
+/* Establish an empty region covering the given HPA range */
+static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd,
+ struct cxl_endpoint_decoder *cxled)
+{
+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+ struct cxl_port *port = cxlrd_to_port(cxlrd);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ int rc, part = READ_ONCE(cxled->part);
+ struct cxl_region *cxlr;
+
+ do {
+ cxlr = __create_region(cxlrd, cxlds->part[part].mode,
+ atomic_read(&cxlrd->region_id));
+ } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY);
+
+ if (IS_ERR(cxlr)) {
+ dev_err(cxlmd->dev.parent,
+ "%s:%s: %s failed assign region: %ld\n",
+ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+ __func__, PTR_ERR(cxlr));
+ return cxlr;
+ }
+
+ rc = __construct_region(cxlr, cxlrd, cxled);
+ if (rc) {
+ devm_release_action(port->uport_dev, unregister_region, cxlr);
+ return ERR_PTR(rc);
+ }
+
+ return cxlr;
}
int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
@@ -3375,6 +3443,34 @@ out:
}
EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, "CXL");
+u64 cxl_port_get_spa_cache_alias(struct cxl_port *endpoint, u64 spa)
+{
+ struct cxl_region_ref *iter;
+ unsigned long index;
+
+ if (!endpoint)
+ return ~0ULL;
+
+ guard(rwsem_write)(&cxl_region_rwsem);
+
+ xa_for_each(&endpoint->regions, index, iter) {
+ struct cxl_region_params *p = &iter->region->params;
+
+ if (p->res->start <= spa && spa <= p->res->end) {
+ if (!p->cache_size)
+ return ~0ULL;
+
+ if (spa >= p->res->start + p->cache_size)
+ return spa - p->cache_size;
+
+ return spa + p->cache_size;
+ }
+ }
+
+ return ~0ULL;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_get_spa_cache_alias, "CXL");
+
static int is_system_ram(struct resource *res, void *arg)
{
struct cxl_region *cxlr = arg;
@@ -3440,9 +3536,9 @@ out:
return rc;
switch (cxlr->mode) {
- case CXL_DECODER_PMEM:
+ case CXL_PARTMODE_PMEM:
return devm_cxl_add_pmem_region(cxlr);
- case CXL_DECODER_RAM:
+ case CXL_PARTMODE_RAM:
/*
* The region can not be manged by CXL if any portion of
* it is already online as 'System RAM'
diff --git a/drivers/cxl/core/trace.h b/drivers/cxl/core/trace.h
index cea706b683b5..25ebfbc1616c 100644
--- a/drivers/cxl/core/trace.h
+++ b/drivers/cxl/core/trace.h
@@ -48,6 +48,34 @@
{ CXL_RAS_UC_IDE_RX_ERR, "IDE Rx Error" } \
)
+TRACE_EVENT(cxl_port_aer_uncorrectable_error,
+ TP_PROTO(struct device *dev, u32 status, u32 fe, u32 *hl),
+ TP_ARGS(dev, status, fe, hl),
+ TP_STRUCT__entry(
+ __string(device, dev_name(dev))
+ __string(host, dev_name(dev->parent))
+ __field(u32, status)
+ __field(u32, first_error)
+ __array(u32, header_log, CXL_HEADERLOG_SIZE_U32)
+ ),
+ TP_fast_assign(
+ __assign_str(device);
+ __assign_str(host);
+ __entry->status = status;
+ __entry->first_error = fe;
+ /*
+ * Embed the 512B headerlog data for user app retrieval and
+ * parsing, but no need to print this in the trace buffer.
+ */
+ memcpy(__entry->header_log, hl, CXL_HEADERLOG_SIZE);
+ ),
+ TP_printk("device=%s host=%s status: '%s' first_error: '%s'",
+ __get_str(device), __get_str(host),
+ show_uc_errs(__entry->status),
+ show_uc_errs(__entry->first_error)
+ )
+);
+
TRACE_EVENT(cxl_aer_uncorrectable_error,
TP_PROTO(const struct cxl_memdev *cxlmd, u32 status, u32 fe, u32 *hl),
TP_ARGS(cxlmd, status, fe, hl),
@@ -96,6 +124,25 @@ TRACE_EVENT(cxl_aer_uncorrectable_error,
{ CXL_RAS_CE_PHYS_LAYER_ERR, "Received Error From Physical Layer" } \
)
+TRACE_EVENT(cxl_port_aer_correctable_error,
+ TP_PROTO(struct device *dev, u32 status),
+ TP_ARGS(dev, status),
+ TP_STRUCT__entry(
+ __string(device, dev_name(dev))
+ __string(host, dev_name(dev->parent))
+ __field(u32, status)
+ ),
+ TP_fast_assign(
+ __assign_str(device);
+ __assign_str(host);
+ __entry->status = status;
+ ),
+ TP_printk("device=%s host=%s status='%s'",
+ __get_str(device), __get_str(host),
+ show_ce_errs(__entry->status)
+ )
+);
+
TRACE_EVENT(cxl_aer_correctable_error,
TP_PROTO(const struct cxl_memdev *cxlmd, u32 status),
TP_ARGS(cxlmd, status),
@@ -392,9 +439,10 @@ TRACE_EVENT(cxl_generic_event,
TRACE_EVENT(cxl_general_media,
TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
- struct cxl_region *cxlr, u64 hpa, struct cxl_event_gen_media *rec),
+ struct cxl_region *cxlr, u64 hpa, u64 hpa_alias0,
+ struct cxl_event_gen_media *rec),
- TP_ARGS(cxlmd, log, cxlr, hpa, rec),
+ TP_ARGS(cxlmd, log, cxlr, hpa, hpa_alias0, rec),
TP_STRUCT__entry(
CXL_EVT_TP_entry
@@ -408,6 +456,7 @@ TRACE_EVENT(cxl_general_media,
__array(u8, comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE)
/* Following are out of order to pack trace record */
__field(u64, hpa)
+ __field(u64, hpa_alias0)
__field_struct(uuid_t, region_uuid)
__field(u16, validity_flags)
__field(u8, rank)
@@ -438,6 +487,7 @@ TRACE_EVENT(cxl_general_media,
CXL_EVENT_GEN_MED_COMP_ID_SIZE);
__entry->validity_flags = get_unaligned_le16(&rec->media_hdr.validity_flags);
__entry->hpa = hpa;
+ __entry->hpa_alias0 = hpa_alias0;
if (cxlr) {
__assign_str(region_name);
uuid_copy(&__entry->region_uuid, &cxlr->params.uuid);
@@ -455,7 +505,7 @@ TRACE_EVENT(cxl_general_media,
"device=%x validity_flags='%s' " \
"comp_id=%s comp_id_pldm_valid_flags='%s' " \
"pldm_entity_id=%s pldm_resource_id=%s " \
- "hpa=%llx region=%s region_uuid=%pUb " \
+ "hpa=%llx hpa_alias0=%llx region=%s region_uuid=%pUb " \
"cme_threshold_ev_flags='%s' cme_count=%u",
__entry->dpa, show_dpa_flags(__entry->dpa_flags),
show_event_desc_flags(__entry->descriptor),
@@ -470,7 +520,7 @@ TRACE_EVENT(cxl_general_media,
CXL_GMER_VALID_COMPONENT_ID_FORMAT, __entry->comp_id),
show_pldm_resource_id(__entry->validity_flags, CXL_GMER_VALID_COMPONENT,
CXL_GMER_VALID_COMPONENT_ID_FORMAT, __entry->comp_id),
- __entry->hpa, __get_str(region_name), &__entry->region_uuid,
+ __entry->hpa, __entry->hpa_alias0, __get_str(region_name), &__entry->region_uuid,
show_cme_threshold_ev_flags(__entry->cme_threshold_ev_flags), __entry->cme_count
)
);
@@ -529,9 +579,10 @@ TRACE_EVENT(cxl_general_media,
TRACE_EVENT(cxl_dram,
TP_PROTO(const struct cxl_memdev *cxlmd, enum cxl_event_log_type log,
- struct cxl_region *cxlr, u64 hpa, struct cxl_event_dram *rec),
+ struct cxl_region *cxlr, u64 hpa, u64 hpa_alias0,
+ struct cxl_event_dram *rec),
- TP_ARGS(cxlmd, log, cxlr, hpa, rec),
+ TP_ARGS(cxlmd, log, cxlr, hpa, hpa_alias0, rec),
TP_STRUCT__entry(
CXL_EVT_TP_entry
@@ -547,6 +598,7 @@ TRACE_EVENT(cxl_dram,
__field(u32, row)
__array(u8, cor_mask, CXL_EVENT_DER_CORRECTION_MASK_SIZE)
__field(u64, hpa)
+ __field(u64, hpa_alias0)
__field_struct(uuid_t, region_uuid)
__field(u8, rank) /* Out of order to pack trace record */
__field(u8, bank_group) /* Out of order to pack trace record */
@@ -584,6 +636,7 @@ TRACE_EVENT(cxl_dram,
memcpy(__entry->cor_mask, &rec->correction_mask,
CXL_EVENT_DER_CORRECTION_MASK_SIZE);
__entry->hpa = hpa;
+ __entry->hpa_alias0 = hpa_alias0;
if (cxlr) {
__assign_str(region_name);
uuid_copy(&__entry->region_uuid, &cxlr->params.uuid);
@@ -604,7 +657,7 @@ TRACE_EVENT(cxl_dram,
"validity_flags='%s' " \
"comp_id=%s comp_id_pldm_valid_flags='%s' " \
"pldm_entity_id=%s pldm_resource_id=%s " \
- "hpa=%llx region=%s region_uuid=%pUb " \
+ "hpa=%llx hpa_alias0=%llx region=%s region_uuid=%pUb " \
"sub_channel=%u cme_threshold_ev_flags='%s' cvme_count=%u",
__entry->dpa, show_dpa_flags(__entry->dpa_flags),
show_event_desc_flags(__entry->descriptor),
@@ -622,7 +675,7 @@ TRACE_EVENT(cxl_dram,
CXL_DER_VALID_COMPONENT_ID_FORMAT, __entry->comp_id),
show_pldm_resource_id(__entry->validity_flags, CXL_DER_VALID_COMPONENT,
CXL_DER_VALID_COMPONENT_ID_FORMAT, __entry->comp_id),
- __entry->hpa, __get_str(region_name), &__entry->region_uuid,
+ __entry->hpa, __entry->hpa_alias0, __get_str(region_name), &__entry->region_uuid,
__entry->sub_channel, show_cme_threshold_ev_flags(__entry->cme_threshold_ev_flags),
__entry->cvme_count
)
@@ -870,6 +923,7 @@ TRACE_EVENT(cxl_poison,
__string(region, cxlr ? dev_name(&cxlr->dev) : "")
__field(u64, overflow_ts)
__field(u64, hpa)
+ __field(u64, hpa_alias0)
__field(u64, dpa)
__field(u32, dpa_length)
__array(char, uuid, 16)
@@ -892,16 +946,22 @@ TRACE_EVENT(cxl_poison,
memcpy(__entry->uuid, &cxlr->params.uuid, 16);
__entry->hpa = cxl_dpa_to_hpa(cxlr, cxlmd,
__entry->dpa);
+ if (__entry->hpa != ULLONG_MAX && cxlr->params.cache_size)
+ __entry->hpa_alias0 = __entry->hpa +
+ cxlr->params.cache_size;
+ else
+ __entry->hpa_alias0 = ULLONG_MAX;
} else {
__assign_str(region);
memset(__entry->uuid, 0, 16);
__entry->hpa = ULLONG_MAX;
+ __entry->hpa_alias0 = ULLONG_MAX;
}
),
TP_printk("memdev=%s host=%s serial=%lld trace_type=%s region=%s " \
- "region_uuid=%pU hpa=0x%llx dpa=0x%llx dpa_length=0x%x " \
- "source=%s flags=%s overflow_time=%llu",
+ "region_uuid=%pU hpa=0x%llx hpa_alias0=0x%llx dpa=0x%llx " \
+ "dpa_length=0x%x source=%s flags=%s overflow_time=%llu",
__get_str(memdev),
__get_str(host),
__entry->serial,
@@ -909,6 +969,7 @@ TRACE_EVENT(cxl_poison,
__get_str(region),
__entry->uuid,
__entry->hpa,
+ __entry->hpa_alias0,
__entry->dpa,
__entry->dpa_length,
show_poison_source(__entry->source),
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index bbbaa0d0a670..be8a7dc77719 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -373,32 +373,6 @@ struct cxl_decoder {
};
/*
- * CXL_DECODER_DEAD prevents endpoints from being reattached to regions
- * while cxld_unregister() is running
- */
-enum cxl_decoder_mode {
- CXL_DECODER_NONE,
- CXL_DECODER_RAM,
- CXL_DECODER_PMEM,
- CXL_DECODER_MIXED,
- CXL_DECODER_DEAD,
-};
-
-static inline const char *cxl_decoder_mode_name(enum cxl_decoder_mode mode)
-{
- static const char * const names[] = {
- [CXL_DECODER_NONE] = "none",
- [CXL_DECODER_RAM] = "ram",
- [CXL_DECODER_PMEM] = "pmem",
- [CXL_DECODER_MIXED] = "mixed",
- };
-
- if (mode >= CXL_DECODER_NONE && mode <= CXL_DECODER_MIXED)
- return names[mode];
- return "mixed";
-}
-
-/*
* Track whether this decoder is reserved for region autodiscovery, or
* free for userspace provisioning.
*/
@@ -412,16 +386,16 @@ enum cxl_decoder_state {
* @cxld: base cxl_decoder_object
* @dpa_res: actively claimed DPA span of this decoder
* @skip: offset into @dpa_res where @cxld.hpa_range maps
- * @mode: which memory type / access-mode-partition this decoder targets
* @state: autodiscovery state
+ * @part: partition index this decoder maps
* @pos: interleave position in @cxld.region
*/
struct cxl_endpoint_decoder {
struct cxl_decoder cxld;
struct resource *dpa_res;
resource_size_t skip;
- enum cxl_decoder_mode mode;
enum cxl_decoder_state state;
+ int part;
int pos;
};
@@ -493,6 +467,7 @@ enum cxl_config_state {
* @res: allocated iomem capacity for this region
* @targets: active ordered targets in current decoder configuration
* @nr_targets: number of targets
+ * @cache_size: extended linear cache size if exists, otherwise zero.
*
* State transitions are protected by the cxl_region_rwsem
*/
@@ -504,6 +479,12 @@ struct cxl_region_params {
struct resource *res;
struct cxl_endpoint_decoder *targets[CXL_DECODER_MAX_INTERLEAVE];
int nr_targets;
+ resource_size_t cache_size;
+};
+
+enum cxl_partition_mode {
+ CXL_PARTMODE_RAM,
+ CXL_PARTMODE_PMEM,
};
/*
@@ -525,7 +506,7 @@ struct cxl_region_params {
* struct cxl_region - CXL region
* @dev: This region's device
* @id: This region's id. Id is globally unique across all regions
- * @mode: Endpoint decoder allocation / access mode
+ * @mode: Operational mode of the mapped capacity
* @type: Endpoint decoder target type
* @cxl_nvb: nvdimm bridge for coordinating @cxlr_pmem setup / shutdown
* @cxlr_pmem: (for pmem regions) cached copy of the nvdimm bridge
@@ -538,7 +519,7 @@ struct cxl_region_params {
struct cxl_region {
struct device dev;
int id;
- enum cxl_decoder_mode mode;
+ enum cxl_partition_mode mode;
enum cxl_decoder_type type;
struct cxl_nvdimm_bridge *cxl_nvb;
struct cxl_pmem_region *cxlr_pmem;
@@ -563,6 +544,7 @@ struct cxl_nvdimm {
struct device dev;
struct cxl_memdev *cxlmd;
u8 dev_id[CXL_DEV_ID_LEN]; /* for nvdimm, string of 'serial' */
+ u64 dirty_shutdowns;
};
struct cxl_pmem_region_mapping {
@@ -610,6 +592,7 @@ struct cxl_dax_region {
* @cdat: Cached CDAT data
* @cdat_available: Should a CDAT attribute be available in sysfs
* @pci_latency: Upstream latency in picoseconds
+ * @gpf_dvsec: Cached GPF port DVSEC
*/
struct cxl_port {
struct device dev;
@@ -633,6 +616,7 @@ struct cxl_port {
} cdat;
bool cdat_available;
long pci_latency;
+ int gpf_dvsec;
};
/**
@@ -875,6 +859,7 @@ struct cxl_pmem_region *to_cxl_pmem_region(struct device *dev);
int cxl_add_to_region(struct cxl_port *root,
struct cxl_endpoint_decoder *cxled);
struct cxl_dax_region *to_cxl_dax_region(struct device *dev);
+u64 cxl_port_get_spa_cache_alias(struct cxl_port *endpoint, u64 spa);
#else
static inline bool is_cxl_pmem_region(struct device *dev)
{
@@ -893,6 +878,11 @@ static inline struct cxl_dax_region *to_cxl_dax_region(struct device *dev)
{
return NULL;
}
+static inline u64 cxl_port_get_spa_cache_alias(struct cxl_port *endpoint,
+ u64 spa)
+{
+ return 0;
+}
#endif
void cxl_endpoint_parse_cdat(struct cxl_port *port);
@@ -920,4 +910,6 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
#define __mock static
#endif
+u16 cxl_gpf_get_dvsec(struct device *dev, bool is_port);
+
#endif /* __CXL_H__ */
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index dd2b7060d501..3ec6b906371b 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -97,6 +97,19 @@ int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
resource_size_t base, resource_size_t len,
resource_size_t skipped);
+#define CXL_NR_PARTITIONS_MAX 2
+
+struct cxl_dpa_info {
+ u64 size;
+ struct cxl_dpa_part_info {
+ struct range range;
+ enum cxl_partition_mode mode;
+ } part[CXL_NR_PARTITIONS_MAX];
+ int nr_partitions;
+};
+
+int cxl_dpa_setup(struct cxl_dev_state *cxlds, const struct cxl_dpa_info *info);
+
static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,
struct cxl_memdev *cxlmd)
{
@@ -373,6 +386,18 @@ struct cxl_dpa_perf {
};
/**
+ * struct cxl_dpa_partition - DPA partition descriptor
+ * @res: shortcut to the partition in the DPA resource tree (cxlds->dpa_res)
+ * @perf: performance attributes of the partition from CDAT
+ * @mode: operation mode for the DPA capacity, e.g. ram, pmem, dynamic...
+ */
+struct cxl_dpa_partition {
+ struct resource res;
+ struct cxl_dpa_perf perf;
+ enum cxl_partition_mode mode;
+};
+
+/**
* struct cxl_dev_state - The driver device state
*
* cxl_dev_state represents the CXL driver/device state. It provides an
@@ -387,8 +412,8 @@ struct cxl_dpa_perf {
* @rcd: operating in RCD mode (CXL 3.0 9.11.8 CXL Devices Attached to an RCH)
* @media_ready: Indicate whether the device media is usable
* @dpa_res: Overall DPA resource tree for the device
- * @pmem_res: Active Persistent memory capacity configuration
- * @ram_res: Active Volatile memory capacity configuration
+ * @part: DPA partition array
+ * @nr_partitions: Number of DPA partitions
* @serial: PCIe Device Serial Number
* @type: Generic Memory Class device or Vendor Specific Memory device
* @cxl_mbox: CXL mailbox context
@@ -403,8 +428,8 @@ struct cxl_dev_state {
bool rcd;
bool media_ready;
struct resource dpa_res;
- struct resource pmem_res;
- struct resource ram_res;
+ struct cxl_dpa_partition part[CXL_NR_PARTITIONS_MAX];
+ unsigned int nr_partitions;
u64 serial;
enum cxl_devtype type;
struct cxl_mailbox cxl_mbox;
@@ -413,6 +438,18 @@ struct cxl_dev_state {
#endif
};
+static inline resource_size_t cxl_pmem_size(struct cxl_dev_state *cxlds)
+{
+ /*
+ * Static PMEM may be at partition index 0 when there is no static RAM
+ * capacity.
+ */
+ for (int i = 0; i < cxlds->nr_partitions; i++)
+ if (cxlds->part[i].mode == CXL_PARTMODE_PMEM)
+ return resource_size(&cxlds->part[i].res);
+ return 0;
+}
+
static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
{
return dev_get_drvdata(cxl_mbox->host);
@@ -435,14 +472,11 @@ static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
* @partition_align_bytes: alignment size for partition-able capacity
* @active_volatile_bytes: sum of hard + soft volatile
* @active_persistent_bytes: sum of hard + soft persistent
- * @next_volatile_bytes: volatile capacity change pending device reset
- * @next_persistent_bytes: persistent capacity change pending device reset
- * @ram_perf: performance data entry matched to RAM partition
- * @pmem_perf: performance data entry matched to PMEM partition
* @event: event log driver state
* @poison: poison driver state info
* @security: security driver state info
* @fw: firmware upload / activation state
+ * @mce_notifier: MCE notifier
*
* See CXL 3.0 8.2.9.8.2 Capacity Configuration and Label Storage for
* details on capacity parameters.
@@ -457,16 +491,12 @@ struct cxl_memdev_state {
u64 partition_align_bytes;
u64 active_volatile_bytes;
u64 active_persistent_bytes;
- u64 next_volatile_bytes;
- u64 next_persistent_bytes;
-
- struct cxl_dpa_perf ram_perf;
- struct cxl_dpa_perf pmem_perf;
struct cxl_event_state event;
struct cxl_poison_state poison;
struct cxl_security_state security;
struct cxl_fw_state fw;
+ struct notifier_block mce_notifier;
};
static inline struct cxl_memdev_state *
@@ -660,6 +690,23 @@ struct cxl_mbox_set_partition_info {
#define CXL_SET_PARTITION_IMMEDIATE_FLAG BIT(0)
+/* Get Health Info Output Payload CXL 3.2 Spec 8.2.10.9.3.1 Table 8-148 */
+struct cxl_mbox_get_health_info_out {
+ u8 health_status;
+ u8 media_status;
+ u8 additional_status;
+ u8 life_used;
+ __le16 device_temperature;
+ __le32 dirty_shutdown_cnt;
+ __le32 corrected_volatile_error_cnt;
+ __le32 corrected_persistent_error_cnt;
+} __packed;
+
+/* Set Shutdown State Input Payload CXL 3.2 Spec 8.2.10.9.3.5 Table 8-152 */
+struct cxl_mbox_set_shutdown_state_in {
+ u8 state;
+} __packed;
+
/* Set Timestamp CXL 3.0 Spec 8.2.9.4.2 */
struct cxl_mbox_set_timestamp_in {
__le64 timestamp;
@@ -785,7 +832,7 @@ int cxl_internal_send_cmd(struct cxl_mailbox *cxl_mbox,
int cxl_dev_state_identify(struct cxl_memdev_state *mds);
int cxl_await_media_ready(struct cxl_dev_state *cxlds);
int cxl_enumerate_cmds(struct cxl_memdev_state *mds);
-int cxl_mem_create_range_info(struct cxl_memdev_state *mds);
+int cxl_mem_dpa_fetch(struct cxl_memdev_state *mds, struct cxl_dpa_info *info);
struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev);
void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
unsigned long *cmds);
@@ -796,6 +843,8 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
enum cxl_event_log_type type,
enum cxl_event_type event_type,
const uuid_t *uuid, union cxl_event *evt);
+int cxl_get_dirty_count(struct cxl_memdev_state *mds, u32 *count);
+int cxl_arm_dirty_shutdown(struct cxl_memdev_state *mds);
int cxl_set_timestamp(struct cxl_memdev_state *mds);
int cxl_poison_state_init(struct cxl_memdev_state *mds);
int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index 4da07727ab9c..54e219b0049e 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -40,6 +40,12 @@
/* CXL 2.0 8.1.6: GPF DVSEC for CXL Port */
#define CXL_DVSEC_PORT_GPF 4
+#define CXL_DVSEC_PORT_GPF_PHASE_1_CONTROL_OFFSET 0x0C
+#define CXL_DVSEC_PORT_GPF_PHASE_1_TMO_BASE_MASK GENMASK(3, 0)
+#define CXL_DVSEC_PORT_GPF_PHASE_1_TMO_SCALE_MASK GENMASK(11, 8)
+#define CXL_DVSEC_PORT_GPF_PHASE_2_CONTROL_OFFSET 0xE
+#define CXL_DVSEC_PORT_GPF_PHASE_2_TMO_BASE_MASK GENMASK(3, 0)
+#define CXL_DVSEC_PORT_GPF_PHASE_2_TMO_SCALE_MASK GENMASK(11, 8)
/* CXL 2.0 8.1.7: GPF DVSEC for CXL Device */
#define CXL_DVSEC_DEVICE_GPF 5
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 2f03a4d5606e..9675243bd05b 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -152,7 +152,7 @@ static int cxl_mem_probe(struct device *dev)
return -ENXIO;
}
- if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) {
+ if (cxl_pmem_size(cxlds) && IS_ENABLED(CONFIG_CXL_PMEM)) {
rc = devm_cxl_add_nvdimm(parent_port, cxlmd);
if (rc) {
if (rc == -ENODEV)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 993fa60fe453..7b14a154463c 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -903,6 +903,7 @@ __ATTRIBUTE_GROUPS(cxl_rcd);
static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
+ struct cxl_dpa_info range_info = { 0 };
struct cxl_memdev_state *mds;
struct cxl_dev_state *cxlds;
struct cxl_register_map map;
@@ -993,7 +994,11 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
- rc = cxl_mem_create_range_info(mds);
+ rc = cxl_mem_dpa_fetch(mds, &range_info);
+ if (rc)
+ return rc;
+
+ rc = cxl_dpa_setup(cxlds, &range_info);
if (rc)
return rc;
diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
index f9c95996e937..d061fe3d2b86 100644
--- a/drivers/cxl/pmem.c
+++ b/drivers/cxl/pmem.c
@@ -42,15 +42,44 @@ static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *
}
static DEVICE_ATTR_RO(id);
+static ssize_t dirty_shutdown_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nvdimm *nvdimm = to_nvdimm(dev);
+ struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
+
+ return sysfs_emit(buf, "%llu\n", cxl_nvd->dirty_shutdowns);
+}
+static DEVICE_ATTR_RO(dirty_shutdown);
+
static struct attribute *cxl_dimm_attributes[] = {
&dev_attr_id.attr,
&dev_attr_provider.attr,
+ &dev_attr_dirty_shutdown.attr,
NULL
};
+#define CXL_INVALID_DIRTY_SHUTDOWN_COUNT ULLONG_MAX
+static umode_t cxl_dimm_visible(struct kobject *kobj,
+ struct attribute *a, int n)
+{
+ if (a == &dev_attr_dirty_shutdown.attr) {
+ struct device *dev = kobj_to_dev(kobj);
+ struct nvdimm *nvdimm = to_nvdimm(dev);
+ struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
+
+ if (cxl_nvd->dirty_shutdowns ==
+ CXL_INVALID_DIRTY_SHUTDOWN_COUNT)
+ return 0;
+ }
+
+ return a->mode;
+}
+
static const struct attribute_group cxl_dimm_attribute_group = {
.name = "cxl",
.attrs = cxl_dimm_attributes,
+ .is_visible = cxl_dimm_visible
};
static const struct attribute_group *cxl_dimm_attribute_groups[] = {
@@ -58,6 +87,38 @@ static const struct attribute_group *cxl_dimm_attribute_groups[] = {
NULL
};
+static void cxl_nvdimm_arm_dirty_shutdown_tracking(struct cxl_nvdimm *cxl_nvd)
+{
+ struct cxl_memdev *cxlmd = cxl_nvd->cxlmd;
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
+ struct device *dev = &cxl_nvd->dev;
+ u32 count;
+
+ /*
+ * Dirty tracking is enabled and exposed to the user, only when:
+ * - dirty shutdown on the device can be set, and,
+ * - the device has a Device GPF DVSEC (albeit unused), and,
+ * - the Get Health Info cmd can retrieve the device's dirty count.
+ */
+ cxl_nvd->dirty_shutdowns = CXL_INVALID_DIRTY_SHUTDOWN_COUNT;
+
+ if (cxl_arm_dirty_shutdown(mds)) {
+ dev_warn(dev, "GPF: could not set dirty shutdown state\n");
+ return;
+ }
+
+ if (!cxl_gpf_get_dvsec(cxlds->dev, false))
+ return;
+
+ if (cxl_get_dirty_count(mds, &count)) {
+ dev_warn(dev, "GPF: could not retrieve dirty count\n");
+ return;
+ }
+
+ cxl_nvd->dirty_shutdowns = count;
+}
+
static int cxl_nvdimm_probe(struct device *dev)
{
struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev);
@@ -78,6 +139,14 @@ static int cxl_nvdimm_probe(struct device *dev)
set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask);
set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask);
set_bit(ND_CMD_SET_CONFIG_DATA, &cmd_mask);
+
+ /*
+ * Set dirty shutdown now, with the expectation that the device
+ * clear it upon a successful GPF flow. The exception to this
+ * is upon Viral detection, per CXL 3.2 section 12.4.2.
+ */
+ cxl_nvdimm_arm_dirty_shutdown_tracking(cxl_nvd);
+
nvdimm = __nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd,
cxl_dimm_attribute_groups, flags,
cmd_mask, 0, NULL, cxl_nvd->dev_id,
@@ -375,6 +444,16 @@ static int cxl_pmem_region_probe(struct device *dev)
goto out_nvd;
}
+ if (cxlds->serial == 0) {
+ /* include missing alongside invalid in this error message. */
+ dev_err(dev, "%s: invalid or missing serial number\n",
+ dev_name(&cxlmd->dev));
+ rc = -ENXIO;
+ goto out_nvd;
+ }
+ info[i].serial = cxlds->serial;
+ info[i].offset = m->start;
+
m->cxl_nvd = cxl_nvd;
mappings[i] = (struct nd_mapping_desc) {
.nvdimm = nvdimm,
@@ -382,8 +461,6 @@ static int cxl_pmem_region_probe(struct device *dev)
.size = m->size,
.position = i,
};
- info[i].offset = m->start;
- info[i].serial = cxlds->serial;
}
ndr_desc.num_mappings = cxlr_pmem->nr_mappings;
ndr_desc.mapping = mappings;
diff --git a/drivers/dma-buf/st-dma-fence.c b/drivers/dma-buf/st-dma-fence.c
index cf2ce3744ce6..9f80a45498f0 100644
--- a/drivers/dma-buf/st-dma-fence.c
+++ b/drivers/dma-buf/st-dma-fence.c
@@ -412,7 +412,7 @@ static int test_wait_timeout(void *arg)
err = 0;
err_free:
- del_timer_sync(&wt.timer);
+ timer_delete_sync(&wt.timer);
destroy_timer_on_stack(&wt.timer);
dma_fence_signal(wt.f);
dma_fence_put(wt.f);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8afea2e23360..df2d2dc00a05 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -546,7 +546,7 @@ config PL330_DMA
config PXA_DMA
bool "PXA DMA support"
- depends on (ARCH_MMP || ARCH_PXA)
+ depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
help
diff --git a/drivers/dma/amd/ae4dma/ae4dma-pci.c b/drivers/dma/amd/ae4dma/ae4dma-pci.c
index aad0dc4294a3..2c63907db228 100644
--- a/drivers/dma/amd/ae4dma/ae4dma-pci.c
+++ b/drivers/dma/amd/ae4dma/ae4dma-pci.c
@@ -46,8 +46,8 @@ static int ae4_get_irqs(struct ae4_device *ae4)
} else {
ae4_msix->msix_count = ret;
- for (i = 0; i < MAX_AE4_HW_QUEUES; i++)
- ae4->ae4_irq[i] = ae4_msix->msix_entry[i].vector;
+ for (i = 0; i < ae4_msix->msix_count; i++)
+ ae4->ae4_irq[i] = pci_irq_vector(pdev, i);
}
return ret;
@@ -137,8 +137,6 @@ static void ae4_pci_remove(struct pci_dev *pdev)
}
static const struct pci_device_id ae4_pci_table[] = {
- { PCI_VDEVICE(AMD, 0x14C8), },
- { PCI_VDEVICE(AMD, 0x14DC), },
{ PCI_VDEVICE(AMD, 0x149B), },
/* Last entry must be zero */
{ 0, }
diff --git a/drivers/dma/amd/ae4dma/ae4dma.h b/drivers/dma/amd/ae4dma/ae4dma.h
index 265c5d436008..57f6048726bb 100644
--- a/drivers/dma/amd/ae4dma/ae4dma.h
+++ b/drivers/dma/amd/ae4dma/ae4dma.h
@@ -37,6 +37,8 @@
#define AE4_DMA_VERSION 4
#define CMD_AE4_DESC_DW0_VAL 2
+#define AE4_TIME_OUT 5000
+
struct ae4_msix {
int msix_count;
struct msix_entry msix_entry[MAX_AE4_HW_QUEUES];
diff --git a/drivers/dma/amd/ptdma/ptdma-dmaengine.c b/drivers/dma/amd/ptdma/ptdma-dmaengine.c
index 35c84ec9608b..715ac3ae067b 100644
--- a/drivers/dma/amd/ptdma/ptdma-dmaengine.c
+++ b/drivers/dma/amd/ptdma/ptdma-dmaengine.c
@@ -198,8 +198,10 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
{
struct dma_async_tx_descriptor *tx_desc;
struct virt_dma_desc *vd;
+ struct pt_device *pt;
unsigned long flags;
+ pt = chan->pt;
/* Loop over descriptors until one is found with commands */
do {
if (desc) {
@@ -217,7 +219,7 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
spin_lock_irqsave(&chan->vc.lock, flags);
- if (desc) {
+ if (pt->ver != AE4_DMA_VERSION && desc) {
if (desc->status != DMA_COMPLETE) {
if (desc->status != DMA_ERROR)
desc->status = DMA_COMPLETE;
@@ -235,7 +237,7 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
spin_unlock_irqrestore(&chan->vc.lock, flags);
- if (tx_desc) {
+ if (pt->ver != AE4_DMA_VERSION && tx_desc) {
dmaengine_desc_get_callback_invoke(tx_desc, NULL);
dma_run_dependencies(tx_desc);
vchan_vdesc_fini(vd);
@@ -245,11 +247,25 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
return NULL;
}
+static inline bool ae4_core_queue_full(struct pt_cmd_queue *cmd_q)
+{
+ u32 front_wi = readl(cmd_q->reg_control + AE4_WR_IDX_OFF);
+ u32 rear_ri = readl(cmd_q->reg_control + AE4_RD_IDX_OFF);
+
+ if (((MAX_CMD_QLEN + front_wi - rear_ri) % MAX_CMD_QLEN) >= (MAX_CMD_QLEN - 1))
+ return true;
+
+ return false;
+}
+
static void pt_cmd_callback(void *data, int err)
{
struct pt_dma_desc *desc = data;
+ struct ae4_cmd_queue *ae4cmd_q;
struct dma_chan *dma_chan;
struct pt_dma_chan *chan;
+ struct ae4_device *ae4;
+ struct pt_device *pt;
int ret;
if (err == -EINPROGRESS)
@@ -257,11 +273,32 @@ static void pt_cmd_callback(void *data, int err)
dma_chan = desc->vd.tx.chan;
chan = to_pt_chan(dma_chan);
+ pt = chan->pt;
if (err)
desc->status = DMA_ERROR;
while (true) {
+ if (pt->ver == AE4_DMA_VERSION) {
+ ae4 = container_of(pt, struct ae4_device, pt);
+ ae4cmd_q = &ae4->ae4cmd_q[chan->id];
+
+ if (ae4cmd_q->q_cmd_count >= (CMD_Q_LEN - 1) ||
+ ae4_core_queue_full(&ae4cmd_q->cmd_q)) {
+ wake_up(&ae4cmd_q->q_w);
+
+ if (wait_for_completion_timeout(&ae4cmd_q->cmp,
+ msecs_to_jiffies(AE4_TIME_OUT))
+ == 0) {
+ dev_err(pt->dev, "TIMEOUT %d:\n", ae4cmd_q->id);
+ break;
+ }
+
+ reinit_completion(&ae4cmd_q->cmp);
+ continue;
+ }
+ }
+
/* Check for DMA descriptor completion */
desc = pt_handle_active_desc(chan, desc);
@@ -296,6 +333,49 @@ static struct pt_dma_desc *pt_alloc_dma_desc(struct pt_dma_chan *chan,
return desc;
}
+static void pt_cmd_callback_work(void *data, int err)
+{
+ struct dma_async_tx_descriptor *tx_desc;
+ struct pt_dma_desc *desc = data;
+ struct dma_chan *dma_chan;
+ struct virt_dma_desc *vd;
+ struct pt_dma_chan *chan;
+ unsigned long flags;
+
+ dma_chan = desc->vd.tx.chan;
+ chan = to_pt_chan(dma_chan);
+
+ if (err == -EINPROGRESS)
+ return;
+
+ tx_desc = &desc->vd.tx;
+ vd = &desc->vd;
+
+ if (err)
+ desc->status = DMA_ERROR;
+
+ spin_lock_irqsave(&chan->vc.lock, flags);
+ if (desc) {
+ if (desc->status != DMA_COMPLETE) {
+ if (desc->status != DMA_ERROR)
+ desc->status = DMA_COMPLETE;
+
+ dma_cookie_complete(tx_desc);
+ dma_descriptor_unmap(tx_desc);
+ } else {
+ tx_desc = NULL;
+ }
+ }
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
+
+ if (tx_desc) {
+ dmaengine_desc_get_callback_invoke(tx_desc, NULL);
+ dma_run_dependencies(tx_desc);
+ list_del(&desc->vd.node);
+ vchan_vdesc_fini(vd);
+ }
+}
+
static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
dma_addr_t dst,
dma_addr_t src,
@@ -327,6 +407,7 @@ static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
desc->len = len;
if (pt->ver == AE4_DMA_VERSION) {
+ pt_cmd->pt_cmd_callback = pt_cmd_callback_work;
ae4 = container_of(pt, struct ae4_device, pt);
ae4cmd_q = &ae4->ae4cmd_q[chan->id];
mutex_lock(&ae4cmd_q->cmd_lock);
@@ -367,13 +448,16 @@ static void pt_issue_pending(struct dma_chan *dma_chan)
{
struct pt_dma_chan *chan = to_pt_chan(dma_chan);
struct pt_dma_desc *desc;
+ struct pt_device *pt;
unsigned long flags;
bool engine_is_idle = true;
+ pt = chan->pt;
+
spin_lock_irqsave(&chan->vc.lock, flags);
desc = pt_next_dma_desc(chan);
- if (desc)
+ if (desc && pt->ver != AE4_DMA_VERSION)
engine_is_idle = false;
vchan_issue_pending(&chan->vc);
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 20b10c15c696..0117bb2e8591 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -893,7 +893,7 @@ static int bcm2835_dma_suspend_late(struct device *dev)
}
static const struct dev_pm_ops bcm2835_dma_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL)
+ LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL)
};
static int bcm2835_dma_probe(struct platform_device *pdev)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index c1357d7f3dc6..758fcd0546d8 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -40,6 +40,8 @@
#include <linux/dmaengine.h>
#include <linux/hardirq.h>
#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/property.h>
#include <linux/percpu.h>
#include <linux/rcupdate.h>
#include <linux/mutex.h>
@@ -812,15 +814,13 @@ static const struct dma_slave_map *dma_filter_match(struct dma_device *device,
*/
struct dma_chan *dma_request_chan(struct device *dev, const char *name)
{
+ struct fwnode_handle *fwnode = dev_fwnode(dev);
struct dma_device *d, *_d;
struct dma_chan *chan = NULL;
- /* If device-tree is present get slave info from here */
- if (dev->of_node)
- chan = of_dma_request_slave_channel(dev->of_node, name);
-
- /* If device was enumerated by ACPI get slave info from here */
- if (has_acpi_companion(dev) && !chan)
+ if (is_of_node(fwnode))
+ chan = of_dma_request_slave_channel(to_of_node(fwnode), name);
+ else if (is_acpi_device_node(fwnode))
chan = acpi_dma_request_slave_chan_by_name(dev, name);
if (PTR_ERR(chan) == -EPROBE_DEFER)
@@ -854,8 +854,8 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name)
found:
#ifdef CONFIG_DEBUG_FS
- chan->dbg_client_name = kasprintf(GFP_KERNEL, "%s:%s", dev_name(dev),
- name);
+ chan->dbg_client_name = kasprintf(GFP_KERNEL, "%s:%s", dev_name(dev), name);
+ /* No functional issue if it fails, users are supposed to test before use */
#endif
chan->name = kasprintf(GFP_KERNEL, "dma:%s", name);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 91b2fbc0b864..d891dfca358e 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -841,9 +841,9 @@ static int dmatest_func(void *data)
} else {
dma_async_issue_pending(chan);
- wait_event_freezable_timeout(thread->done_wait,
- done->done,
- msecs_to_jiffies(params->timeout));
+ wait_event_timeout(thread->done_wait,
+ done->done,
+ msecs_to_jiffies(params->timeout));
status = dma_async_is_tx_complete(chan, cookie, NULL,
NULL);
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index 68236247059d..c2b88cc99e5d 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c
@@ -15,6 +15,7 @@
#include <linux/irq.h>
#include <linux/dma/edma.h>
#include <linux/dma-mapping.h>
+#include <linux/string_choices.h>
#include "dw-edma-core.h"
#include "dw-edma-v0-core.h"
@@ -746,7 +747,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
chan->ll_max -= 1;
dev_vdbg(dev, "L. List:\tChannel %s[%u] max_cnt=%u\n",
- chan->dir == EDMA_DIR_WRITE ? "write" : "read",
+ str_write_read(chan->dir == EDMA_DIR_WRITE),
chan->id, chan->ll_max);
if (dw->nr_irqs == 1)
@@ -767,7 +768,8 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
memcpy(&chan->msi, &irq->msi, sizeof(chan->msi));
dev_vdbg(dev, "MSI:\t\tChannel %s[%u] addr=0x%.8x%.8x, data=0x%.8x\n",
- chan->dir == EDMA_DIR_WRITE ? "write" : "read", chan->id,
+ str_write_read(chan->dir == EDMA_DIR_WRITE),
+ chan->id,
chan->msi.address_hi, chan->msi.address_lo,
chan->msi.data);
diff --git a/drivers/dma/dw/pci.c b/drivers/dma/dw/pci.c
index e8a0eb81726a..a3aae3d1c093 100644
--- a/drivers/dma/dw/pci.c
+++ b/drivers/dma/dw/pci.c
@@ -76,8 +76,6 @@ static void dw_pci_remove(struct pci_dev *pdev)
dev_warn(&pdev->dev, "can't remove device properly: %d\n", ret);
}
-#ifdef CONFIG_PM_SLEEP
-
static int dw_pci_suspend_late(struct device *dev)
{
struct dw_dma_chip_pdata *data = dev_get_drvdata(dev);
@@ -94,10 +92,8 @@ static int dw_pci_resume_early(struct device *dev)
return do_dw_dma_enable(chip);
};
-#endif /* CONFIG_PM_SLEEP */
-
static const struct dev_pm_ops dw_pci_dev_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_pci_suspend_late, dw_pci_resume_early)
+ LATE_SYSTEM_SLEEP_PM_OPS(dw_pci_suspend_late, dw_pci_resume_early)
};
static const struct pci_device_id dw_pci_id_table[] = {
@@ -136,7 +132,7 @@ static struct pci_driver dw_pci_driver = {
.probe = dw_pci_probe,
.remove = dw_pci_remove,
.driver = {
- .pm = &dw_pci_dev_pm_ops,
+ .pm = pm_sleep_ptr(&dw_pci_dev_pm_ops),
},
};
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index 2606cf9cd429..cee56cd31a61 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -157,8 +157,6 @@ static const struct acpi_device_id dw_dma_acpi_id_table[] = {
MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table);
#endif
-#ifdef CONFIG_PM_SLEEP
-
static int dw_suspend_late(struct device *dev)
{
struct dw_dma_chip_pdata *data = dev_get_drvdata(dev);
@@ -183,10 +181,8 @@ static int dw_resume_early(struct device *dev)
return do_dw_dma_enable(chip);
}
-#endif /* CONFIG_PM_SLEEP */
-
static const struct dev_pm_ops dw_dev_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_suspend_late, dw_resume_early)
+ LATE_SYSTEM_SLEEP_PM_OPS(dw_suspend_late, dw_resume_early)
};
static struct platform_driver dw_driver = {
@@ -195,7 +191,7 @@ static struct platform_driver dw_driver = {
.shutdown = dw_shutdown,
.driver = {
.name = DRV_NAME,
- .pm = &dw_dev_pm_ops,
+ .pm = pm_sleep_ptr(&dw_dev_pm_ops),
.of_match_table = of_match_ptr(dw_dma_of_id_table),
.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
},
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index f989b6c9c0a9..756d67325db5 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -164,7 +164,7 @@ static bool fsl_edma_srcid_in_use(struct fsl_edma_engine *fsl_edma, u32 srcid)
fsl_chan = &fsl_edma->chans[i];
if (fsl_chan->srcid && srcid == fsl_chan->srcid) {
- dev_err(&fsl_chan->pdev->dev, "The srcid is in use, can't use!");
+ dev_err(&fsl_chan->pdev->dev, "The srcid is in use, can't use!\n");
return true;
}
}
@@ -401,6 +401,7 @@ fsl_edma2_irq_init(struct platform_device *pdev,
/* The last IRQ is for eDMA err */
if (i == count - 1) {
+ fsl_edma->errirq = irq;
ret = devm_request_irq(&pdev->dev, irq,
fsl_edma_err_handler,
0, "eDMA2-ERR", fsl_edma);
@@ -420,10 +421,13 @@ static void fsl_edma_irq_exit(
struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
{
if (fsl_edma->txirq == fsl_edma->errirq) {
- devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
+ if (fsl_edma->txirq >= 0)
+ devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
} else {
- devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
- devm_free_irq(&pdev->dev, fsl_edma->errirq, fsl_edma);
+ if (fsl_edma->txirq >= 0)
+ devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
+ if (fsl_edma->errirq >= 0)
+ devm_free_irq(&pdev->dev, fsl_edma->errirq, fsl_edma);
}
}
@@ -620,6 +624,8 @@ static int fsl_edma_probe(struct platform_device *pdev)
if (!fsl_edma)
return -ENOMEM;
+ fsl_edma->errirq = -EINVAL;
+ fsl_edma->txirq = -EINVAL;
fsl_edma->drvdata = drvdata;
fsl_edma->n_chans = chans;
mutex_init(&fsl_edma->fsl_edma_mutex);
@@ -802,9 +808,9 @@ static void fsl_edma_remove(struct platform_device *pdev)
struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev);
fsl_edma_irq_exit(pdev, fsl_edma);
- fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
of_dma_controller_free(np);
dma_async_device_unregister(&fsl_edma->dma_dev);
+ fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs);
}
@@ -822,7 +828,7 @@ static int fsl_edma_suspend_late(struct device *dev)
spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
/* Make sure chan is idle or will force disable. */
if (unlikely(fsl_chan->status == DMA_IN_PROGRESS)) {
- dev_warn(dev, "WARN: There is non-idle channel.");
+ dev_warn(dev, "WARN: There is non-idle channel.\n");
fsl_edma_disable_request(fsl_chan);
fsl_edma_chan_mux(fsl_chan, 0, false);
}
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index b946f78f85e1..fca1d2924999 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -912,8 +912,7 @@ static void idxd_device_config_restore(struct idxd_device *idxd,
idxd->rdbuf_limit = idxd_saved->saved_idxd.rdbuf_limit;
- if (saved_evl)
- idxd->evl->size = saved_evl->size;
+ idxd->evl->size = saved_evl->size;
for (i = 0; i < idxd->max_groups; i++) {
struct idxd_group *saved_group, *group;
diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
index 4127c1bdcca7..fd55bcd060ab 100644
--- a/drivers/dma/img-mdc-dma.c
+++ b/drivers/dma/img-mdc-dma.c
@@ -1073,7 +1073,7 @@ static struct platform_driver mdc_dma_driver = {
.driver = {
.name = "img-mdc-dma",
.pm = &img_mdc_pm_ops,
- .of_match_table = of_match_ptr(mdc_dma_of_match),
+ .of_match_table = mdc_dma_of_match,
},
.probe = mdc_dma_probe,
.remove = mdc_dma_remove,
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index a651e0995ce8..b96cc0a83872 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -17,6 +17,7 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
@@ -323,7 +324,7 @@ static void imxdma_disable_hw(struct imxdma_channel *imxdmac)
dev_dbg(imxdma->dev, "%s channel %d\n", __func__, channel);
if (imxdma_hw_chain(imxdmac))
- del_timer(&imxdmac->watchdog);
+ timer_delete(&imxdmac->watchdog);
local_irq_save(flags);
imx_dmav1_writel(imxdma, imx_dmav1_readl(imxdma, DMA_DIMR) |
@@ -453,7 +454,7 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
}
if (imxdma_hw_chain(imxdmac)) {
- del_timer(&imxdmac->watchdog);
+ timer_delete(&imxdmac->watchdog);
return;
}
}
@@ -942,7 +943,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_interleaved(
" src_sgl=%s dst_sgl=%s numf=%zu frame_size=%zu\n", __func__,
imxdmac->channel, (unsigned long long)xt->src_start,
(unsigned long long) xt->dst_start,
- xt->src_sgl ? "true" : "false", xt->dst_sgl ? "true" : "false",
+ str_true_false(xt->src_sgl), str_true_false(xt->dst_sgl),
xt->numf, xt->frame_size);
if (list_empty(&imxdmac->ld_free) ||
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 3449006cd14b..02a85d6f1bea 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1459,9 +1459,8 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
* dmatest, thus create 'struct imx_dma_data mem_data' for this case.
* Please note in any other slave case, you have to setup chan->private
* with 'struct imx_dma_data' in your own filter function if you want to
- * request dma channel by dma_request_channel() rather than
- * dma_request_slave_channel(). Othwise, 'MEMCPY in case?' will appear
- * to warn you to correct your filter function.
+ * request DMA channel by dma_request_channel(), otherwise, 'MEMCPY in
+ * case?' will appear to warn you to correct your filter function.
*/
if (!data) {
dev_dbg(sdmac->sdma->dev, "MEMCPY in case?\n");
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 79d8957f9e60..06a813cc7641 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -159,7 +159,7 @@ void ioat_stop(struct ioatdma_chan *ioat_chan)
}
/* flush inflight timers */
- del_timer_sync(&ioat_chan->timer);
+ timer_delete_sync(&ioat_chan->timer);
/* flush inflight tasklet runs */
tasklet_kill(&ioat_chan->cleanup_task);
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c
index cc9ddd6c325b..02f68b328511 100644
--- a/drivers/dma/ioat/init.c
+++ b/drivers/dma/ioat/init.c
@@ -1224,12 +1224,12 @@ static void ioat_shutdown(struct pci_dev *pdev)
set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
spin_unlock_bh(&ioat_chan->prep_lock);
/*
- * Synchronization rule for del_timer_sync():
+ * Synchronization rule for timer_delete_sync():
* - The caller must not hold locks which would prevent
* completion of the timer's handler.
* So prep_lock cannot be held before calling it.
*/
- del_timer_sync(&ioat_chan->timer);
+ timer_delete_sync(&ioat_chan->timer);
/* this should quiesce then reset */
ioat_reset_hw(ioat_chan);
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index e50cf3357e5e..249296389771 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <linux/dmaengine.h>
#include <linux/platform_device.h>
#include <linux/device.h>
@@ -277,8 +278,7 @@ static int chan_state_show(struct seq_file *s, void *p)
seq_printf(s, "\tPriority : %s\n",
str_prio[(phy->idx & 0xf) / 4]);
seq_printf(s, "\tUnaligned transfer bit: %s\n",
- _phy_readl_relaxed(phy, DALGN) & BIT(phy->idx) ?
- "yes" : "no");
+ str_yes_no(_phy_readl_relaxed(phy, DALGN) & BIT(phy->idx)));
seq_printf(s, "\tDCSR = %08x (%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
dcsr, PXA_DCSR_STR(RUN), PXA_DCSR_STR(NODESC),
PXA_DCSR_STR(STOPIRQEN), PXA_DCSR_STR(EORIRQEN),
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index fdd41e1c2263..6b4fce453c85 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -725,7 +725,7 @@ static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic(
slave_addr = ops->slave_addr(schan);
/*
- * Allocate the sg list dynamically as it would consumer too much stack
+ * Allocate the sg list dynamically as it would consume too much stack
* space.
*/
sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_KERNEL);
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 95ecb12caaa5..2215ff877bf7 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <linux/types.h>
#include "virt-dma.h"
@@ -553,7 +554,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id)
continue;
dev_dbg(sdev->slave.dev, "DMA irq status %s: 0x%x\n",
- i ? "high" : "low", status);
+ str_high_low(i), status);
writel(status, sdev->base + DMA_IRQ_STAT(i));
diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
index 4ece125b2ae7..3ed406f08c44 100644
--- a/drivers/dma/ti/edma.c
+++ b/drivers/dma/ti/edma.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/string_choices.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/of_irq.h>
@@ -2047,7 +2048,7 @@ static int edma_setup_from_hw(struct device *dev, struct edma_soc_info *pdata,
dev_dbg(dev, "num_qchannels: %u\n", ecc->num_qchannels);
dev_dbg(dev, "num_slots: %u\n", ecc->num_slots);
dev_dbg(dev, "num_tc: %u\n", ecc->num_tc);
- dev_dbg(dev, "chmap_exist: %s\n", ecc->chmap_exist ? "yes" : "no");
+ dev_dbg(dev, "chmap_exist: %s\n", str_yes_no(ecc->chmap_exist));
/* Nothing need to be done if queue priority is provided */
if (pdata->queue_priority_mapping)
@@ -2258,8 +2259,12 @@ static struct dma_chan *of_edma_xlate(struct of_phandle_args *dma_spec,
return NULL;
out:
- /* The channel is going to be used as HW synchronized */
- echan->hw_triggered = true;
+ /*
+ * The channel is going to be HW synchronized, unless it was
+ * reserved as a memcpy channel
+ */
+ echan->hw_triggered =
+ !edma_is_memcpy_channel(i, ecc->info->memcpy_channels);
return dma_get_slave_channel(chan);
}
#else
diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
index 7c224c3ab7a0..f87d244cc2d6 100644
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -84,6 +84,7 @@ struct k3_udma_glue_rx_channel {
struct k3_udma_glue_rx_flow *flows;
u32 flow_num;
u32 flows_ready;
+ bool single_fdq; /* one FDQ for all flows */
};
static void k3_udma_chan_dev_release(struct device *dev)
@@ -970,10 +971,13 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
ep_cfg = rx_chn->common.ep_config;
- if (xudma_is_pktdma(rx_chn->common.udmax))
+ if (xudma_is_pktdma(rx_chn->common.udmax)) {
rx_chn->udma_rchan_id = ep_cfg->mapped_channel_id;
- else
+ rx_chn->single_fdq = false;
+ } else {
rx_chn->udma_rchan_id = -1;
+ rx_chn->single_fdq = true;
+ }
/* request and cfg UDMAP RX channel */
rx_chn->udma_rchanx = xudma_rchan_get(rx_chn->common.udmax,
@@ -1103,6 +1107,9 @@ k3_udma_glue_request_remote_rx_chn_common(struct k3_udma_glue_rx_channel *rx_chn
rx_chn->common.chan_dev.dma_coherent = true;
dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev,
DMA_BIT_MASK(48));
+ rx_chn->single_fdq = false;
+ } else {
+ rx_chn->single_fdq = true;
}
ret = k3_udma_glue_allocate_rx_flows(rx_chn, cfg);
@@ -1453,7 +1460,7 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_tdown_rx_chn);
void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn,
u32 flow_num, void *data,
- void (*cleanup)(void *data, dma_addr_t desc_dma), bool skip_fdq)
+ void (*cleanup)(void *data, dma_addr_t desc_dma))
{
struct k3_udma_glue_rx_flow *flow = &rx_chn->flows[flow_num];
struct device *dev = rx_chn->common.dev;
@@ -1465,7 +1472,7 @@ void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn,
dev_dbg(dev, "RX reset flow %u occ_rx %u\n", flow_num, occ_rx);
/* Skip RX FDQ in case one FDQ is used for the set of flows */
- if (skip_fdq)
+ if (rx_chn->single_fdq && flow_num)
goto do_reset;
/*
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 7ed1956b4642..b223a7aacb0c 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -4886,6 +4886,12 @@ static int bcdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i].start = rm_res->desc[i].start +
oes->bcdma_bchan_ring;
irq_res.desc[i].num = rm_res->desc[i].num;
+
+ if (rm_res->desc[i].num_sec) {
+ irq_res.desc[i].start_sec = rm_res->desc[i].start_sec +
+ oes->bcdma_bchan_ring;
+ irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+ }
}
}
} else {
@@ -4909,6 +4915,15 @@ static int bcdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i + 1].start = rm_res->desc[j].start +
oes->bcdma_tchan_ring;
irq_res.desc[i + 1].num = rm_res->desc[j].num;
+
+ if (rm_res->desc[j].num_sec) {
+ irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+ oes->bcdma_tchan_data;
+ irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+ irq_res.desc[i + 1].start_sec = rm_res->desc[j].start_sec +
+ oes->bcdma_tchan_ring;
+ irq_res.desc[i + 1].num_sec = rm_res->desc[j].num_sec;
+ }
}
}
}
@@ -4929,6 +4944,15 @@ static int bcdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i + 1].start = rm_res->desc[j].start +
oes->bcdma_rchan_ring;
irq_res.desc[i + 1].num = rm_res->desc[j].num;
+
+ if (rm_res->desc[j].num_sec) {
+ irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+ oes->bcdma_rchan_data;
+ irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+ irq_res.desc[i + 1].start_sec = rm_res->desc[j].start_sec +
+ oes->bcdma_rchan_ring;
+ irq_res.desc[i + 1].num_sec = rm_res->desc[j].num_sec;
+ }
}
}
}
@@ -5063,6 +5087,12 @@ static int pktdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i].start = rm_res->desc[i].start +
oes->pktdma_tchan_flow;
irq_res.desc[i].num = rm_res->desc[i].num;
+
+ if (rm_res->desc[i].num_sec) {
+ irq_res.desc[i].start_sec = rm_res->desc[i].start_sec +
+ oes->pktdma_tchan_flow;
+ irq_res.desc[i].num_sec = rm_res->desc[i].num_sec;
+ }
}
}
rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW];
@@ -5074,6 +5104,12 @@ static int pktdma_setup_resources(struct udma_dev *ud)
irq_res.desc[i].start = rm_res->desc[j].start +
oes->pktdma_rchan_flow;
irq_res.desc[i].num = rm_res->desc[j].num;
+
+ if (rm_res->desc[j].num_sec) {
+ irq_res.desc[i].start_sec = rm_res->desc[j].start_sec +
+ oes->pktdma_rchan_flow;
+ irq_res.desc[i].num_sec = rm_res->desc[j].num_sec;
+ }
}
}
ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res);
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 108a7287f4cd..3ad44afd0e74 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -46,6 +46,7 @@
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <linux/clk.h>
#include <linux/io-64-nonatomic-lo-hi.h>
@@ -2940,7 +2941,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
XILINX_DMA_DMASR_SG_MASK)
chan->has_sg = true;
dev_dbg(chan->dev, "ch %d: SG %s\n", chan->id,
- chan->has_sg ? "enabled" : "disabled");
+ str_enabled_disabled(chan->has_sg));
}
/* Initialize the tasklet */
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index b360dca2c69e..bd04980009a4 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1137,10 +1137,7 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
unsigned long payload, buffer_end, transmit_header_bytes = 0;
u32 control;
int count;
- struct {
- struct fw_iso_packet packet;
- u8 header[256];
- } u;
+ DEFINE_RAW_FLEX(struct fw_iso_packet, u, header, 64);
if (ctx == NULL || a->handle != 0)
return -EINVAL;
@@ -1172,29 +1169,29 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
while (p < end) {
if (get_user(control, &p->control))
return -EFAULT;
- u.packet.payload_length = GET_PAYLOAD_LENGTH(control);
- u.packet.interrupt = GET_INTERRUPT(control);
- u.packet.skip = GET_SKIP(control);
- u.packet.tag = GET_TAG(control);
- u.packet.sy = GET_SY(control);
- u.packet.header_length = GET_HEADER_LENGTH(control);
+ u->payload_length = GET_PAYLOAD_LENGTH(control);
+ u->interrupt = GET_INTERRUPT(control);
+ u->skip = GET_SKIP(control);
+ u->tag = GET_TAG(control);
+ u->sy = GET_SY(control);
+ u->header_length = GET_HEADER_LENGTH(control);
switch (ctx->type) {
case FW_ISO_CONTEXT_TRANSMIT:
- if (u.packet.header_length & 3)
+ if (u->header_length & 3)
return -EINVAL;
- transmit_header_bytes = u.packet.header_length;
+ transmit_header_bytes = u->header_length;
break;
case FW_ISO_CONTEXT_RECEIVE:
- if (u.packet.header_length == 0 ||
- u.packet.header_length % ctx->header_size != 0)
+ if (u->header_length == 0 ||
+ u->header_length % ctx->header_size != 0)
return -EINVAL;
break;
case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
- if (u.packet.payload_length == 0 ||
- u.packet.payload_length & 3)
+ if (u->payload_length == 0 ||
+ u->payload_length & 3)
return -EINVAL;
break;
}
@@ -1204,20 +1201,19 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
if (next > end)
return -EINVAL;
if (copy_from_user
- (u.packet.header, p->header, transmit_header_bytes))
+ (u->header, p->header, transmit_header_bytes))
return -EFAULT;
- if (u.packet.skip && ctx->type == FW_ISO_CONTEXT_TRANSMIT &&
- u.packet.header_length + u.packet.payload_length > 0)
+ if (u->skip && ctx->type == FW_ISO_CONTEXT_TRANSMIT &&
+ u->header_length + u->payload_length > 0)
return -EINVAL;
- if (payload + u.packet.payload_length > buffer_end)
+ if (payload + u->payload_length > buffer_end)
return -EINVAL;
- if (fw_iso_context_queue(ctx, &u.packet,
- &client->buffer, payload))
+ if (fw_iso_context_queue(ctx, u, &client->buffer, payload))
break;
p = next;
- payload += u.packet.payload_length;
+ payload += u->payload_length;
count++;
}
fw_iso_context_queue_flush(ctx);
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index e141d24a7644..b0f9ef6ac6df 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -39,7 +39,7 @@
static int try_cancel_split_timeout(struct fw_transaction *t)
{
if (t->is_split_transaction)
- return del_timer(&t->split_timeout_timer);
+ return timer_delete(&t->split_timeout_timer);
else
return 1;
}
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
index 42433c19eb30..560724ce21aa 100644
--- a/drivers/firmware/cirrus/cs_dsp.c
+++ b/drivers/firmware/cirrus/cs_dsp.c
@@ -1631,6 +1631,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
cs_dsp_debugfs_save_wmfwname(dsp, file);
+ ret = 0;
out_fw:
cs_dsp_buf_free(&buf_list);
@@ -2338,6 +2339,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
cs_dsp_debugfs_save_binname(dsp, file);
+ ret = 0;
out_fw:
cs_dsp_buf_free(&buf_list);
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index b69e68ef3f02..928409199a1a 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -24,7 +24,7 @@
#include <linux/bcd.h>
#include <acpi/ghes.h>
#include <ras/ras_event.h>
-#include "cper_cxl.h"
+#include <cxl/event.h>
/*
* CPER record ID need to be unique even after reboot, because record
@@ -624,11 +624,11 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
else
goto err_section_too_small;
} else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
- struct cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
+ struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
printk("%ssection_type: CXL Protocol Error\n", newpfx);
if (gdata->error_data_length >= sizeof(*prot_err))
- cper_print_prot_err(newpfx, prot_err);
+ cxl_cper_print_prot_err(newpfx, prot_err);
else
goto err_section_too_small;
} else {
diff --git a/drivers/firmware/efi/cper_cxl.c b/drivers/firmware/efi/cper_cxl.c
index a55771b99a97..8a7667faf953 100644
--- a/drivers/firmware/efi/cper_cxl.c
+++ b/drivers/firmware/efi/cper_cxl.c
@@ -8,26 +8,7 @@
*/
#include <linux/cper.h>
-#include "cper_cxl.h"
-
-#define PROT_ERR_VALID_AGENT_TYPE BIT_ULL(0)
-#define PROT_ERR_VALID_AGENT_ADDRESS BIT_ULL(1)
-#define PROT_ERR_VALID_DEVICE_ID BIT_ULL(2)
-#define PROT_ERR_VALID_SERIAL_NUMBER BIT_ULL(3)
-#define PROT_ERR_VALID_CAPABILITY BIT_ULL(4)
-#define PROT_ERR_VALID_DVSEC BIT_ULL(5)
-#define PROT_ERR_VALID_ERROR_LOG BIT_ULL(6)
-
-/* CXL RAS Capability Structure, CXL v3.0 sec 8.2.4.16 */
-struct cxl_ras_capability_regs {
- u32 uncor_status;
- u32 uncor_mask;
- u32 uncor_severity;
- u32 cor_status;
- u32 cor_mask;
- u32 cap_control;
- u32 header_log[16];
-};
+#include <cxl/event.h>
static const char * const prot_err_agent_type_strs[] = {
"Restricted CXL Device",
@@ -40,22 +21,8 @@ static const char * const prot_err_agent_type_strs[] = {
"CXL Upstream Switch Port",
};
-/*
- * The layout of the enumeration and the values matches CXL Agent Type
- * field in the UEFI 2.10 Section N.2.13,
- */
-enum {
- RCD, /* Restricted CXL Device */
- RCH_DP, /* Restricted CXL Host Downstream Port */
- DEVICE, /* CXL Device */
- LD, /* CXL Logical Device */
- FMLD, /* CXL Fabric Manager managed Logical Device */
- RP, /* CXL Root Port */
- DSP, /* CXL Downstream Switch Port */
- USP, /* CXL Upstream Switch Port */
-};
-
-void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err)
+void cxl_cper_print_prot_err(const char *pfx,
+ const struct cxl_cper_sec_prot_err *prot_err)
{
if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_TYPE)
pr_info("%s agent_type: %d, %s\n", pfx, prot_err->agent_type,
diff --git a/drivers/firmware/efi/cper_cxl.h b/drivers/firmware/efi/cper_cxl.h
deleted file mode 100644
index 86bfcf7909ec..000000000000
--- a/drivers/firmware/efi/cper_cxl.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * UEFI Common Platform Error Record (CPER) support for CXL Section.
- *
- * Copyright (C) 2022 Advanced Micro Devices, Inc.
- *
- * Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
- */
-
-#ifndef LINUX_CPER_CXL_H
-#define LINUX_CPER_CXL_H
-
-/* CXL Protocol Error Section */
-#define CPER_SEC_CXL_PROT_ERR \
- GUID_INIT(0x80B9EFB4, 0x52B5, 0x4DE3, 0xA7, 0x77, 0x68, 0x78, \
- 0x4B, 0x77, 0x10, 0x48)
-
-#pragma pack(1)
-
-/* Compute Express Link Protocol Error Section, UEFI v2.10 sec N.2.13 */
-struct cper_sec_prot_err {
- u64 valid_bits;
- u8 agent_type;
- u8 reserved[7];
-
- /*
- * Except for RCH Downstream Port, all the remaining CXL Agent
- * types are uniquely identified by the PCIe compatible SBDF number.
- */
- union {
- u64 rcrb_base_addr;
- struct {
- u8 function;
- u8 device;
- u8 bus;
- u16 segment;
- u8 reserved_1[3];
- };
- } agent_addr;
-
- struct {
- u16 vendor_id;
- u16 device_id;
- u16 subsystem_vendor_id;
- u16 subsystem_id;
- u8 class_code[2];
- u16 slot;
- u8 reserved_1[4];
- } device_id;
-
- struct {
- u32 lower_dw;
- u32 upper_dw;
- } dev_serial_num;
-
- u8 capability[60];
- u16 dvsec_len;
- u16 err_len;
- u8 reserved_2[4];
-};
-
-#pragma pack()
-
-void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err);
-
-#endif //__CPER_CXL_
diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
index 116eb465cdb4..b662b7e28b80 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -342,7 +342,7 @@ static int suspend_test_thread(void *arg)
* Disable the timer to make sure that the timer will not trigger
* later.
*/
- del_timer(&wakeup_timer);
+ timer_delete(&wakeup_timer);
destroy_timer_on_stack(&wakeup_timer);
if (atomic_dec_return_relaxed(&nb_active_threads) == 0)
diff --git a/drivers/gpu/drm/adp/adp_drv.c b/drivers/gpu/drm/adp/adp_drv.c
index 0eeb9e5fab26..c98c647f981d 100644
--- a/drivers/gpu/drm/adp/adp_drv.c
+++ b/drivers/gpu/drm/adp/adp_drv.c
@@ -232,9 +232,9 @@ static struct drm_plane *adp_plane_new(struct adp_drv_private *adp)
ALL_CRTCS, &adp_plane_funcs,
plane_formats, ARRAY_SIZE(plane_formats),
NULL, DRM_PLANE_TYPE_PRIMARY, "plane");
- if (!plane) {
+ if (IS_ERR(plane)) {
drm_err(drm, "failed to allocate plane");
- return ERR_PTR(-ENOMEM);
+ return plane;
}
drm_plane_helper_add(plane, &adp_plane_helper_funcs);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c
index dc47f5fd4ea1..b4ad163f42a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c
@@ -195,6 +195,10 @@ static bool aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank,
{
const struct aca_bank_ops *bank_ops = handle->bank_ops;
+ /* Parse all deferred errors with UMC aca handle */
+ if (ACA_BANK_ERR_IS_DEFFERED(bank))
+ return handle->hwip == ACA_HWIP_TYPE_UMC;
+
if (!aca_bank_hwip_is_matched(bank, handle->hwip))
return false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h
index 6b180f1b33fd..38c88897e1ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h
@@ -80,14 +80,6 @@ struct ras_query_context;
(ACA_REG__STATUS__POISON((bank)->regs[ACA_REG_IDX_STATUS]) || \
ACA_REG__STATUS__DEFERRED((bank)->regs[ACA_REG_IDX_STATUS]))
-#define ACA_BANK_ERR_CE_DE_DECODE(bank) \
- (ACA_BANK_ERR_IS_DEFFERED(bank) ? ACA_ERROR_TYPE_DEFERRED : \
- ACA_ERROR_TYPE_CE)
-
-#define ACA_BANK_ERR_UE_DE_DECODE(bank) \
- (ACA_BANK_ERR_IS_DEFFERED(bank) ? ACA_ERROR_TYPE_DEFERRED : \
- ACA_ERROR_TYPE_UE)
-
enum aca_reg_idx {
ACA_REG_IDX_CTL = 0,
ACA_REG_IDX_STATUS = 1,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 75fcc521c171..00e96419fcda 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -447,6 +447,13 @@ success:
return true;
}
+static bool amdgpu_prefer_rom_resource(struct amdgpu_device *adev)
+{
+ struct resource *res = &adev->pdev->resource[PCI_ROM_RESOURCE];
+
+ return (res->flags & IORESOURCE_ROM_SHADOW);
+}
+
static bool amdgpu_get_bios_dgpu(struct amdgpu_device *adev)
{
if (amdgpu_atrm_get_bios(adev)) {
@@ -465,14 +472,27 @@ static bool amdgpu_get_bios_dgpu(struct amdgpu_device *adev)
goto success;
}
- if (amdgpu_read_platform_bios(adev)) {
- dev_info(adev->dev, "Fetched VBIOS from platform\n");
- goto success;
- }
+ if (amdgpu_prefer_rom_resource(adev)) {
+ if (amdgpu_read_bios(adev)) {
+ dev_info(adev->dev, "Fetched VBIOS from ROM BAR\n");
+ goto success;
+ }
- if (amdgpu_read_bios(adev)) {
- dev_info(adev->dev, "Fetched VBIOS from ROM BAR\n");
- goto success;
+ if (amdgpu_read_platform_bios(adev)) {
+ dev_info(adev->dev, "Fetched VBIOS from platform\n");
+ goto success;
+ }
+
+ } else {
+ if (amdgpu_read_platform_bios(adev)) {
+ dev_info(adev->dev, "Fetched VBIOS from platform\n");
+ goto success;
+ }
+
+ if (amdgpu_read_bios(adev)) {
+ dev_info(adev->dev, "Fetched VBIOS from ROM BAR\n");
+ goto success;
+ }
}
if (amdgpu_read_bios_from_rom(adev)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 23cfce5aa1fc..26bf896f1444 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1809,7 +1809,6 @@ static const u16 amdgpu_unsupported_pciidlist[] = {
};
static const struct pci_device_id pciidlist[] = {
-#ifdef CONFIG_DRM_AMDGPU_SI
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
{0x1002, 0x6784, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
{0x1002, 0x6788, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
@@ -1882,8 +1881,6 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x6665, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|AMD_IS_MOBILITY},
{0x1002, 0x6667, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|AMD_IS_MOBILITY},
{0x1002, 0x666F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|AMD_IS_MOBILITY},
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
/* Kaveri */
{0x1002, 0x1304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMD_IS_MOBILITY|AMD_IS_APU},
{0x1002, 0x1305, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KAVERI|AMD_IS_APU},
@@ -1966,7 +1963,6 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x985D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
{0x1002, 0x985E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
{0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
-#endif
/* topaz */
{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
@@ -2313,14 +2309,14 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
return -ENOTSUPP;
}
+ switch (flags & AMD_ASIC_MASK) {
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ case CHIP_OLAND:
+ case CHIP_HAINAN:
#ifdef CONFIG_DRM_AMDGPU_SI
- if (!amdgpu_si_support) {
- switch (flags & AMD_ASIC_MASK) {
- case CHIP_TAHITI:
- case CHIP_PITCAIRN:
- case CHIP_VERDE:
- case CHIP_OLAND:
- case CHIP_HAINAN:
+ if (!amdgpu_si_support) {
dev_info(&pdev->dev,
"SI support provided by radeon.\n");
dev_info(&pdev->dev,
@@ -2328,16 +2324,18 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
);
return -ENODEV;
}
- }
+ break;
+#else
+ dev_info(&pdev->dev, "amdgpu is built without SI support.\n");
+ return -ENODEV;
#endif
+ case CHIP_KAVERI:
+ case CHIP_BONAIRE:
+ case CHIP_HAWAII:
+ case CHIP_KABINI:
+ case CHIP_MULLINS:
#ifdef CONFIG_DRM_AMDGPU_CIK
- if (!amdgpu_cik_support) {
- switch (flags & AMD_ASIC_MASK) {
- case CHIP_KAVERI:
- case CHIP_BONAIRE:
- case CHIP_HAWAII:
- case CHIP_KABINI:
- case CHIP_MULLINS:
+ if (!amdgpu_cik_support) {
dev_info(&pdev->dev,
"CIK support provided by radeon.\n");
dev_info(&pdev->dev,
@@ -2345,8 +2343,14 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
);
return -ENODEV;
}
- }
+ break;
+#else
+ dev_info(&pdev->dev, "amdgpu is built without CIK support.\n");
+ return -ENODEV;
#endif
+ default:
+ break;
+ }
adev = devm_drm_dev_alloc(&pdev->dev, &amdgpu_kms_driver, typeof(*adev), ddev);
if (IS_ERR(adev))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2f24a6aa13bf..5f5c00ace96b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -280,7 +280,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
} while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq);
- if (del_timer(&ring->fence_drv.fallback_timer) &&
+ if (timer_delete(&ring->fence_drv.fallback_timer) &&
seq != ring->fence_drv.sync_seq)
amdgpu_fence_schedule_fallback(ring);
@@ -618,7 +618,7 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev)
amdgpu_irq_put(adev, ring->fence_drv.irq_src,
ring->fence_drv.irq_type);
- del_timer_sync(&ring->fence_drv.fallback_timer);
+ timer_delete_sync(&ring->fence_drv.fallback_timer);
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 85f774063f9b..fb212f0a1136 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1239,7 +1239,7 @@ void amdgpu_mes_remove_ring(struct amdgpu_device *adev,
return;
amdgpu_mes_remove_hw_queue(adev, ring->hw_queue_id);
- del_timer_sync(&ring->fence_drv.fallback_timer);
+ timer_delete_sync(&ring->fence_drv.fallback_timer);
amdgpu_ring_fini(ring);
kfree(ring);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 68685aca2835..443409d4f4b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -77,6 +77,7 @@ const char *ras_block_string[] = {
"jpeg",
"ih",
"mpio",
+ "mmsch",
};
const char *ras_mca_block_string[] = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 764e9fa0a914..927d6bff734a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -98,6 +98,7 @@ enum amdgpu_ras_block {
AMDGPU_RAS_BLOCK__JPEG,
AMDGPU_RAS_BLOCK__IH,
AMDGPU_RAS_BLOCK__MPIO,
+ AMDGPU_RAS_BLOCK__MMSCH,
AMDGPU_RAS_BLOCK__LAST,
AMDGPU_RAS_BLOCK__ANY = -1
@@ -795,6 +796,12 @@ amdgpu_ras_block_to_ta(enum amdgpu_ras_block block) {
return TA_RAS_BLOCK__VCN;
case AMDGPU_RAS_BLOCK__JPEG:
return TA_RAS_BLOCK__JPEG;
+ case AMDGPU_RAS_BLOCK__IH:
+ return TA_RAS_BLOCK__IH;
+ case AMDGPU_RAS_BLOCK__MPIO:
+ return TA_RAS_BLOCK__MPIO;
+ case AMDGPU_RAS_BLOCK__MMSCH:
+ return TA_RAS_BLOCK__MMSCH;
default:
WARN_ONCE(1, "RAS ERROR: unexpected block id %d\n", block);
return TA_RAS_BLOCK__UMC;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index d55c8b7fdb59..59acdbfe28d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -608,59 +608,17 @@ static ssize_t amdgpu_debugfs_mqd_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_ring *ring = file_inode(f)->i_private;
- volatile u32 *mqd;
- u32 *kbuf;
- int r, i;
- uint32_t value, result;
+ ssize_t bytes = min_t(ssize_t, ring->mqd_size - *pos, size);
+ void *from = ((u8 *)ring->mqd_ptr) + *pos;
- if (*pos & 3 || size & 3)
- return -EINVAL;
-
- kbuf = kmalloc(ring->mqd_size, GFP_KERNEL);
- if (!kbuf)
- return -ENOMEM;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto err_free;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&mqd);
- if (r)
- goto err_unreserve;
-
- /*
- * Copy to local buffer to avoid put_user(), which might fault
- * and acquire mmap_sem, under reservation_ww_class_mutex.
- */
- for (i = 0; i < ring->mqd_size/sizeof(u32); i++)
- kbuf[i] = mqd[i];
+ if (*pos > ring->mqd_size)
+ return 0;
- amdgpu_bo_kunmap(ring->mqd_obj);
- amdgpu_bo_unreserve(ring->mqd_obj);
+ if (copy_to_user(buf, from, bytes))
+ return -EFAULT;
- result = 0;
- while (size) {
- if (*pos >= ring->mqd_size)
- break;
-
- value = kbuf[*pos/4];
- r = put_user(value, (uint32_t *)buf);
- if (r)
- goto err_free;
- buf += 4;
- result += 4;
- size -= 4;
- *pos += 4;
- }
-
- kfree(kbuf);
- return result;
-
-err_unreserve:
- amdgpu_bo_unreserve(ring->mqd_obj);
-err_free:
- kfree(kbuf);
- return r;
+ *pos += bytes;
+ return bytes;
}
static const struct file_operations amdgpu_debugfs_mqd_fops = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c
index 1c66da1c3fb4..03ed14663107 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c
@@ -124,7 +124,7 @@ static void amdgpu_mux_resubmit_chunks(struct amdgpu_ring_mux *mux)
}
}
- del_timer(&mux->resubmit_timer);
+ timer_delete(&mux->resubmit_timer);
mux->s_resubmit = false;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
index 6029a799074d..477424472bbe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
@@ -1172,7 +1172,7 @@ static int xgmi_v6_4_0_aca_bank_parser(struct aca_handle *handle, struct aca_ban
break;
case ACA_SMU_TYPE_CE:
count = ext_error_code == 6 ? count : 0ULL;
- bank->aca_err_type = ACA_BANK_ERR_CE_DE_DECODE(bank);
+ bank->aca_err_type = ACA_ERROR_TYPE_CE;
ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type, count);
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c
index 3c07517be09a..ae071985f26e 100644
--- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c
+++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c
@@ -473,7 +473,8 @@ static int aqua_vanjaram_get_xcp_res_info(struct amdgpu_xcp_mgr *xcp_mgr,
break;
case AMDGPU_DPX_PARTITION_MODE:
num_xcp = 2;
- nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE);
+ nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) |
+ BIT(AMDGPU_NPS2_PARTITION_MODE);
break;
case AMDGPU_TPX_PARTITION_MODE:
num_xcp = 3;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 6d514efb0a6d..a63ce747863f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -6851,22 +6851,9 @@ static int gfx_v10_0_kgq_init_queue(struct amdgpu_ring *ring, bool reset)
static int gfx_v10_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
{
int r, i;
- struct amdgpu_ring *ring;
for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
- ring = &adev->gfx.gfx_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v10_0_kgq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v10_0_kgq_init_queue(&adev->gfx.gfx_ring[i], false);
if (r)
return r;
}
@@ -7173,55 +7160,24 @@ static int gfx_v10_0_kcq_init_queue(struct amdgpu_ring *ring, bool restore)
static int gfx_v10_0_kiq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring;
- int r;
-
- ring = &adev->gfx.kiq[0].ring;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (unlikely(r != 0)) {
- amdgpu_bo_unreserve(ring->mqd_obj);
- return r;
- }
-
- gfx_v10_0_kiq_init_queue(ring);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- amdgpu_bo_unreserve(ring->mqd_obj);
+ gfx_v10_0_kiq_init_queue(&adev->gfx.kiq[0].ring);
return 0;
}
static int gfx_v10_0_kcq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring = NULL;
- int r = 0, i;
+ int i, r;
gfx_v10_0_cp_compute_enable(adev, true);
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
- ring = &adev->gfx.compute_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v10_0_kcq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v10_0_kcq_init_queue(&adev->gfx.compute_ring[i],
+ false);
if (r)
- goto done;
+ return r;
}
- r = amdgpu_gfx_enable_kcq(adev, 0);
-done:
- return r;
+ return amdgpu_gfx_enable_kcq(adev, 0);
}
static int gfx_v10_0_cp_resume(struct amdgpu_device *adev)
@@ -9579,20 +9535,9 @@ static int gfx_v10_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
if (r)
return r;
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)) {
- DRM_ERROR("fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v10_0_kgq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v10_0_kgq_init_queue(ring, true);
if (r) {
- DRM_ERROR("fail to unresv mqd_obj\n");
+ DRM_ERROR("fail to init kgq\n");
return r;
}
@@ -9649,20 +9594,9 @@ static int gfx_v10_0_reset_kcq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)) {
- dev_err(adev->dev, "fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v10_0_kcq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v10_0_kcq_init_queue(ring, true);
if (r) {
- dev_err(adev->dev, "fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "fail to init kcq\n");
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index d8772cd6db63..d57db42f9536 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -1581,7 +1581,7 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 1;
- adev->gfx.mec.num_mec = 2;
+ adev->gfx.mec.num_mec = 1;
adev->gfx.mec.num_pipe_per_mec = 4;
adev->gfx.mec.num_queue_per_pipe = 4;
break;
@@ -4115,22 +4115,9 @@ static int gfx_v11_0_kgq_init_queue(struct amdgpu_ring *ring, bool reset)
static int gfx_v11_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
{
int r, i;
- struct amdgpu_ring *ring;
for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
- ring = &adev->gfx.gfx_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v11_0_kgq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v11_0_kgq_init_queue(&adev->gfx.gfx_ring[i], false);
if (r)
return r;
}
@@ -4452,57 +4439,24 @@ static int gfx_v11_0_kcq_init_queue(struct amdgpu_ring *ring, bool reset)
static int gfx_v11_0_kiq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring;
- int r;
-
- ring = &adev->gfx.kiq[0].ring;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (unlikely(r != 0)) {
- amdgpu_bo_unreserve(ring->mqd_obj);
- return r;
- }
-
- gfx_v11_0_kiq_init_queue(ring);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- amdgpu_bo_unreserve(ring->mqd_obj);
- ring->sched.ready = true;
+ gfx_v11_0_kiq_init_queue(&adev->gfx.kiq[0].ring);
return 0;
}
static int gfx_v11_0_kcq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring = NULL;
- int r = 0, i;
+ int i, r;
if (!amdgpu_async_gfx_ring)
gfx_v11_0_cp_compute_enable(adev, true);
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
- ring = &adev->gfx.compute_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v11_0_kcq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v11_0_kcq_init_queue(&adev->gfx.compute_ring[i], false);
if (r)
- goto done;
+ return r;
}
- r = amdgpu_gfx_enable_kcq(adev, 0);
-done:
- return r;
+ return amdgpu_gfx_enable_kcq(adev, 0);
}
static int gfx_v11_0_cp_resume(struct amdgpu_device *adev)
@@ -6667,20 +6621,9 @@ static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
if (r)
return r;
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)) {
- dev_err(adev->dev, "fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v11_0_kgq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v11_0_kgq_init_queue(ring, true);
if (r) {
- dev_err(adev->dev, "fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "failed to init kgq\n");
return r;
}
@@ -6707,20 +6650,9 @@ static int gfx_v11_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid)
return r;
}
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)) {
- dev_err(adev->dev, "fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v11_0_kcq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v11_0_kcq_init_queue(ring, true);
if (r) {
- dev_err(adev->dev, "fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "fail to init kcq\n");
return r;
}
r = amdgpu_mes_map_legacy_queue(adev, ring);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index dceb5ad38862..e7b58e470292 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -1355,7 +1355,7 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 1;
- adev->gfx.mec.num_mec = 2;
+ adev->gfx.mec.num_mec = 1;
adev->gfx.mec.num_pipe_per_mec = 2;
adev->gfx.mec.num_queue_per_pipe = 4;
break;
@@ -3001,37 +3001,19 @@ static int gfx_v12_0_kgq_init_queue(struct amdgpu_ring *ring, bool reset)
static int gfx_v12_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
{
- int r, i;
- struct amdgpu_ring *ring;
+ int i, r;
for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
- ring = &adev->gfx.gfx_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v12_0_kgq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v12_0_kgq_init_queue(&adev->gfx.gfx_ring[i], false);
if (r)
- goto done;
+ return r;
}
r = amdgpu_gfx_enable_kgq(adev, 0);
if (r)
- goto done;
-
- r = gfx_v12_0_cp_gfx_start(adev);
- if (r)
- goto done;
+ return r;
-done:
- return r;
+ return gfx_v12_0_cp_gfx_start(adev);
}
static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
@@ -3344,57 +3326,25 @@ static int gfx_v12_0_kcq_init_queue(struct amdgpu_ring *ring, bool reset)
static int gfx_v12_0_kiq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring;
- int r;
-
- ring = &adev->gfx.kiq[0].ring;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (unlikely(r != 0)) {
- amdgpu_bo_unreserve(ring->mqd_obj);
- return r;
- }
-
- gfx_v12_0_kiq_init_queue(ring);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- amdgpu_bo_unreserve(ring->mqd_obj);
- ring->sched.ready = true;
+ gfx_v12_0_kiq_init_queue(&adev->gfx.kiq[0].ring);
+ adev->gfx.kiq[0].ring.sched.ready = true;
return 0;
}
static int gfx_v12_0_kcq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring = NULL;
- int r = 0, i;
+ int i, r;
if (!amdgpu_async_gfx_ring)
gfx_v12_0_cp_compute_enable(adev, true);
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
- ring = &adev->gfx.compute_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v12_0_kcq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v12_0_kcq_init_queue(&adev->gfx.compute_ring[i], false);
if (r)
- goto done;
+ return r;
}
- r = amdgpu_gfx_enable_kcq(adev, 0);
-done:
- return r;
+ return amdgpu_gfx_enable_kcq(adev, 0);
}
static int gfx_v12_0_cp_resume(struct amdgpu_device *adev)
@@ -5224,20 +5174,9 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
return r;
}
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)) {
- dev_err(adev->dev, "fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v12_0_kgq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v12_0_kgq_init_queue(ring, true);
if (r) {
- DRM_ERROR("fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "failed to init kgq\n");
return r;
}
@@ -5264,20 +5203,9 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid)
return r;
}
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)) {
- DRM_ERROR("fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v12_0_kcq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v12_0_kcq_init_queue(ring, true);
if (r) {
- DRM_ERROR("fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "failed to init kcq\n");
return r;
}
r = amdgpu_mes_map_legacy_queue(adev, ring);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index d116a2e2f469..bfedd487efc5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -4683,60 +4683,25 @@ static void gfx_v8_0_set_mec_doorbell_range(struct amdgpu_device *adev)
static int gfx_v8_0_kiq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring;
- int r;
-
- ring = &adev->gfx.kiq[0].ring;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, &ring->mqd_ptr);
- if (unlikely(r != 0)) {
- amdgpu_bo_unreserve(ring->mqd_obj);
- return r;
- }
-
- gfx_v8_0_kiq_init_queue(ring);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- amdgpu_bo_unreserve(ring->mqd_obj);
+ gfx_v8_0_kiq_init_queue(&adev->gfx.kiq[0].ring);
return 0;
}
static int gfx_v8_0_kcq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring = NULL;
- int r = 0, i;
+ int i, r;
gfx_v8_0_cp_compute_enable(adev, true);
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
- ring = &adev->gfx.compute_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
- r = amdgpu_bo_kmap(ring->mqd_obj, &ring->mqd_ptr);
- if (!r) {
- r = gfx_v8_0_kcq_init_queue(ring);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v8_0_kcq_init_queue(&adev->gfx.compute_ring[i]);
if (r)
- goto done;
+ return r;
}
gfx_v8_0_set_mec_doorbell_range(adev);
- r = gfx_v8_0_kiq_kcq_enable(adev);
- if (r)
- goto done;
-
-done:
- return r;
+ return gfx_v8_0_kiq_kcq_enable(adev);
}
static int gfx_v8_0_cp_test_all_rings(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index d345285ea885..d7db4cb907ae 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -1269,6 +1269,7 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev)
adev->gfx.mec_fw_write_wait = false;
if ((amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 1)) &&
+ (amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 2)) &&
((adev->gfx.mec_fw_version < 0x000001a5) ||
(adev->gfx.mec_feature_version < 46) ||
(adev->gfx.pfp_fw_version < 0x000000b7) ||
@@ -3890,55 +3891,23 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring, bool restore)
static int gfx_v9_0_kiq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring;
- int r;
-
- ring = &adev->gfx.kiq[0].ring;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (unlikely(r != 0)) {
- amdgpu_bo_unreserve(ring->mqd_obj);
- return r;
- }
-
- gfx_v9_0_kiq_init_queue(ring);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- amdgpu_bo_unreserve(ring->mqd_obj);
+ gfx_v9_0_kiq_init_queue(&adev->gfx.kiq[0].ring);
return 0;
}
static int gfx_v9_0_kcq_resume(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring = NULL;
- int r = 0, i;
+ int i, r;
gfx_v9_0_cp_compute_enable(adev, true);
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
- ring = &adev->gfx.compute_ring[i];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v9_0_kcq_init_queue(ring, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v9_0_kcq_init_queue(&adev->gfx.compute_ring[i], false);
if (r)
- goto done;
+ return r;
}
- r = amdgpu_gfx_enable_kcq(adev, 0);
-done:
- return r;
+ return amdgpu_gfx_enable_kcq(adev, 0);
}
static int gfx_v9_0_cp_resume(struct amdgpu_device *adev)
@@ -7319,20 +7288,9 @@ static int gfx_v9_0_reset_kcq(struct amdgpu_ring *ring,
return r;
}
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)){
- dev_err(adev->dev, "fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v9_0_kcq_init_queue(ring, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v9_0_kcq_init_queue(ring, true);
if (r) {
- dev_err(adev->dev, "fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "fail to init kcq\n");
return r;
}
spin_lock_irqsave(&kiq->ring_lock, flags);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index 736398b0d16d..53fbf6ca7cdb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -867,13 +867,12 @@ static int gfx_v9_4_3_aca_bank_parser(struct aca_handle *handle,
switch (type) {
case ACA_SMU_TYPE_UE:
- bank->aca_err_type = ACA_BANK_ERR_UE_DE_DECODE(bank);
+ bank->aca_err_type = ACA_ERROR_TYPE_UE;
ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type, 1ULL);
break;
case ACA_SMU_TYPE_CE:
- bank->aca_err_type = ACA_BANK_ERR_CE_DE_DECODE(bank);
- ret = aca_error_cache_log_bank_error(handle, &info,
- bank->aca_err_type,
+ bank->aca_err_type = ACA_ERROR_TYPE_CE;
+ ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
ACA_REG__MISC0__ERRCNT(misc0));
break;
default:
@@ -2168,55 +2167,27 @@ static int gfx_v9_4_3_xcc_kcq_fini_register(struct amdgpu_device *adev, int xcc_
static int gfx_v9_4_3_xcc_kiq_resume(struct amdgpu_device *adev, int xcc_id)
{
- struct amdgpu_ring *ring;
- int r;
-
- ring = &adev->gfx.kiq[xcc_id].ring;
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- return r;
-
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (unlikely(r != 0)) {
- amdgpu_bo_unreserve(ring->mqd_obj);
- return r;
- }
-
- gfx_v9_4_3_xcc_kiq_init_queue(ring, xcc_id);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- amdgpu_bo_unreserve(ring->mqd_obj);
+ gfx_v9_4_3_xcc_kiq_init_queue(&adev->gfx.kiq[xcc_id].ring, xcc_id);
return 0;
}
static int gfx_v9_4_3_xcc_kcq_resume(struct amdgpu_device *adev, int xcc_id)
{
- struct amdgpu_ring *ring = NULL;
- int r = 0, i;
+ struct amdgpu_ring *ring;
+ int i, r;
gfx_v9_4_3_xcc_cp_compute_enable(adev, true, xcc_id);
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
- ring = &adev->gfx.compute_ring[i + xcc_id * adev->gfx.num_compute_rings];
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto done;
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v9_4_3_xcc_kcq_init_queue(ring, xcc_id, false);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ ring = &adev->gfx.compute_ring[i + xcc_id *
+ adev->gfx.num_compute_rings];
+
+ r = gfx_v9_4_3_xcc_kcq_init_queue(ring, xcc_id, false);
if (r)
- goto done;
+ return r;
}
- r = amdgpu_gfx_enable_kcq(adev, xcc_id);
-done:
- return r;
+ return amdgpu_gfx_enable_kcq(adev, xcc_id);
}
static int gfx_v9_4_3_xcc_cp_resume(struct amdgpu_device *adev, int xcc_id)
@@ -3588,20 +3559,9 @@ pipe_reset:
return r;
}
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0)){
- dev_err(adev->dev, "fail to resv mqd_obj\n");
- return r;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr);
- if (!r) {
- r = gfx_v9_4_3_xcc_kcq_init_queue(ring, ring->xcc_id, true);
- amdgpu_bo_kunmap(ring->mqd_obj);
- ring->mqd_ptr = NULL;
- }
- amdgpu_bo_unreserve(ring->mqd_obj);
+ r = gfx_v9_4_3_xcc_kcq_init_queue(ring, ring->xcc_id, true);
if (r) {
- dev_err(adev->dev, "fail to unresv mqd_obj\n");
+ dev_err(adev->dev, "fail to init kcq\n");
return r;
}
spin_lock_irqsave(&kiq->ring_lock, flags);
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
index 5598a35f72af..a8ccae361ec7 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
@@ -1328,7 +1328,7 @@ static int jpeg_v4_0_3_aca_bank_parser(struct aca_handle *handle, struct aca_ban
1ULL);
break;
case ACA_SMU_TYPE_CE:
- bank->aca_err_type = ACA_BANK_ERR_CE_DE_DECODE(bank);
+ bank->aca_err_type = ACA_ERROR_TYPE_CE;
ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
ACA_REG__MISC0__ERRCNT(misc0));
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
index a54e7b929295..84cde1239ee4 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
@@ -751,7 +751,7 @@ static int mmhub_v1_8_aca_bank_parser(struct aca_handle *handle, struct aca_bank
1ULL);
break;
case ACA_SMU_TYPE_CE:
- bank->aca_err_type = ACA_BANK_ERR_CE_DE_DECODE(bank);
+ bank->aca_err_type = ACA_ERROR_TYPE_CE;
ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
ACA_REG__MISC0__ERRCNT(misc0));
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
index dc94d58d33a6..688a720bbbbd 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -31,7 +31,6 @@
#include "amdgpu_ucode.h"
#include "amdgpu_trace.h"
#include "amdgpu_reset.h"
-#include "gc/gc_9_0_sh_mask.h"
#include "sdma/sdma_4_4_2_offset.h"
#include "sdma/sdma_4_4_2_sh_mask.h"
@@ -1291,71 +1290,21 @@ static void sdma_v4_4_2_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
seq, 0xffffffff, 4);
}
-/*
- * sdma_v4_4_2_get_invalidate_req - Construct the VM_INVALIDATE_ENG0_REQ register value
- * @vmid: The VMID to invalidate
- * @flush_type: The type of flush (0 = legacy, 1 = lightweight, 2 = heavyweight)
- *
- * This function constructs the VM_INVALIDATE_ENG0_REQ register value for the specified VMID
- * and flush type. It ensures that all relevant page table cache levels (L1 PTEs, L2 PTEs, and
- * L2 PDEs) are invalidated.
- */
-static uint32_t sdma_v4_4_2_get_invalidate_req(unsigned int vmid,
- uint32_t flush_type)
-{
- u32 req = 0;
-
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ,
- PER_VMID_INVALIDATE_REQ, 1 << vmid);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
- req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ,
- CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0);
- return req;
-}
-
-/*
- * sdma_v4_4_2_ring_emit_vm_flush - Emit VM flush commands for SDMA
- * @ring: The SDMA ring
- * @vmid: The VMID to flush
- * @pd_addr: The page directory address
+/**
+ * sdma_v4_4_2_ring_emit_vm_flush - vm flush using sDMA
*
- * This function emits the necessary register writes and waits to perform a VM flush for the
- * specified VMID. It updates the PTB address registers and issues a VM invalidation request
- * using the specified VM invalidation engine.
+ * @ring: amdgpu_ring pointer
+ * @vmid: vmid number to use
+ * @pd_addr: address
+ *
+ * Update the page table base and flush the VM TLB
+ * using sDMA.
*/
static void sdma_v4_4_2_ring_emit_vm_flush(struct amdgpu_ring *ring,
- unsigned int vmid, uint64_t pd_addr)
+ unsigned vmid, uint64_t pd_addr)
{
- struct amdgpu_device *adev = ring->adev;
- uint32_t req = sdma_v4_4_2_get_invalidate_req(vmid, 0);
- unsigned int eng = ring->vm_inv_eng;
- struct amdgpu_vmhub *hub = &adev->vmhub[ring->vm_hub];
-
- amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 +
- (hub->ctx_addr_distance * vmid),
- lower_32_bits(pd_addr));
-
- amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_hi32 +
- (hub->ctx_addr_distance * vmid),
- upper_32_bits(pd_addr));
- /*
- * Construct and emit the VM invalidation packet
- */
- amdgpu_ring_write(ring,
- SDMA_PKT_VM_INVALIDATION_HEADER_OP(SDMA_OP_VM_INVALIDATE) |
- SDMA_PKT_VM_INVALIDATION_HEADER_SUB_OP(SDMA_SUBOP_VM_INVALIDATE) |
- SDMA_PKT_VM_INVALIDATION_HEADER_XCC0_ENG_ID(0x1f) |
- SDMA_PKT_VM_INVALIDATION_HEADER_XCC1_ENG_ID(0x1f) |
- SDMA_PKT_VM_INVALIDATION_HEADER_MMHUB_ENG_ID(eng));
- amdgpu_ring_write(ring, SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_INVALIDATEREQ(req));
- amdgpu_ring_write(ring, 0);
- amdgpu_ring_write(ring, SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_INVALIDATEACK(BIT(vmid)));
+ amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
}
static void sdma_v4_4_2_ring_emit_wreg(struct amdgpu_ring *ring,
@@ -2177,7 +2126,8 @@ static const struct amdgpu_ring_funcs sdma_v4_4_2_ring_funcs = {
3 + /* hdp invalidate */
6 + /* sdma_v4_4_2_ring_emit_pipeline_sync */
/* sdma_v4_4_2_ring_emit_vm_flush */
- 4 + 2 * 3 +
+ SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
+ SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 +
10 + 10 + 10, /* sdma_v4_4_2_ring_emit_fence x3 for user fence, vm fence */
.emit_ib_size = 7 + 6, /* sdma_v4_4_2_ring_emit_ib */
.emit_ib = sdma_v4_4_2_ring_emit_ib,
@@ -2209,7 +2159,8 @@ static const struct amdgpu_ring_funcs sdma_v4_4_2_page_ring_funcs = {
3 + /* hdp invalidate */
6 + /* sdma_v4_4_2_ring_emit_pipeline_sync */
/* sdma_v4_4_2_ring_emit_vm_flush */
- 4 + 2 * 3 +
+ SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
+ SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 +
10 + 10 + 10, /* sdma_v4_4_2_ring_emit_fence x3 for user fence, vm fence */
.emit_ib_size = 7 + 6, /* sdma_v4_4_2_ring_emit_ib */
.emit_ib = sdma_v4_4_2_ring_emit_ib,
@@ -2595,7 +2546,7 @@ static int sdma_v4_4_2_aca_bank_parser(struct aca_handle *handle, struct aca_ban
1ULL);
break;
case ACA_SMU_TYPE_CE:
- bank->aca_err_type = ACA_BANK_ERR_CE_DE_DECODE(bank);
+ bank->aca_err_type = ACA_ERROR_TYPE_CE;
ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
ACA_REG__MISC0__ERRCNT(misc0));
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h b/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
index a3b5fda22432..8a3f326474e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
@@ -92,6 +92,9 @@ enum ta_ras_block {
TA_RAS_BLOCK__MCA,
TA_RAS_BLOCK__VCN,
TA_RAS_BLOCK__JPEG,
+ TA_RAS_BLOCK__IH,
+ TA_RAS_BLOCK__MPIO,
+ TA_RAS_BLOCK__MMSCH,
TA_NUM_BLOCK_MAX
};
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
index 74f57b2d30a5..0e404c074975 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
@@ -85,7 +85,8 @@ bool umc_v12_0_is_deferred_error(struct amdgpu_device *adev, uint64_t mc_umc_sta
return (amdgpu_ras_is_poison_mode_supported(adev) &&
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
- (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1));
+ ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1) ||
+ (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Poison) == 1)));
}
bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_umc_status)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
index 7446ecc55714..3e176b4b7c69 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
@@ -1965,7 +1965,7 @@ static int vcn_v4_0_3_aca_bank_parser(struct aca_handle *handle, struct aca_bank
1ULL);
break;
case ACA_SMU_TYPE_CE:
- bank->aca_err_type = ACA_BANK_ERR_CE_DE_DECODE(bank);
+ bank->aca_err_type = ACA_ERROR_TYPE_CE;
ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
ACA_REG__MISC0__ERRCNT(misc0));
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_sdma_pkt_open.h b/drivers/gpu/drm/amd/amdgpu/vega10_sdma_pkt_open.h
index 3ca8a417c6d8..8de4ccce5e38 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_sdma_pkt_open.h
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_sdma_pkt_open.h
@@ -64,9 +64,6 @@
#define HEADER_BARRIER 5
#define SDMA_OP_AQL_COPY 0
#define SDMA_OP_AQL_BARRIER_OR 0
-/* vm invalidation is only available for GC9.4.3/GC9.4.4/GC9.5.0 */
-#define SDMA_OP_VM_INVALIDATE 8
-#define SDMA_SUBOP_VM_INVALIDATE 4
/*define for op field*/
#define SDMA_PKT_HEADER_op_offset 0
@@ -3334,72 +3331,5 @@
#define SDMA_AQL_PKT_BARRIER_OR_COMPLETION_SIGNAL_HI_completion_signal_63_32_shift 0
#define SDMA_AQL_PKT_BARRIER_OR_COMPLETION_SIGNAL_HI_COMPLETION_SIGNAL_63_32(x) (((x) & SDMA_AQL_PKT_BARRIER_OR_COMPLETION_SIGNAL_HI_completion_signal_63_32_mask) << SDMA_AQL_PKT_BARRIER_OR_COMPLETION_SIGNAL_HI_completion_signal_63_32_shift)
-/*
-** Definitions for SDMA_PKT_VM_INVALIDATION packet
-*/
-
-/*define for HEADER word*/
-/*define for op field*/
-#define SDMA_PKT_VM_INVALIDATION_HEADER_op_offset 0
-#define SDMA_PKT_VM_INVALIDATION_HEADER_op_mask 0x000000FF
-#define SDMA_PKT_VM_INVALIDATION_HEADER_op_shift 0
-#define SDMA_PKT_VM_INVALIDATION_HEADER_OP(x) ((x & SDMA_PKT_VM_INVALIDATION_HEADER_op_mask) << SDMA_PKT_VM_INVALIDATION_HEADER_op_shift)
-
-/*define for sub_op field*/
-#define SDMA_PKT_VM_INVALIDATION_HEADER_sub_op_offset 0
-#define SDMA_PKT_VM_INVALIDATION_HEADER_sub_op_mask 0x000000FF
-#define SDMA_PKT_VM_INVALIDATION_HEADER_sub_op_shift 8
-#define SDMA_PKT_VM_INVALIDATION_HEADER_SUB_OP(x) ((x & SDMA_PKT_VM_INVALIDATION_HEADER_sub_op_mask) << SDMA_PKT_VM_INVALIDATION_HEADER_sub_op_shift)
-
-/*define for xcc0_eng_id field*/
-#define SDMA_PKT_VM_INVALIDATION_HEADER_xcc0_eng_id_offset 0
-#define SDMA_PKT_VM_INVALIDATION_HEADER_xcc0_eng_id_mask 0x0000001F
-#define SDMA_PKT_VM_INVALIDATION_HEADER_xcc0_eng_id_shift 16
-#define SDMA_PKT_VM_INVALIDATION_HEADER_XCC0_ENG_ID(x) ((x & SDMA_PKT_VM_INVALIDATION_HEADER_xcc0_eng_id_mask) << SDMA_PKT_VM_INVALIDATION_HEADER_xcc0_eng_id_shift)
-
-/*define for xcc1_eng_id field*/
-#define SDMA_PKT_VM_INVALIDATION_HEADER_xcc1_eng_id_offset 0
-#define SDMA_PKT_VM_INVALIDATION_HEADER_xcc1_eng_id_mask 0x0000001F
-#define SDMA_PKT_VM_INVALIDATION_HEADER_xcc1_eng_id_shift 21
-#define SDMA_PKT_VM_INVALIDATION_HEADER_XCC1_ENG_ID(x) ((x & SDMA_PKT_VM_INVALIDATION_HEADER_xcc1_eng_id_mask) << SDMA_PKT_VM_INVALIDATION_HEADER_xcc1_eng_id_shift)
-
-/*define for mmhub_eng_id field*/
-#define SDMA_PKT_VM_INVALIDATION_HEADER_mmhub_eng_id_offset 0
-#define SDMA_PKT_VM_INVALIDATION_HEADER_mmhub_eng_id_mask 0x0000001F
-#define SDMA_PKT_VM_INVALIDATION_HEADER_mmhub_eng_id_shift 26
-#define SDMA_PKT_VM_INVALIDATION_HEADER_MMHUB_ENG_ID(x) ((x & SDMA_PKT_VM_INVALIDATION_HEADER_mmhub_eng_id_mask) << SDMA_PKT_VM_INVALIDATION_HEADER_mmhub_eng_id_shift)
-
-/*define for INVALIDATEREQ word*/
-/*define for invalidatereq field*/
-#define SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_invalidatereq_offset 1
-#define SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_invalidatereq_mask 0xFFFFFFFF
-#define SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_invalidatereq_shift 0
-#define SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_INVALIDATEREQ(x) ((x & SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_invalidatereq_mask) << SDMA_PKT_VM_INVALIDATION_INVALIDATEREQ_invalidatereq_shift)
-
-/*define for ADDRESSRANGELO word*/
-/*define for addressrangelo field*/
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGELO_addressrangelo_offset 2
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGELO_addressrangelo_mask 0xFFFFFFFF
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGELO_addressrangelo_shift 0
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGELO_ADDRESSRANGELO(x) ((x & SDMA_PKT_VM_INVALIDATION_ADDRESSRANGELO_addressrangelo_mask) << SDMA_PKT_VM_INVALIDATION_ADDRESSRANGELO_addressrangelo_shift)
-
-/*define for ADDRESSRANGEHI word*/
-/*define for invalidateack field*/
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_invalidateack_offset 3
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_invalidateack_mask 0x0000FFFF
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_invalidateack_shift 0
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_INVALIDATEACK(x) ((x & SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_invalidateack_mask) << SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_invalidateack_shift)
-
-/*define for addressrangehi field*/
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_addressrangehi_offset 3
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_addressrangehi_mask 0x0000001F
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_addressrangehi_shift 16
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_ADDRESSRANGEHI(x) ((x & SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_addressrangehi_mask) << SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_addressrangehi_shift)
-
-/*define for reserved field*/
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_reserved_offset 3
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_reserved_mask 0x000001FF
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_reserved_shift 23
-#define SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_RESERVED(x) ((x & SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_reserved_mask) << SDMA_PKT_VM_INVALIDATION_ADDRESSRANGEHI_reserved_shift)
#endif /* __SDMA_PKT_OPEN_H_ */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index bae83a129b5f..d0d8ad5368c3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8707,14 +8707,39 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
int offdelay;
if (acrtc_state) {
- if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
- IP_VERSION(3, 5, 0) ||
- acrtc_state->stream->link->psr_settings.psr_version <
- DC_PSR_VERSION_UNSUPPORTED ||
- !(adev->flags & AMD_IS_APU)) {
- timing = &acrtc_state->stream->timing;
-
- /* at least 2 frames */
+ timing = &acrtc_state->stream->timing;
+
+ /*
+ * Depending on when the HW latching event of double-buffered
+ * registers happen relative to the PSR SDP deadline, and how
+ * bad the Panel clock has drifted since the last ALPM off
+ * event, there can be up to 3 frames of delay between sending
+ * the PSR exit cmd to DMUB fw, and when the panel starts
+ * displaying live frames.
+ *
+ * We can set:
+ *
+ * 20/100 * offdelay_ms = 3_frames_ms
+ * => offdelay_ms = 5 * 3_frames_ms
+ *
+ * This ensures that `3_frames_ms` will only be experienced as a
+ * 20% delay on top how long the display has been static, and
+ * thus make the delay less perceivable.
+ */
+ if (acrtc_state->stream->link->psr_settings.psr_version <
+ DC_PSR_VERSION_UNSUPPORTED) {
+ offdelay = DIV64_U64_ROUND_UP((u64)5 * 3 * 10 *
+ timing->v_total *
+ timing->h_total,
+ timing->pix_clk_100hz);
+ config.offdelay_ms = offdelay ?: 30;
+ } else if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
+ IP_VERSION(3, 5, 0) ||
+ !(adev->flags & AMD_IS_APU)) {
+ /*
+ * Older HW and DGPU have issues with instant off;
+ * use a 2 frame offdelay.
+ */
offdelay = DIV64_U64_ROUND_UP((u64)20 *
timing->v_total *
timing->h_total,
@@ -8722,6 +8747,8 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
config.offdelay_ms = offdelay ?: 30;
} else {
+ /* offdelay_ms = 0 will never disable vblank */
+ config.offdelay_ms = 1;
config.disable_immediate = true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
index 70c39df62533..2061d43b92e1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -590,11 +590,11 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc,
p->out_states->state_array[i].dtbclk_mhz = max_dtbclk_mhz;
p->out_states->state_array[i].phyclk_mhz = max_phyclk_mhz;
+ p->out_states->state_array[i].dscclk_mhz = max_dispclk_mhz / 3.0;
p->out_states->state_array[i].phyclk_mhz = max_phyclk_mhz;
p->out_states->state_array[i].dtbclk_mhz = max_dtbclk_mhz;
/* Dependent states. */
- p->out_states->state_array[i].dscclk_mhz = p->in_states->state_array[i].dscclk_mhz;
p->out_states->state_array[i].dram_speed_mts = p->in_states->state_array[i].dram_speed_mts;
p->out_states->state_array[i].fabricclk_mhz = p->in_states->state_array[i].fabricclk_mhz;
p->out_states->state_array[i].socclk_mhz = p->in_states->state_array[i].socclk_mhz;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 926c08e790c1..846c9c51f2d9 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -3033,7 +3033,11 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
phyd32clk = get_phyd32clk_src(link);
- dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+ if (link->cur_link_settings.link_rate == LINK_RATE_UNKNOWN) {
+ dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
+ } else {
+ dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+ }
} else {
if (dccg->funcs->enable_symclk_se)
dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 8f5da0ded850..5489f3d431f6 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -936,8 +936,11 @@ void dcn401_enable_stream(struct pipe_ctx *pipe_ctx)
if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
dccg->funcs->set_dpstreamclk(dccg, DPREFCLK, tg->inst, dp_hpo_inst);
-
- dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+ if (link->cur_link_settings.link_rate == LINK_RATE_UNKNOWN) {
+ dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
+ } else {
+ dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+ }
} else {
dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst,
link_enc->transmitter - TRANSMITTER_UNIPHY_A);
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 9189dcb65188..2a9606118d89 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -341,6 +341,7 @@ enum pp_policy_soc_pstate {
#define MAX_CLKS 4
#define NUM_VCN 4
#define NUM_JPEG_ENG 32
+#define NUM_JPEG_ENG_V1 40
#define MAX_XCC 8
#define NUM_XCP 8
struct seq_file;
@@ -376,6 +377,20 @@ struct amdgpu_xcp_metrics_v1_1 {
uint64_t gfx_below_host_limit_acc[MAX_XCC];
};
+struct amdgpu_xcp_metrics_v1_2 {
+ /* Utilization Instantaneous (%) */
+ uint32_t gfx_busy_inst[MAX_XCC];
+ uint16_t jpeg_busy[NUM_JPEG_ENG_V1];
+ uint16_t vcn_busy[NUM_VCN];
+ /* Utilization Accumulated (%) */
+ uint64_t gfx_busy_acc[MAX_XCC];
+ /* Total App Clock Counter Accumulated */
+ uint64_t gfx_below_host_limit_ppt_acc[MAX_XCC];
+ uint64_t gfx_below_host_limit_thm_acc[MAX_XCC];
+ uint64_t gfx_low_utilization_acc[MAX_XCC];
+ uint64_t gfx_below_host_limit_total_acc[MAX_XCC];
+};
+
struct amd_pm_funcs {
/* export for dpm on ci and si */
int (*pre_set_power_state)(void *handle);
@@ -1090,6 +1105,105 @@ struct gpu_metrics_v1_7 {
uint32_t pcie_lc_perf_other_end_recovery;
};
+struct gpu_metrics_v1_8 {
+ struct metrics_table_header common_header;
+
+ /* Temperature (Celsius) */
+ uint16_t temperature_hotspot;
+ uint16_t temperature_mem;
+ uint16_t temperature_vrsoc;
+
+ /* Power (Watts) */
+ uint16_t curr_socket_power;
+
+ /* Utilization (%) */
+ uint16_t average_gfx_activity;
+ uint16_t average_umc_activity; // memory controller
+
+ /* VRAM max bandwidthi (in GB/sec) at max memory clock */
+ uint64_t mem_max_bandwidth;
+
+ /* Energy (15.259uJ (2^-16) units) */
+ uint64_t energy_accumulator;
+
+ /* Driver attached timestamp (in ns) */
+ uint64_t system_clock_counter;
+
+ /* Accumulation cycle counter */
+ uint32_t accumulation_counter;
+
+ /* Accumulated throttler residencies */
+ uint32_t prochot_residency_acc;
+ uint32_t ppt_residency_acc;
+ uint32_t socket_thm_residency_acc;
+ uint32_t vr_thm_residency_acc;
+ uint32_t hbm_thm_residency_acc;
+
+ /* Clock Lock Status. Each bit corresponds to clock instance */
+ uint32_t gfxclk_lock_status;
+
+ /* Link width (number of lanes) and speed (in 0.1 GT/s) */
+ uint16_t pcie_link_width;
+ uint16_t pcie_link_speed;
+
+ /* XGMI bus width and bitrate (in Gbps) */
+ uint16_t xgmi_link_width;
+ uint16_t xgmi_link_speed;
+
+ /* Utilization Accumulated (%) */
+ uint32_t gfx_activity_acc;
+ uint32_t mem_activity_acc;
+
+ /*PCIE accumulated bandwidth (GB/sec) */
+ uint64_t pcie_bandwidth_acc;
+
+ /*PCIE instantaneous bandwidth (GB/sec) */
+ uint64_t pcie_bandwidth_inst;
+
+ /* PCIE L0 to recovery state transition accumulated count */
+ uint64_t pcie_l0_to_recov_count_acc;
+
+ /* PCIE replay accumulated count */
+ uint64_t pcie_replay_count_acc;
+
+ /* PCIE replay rollover accumulated count */
+ uint64_t pcie_replay_rover_count_acc;
+
+ /* PCIE NAK sent accumulated count */
+ uint32_t pcie_nak_sent_count_acc;
+
+ /* PCIE NAK received accumulated count */
+ uint32_t pcie_nak_rcvd_count_acc;
+
+ /* XGMI accumulated data transfer size(KiloBytes) */
+ uint64_t xgmi_read_data_acc[NUM_XGMI_LINKS];
+ uint64_t xgmi_write_data_acc[NUM_XGMI_LINKS];
+
+ /* XGMI link status(active/inactive) */
+ uint16_t xgmi_link_status[NUM_XGMI_LINKS];
+
+ uint16_t padding;
+
+ /* PMFW attached timestamp (10ns resolution) */
+ uint64_t firmware_timestamp;
+
+ /* Current clocks (Mhz) */
+ uint16_t current_gfxclk[MAX_GFX_CLKS];
+ uint16_t current_socclk[MAX_CLKS];
+ uint16_t current_vclk0[MAX_CLKS];
+ uint16_t current_dclk0[MAX_CLKS];
+ uint16_t current_uclk;
+
+ /* Number of current partition */
+ uint16_t num_partition;
+
+ /* XCP metrics stats */
+ struct amdgpu_xcp_metrics_v1_2 xcp_stats[NUM_XCP];
+
+ /* PCIE other end recovery counter */
+ uint32_t pcie_lc_perf_other_end_recovery;
+};
+
/*
* gpu_metrics_v2_0 is not recommended as it's not naturally aligned.
* Use gpu_metrics_v2_1 or later instead.
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c
index a8fc0fa44db6..ba5c1237fcfe 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c
@@ -267,10 +267,10 @@ int smu7_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
if (hwmgr->thermal_controller.fanInfo.bNoFan ||
(hwmgr->thermal_controller.fanInfo.
ucTachometerPulsesPerRevolution == 0) ||
- speed == 0 ||
+ (!speed || speed > UINT_MAX/8) ||
(speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) ||
(speed > hwmgr->thermal_controller.fanInfo.ulMaxRPM))
- return 0;
+ return -EINVAL;
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
smu7_fan_ctrl_stop_smc_fan_control(hwmgr);
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
index 379012494da5..56423aedf3fa 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
@@ -307,10 +307,10 @@ int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
int result = 0;
if (hwmgr->thermal_controller.fanInfo.bNoFan ||
- speed == 0 ||
+ (!speed || speed > UINT_MAX/8) ||
(speed < hwmgr->thermal_controller.fanInfo.ulMinRPM) ||
(speed > hwmgr->thermal_controller.fanInfo.ulMaxRPM))
- return -1;
+ return -EINVAL;
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
result = vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c
index a3331ffb2daf..1b1c88590156 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c
@@ -191,7 +191,7 @@ int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
uint32_t tach_period, crystal_clock_freq;
int result = 0;
- if (!speed)
+ if (!speed || speed > UINT_MAX/8)
return -EINVAL;
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h
index f8ed45857878..d26f35119a12 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h
@@ -127,7 +127,7 @@ typedef enum {
VOLTAGE_GUARDBAND_COUNT
} GFX_GUARDBAND_e;
-#define SMU_METRICS_TABLE_VERSION 0xF
+#define SMU_METRICS_TABLE_VERSION 0x10
// Unified metrics table for smu_v13_0_6
typedef struct __attribute__((packed, aligned(4))) {
@@ -241,7 +241,10 @@ typedef struct __attribute__((packed, aligned(4))) {
uint32_t PCIeOtherEndRecoveryAcc; // The Pcie counter itself is accumulated
//Total App Clock Counter
- uint64_t GfxclkBelowHostLimitAcc[8];
+ uint64_t GfxclkBelowHostLimitPptAcc[8];
+ uint64_t GfxclkBelowHostLimitThmAcc[8];
+ uint64_t GfxclkBelowHostLimitTotalAcc[8];
+ uint64_t GfxclkLowUtilizationAcc[8];
} MetricsTableV0_t;
// Metrics table for smu_v13_0_6 APUS
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
index 8aa61a9f7778..453952cdc353 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
@@ -1267,6 +1267,9 @@ static int arcturus_set_fan_speed_rpm(struct smu_context *smu,
uint32_t crystal_clock_freq = 2500;
uint32_t tach_period;
+ if (!speed || speed > UINT_MAX/8)
+ return -EINVAL;
+
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
WREG32_SOC15(THM, 0, mmCG_TACH_CTRL_ARCT,
REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL_ARCT),
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index 0915d6377613..ba5a9012dbd5 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -1226,7 +1226,7 @@ int smu_v13_0_set_fan_speed_rpm(struct smu_context *smu,
uint32_t tach_period;
int ret;
- if (!speed)
+ if (!speed || speed > UINT_MAX/8)
return -EINVAL;
ret = smu_v13_0_auto_fan_control(smu, 0);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
index 682646068000..c478b3be37af 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
@@ -109,7 +109,6 @@ enum smu_v13_0_6_caps {
SMU_CAP(OTHER_END_METRICS),
SMU_CAP(SET_UCLK_MAX),
SMU_CAP(PCIE_METRICS),
- SMU_CAP(HST_LIMIT_METRICS),
SMU_CAP(MCA_DEBUG_MODE),
SMU_CAP(PER_INST_METRICS),
SMU_CAP(CTF_LIMIT),
@@ -325,8 +324,6 @@ static void smu_v13_0_14_init_caps(struct smu_context *smu)
if (fw_ver >= 0x05550E00)
smu_v13_0_6_cap_set(smu, SMU_CAP(OTHER_END_METRICS));
- if (fw_ver >= 0x05551000)
- smu_v13_0_6_cap_set(smu, SMU_CAP(HST_LIMIT_METRICS));
if (fw_ver >= 0x05550B00)
smu_v13_0_6_cap_set(smu, SMU_CAP(PER_INST_METRICS));
if (fw_ver >= 0x5551200)
@@ -342,7 +339,6 @@ static void smu_v13_0_12_init_caps(struct smu_context *smu)
SMU_CAP(RMA_MSG),
SMU_CAP(ACA_SYND),
SMU_CAP(OTHER_END_METRICS),
- SMU_CAP(HST_LIMIT_METRICS),
SMU_CAP(PER_INST_METRICS) };
uint32_t fw_ver = smu->smc_fw_version;
@@ -387,8 +383,6 @@ static void smu_v13_0_6_init_caps(struct smu_context *smu)
smu_v13_0_6_cap_clear(smu, SMU_CAP(RMA_MSG));
smu_v13_0_6_cap_clear(smu, SMU_CAP(ACA_SYND));
- if (fw_ver >= 0x04556F00)
- smu_v13_0_6_cap_set(smu, SMU_CAP(HST_LIMIT_METRICS));
if (fw_ver >= 0x04556A00)
smu_v13_0_6_cap_set(smu, SMU_CAP(PER_INST_METRICS));
} else {
@@ -408,8 +402,6 @@ static void smu_v13_0_6_init_caps(struct smu_context *smu)
smu_v13_0_6_cap_clear(smu, SMU_CAP(RMA_MSG));
if (fw_ver < 0x00555600)
smu_v13_0_6_cap_clear(smu, SMU_CAP(ACA_SYND));
- if (pgm == 0 && fw_ver >= 0x557900)
- smu_v13_0_6_cap_set(smu, SMU_CAP(HST_LIMIT_METRICS));
}
if (((pgm == 7) && (fw_ver >= 0x7550700)) ||
((pgm == 0) && (fw_ver >= 0x00557900)) ||
@@ -2674,13 +2666,6 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table
gpu_metrics->xcp_stats[i].gfx_busy_acc[idx] =
SMUQ10_ROUND(GET_GPU_METRIC_FIELD(GfxBusyAcc,
version)[inst]);
-
- if (smu_v13_0_6_cap_supported(
- smu, SMU_CAP(HST_LIMIT_METRICS)))
- gpu_metrics->xcp_stats[i].gfx_below_host_limit_acc[idx] =
- SMUQ10_ROUND(GET_GPU_METRIC_FIELD
- (GfxclkBelowHostLimitAcc, version)
- [inst]);
idx++;
}
}
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 f7cfe1f35cae..82c2db972491 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
@@ -79,6 +79,7 @@
#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
+#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
static struct cmn2asic_msg_mapping smu_v14_0_2_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
@@ -1052,6 +1053,10 @@ static void smu_v14_0_2_get_od_setting_limits(struct smu_context *smu,
od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
od_max_setting = overdrive_upperlimits->FanMinimumPwm;
break;
+ case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
+ od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
+ od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
+ break;
default:
od_min_setting = od_max_setting = INT_MAX;
break;
@@ -1330,6 +1335,24 @@ static int smu_v14_0_2_print_clk_levels(struct smu_context *smu,
min_value, max_value);
break;
+ case SMU_OD_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v14_0_2_is_od_feature_supported(smu,
+ PP_OD_FEATURE_ZERO_FAN_BIT))
+ break;
+
+ size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
+ size += sysfs_emit_at(buf, size, "%d\n",
+ (int)od_table->OverDriveTable.FanZeroRpmEnable);
+
+ size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
+ smu_v14_0_2_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &min_value,
+ &max_value);
+ size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
+ min_value, max_value);
+ break;
+
case SMU_OD_RANGE:
if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
@@ -2270,7 +2293,9 @@ static void smu_v14_0_2_set_supported_od_feature_mask(struct smu_context *smu)
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
- OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET;
+ OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
+ OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
}
static int smu_v14_0_2_get_overdrive_table(struct smu_context *smu,
@@ -2349,6 +2374,8 @@ static int smu_v14_0_2_set_default_od_settings(struct smu_context *smu)
user_od_table_bak.OverDriveTable.FanTargetTemperature;
user_od_table->OverDriveTable.FanMinimumPwm =
user_od_table_bak.OverDriveTable.FanMinimumPwm;
+ user_od_table->OverDriveTable.FanZeroRpmEnable =
+ user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
}
smu_v14_0_2_set_supported_od_feature_mask(smu);
@@ -2396,6 +2423,11 @@ 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);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ od_table->OverDriveTable.FanZeroRpmEnable =
+ boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
case PP_OD_EDIT_ACOUSTIC_LIMIT:
od_table->OverDriveTable.AcousticLimitRpmThreshold =
boot_overdrive_table->OverDriveTable.AcousticLimitRpmThreshold;
@@ -2678,6 +2710,27 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
+ case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
+ if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
+ dev_warn(adev->dev, "Zero RPM setting not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ smu_v14_0_2_get_od_setting_limits(smu,
+ PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
+ &minimum,
+ &maximum);
+ if (input[0] < minimum ||
+ input[0] > maximum) {
+ dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
+ input[0], minimum, maximum);
+ return -EINVAL;
+ }
+
+ od_table->OverDriveTable.FanZeroRpmEnable = input[0];
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ break;
+
case PP_OD_RESTORE_DEFAULT_TABLE:
if (size == 1) {
ret = smu_v14_0_2_od_restore_table_single(smu, input[0]);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index d834d134ad2b..80eb1a03b3ca 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -1083,6 +1083,9 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev)
case METRICS_VERSION(1, 7):
structure_size = sizeof(struct gpu_metrics_v1_7);
break;
+ case METRICS_VERSION(1, 8):
+ structure_size = sizeof(struct gpu_metrics_v1_8);
+ break;
case METRICS_VERSION(2, 0):
structure_size = sizeof(struct gpu_metrics_v2_0);
break;
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index d20f1646dac2..09a1be234f71 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -91,12 +91,13 @@ config DRM_FSL_LDB
Support for i.MX8MP DPI-to-LVDS on-SoC encoder.
config DRM_I2C_NXP_TDA998X
- tristate "NXP Semiconductors TDA998X HDMI encoder"
- default m if DRM_TILCDC
- select CEC_CORE if CEC_NOTIFIER
- select SND_SOC_HDMI_CODEC if SND_SOC
- help
- Support for NXP Semiconductors TDA998X HDMI encoders.
+ tristate "NXP Semiconductors TDA998X HDMI encoder"
+ default m if DRM_TILCDC
+ select CEC_CORE if CEC_NOTIFIER
+ select DRM_KMS_HELPER
+ select SND_SOC_HDMI_CODEC if SND_SOC
+ help
+ Support for NXP Semiconductors TDA998X HDMI encoders.
config DRM_ITE_IT6263
tristate "ITE IT6263 LVDS/HDMI bridge"
diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c
index ebc758c72891..20658258fb51 100644
--- a/drivers/gpu/drm/bridge/tda998x_drv.c
+++ b/drivers/gpu/drm/bridge/tda998x_drv.c
@@ -1763,7 +1763,7 @@ static void tda998x_destroy(struct device *dev)
if (priv->hdmi->irq)
free_irq(priv->hdmi->irq, priv);
- del_timer_sync(&priv->edid_delay_timer);
+ timer_delete_sync(&priv->edid_delay_timer);
cancel_work_sync(&priv->detect_work);
i2c_unregister_device(priv->cec);
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 94e45ed6869d..78958ddf8485 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -508,7 +508,7 @@ static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
drm_core_check_feature(dev, DRIVER_MODESET));
drm_vblank_destroy_worker(vblank);
- del_timer_sync(&vblank->disable_timer);
+ timer_delete_sync(&vblank->disable_timer);
}
/**
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index fd388b1dbe68..08cf79a62025 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -427,7 +427,7 @@ static void vidi_unbind(struct device *dev, struct device *master, void *data)
{
struct vidi_context *ctx = dev_get_drvdata(dev);
- del_timer_sync(&ctx->timer);
+ timer_delete_sync(&ctx->timer);
}
static const struct component_ops vidi_component_ops = {
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index e163649816d5..77cfcf37ddd2 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -254,7 +254,7 @@ static int gud_usb_bulk(struct gud_device *gdrm, size_t len)
usb_sg_wait(&ctx.sgr);
- if (!del_timer_sync(&ctx.timer))
+ if (!timer_delete_sync(&ctx.timer))
ret = -ETIMEDOUT;
else if (ctx.sgr.status < 0)
ret = ctx.sgr.status;
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h
index ca2c8c438f02..89bad3a2b01a 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
@@ -6,6 +6,8 @@
#ifndef __INTEL_FBDEV_H__
#define __INTEL_FBDEV_H__
+#include <linux/types.h>
+
struct drm_fb_helper;
struct drm_fb_helper_surface_size;
struct drm_i915_private;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 2d0de1c63308..621e97943542 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2314,6 +2314,7 @@ cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state)
static int
dsc_prefill_latency(const struct intel_crtc_state *crtc_state)
{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal,
@@ -2323,7 +2324,9 @@ dsc_prefill_latency(const struct intel_crtc_state *crtc_state)
crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1;
u32 dsc_prefill_latency = 0;
- if (!crtc_state->dsc.compression_enable || !num_scaler_users)
+ if (!crtc_state->dsc.compression_enable ||
+ !num_scaler_users ||
+ num_scaler_users > crtc->num_scalers)
return dsc_prefill_latency;
dsc_prefill_latency = DIV_ROUND_UP(15 * linetime * chroma_downscaling_factor, 10);
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 4a80ffa1b962..03baa7fa0a27 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -2502,7 +2502,7 @@ static void execlists_irq_handler(struct intel_engine_cs *engine, u16 iir)
ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI));
ENGINE_TRACE(engine, "semaphore yield: %08x\n",
engine->execlists.yield);
- if (del_timer(&engine->execlists.timer))
+ if (timer_delete(&engine->execlists.timer))
tasklet = true;
}
@@ -3370,8 +3370,8 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine)
static void execlists_shutdown(struct intel_engine_cs *engine)
{
/* Synchronise with residual timers and any softirq they raise */
- del_timer_sync(&engine->execlists.timer);
- del_timer_sync(&engine->execlists.preempt);
+ timer_delete_sync(&engine->execlists.timer);
+ timer_delete_sync(&engine->execlists.preempt);
tasklet_kill(&engine->sched_engine->tasklet);
}
diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c
index 2cfaedb04876..64e9317f58fb 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -161,7 +161,7 @@ static void rps_start_timer(struct intel_rps *rps)
static void rps_stop_timer(struct intel_rps *rps)
{
- del_timer_sync(&rps->timer);
+ timer_delete_sync(&rps->timer);
rps->pm_timestamp = ktime_sub(ktime_get(), rps->pm_timestamp);
cancel_work_sync(&rps->work);
}
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index c0637bf799a3..64315b714743 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -297,7 +297,7 @@ static void mock_reset_cancel(struct intel_engine_cs *engine)
struct i915_request *rq;
unsigned long flags;
- del_timer_sync(&mock->hw_delay);
+ timer_delete_sync(&mock->hw_delay);
spin_lock_irqsave(&engine->sched_engine->lock, flags);
@@ -432,7 +432,7 @@ void mock_engine_flush(struct intel_engine_cs *engine)
container_of(engine, typeof(*mock), base);
struct i915_request *request, *rn;
- del_timer_sync(&mock->hw_delay);
+ timer_delete_sync(&mock->hw_delay);
spin_lock_irq(&mock->hw_lock);
list_for_each_entry_safe(request, rn, &mock->hw_queue, mock.link)
diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
index d7717de17ecc..0454eb1814bb 100644
--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
+++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
@@ -1198,7 +1198,7 @@ static int live_timeslice_rewind(void *arg)
ENGINE_TRACE(engine, "forcing tasklet for rewind\n");
while (i915_request_is_active(rq[A2])) { /* semaphore yield! */
/* Wait for the timeslice to kick in */
- del_timer(&engine->execlists.timer);
+ timer_delete(&engine->execlists.timer);
tasklet_hi_schedule(&engine->sched_engine->tasklet);
intel_engine_flush_submission(engine);
}
@@ -2357,7 +2357,7 @@ static int __cancel_fail(struct live_preempt_cancel *arg)
/* force preempt reset [failure] */
while (!engine->execlists.pending[0])
intel_engine_flush_submission(engine);
- del_timer_sync(&engine->execlists.preempt);
+ timer_delete_sync(&engine->execlists.preempt);
intel_engine_flush_submission(engine);
cancel_reset_timeout(engine);
diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c
index 1bf7b88d9a9d..401bee030dbc 100644
--- a/drivers/gpu/drm/i915/gt/selftest_migrate.c
+++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c
@@ -660,7 +660,7 @@ static int live_emit_pte_full_ring(void *arg)
out_rq:
i915_request_add(rq); /* GEM_BUG_ON(rq->reserved_space > ring->space)? */
- del_timer_sync(&st.timer);
+ timer_delete_sync(&st.timer);
destroy_timer_on_stack(&st.timer);
out_unpin:
intel_context_unpin(ce);
diff --git a/drivers/gpu/drm/i915/i915_iosf_mbi.h b/drivers/gpu/drm/i915/i915_iosf_mbi.h
index 8f81b7603d37..317075d0da4e 100644
--- a/drivers/gpu/drm/i915/i915_iosf_mbi.h
+++ b/drivers/gpu/drm/i915/i915_iosf_mbi.h
@@ -31,12 +31,6 @@ iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(struct notifier_block *nb)
{
return 0;
}
-
-static inline
-int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb)
-{
- return 0;
-}
#endif
#endif /* __I915_IOSF_MBI_H__ */
diff --git a/drivers/gpu/drm/i915/i915_utils.c b/drivers/gpu/drm/i915/i915_utils.c
index 2576f8f6c0f6..b60c28fbd207 100644
--- a/drivers/gpu/drm/i915/i915_utils.c
+++ b/drivers/gpu/drm/i915/i915_utils.c
@@ -52,7 +52,7 @@ void cancel_timer(struct timer_list *t)
if (!timer_active(t))
return;
- del_timer(t);
+ timer_delete(t);
WRITE_ONCE(t->expires, 0);
}
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index 87f246047312..07e81be4d392 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -163,7 +163,7 @@ void intel_wakeref_auto(struct intel_wakeref_auto *wf, unsigned long timeout)
unsigned long flags;
if (!timeout) {
- if (del_timer_sync(&wf->timer))
+ if (timer_delete_sync(&wf->timer))
wakeref_auto_timeout(&wf->timer);
return;
}
diff --git a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c
index bf2752cc1e0b..d5ecc68155da 100644
--- a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c
+++ b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c
@@ -74,7 +74,7 @@ void timed_fence_init(struct timed_fence *tf, unsigned long expires)
void timed_fence_fini(struct timed_fence *tf)
{
- if (del_timer_sync(&tf->timer))
+ if (timer_delete_sync(&tf->timer))
i915_sw_fence_commit(&tf->fence);
destroy_timer_on_stack(&tf->timer);
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index ccdc57cef3ea..fed3307d3374 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -2847,7 +2847,7 @@ static void mtk_dp_remove(struct platform_device *pdev)
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP)
- del_timer_sync(&mtk_dp->debounce_timer);
+ timer_delete_sync(&mtk_dp->debounce_timer);
platform_device_unregister(mtk_dp->phy_dev);
if (mtk_dp->audio_pdev)
platform_device_unregister(mtk_dp->audio_pdev);
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 71dca78cd7a5..650e5bac225f 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1253,7 +1253,7 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
gpu_read(gpu, REG_A5XX_CP_IB2_BUFSZ));
/* Turn off the hangcheck timer to keep it from bothering us */
- del_timer(&gpu->hangcheck_timer);
+ timer_delete(&gpu->hangcheck_timer);
kthread_queue_work(gpu->worker, &gpu->recover_work);
}
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
index 0469fea55010..36f72c43eae8 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
@@ -182,7 +182,7 @@ void a5xx_preempt_irq(struct msm_gpu *gpu)
return;
/* Delete the preemption watchdog timer */
- del_timer(&a5xx_gpu->preempt_timer);
+ timer_delete(&a5xx_gpu->preempt_timer);
/*
* The hardware should be setting CP_CONTEXT_SWITCH_CNTL to zero before
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 38c94915d4c9..c8711938a5f4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -28,7 +28,7 @@ static void a6xx_gmu_fault(struct a6xx_gmu *gmu)
gmu->hung = true;
/* Turn off the hangcheck timer while we are resetting */
- del_timer(&gpu->hangcheck_timer);
+ timer_delete(&gpu->hangcheck_timer);
/* Queue the GPU handler because we need to treat this as a recovery */
kthread_queue_work(gpu->worker, &gpu->recover_work);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 1820c167fcee..06465bc2d0b4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1706,7 +1706,7 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
gpu_read(gpu, REG_A6XX_CP_IB2_REM_SIZE));
/* Turn off the hangcheck timer to keep it from bothering us */
- del_timer(&gpu->hangcheck_timer);
+ timer_delete(&gpu->hangcheck_timer);
kthread_queue_work(gpu->worker, &gpu->recover_work);
}
@@ -1726,7 +1726,7 @@ static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
*/
if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
- del_timer(&gpu->hangcheck_timer);
+ timer_delete(&gpu->hangcheck_timer);
kthread_queue_work(gpu->worker, &gpu->recover_work);
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_preempt.c b/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
index 2fd4e39f618f..9b5e27d2373c 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
@@ -146,7 +146,7 @@ void a6xx_preempt_irq(struct msm_gpu *gpu)
return;
/* Delete the preemption watchdog timer */
- del_timer(&a6xx_gpu->preempt_timer);
+ timer_delete(&a6xx_gpu->preempt_timer);
/*
* The hardware should be setting the stop bit of CP_CONTEXT_SWITCH_CNTL
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 7156cda07b03..26db1f4b5fb9 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -292,7 +292,7 @@ int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
if (do_devcoredump) {
/* Turn off the hangcheck timer to keep it from bothering us */
- del_timer(&gpu->hangcheck_timer);
+ timer_delete(&gpu->hangcheck_timer);
gpu->fault_info.ttbr0 = info->ttbr0;
gpu->fault_info.iova = iova;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 284e69bb47c1..8610bbf2b87c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1410,7 +1410,7 @@ static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc,
/* after phys waits for frame-done, should be no more frames pending */
if (atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
DPU_ERROR("enc%d timeout pending\n", drm_enc->base.id);
- del_timer_sync(&dpu_enc->frame_done_timer);
+ timer_delete_sync(&dpu_enc->frame_done_timer);
}
dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_STOP);
@@ -1582,7 +1582,7 @@ void dpu_encoder_frame_done_callback(
if (!dpu_enc->frame_busy_mask[0]) {
atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
- del_timer(&dpu_enc->frame_done_timer);
+ timer_delete(&dpu_enc->frame_done_timer);
dpu_encoder_resource_control(drm_enc,
DPU_ENC_RC_EVENT_FRAME_DONE);
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 59d20eb8a7e0..9b9cc593790c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -452,7 +452,7 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
#ifdef DSI_CATCH_MISSING_TE
if (irqstatus & DSI_IRQ_TE_TRIGGER)
- del_timer(&dsi->te_timer);
+ timer_delete(&dsi->te_timer);
#endif
/* make a copy and unlock, so that isrs can unregister
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index fb450b6a4d44..7125773889f1 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -1043,7 +1043,7 @@ static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused)
struct vc4_dev *vc4 = to_vc4_dev(dev);
int i;
- del_timer(&vc4->bo_cache.time_timer);
+ timer_delete(&vc4->bo_cache.time_timer);
cancel_work_sync(&vc4->bo_cache.time_work);
vc4_bo_cache_purge(dev);
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
index e15754178395..37bb1fb58cf9 100644
--- a/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -49,7 +49,7 @@ static void vgem_fence_release(struct dma_fence *base)
{
struct vgem_fence *fence = container_of(base, typeof(*fence), base);
- del_timer_sync(&fence->timer);
+ timer_delete_sync(&fence->timer);
dma_fence_free(&fence->base);
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 1f15990d3934..1d9a42cbc88f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -289,7 +289,7 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
return -EINVAL;
}
-STACK_FRAME_NON_STANDARD(vmw_send_msg);
+STACK_FRAME_NON_STANDARD_FP(vmw_send_msg);
/**
diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig
index 7d7995196702..5c2f459a2925 100644
--- a/drivers/gpu/drm/xe/Kconfig
+++ b/drivers/gpu/drm/xe/Kconfig
@@ -53,7 +53,7 @@ config DRM_XE
config DRM_XE_DISPLAY
bool "Enable display support"
depends on DRM_XE && DRM_XE=m && HAS_IOPORT
- select FB_IOMEM_HELPERS
+ select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
select I2C
select I2C_ALGOBIT
default y
diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
index 4f372dc2cb89..fb8ec317b6ee 100644
--- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
@@ -130,6 +130,10 @@
#define RING_EXECLIST_STATUS_LO(base) XE_REG((base) + 0x234)
#define RING_EXECLIST_STATUS_HI(base) XE_REG((base) + 0x234 + 4)
+#define RING_IDLEDLY(base) XE_REG((base) + 0x23c)
+#define INHIBIT_SWITCH_UNTIL_PREEMPTED REG_BIT(31)
+#define IDLE_DELAY REG_GENMASK(20, 0)
+
#define RING_CONTEXT_CONTROL(base) XE_REG((base) + 0x244, XE_REG_OPTION_MASKED)
#define CTX_CTRL_PXP_ENABLE REG_BIT(10)
#define CTX_CTRL_OAC_CONTEXT_ENABLE REG_BIT(8)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 5d79b439dd62..00191227bc95 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -53,6 +53,7 @@
#include "xe_pxp.h"
#include "xe_query.h"
#include "xe_shrinker.h"
+#include "xe_survivability_mode.h"
#include "xe_sriov.h"
#include "xe_tile.h"
#include "xe_ttm_stolen_mgr.h"
@@ -705,8 +706,20 @@ int xe_device_probe_early(struct xe_device *xe)
sriov_update_device_info(xe);
err = xe_pcode_probe_early(xe);
- if (err)
- return err;
+ if (err) {
+ int save_err = err;
+
+ /*
+ * Try to leave device in survivability mode if device is
+ * possible, but still return the previous error for error
+ * propagation
+ */
+ err = xe_survivability_mode_enable(xe);
+ if (err)
+ return err;
+
+ return save_err;
+ }
err = wait_for_lmem_ready(xe);
if (err)
diff --git a/drivers/gpu/drm/xe/xe_eu_stall.c b/drivers/gpu/drm/xe/xe_eu_stall.c
index 88a92baf5c95..f2bb9168967c 100644
--- a/drivers/gpu/drm/xe/xe_eu_stall.c
+++ b/drivers/gpu/drm/xe/xe_eu_stall.c
@@ -222,13 +222,7 @@ int xe_eu_stall_init(struct xe_gt *gt)
goto exit_free;
}
- ret = devm_add_action_or_reset(xe->drm.dev, xe_eu_stall_fini, gt);
- if (ret)
- goto exit_destroy;
-
- return 0;
-exit_destroy:
- destroy_workqueue(gt->eu_stall->buf_ptr_poll_wq);
+ return devm_add_action_or_reset(xe->drm.dev, xe_eu_stall_fini, gt);
exit_free:
mutex_destroy(&gt->eu_stall->stream_lock);
kfree(gt->eu_stall);
diff --git a/drivers/gpu/drm/xe/xe_execlist.c b/drivers/gpu/drm/xe/xe_execlist.c
index 9fbed1a2fcc6..788f56b066b6 100644
--- a/drivers/gpu/drm/xe/xe_execlist.c
+++ b/drivers/gpu/drm/xe/xe_execlist.c
@@ -297,7 +297,7 @@ err:
void xe_execlist_port_destroy(struct xe_execlist_port *port)
{
- del_timer(&port->irq_fail);
+ timer_delete(&port->irq_fail);
/* Prevent an interrupt while we're destroying */
spin_lock_irq(&gt_to_xe(port->hwe->gt)->irq.lock);
diff --git a/drivers/gpu/drm/xe/xe_gt_clock.c b/drivers/gpu/drm/xe/xe_gt_clock.c
index 2a958c92d8ea..4f011d1573c6 100644
--- a/drivers/gpu/drm/xe/xe_gt_clock.c
+++ b/drivers/gpu/drm/xe/xe_gt_clock.c
@@ -16,35 +16,47 @@
#include "xe_macros.h"
#include "xe_mmio.h"
-static u32 get_crystal_clock_freq(u32 rpm_config_reg)
+#define f19_2_mhz 19200000
+#define f24_mhz 24000000
+#define f25_mhz 25000000
+#define f38_4_mhz 38400000
+#define ts_base_83 83333
+#define ts_base_52 52083
+#define ts_base_80 80000
+
+static void read_crystal_clock(struct xe_gt *gt, u32 rpm_config_reg, u32 *freq,
+ u32 *timestamp_base)
{
- const u32 f19_2_mhz = 19200000;
- const u32 f24_mhz = 24000000;
- const u32 f25_mhz = 25000000;
- const u32 f38_4_mhz = 38400000;
u32 crystal_clock = REG_FIELD_GET(RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK,
rpm_config_reg);
switch (crystal_clock) {
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
- return f24_mhz;
+ *freq = f24_mhz;
+ *timestamp_base = ts_base_83;
+ return;
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
- return f19_2_mhz;
+ *freq = f19_2_mhz;
+ *timestamp_base = ts_base_52;
+ return;
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
- return f38_4_mhz;
+ *freq = f38_4_mhz;
+ *timestamp_base = ts_base_52;
+ return;
case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
- return f25_mhz;
+ *freq = f25_mhz;
+ *timestamp_base = ts_base_80;
+ return;
default:
- XE_WARN_ON("NOT_POSSIBLE");
- return 0;
+ xe_gt_warn(gt, "Invalid crystal clock frequency: %u", crystal_clock);
+ *freq = 0;
+ *timestamp_base = 0;
+ return;
}
}
-int xe_gt_clock_init(struct xe_gt *gt)
+static void check_ctc_mode(struct xe_gt *gt)
{
- u32 c0 = xe_mmio_read32(&gt->mmio, RPM_CONFIG0);
- u32 freq = 0;
-
/*
* CTC_MODE[0] = 1 is definitely not supported for Xe2 and later
* platforms. In theory it could be a valid setting for pre-Xe2
@@ -57,8 +69,18 @@ int xe_gt_clock_init(struct xe_gt *gt)
*/
if (xe_mmio_read32(&gt->mmio, CTC_MODE) & CTC_SOURCE_DIVIDE_LOGIC)
xe_gt_warn(gt, "CTC_MODE[0] is set; this is unexpected and undocumented\n");
+}
+
+int xe_gt_clock_init(struct xe_gt *gt)
+{
+ u32 freq;
+ u32 c0;
+
+ if (!IS_SRIOV_VF(gt_to_xe(gt)))
+ check_ctc_mode(gt);
- freq = get_crystal_clock_freq(c0);
+ c0 = xe_mmio_read32(&gt->mmio, RPM_CONFIG0);
+ read_crystal_clock(gt, c0, &freq, &gt->info.timestamp_base);
/*
* Now figure out how the command stream's timestamp
diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
index e3cfb026ac88..7def0959da35 100644
--- a/drivers/gpu/drm/xe/xe_gt_types.h
+++ b/drivers/gpu/drm/xe/xe_gt_types.h
@@ -121,6 +121,8 @@ struct xe_gt {
enum xe_gt_type type;
/** @info.reference_clock: clock frequency */
u32 reference_clock;
+ /** @info.timestamp_base: GT timestamp base */
+ u32 timestamp_base;
/**
* @info.engine_mask: mask of engines present on GT. Some of
* them may be reserved in runtime and not available for user.
diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
index 223b95de388c..8c05fd30b7df 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine.c
@@ -8,7 +8,9 @@
#include <linux/nospec.h>
#include <drm/drm_managed.h>
+#include <drm/drm_print.h>
#include <uapi/drm/xe_drm.h>
+#include <generated/xe_wa_oob.h>
#include "regs/xe_engine_regs.h"
#include "regs/xe_gt_regs.h"
@@ -21,6 +23,7 @@
#include "xe_gsc.h"
#include "xe_gt.h"
#include "xe_gt_ccs_mode.h"
+#include "xe_gt_clock.h"
#include "xe_gt_printk.h"
#include "xe_gt_mcr.h"
#include "xe_gt_topology.h"
@@ -564,6 +567,33 @@ static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe,
xe_reg_whitelist_process_engine(hwe);
}
+static void adjust_idledly(struct xe_hw_engine *hwe)
+{
+ struct xe_gt *gt = hwe->gt;
+ u32 idledly, maxcnt;
+ u32 idledly_units_ps = 8 * gt->info.timestamp_base;
+ u32 maxcnt_units_ns = 640;
+ bool inhibit_switch = 0;
+
+ if (!IS_SRIOV_VF(gt_to_xe(hwe->gt)) && XE_WA(gt, 16023105232)) {
+ idledly = xe_mmio_read32(&gt->mmio, RING_IDLEDLY(hwe->mmio_base));
+ maxcnt = xe_mmio_read32(&gt->mmio, RING_PWRCTX_MAXCNT(hwe->mmio_base));
+
+ inhibit_switch = idledly & INHIBIT_SWITCH_UNTIL_PREEMPTED;
+ idledly = REG_FIELD_GET(IDLE_DELAY, idledly);
+ idledly = DIV_ROUND_CLOSEST(idledly * idledly_units_ps, 1000);
+ maxcnt = REG_FIELD_GET(IDLE_WAIT_TIME, maxcnt);
+ maxcnt *= maxcnt_units_ns;
+
+ if (xe_gt_WARN_ON(gt, idledly >= maxcnt || inhibit_switch)) {
+ idledly = DIV_ROUND_CLOSEST(((maxcnt - 1) * maxcnt_units_ns),
+ idledly_units_ps);
+ idledly = DIV_ROUND_CLOSEST(idledly, 1000);
+ xe_mmio_write32(&gt->mmio, RING_IDLEDLY(hwe->mmio_base), idledly);
+ }
+ }
+}
+
static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe,
enum xe_hw_engine_id id)
{
@@ -604,6 +634,9 @@ static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe,
if (xe->info.has_usm && hwe->class == XE_ENGINE_CLASS_COPY)
gt->usm.reserved_bcs_instance = hwe->instance;
+ /* Ensure IDLEDLY is lower than MAXCNT */
+ adjust_idledly(hwe);
+
return devm_add_action_or_reset(xe->drm.dev, hw_engine_fini, hwe);
err_hwsp:
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index da9679c8cf26..818f023166d5 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -803,16 +803,14 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
err = xe_device_probe_early(xe);
-
- /*
- * In Boot Survivability mode, no drm card is exposed and driver is
- * loaded with bare minimum to allow for firmware to be flashed through
- * mei. If early probe fails, check if survivability mode is flagged by
- * HW to be enabled. In that case enable it and return success.
- */
if (err) {
- if (xe_survivability_mode_required(xe) &&
- xe_survivability_mode_enable(xe))
+ /*
+ * In Boot Survivability mode, no drm card is exposed and driver
+ * is loaded with bare minimum to allow for firmware to be
+ * flashed through mei. If early probe failed, but it managed to
+ * enable survivability mode, return success.
+ */
+ if (xe_survivability_mode_is_enabled(xe))
return 0;
return err;
diff --git a/drivers/gpu/drm/xe/xe_survivability_mode.c b/drivers/gpu/drm/xe/xe_survivability_mode.c
index d939ce70e6fa..cb813b337fd3 100644
--- a/drivers/gpu/drm/xe/xe_survivability_mode.c
+++ b/drivers/gpu/drm/xe/xe_survivability_mode.c
@@ -155,13 +155,21 @@ static int enable_survivability_mode(struct pci_dev *pdev)
if (ret)
return ret;
+ /* Make sure xe_heci_gsc_init() knows about survivability mode */
+ survivability->mode = true;
+
ret = xe_heci_gsc_init(xe);
- if (ret)
+ if (ret) {
+ /*
+ * But if it fails, device can't enter survivability
+ * so move it back for correct error handling
+ */
+ survivability->mode = false;
return ret;
+ }
xe_vsec_init(xe);
- survivability->mode = true;
dev_err(dev, "In Survivability Mode\n");
return 0;
@@ -178,15 +186,16 @@ bool xe_survivability_mode_is_enabled(struct xe_device *xe)
return xe->survivability.mode;
}
-/**
- * xe_survivability_mode_required - checks if survivability mode is required
- * @xe: xe device instance
+/*
+ * survivability_mode_requested - check if it's possible to enable
+ * survivability mode and that was requested by firmware
*
- * This function reads the boot status from Pcode
+ * This function reads the boot status from Pcode.
*
- * Return: true if boot status indicates failure, false otherwise
+ * Return: true if platform support is available and boot status indicates
+ * failure, false otherwise.
*/
-bool xe_survivability_mode_required(struct xe_device *xe)
+static bool survivability_mode_requested(struct xe_device *xe)
{
struct xe_survivability *survivability = &xe->survivability;
struct xe_mmio *mmio = xe_root_tile_mmio(xe);
@@ -208,7 +217,8 @@ bool xe_survivability_mode_required(struct xe_device *xe)
*
* Initialize survivability information and enable survivability mode
*
- * Return: 0 for success, negative error code otherwise.
+ * Return: 0 if survivability mode is enabled or not requested; negative error
+ * code otherwise.
*/
int xe_survivability_mode_enable(struct xe_device *xe)
{
@@ -216,6 +226,9 @@ int xe_survivability_mode_enable(struct xe_device *xe)
struct xe_survivability_info *info;
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
+ if (!survivability_mode_requested(xe))
+ return 0;
+
survivability->size = MAX_SCRATCH_MMIO;
info = devm_kcalloc(xe->drm.dev, survivability->size, sizeof(*info),
diff --git a/drivers/gpu/drm/xe/xe_survivability_mode.h b/drivers/gpu/drm/xe/xe_survivability_mode.h
index f4df5f9025ce..d7e64885570d 100644
--- a/drivers/gpu/drm/xe/xe_survivability_mode.h
+++ b/drivers/gpu/drm/xe/xe_survivability_mode.h
@@ -12,6 +12,5 @@ struct xe_device;
int xe_survivability_mode_enable(struct xe_device *xe);
bool xe_survivability_mode_is_enabled(struct xe_device *xe);
-bool xe_survivability_mode_required(struct xe_device *xe);
#endif /* _XE_SURVIVABILITY_MODE_H_ */
diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
index a25afb757f70..24f644c0a673 100644
--- a/drivers/gpu/drm/xe/xe_wa.c
+++ b/drivers/gpu/drm/xe/xe_wa.c
@@ -622,6 +622,12 @@ static const struct xe_rtp_entry_sr engine_was[] = {
FUNC(xe_rtp_match_first_render_or_compute)),
XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS))
},
+ { XE_RTP_NAME("16023105232"),
+ XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, 3000), OR,
+ GRAPHICS_VERSION_RANGE(2001, 3001)),
+ XE_RTP_ACTIONS(SET(RING_PSMI_CTL(0), RC_SEMA_IDLE_MSG_DISABLE,
+ XE_RTP_ACTION_FLAG(ENGINE_BASE)))
+ },
};
static const struct xe_rtp_entry_sr lrc_was[] = {
diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules
index e0c5fa460487..0c738af24f7c 100644
--- a/drivers/gpu/drm/xe/xe_wa_oob.rules
+++ b/drivers/gpu/drm/xe/xe_wa_oob.rules
@@ -53,3 +53,5 @@ no_media_l3 MEDIA_VERSION(3000)
GRAPHICS_VERSION_RANGE(1270, 1274)
1508761755 GRAPHICS_VERSION(1255)
GRAPHICS_VERSION(1260), GRAPHICS_STEP(A0, B0)
+16023105232 GRAPHICS_VERSION_RANGE(2001, 3001)
+ MEDIA_VERSION_RANGE(1301, 3000)
diff --git a/drivers/greybus/operation.c b/drivers/greybus/operation.c
index 8459e9bc0749..f6beeebf974c 100644
--- a/drivers/greybus/operation.c
+++ b/drivers/greybus/operation.c
@@ -279,7 +279,7 @@ static void gb_operation_work(struct work_struct *work)
if (gb_operation_is_incoming(operation)) {
gb_operation_request_handle(operation);
} else {
- ret = del_timer_sync(&operation->timer);
+ ret = timer_delete_sync(&operation->timer);
if (!ret) {
/* Cancel request message if scheduled by timeout. */
if (gb_operation_result(operation) == -ETIMEDOUT)
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index d900dd05c335..ed34f5cd5a91 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -950,7 +950,7 @@ static int apple_probe(struct hid_device *hdev,
return 0;
out_err:
- del_timer_sync(&asc->battery_timer);
+ timer_delete_sync(&asc->battery_timer);
hid_hw_stop(hdev);
return ret;
}
@@ -959,7 +959,7 @@ static void apple_remove(struct hid_device *hdev)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
- del_timer_sync(&asc->battery_timer);
+ timer_delete_sync(&asc->battery_timer);
hid_hw_stop(hdev);
}
diff --git a/drivers/hid/hid-appleir.c b/drivers/hid/hid-appleir.c
index c45e5aa569d2..bb7db9ae41c2 100644
--- a/drivers/hid/hid-appleir.c
+++ b/drivers/hid/hid-appleir.c
@@ -319,7 +319,7 @@ static void appleir_remove(struct hid_device *hid)
{
struct appleir *appleir = hid_get_drvdata(hid);
hid_hw_stop(hid);
- del_timer_sync(&appleir->key_up_timer);
+ timer_delete_sync(&appleir->key_up_timer);
}
static const struct hid_device_id appleir_devices[] = {
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
index d4b95aa3eecb..029ccbaa1d12 100644
--- a/drivers/hid/hid-appletb-kbd.c
+++ b/drivers/hid/hid-appletb-kbd.c
@@ -448,7 +448,7 @@ static void appletb_kbd_remove(struct hid_device *hdev)
appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
input_unregister_handler(&kbd->inp_handler);
- del_timer_sync(&kbd->inactivity_timer);
+ timer_delete_sync(&kbd->inactivity_timer);
hid_hw_close(hdev);
hid_hw_stop(hdev);
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index a76f17158539..adfa329e917b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -915,7 +915,7 @@ static int magicmouse_probe(struct hid_device *hdev,
return 0;
err_stop_hw:
- del_timer_sync(&msc->battery_timer);
+ timer_delete_sync(&msc->battery_timer);
hid_hw_stop(hdev);
return ret;
}
@@ -926,7 +926,7 @@ static void magicmouse_remove(struct hid_device *hdev)
if (msc) {
cancel_delayed_work_sync(&msc->work);
- del_timer_sync(&msc->battery_timer);
+ timer_delete_sync(&msc->battery_timer);
}
hid_hw_stop(hdev);
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index e50887a6d22c..7ac8e16e6158 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1299,7 +1299,7 @@ static void mt_touch_report(struct hid_device *hid,
mod_timer(&td->release_timer,
jiffies + msecs_to_jiffies(100));
else
- del_timer(&td->release_timer);
+ timer_delete(&td->release_timer);
}
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
@@ -1881,7 +1881,7 @@ static void mt_remove(struct hid_device *hdev)
{
struct mt_device *td = hid_get_drvdata(hdev);
- del_timer_sync(&td->release_timer);
+ timer_delete_sync(&td->release_timer);
sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
hid_hw_stop(hdev);
diff --git a/drivers/hid/hid-nvidia-shield.c b/drivers/hid/hid-nvidia-shield.c
index ff9078ad1961..b0c40a245bf8 100644
--- a/drivers/hid/hid-nvidia-shield.c
+++ b/drivers/hid/hid-nvidia-shield.c
@@ -1102,7 +1102,7 @@ static void shield_remove(struct hid_device *hdev)
hid_hw_close(hdev);
thunderstrike_destroy(ts);
- del_timer_sync(&ts->psy_stats_timer);
+ timer_delete_sync(&ts->psy_stats_timer);
cancel_work_sync(&ts->hostcmd_req_work);
hid_hw_stop(hdev);
}
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 3d08c190a935..c6b922c2adba 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -254,7 +254,7 @@ static void stop_sustain_timers(struct pcmidi_snd *pm)
for (i = 0; i < PCMIDI_SUSTAINED_MAX; i++) {
pms = &pm->sustained_notes[i];
pms->in_use = 1;
- del_timer_sync(&pms->timer);
+ timer_delete_sync(&pms->timer);
}
}
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 5258b45684e8..a2be652b7bbd 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -2164,7 +2164,7 @@ static void sony_remove(struct hid_device *hdev)
struct sony_sc *sc = hid_get_drvdata(hdev);
if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) {
- del_timer_sync(&sc->ghl_poke_timer);
+ timer_delete_sync(&sc->ghl_poke_timer);
usb_free_urb(sc->ghl_urb);
}
diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
index d8008933c052..a367df6ea01f 100644
--- a/drivers/hid/hid-uclogic-core.c
+++ b/drivers/hid/hid-uclogic-core.c
@@ -474,7 +474,7 @@ static void uclogic_remove(struct hid_device *hdev)
{
struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
- del_timer_sync(&drvdata->inrange_timer);
+ timer_delete_sync(&drvdata->inrange_timer);
hid_hw_stop(hdev);
kfree(drvdata->desc_ptr);
uclogic_params_cleanup(&drvdata->params);
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 26167cfb696f..8080083121d3 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -1171,7 +1171,7 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata)
wiimote_cmd_release(wdata);
/* delete MP hotplug timer */
- del_timer_sync(&wdata->timer);
+ timer_delete_sync(&wdata->timer);
} else {
/* reschedule MP hotplug timer */
if (!(flags & WIIPROTO_FLAG_BUILTIN_MP) &&
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 44c2351b870f..7d9297fad90e 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1462,13 +1462,13 @@ static void usbhid_disconnect(struct usb_interface *intf)
static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
{
- del_timer_sync(&usbhid->io_retry);
+ timer_delete_sync(&usbhid->io_retry);
cancel_work_sync(&usbhid->reset_work);
}
static void hid_cease_io(struct usbhid_device *usbhid)
{
- del_timer_sync(&usbhid->io_retry);
+ timer_delete_sync(&usbhid->io_retry);
usb_kill_urb(usbhid->urbin);
usb_kill_urb(usbhid->urbctrl);
usb_kill_urb(usbhid->urbout);
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 97393a3083ca..1556d4287fa5 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2896,7 +2896,7 @@ static void wacom_remove(struct hid_device *hdev)
cancel_work_sync(&wacom->battery_work);
cancel_work_sync(&wacom->remote_work);
cancel_work_sync(&wacom->mode_change_work);
- del_timer_sync(&wacom->idleprox_timer);
+ timer_delete_sync(&wacom->idleprox_timer);
if (hdev->bus == BUS_BLUETOOTH)
device_remove_file(&hdev->dev, &dev_attr_speed);
diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
index 6105ea9a6c6a..cbc5e72857de 100644
--- a/drivers/hsi/clients/ssi_protocol.c
+++ b/drivers/hsi/clients/ssi_protocol.c
@@ -281,9 +281,9 @@ static void ssip_set_rxstate(struct ssi_protocol *ssi, unsigned int state)
ssi->recv_state = state;
switch (state) {
case RECV_IDLE:
- del_timer(&ssi->rx_wd);
+ timer_delete(&ssi->rx_wd);
if (ssi->send_state == SEND_IDLE)
- del_timer(&ssi->keep_alive);
+ timer_delete(&ssi->keep_alive);
break;
case RECV_READY:
/* CMT speech workaround */
@@ -306,9 +306,9 @@ static void ssip_set_txstate(struct ssi_protocol *ssi, unsigned int state)
switch (state) {
case SEND_IDLE:
case SEND_READY:
- del_timer(&ssi->tx_wd);
+ timer_delete(&ssi->tx_wd);
if (ssi->recv_state == RECV_IDLE)
- del_timer(&ssi->keep_alive);
+ timer_delete(&ssi->keep_alive);
break;
case WAIT4READY:
case SENDING:
@@ -398,9 +398,9 @@ static void ssip_reset(struct hsi_client *cl)
if (test_and_clear_bit(SSIP_WAKETEST_FLAG, &ssi->flags))
ssi_waketest(cl, 0); /* FIXME: To be removed */
spin_lock_bh(&ssi->lock);
- del_timer(&ssi->rx_wd);
- del_timer(&ssi->tx_wd);
- del_timer(&ssi->keep_alive);
+ timer_delete(&ssi->rx_wd);
+ timer_delete(&ssi->tx_wd);
+ timer_delete(&ssi->keep_alive);
cancel_work_sync(&ssi->work);
ssi->main_state = 0;
ssi->send_state = 0;
@@ -648,7 +648,7 @@ static void ssip_rx_data_complete(struct hsi_msg *msg)
ssip_error(cl);
return;
}
- del_timer(&ssi->rx_wd); /* FIXME: Revisit */
+ timer_delete(&ssi->rx_wd); /* FIXME: Revisit */
skb = msg->context;
ssip_pn_rx(skb);
hsi_free_msg(msg);
@@ -731,7 +731,7 @@ static void ssip_rx_waketest(struct hsi_client *cl, u32 cmd)
spin_lock_bh(&ssi->lock);
ssi->main_state = ACTIVE;
- del_timer(&ssi->tx_wd); /* Stop boot handshake timer */
+ timer_delete(&ssi->tx_wd); /* Stop boot handshake timer */
spin_unlock_bh(&ssi->lock);
dev_notice(&cl->device, "WAKELINES TEST %s\n",
diff --git a/drivers/hte/hte-tegra194-test.c b/drivers/hte/hte-tegra194-test.c
index f890b79723af..94e931f45305 100644
--- a/drivers/hte/hte-tegra194-test.c
+++ b/drivers/hte/hte-tegra194-test.c
@@ -221,7 +221,7 @@ static void tegra_hte_test_remove(struct platform_device *pdev)
free_irq(hte.gpio_in_irq, &hte);
gpiod_put(hte.gpio_in);
gpiod_put(hte.gpio_out);
- del_timer_sync(&hte.timer);
+ timer_delete_sync(&hte.timer);
}
static struct platform_driver tegra_hte_test_driver = {
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 579d31bb9ac7..d506a5e7e033 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -483,7 +483,7 @@ static void pwm_fan_cleanup(void *__ctx)
{
struct pwm_fan_ctx *ctx = __ctx;
- del_timer_sync(&ctx->rpm_timer);
+ timer_delete_sync(&ctx->rpm_timer);
/* Switch off everything */
ctx->enable_mode = pwm_disable_reg_disable;
pwm_fan_power_off(ctx, true);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index fc438f445771..83c88c79afe2 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -783,6 +783,23 @@ config I2C_JZ4780
If you don't know what to do here, say N.
+config I2C_K1
+ tristate "SpacemiT K1 I2C adapter"
+ depends on ARCH_SPACEMIT || COMPILE_TEST
+ depends on OF
+ help
+ This option enables support for the I2C interface on the SpacemiT K1
+ platform.
+
+ If you enable this configuration, the kernel will include support for
+ the I2C adapter specific to the SpacemiT K1 platform. This driver can
+ be used to manage I2C bus transactions, which are necessary for
+ interfacing with I2C peripherals such as sensors, EEPROMs, and other
+ devices.
+
+ This driver can also be built as a module. If so, the
+ module will be called `i2c-k1`.
+
config I2C_KEBA
tristate "KEBA I2C controller support"
depends on HAS_IOMEM
@@ -940,6 +957,7 @@ config I2C_OMAP
tristate "OMAP I2C adapter"
depends on ARCH_OMAP || ARCH_K3 || COMPILE_TEST
default MACH_OMAP_OSK
+ select MULTIPLEXER
help
If you say yes to this option, support will be included for the
I2C interface on the Texas Instruments OMAP1/2 family of processors.
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 1c2a4510abe4..c1252e2b779e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_I2C_IMX) += i2c-imx.o
obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-lpi2c.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
+obj-$(CONFIG_I2C_K1) += i2c-k1.o
obj-$(CONFIG_I2C_KEBA) += i2c-keba.o
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o
diff --git a/drivers/i2c/busses/i2c-amd-asf-plat.c b/drivers/i2c/busses/i2c-amd-asf-plat.c
index 93ebec162c6d..ca45f0f23321 100644
--- a/drivers/i2c/busses/i2c-amd-asf-plat.c
+++ b/drivers/i2c/busses/i2c-amd-asf-plat.c
@@ -69,7 +69,7 @@ static void amd_asf_process_target(struct work_struct *work)
/* Check if no error bits are set in target status register */
if (reg & ASF_ERROR_STATUS) {
/* Set bank as full */
- cmd = 0;
+ cmd = 1;
reg |= GENMASK(3, 2);
outb_p(reg, ASFDATABNKSEL);
} else {
@@ -272,9 +272,9 @@ static u32 amd_asf_func(struct i2c_adapter *adapter)
}
static const struct i2c_algorithm amd_asf_smbus_algorithm = {
- .master_xfer = amd_asf_xfer,
- .reg_slave = amd_asf_reg_target,
- .unreg_slave = amd_asf_unreg_target,
+ .xfer = amd_asf_xfer,
+ .reg_target = amd_asf_reg_target,
+ .unreg_target = amd_asf_unreg_target,
.functionality = amd_asf_func,
};
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index 48916cf45ff7..50030256cd85 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -255,11 +255,6 @@ static int i2c_m_rd(const struct i2c_msg *msg)
return (msg->flags & I2C_M_RD) != 0;
}
-static int i2c_m_ten(const struct i2c_msg *msg)
-{
- return (msg->flags & I2C_M_TEN) != 0;
-}
-
static int i2c_m_recv_len(const struct i2c_msg *msg)
{
return (msg->flags & I2C_M_RECV_LEN) != 0;
@@ -439,20 +434,10 @@ static void axxia_i2c_set_addr(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
{
u32 addr_1, addr_2;
- if (i2c_m_ten(msg)) {
- /* 10-bit address
- * addr_1: 5'b11110 | addr[9:8] | (R/nW)
- * addr_2: addr[7:0]
- */
- addr_1 = 0xF0 | ((msg->addr >> 7) & 0x06);
- if (i2c_m_rd(msg))
- addr_1 |= 1; /* Set the R/nW bit of the address */
- addr_2 = msg->addr & 0xFF;
+ if (msg->flags & I2C_M_TEN) {
+ addr_1 = i2c_10bit_addr_hi_from_msg(msg);
+ addr_2 = i2c_10bit_addr_lo_from_msg(msg);
} else {
- /* 7-bit address
- * addr_1: addr[6:0] | (R/nW)
- * addr_2: dont care
- */
addr_1 = i2c_8bit_addr_from_msg(msg);
addr_2 = 0;
}
diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
index 15b632a146e1..332a0fcca28d 100644
--- a/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -678,7 +678,7 @@ static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data)
return IRQ_HANDLED;
}
-static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c)
+static void bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c)
{
u32 val;
@@ -706,8 +706,6 @@ static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c)
/* clear all pending interrupts */
iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, 0xffffffff);
-
- return 0;
}
static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c,
@@ -1081,9 +1079,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
bcm_iproc_algo.unreg_slave = NULL;
}
- ret = bcm_iproc_i2c_init(iproc_i2c);
- if (ret)
- return ret;
+ bcm_iproc_i2c_init(iproc_i2c);
ret = bcm_iproc_i2c_cfg_speed(iproc_i2c);
if (ret)
@@ -1162,16 +1158,13 @@ static int bcm_iproc_i2c_suspend(struct device *dev)
static int bcm_iproc_i2c_resume(struct device *dev)
{
struct bcm_iproc_i2c_dev *iproc_i2c = dev_get_drvdata(dev);
- int ret;
u32 val;
/*
* Power domain could have been shut off completely in system deep
* sleep, so re-initialize the block here
*/
- ret = bcm_iproc_i2c_init(iproc_i2c);
- if (ret)
- return ret;
+ bcm_iproc_i2c_init(iproc_i2c);
/* configure to the desired bus speed */
val = iproc_i2c_rd_reg(iproc_i2c, TIM_CFG_OFFSET);
diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c
index 340fe1305dd9..9d8838bbd938 100644
--- a/drivers/i2c/busses/i2c-bcm-kona.c
+++ b/drivers/i2c/busses/i2c-bcm-kona.c
@@ -471,12 +471,12 @@ static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev,
if (msg->flags & I2C_M_TEN) {
/* First byte is 11110XX0 where XX is upper 2 bits */
- addr = 0xF0 | ((msg->addr & 0x300) >> 7);
+ addr = i2c_10bit_addr_hi_from_msg(msg) & ~I2C_M_RD;
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
/* Second byte is the remaining 8 bits */
- addr = msg->addr & 0xFF;
+ addr = i2c_10bit_addr_lo_from_msg(msg);
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
@@ -486,7 +486,7 @@ static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev,
return -EREMOTEIO;
/* Then re-send the first byte with the read bit set */
- addr = 0xF0 | ((msg->addr & 0x300) >> 7) | 0x01;
+ addr = i2c_10bit_addr_hi_from_msg(msg);
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
return -EREMOTEIO;
}
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
index 00f1a046e985..5fa30e8926c5 100644
--- a/drivers/i2c/busses/i2c-brcmstb.c
+++ b/drivers/i2c/busses/i2c-brcmstb.c
@@ -414,23 +414,22 @@ static int brcmstb_i2c_do_addr(struct brcmstb_i2c_dev *dev,
if (msg->flags & I2C_M_TEN) {
/* First byte is 11110XX0 where XX is upper 2 bits */
- addr = 0xF0 | ((msg->addr & 0x300) >> 7);
+ addr = i2c_10bit_addr_hi_from_msg(msg) & ~I2C_M_RD;
bsc_writel(dev, addr, chip_address);
/* Second byte is the remaining 8 bits */
- addr = msg->addr & 0xFF;
+ addr = i2c_10bit_addr_lo_from_msg(msg);
if (brcmstb_i2c_write_data_byte(dev, &addr, 0) < 0)
return -EREMOTEIO;
if (msg->flags & I2C_M_RD) {
/* For read, send restart without stop condition */
- brcmstb_set_i2c_start_stop(dev, COND_RESTART
- | COND_NOSTOP);
+ brcmstb_set_i2c_start_stop(dev, COND_RESTART | COND_NOSTOP);
+
/* Then re-send the first byte with the read bit set */
- addr = 0xF0 | ((msg->addr & 0x300) >> 7) | 0x01;
+ addr = i2c_10bit_addr_hi_from_msg(msg);
if (brcmstb_i2c_write_data_byte(dev, &addr, 0) < 0)
return -EREMOTEIO;
-
}
} else {
addr = i2c_8bit_addr_from_msg(msg);
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index b64026fbca66..8df63aaf2a80 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -1541,7 +1541,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
snprintf(id->adap.name, sizeof(id->adap.name),
"Cadence I2C at %08lx", (unsigned long)r_mem->start);
- id->clk = devm_clk_get(&pdev->dev, NULL);
+ id->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(id->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(id->clk),
"input clock not found.\n");
@@ -1551,16 +1551,10 @@ static int cdns_i2c_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(id->reset),
"Failed to request reset.\n");
- ret = clk_prepare_enable(id->clk);
- if (ret)
- dev_err(&pdev->dev, "Unable to enable clock.\n");
-
ret = reset_control_deassert(id->reset);
- if (ret) {
- dev_err_probe(&pdev->dev, ret,
- "Failed to de-assert reset.\n");
- goto err_clk_dis;
- }
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to de-assert reset.\n");
pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT);
pm_runtime_use_autosuspend(id->dev);
@@ -1615,11 +1609,9 @@ static int cdns_i2c_probe(struct platform_device *pdev)
err_clk_notifier_unregister:
clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
- reset_control_assert(id->reset);
-err_clk_dis:
- clk_disable_unprepare(id->clk);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
+ reset_control_assert(id->reset);
return ret;
}
@@ -1642,7 +1634,6 @@ static void cdns_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&id->adap);
clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
reset_control_assert(id->reset);
- clk_disable_unprepare(id->clk);
}
static struct platform_driver cdns_i2c_drv = {
diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c
index 8fbd2a10c31a..404571ad61a8 100644
--- a/drivers/i2c/busses/i2c-designware-amdpsp.c
+++ b/drivers/i2c/busses/i2c-designware-amdpsp.c
@@ -151,19 +151,16 @@ static void release_bus(void)
static void psp_release_i2c_bus_deferred(struct work_struct *work)
{
- mutex_lock(&psp_i2c_access_mutex);
+ guard(mutex)(&psp_i2c_access_mutex);
/*
* If there is any pending transaction, cannot release the bus here.
* psp_release_i2c_bus() will take care of this later.
*/
if (psp_i2c_access_count)
- goto cleanup;
+ return;
release_bus();
-
-cleanup:
- mutex_unlock(&psp_i2c_access_mutex);
}
static DECLARE_DELAYED_WORK(release_queue, psp_release_i2c_bus_deferred);
@@ -171,11 +168,11 @@ static int psp_acquire_i2c_bus(void)
{
int status;
- mutex_lock(&psp_i2c_access_mutex);
+ guard(mutex)(&psp_i2c_access_mutex);
/* Return early if mailbox malfunctioned */
if (psp_i2c_mbox_fail)
- goto cleanup;
+ return 0;
psp_i2c_access_count++;
@@ -184,11 +181,11 @@ static int psp_acquire_i2c_bus(void)
* reservation period.
*/
if (psp_i2c_sem_acquired)
- goto cleanup;
+ return 0;
status = psp_send_i2c_req(PSP_I2C_REQ_ACQUIRE);
if (status)
- goto cleanup;
+ return 0;
psp_i2c_sem_acquired = jiffies;
@@ -201,18 +198,16 @@ static int psp_acquire_i2c_bus(void)
* communication with PSP. At any case i2c bus is granted to the caller,
* thus always return success.
*/
-cleanup:
- mutex_unlock(&psp_i2c_access_mutex);
return 0;
}
static void psp_release_i2c_bus(void)
{
- mutex_lock(&psp_i2c_access_mutex);
+ guard(mutex)(&psp_i2c_access_mutex);
/* Return early if mailbox was malfunctioned */
if (psp_i2c_mbox_fail)
- goto cleanup;
+ return;
/*
* If we are last owner of PSP semaphore, need to release arbitration
@@ -220,7 +215,7 @@ static void psp_release_i2c_bus(void)
*/
psp_i2c_access_count--;
if (psp_i2c_access_count)
- goto cleanup;
+ return;
/*
* Send a release command to PSP if the semaphore reservation timeout
@@ -228,9 +223,6 @@ static void psp_release_i2c_bus(void)
*/
if (!delayed_work_pending(&release_queue))
release_bus();
-
-cleanup:
- mutex_unlock(&psp_i2c_access_mutex);
}
/*
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 2569bf1a72e0..c5394229b77f 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -907,7 +907,7 @@ done_nolock:
}
static const struct i2c_algorithm i2c_dw_algo = {
- .master_xfer = i2c_dw_xfer,
+ .xfer = i2c_dw_xfer,
.functionality = i2c_dw_func,
};
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index 4914bfbee2a9..efdaddf99f9e 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -48,8 +48,6 @@
#define BUS_IDLE_TIMEOUT 20
#define PCH_I2CCTL_I2CMEN 0x0080
-#define TEN_BIT_ADDR_DEFAULT 0xF000
-#define TEN_BIT_ADDR_MASK 0xF0
#define PCH_START 0x0020
#define PCH_RESTART 0x0004
#define PCH_ESR_START 0x0001
@@ -58,7 +56,6 @@
#define PCH_ACK 0x0008
#define PCH_GETACK 0x0001
#define CLR_REG 0x0
-#define I2C_RD 0x1
#define I2CMCF_BIT 0x0080
#define I2CMIF_BIT 0x0002
#define I2CMAL_BIT 0x0010
@@ -76,8 +73,6 @@
#define I2CMBB_BIT 0x0020
#define BUFFER_MODE_MASK (I2CBMFI_BIT | I2CBMAL_BIT | I2CBMNA_BIT | \
I2CBMTO_BIT | I2CBMIS_BIT)
-#define I2C_ADDR_MSK 0xFF
-#define I2C_MSB_2B_MSK 0x300
#define FAST_MODE_CLK 400
#define FAST_MODE_EN 0x0001
#define SUB_ADDR_LEN_MAX 4
@@ -371,16 +366,12 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
u8 *buf;
u32 length;
- u32 addr;
- u32 addr_2_msb;
- u32 addr_8_lsb;
s32 wrcount;
s32 rtn;
void __iomem *p = adap->pch_base_address;
length = msgs->len;
buf = msgs->buf;
- addr = msgs->addr;
/* enable master tx */
pch_setbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);
@@ -394,8 +385,7 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
}
if (msgs->flags & I2C_M_TEN) {
- addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7) & 0x06;
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
+ iowrite32(i2c_10bit_addr_hi_from_msg(msgs), p + PCH_I2CDR);
if (first)
pch_i2c_start(adap);
@@ -403,8 +393,7 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
if (rtn)
return rtn;
- addr_8_lsb = (addr & I2C_ADDR_MSK);
- iowrite32(addr_8_lsb, p + PCH_I2CDR);
+ iowrite32(i2c_10bit_addr_lo_from_msg(msgs), p + PCH_I2CDR);
} else {
/* set 7 bit slave address and R/W bit as 0 */
iowrite32(i2c_8bit_addr_from_msg(msgs), p + PCH_I2CDR);
@@ -490,15 +479,11 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
u8 *buf;
u32 count;
u32 length;
- u32 addr;
- u32 addr_2_msb;
- u32 addr_8_lsb;
void __iomem *p = adap->pch_base_address;
s32 rtn;
length = msgs->len;
buf = msgs->buf;
- addr = msgs->addr;
/* enable master reception */
pch_clrbit(adap->pch_base_address, PCH_I2CCTL, I2C_TX_MODE);
@@ -509,8 +494,7 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
}
if (msgs->flags & I2C_M_TEN) {
- addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7);
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
+ iowrite32(i2c_10bit_addr_hi_from_msg(msgs) & ~I2C_M_RD, p + PCH_I2CDR);
if (first)
pch_i2c_start(adap);
@@ -518,8 +502,7 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
if (rtn)
return rtn;
- addr_8_lsb = (addr & I2C_ADDR_MSK);
- iowrite32(addr_8_lsb, p + PCH_I2CDR);
+ iowrite32(i2c_10bit_addr_lo_from_msg(msgs), p + PCH_I2CDR);
pch_i2c_restart(adap);
@@ -527,8 +510,7 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
if (rtn)
return rtn;
- addr_2_msb |= I2C_RD;
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
+ iowrite32(i2c_10bit_addr_hi_from_msg(msgs), p + PCH_I2CDR);
} else {
/* 7 address bits + R/W bit */
iowrite32(i2c_8bit_addr_from_msg(msgs), p + PCH_I2CDR);
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index 6cdd957ea7e4..02f24479aa07 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -814,7 +814,7 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
ret = i2c->state;
/*
- * If this is the last message to be transfered (stop == 1)
+ * If this is the last message to be transferred (stop == 1)
* Then check if the bus can be brought back to idle.
*/
if (ret == 0 && stop)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 171d29d2770e..48e1af544b75 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -144,6 +144,7 @@
#define SMBNTFDADD(p) (20 + (p)->smba) /* ICH3 and later */
/* PCI Address Constants */
+#define SMBBAR_MMIO 0
#define SMBBAR 4
#define SMBHSTCFG 0x040
#define TCOBASE 0x050
@@ -276,7 +277,7 @@ struct i801_mux_config {
struct i801_priv {
struct i2c_adapter adapter;
- unsigned long smba;
+ void __iomem *smba;
unsigned char original_hstcfg;
unsigned char original_hstcnt;
unsigned char original_slvcmd;
@@ -337,9 +338,43 @@ MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n"
"\t\t 0x10 don't use interrupts\n"
"\t\t 0x20 disable SMBus Host Notify ");
+/* Wait for BUSY being cleared and either INTR or an error flag being set */
+static int i801_wait_intr(struct i801_priv *priv)
+{
+ unsigned long timeout = jiffies + priv->adapter.timeout;
+ int status, busy;
+
+ do {
+ usleep_range(250, 500);
+ status = ioread8(SMBHSTSTS(priv));
+ busy = status & SMBHSTSTS_HOST_BUSY;
+ status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
+ if (!busy && status)
+ return status & STATUS_ERROR_FLAGS;
+ } while (time_is_after_eq_jiffies(timeout));
+
+ return -ETIMEDOUT;
+}
+
+/* Wait for either BYTE_DONE or an error flag being set */
+static int i801_wait_byte_done(struct i801_priv *priv)
+{
+ unsigned long timeout = jiffies + priv->adapter.timeout;
+ int status;
+
+ do {
+ usleep_range(250, 500);
+ status = ioread8(SMBHSTSTS(priv));
+ if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
+ return status & STATUS_ERROR_FLAGS;
+ } while (time_is_after_eq_jiffies(timeout));
+
+ return -ETIMEDOUT;
+}
+
static int i801_get_block_len(struct i801_priv *priv)
{
- u8 len = inb_p(SMBHSTDAT0(priv));
+ u8 len = ioread8(SMBHSTDAT0(priv));
if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
pci_err(priv->pci_dev, "Illegal SMBus block read size %u\n", len);
@@ -356,9 +391,9 @@ static int i801_check_and_clear_pec_error(struct i801_priv *priv)
if (!(priv->features & FEATURE_SMBUS_PEC))
return 0;
- status = inb_p(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE;
+ status = ioread8(SMBAUXSTS(priv)) & SMBAUXSTS_CRCE;
if (status) {
- outb_p(status, SMBAUXSTS(priv));
+ iowrite8(status, SMBAUXSTS(priv));
return -EBADMSG;
}
@@ -371,7 +406,7 @@ static int i801_check_pre(struct i801_priv *priv)
{
int status, result;
- status = inb_p(SMBHSTSTS(priv));
+ status = ioread8(SMBHSTSTS(priv));
if (status & SMBHSTSTS_HOST_BUSY) {
pci_err(priv->pci_dev, "SMBus is busy, can't use it!\n");
return -EBUSY;
@@ -380,7 +415,7 @@ static int i801_check_pre(struct i801_priv *priv)
status &= STATUS_FLAGS;
if (status) {
pci_dbg(priv->pci_dev, "Clearing status flags (%02x)\n", status);
- outb_p(status, SMBHSTSTS(priv));
+ iowrite8(status, SMBHSTSTS(priv));
}
/*
@@ -406,22 +441,19 @@ static int i801_check_post(struct i801_priv *priv, int status)
*/
if (unlikely(status < 0)) {
/* try to stop the current command */
- outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv));
- usleep_range(1000, 2000);
- outb_p(0, SMBHSTCNT(priv));
+ iowrite8(SMBHSTCNT_KILL, SMBHSTCNT(priv));
+ status = i801_wait_intr(priv);
+ iowrite8(0, SMBHSTCNT(priv));
/* Check if it worked */
- status = inb_p(SMBHSTSTS(priv));
- if ((status & SMBHSTSTS_HOST_BUSY) ||
- !(status & SMBHSTSTS_FAILED))
- dev_dbg(&priv->pci_dev->dev,
- "Failed terminating the transaction\n");
+ if (status < 0 || !(status & SMBHSTSTS_FAILED))
+ pci_dbg(priv->pci_dev, "Failed terminating the transaction\n");
return -ETIMEDOUT;
}
if (status & SMBHSTSTS_FAILED) {
result = -EIO;
- dev_err(&priv->pci_dev->dev, "Transaction failed\n");
+ pci_err(priv->pci_dev, "Transaction failed\n");
}
if (status & SMBHSTSTS_DEV_ERR) {
/*
@@ -449,46 +481,12 @@ static int i801_check_post(struct i801_priv *priv, int status)
}
if (status & SMBHSTSTS_BUS_ERR) {
result = -EAGAIN;
- dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
+ pci_dbg(priv->pci_dev, "Lost arbitration\n");
}
return result;
}
-/* Wait for BUSY being cleared and either INTR or an error flag being set */
-static int i801_wait_intr(struct i801_priv *priv)
-{
- unsigned long timeout = jiffies + priv->adapter.timeout;
- int status, busy;
-
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- busy = status & SMBHSTSTS_HOST_BUSY;
- status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
- if (!busy && status)
- return status & STATUS_ERROR_FLAGS;
- } while (time_is_after_eq_jiffies(timeout));
-
- return -ETIMEDOUT;
-}
-
-/* Wait for either BYTE_DONE or an error flag being set */
-static int i801_wait_byte_done(struct i801_priv *priv)
-{
- unsigned long timeout = jiffies + priv->adapter.timeout;
- int status;
-
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
- return status & STATUS_ERROR_FLAGS;
- } while (time_is_after_eq_jiffies(timeout));
-
- return -ETIMEDOUT;
-}
-
static int i801_transaction(struct i801_priv *priv, int xact)
{
unsigned long result;
@@ -496,13 +494,13 @@ static int i801_transaction(struct i801_priv *priv, int xact)
if (priv->features & FEATURE_IRQ) {
reinit_completion(&priv->done);
- outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
+ iowrite8(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
SMBHSTCNT(priv));
result = wait_for_completion_timeout(&priv->done, adap->timeout);
return result ? priv->status : -ETIMEDOUT;
}
- outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
+ iowrite8(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
return i801_wait_intr(priv);
}
@@ -511,7 +509,7 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
union i2c_smbus_data *data,
char read_write, int command)
{
- int i, len, status, xact;
+ int len, status, xact;
switch (command) {
case I2C_SMBUS_BLOCK_PROC_CALL:
@@ -525,14 +523,13 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
}
/* Set block buffer mode */
- outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
+ iowrite8(ioread8(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
if (read_write == I2C_SMBUS_WRITE) {
len = data->block[0];
- outb_p(len, SMBHSTDAT0(priv));
- inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
- for (i = 0; i < len; i++)
- outb_p(data->block[i+1], SMBBLKDAT(priv));
+ iowrite8(len, SMBHSTDAT0(priv));
+ ioread8(SMBHSTCNT(priv)); /* reset the data buffer index */
+ iowrite8_rep(SMBBLKDAT(priv), data->block + 1, len);
}
status = i801_transaction(priv, xact);
@@ -548,12 +545,11 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
}
data->block[0] = len;
- inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
- for (i = 0; i < len; i++)
- data->block[i + 1] = inb_p(SMBBLKDAT(priv));
+ ioread8(SMBHSTCNT(priv)); /* reset the data buffer index */
+ ioread8_rep(SMBBLKDAT(priv), data->block + 1, len);
}
out:
- outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_E32B, SMBAUXCTL(priv));
+ iowrite8(ioread8(SMBAUXCTL(priv)) & ~SMBAUXCTL_E32B, SMBAUXCTL(priv));
return status;
}
@@ -576,18 +572,17 @@ static void i801_isr_byte_done(struct i801_priv *priv)
/* Read next byte */
if (priv->count < priv->len)
- priv->data[priv->count++] = inb(SMBBLKDAT(priv));
+ priv->data[priv->count++] = ioread8(SMBBLKDAT(priv));
else
- dev_dbg(&priv->pci_dev->dev,
- "Discarding extra byte on block read\n");
+ pci_dbg(priv->pci_dev, "Discarding extra byte on block read\n");
/* Set LAST_BYTE for last byte of read transaction */
if (priv->count == priv->len - 1)
- outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE,
+ iowrite8(priv->cmd | SMBHSTCNT_LAST_BYTE,
SMBHSTCNT(priv));
} else if (priv->count < priv->len - 1) {
/* Write next byte, except for IRQ after last byte */
- outb_p(priv->data[++priv->count], SMBBLKDAT(priv));
+ iowrite8(priv->data[++priv->count], SMBBLKDAT(priv));
}
}
@@ -595,7 +590,7 @@ static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
{
unsigned short addr;
- addr = inb_p(SMBNTFDADD(priv)) >> 1;
+ addr = ioread8(SMBNTFDADD(priv)) >> 1;
/*
* With the tested platforms, reading SMBNTFDDAT (22 + (p)->smba)
@@ -605,7 +600,7 @@ static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
i2c_handle_smbus_host_notify(&priv->adapter, addr);
/* clear Host Notify bit and return */
- outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
+ iowrite8(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
return IRQ_HANDLED;
}
@@ -636,12 +631,12 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
return IRQ_NONE;
if (priv->features & FEATURE_HOST_NOTIFY) {
- status = inb_p(SMBSLVSTS(priv));
+ status = ioread8(SMBSLVSTS(priv));
if (status & SMBSLVSTS_HST_NTFY_STS)
return i801_host_notify_isr(priv);
}
- status = inb_p(SMBHSTSTS(priv));
+ status = ioread8(SMBHSTSTS(priv));
if ((status & (SMBHSTSTS_BYTE_DONE | STATUS_ERROR_FLAGS)) == SMBHSTSTS_BYTE_DONE)
i801_isr_byte_done(priv);
@@ -651,7 +646,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
* so clear it always when the status is set.
*/
status &= STATUS_FLAGS | SMBHSTSTS_SMBALERT_STS;
- outb_p(status, SMBHSTSTS(priv));
+ iowrite8(status, SMBHSTSTS(priv));
status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
if (status) {
@@ -683,8 +678,8 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
len = data->block[0];
if (read_write == I2C_SMBUS_WRITE) {
- outb_p(len, SMBHSTDAT0(priv));
- outb_p(data->block[1], SMBBLKDAT(priv));
+ iowrite8(len, SMBHSTDAT0(priv));
+ iowrite8(data->block[1], SMBBLKDAT(priv));
}
if (command == I2C_SMBUS_I2C_BLOCK_DATA &&
@@ -703,14 +698,14 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
priv->data = &data->block[1];
reinit_completion(&priv->done);
- outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
+ iowrite8(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
result = wait_for_completion_timeout(&priv->done, adap->timeout);
return result ? priv->status : -ETIMEDOUT;
}
if (len == 1 && read_write == I2C_SMBUS_READ)
smbcmd |= SMBHSTCNT_LAST_BYTE;
- outb_p(smbcmd | SMBHSTCNT_START, SMBHSTCNT(priv));
+ iowrite8(smbcmd | SMBHSTCNT_START, SMBHSTCNT(priv));
for (i = 1; i <= len; i++) {
status = i801_wait_byte_done(priv);
@@ -726,27 +721,27 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
len = i801_get_block_len(priv);
if (len < 0) {
/* Recover */
- while (inb_p(SMBHSTSTS(priv)) &
+ while (ioread8(SMBHSTSTS(priv)) &
SMBHSTSTS_HOST_BUSY)
- outb_p(SMBHSTSTS_BYTE_DONE,
+ iowrite8(SMBHSTSTS_BYTE_DONE,
SMBHSTSTS(priv));
- outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
+ iowrite8(SMBHSTSTS_INTR, SMBHSTSTS(priv));
return -EPROTO;
}
data->block[0] = len;
}
if (read_write == I2C_SMBUS_READ) {
- data->block[i] = inb_p(SMBBLKDAT(priv));
+ data->block[i] = ioread8(SMBBLKDAT(priv));
if (i == len - 1)
- outb_p(smbcmd | SMBHSTCNT_LAST_BYTE, SMBHSTCNT(priv));
+ iowrite8(smbcmd | SMBHSTCNT_LAST_BYTE, SMBHSTCNT(priv));
}
if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
- outb_p(data->block[i+1], SMBBLKDAT(priv));
+ iowrite8(data->block[i+1], SMBBLKDAT(priv));
/* signals SMBBLKDAT ready */
- outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
+ iowrite8(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
}
return i801_wait_intr(priv);
@@ -754,7 +749,7 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
static void i801_set_hstadd(struct i801_priv *priv, u8 addr, char read_write)
{
- outb_p((addr << 1) | (read_write & 0x01), SMBHSTADD(priv));
+ iowrite8((addr << 1) | (read_write & 0x01), SMBHSTADD(priv));
}
/* Single value transaction function */
@@ -771,30 +766,30 @@ static int i801_simple_transaction(struct i801_priv *priv, union i2c_smbus_data
case I2C_SMBUS_BYTE:
i801_set_hstadd(priv, addr, read_write);
if (read_write == I2C_SMBUS_WRITE)
- outb_p(hstcmd, SMBHSTCMD(priv));
+ iowrite8(hstcmd, SMBHSTCMD(priv));
xact = I801_BYTE;
break;
case I2C_SMBUS_BYTE_DATA:
i801_set_hstadd(priv, addr, read_write);
if (read_write == I2C_SMBUS_WRITE)
- outb_p(data->byte, SMBHSTDAT0(priv));
- outb_p(hstcmd, SMBHSTCMD(priv));
+ iowrite8(data->byte, SMBHSTDAT0(priv));
+ iowrite8(hstcmd, SMBHSTCMD(priv));
xact = I801_BYTE_DATA;
break;
case I2C_SMBUS_WORD_DATA:
i801_set_hstadd(priv, addr, read_write);
if (read_write == I2C_SMBUS_WRITE) {
- outb_p(data->word & 0xff, SMBHSTDAT0(priv));
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
+ iowrite8(data->word & 0xff, SMBHSTDAT0(priv));
+ iowrite8((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
}
- outb_p(hstcmd, SMBHSTCMD(priv));
+ iowrite8(hstcmd, SMBHSTCMD(priv));
xact = I801_WORD_DATA;
break;
case I2C_SMBUS_PROC_CALL:
i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
- outb_p(data->word & 0xff, SMBHSTDAT0(priv));
- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
- outb_p(hstcmd, SMBHSTCMD(priv));
+ iowrite8(data->word & 0xff, SMBHSTDAT0(priv));
+ iowrite8((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
+ iowrite8(hstcmd, SMBHSTCMD(priv));
read_write = I2C_SMBUS_READ;
xact = I801_PROC_CALL;
break;
@@ -810,12 +805,12 @@ static int i801_simple_transaction(struct i801_priv *priv, union i2c_smbus_data
switch (command) {
case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0(priv));
+ data->byte = ioread8(SMBHSTDAT0(priv));
break;
case I2C_SMBUS_WORD_DATA:
case I2C_SMBUS_PROC_CALL:
- data->word = inb_p(SMBHSTDAT0(priv)) +
- (inb_p(SMBHSTDAT1(priv)) << 8);
+ data->word = ioread8(SMBHSTDAT0(priv)) +
+ (ioread8(SMBHSTDAT1(priv)) << 8);
break;
}
@@ -836,7 +831,7 @@ static int i801_smbus_block_transaction(struct i801_priv *priv, union i2c_smbus_
i801_set_hstadd(priv, addr, I2C_SMBUS_WRITE);
else
i801_set_hstadd(priv, addr, read_write);
- outb_p(hstcmd, SMBHSTCMD(priv));
+ iowrite8(hstcmd, SMBHSTCMD(priv));
if (priv->features & FEATURE_BLOCK_BUFFER)
return i801_block_transaction_by_block(priv, data, read_write, command);
@@ -862,9 +857,9 @@ static int i801_i2c_block_transaction(struct i801_priv *priv, union i2c_smbus_da
/* NB: page 240 of ICH5 datasheet shows that DATA1 is the cmd field when reading */
if (read_write == I2C_SMBUS_READ)
- outb_p(hstcmd, SMBHSTDAT1(priv));
+ iowrite8(hstcmd, SMBHSTDAT1(priv));
else
- outb_p(hstcmd, SMBHSTCMD(priv));
+ iowrite8(hstcmd, SMBHSTCMD(priv));
if (read_write == I2C_SMBUS_WRITE) {
/* set I2C_EN bit in configuration register */
@@ -907,9 +902,9 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
&& size != I2C_SMBUS_I2C_BLOCK_DATA;
if (hwpec) /* enable/disable hardware PEC */
- outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
+ iowrite8(ioread8(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
else
- outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
+ iowrite8(ioread8(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
SMBAUXCTL(priv));
if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_BLOCK_PROC_CALL)
@@ -925,13 +920,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
* time, so we forcibly disable it after every transaction.
*/
if (hwpec)
- outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
+ iowrite8(ioread8(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
out:
/*
* Unlock the SMBus device for use by BIOS/ACPI,
* and clear status flags if not done already.
*/
- outb_p(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
+ iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
pm_runtime_mark_last_busy(&priv->pci_dev->dev);
pm_runtime_put_autosuspend(&priv->pci_dev->dev);
@@ -968,11 +963,11 @@ static void i801_enable_host_notify(struct i2c_adapter *adapter)
* from the SMB_ALERT signal because the driver does not support
* SMBus Alert.
*/
- outb_p(SMBSLVCMD_HST_NTFY_INTREN | SMBSLVCMD_SMBALERT_DISABLE |
+ iowrite8(SMBSLVCMD_HST_NTFY_INTREN | SMBSLVCMD_SMBALERT_DISABLE |
priv->original_slvcmd, SMBSLVCMD(priv));
/* clear Host Notify bit to allow a new notification */
- outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
+ iowrite8(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv));
}
static void i801_disable_host_notify(struct i801_priv *priv)
@@ -980,7 +975,7 @@ static void i801_disable_host_notify(struct i801_priv *priv)
if (!(priv->features & FEATURE_HOST_NOTIFY))
return;
- outb_p(priv->original_slvcmd, SMBSLVCMD(priv));
+ iowrite8(priv->original_slvcmd, SMBSLVCMD(priv));
}
static const struct i2c_algorithm smbus_algorithm = {
@@ -1438,14 +1433,14 @@ static void i801_add_tco(struct i801_priv *priv)
priv->tco_pdev = i801_add_tco_spt(pci_dev, tco_res);
if (IS_ERR(priv->tco_pdev))
- dev_warn(&pci_dev->dev, "failed to create iTCO device\n");
+ pci_warn(pci_dev, "failed to create iTCO device\n");
}
#ifdef CONFIG_ACPI
static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv,
acpi_physical_address address)
{
- return address >= priv->smba &&
+ return address >= pci_resource_start(priv->pci_dev, SMBBAR) &&
address <= pci_resource_end(priv->pci_dev, SMBBAR);
}
@@ -1467,8 +1462,8 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
priv->acpi_reserved = true;
- dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
- dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n");
+ pci_warn(pdev, "BIOS is accessing SMBus registers\n");
+ pci_warn(pdev, "Driver SMBus register access inhibited\n");
/*
* BIOS is accessing the host controller so prevent it from
@@ -1522,13 +1517,13 @@ static void i801_setup_hstcfg(struct i801_priv *priv)
static void i801_restore_regs(struct i801_priv *priv)
{
- outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
+ iowrite8(priv->original_hstcnt, SMBHSTCNT(priv));
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg);
}
static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- int err, i;
+ int err, i, bar = SMBBAR;
struct i801_priv *priv;
priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
@@ -1549,8 +1544,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* Disable features on user request */
for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
if (priv->features & disable_features & (1 << i))
- dev_notice(&dev->dev, "%s disabled by user\n",
- i801_feature_names[i]);
+ pci_notice(dev, "%s disabled by user\n", i801_feature_names[i]);
}
priv->features &= ~disable_features;
@@ -1564,48 +1558,46 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
*/
err = pci_enable_device(dev);
if (err) {
- dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
- err);
+ pci_err(dev, "Failed to enable SMBus PCI device (%d)\n", err);
return err;
}
/* Determine the address of the SMBus area */
- priv->smba = pci_resource_start(dev, SMBBAR);
- if (!priv->smba) {
- dev_err(&dev->dev,
- "SMBus base address uninitialized, upgrade BIOS\n");
+ if (!pci_resource_start(dev, SMBBAR)) {
+ pci_err(dev, "SMBus base address uninitialized, upgrade BIOS\n");
return -ENODEV;
}
if (i801_acpi_probe(priv))
return -ENODEV;
- err = pcim_iomap_regions(dev, 1 << SMBBAR, DRV_NAME);
- if (err) {
- dev_err(&dev->dev,
- "Failed to request SMBus region 0x%lx-0x%Lx\n",
- priv->smba,
- (unsigned long long)pci_resource_end(dev, SMBBAR));
+ if (pci_resource_flags(dev, SMBBAR_MMIO) & IORESOURCE_MEM)
+ bar = SMBBAR_MMIO;
+
+ priv->smba = pcim_iomap_region(dev, bar, DRV_NAME);
+ if (IS_ERR(priv->smba)) {
+ pci_err(dev, "Failed to request SMBus region %pr\n",
+ pci_resource_n(dev, bar));
i801_acpi_remove(priv);
- return err;
+ return PTR_ERR(priv->smba);
}
- pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg);
+ pci_read_config_byte(dev, SMBHSTCFG, &priv->original_hstcfg);
i801_setup_hstcfg(priv);
if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN))
- dev_info(&dev->dev, "Enabling SMBus device\n");
+ pci_info(dev, "Enabling SMBus device\n");
if (priv->original_hstcfg & SMBHSTCFG_SMB_SMI_EN) {
- dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
+ pci_dbg(dev, "SMBus using interrupt SMI#\n");
/* Disable SMBus interrupt feature if SMBus using SMI# */
priv->features &= ~FEATURE_IRQ;
}
if (priv->original_hstcfg & SMBHSTCFG_SPD_WD)
- dev_info(&dev->dev, "SPD Write Disable is set\n");
+ pci_info(dev, "SPD Write Disable is set\n");
/* Clear special mode bits */
if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
- outb_p(inb_p(SMBAUXCTL(priv)) &
+ iowrite8(ioread8(SMBAUXCTL(priv)) &
~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
/* Default timeout in interrupt mode: 200 ms */
@@ -1620,7 +1612,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* Complain if an interrupt is already pending */
pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
if (pcists & PCI_STATUS_INTERRUPT)
- dev_warn(&dev->dev, "An interrupt is pending!\n");
+ pci_warn(dev, "An interrupt is pending!\n");
}
if (priv->features & FEATURE_IRQ) {
@@ -1629,12 +1621,11 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
- dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
- dev->irq, err);
+ pci_err(dev, "Failed to allocate irq %d: %d\n", dev->irq, err);
priv->features &= ~FEATURE_IRQ;
}
}
- dev_info(&dev->dev, "SMBus using %s\n",
+ pci_info(dev, "SMBus using %s\n",
priv->features & FEATURE_IRQ ? "PCI interrupt" : "polling");
/* Host notification uses an interrupt */
@@ -1642,9 +1633,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
priv->features &= ~FEATURE_HOST_NOTIFY;
/* Remember original Interrupt and Host Notify settings */
- priv->original_hstcnt = inb_p(SMBHSTCNT(priv)) & ~SMBHSTCNT_KILL;
+ priv->original_hstcnt = ioread8(SMBHSTCNT(priv)) & ~SMBHSTCNT_KILL;
if (priv->features & FEATURE_HOST_NOTIFY)
- priv->original_slvcmd = inb_p(SMBSLVCMD(priv));
+ priv->original_slvcmd = ioread8(SMBSLVCMD(priv));
i801_add_tco(priv);
@@ -1653,9 +1644,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
* to instantiante i2c_clients, do not change.
*/
snprintf(priv->adapter.name, sizeof(priv->adapter.name),
- "SMBus %s adapter at %04lx",
+ "SMBus %s adapter at %s",
(priv->features & FEATURE_IDF) ? "I801 IDF" : "I801",
- priv->smba);
+ pci_name(dev));
err = i2c_add_adapter(&priv->adapter);
if (err) {
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index c76c4116ddc7..6bf45d752ff9 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -512,19 +512,17 @@ static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,
static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
{
volatile struct iic_regs __iomem *iic = dev->vaddr;
- u16 addr = msg->addr;
DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx,
- addr, msg->flags & I2C_M_TEN ? 10 : 7);
+ msg->addr, msg->flags & I2C_M_TEN ? 10 : 7);
- if (msg->flags & I2C_M_TEN){
+ if (msg->flags & I2C_M_TEN) {
out_8(&iic->cntl, CNTL_AMD);
- out_8(&iic->lmadr, addr);
- out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06));
- }
- else {
+ out_8(&iic->lmadr, i2c_10bit_addr_lo_from_msg(msg));
+ out_8(&iic->hmadr, i2c_10bit_addr_hi_from_msg(msg) & ~I2C_M_RD);
+ } else {
out_8(&iic->cntl, 0);
- out_8(&iic->lmadr, addr << 1);
+ out_8(&iic->lmadr, i2c_8bit_addr_from_msg(msg) & ~I2C_M_RD);
}
}
diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c
index 02f75cf310aa..5d8b82ae6fd6 100644
--- a/drivers/i2c/busses/i2c-img-scb.c
+++ b/drivers/i2c/busses/i2c-img-scb.c
@@ -1122,7 +1122,7 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
time_left = wait_for_completion_timeout(&i2c->msg_complete,
IMG_I2C_TIMEOUT);
- del_timer_sync(&i2c->check_timer);
+ timer_delete_sync(&i2c->check_timer);
if (time_left == 0)
i2c->msg_status = -ETIMEDOUT;
diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c
new file mode 100644
index 000000000000..5965b4cf6220
--- /dev/null
+++ b/drivers/i2c/busses/i2c-k1.c
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024-2025 Troy Mitchell <troymitchell988@gmail.com>
+ */
+
+ #include <linux/clk.h>
+ #include <linux/i2c.h>
+ #include <linux/iopoll.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
+
+/* spacemit i2c registers */
+#define SPACEMIT_ICR 0x0 /* Control register */
+#define SPACEMIT_ISR 0x4 /* Status register */
+#define SPACEMIT_IDBR 0xc /* Data buffer register */
+#define SPACEMIT_IBMR 0x1c /* Bus monitor register */
+
+/* SPACEMIT_ICR register fields */
+#define SPACEMIT_CR_START BIT(0) /* start bit */
+#define SPACEMIT_CR_STOP BIT(1) /* stop bit */
+#define SPACEMIT_CR_ACKNAK BIT(2) /* send ACK(0) or NAK(1) */
+#define SPACEMIT_CR_TB BIT(3) /* transfer byte bit */
+/* Bits 4-7 are reserved */
+#define SPACEMIT_CR_MODE_FAST BIT(8) /* bus mode (master operation) */
+/* Bit 9 is reserved */
+#define SPACEMIT_CR_UR BIT(10) /* unit reset */
+/* Bits 11-12 are reserved */
+#define SPACEMIT_CR_SCLE BIT(13) /* master clock enable */
+#define SPACEMIT_CR_IUE BIT(14) /* unit enable */
+/* Bits 15-17 are reserved */
+#define SPACEMIT_CR_ALDIE BIT(18) /* enable arbitration interrupt */
+#define SPACEMIT_CR_DTEIE BIT(19) /* enable TX interrupts */
+#define SPACEMIT_CR_DRFIE BIT(20) /* enable RX interrupts */
+#define SPACEMIT_CR_GCD BIT(21) /* general call disable */
+#define SPACEMIT_CR_BEIE BIT(22) /* enable bus error ints */
+/* Bits 23-24 are reserved */
+#define SPACEMIT_CR_MSDIE BIT(25) /* master STOP detected int enable */
+#define SPACEMIT_CR_MSDE BIT(26) /* master STOP detected enable */
+#define SPACEMIT_CR_TXDONEIE BIT(27) /* transaction done int enable */
+#define SPACEMIT_CR_TXEIE BIT(28) /* transmit FIFO empty int enable */
+#define SPACEMIT_CR_RXHFIE BIT(29) /* receive FIFO half-full int enable */
+#define SPACEMIT_CR_RXFIE BIT(30) /* receive FIFO full int enable */
+#define SPACEMIT_CR_RXOVIE BIT(31) /* receive FIFO overrun int enable */
+
+#define SPACEMIT_I2C_INT_CTRL_MASK (SPACEMIT_CR_ALDIE | SPACEMIT_CR_DTEIE | \
+ SPACEMIT_CR_DRFIE | SPACEMIT_CR_BEIE | \
+ SPACEMIT_CR_TXDONEIE | SPACEMIT_CR_TXEIE | \
+ SPACEMIT_CR_RXHFIE | SPACEMIT_CR_RXFIE | \
+ SPACEMIT_CR_RXOVIE | SPACEMIT_CR_MSDIE)
+
+/* SPACEMIT_ISR register fields */
+/* Bits 0-13 are reserved */
+#define SPACEMIT_SR_ACKNAK BIT(14) /* ACK/NACK status */
+#define SPACEMIT_SR_UB BIT(15) /* unit busy */
+#define SPACEMIT_SR_IBB BIT(16) /* i2c bus busy */
+#define SPACEMIT_SR_EBB BIT(17) /* early bus busy */
+#define SPACEMIT_SR_ALD BIT(18) /* arbitration loss detected */
+#define SPACEMIT_SR_ITE BIT(19) /* TX buffer empty */
+#define SPACEMIT_SR_IRF BIT(20) /* RX buffer full */
+#define SPACEMIT_SR_GCAD BIT(21) /* general call address detected */
+#define SPACEMIT_SR_BED BIT(22) /* bus error no ACK/NAK */
+#define SPACEMIT_SR_SAD BIT(23) /* slave address detected */
+#define SPACEMIT_SR_SSD BIT(24) /* slave stop detected */
+/* Bit 25 is reserved */
+#define SPACEMIT_SR_MSD BIT(26) /* master stop detected */
+#define SPACEMIT_SR_TXDONE BIT(27) /* transaction done */
+#define SPACEMIT_SR_TXE BIT(28) /* TX FIFO empty */
+#define SPACEMIT_SR_RXHF BIT(29) /* RX FIFO half-full */
+#define SPACEMIT_SR_RXF BIT(30) /* RX FIFO full */
+#define SPACEMIT_SR_RXOV BIT(31) /* RX FIFO overrun */
+
+#define SPACEMIT_I2C_INT_STATUS_MASK (SPACEMIT_SR_RXOV | SPACEMIT_SR_RXF | SPACEMIT_SR_RXHF | \
+ SPACEMIT_SR_TXE | SPACEMIT_SR_TXDONE | SPACEMIT_SR_MSD | \
+ SPACEMIT_SR_SSD | SPACEMIT_SR_SAD | SPACEMIT_SR_BED | \
+ SPACEMIT_SR_GCAD | SPACEMIT_SR_IRF | SPACEMIT_SR_ITE | \
+ SPACEMIT_SR_ALD)
+
+/* SPACEMIT_IBMR register fields */
+#define SPACEMIT_BMR_SDA BIT(0) /* SDA line level */
+#define SPACEMIT_BMR_SCL BIT(1) /* SCL line level */
+
+/* i2c bus recover timeout: us */
+#define SPACEMIT_I2C_BUS_BUSY_TIMEOUT 100000
+
+#define SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ 100000 /* Hz */
+#define SPACEMIT_I2C_MAX_FAST_MODE_FREQ 400000 /* Hz */
+
+#define SPACEMIT_SR_ERR (SPACEMIT_SR_BED | SPACEMIT_SR_RXOV | SPACEMIT_SR_ALD)
+
+enum spacemit_i2c_state {
+ SPACEMIT_STATE_IDLE,
+ SPACEMIT_STATE_START,
+ SPACEMIT_STATE_READ,
+ SPACEMIT_STATE_WRITE,
+};
+
+/* i2c-spacemit driver's main struct */
+struct spacemit_i2c_dev {
+ struct device *dev;
+ struct i2c_adapter adapt;
+
+ /* hardware resources */
+ void __iomem *base;
+ int irq;
+ u32 clock_freq;
+
+ struct i2c_msg *msgs;
+ u32 msg_num;
+
+ /* index of the current message being processed */
+ u32 msg_idx;
+ u8 *msg_buf;
+ /* the number of unprocessed bytes remaining in the current message */
+ u32 unprocessed;
+
+ enum spacemit_i2c_state state;
+ bool read;
+ struct completion complete;
+ u32 status;
+};
+
+static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
+{
+ u32 val;
+
+ val = readl(i2c->base + SPACEMIT_ICR);
+ val |= SPACEMIT_CR_IUE;
+ writel(val, i2c->base + SPACEMIT_ICR);
+}
+
+static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
+{
+ u32 val;
+
+ val = readl(i2c->base + SPACEMIT_ICR);
+ val &= ~SPACEMIT_CR_IUE;
+ writel(val, i2c->base + SPACEMIT_ICR);
+}
+
+static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
+{
+ writel(SPACEMIT_CR_UR, i2c->base + SPACEMIT_ICR);
+ udelay(5);
+ writel(0, i2c->base + SPACEMIT_ICR);
+}
+
+static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
+{
+ dev_dbg(i2c->dev, "i2c error status: 0x%08x\n", i2c->status);
+
+ if (i2c->status & (SPACEMIT_SR_BED | SPACEMIT_SR_ALD)) {
+ spacemit_i2c_reset(i2c);
+ return -EAGAIN;
+ }
+
+ return i2c->status & SPACEMIT_SR_ACKNAK ? -ENXIO : -EIO;
+}
+
+static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
+{
+ u32 status;
+
+ /* if bus is locked, reset unit. 0: locked */
+ status = readl(i2c->base + SPACEMIT_IBMR);
+ if ((status & SPACEMIT_BMR_SDA) && (status & SPACEMIT_BMR_SCL))
+ return;
+
+ spacemit_i2c_reset(i2c);
+ usleep_range(10, 20);
+
+ /* check scl status again */
+ status = readl(i2c->base + SPACEMIT_IBMR);
+ if (!(status & SPACEMIT_BMR_SCL))
+ dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
+}
+
+static int spacemit_i2c_wait_bus_idle(struct spacemit_i2c_dev *i2c)
+{
+ int ret;
+ u32 val;
+
+ val = readl(i2c->base + SPACEMIT_ISR);
+ if (!(val & (SPACEMIT_SR_UB | SPACEMIT_SR_IBB)))
+ return 0;
+
+ ret = readl_poll_timeout(i2c->base + SPACEMIT_ISR,
+ val, !(val & (SPACEMIT_SR_UB | SPACEMIT_SR_IBB)),
+ 1500, SPACEMIT_I2C_BUS_BUSY_TIMEOUT);
+ if (ret)
+ spacemit_i2c_reset(i2c);
+
+ return ret;
+}
+
+static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c)
+{
+ /* in case bus is not released after transfer completes */
+ if (readl(i2c->base + SPACEMIT_ISR) & SPACEMIT_SR_EBB) {
+ spacemit_i2c_conditionally_reset_bus(i2c);
+ usleep_range(90, 150);
+ }
+}
+
+static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
+{
+ u32 val;
+
+ /*
+ * Unmask interrupt bits for all xfer mode:
+ * bus error, arbitration loss detected.
+ * For transaction complete signal, we use master stop
+ * interrupt, so we don't need to unmask SPACEMIT_CR_TXDONEIE.
+ */
+ val = SPACEMIT_CR_BEIE | SPACEMIT_CR_ALDIE;
+
+ /*
+ * Unmask interrupt bits for interrupt xfer mode:
+ * When IDBR receives a byte, an interrupt is triggered.
+ *
+ * For the tx empty interrupt, it will be enabled in the
+ * i2c_start function.
+ * Otherwise, it will cause an erroneous empty interrupt before i2c_start.
+ */
+ val |= SPACEMIT_CR_DRFIE;
+
+ if (i2c->clock_freq == SPACEMIT_I2C_MAX_FAST_MODE_FREQ)
+ val |= SPACEMIT_CR_MODE_FAST;
+
+ /* disable response to general call */
+ val |= SPACEMIT_CR_GCD;
+
+ /* enable SCL clock output */
+ val |= SPACEMIT_CR_SCLE;
+
+ /* enable master stop detected */
+ val |= SPACEMIT_CR_MSDE | SPACEMIT_CR_MSDIE;
+
+ writel(val, i2c->base + SPACEMIT_ICR);
+}
+
+static inline void
+spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask)
+{
+ writel(mask & SPACEMIT_I2C_INT_STATUS_MASK, i2c->base + SPACEMIT_ISR);
+}
+
+static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
+{
+ u32 target_addr_rw, val;
+ struct i2c_msg *cur_msg = i2c->msgs + i2c->msg_idx;
+
+ i2c->read = !!(cur_msg->flags & I2C_M_RD);
+
+ i2c->state = SPACEMIT_STATE_START;
+
+ target_addr_rw = (cur_msg->addr & 0x7f) << 1;
+ if (cur_msg->flags & I2C_M_RD)
+ target_addr_rw |= 1;
+
+ writel(target_addr_rw, i2c->base + SPACEMIT_IDBR);
+
+ /* send start pulse */
+ val = readl(i2c->base + SPACEMIT_ICR);
+ val &= ~SPACEMIT_CR_STOP;
+ val |= SPACEMIT_CR_START | SPACEMIT_CR_TB | SPACEMIT_CR_DTEIE;
+ writel(val, i2c->base + SPACEMIT_ICR);
+}
+
+static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
+{
+ u32 val;
+
+ val = readl(i2c->base + SPACEMIT_ICR);
+ val |= SPACEMIT_CR_STOP | SPACEMIT_CR_ALDIE | SPACEMIT_CR_TB;
+
+ if (i2c->read)
+ val |= SPACEMIT_CR_ACKNAK;
+
+ writel(val, i2c->base + SPACEMIT_ICR);
+}
+
+static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
+{
+ unsigned long time_left;
+ struct i2c_msg *msg;
+
+ for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
+ msg = &i2c->msgs[i2c->msg_idx];
+ i2c->msg_buf = msg->buf;
+ i2c->unprocessed = msg->len;
+ i2c->status = 0;
+
+ reinit_completion(&i2c->complete);
+
+ spacemit_i2c_start(i2c);
+
+ time_left = wait_for_completion_timeout(&i2c->complete,
+ i2c->adapt.timeout);
+ if (!time_left) {
+ dev_err(i2c->dev, "msg completion timeout\n");
+ spacemit_i2c_conditionally_reset_bus(i2c);
+ spacemit_i2c_reset(i2c);
+ return -ETIMEDOUT;
+ }
+
+ if (i2c->status & SPACEMIT_SR_ERR)
+ return spacemit_i2c_handle_err(i2c);
+ }
+
+ return 0;
+}
+
+static bool spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
+{
+ if (i2c->msg_idx != i2c->msg_num - 1)
+ return false;
+
+ if (i2c->read)
+ return i2c->unprocessed == 1;
+
+ return !i2c->unprocessed;
+}
+
+static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c)
+{
+ /* if transfer completes, SPACEMIT_ISR will handle it */
+ if (i2c->status & SPACEMIT_SR_MSD)
+ return;
+
+ if (i2c->unprocessed) {
+ writel(*i2c->msg_buf++, i2c->base + SPACEMIT_IDBR);
+ i2c->unprocessed--;
+ return;
+ }
+
+ /* SPACEMIT_STATE_IDLE avoids trigger next byte */
+ i2c->state = SPACEMIT_STATE_IDLE;
+ complete(&i2c->complete);
+}
+
+static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c)
+{
+ if (i2c->unprocessed) {
+ *i2c->msg_buf++ = readl(i2c->base + SPACEMIT_IDBR);
+ i2c->unprocessed--;
+ }
+
+ /* if transfer completes, SPACEMIT_ISR will handle it */
+ if (i2c->status & (SPACEMIT_SR_MSD | SPACEMIT_SR_ACKNAK))
+ return;
+
+ /* it has to append stop bit in icr that read last byte */
+ if (i2c->unprocessed)
+ return;
+
+ /* SPACEMIT_STATE_IDLE avoids trigger next byte */
+ i2c->state = SPACEMIT_STATE_IDLE;
+ complete(&i2c->complete);
+}
+
+static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c)
+{
+ i2c->state = i2c->read ? SPACEMIT_STATE_READ : SPACEMIT_STATE_WRITE;
+ if (i2c->state == SPACEMIT_STATE_WRITE)
+ spacemit_i2c_handle_write(i2c);
+}
+
+static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
+{
+ u32 val;
+
+ /*
+ * Send transaction complete signal:
+ * error happens, detect master stop
+ */
+ if (!(i2c->status & (SPACEMIT_SR_ERR | SPACEMIT_SR_MSD)))
+ return;
+
+ /*
+ * Here the transaction is already done, we don't need any
+ * other interrupt signals from now, in case any interrupt
+ * happens before spacemit_i2c_xfer to disable irq and i2c unit,
+ * we mask all the interrupt signals and clear the interrupt
+ * status.
+ */
+ val = readl(i2c->base + SPACEMIT_ICR);
+ val &= ~SPACEMIT_I2C_INT_CTRL_MASK;
+ writel(val, i2c->base + SPACEMIT_ICR);
+
+ spacemit_i2c_clear_int_status(i2c, SPACEMIT_I2C_INT_STATUS_MASK);
+
+ i2c->state = SPACEMIT_STATE_IDLE;
+ complete(&i2c->complete);
+}
+
+static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
+{
+ struct spacemit_i2c_dev *i2c = devid;
+ u32 status, val;
+
+ status = readl(i2c->base + SPACEMIT_ISR);
+ if (!status)
+ return IRQ_HANDLED;
+
+ i2c->status = status;
+
+ spacemit_i2c_clear_int_status(i2c, status);
+
+ if (i2c->status & SPACEMIT_SR_ERR)
+ goto err_out;
+
+ val = readl(i2c->base + SPACEMIT_ICR);
+ val &= ~(SPACEMIT_CR_TB | SPACEMIT_CR_ACKNAK | SPACEMIT_CR_STOP | SPACEMIT_CR_START);
+ writel(val, i2c->base + SPACEMIT_ICR);
+
+ switch (i2c->state) {
+ case SPACEMIT_STATE_START:
+ spacemit_i2c_handle_start(i2c);
+ break;
+ case SPACEMIT_STATE_READ:
+ spacemit_i2c_handle_read(i2c);
+ break;
+ case SPACEMIT_STATE_WRITE:
+ spacemit_i2c_handle_write(i2c);
+ break;
+ default:
+ break;
+ }
+
+ if (i2c->state != SPACEMIT_STATE_IDLE) {
+ if (spacemit_i2c_is_last_msg(i2c)) {
+ /* trigger next byte with stop */
+ spacemit_i2c_stop(i2c);
+ } else {
+ /* trigger next byte */
+ val |= SPACEMIT_CR_ALDIE | SPACEMIT_CR_TB;
+ writel(val, i2c->base + SPACEMIT_ICR);
+ }
+ }
+
+err_out:
+ spacemit_i2c_err_check(i2c);
+ return IRQ_HANDLED;
+}
+
+static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c)
+{
+ unsigned long timeout;
+ int idx = 0, cnt = 0;
+
+ for (; idx < i2c->msg_num; idx++)
+ cnt += (i2c->msgs + idx)->len + 1;
+
+ /*
+ * Multiply by 9 because each byte in I2C transmission requires
+ * 9 clock cycles: 8 bits of data plus 1 ACK/NACK bit.
+ */
+ timeout = cnt * 9 * USEC_PER_SEC / i2c->clock_freq;
+
+ i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 10) / i2c->msg_num;
+}
+
+static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg *msgs, int num)
+{
+ struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt);
+ int ret;
+
+ i2c->msgs = msgs;
+ i2c->msg_num = num;
+
+ spacemit_i2c_calc_timeout(i2c);
+
+ spacemit_i2c_init(i2c);
+
+ spacemit_i2c_enable(i2c);
+
+ ret = spacemit_i2c_wait_bus_idle(i2c);
+ if (!ret)
+ spacemit_i2c_xfer_msg(i2c);
+ else if (ret < 0)
+ dev_dbg(i2c->dev, "i2c transfer error: %d\n", ret);
+ else
+ spacemit_i2c_check_bus_release(i2c);
+
+ spacemit_i2c_disable(i2c);
+
+ if (ret == -ETIMEDOUT || ret == -EAGAIN)
+ dev_err(i2c->dev, "i2c transfer failed, ret %d err 0x%lx\n",
+ ret, i2c->status & SPACEMIT_SR_ERR);
+
+ return ret < 0 ? ret : num;
+}
+
+static u32 spacemit_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+static const struct i2c_algorithm spacemit_i2c_algo = {
+ .xfer = spacemit_i2c_xfer,
+ .functionality = spacemit_i2c_func,
+};
+
+static int spacemit_i2c_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ struct device *dev = &pdev->dev;
+ struct device_node *of_node = pdev->dev.of_node;
+ struct spacemit_i2c_dev *i2c;
+ int ret;
+
+ i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(of_node, "clock-frequency", &i2c->clock_freq);
+ if (ret && ret != -EINVAL)
+ dev_warn(dev, "failed to read clock-frequency property: %d\n", ret);
+
+ /* For now, this driver doesn't support high-speed. */
+ if (!i2c->clock_freq || i2c->clock_freq > SPACEMIT_I2C_MAX_FAST_MODE_FREQ) {
+ dev_warn(dev, "unsupported clock frequency %u; using %u\n",
+ i2c->clock_freq, SPACEMIT_I2C_MAX_FAST_MODE_FREQ);
+ i2c->clock_freq = SPACEMIT_I2C_MAX_FAST_MODE_FREQ;
+ } else if (i2c->clock_freq < SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ) {
+ dev_warn(dev, "unsupported clock frequency %u; using %u\n",
+ i2c->clock_freq, SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ);
+ i2c->clock_freq = SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ;
+ }
+
+ i2c->dev = &pdev->dev;
+
+ i2c->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(i2c->base))
+ return dev_err_probe(dev, PTR_ERR(i2c->base), "failed to do ioremap");
+
+ i2c->irq = platform_get_irq(pdev, 0);
+ if (i2c->irq < 0)
+ return dev_err_probe(dev, i2c->irq, "failed to get irq resource");
+
+ ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
+ IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to request irq");
+
+ clk = devm_clk_get_enabled(dev, "func");
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk), "failed to enable func clock");
+
+ clk = devm_clk_get_enabled(dev, "bus");
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk), "failed to enable bus clock");
+
+ spacemit_i2c_reset(i2c);
+
+ i2c_set_adapdata(&i2c->adapt, i2c);
+ i2c->adapt.owner = THIS_MODULE;
+ i2c->adapt.algo = &spacemit_i2c_algo;
+ i2c->adapt.dev.parent = i2c->dev;
+ i2c->adapt.nr = pdev->id;
+
+ i2c->adapt.dev.of_node = of_node;
+
+ strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
+
+ init_completion(&i2c->complete);
+
+ platform_set_drvdata(pdev, i2c);
+
+ ret = i2c_add_numbered_adapter(&i2c->adapt);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
+
+ return 0;
+}
+
+static void spacemit_i2c_remove(struct platform_device *pdev)
+{
+ struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adapt);
+}
+
+static const struct of_device_id spacemit_i2c_of_match[] = {
+ { .compatible = "spacemit,k1-i2c", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match);
+
+static struct platform_driver spacemit_i2c_driver = {
+ .probe = spacemit_i2c_probe,
+ .remove = spacemit_i2c_remove,
+ .driver = {
+ .name = "i2c-k1",
+ .of_match_table = spacemit_i2c_of_match,
+ },
+};
+module_platform_driver(spacemit_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC");
diff --git a/drivers/i2c/busses/i2c-kempld.c b/drivers/i2c/busses/i2c-kempld.c
index 212196af68ba..9b4c7cba62b6 100644
--- a/drivers/i2c/busses/i2c-kempld.c
+++ b/drivers/i2c/busses/i2c-kempld.c
@@ -115,9 +115,7 @@ static int kempld_i2c_process(struct kempld_i2c_data *i2c)
if (i2c->state == STATE_ADDR) {
/* 10 bit address? */
if (i2c->msg->flags & I2C_M_TEN) {
- addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6);
- /* Set read bit if necessary */
- addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;
+ addr = i2c_10bit_addr_hi_from_msg(msg);
i2c->state = STATE_ADDR10;
} else {
addr = i2c_8bit_addr_from_msg(i2c->msg);
@@ -132,10 +130,12 @@ static int kempld_i2c_process(struct kempld_i2c_data *i2c)
/* Second part of 10 bit addressing */
if (i2c->state == STATE_ADDR10) {
- kempld_write8(pld, KEMPLD_I2C_DATA, i2c->msg->addr & 0xff);
+ addr = i2c_10bit_addr_lo_from_msg(msg);
+ i2c->state = STATE_START;
+
+ kempld_write8(pld, KEMPLD_I2C_DATA, addr);
kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
- i2c->state = STATE_START;
return 0;
}
diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c
index 21f67f3b65b6..280dde53d7f3 100644
--- a/drivers/i2c/busses/i2c-mlxbf.c
+++ b/drivers/i2c/busses/i2c-mlxbf.c
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -495,65 +496,6 @@ static u8 mlxbf_i2c_bus_count;
static struct mutex mlxbf_i2c_bus_lock;
-/*
- * Function to poll a set of bits at a specific address; it checks whether
- * the bits are equal to zero when eq_zero is set to 'true', and not equal
- * to zero when eq_zero is set to 'false'.
- * Note that the timeout is given in microseconds.
- */
-static u32 mlxbf_i2c_poll(void __iomem *io, u32 addr, u32 mask,
- bool eq_zero, u32 timeout)
-{
- u32 bits;
-
- timeout = (timeout / MLXBF_I2C_POLL_FREQ_IN_USEC) + 1;
-
- do {
- bits = readl(io + addr) & mask;
- if (eq_zero ? bits == 0 : bits != 0)
- return eq_zero ? 1 : bits;
- udelay(MLXBF_I2C_POLL_FREQ_IN_USEC);
- } while (timeout-- != 0);
-
- return 0;
-}
-
-/*
- * SW must make sure that the SMBus Master GW is idle before starting
- * a transaction. Accordingly, this function polls the Master FSM stop
- * bit; it returns false when the bit is asserted, true if not.
- */
-static bool mlxbf_i2c_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv)
-{
- u32 mask = MLXBF_I2C_SMBUS_MASTER_FSM_STOP_MASK;
- u32 addr = priv->chip->smbus_master_fsm_off;
- u32 timeout = MLXBF_I2C_SMBUS_TIMEOUT;
-
- if (mlxbf_i2c_poll(priv->mst->io, addr, mask, true, timeout))
- return true;
-
- return false;
-}
-
-/*
- * wait for the lock to be released before acquiring it.
- */
-static bool mlxbf_i2c_smbus_master_lock(struct mlxbf_i2c_priv *priv)
-{
- if (mlxbf_i2c_poll(priv->mst->io, MLXBF_I2C_SMBUS_MASTER_GW,
- MLXBF_I2C_MASTER_LOCK_BIT, true,
- MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT))
- return true;
-
- return false;
-}
-
-static void mlxbf_i2c_smbus_master_unlock(struct mlxbf_i2c_priv *priv)
-{
- /* Clear the gw to clear the lock */
- writel(0, priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW);
-}
-
static bool mlxbf_i2c_smbus_transaction_success(u32 master_status,
u32 cause_status)
{
@@ -583,6 +525,7 @@ static int mlxbf_i2c_smbus_check_status(struct mlxbf_i2c_priv *priv)
{
u32 master_status_bits;
u32 cause_status_bits;
+ u32 bits;
/*
* GW busy bit is raised by the driver and cleared by the HW
@@ -591,9 +534,9 @@ static int mlxbf_i2c_smbus_check_status(struct mlxbf_i2c_priv *priv)
* then read the cause and master status bits to determine if
* errors occurred during the transaction.
*/
- mlxbf_i2c_poll(priv->mst->io, MLXBF_I2C_SMBUS_MASTER_GW,
- MLXBF_I2C_MASTER_BUSY_BIT, true,
- MLXBF_I2C_SMBUS_TIMEOUT);
+ readl_poll_timeout_atomic(priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW,
+ bits, !(bits & MLXBF_I2C_MASTER_BUSY_BIT),
+ MLXBF_I2C_POLL_FREQ_IN_USEC, MLXBF_I2C_SMBUS_TIMEOUT);
/* Read cause status bits. */
cause_status_bits = readl(priv->mst_cause->io +
@@ -740,7 +683,8 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
u8 read_en, write_en, block_en, pec_en;
u8 slave, flags, addr;
u8 *read_buf;
- int ret = 0;
+ u32 bits;
+ int ret;
if (request->operation_cnt > MLXBF_I2C_SMBUS_MAX_OP_CNT)
return -EINVAL;
@@ -760,11 +704,22 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
* Try to acquire the smbus gw lock before any reads of the GW register since
* a read sets the lock.
*/
- if (WARN_ON(!mlxbf_i2c_smbus_master_lock(priv)))
+ ret = readl_poll_timeout_atomic(priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW,
+ bits, !(bits & MLXBF_I2C_MASTER_LOCK_BIT),
+ MLXBF_I2C_POLL_FREQ_IN_USEC,
+ MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT);
+ if (WARN_ON(ret))
return -EBUSY;
- /* Check whether the HW is idle */
- if (WARN_ON(!mlxbf_i2c_smbus_master_wait_for_idle(priv))) {
+ /*
+ * SW must make sure that the SMBus Master GW is idle before starting
+ * a transaction. Accordingly, this call polls the Master FSM stop bit;
+ * it returns -ETIMEDOUT when the bit is asserted, 0 if not.
+ */
+ ret = readl_poll_timeout_atomic(priv->mst->io + priv->chip->smbus_master_fsm_off,
+ bits, !(bits & MLXBF_I2C_SMBUS_MASTER_FSM_STOP_MASK),
+ MLXBF_I2C_POLL_FREQ_IN_USEC, MLXBF_I2C_SMBUS_TIMEOUT);
+ if (WARN_ON(ret)) {
ret = -EBUSY;
goto out_unlock;
}
@@ -855,7 +810,8 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
}
out_unlock:
- mlxbf_i2c_smbus_master_unlock(priv);
+ /* Clear the gw to clear the lock */
+ writel(0, priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW);
return ret;
}
@@ -1829,18 +1785,6 @@ static bool mlxbf_i2c_has_coalesce(struct mlxbf_i2c_priv *priv, bool *read,
return true;
}
-static bool mlxbf_i2c_slave_wait_for_idle(struct mlxbf_i2c_priv *priv,
- u32 timeout)
-{
- u32 mask = MLXBF_I2C_CAUSE_S_GW_BUSY_FALL;
- u32 addr = MLXBF_I2C_CAUSE_ARBITER;
-
- if (mlxbf_i2c_poll(priv->slv_cause->io, addr, mask, false, timeout))
- return true;
-
- return false;
-}
-
static struct i2c_client *mlxbf_i2c_get_slave_from_addr(
struct mlxbf_i2c_priv *priv, u8 addr)
{
@@ -1943,7 +1887,9 @@ static int mlxbf_i2c_irq_send(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
* Wait until the transfer is completed; the driver will wait
* until the GW is idle, a cause will rise on fall of GW busy.
*/
- mlxbf_i2c_slave_wait_for_idle(priv, MLXBF_I2C_SMBUS_TIMEOUT);
+ readl_poll_timeout_atomic(priv->slv_cause->io + MLXBF_I2C_CAUSE_ARBITER,
+ data32, data32 & MLXBF_I2C_CAUSE_S_GW_BUSY_FALL,
+ MLXBF_I2C_POLL_FREQ_IN_USEC, MLXBF_I2C_SMBUS_TIMEOUT);
clear_csr:
/* Release the Slave GW. */
diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
index 2103f21f9ddd..0a288c998419 100644
--- a/drivers/i2c/busses/i2c-mt7621.c
+++ b/drivers/i2c/busses/i2c-mt7621.c
@@ -164,22 +164,18 @@ static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
/* write address */
if (pmsg->flags & I2C_M_TEN) {
/* 10 bits address */
- addr = 0xf0 | ((pmsg->addr >> 7) & 0x06);
- addr |= (pmsg->addr & 0xff) << 8;
- if (pmsg->flags & I2C_M_RD)
- addr |= 1;
- iowrite32(addr, i2c->base + REG_SM0D0_REG);
- ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, 2);
- if (ret)
- goto err_timeout;
+ addr = i2c_10bit_addr_hi_from_msg(pmsg);
+ addr |= i2c_10bit_addr_lo_from_msg(pmsg) << 8;
+ len = 2;
} else {
/* 7 bits address */
addr = i2c_8bit_addr_from_msg(pmsg);
- iowrite32(addr, i2c->base + REG_SM0D0_REG);
- ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, 1);
- if (ret)
- goto err_timeout;
+ len = 1;
}
+ iowrite32(addr, i2c->base + REG_SM0D0_REG);
+ ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, len);
+ if (ret)
+ goto err_timeout;
/* check address ACK */
if (!(pmsg->flags & I2C_M_IGNORE_NAK)) {
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 874309580c33..8fc26a511320 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -27,7 +27,6 @@
#include <linux/err.h>
#include <linux/delay.h>
-#define MV64XXX_I2C_ADDR_ADDR(val) ((val & 0x7f) << 1)
#define MV64XXX_I2C_BAUD_DIV_N(val) (val & 0x7)
#define MV64XXX_I2C_BAUD_DIV_M(val) ((val & 0xf) << 3)
@@ -176,22 +175,17 @@ static void
mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
struct i2c_msg *msg)
{
- u32 dir = 0;
-
drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
MV64XXX_I2C_REG_CONTROL_TWSIEN;
if (!drv_data->atomic)
drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_INTEN;
- if (msg->flags & I2C_M_RD)
- dir = 1;
-
if (msg->flags & I2C_M_TEN) {
- drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
- drv_data->addr2 = (u32)msg->addr & 0xff;
+ drv_data->addr1 = i2c_10bit_addr_hi_from_msg(msg);
+ drv_data->addr2 = i2c_10bit_addr_lo_from_msg(msg);
} else {
- drv_data->addr1 = MV64XXX_I2C_ADDR_ADDR((u32)msg->addr) | dir;
+ drv_data->addr1 = i2c_8bit_addr_from_msg(msg);
drv_data->addr2 = 0;
}
}
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 16cc34a0526e..baf6b27f3752 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -45,7 +45,7 @@ static bool octeon_i2c_test_iflg(struct octeon_i2c *i2c)
* octeon_i2c_wait - wait for the IFLG to be set
* @i2c: The struct octeon_i2c
*
- * Returns 0 on success, otherwise a negative errno.
+ * Returns: 0 on success, otherwise a negative errno.
*/
static int octeon_i2c_wait(struct octeon_i2c *i2c)
{
@@ -139,7 +139,7 @@ static void octeon_i2c_hlc_disable(struct octeon_i2c *i2c)
* octeon_i2c_hlc_wait - wait for an HLC operation to complete
* @i2c: The struct octeon_i2c
*
- * Returns 0 on success, otherwise -ETIMEDOUT.
+ * Returns: 0 on success, otherwise -ETIMEDOUT.
*/
static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
{
@@ -273,7 +273,7 @@ static int octeon_i2c_recovery(struct octeon_i2c *i2c)
* octeon_i2c_start - send START to the bus
* @i2c: The struct octeon_i2c
*
- * Returns 0 on success, otherwise a negative errno.
+ * Returns: 0 on success, otherwise a negative errno.
*/
static int octeon_i2c_start(struct octeon_i2c *i2c)
{
@@ -314,7 +314,7 @@ static void octeon_i2c_stop(struct octeon_i2c *i2c)
*
* The address is sent over the bus, then the data is read.
*
- * Returns 0 on success, otherwise a negative errno.
+ * Returns: 0 on success, otherwise a negative errno.
*/
static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
u8 *data, u16 *rlength, bool recv_len)
@@ -382,7 +382,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
*
* The address is sent over the bus, then the data.
*
- * Returns 0 on success, otherwise a negative errno.
+ * Returns: 0 on success, otherwise a negative errno.
*/
static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
const u8 *data, int length)
@@ -421,17 +421,12 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
octeon_i2c_hlc_enable(i2c);
octeon_i2c_hlc_int_clear(i2c);
- cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
+ cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR | SW_TWSI_OP_7;
/* SIZE */
cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
/* A */
cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
- if (msgs[0].flags & I2C_M_TEN)
- cmd |= SW_TWSI_OP_10;
- else
- cmd |= SW_TWSI_OP_7;
-
octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
ret = octeon_i2c_hlc_wait(i2c);
if (ret)
@@ -463,17 +458,12 @@ static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
octeon_i2c_hlc_enable(i2c);
octeon_i2c_hlc_int_clear(i2c);
- cmd = SW_TWSI_V | SW_TWSI_SOVR;
+ cmd = SW_TWSI_V | SW_TWSI_SOVR | SW_TWSI_OP_7;
/* SIZE */
cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
/* A */
cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
- if (msgs[0].flags & I2C_M_TEN)
- cmd |= SW_TWSI_OP_10;
- else
- cmd |= SW_TWSI_OP_7;
-
for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--)
cmd |= (u64)msgs[0].buf[j] << (8 * i);
@@ -498,6 +488,45 @@ err:
return ret;
}
+/* Process hlc transaction */
+static int octeon_i2c_hlc_cmd_send(struct octeon_i2c *i2c, u64 cmd)
+{
+ octeon_i2c_hlc_int_clear(i2c);
+ octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
+
+ return octeon_i2c_hlc_wait(i2c);
+}
+
+/* Generic consideration for extended internal addresses in i2c hlc r/w ops */
+static bool octeon_i2c_hlc_ext(struct octeon_i2c *i2c, struct i2c_msg msg, u64 *cmd_in, u64 *ext)
+{
+ bool set_ext = false;
+ u64 cmd = 0;
+
+ if (msg.len == 2) {
+ cmd |= SW_TWSI_EIA;
+ *ext = (u64)msg.buf[0] << SW_TWSI_IA_SHIFT;
+ cmd |= (u64)msg.buf[1] << SW_TWSI_IA_SHIFT;
+ set_ext = true;
+ } else {
+ cmd |= (u64)msg.buf[0] << SW_TWSI_IA_SHIFT;
+ }
+
+ *cmd_in |= cmd;
+ return set_ext;
+}
+
+/* Construct and send i2c transaction core cmd for read ops */
+static int octeon_i2c_hlc_read_cmd(struct octeon_i2c *i2c, struct i2c_msg msg, u64 cmd)
+{
+ u64 ext = 0;
+
+ if (octeon_i2c_hlc_ext(i2c, msg, &cmd, &ext))
+ octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
+
+ return octeon_i2c_hlc_cmd_send(i2c, cmd);
+}
+
/* high-level-controller composite write+read, msg0=addr, msg1=data */
static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
{
@@ -506,32 +535,14 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs
octeon_i2c_hlc_enable(i2c);
- cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
+ cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR | SW_TWSI_OP_7_IA;
/* SIZE */
cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
/* A */
cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
- if (msgs[0].flags & I2C_M_TEN)
- cmd |= SW_TWSI_OP_10_IA;
- else
- cmd |= SW_TWSI_OP_7_IA;
-
- if (msgs[0].len == 2) {
- u64 ext = 0;
-
- cmd |= SW_TWSI_EIA;
- ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
- cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
- octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
- } else {
- cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
- }
-
- octeon_i2c_hlc_int_clear(i2c);
- octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
-
- ret = octeon_i2c_hlc_wait(i2c);
+ /* Send core command */
+ ret = octeon_i2c_hlc_read_cmd(i2c, msgs[0], cmd);
if (ret)
goto err;
@@ -561,25 +572,14 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg
octeon_i2c_hlc_enable(i2c);
- cmd = SW_TWSI_V | SW_TWSI_SOVR;
+ cmd = SW_TWSI_V | SW_TWSI_SOVR | SW_TWSI_OP_7_IA;
/* SIZE */
cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
/* A */
cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
- if (msgs[0].flags & I2C_M_TEN)
- cmd |= SW_TWSI_OP_10_IA;
- else
- cmd |= SW_TWSI_OP_7_IA;
-
- if (msgs[0].len == 2) {
- cmd |= SW_TWSI_EIA;
- ext |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
- set_ext = true;
- cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
- } else {
- cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
- }
+ /* Set parameters for extended message (if required) */
+ set_ext = octeon_i2c_hlc_ext(i2c, msgs[0], &cmd, &ext);
for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--)
cmd |= (u64)msgs[1].buf[j] << (8 * i);
@@ -592,10 +592,7 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg
if (set_ext)
octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
- octeon_i2c_hlc_int_clear(i2c);
- octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
-
- ret = octeon_i2c_hlc_wait(i2c);
+ ret = octeon_i2c_hlc_cmd_send(i2c, cmd);
if (ret)
goto err;
@@ -613,7 +610,7 @@ err:
* @msgs: Pointer to the messages to be processed
* @num: Length of the MSGS array
*
- * Returns the number of messages processed, or a negative errno on failure.
+ * Returns: the number of messages processed, or a negative errno on failure.
*/
int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f18c3e74b076..16afb9ca19bb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/mux/consumer.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/platform_data/i2c-omap.h>
@@ -211,6 +212,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+ struct mux_state *mux_state;
};
static const u8 reg_map_ip_v1[] = {
@@ -1452,6 +1454,23 @@ omap_i2c_probe(struct platform_device *pdev)
(1000 * omap->speed / 8);
}
+ if (of_property_read_bool(node, "mux-states")) {
+ struct mux_state *mux_state;
+
+ mux_state = devm_mux_state_get(&pdev->dev, NULL);
+ if (IS_ERR(mux_state)) {
+ r = PTR_ERR(mux_state);
+ dev_dbg(&pdev->dev, "failed to get I2C mux: %d\n", r);
+ goto err_disable_pm;
+ }
+ omap->mux_state = mux_state;
+ r = mux_state_select(omap->mux_state);
+ if (r) {
+ dev_err(&pdev->dev, "failed to select I2C mux: %d\n", r);
+ goto err_disable_pm;
+ }
+ }
+
/* reset ASAP, clearing any IRQs */
omap_i2c_init(omap);
@@ -1511,6 +1530,9 @@ static void omap_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&omap->adapter);
+ if (omap->mux_state)
+ mux_state_deselect(omap->mux_state);
+
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0)
dev_err(omap->dev, "Failed to resume hardware, skip disable\n");
diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index dac694a9d781..bd128ab2e2eb 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -5,6 +5,7 @@
* SMBus host driver for PA Semi PWRficient
*/
+#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
@@ -26,21 +27,30 @@
#define REG_REV 0x28
/* Register defs */
-#define MTXFIFO_READ 0x00000400
-#define MTXFIFO_STOP 0x00000200
-#define MTXFIFO_START 0x00000100
-#define MTXFIFO_DATA_M 0x000000ff
-
-#define MRXFIFO_EMPTY 0x00000100
-#define MRXFIFO_DATA_M 0x000000ff
-
-#define SMSTA_XEN 0x08000000
-#define SMSTA_MTN 0x00200000
-
-#define CTL_MRR 0x00000400
-#define CTL_MTR 0x00000200
-#define CTL_EN 0x00000800
-#define CTL_CLK_M 0x000000ff
+#define MTXFIFO_READ BIT(10)
+#define MTXFIFO_STOP BIT(9)
+#define MTXFIFO_START BIT(8)
+#define MTXFIFO_DATA_M GENMASK(7, 0)
+
+#define MRXFIFO_EMPTY BIT(8)
+#define MRXFIFO_DATA_M GENMASK(7, 0)
+
+#define SMSTA_XIP BIT(28)
+#define SMSTA_XEN BIT(27)
+#define SMSTA_JMD BIT(25)
+#define SMSTA_JAM BIT(24)
+#define SMSTA_MTO BIT(23)
+#define SMSTA_MTA BIT(22)
+#define SMSTA_MTN BIT(21)
+#define SMSTA_MRNE BIT(19)
+#define SMSTA_MTE BIT(16)
+#define SMSTA_TOM BIT(6)
+
+#define CTL_EN BIT(11)
+#define CTL_MRR BIT(10)
+#define CTL_MTR BIT(9)
+#define CTL_UJM BIT(8)
+#define CTL_CLK_M GENMASK(7, 0)
static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
{
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index cb6988482673..4415a29f749b 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -1503,7 +1503,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->adap.name);
}
- clk_prepare_enable(i2c->clk);
+ ret = clk_prepare_enable(i2c->clk);
+ if (ret)
+ return dev_err_probe(&dev->dev, ret,
+ "failed to enable clock\n");
if (i2c->use_pio) {
i2c->adap.algo = &i2c_pxa_pio_algorithm;
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 7bbd478171e0..515a784c951c 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -148,9 +148,9 @@ struct geni_i2c_clk_fld {
* source_clock = 19.2 MHz
*/
static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = {
- {KHZ(100), 7, 10, 11, 26},
- {KHZ(400), 2, 5, 12, 24},
- {KHZ(1000), 1, 3, 9, 18},
+ {KHZ(100), 7, 10, 12, 26},
+ {KHZ(400), 2, 5, 11, 22},
+ {KHZ(1000), 1, 2, 8, 18},
{},
};
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index da20b4487c9a..3a36d682ed57 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -14,6 +14,7 @@
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/interconnect.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
@@ -150,6 +151,8 @@
/* TAG length for DATA READ in RX FIFO */
#define READ_RX_TAGS_LEN 2
+#define QUP_BUS_WIDTH 8
+
static unsigned int scl_freq;
module_param_named(scl_freq, scl_freq, uint, 0444);
MODULE_PARM_DESC(scl_freq, "SCL frequency override");
@@ -227,6 +230,7 @@ struct qup_i2c_dev {
int irq;
struct clk *clk;
struct clk *pclk;
+ struct icc_path *icc_path;
struct i2c_adapter adap;
int clk_ctl;
@@ -255,6 +259,10 @@ struct qup_i2c_dev {
/* To configure when bus is in run state */
u32 config_run;
+ /* bandwidth votes */
+ u32 src_clk_freq;
+ u32 cur_bw_clk_freq;
+
/* dma parameters */
bool is_dma;
/* To check if the current transfer is using DMA */
@@ -453,6 +461,23 @@ static int qup_i2c_bus_active(struct qup_i2c_dev *qup, int len)
return ret;
}
+static int qup_i2c_vote_bw(struct qup_i2c_dev *qup, u32 clk_freq)
+{
+ u32 needed_peak_bw;
+ int ret;
+
+ if (qup->cur_bw_clk_freq == clk_freq)
+ return 0;
+
+ needed_peak_bw = Bps_to_icc(clk_freq * QUP_BUS_WIDTH);
+ ret = icc_set_bw(qup->icc_path, 0, needed_peak_bw);
+ if (ret)
+ return ret;
+
+ qup->cur_bw_clk_freq = clk_freq;
+ return 0;
+}
+
static void qup_i2c_write_tx_fifo_v1(struct qup_i2c_dev *qup)
{
struct qup_i2c_block *blk = &qup->blk;
@@ -838,6 +863,10 @@ static int qup_i2c_bam_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
int ret = 0;
int idx = 0;
+ ret = qup_i2c_vote_bw(qup, qup->src_clk_freq);
+ if (ret)
+ return ret;
+
enable_irq(qup->irq);
ret = qup_i2c_req_dma(qup);
@@ -1643,6 +1672,7 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup)
config = readl(qup->base + QUP_CONFIG);
config |= QUP_CLOCK_AUTO_GATE;
writel(config, qup->base + QUP_CONFIG);
+ qup_i2c_vote_bw(qup, 0);
clk_disable_unprepare(qup->pclk);
}
@@ -1743,6 +1773,11 @@ static int qup_i2c_probe(struct platform_device *pdev)
goto fail_dma;
}
qup->is_dma = true;
+
+ qup->icc_path = devm_of_icc_get(&pdev->dev, NULL);
+ if (IS_ERR(qup->icc_path))
+ return dev_err_probe(&pdev->dev, PTR_ERR(qup->icc_path),
+ "failed to get interconnect path\n");
}
nodma:
@@ -1791,6 +1826,7 @@ nodma:
qup_i2c_enable_clocks(qup);
src_clk_freq = clk_get_rate(qup->clk);
}
+ qup->src_clk_freq = src_clk_freq;
/*
* Bootloaders might leave a pending interrupt on certain QUP's,
diff --git a/drivers/i2c/busses/i2c-rzv2m.c b/drivers/i2c/busses/i2c-rzv2m.c
index 02b76e24a476..53762cc56d28 100644
--- a/drivers/i2c/busses/i2c-rzv2m.c
+++ b/drivers/i2c/busses/i2c-rzv2m.c
@@ -287,20 +287,15 @@ static int rzv2m_i2c_send_address(struct rzv2m_i2c_priv *priv,
int ret;
if (msg->flags & I2C_M_TEN) {
- /*
- * 10-bit address
- * addr_1: 5'b11110 | addr[9:8] | (R/nW)
- * addr_2: addr[7:0]
- */
- addr = 0xf0 | ((msg->addr & GENMASK(9, 8)) >> 7);
- addr |= !!(msg->flags & I2C_M_RD);
- /* Send 1st address(extend code) */
+ /* 10-bit address: Send 1st address(extend code) */
+ addr = i2c_10bit_addr_hi_from_msg(msg);
ret = rzv2m_i2c_write_with_ack(priv, addr);
if (ret)
return ret;
- /* Send 2nd address */
- ret = rzv2m_i2c_write_with_ack(priv, msg->addr & 0xff);
+ /* 10-bit address: Send 2nd address */
+ addr = i2c_10bit_addr_lo_from_msg(msg);
+ ret = rzv2m_i2c_write_with_ack(priv, addr);
} else {
/* 7-bit address */
addr = i2c_8bit_addr_from_msg(msg);
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
index a6c407d36800..02feee6c9ba9 100644
--- a/drivers/i2c/i2c-core-of.c
+++ b/drivers/i2c/i2c-core-of.c
@@ -157,7 +157,6 @@ const struct of_device_id
return i2c_of_match_device_sysfs(matches, client);
}
-EXPORT_SYMBOL_GPL(i2c_of_match_device);
#if IS_ENABLED(CONFIG_OF_DYNAMIC)
static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
index 36587f38dff3..4797ba88331c 100644
--- a/drivers/i2c/i2c-core.h
+++ b/drivers/i2c/i2c-core.h
@@ -84,8 +84,17 @@ static inline void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter) {
#ifdef CONFIG_OF
void of_i2c_register_devices(struct i2c_adapter *adap);
+const struct of_device_id *i2c_of_match_device(const struct of_device_id *matches,
+ struct i2c_client *client);
+
#else
static inline void of_i2c_register_devices(struct i2c_adapter *adap) { }
+static inline
+const struct of_device_id *i2c_of_match_device(const struct of_device_id *matches,
+ struct i2c_client *client)
+{
+ return NULL;
+}
#endif
extern struct notifier_block i2c_of_notifier;
diff --git a/drivers/i2c/muxes/i2c-mux-ltc4306.c b/drivers/i2c/muxes/i2c-mux-ltc4306.c
index 19a7c370946d..8a87f19bf5d5 100644
--- a/drivers/i2c/muxes/i2c-mux-ltc4306.c
+++ b/drivers/i2c/muxes/i2c-mux-ltc4306.c
@@ -303,7 +303,7 @@ static void ltc4306_remove(struct i2c_client *client)
static struct i2c_driver ltc4306_driver = {
.driver = {
.name = "ltc4306",
- .of_match_table = of_match_ptr(ltc4306_of_match),
+ .of_match_table = ltc4306_of_match,
},
.probe = ltc4306_probe,
.remove = ltc4306_remove,
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 6f84018258c4..db95113a5b49 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -414,7 +414,7 @@ static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
pending = (ret >> PCA954X_IRQ_OFFSET) & (BIT(data->chip->nchans) - 1);
for_each_set_bit(i, &pending, data->chip->nchans)
- handle_nested_irq(irq_linear_revmap(data->irq, i));
+ handle_nested_irq(irq_find_mapping(data->irq, i));
return IRQ_RETVAL(pending);
}
diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
index dfa472d514cc..1e566ea92bc9 100644
--- a/drivers/i2c/muxes/i2c-mux-reg.c
+++ b/drivers/i2c/muxes/i2c-mux-reg.c
@@ -250,7 +250,7 @@ static struct platform_driver i2c_mux_reg_driver = {
.remove = i2c_mux_reg_remove,
.driver = {
.name = "i2c-mux-reg",
- .of_match_table = of_match_ptr(i2c_mux_reg_of_match),
+ .of_match_table = i2c_mux_reg_of_match,
},
};
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index d5dc4180afbc..fd81871609d9 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -2276,7 +2276,7 @@ static int of_i3c_master_add_dev(struct i3c_master_controller *master,
u32 reg[3];
int ret;
- if (!master || !node)
+ if (!master)
return -EINVAL;
ret = of_property_read_u32_array(node, "reg", reg, ARRAY_SIZE(reg));
@@ -2369,14 +2369,10 @@ static u8 i3c_master_i2c_get_lvr(struct i2c_client *client)
{
/* Fall back to no spike filters and FM bus mode. */
u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE;
+ u32 reg[3];
- if (client->dev.of_node) {
- u32 reg[3];
-
- if (!of_property_read_u32_array(client->dev.of_node, "reg",
- reg, ARRAY_SIZE(reg)))
- lvr = reg[2];
- }
+ if (!of_property_read_u32_array(client->dev.of_node, "reg", reg, ARRAY_SIZE(reg)))
+ lvr = reg[2];
return lvr;
}
@@ -2486,7 +2482,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master);
struct i2c_dev_desc *i2cdev;
struct i2c_dev_boardinfo *i2cboardinfo;
- int ret, id = -ENODEV;
+ int ret, id;
adap->dev.parent = master->dev.parent;
adap->owner = master->dev.parent->driver->owner;
@@ -2497,9 +2493,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
adap->timeout = 1000;
adap->retries = 3;
- if (master->dev.of_node)
- id = of_alias_get_id(master->dev.of_node, "i2c");
-
+ id = of_alias_get_id(master->dev.of_node, "i2c");
if (id >= 0) {
adap->nr = id;
ret = i2c_add_numbered_adapter(adap);
@@ -2561,6 +2555,9 @@ static void i3c_master_unregister_i3c_devs(struct i3c_master_controller *master)
*/
void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot)
{
+ if (!dev->ibi || !slot)
+ return;
+
atomic_inc(&dev->ibi->pending_ibis);
queue_work(dev->ibi->wq, &slot->work);
}
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 2fbf8b2addd0..611c22b72c15 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1079,7 +1079,7 @@ static void dw_i3c_master_detach_i3c_dev(struct i3c_dev_desc *dev)
}
static int dw_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
- const struct i2c_msg *i2c_xfers,
+ struct i2c_msg *i2c_xfers,
int i2c_nxfers)
{
struct dw_i3c_i2c_dev_data *data = i2c_dev_get_master_data(dev);
diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c
index fedbe6624a1c..fd3752cea654 100644
--- a/drivers/i3c/master/i3c-master-cdns.c
+++ b/drivers/i3c/master/i3c-master-cdns.c
@@ -813,7 +813,7 @@ static int cdns_i3c_master_priv_xfers(struct i3c_dev_desc *dev,
}
static int cdns_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
- const struct i2c_msg *xfers, int nxfers)
+ struct i2c_msg *xfers, int nxfers)
{
struct i3c_master_controller *m = i2c_dev_get_master(dev);
struct cdns_i3c_master *master = to_cdns_i3c_master(m);
diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c
index 648c501407ce..a71226d7ca59 100644
--- a/drivers/i3c/master/mipi-i3c-hci/core.c
+++ b/drivers/i3c/master/mipi-i3c-hci/core.c
@@ -367,7 +367,7 @@ out:
}
static int i3c_hci_i2c_xfers(struct i2c_dev_desc *dev,
- const struct i2c_msg *i2c_xfers, int nxfers)
+ struct i2c_msg *i2c_xfers, int nxfers)
{
struct i3c_master_controller *m = i2c_dev_get_master(dev);
struct i3c_hci *hci = to_i3c_hci(m);
@@ -382,14 +382,11 @@ static int i3c_hci_i2c_xfers(struct i2c_dev_desc *dev,
return -ENOMEM;
for (i = 0; i < nxfers; i++) {
- xfer[i].data = i2c_xfers[i].buf;
+ xfer[i].data = i2c_get_dma_safe_msg_buf(&i2c_xfers[i], 1);
xfer[i].data_len = i2c_xfers[i].len;
xfer[i].rnw = i2c_xfers[i].flags & I2C_M_RD;
hci->cmd->prep_i2c_xfer(hci, dev, &xfer[i]);
xfer[i].cmd_desc[0] |= CMD_0_ROC;
- ret = i3c_hci_alloc_safe_xfer_buf(hci, &xfer[i]);
- if (ret)
- goto out;
}
last = i - 1;
xfer[last].cmd_desc[0] |= CMD_0_TOC;
@@ -412,7 +409,8 @@ static int i3c_hci_i2c_xfers(struct i2c_dev_desc *dev,
out:
for (i = 0; i < nxfers; i++)
- i3c_hci_free_safe_xfer_buf(hci, &xfer[i]);
+ i2c_put_dma_safe_msg_buf(xfer[i].data, &i2c_xfers[i],
+ ret ? false : true);
hci_free_xfer(xfer, nxfers);
return ret;
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index d6057d8c7dec..85e16de208d3 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -32,6 +32,7 @@
#define SVC_I3C_MCONFIG_ODBAUD(x) FIELD_PREP(GENMASK(23, 16), (x))
#define SVC_I3C_MCONFIG_ODHPP(x) FIELD_PREP(BIT(24), (x))
#define SVC_I3C_MCONFIG_SKEW(x) FIELD_PREP(GENMASK(27, 25), (x))
+#define SVC_I3C_MCONFIG_SKEW_MASK GENMASK(27, 25)
#define SVC_I3C_MCONFIG_I2CBAUD(x) FIELD_PREP(GENMASK(31, 28), (x))
#define SVC_I3C_MCTRL 0x084
@@ -58,6 +59,7 @@
#define SVC_I3C_MSTATUS 0x088
#define SVC_I3C_MSTATUS_STATE(x) FIELD_GET(GENMASK(2, 0), (x))
#define SVC_I3C_MSTATUS_STATE_DAA(x) (SVC_I3C_MSTATUS_STATE(x) == 5)
+#define SVC_I3C_MSTATUS_STATE_SLVREQ(x) (SVC_I3C_MSTATUS_STATE(x) == 1)
#define SVC_I3C_MSTATUS_STATE_IDLE(x) (SVC_I3C_MSTATUS_STATE(x) == 0)
#define SVC_I3C_MSTATUS_BETWEEN(x) FIELD_GET(BIT(4), (x))
#define SVC_I3C_MSTATUS_NACKED(x) FIELD_GET(BIT(5), (x))
@@ -113,6 +115,7 @@
#define SVC_I3C_MWDATAHE 0x0BC
#define SVC_I3C_MRDATAB 0x0C0
#define SVC_I3C_MRDATAH 0x0C8
+#define SVC_I3C_MWDATAB1 0x0CC
#define SVC_I3C_MWMSG_SDR 0x0D0
#define SVC_I3C_MRMSG_SDR 0x0D4
#define SVC_I3C_MWMSG_DDR 0x0D8
@@ -133,6 +136,32 @@
#define SVC_I3C_EVENT_IBI GENMASK(7, 0)
#define SVC_I3C_EVENT_HOTJOIN BIT(31)
+/*
+ * SVC_I3C_QUIRK_FIFO_EMPTY:
+ * I3C HW stalls the write transfer if the transmit FIFO becomes empty,
+ * when new data is written to FIFO, I3C HW resumes the transfer but
+ * the first transmitted data bit may have the wrong value.
+ * Workaround:
+ * Fill the FIFO in advance to prevent FIFO from becoming empty.
+ */
+#define SVC_I3C_QUIRK_FIFO_EMPTY BIT(0)
+/*
+ * SVC_I3C_QUIRK_FLASE_SLVSTART:
+ * I3C HW may generate an invalid SlvStart event when emitting a STOP.
+ * If it is a true SlvStart, the MSTATUS state is SLVREQ.
+ */
+#define SVC_I3C_QUIRK_FALSE_SLVSTART BIT(1)
+/*
+ * SVC_I3C_QUIRK_DAA_CORRUPT:
+ * When MCONFIG.SKEW=0 and MCONFIG.ODHPP=0, the ENTDAA transaction gets
+ * corrupted and results in a no repeated-start condition at the end of
+ * address assignment.
+ * Workaround:
+ * Set MCONFIG.SKEW to 1 before initiating the DAA process. After the DAA
+ * process is completed, return MCONFIG.SKEW to its previous value.
+ */
+#define SVC_I3C_QUIRK_DAA_CORRUPT BIT(2)
+
struct svc_i3c_cmd {
u8 addr;
bool rnw;
@@ -158,6 +187,10 @@ struct svc_i3c_regs_save {
u32 mdynaddr;
};
+struct svc_i3c_drvdata {
+ u32 quirks;
+};
+
/**
* struct svc_i3c_master - Silvaco I3C Master structure
* @base: I3C master controller
@@ -183,6 +216,7 @@ struct svc_i3c_regs_save {
* @ibi.tbq_slot: To be queued IBI slot
* @ibi.lock: IBI lock
* @lock: Transfer lock, protect between IBI work thread and callbacks from master
+ * @drvdata: Driver data
* @enabled_events: Bit masks for enable events (IBI, HotJoin).
* @mctrl_config: Configuration value in SVC_I3C_MCTRL for setting speed back.
*/
@@ -214,6 +248,7 @@ struct svc_i3c_master {
spinlock_t lock;
} ibi;
struct mutex lock;
+ const struct svc_i3c_drvdata *drvdata;
u32 enabled_events;
u32 mctrl_config;
};
@@ -230,6 +265,18 @@ struct svc_i3c_i2c_dev_data {
struct i3c_generic_ibi_pool *ibi_pool;
};
+static inline bool svc_has_quirk(struct svc_i3c_master *master, u32 quirk)
+{
+ return (master->drvdata->quirks & quirk);
+}
+
+static inline bool svc_has_daa_corrupt(struct svc_i3c_master *master)
+{
+ return ((master->drvdata->quirks & SVC_I3C_QUIRK_DAA_CORRUPT) &&
+ !(master->mctrl_config &
+ (SVC_I3C_MCONFIG_SKEW_MASK | SVC_I3C_MCONFIG_ODHPP(1))));
+}
+
static inline bool is_events_enabled(struct svc_i3c_master *master, u32 mask)
{
return !!(master->enabled_events & mask);
@@ -378,7 +425,7 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master,
slot->len < SVC_I3C_FIFO_SIZE) {
mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL);
count = SVC_I3C_MDATACTRL_RXCOUNT(mdatactrl);
- readsl(master->regs + SVC_I3C_MRDATAB, buf, count);
+ readsb(master->regs + SVC_I3C_MRDATAB, buf, count);
slot->len += count;
buf += count;
}
@@ -545,6 +592,8 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
queue_work(master->base.wq, &master->hj_work);
break;
case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST:
+ svc_i3c_master_emit_stop(master);
+ break;
default:
break;
}
@@ -564,6 +613,11 @@ static irqreturn_t svc_i3c_master_irq_handler(int irq, void *dev_id)
/* Clear the interrupt status */
writel(SVC_I3C_MINT_SLVSTART, master->regs + SVC_I3C_MSTATUS);
+ /* Ignore the false event */
+ if (svc_has_quirk(master, SVC_I3C_QUIRK_FALSE_SLVSTART) &&
+ !SVC_I3C_MSTATUS_STATE_SLVREQ(active))
+ return IRQ_HANDLED;
+
svc_i3c_master_disable_interrupts(master);
/* Handle the interrupt in a non atomic context */
@@ -888,10 +942,12 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
u8 *addrs, unsigned int *count)
{
u64 prov_id[SVC_I3C_MAX_DEVS] = {}, nacking_prov_id = 0;
- unsigned int dev_nb = 0, last_addr = 0;
+ unsigned int dev_nb = 0, last_addr = 0, dyn_addr = 0;
u32 reg;
int ret, i;
+ svc_i3c_master_flush_fifo(master);
+
while (true) {
/* clean SVC_I3C_MINT_IBIWON w1c bits */
writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
@@ -932,6 +988,26 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
u8 data[6];
/*
+ * One slave sends its ID to request for address assignment,
+ * prefilling the dynamic address can reduce SCL clock stalls
+ * and also fix the SVC_I3C_QUIRK_FIFO_EMPTY quirk.
+ *
+ * Ideally, prefilling before the processDAA command is better.
+ * However, it requires an additional check to write the dyn_addr
+ * at the right time because the driver needs to write the processDAA
+ * command twice for one assignment.
+ * Prefilling here is safe and efficient because the FIFO starts
+ * filling within a few hundred nanoseconds, which is significantly
+ * faster compared to the 64 SCL clock cycles.
+ */
+ ret = i3c_master_get_free_addr(&master->base, last_addr + 1);
+ if (ret < 0)
+ break;
+
+ dyn_addr = ret;
+ writel(dyn_addr, master->regs + SVC_I3C_MWDATAB);
+
+ /*
* We only care about the 48-bit provisioned ID yet to
* be sure a device does not nack an address twice.
* Otherwise, we would just need to flush the RX FIFO.
@@ -1009,21 +1085,16 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master,
if (ret)
break;
- /* Give the slave device a suitable dynamic address */
- ret = i3c_master_get_free_addr(&master->base, last_addr + 1);
- if (ret < 0)
- break;
-
- addrs[dev_nb] = ret;
+ addrs[dev_nb] = dyn_addr;
dev_dbg(master->dev, "DAA: device %d assigned to 0x%02x\n",
dev_nb, addrs[dev_nb]);
-
- writel(addrs[dev_nb], master->regs + SVC_I3C_MWDATAB);
last_addr = addrs[dev_nb++];
}
/* Need manual issue STOP except for Complete condition */
svc_i3c_master_emit_stop(master);
+ svc_i3c_master_flush_fifo(master);
+
return ret;
}
@@ -1037,7 +1108,7 @@ static int svc_i3c_update_ibirules(struct svc_i3c_master *master)
/* Create the IBIRULES register for both cases */
i3c_bus_for_each_i3cdev(&master->base.bus, dev) {
- if (I3C_BCR_DEVICE_ROLE(dev->info.bcr) == I3C_BCR_I3C_MASTER)
+ if (!(dev->info.bcr & I3C_BCR_IBI_REQ_CAP))
continue;
if (dev->info.bcr & I3C_BCR_IBI_PAYLOAD) {
@@ -1096,7 +1167,16 @@ static int svc_i3c_master_do_daa(struct i3c_master_controller *m)
}
spin_lock_irqsave(&master->xferqueue.lock, flags);
+
+ if (svc_has_daa_corrupt(master))
+ writel(master->mctrl_config | SVC_I3C_MCONFIG_SKEW(1),
+ master->regs + SVC_I3C_MCONFIG);
+
ret = svc_i3c_master_do_daa_locked(master, addrs, &dev_nb);
+
+ if (svc_has_daa_corrupt(master))
+ writel(master->mctrl_config, master->regs + SVC_I3C_MCONFIG);
+
spin_unlock_irqrestore(&master->xferqueue.lock, flags);
svc_i3c_master_clear_merrwarn(master);
@@ -1220,6 +1300,24 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
SVC_I3C_MCTRL_RDTERM(*actual_len),
master->regs + SVC_I3C_MCTRL);
+ /*
+ * The entire transaction can consist of multiple write transfers.
+ * Prefilling before EmitStartAddr causes the data to be emitted
+ * immediately, becoming part of the previous transfer.
+ * The only way to work around this hardware issue is to let the
+ * FIFO start filling as soon as possible after EmitStartAddr.
+ */
+ if (svc_has_quirk(master, SVC_I3C_QUIRK_FIFO_EMPTY) && !rnw && xfer_len) {
+ u32 end = xfer_len > SVC_I3C_FIFO_SIZE ? 0 : SVC_I3C_MWDATAB_END;
+ u32 len = min_t(u32, xfer_len, SVC_I3C_FIFO_SIZE);
+
+ writesb(master->regs + SVC_I3C_MWDATAB1, out, len - 1);
+ /* Mark END bit if this is the last byte */
+ writel(out[len - 1] | end, master->regs + SVC_I3C_MWDATAB);
+ xfer_len -= len;
+ out += len;
+ }
+
ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg,
SVC_I3C_MSTATUS_MCTRLDONE(reg), 0, 1000);
if (ret)
@@ -1308,6 +1406,7 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
emit_stop:
svc_i3c_master_emit_stop(master);
svc_i3c_master_clear_merrwarn(master);
+ svc_i3c_master_flush_fifo(master);
return ret;
}
@@ -1584,7 +1683,7 @@ static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev,
}
static int svc_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
- const struct i2c_msg *xfers,
+ struct i2c_msg *xfers,
int nxfers)
{
struct i3c_master_controller *m = i2c_dev_get_master(dev);
@@ -1817,6 +1916,10 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
if (!master)
return -ENOMEM;
+ master->drvdata = of_device_get_match_data(dev);
+ if (!master->drvdata)
+ return -EINVAL;
+
master->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(master->regs))
return PTR_ERR(master->regs);
@@ -1958,8 +2061,17 @@ static const struct dev_pm_ops svc_i3c_pm_ops = {
svc_i3c_runtime_resume, NULL)
};
+static const struct svc_i3c_drvdata npcm845_drvdata = {
+ .quirks = SVC_I3C_QUIRK_FIFO_EMPTY |
+ SVC_I3C_QUIRK_FALSE_SLVSTART |
+ SVC_I3C_QUIRK_DAA_CORRUPT,
+};
+
+static const struct svc_i3c_drvdata svc_default_drvdata = {};
+
static const struct of_device_id svc_i3c_master_of_match_tbl[] = {
- { .compatible = "silvaco,i3c-master-v1"},
+ { .compatible = "nuvoton,npcm845-i3c", .data = &npcm845_drvdata },
+ { .compatible = "silvaco,i3c-master-v1", .data = &svc_default_drvdata },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, svc_i3c_master_of_match_tbl);
diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c
index 65f8a2b13cfd..22ea10eb48ae 100644
--- a/drivers/iio/common/ssp_sensors/ssp_dev.c
+++ b/drivers/iio/common/ssp_sensors/ssp_dev.c
@@ -190,7 +190,7 @@ static void ssp_enable_wdt_timer(struct ssp_data *data)
static void ssp_disable_wdt_timer(struct ssp_data *data)
{
- del_timer_sync(&data->wdt_timer);
+ timer_delete_sync(&data->wdt_timer);
cancel_work_sync(&data->work_wdt);
}
@@ -589,7 +589,7 @@ static void ssp_remove(struct spi_device *spi)
free_irq(data->spi->irq, data);
- del_timer_sync(&data->wdt_timer);
+ timer_delete_sync(&data->wdt_timer);
cancel_work_sync(&data->work_wdt);
mutex_destroy(&data->comm_lock);
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 8d753e6e0c71..e02721a9e288 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -191,7 +191,7 @@ static void start_ep_timer(struct c4iw_ep *ep)
static int stop_ep_timer(struct c4iw_ep *ep)
{
pr_debug("ep %p stopping\n", ep);
- del_timer_sync(&ep->timer);
+ timer_delete_sync(&ep->timer);
if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
c4iw_put_ep(&ep->com);
return 0;
diff --git a/drivers/infiniband/hw/hfi1/aspm.c b/drivers/infiniband/hw/hfi1/aspm.c
index a3c53be4072c..9b508eaf441d 100644
--- a/drivers/infiniband/hw/hfi1/aspm.c
+++ b/drivers/infiniband/hw/hfi1/aspm.c
@@ -191,7 +191,7 @@ void aspm_disable_all(struct hfi1_devdata *dd)
for (i = 0; i < dd->first_dyn_alloc_ctxt; i++) {
rcd = hfi1_rcd_get_by_index(dd, i);
if (rcd) {
- del_timer_sync(&rcd->aspm_timer);
+ timer_delete_sync(&rcd->aspm_timer);
spin_lock_irqsave(&rcd->aspm_lock, flags);
rcd->aspm_intr_enable = false;
spin_unlock_irqrestore(&rcd->aspm_lock, flags);
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 368b6be3226f..e908f529335d 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -5576,7 +5576,7 @@ static int init_rcverr(struct hfi1_devdata *dd)
static void free_rcverr(struct hfi1_devdata *dd)
{
if (dd->rcverr_timer.function)
- del_timer_sync(&dd->rcverr_timer);
+ timer_delete_sync(&dd->rcverr_timer);
}
static void handle_rxe_err(struct hfi1_devdata *dd, u32 unused, u64 reg)
@@ -12308,7 +12308,7 @@ static void free_cntrs(struct hfi1_devdata *dd)
int i;
if (dd->synth_stats_timer.function)
- del_timer_sync(&dd->synth_stats_timer);
+ timer_delete_sync(&dd->synth_stats_timer);
cancel_work_sync(&dd->update_cntr_work);
ppd = (struct hfi1_pportdata *)(dd + 1);
for (i = 0; i < dd->num_pports; i++, ppd++) {
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c
index 50826e7cdb7e..3da90f2eb8e7 100644
--- a/drivers/infiniband/hw/hfi1/driver.c
+++ b/drivers/infiniband/hw/hfi1/driver.c
@@ -1303,7 +1303,7 @@ void shutdown_led_override(struct hfi1_pportdata *ppd)
*/
smp_rmb();
if (atomic_read(&ppd->led_override_timer_active)) {
- del_timer_sync(&ppd->led_override_timer);
+ timer_delete_sync(&ppd->led_override_timer);
atomic_set(&ppd->led_override_timer_active, 0);
/* Ensure the atomic_set is visible to all CPUs */
smp_wmb();
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index d6fbd9c2b8b4..b35f92e7d865 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -985,7 +985,7 @@ static void stop_timers(struct hfi1_devdata *dd)
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
if (ppd->led_override_timer.function) {
- del_timer_sync(&ppd->led_override_timer);
+ timer_delete_sync(&ppd->led_override_timer);
atomic_set(&ppd->led_override_timer_active, 0);
}
}
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
index b67d23b1f286..0d2b39b7c8b5 100644
--- a/drivers/infiniband/hw/hfi1/sdma.c
+++ b/drivers/infiniband/hw/hfi1/sdma.c
@@ -1575,7 +1575,7 @@ void sdma_exit(struct hfi1_devdata *dd)
sde->this_idx);
sdma_process_event(sde, sdma_event_e00_go_hw_down);
- del_timer_sync(&sde->err_progress_check_timer);
+ timer_delete_sync(&sde->err_progress_check_timer);
/*
* This waits for the state machine to exit so it is not
diff --git a/drivers/infiniband/hw/hfi1/tid_rdma.c b/drivers/infiniband/hw/hfi1/tid_rdma.c
index c465966a1d9c..78bf4a48c035 100644
--- a/drivers/infiniband/hw/hfi1/tid_rdma.c
+++ b/drivers/infiniband/hw/hfi1/tid_rdma.c
@@ -3965,7 +3965,7 @@ static int hfi1_stop_tid_reap_timer(struct rvt_qp *qp)
lockdep_assert_held(&qp->s_lock);
if (qpriv->s_flags & HFI1_R_TID_RSC_TIMER) {
- rval = del_timer(&qpriv->s_tid_timer);
+ rval = timer_delete(&qpriv->s_tid_timer);
qpriv->s_flags &= ~HFI1_R_TID_RSC_TIMER;
}
return rval;
@@ -3975,7 +3975,7 @@ void hfi1_del_tid_reap_timer(struct rvt_qp *qp)
{
struct hfi1_qp_priv *qpriv = qp->priv;
- del_timer_sync(&qpriv->s_tid_timer);
+ timer_delete_sync(&qpriv->s_tid_timer);
qpriv->s_flags &= ~HFI1_R_TID_RSC_TIMER;
}
@@ -4781,7 +4781,7 @@ static int hfi1_stop_tid_retry_timer(struct rvt_qp *qp)
lockdep_assert_held(&qp->s_lock);
if (priv->s_flags & HFI1_S_TID_RETRY_TIMER) {
- rval = del_timer(&priv->s_tid_retry_timer);
+ rval = timer_delete(&priv->s_tid_retry_timer);
priv->s_flags &= ~HFI1_S_TID_RETRY_TIMER;
}
return rval;
@@ -4791,7 +4791,7 @@ void hfi1_del_tid_retry_timer(struct rvt_qp *qp)
{
struct hfi1_qp_priv *priv = qp->priv;
- del_timer_sync(&priv->s_tid_retry_timer);
+ timer_delete_sync(&priv->s_tid_retry_timer);
priv->s_flags &= ~HFI1_S_TID_RETRY_TIMER;
}
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
index 33af2196ef31..49e0f79b950c 100644
--- a/drivers/infiniband/hw/hfi1/verbs.c
+++ b/drivers/infiniband/hw/hfi1/verbs.c
@@ -1900,7 +1900,7 @@ void hfi1_unregister_ib_device(struct hfi1_devdata *dd)
if (!list_empty(&dev->memwait))
dd_dev_err(dd, "memwait list not empty!\n");
- del_timer_sync(&dev->mem_timer);
+ timer_delete_sync(&dev->mem_timer);
verbs_txreq_exit(dev);
kfree(dev_cntr_descs);
diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
index ce8d821bdad8..23207f13ac1b 100644
--- a/drivers/infiniband/hw/irdma/cm.c
+++ b/drivers/infiniband/hw/irdma/cm.c
@@ -3303,7 +3303,7 @@ void irdma_cleanup_cm_core(struct irdma_cm_core *cm_core)
if (!cm_core)
return;
- del_timer_sync(&cm_core->tcp_timer);
+ timer_delete_sync(&cm_core->tcp_timer);
destroy_workqueue(cm_core->event_wq);
cm_core->dev->ws_reset(&cm_core->iwdev->vsi);
diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
index e73b14fd95ef..d66b4f7a84ec 100644
--- a/drivers/infiniband/hw/irdma/utils.c
+++ b/drivers/infiniband/hw/irdma/utils.c
@@ -963,7 +963,7 @@ void irdma_terminate_del_timer(struct irdma_sc_qp *qp)
int ret;
iwqp = qp->qp_uk.back_qp;
- ret = del_timer(&iwqp->terminate_timer);
+ ret = timer_delete(&iwqp->terminate_timer);
if (ret)
irdma_qp_rem_ref(&iwqp->ibqp);
}
@@ -1570,7 +1570,7 @@ void irdma_hw_stats_stop_timer(struct irdma_sc_vsi *vsi)
{
struct irdma_vsi_pestat *devstat = vsi->pestat;
- del_timer_sync(&devstat->stats_timer);
+ timer_delete_sync(&devstat->stats_timer);
}
/**
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index b7c8c926c578..5fbebafc8774 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -1026,7 +1026,7 @@ void mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev)
mlx5r_destroy_cache_entries(dev);
destroy_workqueue(dev->cache.wq);
- del_timer_sync(&dev->delay_timer);
+ timer_delete_sync(&dev->delay_timer);
}
struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc)
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index ffb98eaaf1c2..6eabef9aa211 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -171,7 +171,7 @@ void mthca_start_catas_poll(struct mthca_dev *dev)
void mthca_stop_catas_poll(struct mthca_dev *dev)
{
- del_timer_sync(&dev->catas_err.timer);
+ timer_delete_sync(&dev->catas_err.timer);
if (dev->catas_err.map)
iounmap(dev->catas_err.map);
diff --git a/drivers/infiniband/hw/qib/qib_driver.c b/drivers/infiniband/hw/qib/qib_driver.c
index 4fcbef99e400..bdd724add147 100644
--- a/drivers/infiniband/hw/qib/qib_driver.c
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -768,7 +768,7 @@ int qib_reset_device(int unit)
ppd = dd->pport + pidx;
if (atomic_read(&ppd->led_override_timer_active)) {
/* Need to stop LED timer, _then_ shut off LEDs */
- del_timer_sync(&ppd->led_override_timer);
+ timer_delete_sync(&ppd->led_override_timer);
atomic_set(&ppd->led_override_timer_active, 0);
}
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
index b27791029fa9..b9f4a2937c3a 100644
--- a/drivers/infiniband/hw/qib/qib_fs.c
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -55,6 +55,7 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
struct inode *inode = new_inode(dir->i_sb);
if (!inode) {
+ dput(dentry);
error = -EPERM;
goto bail;
}
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
index 78dfe98ebcf7..302c0d19f57d 100644
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
@@ -1656,7 +1656,7 @@ static void qib_7220_quiet_serdes(struct qib_pportdata *ppd)
ppd->cpspec->chase_end = 0;
if (ppd->cpspec->chase_timer.function) /* if initted */
- del_timer_sync(&ppd->cpspec->chase_timer);
+ timer_delete_sync(&ppd->cpspec->chase_timer);
if (ppd->cpspec->ibsymdelta || ppd->cpspec->iblnkerrdelta ||
ppd->cpspec->ibdeltainprog) {
@@ -2605,7 +2605,7 @@ static int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val)
* wait forpending timer, but don't clear .data (ppd)!
*/
if (ppd->cpspec->chase_timer.expires) {
- del_timer_sync(&ppd->cpspec->chase_timer);
+ timer_delete_sync(&ppd->cpspec->chase_timer);
ppd->cpspec->chase_timer.expires = 0;
}
break;
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
index 9db29916e35a..7b4bf06c3b38 100644
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
@@ -2512,7 +2512,7 @@ static void qib_7322_mini_quiet_serdes(struct qib_pportdata *ppd)
ppd->cpspec->chase_end = 0;
if (ppd->cpspec->chase_timer.function) /* if initted */
- del_timer_sync(&ppd->cpspec->chase_timer);
+ timer_delete_sync(&ppd->cpspec->chase_timer);
/*
* Despite the name, actually disables IBC as well. Do it when
@@ -4239,7 +4239,7 @@ static int qib_7322_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val)
* wait forpending timer, but don't clear .data (ppd)!
*/
if (ppd->cpspec->chase_timer.expires) {
- del_timer_sync(&ppd->cpspec->chase_timer);
+ timer_delete_sync(&ppd->cpspec->chase_timer);
ppd->cpspec->chase_timer.expires = 0;
}
break;
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index 4100656fe9a3..33c23adec101 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -796,19 +796,19 @@ static void qib_stop_timers(struct qib_devdata *dd)
int pidx;
if (dd->stats_timer.function)
- del_timer_sync(&dd->stats_timer);
+ timer_delete_sync(&dd->stats_timer);
if (dd->intrchk_timer.function)
- del_timer_sync(&dd->intrchk_timer);
+ timer_delete_sync(&dd->intrchk_timer);
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
if (ppd->hol_timer.function)
- del_timer_sync(&ppd->hol_timer);
+ timer_delete_sync(&ppd->hol_timer);
if (ppd->led_override_timer.function) {
- del_timer_sync(&ppd->led_override_timer);
+ timer_delete_sync(&ppd->led_override_timer);
atomic_set(&ppd->led_override_timer_active, 0);
}
if (ppd->symerr_clear_timer.function)
- del_timer_sync(&ppd->symerr_clear_timer);
+ timer_delete_sync(&ppd->symerr_clear_timer);
}
}
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c
index ef02f2bfddb2..568deb77ab4d 100644
--- a/drivers/infiniband/hw/qib/qib_mad.c
+++ b/drivers/infiniband/hw/qib/qib_mad.c
@@ -2441,7 +2441,7 @@ void qib_notify_free_mad_agent(struct rvt_dev_info *rdi, int port_idx)
struct qib_devdata, verbs_dev);
if (dd->pport[port_idx].cong_stats.timer.function)
- del_timer_sync(&dd->pport[port_idx].cong_stats.timer);
+ timer_delete_sync(&dd->pport[port_idx].cong_stats.timer);
if (dd->pport[port_idx].ibport_data.smi_ah)
rdma_destroy_ah(&dd->pport[port_idx].ibport_data.smi_ah->ibah,
diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c
index 1dc3ccf0cf1f..c4ee120ac7fb 100644
--- a/drivers/infiniband/hw/qib/qib_sd7220.c
+++ b/drivers/infiniband/hw/qib/qib_sd7220.c
@@ -1375,7 +1375,7 @@ void toggle_7220_rclkrls(struct qib_devdata *dd)
void shutdown_7220_relock_poll(struct qib_devdata *dd)
{
if (dd->cspec->relock_timer_active)
- del_timer_sync(&dd->cspec->relock_timer);
+ timer_delete_sync(&dd->cspec->relock_timer);
}
static unsigned qib_relock_by_timer = 1;
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index 5fcb41970ad9..9832567a8bb8 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -1655,7 +1655,7 @@ void qib_unregister_ib_device(struct qib_devdata *dd)
if (!list_empty(&dev->memwait))
qib_dev_err(dd, "memwait list not empty!\n");
- del_timer_sync(&dev->mem_timer);
+ timer_delete_sync(&dev->mem_timer);
while (!list_empty(&dev->txreq_free)) {
struct list_head *l = dev->txreq_free.next;
struct qib_verbs_txreq *tx;
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 614009fb9632..583debe4b9a2 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -1297,7 +1297,7 @@ int rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err)
if (qp->s_flags & (RVT_S_TIMER | RVT_S_WAIT_RNR)) {
qp->s_flags &= ~(RVT_S_TIMER | RVT_S_WAIT_RNR);
- del_timer(&qp->s_timer);
+ timer_delete(&qp->s_timer);
}
if (qp->s_flags & RVT_S_ANY_WAIT_SEND)
@@ -2546,7 +2546,7 @@ void rvt_stop_rc_timers(struct rvt_qp *qp)
/* Remove QP from all timers */
if (qp->s_flags & (RVT_S_TIMER | RVT_S_WAIT_RNR)) {
qp->s_flags &= ~(RVT_S_TIMER | RVT_S_WAIT_RNR);
- del_timer(&qp->s_timer);
+ timer_delete(&qp->s_timer);
hrtimer_try_to_cancel(&qp->s_rnr_timer);
}
}
@@ -2575,7 +2575,7 @@ static void rvt_stop_rnr_timer(struct rvt_qp *qp)
*/
void rvt_del_timers_sync(struct rvt_qp *qp)
{
- del_timer_sync(&qp->s_timer);
+ timer_delete_sync(&qp->s_timer);
hrtimer_cancel(&qp->s_rnr_timer);
}
EXPORT_SYMBOL(rvt_del_timers_sync);
@@ -2596,7 +2596,7 @@ static void rvt_rc_timeout(struct timer_list *t)
qp->s_flags &= ~RVT_S_TIMER;
rvp->n_rc_timeouts++;
- del_timer(&qp->s_timer);
+ timer_delete(&qp->s_timer);
trace_rvt_rc_timeout(qp, qp->s_last_psn + 1);
if (rdi->driver_f.notify_restart_rc)
rdi->driver_f.notify_restart_rc(qp,
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
index 91d329e90308..7975fb0e2782 100644
--- a/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -812,8 +812,8 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
qp->qp_timeout_jiffies = 0;
if (qp_type(qp) == IB_QPT_RC) {
- del_timer_sync(&qp->retrans_timer);
- del_timer_sync(&qp->rnr_nak_timer);
+ timer_delete_sync(&qp->retrans_timer);
+ timer_delete_sync(&qp->rnr_nak_timer);
}
if (qp->recv_task.func)
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index e9120ba6bae0..009822fa61b8 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -136,7 +136,7 @@ static void ml_schedule_timer(struct ml_device *ml)
if (!events) {
pr_debug("no actions\n");
- del_timer(&ml->timer);
+ timer_delete(&ml->timer);
} else {
pr_debug("timer set\n");
mod_timer(&ml->timer, earliest);
@@ -489,7 +489,7 @@ static void ml_ff_destroy(struct ff_device *ff)
* do not actually stop the timer, and therefore we should
* do it here.
*/
- del_timer_sync(&ml->timer);
+ timer_delete_sync(&ml->timer);
kfree(ml->private);
}
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 10cc95867415..ae51f108bfae 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -191,7 +191,7 @@ void gameport_stop_polling(struct gameport *gameport)
spin_lock(&gameport->timer_lock);
if (!--gameport->poll_cnt)
- del_timer(&gameport->poll_timer);
+ timer_delete(&gameport->poll_timer);
spin_unlock(&gameport->timer_lock);
}
@@ -847,7 +847,7 @@ EXPORT_SYMBOL(gameport_open);
void gameport_close(struct gameport *gameport)
{
- del_timer_sync(&gameport->poll_timer);
+ timer_delete_sync(&gameport->poll_timer);
gameport->poll_handler = NULL;
gameport->poll_interval = 0;
gameport_set_drv(gameport, NULL);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c9e3ac64bcd0..ec4346f20efd 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -96,7 +96,7 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
static void input_stop_autorepeat(struct input_dev *dev)
{
- del_timer(&dev->timer);
+ timer_delete(&dev->timer);
}
/*
@@ -2223,7 +2223,7 @@ static void __input_unregister_device(struct input_dev *dev)
handle->handler->disconnect(handle);
WARN_ON(!list_empty(&dev->h_list));
- del_timer_sync(&dev->timer);
+ timer_delete_sync(&dev->timer);
list_del_init(&dev->node);
input_wakeup_procfs_readers();
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index a9f1946cf0d6..d7a253835889 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -531,7 +531,7 @@ static void db9_close(struct input_dev *dev)
guard(mutex)(&db9->mutex);
if (!--db9->used) {
- del_timer_sync(&db9->timer);
+ timer_delete_sync(&db9->timer);
parport_write_control(port, 0x00);
parport_data_forward(port);
parport_release(db9->pd);
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index b53cafd7a5ee..9fc629ad58b8 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -786,7 +786,7 @@ static void gc_close(struct input_dev *dev)
guard(mutex)(&gc->mutex);
if (!--gc->used) {
- del_timer_sync(&gc->timer);
+ timer_delete_sync(&gc->timer);
parport_write_control(gc->pd->port, 0x00);
parport_release(gc->pd);
}
diff --git a/drivers/input/joystick/n64joy.c b/drivers/input/joystick/n64joy.c
index c344dbc0c493..94d2f4e96fe6 100644
--- a/drivers/input/joystick/n64joy.c
+++ b/drivers/input/joystick/n64joy.c
@@ -216,7 +216,7 @@ static void n64joy_close(struct input_dev *dev)
guard(mutex)(&priv->n64joy_mutex);
if (!--priv->n64joy_opened)
- del_timer_sync(&priv->timer);
+ timer_delete_sync(&priv->timer);
}
static const u64 __initconst scandata[] ____cacheline_aligned = {
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index db696ba61a3b..aa3e7d471b96 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -124,7 +124,7 @@ static void tgfx_close(struct input_dev *dev)
guard(mutex)(&tgfx->sem);
if (!--tgfx->used) {
- del_timer_sync(&tgfx->timer);
+ timer_delete_sync(&tgfx->timer);
parport_write_control(tgfx->pd->port, 0x00);
parport_release(tgfx->pd);
}
diff --git a/drivers/input/joystick/walkera0701.c b/drivers/input/joystick/walkera0701.c
index 59eea813f258..15370fb82317 100644
--- a/drivers/input/joystick/walkera0701.c
+++ b/drivers/input/joystick/walkera0701.c
@@ -232,8 +232,7 @@ static void walkera0701_attach(struct parport *pp)
goto err_unregister_device;
}
- hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- w->timer.function = timer_handler;
+ hrtimer_setup(&w->timer, timer_handler, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
w->input_dev = input_allocate_device();
if (!w->input_dev) {
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 5eef66516e37..5c39a217b94c 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -590,9 +590,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func);
- hrtimer_init(&bdata->debounce_timer,
- CLOCK_REALTIME, HRTIMER_MODE_REL);
- bdata->debounce_timer.function = gpio_keys_debounce_timer;
+ hrtimer_setup(&bdata->debounce_timer, gpio_keys_debounce_timer,
+ CLOCK_REALTIME, HRTIMER_MODE_REL);
isr = gpio_keys_gpio_isr;
irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
@@ -628,9 +627,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
}
bdata->release_delay = button->debounce_interval;
- hrtimer_init(&bdata->release_timer,
- CLOCK_REALTIME, HRTIMER_MODE_REL_HARD);
- bdata->release_timer.function = gpio_keys_irq_timer;
+ hrtimer_setup(&bdata->release_timer, gpio_keys_irq_timer,
+ CLOCK_REALTIME, HRTIMER_MODE_REL_HARD);
isr = gpio_keys_irq_isr;
irqflags = 0;
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index b92268ddfd84..3cd47fa44efc 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -370,7 +370,7 @@ static void imx_keypad_close(struct input_dev *dev)
/* Mark keypad as being inactive */
keypad->enabled = false;
synchronize_irq(keypad->irq);
- del_timer_sync(&keypad->check_matrix_timer);
+ timer_delete_sync(&keypad->check_matrix_timer);
imx_keypad_inhibit(keypad);
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 2a3b3bfc2878..e46473cb817c 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -26,6 +26,7 @@ struct matrix_keypad {
unsigned int row_shift;
unsigned int col_scan_delay_us;
+ unsigned int all_cols_on_delay_us;
/* key debounce interval in milli-second */
unsigned int debounce_ms;
bool drive_inactive_cols;
@@ -68,7 +69,7 @@ static void activate_col(struct matrix_keypad *keypad, int col, bool on)
__activate_col(keypad, col, on);
if (on && keypad->col_scan_delay_us)
- udelay(keypad->col_scan_delay_us);
+ fsleep(keypad->col_scan_delay_us);
}
static void activate_all_cols(struct matrix_keypad *keypad, bool on)
@@ -77,6 +78,9 @@ static void activate_all_cols(struct matrix_keypad *keypad, bool on)
for (col = 0; col < keypad->num_col_gpios; col++)
__activate_col(keypad, col, on);
+
+ if (on && keypad->all_cols_on_delay_us)
+ fsleep(keypad->all_cols_on_delay_us);
}
static bool row_asserted(struct matrix_keypad *keypad, int row)
@@ -392,6 +396,8 @@ static int matrix_keypad_probe(struct platform_device *pdev)
&keypad->debounce_ms);
device_property_read_u32(&pdev->dev, "col-scan-delay-us",
&keypad->col_scan_delay_us);
+ device_property_read_u32(&pdev->dev, "all-cols-on-delay-us",
+ &keypad->all_cols_on_delay_us);
err = matrix_keypad_init_gpio(pdev, keypad);
if (err)
diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
index f7b5f1e25c80..bbf409dda89f 100644
--- a/drivers/input/keyboard/snvs_pwrkey.c
+++ b/drivers/input/keyboard/snvs_pwrkey.c
@@ -104,7 +104,7 @@ static void imx_snvs_pwrkey_act(void *pdata)
{
struct pwrkey_drv_data *pd = pdata;
- del_timer_sync(&pd->check_timer);
+ timer_delete_sync(&pd->check_timer);
}
static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index 6776dd94ce76..32a676f0de53 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -416,7 +416,7 @@ static void tegra_kbc_stop(struct tegra_kbc *kbc)
}
disable_irq(kbc->irq);
- del_timer_sync(&kbc->timer);
+ timer_delete_sync(&kbc->timer);
clk_disable_unprepare(kbc->clk);
}
@@ -703,7 +703,7 @@ static int tegra_kbc_suspend(struct device *dev)
if (device_may_wakeup(&pdev->dev)) {
disable_irq(kbc->irq);
- del_timer_sync(&kbc->timer);
+ timer_delete_sync(&kbc->timer);
tegra_kbc_set_fifo_interrupt(kbc, false);
/* Forcefully clear the interrupt status */
diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c
index d0c46665e527..d952c16f2458 100644
--- a/drivers/input/misc/pm8941-pwrkey.c
+++ b/drivers/input/misc/pm8941-pwrkey.c
@@ -154,8 +154,8 @@ static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
if (pwrkey->sw_debounce_time_us) {
if (ktime_before(ktime_get(), pwrkey->sw_debounce_end_time)) {
dev_dbg(pwrkey->dev,
- "ignoring key event received before debounce end %llu us\n",
- pwrkey->sw_debounce_end_time);
+ "ignoring key event received before debounce end %lld us\n",
+ ktime_to_us(pwrkey->sw_debounce_end_time));
return IRQ_HANDLED;
}
}
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 0728b5c08f02..0bd7b09b0aa3 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -1519,7 +1519,7 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
return PSMOUSE_GOOD_DATA;
}
- del_timer(&priv->timer);
+ timer_delete(&priv->timer);
if (psmouse->packet[6] & 0x80) {
diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c
index 654b38d249f3..4ee084e00a7c 100644
--- a/drivers/input/mouse/byd.c
+++ b/drivers/input/mouse/byd.c
@@ -425,7 +425,7 @@ static void byd_disconnect(struct psmouse *psmouse)
struct byd_data *priv = psmouse->private;
if (priv) {
- del_timer(&priv->timer);
+ timer_delete(&priv->timer);
kfree(psmouse->private);
psmouse->private = NULL;
}
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 2f2d925a55d7..00c87c0532a6 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -1080,8 +1080,8 @@ static ssize_t cyapa_update_fw_store(struct device *dev,
char fw_name[NAME_MAX];
int ret, error;
- if (count >= NAME_MAX) {
- dev_err(dev, "File name too long\n");
+ if (!count || count >= NAME_MAX) {
+ dev_err(dev, "Bad file name size\n");
return -EINVAL;
}
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index aba57abe6978..309c360aab55 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -161,6 +161,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
NULL
};
+#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS
static const char * const smbus_pnp_ids[] = {
/* all of the topbuttonpad_pnp_ids are valid, we just add some extras */
"LEN0048", /* X1 Carbon 3 */
@@ -196,6 +197,7 @@ static const char * const smbus_pnp_ids[] = {
"SYN3257", /* HP Envy 13-ad105ng */
NULL
};
+#endif
static const char * const forcepad_pnp_ids[] = {
"SYN300D",
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
index 5c3da910b5b2..ac4041a69fcd 100644
--- a/drivers/input/rmi4/rmi_f54.c
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -372,8 +372,6 @@ static const struct vb2_ops rmi_f54_queue_ops = {
.queue_setup = rmi_f54_queue_setup,
.buf_queue = rmi_f54_buffer_queue,
.stop_streaming = rmi_f54_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
static const struct vb2_queue rmi_f54_queue = {
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index d36e89d6fc54..94e8bcbbf94d 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -1017,7 +1017,7 @@ static int __init hil_mlc_init(void)
static void __exit hil_mlc_exit(void)
{
- del_timer_sync(&hil_mlcs_kicker);
+ timer_delete_sync(&hil_mlcs_kicker);
tasklet_kill(&hil_mlcs_tasklet);
}
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 13eacf6ab431..0eec4c5585cb 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -980,7 +980,7 @@ static void hp_sdc_exit(void)
free_irq(hp_sdc.irq, &hp_sdc);
write_unlock_irq(&hp_sdc.lock);
- del_timer_sync(&hp_sdc.kicker);
+ timer_delete_sync(&hp_sdc.kicker);
tasklet_kill(&hp_sdc.task);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 1a03de7fcfa6..91a2b584dab1 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -103,6 +103,19 @@ config TOUCHSCREEN_ADC
To compile this driver as a module, choose M here: the
module will be called resistive-adc-touch.ko.
+config TOUCHSCREEN_APPLE_Z2
+ tristate "Apple Z2 touchscreens"
+ default ARCH_APPLE
+ depends on SPI && (ARCH_APPLE || COMPILE_TEST)
+ help
+ Say Y here if you have an ARM Apple device with
+ a touchscreen or a touchbar.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called apple_z2.
+
config TOUCHSCREEN_AR1021_I2C
tristate "Microchip AR1020/1021 i2c touchscreen"
depends on I2C && OF
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 82bc837ca01e..97a025c6a377 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
obj-$(CONFIG_TOUCHSCREEN_ADC) += resistive-adc-touch.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
+obj-$(CONFIG_TOUCHSCREEN_APPLE_Z2) += apple_z2.o
obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
index a0598e9c7aff..8d8392ce7005 100644
--- a/drivers/input/touchscreen/ad7877.c
+++ b/drivers/input/touchscreen/ad7877.c
@@ -415,7 +415,7 @@ static void ad7877_disable(void *data)
ts->disabled = true;
disable_irq(ts->spi->irq);
- if (del_timer_sync(&ts->timer))
+ if (timer_delete_sync(&ts->timer))
ad7877_ts_event_release(ts);
}
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index e5d69bf2276e..f661e199b63c 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -273,7 +273,7 @@ static void __ad7879_disable(struct ad7879 *ts)
AD7879_PM(AD7879_PM_SHUTDOWN);
disable_irq(ts->irq);
- if (del_timer_sync(&ts->timer))
+ if (timer_delete_sync(&ts->timer))
ad7879_ts_event_release(ts);
ad7879_write(ts, AD7879_REG_CTRL2, reg);
diff --git a/drivers/input/touchscreen/apple_z2.c b/drivers/input/touchscreen/apple_z2.c
new file mode 100644
index 000000000000..0de161eae59a
--- /dev/null
+++ b/drivers/input/touchscreen/apple_z2.c
@@ -0,0 +1,477 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Apple Z2 touchscreen driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ */
+
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/spi/spi.h>
+#include <linux/unaligned.h>
+
+#define APPLE_Z2_NUM_FINGERS_OFFSET 16
+#define APPLE_Z2_FINGERS_OFFSET 24
+#define APPLE_Z2_TOUCH_STARTED 3
+#define APPLE_Z2_TOUCH_MOVED 4
+#define APPLE_Z2_CMD_READ_INTERRUPT_DATA 0xEB
+#define APPLE_Z2_HBPP_CMD_BLOB 0x3001
+#define APPLE_Z2_FW_MAGIC 0x5746325A
+#define LOAD_COMMAND_INIT_PAYLOAD 0
+#define LOAD_COMMAND_SEND_BLOB 1
+#define LOAD_COMMAND_SEND_CALIBRATION 2
+#define CAL_PROP_NAME "apple,z2-cal-blob"
+
+struct apple_z2 {
+ struct spi_device *spidev;
+ struct gpio_desc *reset_gpio;
+ struct input_dev *input_dev;
+ struct completion boot_irq;
+ bool booted;
+ int index_parity;
+ struct touchscreen_properties props;
+ const char *fw_name;
+ u8 *tx_buf;
+ u8 *rx_buf;
+};
+
+struct apple_z2_finger {
+ u8 finger;
+ u8 state;
+ __le16 unknown2;
+ __le16 abs_x;
+ __le16 abs_y;
+ __le16 rel_x;
+ __le16 rel_y;
+ __le16 tool_major;
+ __le16 tool_minor;
+ __le16 orientation;
+ __le16 touch_major;
+ __le16 touch_minor;
+ __le16 unused[2];
+ __le16 pressure;
+ __le16 multi;
+} __packed;
+
+struct apple_z2_hbpp_blob_hdr {
+ __le16 cmd;
+ __le16 len;
+ __le32 addr;
+ __le16 checksum;
+};
+
+struct apple_z2_fw_hdr {
+ __le32 magic;
+ __le32 version;
+};
+
+struct apple_z2_read_interrupt_cmd {
+ u8 cmd;
+ u8 counter;
+ u8 unused[12];
+ __le16 checksum;
+};
+
+static void apple_z2_parse_touches(struct apple_z2 *z2,
+ const u8 *msg, size_t msg_len)
+{
+ int i;
+ int nfingers;
+ int slot;
+ int slot_valid;
+ struct apple_z2_finger *fingers;
+
+ if (msg_len <= APPLE_Z2_NUM_FINGERS_OFFSET)
+ return;
+ nfingers = msg[APPLE_Z2_NUM_FINGERS_OFFSET];
+ fingers = (struct apple_z2_finger *)(msg + APPLE_Z2_FINGERS_OFFSET);
+ for (i = 0; i < nfingers; i++) {
+ slot = input_mt_get_slot_by_key(z2->input_dev, fingers[i].finger);
+ if (slot < 0) {
+ dev_warn(&z2->spidev->dev, "unable to get slot for finger\n");
+ continue;
+ }
+ slot_valid = fingers[i].state == APPLE_Z2_TOUCH_STARTED ||
+ fingers[i].state == APPLE_Z2_TOUCH_MOVED;
+ input_mt_slot(z2->input_dev, slot);
+ if (!input_mt_report_slot_state(z2->input_dev, MT_TOOL_FINGER, slot_valid))
+ continue;
+ touchscreen_report_pos(z2->input_dev, &z2->props,
+ le16_to_cpu(fingers[i].abs_x),
+ le16_to_cpu(fingers[i].abs_y),
+ true);
+ input_report_abs(z2->input_dev, ABS_MT_WIDTH_MAJOR,
+ le16_to_cpu(fingers[i].tool_major));
+ input_report_abs(z2->input_dev, ABS_MT_WIDTH_MINOR,
+ le16_to_cpu(fingers[i].tool_minor));
+ input_report_abs(z2->input_dev, ABS_MT_ORIENTATION,
+ le16_to_cpu(fingers[i].orientation));
+ input_report_abs(z2->input_dev, ABS_MT_TOUCH_MAJOR,
+ le16_to_cpu(fingers[i].touch_major));
+ input_report_abs(z2->input_dev, ABS_MT_TOUCH_MINOR,
+ le16_to_cpu(fingers[i].touch_minor));
+ }
+ input_mt_sync_frame(z2->input_dev);
+ input_sync(z2->input_dev);
+}
+
+static int apple_z2_read_packet(struct apple_z2 *z2)
+{
+ struct apple_z2_read_interrupt_cmd *len_cmd = (void *)z2->tx_buf;
+ struct spi_transfer xfer;
+ int error;
+ size_t pkt_len;
+
+ memset(&xfer, 0, sizeof(xfer));
+ len_cmd->cmd = APPLE_Z2_CMD_READ_INTERRUPT_DATA;
+ len_cmd->counter = z2->index_parity + 1;
+ len_cmd->checksum =
+ cpu_to_le16(APPLE_Z2_CMD_READ_INTERRUPT_DATA + len_cmd->counter);
+ z2->index_parity = !z2->index_parity;
+ xfer.tx_buf = z2->tx_buf;
+ xfer.rx_buf = z2->rx_buf;
+ xfer.len = sizeof(*len_cmd);
+
+ error = spi_sync_transfer(z2->spidev, &xfer, 1);
+ if (error)
+ return error;
+
+ pkt_len = (get_unaligned_le16(z2->rx_buf + 1) + 8) & 0xfffffffc;
+
+ error = spi_read(z2->spidev, z2->rx_buf, pkt_len);
+ if (error)
+ return error;
+
+ apple_z2_parse_touches(z2, z2->rx_buf + 5, pkt_len - 5);
+
+ return 0;
+}
+
+static irqreturn_t apple_z2_irq(int irq, void *data)
+{
+ struct apple_z2 *z2 = data;
+
+ if (unlikely(!z2->booted))
+ complete(&z2->boot_irq);
+ else
+ apple_z2_read_packet(z2);
+
+ return IRQ_HANDLED;
+}
+
+/* Build calibration blob, caller is responsible for freeing the blob data. */
+static const u8 *apple_z2_build_cal_blob(struct apple_z2 *z2,
+ u32 address, size_t *size)
+{
+ u8 *cal_data;
+ int cal_size;
+ size_t blob_size;
+ u32 checksum;
+ u16 checksum_hdr;
+ int i;
+ struct apple_z2_hbpp_blob_hdr *hdr;
+ int error;
+
+ if (!device_property_present(&z2->spidev->dev, CAL_PROP_NAME))
+ return NULL;
+
+ cal_size = device_property_count_u8(&z2->spidev->dev, CAL_PROP_NAME);
+ if (cal_size < 0)
+ return ERR_PTR(cal_size);
+
+ blob_size = sizeof(struct apple_z2_hbpp_blob_hdr) + cal_size + sizeof(__le32);
+ u8 *blob_data __free(kfree) = kzalloc(blob_size, GFP_KERNEL);
+ if (!blob_data)
+ return ERR_PTR(-ENOMEM);
+
+ hdr = (struct apple_z2_hbpp_blob_hdr *)blob_data;
+ hdr->cmd = cpu_to_le16(APPLE_Z2_HBPP_CMD_BLOB);
+ hdr->len = cpu_to_le16(round_up(cal_size, 4) / 4);
+ hdr->addr = cpu_to_le32(address);
+
+ checksum_hdr = 0;
+ for (i = 2; i < 8; i++)
+ checksum_hdr += blob_data[i];
+ hdr->checksum = cpu_to_le16(checksum_hdr);
+
+ cal_data = blob_data + sizeof(struct apple_z2_hbpp_blob_hdr);
+ error = device_property_read_u8_array(&z2->spidev->dev, CAL_PROP_NAME,
+ cal_data, cal_size);
+ if (error)
+ return ERR_PTR(error);
+
+ checksum = 0;
+ for (i = 0; i < cal_size; i++)
+ checksum += cal_data[i];
+ put_unaligned_le32(checksum, cal_data + cal_size);
+
+ *size = blob_size;
+ return no_free_ptr(blob_data);
+}
+
+static int apple_z2_send_firmware_blob(struct apple_z2 *z2, const u8 *data,
+ u32 size, bool init)
+{
+ struct spi_message msg;
+ struct spi_transfer blob_xfer, ack_xfer;
+ int error;
+
+ z2->tx_buf[0] = 0x1a;
+ z2->tx_buf[1] = 0xa1;
+
+ spi_message_init(&msg);
+ memset(&blob_xfer, 0, sizeof(blob_xfer));
+ memset(&ack_xfer, 0, sizeof(ack_xfer));
+
+ blob_xfer.tx_buf = data;
+ blob_xfer.len = size;
+ blob_xfer.bits_per_word = init ? 8 : 16;
+ spi_message_add_tail(&blob_xfer, &msg);
+
+ ack_xfer.tx_buf = z2->tx_buf;
+ ack_xfer.len = 2;
+ spi_message_add_tail(&ack_xfer, &msg);
+
+ reinit_completion(&z2->boot_irq);
+ error = spi_sync(z2->spidev, &msg);
+ if (error)
+ return error;
+
+ /* Irq only happens sometimes, but the thing boots reliably nonetheless */
+ wait_for_completion_timeout(&z2->boot_irq, msecs_to_jiffies(20));
+
+ return 0;
+}
+
+static int apple_z2_upload_firmware(struct apple_z2 *z2)
+{
+ const struct apple_z2_fw_hdr *fw_hdr;
+ size_t fw_idx = sizeof(struct apple_z2_fw_hdr);
+ int error;
+ u32 load_cmd;
+ u32 address;
+ bool init;
+ size_t size;
+
+ const struct firmware *fw __free(firmware) = NULL;
+ error = request_firmware(&fw, z2->fw_name, &z2->spidev->dev);
+ if (error) {
+ dev_err(&z2->spidev->dev, "unable to load firmware\n");
+ return error;
+ }
+
+ fw_hdr = (const struct apple_z2_fw_hdr *)fw->data;
+ if (le32_to_cpu(fw_hdr->magic) != APPLE_Z2_FW_MAGIC || le32_to_cpu(fw_hdr->version) != 1) {
+ dev_err(&z2->spidev->dev, "invalid firmware header\n");
+ return -EINVAL;
+ }
+
+ /*
+ * This will interrupt the upload half-way if the file is malformed
+ * As the device has no non-volatile storage to corrupt, and gets reset
+ * on boot anyway, this is fine.
+ */
+ while (fw_idx < fw->size) {
+ if (fw->size - fw_idx < 8) {
+ dev_err(&z2->spidev->dev, "firmware malformed\n");
+ return -EINVAL;
+ }
+
+ load_cmd = le32_to_cpup((__force __le32 *)(fw->data + fw_idx));
+ fw_idx += sizeof(u32);
+ if (load_cmd == LOAD_COMMAND_INIT_PAYLOAD || load_cmd == LOAD_COMMAND_SEND_BLOB) {
+ size = le32_to_cpup((__force __le32 *)(fw->data + fw_idx));
+ fw_idx += sizeof(u32);
+ if (fw->size - fw_idx < size) {
+ dev_err(&z2->spidev->dev, "firmware malformed\n");
+ return -EINVAL;
+ }
+ init = load_cmd == LOAD_COMMAND_INIT_PAYLOAD;
+ error = apple_z2_send_firmware_blob(z2, fw->data + fw_idx,
+ size, init);
+ if (error)
+ return error;
+ fw_idx += size;
+ } else if (load_cmd == LOAD_COMMAND_SEND_CALIBRATION) {
+ address = le32_to_cpup((__force __le32 *)(fw->data + fw_idx));
+ fw_idx += sizeof(u32);
+
+ const u8 *data __free(kfree) =
+ apple_z2_build_cal_blob(z2, address, &size);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ if (data) {
+ error = apple_z2_send_firmware_blob(z2, data, size, false);
+ if (error)
+ return error;
+ }
+ } else {
+ dev_err(&z2->spidev->dev, "firmware malformed\n");
+ return -EINVAL;
+ }
+ fw_idx = round_up(fw_idx, 4);
+ }
+
+
+ z2->booted = true;
+ apple_z2_read_packet(z2);
+ return 0;
+}
+
+static int apple_z2_boot(struct apple_z2 *z2)
+{
+ int error;
+
+ reinit_completion(&z2->boot_irq);
+ enable_irq(z2->spidev->irq);
+ gpiod_set_value(z2->reset_gpio, 0);
+ if (!wait_for_completion_timeout(&z2->boot_irq, msecs_to_jiffies(20)))
+ return -ETIMEDOUT;
+
+ error = apple_z2_upload_firmware(z2);
+ if (error) {
+ gpiod_set_value(z2->reset_gpio, 1);
+ disable_irq(z2->spidev->irq);
+ return error;
+ }
+
+ return 0;
+}
+
+static int apple_z2_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct apple_z2 *z2;
+ int error;
+
+ z2 = devm_kzalloc(dev, sizeof(*z2), GFP_KERNEL);
+ if (!z2)
+ return -ENOMEM;
+
+ z2->tx_buf = devm_kzalloc(dev, sizeof(struct apple_z2_read_interrupt_cmd), GFP_KERNEL);
+ if (!z2->tx_buf)
+ return -ENOMEM;
+ /* 4096 will end up being rounded up to 8192 due to devres header */
+ z2->rx_buf = devm_kzalloc(dev, 4000, GFP_KERNEL);
+ if (!z2->rx_buf)
+ return -ENOMEM;
+
+ z2->spidev = spi;
+ init_completion(&z2->boot_irq);
+ spi_set_drvdata(spi, z2);
+
+ /* Reset the device on boot */
+ z2->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(z2->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(z2->reset_gpio), "unable to get reset\n");
+
+ error = devm_request_threaded_irq(dev, z2->spidev->irq, NULL, apple_z2_irq,
+ IRQF_ONESHOT | IRQF_NO_AUTOEN,
+ "apple-z2-irq", z2);
+ if (error)
+ return dev_err_probe(dev, error, "unable to request irq\n");
+
+ error = device_property_read_string(dev, "firmware-name", &z2->fw_name);
+ if (error)
+ return dev_err_probe(dev, error, "unable to get firmware name\n");
+
+ z2->input_dev = devm_input_allocate_device(dev);
+ if (!z2->input_dev)
+ return -ENOMEM;
+
+ z2->input_dev->name = (char *)spi_get_device_id(spi)->driver_data;
+ z2->input_dev->phys = "apple_z2";
+ z2->input_dev->id.bustype = BUS_SPI;
+
+ /* Allocate the axes before setting from DT */
+ input_set_abs_params(z2->input_dev, ABS_MT_POSITION_X, 0, 0, 0, 0);
+ input_set_abs_params(z2->input_dev, ABS_MT_POSITION_Y, 0, 0, 0, 0);
+ touchscreen_parse_properties(z2->input_dev, true, &z2->props);
+ input_abs_set_res(z2->input_dev, ABS_MT_POSITION_X, 100);
+ input_abs_set_res(z2->input_dev, ABS_MT_POSITION_Y, 100);
+ input_set_abs_params(z2->input_dev, ABS_MT_WIDTH_MAJOR, 0, 65535, 0, 0);
+ input_set_abs_params(z2->input_dev, ABS_MT_WIDTH_MINOR, 0, 65535, 0, 0);
+ input_set_abs_params(z2->input_dev, ABS_MT_TOUCH_MAJOR, 0, 65535, 0, 0);
+ input_set_abs_params(z2->input_dev, ABS_MT_TOUCH_MINOR, 0, 65535, 0, 0);
+ input_set_abs_params(z2->input_dev, ABS_MT_ORIENTATION, -32768, 32767, 0, 0);
+
+ error = input_mt_init_slots(z2->input_dev, 256, INPUT_MT_DIRECT);
+ if (error)
+ return dev_err_probe(dev, error, "unable to initialize multitouch slots\n");
+
+ error = input_register_device(z2->input_dev);
+ if (error)
+ return dev_err_probe(dev, error, "unable to register input device\n");
+
+ /* Wait for device reset to finish */
+ usleep_range(5000, 10000);
+ error = apple_z2_boot(z2);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static void apple_z2_shutdown(struct spi_device *spi)
+{
+ struct apple_z2 *z2 = spi_get_drvdata(spi);
+
+ disable_irq(z2->spidev->irq);
+ gpiod_direction_output(z2->reset_gpio, 1);
+ z2->booted = false;
+}
+
+static int apple_z2_suspend(struct device *dev)
+{
+ apple_z2_shutdown(to_spi_device(dev));
+
+ return 0;
+}
+
+static int apple_z2_resume(struct device *dev)
+{
+ struct apple_z2 *z2 = spi_get_drvdata(to_spi_device(dev));
+
+ return apple_z2_boot(z2);
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(apple_z2_pm, apple_z2_suspend, apple_z2_resume);
+
+static const struct of_device_id apple_z2_of_match[] = {
+ { .compatible = "apple,j293-touchbar" },
+ { .compatible = "apple,j493-touchbar" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, apple_z2_of_match);
+
+static struct spi_device_id apple_z2_of_id[] = {
+ { .name = "j293-touchbar", .driver_data = (kernel_ulong_t)"MacBookPro17,1 Touch Bar" },
+ { .name = "j493-touchbar", .driver_data = (kernel_ulong_t)"Mac14,7 Touch Bar" },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, apple_z2_of_id);
+
+static struct spi_driver apple_z2_driver = {
+ .driver = {
+ .name = "apple-z2",
+ .pm = pm_sleep_ptr(&apple_z2_pm),
+ .of_match_table = apple_z2_of_match,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .id_table = apple_z2_of_id,
+ .probe = apple_z2_probe,
+ .remove = apple_z2_shutdown,
+};
+
+module_spi_driver(apple_z2_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("apple/dfrmtfw-*.bin");
+MODULE_DESCRIPTION("Apple Z2 touchscreens driver");
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3ddabc5a2c99..322d5a3d40a0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2535,8 +2535,6 @@ fault:
static const struct vb2_ops mxt_queue_ops = {
.queue_setup = mxt_queue_setup,
.buf_queue = mxt_buffer_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
static const struct vb2_queue mxt_queue = {
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
index 686d0a6b1570..3c997fba7048 100644
--- a/drivers/input/touchscreen/bu21029_ts.c
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -325,7 +325,7 @@ static void bu21029_stop_chip(struct input_dev *dev)
struct bu21029_ts_data *bu21029 = input_get_drvdata(dev);
disable_irq(bu21029->client->irq);
- del_timer_sync(&bu21029->timer);
+ timer_delete_sync(&bu21029->timer);
bu21029_put_chip_in_reset(bu21029);
regulator_disable(bu21029->vdd);
diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c
index fdda8412b164..9a5977d8cad2 100644
--- a/drivers/input/touchscreen/exc3000.c
+++ b/drivers/input/touchscreen/exc3000.c
@@ -174,7 +174,7 @@ static int exc3000_handle_mt_event(struct exc3000_data *data)
/*
* We read full state successfully, no contacts will be "stuck".
*/
- del_timer_sync(&data->timer);
+ timer_delete_sync(&data->timer);
while (total_slots > 0) {
int slots = min(total_slots, EXC3000_SLOTS_PER_FRAME);
diff --git a/drivers/input/touchscreen/goodix_berlin.h b/drivers/input/touchscreen/goodix_berlin.h
index 38b6f9ddbdef..d8bbd4853206 100644
--- a/drivers/input/touchscreen/goodix_berlin.h
+++ b/drivers/input/touchscreen/goodix_berlin.h
@@ -12,12 +12,26 @@
#include <linux/pm.h>
+#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR_A 0x1000C
+#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D 0x10014
+
+#define GOODIX_BERLIN_IC_INFO_ADDR_A 0x10068
+#define GOODIX_BERLIN_IC_INFO_ADDR_D 0x10070
+
+struct goodix_berlin_ic_data {
+ int fw_version_info_addr;
+ int ic_info_addr;
+ ssize_t read_dummy_len;
+ ssize_t read_prefix_len;
+};
+
struct device;
struct input_id;
struct regmap;
int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
- struct regmap *regmap);
+ struct regmap *regmap,
+ const struct goodix_berlin_ic_data *ic_data);
extern const struct dev_pm_ops goodix_berlin_pm_ops;
extern const struct attribute_group *goodix_berlin_groups[];
diff --git a/drivers/input/touchscreen/goodix_berlin_core.c b/drivers/input/touchscreen/goodix_berlin_core.c
index f7ea443b152e..02a1d9a465f2 100644
--- a/drivers/input/touchscreen/goodix_berlin_core.c
+++ b/drivers/input/touchscreen/goodix_berlin_core.c
@@ -12,7 +12,7 @@
* to the previous generations.
*
* Currently the driver only handles Multitouch events with already
- * programmed firmware and "config" for "Revision D" Berlin IC.
+ * programmed firmware and "config" for "Revision A/D" Berlin IC.
*
* Support is missing for:
* - ESD Management
@@ -20,7 +20,7 @@
* - "Config" update/flashing
* - Stylus Events
* - Gesture Events
- * - Support for older revisions (A & B)
+ * - Support for revision B
*/
#include <linux/bitfield.h>
@@ -28,6 +28,7 @@
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
@@ -53,10 +54,8 @@
#define GOODIX_BERLIN_DEV_CONFIRM_VAL 0xAA
#define GOODIX_BERLIN_BOOTOPTION_ADDR 0x10000
-#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR 0x10014
#define GOODIX_BERLIN_IC_INFO_MAX_LEN SZ_1K
-#define GOODIX_BERLIN_IC_INFO_ADDR 0x10070
#define GOODIX_BERLIN_CHECKSUM_SIZE sizeof(u16)
@@ -175,6 +174,8 @@ struct goodix_berlin_core {
/* Runtime parameters extracted from IC_INFO buffer */
u32 touch_data_addr;
+ const struct goodix_berlin_ic_data *ic_data;
+
struct goodix_berlin_event event;
};
@@ -299,7 +300,7 @@ static int goodix_berlin_read_version(struct goodix_berlin_core *cd)
{
int error;
- error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_FW_VERSION_INFO_ADDR,
+ error = regmap_raw_read(cd->regmap, cd->ic_data->fw_version_info_addr,
&cd->fw_version, sizeof(cd->fw_version));
if (error) {
dev_err(cd->dev, "error reading fw version, %d\n", error);
@@ -367,7 +368,7 @@ static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
if (!afe_data)
return -ENOMEM;
- error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
+ error = regmap_raw_read(cd->regmap, cd->ic_data->ic_info_addr,
&length_raw, sizeof(length_raw));
if (error) {
dev_err(cd->dev, "failed get ic info length, %d\n", error);
@@ -380,8 +381,8 @@ static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
return -EINVAL;
}
- error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
- afe_data, length);
+ error = regmap_raw_read(cd->regmap, cd->ic_data->ic_info_addr, afe_data,
+ length);
if (error) {
dev_err(cd->dev, "failed get ic info data, %d\n", error);
return error;
@@ -716,7 +717,8 @@ const struct attribute_group *goodix_berlin_groups[] = {
EXPORT_SYMBOL_GPL(goodix_berlin_groups);
int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
- struct regmap *regmap)
+ struct regmap *regmap,
+ const struct goodix_berlin_ic_data *ic_data)
{
struct goodix_berlin_core *cd;
int error;
@@ -733,6 +735,7 @@ int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
cd->dev = dev;
cd->regmap = regmap;
cd->irq = irq;
+ cd->ic_data = ic_data;
cd->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(cd->reset_gpio))
diff --git a/drivers/input/touchscreen/goodix_berlin_i2c.c b/drivers/input/touchscreen/goodix_berlin_i2c.c
index ad7a60d94338..929090a094bf 100644
--- a/drivers/input/touchscreen/goodix_berlin_i2c.c
+++ b/drivers/input/touchscreen/goodix_berlin_i2c.c
@@ -31,6 +31,8 @@ static const struct input_id goodix_berlin_i2c_input_id = {
static int goodix_berlin_i2c_probe(struct i2c_client *client)
{
+ const struct goodix_berlin_ic_data *ic_data =
+ i2c_get_match_data(client);
struct regmap *regmap;
int error;
@@ -39,22 +41,28 @@ static int goodix_berlin_i2c_probe(struct i2c_client *client)
return PTR_ERR(regmap);
error = goodix_berlin_probe(&client->dev, client->irq,
- &goodix_berlin_i2c_input_id, regmap);
+ &goodix_berlin_i2c_input_id, regmap,
+ ic_data);
if (error)
return error;
return 0;
}
+static const struct goodix_berlin_ic_data gt9916_data = {
+ .fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D,
+ .ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_D,
+};
+
static const struct i2c_device_id goodix_berlin_i2c_id[] = {
- { "gt9916" },
+ { .name = "gt9916", .driver_data = (long)&gt9916_data },
{ }
};
MODULE_DEVICE_TABLE(i2c, goodix_berlin_i2c_id);
static const struct of_device_id goodix_berlin_i2c_of_match[] = {
- { .compatible = "goodix,gt9916", },
+ { .compatible = "goodix,gt9916", .data = &gt9916_data },
{ }
};
MODULE_DEVICE_TABLE(of, goodix_berlin_i2c_of_match);
diff --git a/drivers/input/touchscreen/goodix_berlin_spi.c b/drivers/input/touchscreen/goodix_berlin_spi.c
index 0662e87b8692..01f850f484c2 100644
--- a/drivers/input/touchscreen/goodix_berlin_spi.c
+++ b/drivers/input/touchscreen/goodix_berlin_spi.c
@@ -18,10 +18,14 @@
#define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN 1
#define GOODIX_BERLIN_REGISTER_WIDTH 4
-#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN 3
-#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
+#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A 4
+#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D 3
+#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN_A (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
GOODIX_BERLIN_REGISTER_WIDTH + \
- GOODIX_BERLIN_SPI_READ_DUMMY_LEN)
+ GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A)
+#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN_D (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
+ GOODIX_BERLIN_REGISTER_WIDTH + \
+ GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D)
#define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
GOODIX_BERLIN_REGISTER_WIDTH)
@@ -33,6 +37,7 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
size_t val_size)
{
struct spi_device *spi = context;
+ const struct goodix_berlin_ic_data *ic_data = spi_get_device_match_data(spi);
struct spi_transfer xfers;
struct spi_message spi_msg;
const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */
@@ -42,23 +47,22 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
return -EINVAL;
u8 *buf __free(kfree) =
- kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size,
- GFP_KERNEL);
+ kzalloc(ic_data->read_prefix_len + val_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
spi_message_init(&spi_msg);
memset(&xfers, 0, sizeof(xfers));
- /* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
+ /* buffer format: 0xF1 + addr(4bytes) + dummy(3/4bytes) + data */
buf[0] = GOODIX_BERLIN_SPI_READ_FLAG;
put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN);
memset(buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + GOODIX_BERLIN_REGISTER_WIDTH,
- 0xff, GOODIX_BERLIN_SPI_READ_DUMMY_LEN);
+ 0xff, ic_data->read_dummy_len);
xfers.tx_buf = buf;
xfers.rx_buf = buf;
- xfers.len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size;
+ xfers.len = ic_data->read_prefix_len + val_size;
xfers.cs_change = 0;
spi_message_add_tail(&xfers, &spi_msg);
@@ -68,7 +72,7 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
return error;
}
- memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size);
+ memcpy(val_buf, buf + ic_data->read_prefix_len, val_size);
return error;
}
@@ -123,6 +127,7 @@ static const struct input_id goodix_berlin_spi_input_id = {
static int goodix_berlin_spi_probe(struct spi_device *spi)
{
+ const struct goodix_berlin_ic_data *ic_data = spi_get_device_match_data(spi);
struct regmap_config regmap_config;
struct regmap *regmap;
size_t max_size;
@@ -137,7 +142,7 @@ static int goodix_berlin_spi_probe(struct spi_device *spi)
max_size = spi_max_transfer_size(spi);
regmap_config = goodix_berlin_spi_regmap_conf;
- regmap_config.max_raw_read = max_size - GOODIX_BERLIN_SPI_READ_PREFIX_LEN;
+ regmap_config.max_raw_read = max_size - ic_data->read_prefix_len;
regmap_config.max_raw_write = max_size - GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN;
regmap = devm_regmap_init(&spi->dev, NULL, spi, &regmap_config);
@@ -145,21 +150,38 @@ static int goodix_berlin_spi_probe(struct spi_device *spi)
return PTR_ERR(regmap);
error = goodix_berlin_probe(&spi->dev, spi->irq,
- &goodix_berlin_spi_input_id, regmap);
+ &goodix_berlin_spi_input_id, regmap,
+ ic_data);
if (error)
return error;
return 0;
}
+static const struct goodix_berlin_ic_data gt9897_data = {
+ .fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_A,
+ .ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_A,
+ .read_dummy_len = GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A,
+ .read_prefix_len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN_A,
+};
+
+static const struct goodix_berlin_ic_data gt9916_data = {
+ .fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D,
+ .ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_D,
+ .read_dummy_len = GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D,
+ .read_prefix_len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN_D,
+};
+
static const struct spi_device_id goodix_berlin_spi_ids[] = {
- { "gt9916" },
+ { .name = "gt9897", .driver_data = (long)&gt9897_data },
+ { .name = "gt9916", .driver_data = (long)&gt9916_data },
{ },
};
MODULE_DEVICE_TABLE(spi, goodix_berlin_spi_ids);
static const struct of_device_id goodix_berlin_spi_of_match[] = {
- { .compatible = "goodix,gt9916", },
+ { .compatible = "goodix,gt9897", .data = &gt9897_data },
+ { .compatible = "goodix,gt9916", .data = &gt9916_data },
{ }
};
MODULE_DEVICE_TABLE(of, goodix_berlin_spi_of_match);
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 8365a2ac6fce..7b3b10cbfcfc 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -1108,8 +1108,6 @@ static const struct vb2_ops sur40_queue_ops = {
.buf_queue = sur40_buffer_queue,
.start_streaming = sur40_start_streaming,
.stop_streaming = sur40_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
static const struct vb2_queue sur40_queue = {
diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c
index f5c5881cef6b..e59b8d0ed19e 100644
--- a/drivers/input/touchscreen/sx8654.c
+++ b/drivers/input/touchscreen/sx8654.c
@@ -290,7 +290,7 @@ static void sx8654_close(struct input_dev *dev)
disable_irq(client->irq);
if (!sx8654->data->has_irq_penrelease)
- del_timer_sync(&sx8654->timer);
+ timer_delete_sync(&sx8654->timer);
/* enable manual mode mode */
error = i2c_smbus_write_byte(client, sx8654->data->cmd_manual);
diff --git a/drivers/input/touchscreen/tsc2007.h b/drivers/input/touchscreen/tsc2007.h
index 69b08dd6c8df..e346fb4f7552 100644
--- a/drivers/input/touchscreen/tsc2007.h
+++ b/drivers/input/touchscreen/tsc2007.h
@@ -19,6 +19,7 @@
#ifndef _TSC2007_H
#define _TSC2007_H
+#include <linux/input/touchscreen.h>
struct gpio_desc;
#define TSC2007_MEASURE_TEMP0 (0x0 << 4)
@@ -63,6 +64,7 @@ struct tsc2007 {
struct i2c_client *client;
+ struct touchscreen_properties prop;
u16 model;
u16 x_plate_ohms;
u16 max_rt;
diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c
index 8d832a372b89..5252301686ec 100644
--- a/drivers/input/touchscreen/tsc2007_core.c
+++ b/drivers/input/touchscreen/tsc2007_core.c
@@ -142,8 +142,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
rt = ts->max_rt - rt;
input_report_key(input, BTN_TOUCH, 1);
- input_report_abs(input, ABS_X, tc.x);
- input_report_abs(input, ABS_Y, tc.y);
+ touchscreen_report_pos(input, &ts->prop, tc.x, tc.y, false);
input_report_abs(input, ABS_PRESSURE, rt);
input_sync(input);
@@ -339,9 +338,9 @@ static int tsc2007_probe(struct i2c_client *client)
input_set_drvdata(input_dev, ts);
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
-
input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
+ touchscreen_parse_properties(input_dev, false, &ts->prop);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
ts->fuzzz, 0);
diff --git a/drivers/input/touchscreen/tsc200x-core.c b/drivers/input/touchscreen/tsc200x-core.c
index df39dee13e1c..252a93753ee5 100644
--- a/drivers/input/touchscreen/tsc200x-core.c
+++ b/drivers/input/touchscreen/tsc200x-core.c
@@ -229,7 +229,7 @@ static void __tsc200x_disable(struct tsc200x *ts)
guard(disable_irq)(&ts->irq);
- del_timer_sync(&ts->penup_timer);
+ timer_delete_sync(&ts->penup_timer);
cancel_delayed_work_sync(&ts->esd_work);
}
@@ -388,7 +388,7 @@ static void tsc200x_esd_work(struct work_struct *work)
dev_info(ts->dev, "TSC200X not responding - resetting\n");
scoped_guard(disable_irq, &ts->irq) {
- del_timer_sync(&ts->penup_timer);
+ timer_delete_sync(&ts->penup_timer);
tsc200x_update_pen_state(ts, 0, 0, 0);
tsc200x_reset(ts);
}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 5aa2e7af58b4..e4fd8d522af8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -43,6 +43,8 @@ static void arm_smmu_make_nested_cd_table_ste(
target->data[0] |= nested_domain->ste[0] &
~cpu_to_le64(STRTAB_STE_0_CFG);
target->data[1] |= nested_domain->ste[1];
+ /* Merge events for DoS mitigations on eventq */
+ target->data[1] |= cpu_to_le64(STRTAB_STE_1_MEV);
}
/*
@@ -85,6 +87,47 @@ static void arm_smmu_make_nested_domain_ste(
}
}
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+ struct arm_smmu_nested_domain *nested_domain)
+{
+ struct arm_smmu_vmaster *vmaster;
+ unsigned long vsid;
+ int ret;
+
+ iommu_group_mutex_assert(state->master->dev);
+
+ ret = iommufd_viommu_get_vdev_id(&nested_domain->vsmmu->core,
+ state->master->dev, &vsid);
+ if (ret)
+ return ret;
+
+ vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
+ if (!vmaster)
+ return -ENOMEM;
+ vmaster->vsmmu = nested_domain->vsmmu;
+ vmaster->vsid = vsid;
+ state->vmaster = vmaster;
+
+ return 0;
+}
+
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+ struct arm_smmu_master *master = state->master;
+
+ mutex_lock(&master->smmu->streams_mutex);
+ kfree(master->vmaster);
+ master->vmaster = state->vmaster;
+ mutex_unlock(&master->smmu->streams_mutex);
+}
+
+void arm_smmu_master_clear_vmaster(struct arm_smmu_master *master)
+{
+ struct arm_smmu_attach_state state = { .master = master };
+
+ arm_smmu_attach_commit_vmaster(&state);
+}
+
static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
struct device *dev)
{
@@ -392,4 +435,21 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
return &vsmmu->core;
}
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
+{
+ struct iommu_vevent_arm_smmuv3 vevt;
+ int i;
+
+ lockdep_assert_held(&vmaster->vsmmu->smmu->streams_mutex);
+
+ vevt.evt[0] = cpu_to_le64((evt[0] & ~EVTQ_0_SID) |
+ FIELD_PREP(EVTQ_0_SID, vmaster->vsid));
+ for (i = 1; i < EVTQ_ENT_DWORDS; i++)
+ vevt.evt[i] = cpu_to_le64(evt[i]);
+
+ return iommufd_viommu_report_event(&vmaster->vsmmu->core,
+ IOMMU_VEVENTQ_TYPE_ARM_SMMUV3, &vevt,
+ sizeof(vevt));
+}
+
MODULE_IMPORT_NS("IOMMUFD");
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 358072b4e293..b4c21aaed126 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1052,7 +1052,7 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR |
STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW |
- STRTAB_STE_1_EATS);
+ STRTAB_STE_1_EATS | STRTAB_STE_1_MEV);
used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
/*
@@ -1068,7 +1068,7 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
if (cfg & BIT(1)) {
used_bits[1] |=
cpu_to_le64(STRTAB_STE_1_S2FWB | STRTAB_STE_1_EATS |
- STRTAB_STE_1_SHCFG);
+ STRTAB_STE_1_SHCFG | STRTAB_STE_1_MEV);
used_bits[2] |=
cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
@@ -1813,8 +1813,8 @@ static void arm_smmu_decode_event(struct arm_smmu_device *smmu, u64 *raw,
mutex_unlock(&smmu->streams_mutex);
}
-static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
- struct arm_smmu_event *event)
+static int arm_smmu_handle_event(struct arm_smmu_device *smmu, u64 *evt,
+ struct arm_smmu_event *event)
{
int ret = 0;
u32 perm = 0;
@@ -1823,6 +1823,10 @@ static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
struct iommu_fault *flt = &fault_evt.fault;
switch (event->id) {
+ case EVT_ID_BAD_STE_CONFIG:
+ case EVT_ID_STREAM_DISABLED_FAULT:
+ case EVT_ID_BAD_SUBSTREAMID_CONFIG:
+ case EVT_ID_BAD_CD_CONFIG:
case EVT_ID_TRANSLATION_FAULT:
case EVT_ID_ADDR_SIZE_FAULT:
case EVT_ID_ACCESS_FAULT:
@@ -1832,31 +1836,30 @@ static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
return -EOPNOTSUPP;
}
- if (!event->stall)
- return -EOPNOTSUPP;
-
- if (event->read)
- perm |= IOMMU_FAULT_PERM_READ;
- else
- perm |= IOMMU_FAULT_PERM_WRITE;
+ if (event->stall) {
+ if (event->read)
+ perm |= IOMMU_FAULT_PERM_READ;
+ else
+ perm |= IOMMU_FAULT_PERM_WRITE;
- if (event->instruction)
- perm |= IOMMU_FAULT_PERM_EXEC;
+ if (event->instruction)
+ perm |= IOMMU_FAULT_PERM_EXEC;
- if (event->privileged)
- perm |= IOMMU_FAULT_PERM_PRIV;
+ if (event->privileged)
+ perm |= IOMMU_FAULT_PERM_PRIV;
- flt->type = IOMMU_FAULT_PAGE_REQ;
- flt->prm = (struct iommu_fault_page_request) {
- .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
- .grpid = event->stag,
- .perm = perm,
- .addr = event->iova,
- };
+ flt->type = IOMMU_FAULT_PAGE_REQ;
+ flt->prm = (struct iommu_fault_page_request){
+ .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
+ .grpid = event->stag,
+ .perm = perm,
+ .addr = event->iova,
+ };
- if (event->ssv) {
- flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
- flt->prm.pasid = event->ssid;
+ if (event->ssv) {
+ flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
+ flt->prm.pasid = event->ssid;
+ }
}
mutex_lock(&smmu->streams_mutex);
@@ -1866,7 +1869,12 @@ static int arm_smmu_handle_event(struct arm_smmu_device *smmu,
goto out_unlock;
}
- ret = iommu_report_device_fault(master->dev, &fault_evt);
+ if (event->stall)
+ ret = iommu_report_device_fault(master->dev, &fault_evt);
+ else if (master->vmaster && !event->s2)
+ ret = arm_vmaster_report_event(master->vmaster, evt);
+ else
+ ret = -EOPNOTSUPP; /* Unhandled events should be pinned */
out_unlock:
mutex_unlock(&smmu->streams_mutex);
return ret;
@@ -1944,7 +1952,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
do {
while (!queue_remove_raw(q, evt)) {
arm_smmu_decode_event(smmu, evt, &event);
- if (arm_smmu_handle_event(smmu, &event))
+ if (arm_smmu_handle_event(smmu, evt, &event))
arm_smmu_dump_event(smmu, evt, &event, &rs);
put_device(event.dev);
@@ -2803,6 +2811,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
struct arm_smmu_domain *smmu_domain =
to_smmu_domain_devices(new_domain);
unsigned long flags;
+ int ret;
/*
* arm_smmu_share_asid() must not see two domains pointing to the same
@@ -2832,9 +2841,18 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
}
if (smmu_domain) {
+ if (new_domain->type == IOMMU_DOMAIN_NESTED) {
+ ret = arm_smmu_attach_prepare_vmaster(
+ state, to_smmu_nested_domain(new_domain));
+ if (ret)
+ return ret;
+ }
+
master_domain = kzalloc(sizeof(*master_domain), GFP_KERNEL);
- if (!master_domain)
+ if (!master_domain) {
+ kfree(state->vmaster);
return -ENOMEM;
+ }
master_domain->master = master;
master_domain->ssid = state->ssid;
if (new_domain->type == IOMMU_DOMAIN_NESTED)
@@ -2861,6 +2879,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
spin_unlock_irqrestore(&smmu_domain->devices_lock,
flags);
kfree(master_domain);
+ kfree(state->vmaster);
return -EINVAL;
}
@@ -2893,6 +2912,8 @@ void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
lockdep_assert_held(&arm_smmu_asid_lock);
+ arm_smmu_attach_commit_vmaster(state);
+
if (state->ats_enabled && !master->ats_enabled) {
arm_smmu_enable_ats(master);
} else if (state->ats_enabled && master->ats_enabled) {
@@ -3162,6 +3183,7 @@ static int arm_smmu_attach_dev_identity(struct iommu_domain *domain,
struct arm_smmu_ste ste;
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ arm_smmu_master_clear_vmaster(master);
arm_smmu_make_bypass_ste(master->smmu, &ste);
arm_smmu_attach_dev_ste(domain, dev, &ste, STRTAB_STE_1_S1DSS_BYPASS);
return 0;
@@ -3180,7 +3202,9 @@ static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain,
struct device *dev)
{
struct arm_smmu_ste ste;
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ arm_smmu_master_clear_vmaster(master);
arm_smmu_make_abort_ste(&ste);
arm_smmu_attach_dev_ste(domain, dev, &ste,
STRTAB_STE_1_S1DSS_TERMINATE);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index bd9d7c85576a..dd1ad56ce863 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -266,6 +266,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
#define STRTAB_STE_1_S1COR GENMASK_ULL(5, 4)
#define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
+#define STRTAB_STE_1_MEV (1UL << 19)
#define STRTAB_STE_1_S2FWB (1UL << 25)
#define STRTAB_STE_1_S1STALLD (1UL << 27)
@@ -799,6 +800,11 @@ struct arm_smmu_stream {
struct rb_node node;
};
+struct arm_smmu_vmaster {
+ struct arm_vsmmu *vsmmu;
+ unsigned long vsid;
+};
+
struct arm_smmu_event {
u8 stall : 1,
ssv : 1,
@@ -824,6 +830,7 @@ struct arm_smmu_master {
struct arm_smmu_device *smmu;
struct device *dev;
struct arm_smmu_stream *streams;
+ struct arm_smmu_vmaster *vmaster; /* use smmu->streams_mutex */
/* Locked by the iommu core using the group mutex */
struct arm_smmu_ctx_desc_cfg cd_table;
unsigned int num_streams;
@@ -972,6 +979,7 @@ struct arm_smmu_attach_state {
bool disable_ats;
ioasid_t ssid;
/* Resulting state */
+ struct arm_smmu_vmaster *vmaster;
bool ats_enabled;
};
@@ -1055,9 +1063,37 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
struct iommu_domain *parent,
struct iommufd_ctx *ictx,
unsigned int viommu_type);
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+ struct arm_smmu_nested_domain *nested_domain);
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
+void arm_smmu_master_clear_vmaster(struct arm_smmu_master *master);
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt);
#else
#define arm_smmu_hw_info NULL
#define arm_vsmmu_alloc NULL
+
+static inline int
+arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+ struct arm_smmu_nested_domain *nested_domain)
+{
+ return 0;
+}
+
+static inline void
+arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+}
+
+static inline void
+arm_smmu_master_clear_vmaster(struct arm_smmu_master *master)
+{
+}
+
+static inline int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster,
+ u64 *evt)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
#endif /* _ARM_SMMU_V3_H */
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 0832998eca38..cb7e29dcac15 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -42,11 +42,6 @@ struct iommu_dma_msi_page {
phys_addr_t phys;
};
-enum iommu_dma_cookie_type {
- IOMMU_DMA_IOVA_COOKIE,
- IOMMU_DMA_MSI_COOKIE,
-};
-
enum iommu_dma_queue_type {
IOMMU_DMA_OPTS_PER_CPU_QUEUE,
IOMMU_DMA_OPTS_SINGLE_QUEUE,
@@ -59,34 +54,30 @@ struct iommu_dma_options {
};
struct iommu_dma_cookie {
- enum iommu_dma_cookie_type type;
+ struct iova_domain iovad;
+ struct list_head msi_page_list;
+ /* Flush queue */
union {
- /* Full allocator for IOMMU_DMA_IOVA_COOKIE */
- struct {
- struct iova_domain iovad;
- /* Flush queue */
- union {
- struct iova_fq *single_fq;
- struct iova_fq __percpu *percpu_fq;
- };
- /* Number of TLB flushes that have been started */
- atomic64_t fq_flush_start_cnt;
- /* Number of TLB flushes that have been finished */
- atomic64_t fq_flush_finish_cnt;
- /* Timer to regularily empty the flush queues */
- struct timer_list fq_timer;
- /* 1 when timer is active, 0 when not */
- atomic_t fq_timer_on;
- };
- /* Trivial linear page allocator for IOMMU_DMA_MSI_COOKIE */
- dma_addr_t msi_iova;
+ struct iova_fq *single_fq;
+ struct iova_fq __percpu *percpu_fq;
};
- struct list_head msi_page_list;
-
+ /* Number of TLB flushes that have been started */
+ atomic64_t fq_flush_start_cnt;
+ /* Number of TLB flushes that have been finished */
+ atomic64_t fq_flush_finish_cnt;
+ /* Timer to regularily empty the flush queues */
+ struct timer_list fq_timer;
+ /* 1 when timer is active, 0 when not */
+ atomic_t fq_timer_on;
/* Domain for flush queue callback; NULL if flush queue not in use */
- struct iommu_domain *fq_domain;
+ struct iommu_domain *fq_domain;
/* Options for dma-iommu use */
- struct iommu_dma_options options;
+ struct iommu_dma_options options;
+};
+
+struct iommu_dma_msi_cookie {
+ dma_addr_t msi_iova;
+ struct list_head msi_page_list;
};
static DEFINE_STATIC_KEY_FALSE(iommu_deferred_attach_enabled);
@@ -102,9 +93,6 @@ static int __init iommu_dma_forcedac_setup(char *str)
}
early_param("iommu.forcedac", iommu_dma_forcedac_setup);
-static int iommu_dma_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
- phys_addr_t msi_addr);
-
/* Number of entries per flush queue */
#define IOVA_DEFAULT_FQ_SIZE 256
#define IOVA_SINGLE_FQ_SIZE 32768
@@ -283,7 +271,7 @@ static void iommu_dma_free_fq(struct iommu_dma_cookie *cookie)
if (!cookie->fq_domain)
return;
- del_timer_sync(&cookie->fq_timer);
+ timer_delete_sync(&cookie->fq_timer);
if (cookie->options.qt == IOMMU_DMA_OPTS_SINGLE_QUEUE)
iommu_dma_free_fq_single(cookie->single_fq);
else
@@ -368,39 +356,24 @@ int iommu_dma_init_fq(struct iommu_domain *domain)
return 0;
}
-static inline size_t cookie_msi_granule(struct iommu_dma_cookie *cookie)
-{
- if (cookie->type == IOMMU_DMA_IOVA_COOKIE)
- return cookie->iovad.granule;
- return PAGE_SIZE;
-}
-
-static struct iommu_dma_cookie *cookie_alloc(enum iommu_dma_cookie_type type)
-{
- struct iommu_dma_cookie *cookie;
-
- cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
- if (cookie) {
- INIT_LIST_HEAD(&cookie->msi_page_list);
- cookie->type = type;
- }
- return cookie;
-}
-
/**
* iommu_get_dma_cookie - Acquire DMA-API resources for a domain
* @domain: IOMMU domain to prepare for DMA-API usage
*/
int iommu_get_dma_cookie(struct iommu_domain *domain)
{
- if (domain->iova_cookie)
+ struct iommu_dma_cookie *cookie;
+
+ if (domain->cookie_type != IOMMU_COOKIE_NONE)
return -EEXIST;
- domain->iova_cookie = cookie_alloc(IOMMU_DMA_IOVA_COOKIE);
- if (!domain->iova_cookie)
+ cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
+ if (!cookie)
return -ENOMEM;
- iommu_domain_set_sw_msi(domain, iommu_dma_sw_msi);
+ INIT_LIST_HEAD(&cookie->msi_page_list);
+ domain->cookie_type = IOMMU_COOKIE_DMA_IOVA;
+ domain->iova_cookie = cookie;
return 0;
}
@@ -418,54 +391,56 @@ int iommu_get_dma_cookie(struct iommu_domain *domain)
*/
int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
{
- struct iommu_dma_cookie *cookie;
+ struct iommu_dma_msi_cookie *cookie;
if (domain->type != IOMMU_DOMAIN_UNMANAGED)
return -EINVAL;
- if (domain->iova_cookie)
+ if (domain->cookie_type != IOMMU_COOKIE_NONE)
return -EEXIST;
- cookie = cookie_alloc(IOMMU_DMA_MSI_COOKIE);
+ cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
if (!cookie)
return -ENOMEM;
cookie->msi_iova = base;
- domain->iova_cookie = cookie;
- iommu_domain_set_sw_msi(domain, iommu_dma_sw_msi);
+ INIT_LIST_HEAD(&cookie->msi_page_list);
+ domain->cookie_type = IOMMU_COOKIE_DMA_MSI;
+ domain->msi_cookie = cookie;
return 0;
}
EXPORT_SYMBOL(iommu_get_msi_cookie);
/**
* iommu_put_dma_cookie - Release a domain's DMA mapping resources
- * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() or
- * iommu_get_msi_cookie()
+ * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
*/
void iommu_put_dma_cookie(struct iommu_domain *domain)
{
struct iommu_dma_cookie *cookie = domain->iova_cookie;
struct iommu_dma_msi_page *msi, *tmp;
-#if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
- if (domain->sw_msi != iommu_dma_sw_msi)
- return;
-#endif
-
- if (!cookie)
- return;
-
- if (cookie->type == IOMMU_DMA_IOVA_COOKIE && cookie->iovad.granule) {
+ if (cookie->iovad.granule) {
iommu_dma_free_fq(cookie);
put_iova_domain(&cookie->iovad);
}
+ list_for_each_entry_safe(msi, tmp, &cookie->msi_page_list, list)
+ kfree(msi);
+ kfree(cookie);
+}
+
+/**
+ * iommu_put_msi_cookie - Release a domain's MSI mapping resources
+ * @domain: IOMMU domain previously prepared by iommu_get_msi_cookie()
+ */
+void iommu_put_msi_cookie(struct iommu_domain *domain)
+{
+ struct iommu_dma_msi_cookie *cookie = domain->msi_cookie;
+ struct iommu_dma_msi_page *msi, *tmp;
- list_for_each_entry_safe(msi, tmp, &cookie->msi_page_list, list) {
- list_del(&msi->list);
+ list_for_each_entry_safe(msi, tmp, &cookie->msi_page_list, list)
kfree(msi);
- }
kfree(cookie);
- domain->iova_cookie = NULL;
}
/**
@@ -685,7 +660,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, struct device *dev
struct iova_domain *iovad;
int ret;
- if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE)
+ if (!cookie || domain->cookie_type != IOMMU_COOKIE_DMA_IOVA)
return -EINVAL;
iovad = &cookie->iovad;
@@ -768,9 +743,9 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain,
struct iova_domain *iovad = &cookie->iovad;
unsigned long shift, iova_len, iova;
- if (cookie->type == IOMMU_DMA_MSI_COOKIE) {
- cookie->msi_iova += size;
- return cookie->msi_iova - size;
+ if (domain->cookie_type == IOMMU_COOKIE_DMA_MSI) {
+ domain->msi_cookie->msi_iova += size;
+ return domain->msi_cookie->msi_iova - size;
}
shift = iova_shift(iovad);
@@ -807,16 +782,16 @@ done:
return (dma_addr_t)iova << shift;
}
-static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie,
- dma_addr_t iova, size_t size, struct iommu_iotlb_gather *gather)
+static void iommu_dma_free_iova(struct iommu_domain *domain, dma_addr_t iova,
+ size_t size, struct iommu_iotlb_gather *gather)
{
- struct iova_domain *iovad = &cookie->iovad;
+ struct iova_domain *iovad = &domain->iova_cookie->iovad;
/* The MSI case is only ever cleaning up its most recent allocation */
- if (cookie->type == IOMMU_DMA_MSI_COOKIE)
- cookie->msi_iova -= size;
+ if (domain->cookie_type == IOMMU_COOKIE_DMA_MSI)
+ domain->msi_cookie->msi_iova -= size;
else if (gather && gather->queued)
- queue_iova(cookie, iova_pfn(iovad, iova),
+ queue_iova(domain->iova_cookie, iova_pfn(iovad, iova),
size >> iova_shift(iovad),
&gather->freelist);
else
@@ -844,7 +819,7 @@ static void __iommu_dma_unmap(struct device *dev, dma_addr_t dma_addr,
if (!iotlb_gather.queued)
iommu_iotlb_sync(domain, &iotlb_gather);
- iommu_dma_free_iova(cookie, dma_addr, size, &iotlb_gather);
+ iommu_dma_free_iova(domain, dma_addr, size, &iotlb_gather);
}
static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,
@@ -872,7 +847,7 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,
return DMA_MAPPING_ERROR;
if (iommu_map(domain, iova, phys - iova_off, size, prot, GFP_ATOMIC)) {
- iommu_dma_free_iova(cookie, iova, size, NULL);
+ iommu_dma_free_iova(domain, iova, size, NULL);
return DMA_MAPPING_ERROR;
}
return iova + iova_off;
@@ -1009,7 +984,7 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev,
out_free_sg:
sg_free_table(sgt);
out_free_iova:
- iommu_dma_free_iova(cookie, iova, size, NULL);
+ iommu_dma_free_iova(domain, iova, size, NULL);
out_free_pages:
__iommu_dma_free_pages(pages, count);
return NULL;
@@ -1486,7 +1461,7 @@ int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
return __finalise_sg(dev, sg, nents, iova);
out_free_iova:
- iommu_dma_free_iova(cookie, iova, iova_len, NULL);
+ iommu_dma_free_iova(domain, iova, iova_len, NULL);
out_restore_sg:
__invalidate_sg(sg, nents);
out:
@@ -1764,17 +1739,47 @@ out_err:
dev->dma_iommu = false;
}
+static bool has_msi_cookie(const struct iommu_domain *domain)
+{
+ return domain && (domain->cookie_type == IOMMU_COOKIE_DMA_IOVA ||
+ domain->cookie_type == IOMMU_COOKIE_DMA_MSI);
+}
+
+static size_t cookie_msi_granule(const struct iommu_domain *domain)
+{
+ switch (domain->cookie_type) {
+ case IOMMU_COOKIE_DMA_IOVA:
+ return domain->iova_cookie->iovad.granule;
+ case IOMMU_COOKIE_DMA_MSI:
+ return PAGE_SIZE;
+ default:
+ BUG();
+ };
+}
+
+static struct list_head *cookie_msi_pages(const struct iommu_domain *domain)
+{
+ switch (domain->cookie_type) {
+ case IOMMU_COOKIE_DMA_IOVA:
+ return &domain->iova_cookie->msi_page_list;
+ case IOMMU_COOKIE_DMA_MSI:
+ return &domain->msi_cookie->msi_page_list;
+ default:
+ BUG();
+ };
+}
+
static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
phys_addr_t msi_addr, struct iommu_domain *domain)
{
- struct iommu_dma_cookie *cookie = domain->iova_cookie;
+ struct list_head *msi_page_list = cookie_msi_pages(domain);
struct iommu_dma_msi_page *msi_page;
dma_addr_t iova;
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
- size_t size = cookie_msi_granule(cookie);
+ size_t size = cookie_msi_granule(domain);
msi_addr &= ~(phys_addr_t)(size - 1);
- list_for_each_entry(msi_page, &cookie->msi_page_list, list)
+ list_for_each_entry(msi_page, msi_page_list, list)
if (msi_page->phys == msi_addr)
return msi_page;
@@ -1792,23 +1797,23 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
INIT_LIST_HEAD(&msi_page->list);
msi_page->phys = msi_addr;
msi_page->iova = iova;
- list_add(&msi_page->list, &cookie->msi_page_list);
+ list_add(&msi_page->list, msi_page_list);
return msi_page;
out_free_iova:
- iommu_dma_free_iova(cookie, iova, size, NULL);
+ iommu_dma_free_iova(domain, iova, size, NULL);
out_free_page:
kfree(msi_page);
return NULL;
}
-static int iommu_dma_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
- phys_addr_t msi_addr)
+int iommu_dma_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
+ phys_addr_t msi_addr)
{
struct device *dev = msi_desc_to_dev(desc);
const struct iommu_dma_msi_page *msi_page;
- if (!domain->iova_cookie) {
+ if (!has_msi_cookie(domain)) {
msi_desc_set_iommu_msi_iova(desc, 0, 0);
return 0;
}
@@ -1818,9 +1823,8 @@ static int iommu_dma_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
if (!msi_page)
return -ENOMEM;
- msi_desc_set_iommu_msi_iova(
- desc, msi_page->iova,
- ilog2(cookie_msi_granule(domain->iova_cookie)));
+ msi_desc_set_iommu_msi_iova(desc, msi_page->iova,
+ ilog2(cookie_msi_granule(domain)));
return 0;
}
diff --git a/drivers/iommu/dma-iommu.h b/drivers/iommu/dma-iommu.h
index c12d63457c76..eca201c1f963 100644
--- a/drivers/iommu/dma-iommu.h
+++ b/drivers/iommu/dma-iommu.h
@@ -13,11 +13,15 @@ void iommu_setup_dma_ops(struct device *dev);
int iommu_get_dma_cookie(struct iommu_domain *domain);
void iommu_put_dma_cookie(struct iommu_domain *domain);
+void iommu_put_msi_cookie(struct iommu_domain *domain);
int iommu_dma_init_fq(struct iommu_domain *domain);
void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
+int iommu_dma_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
+ phys_addr_t msi_addr);
+
extern bool iommu_dma_forcedac;
#else /* CONFIG_IOMMU_DMA */
@@ -40,9 +44,19 @@ static inline void iommu_put_dma_cookie(struct iommu_domain *domain)
{
}
+static inline void iommu_put_msi_cookie(struct iommu_domain *domain)
+{
+}
+
static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
{
}
+static inline int iommu_dma_sw_msi(struct iommu_domain *domain,
+ struct msi_desc *desc, phys_addr_t msi_addr)
+{
+ return -ENODEV;
+}
+
#endif /* CONFIG_IOMMU_DMA */
#endif /* __DMA_IOMMU_H */
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ec2f385ae25b..6e67cc66a204 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -3383,7 +3383,8 @@ intel_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags,
bool first_stage;
if (flags &
- (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
+ (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
+ IOMMU_HWPT_ALLOC_PASID)))
return ERR_PTR(-EOPNOTSUPP);
if (nested_parent && !nested_supported(iommu))
return ERR_PTR(-EOPNOTSUPP);
diff --git a/drivers/iommu/intel/nested.c b/drivers/iommu/intel/nested.c
index aba92c00b427..6ac5c534bef4 100644
--- a/drivers/iommu/intel/nested.c
+++ b/drivers/iommu/intel/nested.c
@@ -198,7 +198,7 @@ intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
struct dmar_domain *domain;
int ret;
- if (!nested_supported(iommu) || flags)
+ if (!nested_supported(iommu) || flags & ~IOMMU_HWPT_ALLOC_PASID)
return ERR_PTR(-EOPNOTSUPP);
/* Must be nested domain */
diff --git a/drivers/iommu/iommu-priv.h b/drivers/iommu/iommu-priv.h
index 05fa6e682e88..e236b932e766 100644
--- a/drivers/iommu/iommu-priv.h
+++ b/drivers/iommu/iommu-priv.h
@@ -5,6 +5,7 @@
#define __LINUX_IOMMU_PRIV_H
#include <linux/iommu.h>
+#include <linux/msi.h>
static inline const struct iommu_ops *dev_iommu_ops(struct device *dev)
{
@@ -47,4 +48,19 @@ void iommu_detach_group_handle(struct iommu_domain *domain,
int iommu_replace_group_handle(struct iommu_group *group,
struct iommu_domain *new_domain,
struct iommu_attach_handle *handle);
+
+#if IS_ENABLED(CONFIG_IOMMUFD_DRIVER_CORE) && IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
+int iommufd_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
+ phys_addr_t msi_addr);
+#else /* !CONFIG_IOMMUFD_DRIVER_CORE || !CONFIG_IRQ_MSI_IOMMU */
+static inline int iommufd_sw_msi(struct iommu_domain *domain,
+ struct msi_desc *desc, phys_addr_t msi_addr)
+{
+ return -EOPNOTSUPP;
+}
+#endif /* CONFIG_IOMMUFD_DRIVER_CORE && CONFIG_IRQ_MSI_IOMMU */
+
+int iommu_replace_device_pasid(struct iommu_domain *domain,
+ struct device *dev, ioasid_t pasid,
+ struct iommu_attach_handle *handle);
#endif /* __LINUX_IOMMU_PRIV_H */
diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index 503c5d23c1ea..ab18bc494eef 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -310,6 +310,7 @@ static struct iommu_domain *iommu_sva_domain_alloc(struct device *dev,
}
domain->type = IOMMU_DOMAIN_SVA;
+ domain->cookie_type = IOMMU_COOKIE_SVA;
mmgrab(mm);
domain->mm = mm;
domain->owner = ops;
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9e1b444246f8..c8033ca66377 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/host1x_context_bus.h>
#include <linux/iommu.h>
+#include <linux/iommufd.h>
#include <linux/idr.h>
#include <linux/err.h>
#include <linux/pci.h>
@@ -539,6 +540,13 @@ static void iommu_deinit_device(struct device *dev)
dev_iommu_free(dev);
}
+static struct iommu_domain *pasid_array_entry_to_domain(void *entry)
+{
+ if (xa_pointer_tag(entry) == IOMMU_PASID_ARRAY_DOMAIN)
+ return xa_untag_pointer(entry);
+ return ((struct iommu_attach_handle *)xa_untag_pointer(entry))->domain;
+}
+
DEFINE_MUTEX(iommu_probe_device_lock);
static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
@@ -1973,8 +1981,10 @@ void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler,
void *token)
{
- BUG_ON(!domain);
+ if (WARN_ON(!domain || domain->cookie_type != IOMMU_COOKIE_NONE))
+ return;
+ domain->cookie_type = IOMMU_COOKIE_FAULT_HANDLER;
domain->handler = handler;
domain->handler_token = token;
}
@@ -2044,9 +2054,19 @@ EXPORT_SYMBOL_GPL(iommu_paging_domain_alloc_flags);
void iommu_domain_free(struct iommu_domain *domain)
{
- if (domain->type == IOMMU_DOMAIN_SVA)
+ switch (domain->cookie_type) {
+ case IOMMU_COOKIE_DMA_IOVA:
+ iommu_put_dma_cookie(domain);
+ break;
+ case IOMMU_COOKIE_DMA_MSI:
+ iommu_put_msi_cookie(domain);
+ break;
+ case IOMMU_COOKIE_SVA:
mmdrop(domain->mm);
- iommu_put_dma_cookie(domain);
+ break;
+ default:
+ break;
+ }
if (domain->ops->free)
domain->ops->free(domain);
}
@@ -3335,14 +3355,15 @@ static void iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
}
static int __iommu_set_group_pasid(struct iommu_domain *domain,
- struct iommu_group *group, ioasid_t pasid)
+ struct iommu_group *group, ioasid_t pasid,
+ struct iommu_domain *old)
{
struct group_device *device, *last_gdev;
int ret;
for_each_group_device(group, device) {
ret = domain->ops->set_dev_pasid(domain, device->dev,
- pasid, NULL);
+ pasid, old);
if (ret)
goto err_revert;
}
@@ -3354,7 +3375,15 @@ err_revert:
for_each_group_device(group, device) {
if (device == last_gdev)
break;
- iommu_remove_dev_pasid(device->dev, pasid, domain);
+ /*
+ * If no old domain, undo the succeeded devices/pasid.
+ * Otherwise, rollback the succeeded devices/pasid to the old
+ * domain. And it is a driver bug to fail attaching with a
+ * previously good domain.
+ */
+ if (!old || WARN_ON(old->ops->set_dev_pasid(old, device->dev,
+ pasid, domain)))
+ iommu_remove_dev_pasid(device->dev, pasid, domain);
}
return ret;
}
@@ -3376,6 +3405,9 @@ static void __iommu_remove_group_pasid(struct iommu_group *group,
* @pasid: the pasid of the device.
* @handle: the attach handle.
*
+ * Caller should always provide a new handle to avoid race with the paths
+ * that have lockless reference to handle if it intends to pass a valid handle.
+ *
* Return: 0 on success, or an error.
*/
int iommu_attach_device_pasid(struct iommu_domain *domain,
@@ -3420,7 +3452,7 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
if (ret)
goto out_unlock;
- ret = __iommu_set_group_pasid(domain, group, pasid);
+ ret = __iommu_set_group_pasid(domain, group, pasid, NULL);
if (ret) {
xa_release(&group->pasid_array, pasid);
goto out_unlock;
@@ -3441,6 +3473,97 @@ out_unlock:
}
EXPORT_SYMBOL_GPL(iommu_attach_device_pasid);
+/**
+ * iommu_replace_device_pasid - Replace the domain that a specific pasid
+ * of the device is attached to
+ * @domain: the new iommu domain
+ * @dev: the attached device.
+ * @pasid: the pasid of the device.
+ * @handle: the attach handle.
+ *
+ * This API allows the pasid to switch domains. The @pasid should have been
+ * attached. Otherwise, this fails. The pasid will keep the old configuration
+ * if replacement failed.
+ *
+ * Caller should always provide a new handle to avoid race with the paths
+ * that have lockless reference to handle if it intends to pass a valid handle.
+ *
+ * Return 0 on success, or an error.
+ */
+int iommu_replace_device_pasid(struct iommu_domain *domain,
+ struct device *dev, ioasid_t pasid,
+ struct iommu_attach_handle *handle)
+{
+ /* Caller must be a probed driver on dev */
+ struct iommu_group *group = dev->iommu_group;
+ struct iommu_attach_handle *entry;
+ struct iommu_domain *curr_domain;
+ void *curr;
+ int ret;
+
+ if (!group)
+ return -ENODEV;
+
+ if (!domain->ops->set_dev_pasid)
+ return -EOPNOTSUPP;
+
+ if (dev_iommu_ops(dev) != domain->owner ||
+ pasid == IOMMU_NO_PASID || !handle)
+ return -EINVAL;
+
+ mutex_lock(&group->mutex);
+ entry = iommu_make_pasid_array_entry(domain, handle);
+ curr = xa_cmpxchg(&group->pasid_array, pasid, NULL,
+ XA_ZERO_ENTRY, GFP_KERNEL);
+ if (xa_is_err(curr)) {
+ ret = xa_err(curr);
+ goto out_unlock;
+ }
+
+ /*
+ * No domain (with or without handle) attached, hence not
+ * a replace case.
+ */
+ if (!curr) {
+ xa_release(&group->pasid_array, pasid);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ /*
+ * Reusing handle is problematic as there are paths that refers
+ * the handle without lock. To avoid race, reject the callers that
+ * attempt it.
+ */
+ if (curr == entry) {
+ WARN_ON(1);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ curr_domain = pasid_array_entry_to_domain(curr);
+ ret = 0;
+
+ if (curr_domain != domain) {
+ ret = __iommu_set_group_pasid(domain, group,
+ pasid, curr_domain);
+ if (ret)
+ goto out_unlock;
+ }
+
+ /*
+ * The above xa_cmpxchg() reserved the memory, and the
+ * group->mutex is held, this cannot fail.
+ */
+ WARN_ON(xa_is_err(xa_store(&group->pasid_array,
+ pasid, entry, GFP_KERNEL)));
+
+out_unlock:
+ mutex_unlock(&group->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_NS_GPL(iommu_replace_device_pasid, "IOMMUFD_INTERNAL");
+
/*
* iommu_detach_device_pasid() - Detach the domain from pasid of device
* @domain: the iommu domain.
@@ -3536,6 +3659,9 @@ EXPORT_SYMBOL_NS_GPL(iommu_attach_handle_get, "IOMMUFD_INTERNAL");
* This is a variant of iommu_attach_group(). It allows the caller to provide
* an attach handle and use it when the domain is attached. This is currently
* used by IOMMUFD to deliver the I/O page faults.
+ *
+ * Caller should always provide a new handle to avoid race with the paths
+ * that have lockless reference to handle.
*/
int iommu_attach_group_handle(struct iommu_domain *domain,
struct iommu_group *group,
@@ -3605,6 +3731,9 @@ EXPORT_SYMBOL_NS_GPL(iommu_detach_group_handle, "IOMMUFD_INTERNAL");
*
* If the currently attached domain is a core domain (e.g. a default_domain),
* it will act just like the iommu_attach_group_handle().
+ *
+ * Caller should always provide a new handle to avoid race with the paths
+ * that have lockless reference to handle.
*/
int iommu_replace_group_handle(struct iommu_group *group,
struct iommu_domain *new_domain,
@@ -3662,8 +3791,21 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr)
return 0;
mutex_lock(&group->mutex);
- if (group->domain && group->domain->sw_msi)
- ret = group->domain->sw_msi(group->domain, desc, msi_addr);
+ /* An IDENTITY domain must pass through */
+ if (group->domain && group->domain->type != IOMMU_DOMAIN_IDENTITY) {
+ switch (group->domain->cookie_type) {
+ case IOMMU_COOKIE_DMA_MSI:
+ case IOMMU_COOKIE_DMA_IOVA:
+ ret = iommu_dma_sw_msi(group->domain, desc, msi_addr);
+ break;
+ case IOMMU_COOKIE_IOMMUFD:
+ ret = iommufd_sw_msi(group->domain, desc, msi_addr);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ }
mutex_unlock(&group->mutex);
return ret;
}
diff --git a/drivers/iommu/iommufd/Kconfig b/drivers/iommu/iommufd/Kconfig
index 0a07f9449fd9..2beeb4f60ee5 100644
--- a/drivers/iommu/iommufd/Kconfig
+++ b/drivers/iommu/iommufd/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config IOMMUFD_DRIVER_CORE
- tristate
+ bool
default (IOMMUFD_DRIVER || IOMMUFD) if IOMMUFD!=n
config IOMMUFD
diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile
index cb784da6cddc..71d692c9a8f4 100644
--- a/drivers/iommu/iommufd/Makefile
+++ b/drivers/iommu/iommufd/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
iommufd-y := \
device.o \
- fault.o \
+ eventq.o \
hw_pagetable.o \
io_pagetable.o \
ioas.o \
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 4e107f69f951..2111bad72c72 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -3,9 +3,9 @@
*/
#include <linux/iommu.h>
#include <linux/iommufd.h>
+#include <linux/pci-ats.h>
#include <linux/slab.h>
#include <uapi/linux/iommufd.h>
-#include <linux/msi.h>
#include "../iommu-priv.h"
#include "io_pagetable.h"
@@ -18,12 +18,17 @@ MODULE_PARM_DESC(
"Allow IOMMUFD to bind to devices even if the platform cannot isolate "
"the MSI interrupt window. Enabling this is a security weakness.");
+struct iommufd_attach {
+ struct iommufd_hw_pagetable *hwpt;
+ struct xarray device_array;
+};
+
static void iommufd_group_release(struct kref *kref)
{
struct iommufd_group *igroup =
container_of(kref, struct iommufd_group, ref);
- WARN_ON(igroup->hwpt || !list_empty(&igroup->device_list));
+ WARN_ON(!xa_empty(&igroup->pasid_attach));
xa_cmpxchg(&igroup->ictx->groups, iommu_group_id(igroup->group), igroup,
NULL, GFP_KERNEL);
@@ -90,7 +95,7 @@ static struct iommufd_group *iommufd_get_group(struct iommufd_ctx *ictx,
kref_init(&new_igroup->ref);
mutex_init(&new_igroup->lock);
- INIT_LIST_HEAD(&new_igroup->device_list);
+ xa_init(&new_igroup->pasid_attach);
new_igroup->sw_msi_start = PHYS_ADDR_MAX;
/* group reference moves into new_igroup */
new_igroup->group = group;
@@ -294,129 +299,24 @@ u32 iommufd_device_to_id(struct iommufd_device *idev)
}
EXPORT_SYMBOL_NS_GPL(iommufd_device_to_id, "IOMMUFD");
-/*
- * Get a iommufd_sw_msi_map for the msi physical address requested by the irq
- * layer. The mapping to IOVA is global to the iommufd file descriptor, every
- * domain that is attached to a device using the same MSI parameters will use
- * the same IOVA.
- */
-static __maybe_unused struct iommufd_sw_msi_map *
-iommufd_sw_msi_get_map(struct iommufd_ctx *ictx, phys_addr_t msi_addr,
- phys_addr_t sw_msi_start)
-{
- struct iommufd_sw_msi_map *cur;
- unsigned int max_pgoff = 0;
-
- lockdep_assert_held(&ictx->sw_msi_lock);
-
- list_for_each_entry(cur, &ictx->sw_msi_list, sw_msi_item) {
- if (cur->sw_msi_start != sw_msi_start)
- continue;
- max_pgoff = max(max_pgoff, cur->pgoff + 1);
- if (cur->msi_addr == msi_addr)
- return cur;
- }
-
- if (ictx->sw_msi_id >=
- BITS_PER_BYTE * sizeof_field(struct iommufd_sw_msi_maps, bitmap))
- return ERR_PTR(-EOVERFLOW);
-
- cur = kzalloc(sizeof(*cur), GFP_KERNEL);
- if (!cur)
- return ERR_PTR(-ENOMEM);
-
- cur->sw_msi_start = sw_msi_start;
- cur->msi_addr = msi_addr;
- cur->pgoff = max_pgoff;
- cur->id = ictx->sw_msi_id++;
- list_add_tail(&cur->sw_msi_item, &ictx->sw_msi_list);
- return cur;
-}
-
-static int iommufd_sw_msi_install(struct iommufd_ctx *ictx,
- struct iommufd_hwpt_paging *hwpt_paging,
- struct iommufd_sw_msi_map *msi_map)
+static unsigned int iommufd_group_device_num(struct iommufd_group *igroup,
+ ioasid_t pasid)
{
- unsigned long iova;
-
- lockdep_assert_held(&ictx->sw_msi_lock);
+ struct iommufd_attach *attach;
+ struct iommufd_device *idev;
+ unsigned int count = 0;
+ unsigned long index;
- iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE;
- if (!test_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap)) {
- int rc;
+ lockdep_assert_held(&igroup->lock);
- rc = iommu_map(hwpt_paging->common.domain, iova,
- msi_map->msi_addr, PAGE_SIZE,
- IOMMU_WRITE | IOMMU_READ | IOMMU_MMIO,
- GFP_KERNEL_ACCOUNT);
- if (rc)
- return rc;
- __set_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap);
- }
- return 0;
+ attach = xa_load(&igroup->pasid_attach, pasid);
+ if (attach)
+ xa_for_each(&attach->device_array, index, idev)
+ count++;
+ return count;
}
-/*
- * Called by the irq code if the platform translates the MSI address through the
- * IOMMU. msi_addr is the physical address of the MSI page. iommufd will
- * allocate a fd global iova for the physical page that is the same on all
- * domains and devices.
- */
#ifdef CONFIG_IRQ_MSI_IOMMU
-int iommufd_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
- phys_addr_t msi_addr)
-{
- struct device *dev = msi_desc_to_dev(desc);
- struct iommufd_hwpt_paging *hwpt_paging;
- struct iommu_attach_handle *raw_handle;
- struct iommufd_attach_handle *handle;
- struct iommufd_sw_msi_map *msi_map;
- struct iommufd_ctx *ictx;
- unsigned long iova;
- int rc;
-
- /*
- * It is safe to call iommu_attach_handle_get() here because the iommu
- * core code invokes this under the group mutex which also prevents any
- * change of the attach handle for the duration of this function.
- */
- iommu_group_mutex_assert(dev);
-
- raw_handle =
- iommu_attach_handle_get(dev->iommu_group, IOMMU_NO_PASID, 0);
- if (IS_ERR(raw_handle))
- return 0;
- hwpt_paging = find_hwpt_paging(domain->iommufd_hwpt);
-
- handle = to_iommufd_handle(raw_handle);
- /* No IOMMU_RESV_SW_MSI means no change to the msi_msg */
- if (handle->idev->igroup->sw_msi_start == PHYS_ADDR_MAX)
- return 0;
-
- ictx = handle->idev->ictx;
- guard(mutex)(&ictx->sw_msi_lock);
- /*
- * The input msi_addr is the exact byte offset of the MSI doorbell, we
- * assume the caller has checked that it is contained with a MMIO region
- * that is secure to map at PAGE_SIZE.
- */
- msi_map = iommufd_sw_msi_get_map(handle->idev->ictx,
- msi_addr & PAGE_MASK,
- handle->idev->igroup->sw_msi_start);
- if (IS_ERR(msi_map))
- return PTR_ERR(msi_map);
-
- rc = iommufd_sw_msi_install(ictx, hwpt_paging, msi_map);
- if (rc)
- return rc;
- __set_bit(msi_map->id, handle->idev->igroup->required_sw_msi.bitmap);
-
- iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE;
- msi_desc_set_iommu_msi_iova(desc, iova, PAGE_SHIFT);
- return 0;
-}
-#endif
-
static int iommufd_group_setup_msi(struct iommufd_group *igroup,
struct iommufd_hwpt_paging *hwpt_paging)
{
@@ -443,23 +343,39 @@ static int iommufd_group_setup_msi(struct iommufd_group *igroup,
}
return 0;
}
+#else
+static inline int
+iommufd_group_setup_msi(struct iommufd_group *igroup,
+ struct iommufd_hwpt_paging *hwpt_paging)
+{
+ return 0;
+}
+#endif
+
+static bool
+iommufd_group_first_attach(struct iommufd_group *igroup, ioasid_t pasid)
+{
+ lockdep_assert_held(&igroup->lock);
+ return !xa_load(&igroup->pasid_attach, pasid);
+}
static int
iommufd_device_attach_reserved_iova(struct iommufd_device *idev,
struct iommufd_hwpt_paging *hwpt_paging)
{
+ struct iommufd_group *igroup = idev->igroup;
int rc;
- lockdep_assert_held(&idev->igroup->lock);
+ lockdep_assert_held(&igroup->lock);
rc = iopt_table_enforce_dev_resv_regions(&hwpt_paging->ioas->iopt,
idev->dev,
- &idev->igroup->sw_msi_start);
+ &igroup->sw_msi_start);
if (rc)
return rc;
- if (list_empty(&idev->igroup->device_list)) {
- rc = iommufd_group_setup_msi(idev->igroup, hwpt_paging);
+ if (iommufd_group_first_attach(igroup, IOMMU_NO_PASID)) {
+ rc = iommufd_group_setup_msi(igroup, hwpt_paging);
if (rc) {
iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt,
idev->dev);
@@ -471,13 +387,54 @@ iommufd_device_attach_reserved_iova(struct iommufd_device *idev,
/* The device attach/detach/replace helpers for attach_handle */
+static bool iommufd_device_is_attached(struct iommufd_device *idev,
+ ioasid_t pasid)
+{
+ struct iommufd_attach *attach;
+
+ attach = xa_load(&idev->igroup->pasid_attach, pasid);
+ return xa_load(&attach->device_array, idev->obj.id);
+}
+
+static int iommufd_hwpt_pasid_compat(struct iommufd_hw_pagetable *hwpt,
+ struct iommufd_device *idev,
+ ioasid_t pasid)
+{
+ struct iommufd_group *igroup = idev->igroup;
+
+ lockdep_assert_held(&igroup->lock);
+
+ if (pasid == IOMMU_NO_PASID) {
+ unsigned long start = IOMMU_NO_PASID;
+
+ if (!hwpt->pasid_compat &&
+ xa_find_after(&igroup->pasid_attach,
+ &start, UINT_MAX, XA_PRESENT))
+ return -EINVAL;
+ } else {
+ struct iommufd_attach *attach;
+
+ if (!hwpt->pasid_compat)
+ return -EINVAL;
+
+ attach = xa_load(&igroup->pasid_attach, IOMMU_NO_PASID);
+ if (attach && attach->hwpt && !attach->hwpt->pasid_compat)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
- struct iommufd_device *idev)
+ struct iommufd_device *idev,
+ ioasid_t pasid)
{
struct iommufd_attach_handle *handle;
int rc;
- lockdep_assert_held(&idev->igroup->lock);
+ rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
+ if (rc)
+ return rc;
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
if (!handle)
@@ -490,8 +447,12 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
}
handle->idev = idev;
- rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
- &handle->handle);
+ if (pasid == IOMMU_NO_PASID)
+ rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
+ &handle->handle);
+ else
+ rc = iommu_attach_device_pasid(hwpt->domain, idev->dev, pasid,
+ &handle->handle);
if (rc)
goto out_disable_iopf;
@@ -506,26 +467,31 @@ out_free_handle:
}
static struct iommufd_attach_handle *
-iommufd_device_get_attach_handle(struct iommufd_device *idev)
+iommufd_device_get_attach_handle(struct iommufd_device *idev, ioasid_t pasid)
{
struct iommu_attach_handle *handle;
lockdep_assert_held(&idev->igroup->lock);
handle =
- iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0);
+ iommu_attach_handle_get(idev->igroup->group, pasid, 0);
if (IS_ERR(handle))
return NULL;
return to_iommufd_handle(handle);
}
static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
- struct iommufd_device *idev)
+ struct iommufd_device *idev,
+ ioasid_t pasid)
{
struct iommufd_attach_handle *handle;
- handle = iommufd_device_get_attach_handle(idev);
- iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
+ handle = iommufd_device_get_attach_handle(idev, pasid);
+ if (pasid == IOMMU_NO_PASID)
+ iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
+ else
+ iommu_detach_device_pasid(hwpt->domain, idev->dev, pasid);
+
if (hwpt->fault) {
iommufd_auto_response_faults(hwpt, handle);
iommufd_fault_iopf_disable(idev);
@@ -534,13 +500,19 @@ static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
}
static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
+ ioasid_t pasid,
struct iommufd_hw_pagetable *hwpt,
struct iommufd_hw_pagetable *old)
{
- struct iommufd_attach_handle *handle, *old_handle =
- iommufd_device_get_attach_handle(idev);
+ struct iommufd_attach_handle *handle, *old_handle;
int rc;
+ rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
+ if (rc)
+ return rc;
+
+ old_handle = iommufd_device_get_attach_handle(idev, pasid);
+
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;
@@ -552,8 +524,12 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
}
handle->idev = idev;
- rc = iommu_replace_group_handle(idev->igroup->group, hwpt->domain,
- &handle->handle);
+ if (pasid == IOMMU_NO_PASID)
+ rc = iommu_replace_group_handle(idev->igroup->group,
+ hwpt->domain, &handle->handle);
+ else
+ rc = iommu_replace_device_pasid(hwpt->domain, idev->dev,
+ pasid, &handle->handle);
if (rc)
goto out_disable_iopf;
@@ -575,22 +551,51 @@ out_free_handle:
}
int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
- struct iommufd_device *idev)
+ struct iommufd_device *idev, ioasid_t pasid)
{
struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
+ bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID;
+ struct iommufd_group *igroup = idev->igroup;
+ struct iommufd_hw_pagetable *old_hwpt;
+ struct iommufd_attach *attach;
int rc;
- mutex_lock(&idev->igroup->lock);
+ mutex_lock(&igroup->lock);
- if (idev->igroup->hwpt != NULL && idev->igroup->hwpt != hwpt) {
- rc = -EINVAL;
+ attach = xa_cmpxchg(&igroup->pasid_attach, pasid, NULL,
+ XA_ZERO_ENTRY, GFP_KERNEL);
+ if (xa_is_err(attach)) {
+ rc = xa_err(attach);
goto err_unlock;
}
- if (hwpt_paging) {
+ if (!attach) {
+ attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+ if (!attach) {
+ rc = -ENOMEM;
+ goto err_release_pasid;
+ }
+ xa_init(&attach->device_array);
+ }
+
+ old_hwpt = attach->hwpt;
+
+ rc = xa_insert(&attach->device_array, idev->obj.id, XA_ZERO_ENTRY,
+ GFP_KERNEL);
+ if (rc) {
+ WARN_ON(rc == -EBUSY && !old_hwpt);
+ goto err_free_attach;
+ }
+
+ if (old_hwpt && old_hwpt != hwpt) {
+ rc = -EINVAL;
+ goto err_release_devid;
+ }
+
+ if (attach_resv) {
rc = iommufd_device_attach_reserved_iova(idev, hwpt_paging);
if (rc)
- goto err_unlock;
+ goto err_release_devid;
}
/*
@@ -600,51 +605,74 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
* reserved regions are only updated during individual device
* attachment.
*/
- if (list_empty(&idev->igroup->device_list)) {
- rc = iommufd_hwpt_attach_device(hwpt, idev);
+ if (iommufd_group_first_attach(igroup, pasid)) {
+ rc = iommufd_hwpt_attach_device(hwpt, idev, pasid);
if (rc)
goto err_unresv;
- idev->igroup->hwpt = hwpt;
+ attach->hwpt = hwpt;
+ WARN_ON(xa_is_err(xa_store(&igroup->pasid_attach, pasid, attach,
+ GFP_KERNEL)));
}
refcount_inc(&hwpt->obj.users);
- list_add_tail(&idev->group_item, &idev->igroup->device_list);
- mutex_unlock(&idev->igroup->lock);
+ WARN_ON(xa_is_err(xa_store(&attach->device_array, idev->obj.id,
+ idev, GFP_KERNEL)));
+ mutex_unlock(&igroup->lock);
return 0;
err_unresv:
- if (hwpt_paging)
+ if (attach_resv)
iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, idev->dev);
+err_release_devid:
+ xa_release(&attach->device_array, idev->obj.id);
+err_free_attach:
+ if (iommufd_group_first_attach(igroup, pasid))
+ kfree(attach);
+err_release_pasid:
+ if (iommufd_group_first_attach(igroup, pasid))
+ xa_release(&igroup->pasid_attach, pasid);
err_unlock:
- mutex_unlock(&idev->igroup->lock);
+ mutex_unlock(&igroup->lock);
return rc;
}
struct iommufd_hw_pagetable *
-iommufd_hw_pagetable_detach(struct iommufd_device *idev)
+iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid)
{
- struct iommufd_hw_pagetable *hwpt = idev->igroup->hwpt;
- struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
+ struct iommufd_group *igroup = idev->igroup;
+ struct iommufd_hwpt_paging *hwpt_paging;
+ struct iommufd_hw_pagetable *hwpt;
+ struct iommufd_attach *attach;
+
+ mutex_lock(&igroup->lock);
+ attach = xa_load(&igroup->pasid_attach, pasid);
+ if (!attach) {
+ mutex_unlock(&igroup->lock);
+ return NULL;
+ }
- mutex_lock(&idev->igroup->lock);
- list_del(&idev->group_item);
- if (list_empty(&idev->igroup->device_list)) {
- iommufd_hwpt_detach_device(hwpt, idev);
- idev->igroup->hwpt = NULL;
+ hwpt = attach->hwpt;
+ hwpt_paging = find_hwpt_paging(hwpt);
+
+ xa_erase(&attach->device_array, idev->obj.id);
+ if (xa_empty(&attach->device_array)) {
+ iommufd_hwpt_detach_device(hwpt, idev, pasid);
+ xa_erase(&igroup->pasid_attach, pasid);
+ kfree(attach);
}
- if (hwpt_paging)
+ if (hwpt_paging && pasid == IOMMU_NO_PASID)
iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, idev->dev);
- mutex_unlock(&idev->igroup->lock);
+ mutex_unlock(&igroup->lock);
/* Caller must destroy hwpt */
return hwpt;
}
static struct iommufd_hw_pagetable *
-iommufd_device_do_attach(struct iommufd_device *idev,
+iommufd_device_do_attach(struct iommufd_device *idev, ioasid_t pasid,
struct iommufd_hw_pagetable *hwpt)
{
int rc;
- rc = iommufd_hw_pagetable_attach(hwpt, idev);
+ rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid);
if (rc)
return ERR_PTR(rc);
return NULL;
@@ -654,11 +682,14 @@ static void
iommufd_group_remove_reserved_iova(struct iommufd_group *igroup,
struct iommufd_hwpt_paging *hwpt_paging)
{
+ struct iommufd_attach *attach;
struct iommufd_device *cur;
+ unsigned long index;
lockdep_assert_held(&igroup->lock);
- list_for_each_entry(cur, &igroup->device_list, group_item)
+ attach = xa_load(&igroup->pasid_attach, IOMMU_NO_PASID);
+ xa_for_each(&attach->device_array, index, cur)
iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, cur->dev);
}
@@ -667,14 +698,17 @@ iommufd_group_do_replace_reserved_iova(struct iommufd_group *igroup,
struct iommufd_hwpt_paging *hwpt_paging)
{
struct iommufd_hwpt_paging *old_hwpt_paging;
+ struct iommufd_attach *attach;
struct iommufd_device *cur;
+ unsigned long index;
int rc;
lockdep_assert_held(&igroup->lock);
- old_hwpt_paging = find_hwpt_paging(igroup->hwpt);
+ attach = xa_load(&igroup->pasid_attach, IOMMU_NO_PASID);
+ old_hwpt_paging = find_hwpt_paging(attach->hwpt);
if (!old_hwpt_paging || hwpt_paging->ioas != old_hwpt_paging->ioas) {
- list_for_each_entry(cur, &igroup->device_list, group_item) {
+ xa_for_each(&attach->device_array, index, cur) {
rc = iopt_table_enforce_dev_resv_regions(
&hwpt_paging->ioas->iopt, cur->dev, NULL);
if (rc)
@@ -693,69 +727,81 @@ err_unresv:
}
static struct iommufd_hw_pagetable *
-iommufd_device_do_replace(struct iommufd_device *idev,
+iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
struct iommufd_hw_pagetable *hwpt)
{
struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
+ bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID;
struct iommufd_hwpt_paging *old_hwpt_paging;
struct iommufd_group *igroup = idev->igroup;
struct iommufd_hw_pagetable *old_hwpt;
+ struct iommufd_attach *attach;
unsigned int num_devices;
int rc;
- mutex_lock(&idev->igroup->lock);
+ mutex_lock(&igroup->lock);
+
+ attach = xa_load(&igroup->pasid_attach, pasid);
+ if (!attach) {
+ rc = -EINVAL;
+ goto err_unlock;
+ }
+
+ old_hwpt = attach->hwpt;
- if (igroup->hwpt == NULL) {
+ WARN_ON(!old_hwpt || xa_empty(&attach->device_array));
+
+ if (!iommufd_device_is_attached(idev, pasid)) {
rc = -EINVAL;
goto err_unlock;
}
- if (hwpt == igroup->hwpt) {
- mutex_unlock(&idev->igroup->lock);
+ if (hwpt == old_hwpt) {
+ mutex_unlock(&igroup->lock);
return NULL;
}
- old_hwpt = igroup->hwpt;
- if (hwpt_paging) {
+ if (attach_resv) {
rc = iommufd_group_do_replace_reserved_iova(igroup, hwpt_paging);
if (rc)
goto err_unlock;
}
- rc = iommufd_hwpt_replace_device(idev, hwpt, old_hwpt);
+ rc = iommufd_hwpt_replace_device(idev, pasid, hwpt, old_hwpt);
if (rc)
goto err_unresv;
old_hwpt_paging = find_hwpt_paging(old_hwpt);
- if (old_hwpt_paging &&
+ if (old_hwpt_paging && pasid == IOMMU_NO_PASID &&
(!hwpt_paging || hwpt_paging->ioas != old_hwpt_paging->ioas))
iommufd_group_remove_reserved_iova(igroup, old_hwpt_paging);
- igroup->hwpt = hwpt;
+ attach->hwpt = hwpt;
- num_devices = list_count_nodes(&igroup->device_list);
+ num_devices = iommufd_group_device_num(igroup, pasid);
/*
- * Move the refcounts held by the device_list to the new hwpt. Retain a
+ * Move the refcounts held by the device_array to the new hwpt. Retain a
* refcount for this thread as the caller will free it.
*/
refcount_add(num_devices, &hwpt->obj.users);
if (num_devices > 1)
WARN_ON(refcount_sub_and_test(num_devices - 1,
&old_hwpt->obj.users));
- mutex_unlock(&idev->igroup->lock);
+ mutex_unlock(&igroup->lock);
/* Caller must destroy old_hwpt */
return old_hwpt;
err_unresv:
- if (hwpt_paging)
+ if (attach_resv)
iommufd_group_remove_reserved_iova(igroup, hwpt_paging);
err_unlock:
- mutex_unlock(&idev->igroup->lock);
+ mutex_unlock(&igroup->lock);
return ERR_PTR(rc);
}
typedef struct iommufd_hw_pagetable *(*attach_fn)(
- struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt);
+ struct iommufd_device *idev, ioasid_t pasid,
+ struct iommufd_hw_pagetable *hwpt);
/*
* When automatically managing the domains we search for a compatible domain in
@@ -763,7 +809,7 @@ typedef struct iommufd_hw_pagetable *(*attach_fn)(
* Automatic domain selection will never pick a manually created domain.
*/
static struct iommufd_hw_pagetable *
-iommufd_device_auto_get_domain(struct iommufd_device *idev,
+iommufd_device_auto_get_domain(struct iommufd_device *idev, ioasid_t pasid,
struct iommufd_ioas *ioas, u32 *pt_id,
attach_fn do_attach)
{
@@ -792,7 +838,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
hwpt = &hwpt_paging->common;
if (!iommufd_lock_obj(&hwpt->obj))
continue;
- destroy_hwpt = (*do_attach)(idev, hwpt);
+ destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
if (IS_ERR(destroy_hwpt)) {
iommufd_put_object(idev->ictx, &hwpt->obj);
/*
@@ -810,8 +856,8 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
goto out_unlock;
}
- hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, 0,
- immediate_attach, NULL);
+ hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, pasid,
+ 0, immediate_attach, NULL);
if (IS_ERR(hwpt_paging)) {
destroy_hwpt = ERR_CAST(hwpt_paging);
goto out_unlock;
@@ -819,7 +865,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
hwpt = &hwpt_paging->common;
if (!immediate_attach) {
- destroy_hwpt = (*do_attach)(idev, hwpt);
+ destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
if (IS_ERR(destroy_hwpt))
goto out_abort;
} else {
@@ -840,8 +886,9 @@ out_unlock:
return destroy_hwpt;
}
-static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
- attach_fn do_attach)
+static int iommufd_device_change_pt(struct iommufd_device *idev,
+ ioasid_t pasid,
+ u32 *pt_id, attach_fn do_attach)
{
struct iommufd_hw_pagetable *destroy_hwpt;
struct iommufd_object *pt_obj;
@@ -856,7 +903,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
struct iommufd_hw_pagetable *hwpt =
container_of(pt_obj, struct iommufd_hw_pagetable, obj);
- destroy_hwpt = (*do_attach)(idev, hwpt);
+ destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
if (IS_ERR(destroy_hwpt))
goto out_put_pt_obj;
break;
@@ -865,8 +912,8 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
struct iommufd_ioas *ioas =
container_of(pt_obj, struct iommufd_ioas, obj);
- destroy_hwpt = iommufd_device_auto_get_domain(idev, ioas, pt_id,
- do_attach);
+ destroy_hwpt = iommufd_device_auto_get_domain(idev, pasid, ioas,
+ pt_id, do_attach);
if (IS_ERR(destroy_hwpt))
goto out_put_pt_obj;
break;
@@ -888,22 +935,26 @@ out_put_pt_obj:
}
/**
- * iommufd_device_attach - Connect a device to an iommu_domain
+ * iommufd_device_attach - Connect a device/pasid to an iommu_domain
* @idev: device to attach
+ * @pasid: pasid to attach
* @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HWPT_PAGING
* Output the IOMMUFD_OBJ_HWPT_PAGING ID
*
- * This connects the device to an iommu_domain, either automatically or manually
- * selected. Once this completes the device could do DMA.
+ * This connects the device/pasid to an iommu_domain, either automatically
+ * or manually selected. Once this completes the device could do DMA with
+ * @pasid. @pasid is IOMMU_NO_PASID if this attach is for no pasid usage.
*
* The caller should return the resulting pt_id back to userspace.
* This function is undone by calling iommufd_device_detach().
*/
-int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id)
+int iommufd_device_attach(struct iommufd_device *idev, ioasid_t pasid,
+ u32 *pt_id)
{
int rc;
- rc = iommufd_device_change_pt(idev, pt_id, &iommufd_device_do_attach);
+ rc = iommufd_device_change_pt(idev, pasid, pt_id,
+ &iommufd_device_do_attach);
if (rc)
return rc;
@@ -917,8 +968,9 @@ int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id)
EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, "IOMMUFD");
/**
- * iommufd_device_replace - Change the device's iommu_domain
+ * iommufd_device_replace - Change the device/pasid's iommu_domain
* @idev: device to change
+ * @pasid: pasid to change
* @pt_id: Input a IOMMUFD_OBJ_IOAS, or IOMMUFD_OBJ_HWPT_PAGING
* Output the IOMMUFD_OBJ_HWPT_PAGING ID
*
@@ -929,27 +981,33 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, "IOMMUFD");
*
* If it fails then no change is made to the attachment. The iommu driver may
* implement this so there is no disruption in translation. This can only be
- * called if iommufd_device_attach() has already succeeded.
+ * called if iommufd_device_attach() has already succeeded. @pasid is
+ * IOMMU_NO_PASID for no pasid usage.
*/
-int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id)
+int iommufd_device_replace(struct iommufd_device *idev, ioasid_t pasid,
+ u32 *pt_id)
{
- return iommufd_device_change_pt(idev, pt_id,
+ return iommufd_device_change_pt(idev, pasid, pt_id,
&iommufd_device_do_replace);
}
EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, "IOMMUFD");
/**
- * iommufd_device_detach - Disconnect a device to an iommu_domain
+ * iommufd_device_detach - Disconnect a device/device to an iommu_domain
* @idev: device to detach
+ * @pasid: pasid to detach
*
* Undo iommufd_device_attach(). This disconnects the idev from the previously
* attached pt_id. The device returns back to a blocked DMA translation.
+ * @pasid is IOMMU_NO_PASID for no pasid usage.
*/
-void iommufd_device_detach(struct iommufd_device *idev)
+void iommufd_device_detach(struct iommufd_device *idev, ioasid_t pasid)
{
struct iommufd_hw_pagetable *hwpt;
- hwpt = iommufd_hw_pagetable_detach(idev);
+ hwpt = iommufd_hw_pagetable_detach(idev, pasid);
+ if (!hwpt)
+ return;
iommufd_hw_pagetable_put(idev->ictx, hwpt);
refcount_dec(&idev->obj.users);
}
@@ -1349,7 +1407,7 @@ int iommufd_access_rw(struct iommufd_access *access, unsigned long iova,
struct io_pagetable *iopt;
struct iopt_area *area;
unsigned long last_iova;
- int rc;
+ int rc = -EINVAL;
if (!length)
return -EINVAL;
@@ -1405,7 +1463,8 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd)
void *data;
int rc;
- if (cmd->flags || cmd->__reserved)
+ if (cmd->flags || cmd->__reserved[0] || cmd->__reserved[1] ||
+ cmd->__reserved[2])
return -EOPNOTSUPP;
idev = iommufd_get_device(ucmd, cmd->dev_id);
@@ -1462,6 +1521,36 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd)
if (device_iommu_capable(idev->dev, IOMMU_CAP_DIRTY_TRACKING))
cmd->out_capabilities |= IOMMU_HW_CAP_DIRTY_TRACKING;
+ cmd->out_max_pasid_log2 = 0;
+ /*
+ * Currently, all iommu drivers enable PASID in the probe_device()
+ * op if iommu and device supports it. So the max_pasids stored in
+ * dev->iommu indicates both PASID support and enable status. A
+ * non-zero dev->iommu->max_pasids means PASID is supported and
+ * enabled. The iommufd only reports PASID capability to userspace
+ * if it's enabled.
+ */
+ if (idev->dev->iommu->max_pasids) {
+ cmd->out_max_pasid_log2 = ilog2(idev->dev->iommu->max_pasids);
+
+ if (dev_is_pci(idev->dev)) {
+ struct pci_dev *pdev = to_pci_dev(idev->dev);
+ int ctrl;
+
+ ctrl = pci_pasid_status(pdev);
+
+ WARN_ON_ONCE(ctrl < 0 ||
+ !(ctrl & PCI_PASID_CTRL_ENABLE));
+
+ if (ctrl & PCI_PASID_CTRL_EXEC)
+ cmd->out_capabilities |=
+ IOMMU_HW_CAP_PCI_PASID_EXEC;
+ if (ctrl & PCI_PASID_CTRL_PRIV)
+ cmd->out_capabilities |=
+ IOMMU_HW_CAP_PCI_PASID_PRIV;
+ }
+ }
+
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
out_free:
kfree(data);
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 2d98b04ff1cb..922cd1fe7ec2 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -49,5 +49,203 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
}
EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, "IOMMUFD");
+/* Return -ENOENT if device is not associated to the vIOMMU */
+int iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+ struct device *dev, unsigned long *vdev_id)
+{
+ struct iommufd_vdevice *vdev;
+ unsigned long index;
+ int rc = -ENOENT;
+
+ if (WARN_ON_ONCE(!vdev_id))
+ return -EINVAL;
+
+ xa_lock(&viommu->vdevs);
+ xa_for_each(&viommu->vdevs, index, vdev) {
+ if (vdev->dev == dev) {
+ *vdev_id = vdev->id;
+ rc = 0;
+ break;
+ }
+ }
+ xa_unlock(&viommu->vdevs);
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, "IOMMUFD");
+
+/*
+ * Typically called in driver's threaded IRQ handler.
+ * The @type and @event_data must be defined in include/uapi/linux/iommufd.h
+ */
+int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
+ enum iommu_veventq_type type, void *event_data,
+ size_t data_len)
+{
+ struct iommufd_veventq *veventq;
+ struct iommufd_vevent *vevent;
+ int rc = 0;
+
+ if (WARN_ON_ONCE(!data_len || !event_data))
+ return -EINVAL;
+
+ down_read(&viommu->veventqs_rwsem);
+
+ veventq = iommufd_viommu_find_veventq(viommu, type);
+ if (!veventq) {
+ rc = -EOPNOTSUPP;
+ goto out_unlock_veventqs;
+ }
+
+ spin_lock(&veventq->common.lock);
+ if (veventq->num_events == veventq->depth) {
+ vevent = &veventq->lost_events_header;
+ goto out_set_header;
+ }
+
+ vevent = kzalloc(struct_size(vevent, event_data, data_len), GFP_ATOMIC);
+ if (!vevent) {
+ rc = -ENOMEM;
+ vevent = &veventq->lost_events_header;
+ goto out_set_header;
+ }
+ memcpy(vevent->event_data, event_data, data_len);
+ vevent->data_len = data_len;
+ veventq->num_events++;
+
+out_set_header:
+ iommufd_vevent_handler(veventq, vevent);
+ spin_unlock(&veventq->common.lock);
+out_unlock_veventqs:
+ up_read(&viommu->veventqs_rwsem);
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_report_event, "IOMMUFD");
+
+#ifdef CONFIG_IRQ_MSI_IOMMU
+/*
+ * Get a iommufd_sw_msi_map for the msi physical address requested by the irq
+ * layer. The mapping to IOVA is global to the iommufd file descriptor, every
+ * domain that is attached to a device using the same MSI parameters will use
+ * the same IOVA.
+ */
+static struct iommufd_sw_msi_map *
+iommufd_sw_msi_get_map(struct iommufd_ctx *ictx, phys_addr_t msi_addr,
+ phys_addr_t sw_msi_start)
+{
+ struct iommufd_sw_msi_map *cur;
+ unsigned int max_pgoff = 0;
+
+ lockdep_assert_held(&ictx->sw_msi_lock);
+
+ list_for_each_entry(cur, &ictx->sw_msi_list, sw_msi_item) {
+ if (cur->sw_msi_start != sw_msi_start)
+ continue;
+ max_pgoff = max(max_pgoff, cur->pgoff + 1);
+ if (cur->msi_addr == msi_addr)
+ return cur;
+ }
+
+ if (ictx->sw_msi_id >=
+ BITS_PER_BYTE * sizeof_field(struct iommufd_sw_msi_maps, bitmap))
+ return ERR_PTR(-EOVERFLOW);
+
+ cur = kzalloc(sizeof(*cur), GFP_KERNEL);
+ if (!cur)
+ return ERR_PTR(-ENOMEM);
+
+ cur->sw_msi_start = sw_msi_start;
+ cur->msi_addr = msi_addr;
+ cur->pgoff = max_pgoff;
+ cur->id = ictx->sw_msi_id++;
+ list_add_tail(&cur->sw_msi_item, &ictx->sw_msi_list);
+ return cur;
+}
+
+int iommufd_sw_msi_install(struct iommufd_ctx *ictx,
+ struct iommufd_hwpt_paging *hwpt_paging,
+ struct iommufd_sw_msi_map *msi_map)
+{
+ unsigned long iova;
+
+ lockdep_assert_held(&ictx->sw_msi_lock);
+
+ iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE;
+ if (!test_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap)) {
+ int rc;
+
+ rc = iommu_map(hwpt_paging->common.domain, iova,
+ msi_map->msi_addr, PAGE_SIZE,
+ IOMMU_WRITE | IOMMU_READ | IOMMU_MMIO,
+ GFP_KERNEL_ACCOUNT);
+ if (rc)
+ return rc;
+ __set_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_sw_msi_install, "IOMMUFD_INTERNAL");
+
+/*
+ * Called by the irq code if the platform translates the MSI address through the
+ * IOMMU. msi_addr is the physical address of the MSI page. iommufd will
+ * allocate a fd global iova for the physical page that is the same on all
+ * domains and devices.
+ */
+int iommufd_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
+ phys_addr_t msi_addr)
+{
+ struct device *dev = msi_desc_to_dev(desc);
+ struct iommufd_hwpt_paging *hwpt_paging;
+ struct iommu_attach_handle *raw_handle;
+ struct iommufd_attach_handle *handle;
+ struct iommufd_sw_msi_map *msi_map;
+ struct iommufd_ctx *ictx;
+ unsigned long iova;
+ int rc;
+
+ /*
+ * It is safe to call iommu_attach_handle_get() here because the iommu
+ * core code invokes this under the group mutex which also prevents any
+ * change of the attach handle for the duration of this function.
+ */
+ iommu_group_mutex_assert(dev);
+
+ raw_handle =
+ iommu_attach_handle_get(dev->iommu_group, IOMMU_NO_PASID, 0);
+ if (IS_ERR(raw_handle))
+ return 0;
+ hwpt_paging = find_hwpt_paging(domain->iommufd_hwpt);
+
+ handle = to_iommufd_handle(raw_handle);
+ /* No IOMMU_RESV_SW_MSI means no change to the msi_msg */
+ if (handle->idev->igroup->sw_msi_start == PHYS_ADDR_MAX)
+ return 0;
+
+ ictx = handle->idev->ictx;
+ guard(mutex)(&ictx->sw_msi_lock);
+ /*
+ * The input msi_addr is the exact byte offset of the MSI doorbell, we
+ * assume the caller has checked that it is contained with a MMIO region
+ * that is secure to map at PAGE_SIZE.
+ */
+ msi_map = iommufd_sw_msi_get_map(handle->idev->ictx,
+ msi_addr & PAGE_MASK,
+ handle->idev->igroup->sw_msi_start);
+ if (IS_ERR(msi_map))
+ return PTR_ERR(msi_map);
+
+ rc = iommufd_sw_msi_install(ictx, hwpt_paging, msi_map);
+ if (rc)
+ return rc;
+ __set_bit(msi_map->id, handle->idev->igroup->required_sw_msi.bitmap);
+
+ iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE;
+ msi_desc_set_iommu_msi_iova(desc, iova, PAGE_SHIFT);
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_sw_msi, "IOMMUFD");
+#endif
+
MODULE_DESCRIPTION("iommufd code shared with builtin modules");
+MODULE_IMPORT_NS("IOMMUFD_INTERNAL");
MODULE_LICENSE("GPL");
diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c
new file mode 100644
index 000000000000..f39cf0797347
--- /dev/null
+++ b/drivers/iommu/iommufd/eventq.c
@@ -0,0 +1,598 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2024 Intel Corporation
+ */
+#define pr_fmt(fmt) "iommufd: " fmt
+
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/iommufd.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/pci-ats.h>
+#include <linux/poll.h>
+#include <uapi/linux/iommufd.h>
+
+#include "../iommu-priv.h"
+#include "iommufd_private.h"
+
+/* IOMMUFD_OBJ_FAULT Functions */
+
+int iommufd_fault_iopf_enable(struct iommufd_device *idev)
+{
+ struct device *dev = idev->dev;
+ int ret;
+
+ /*
+ * Once we turn on PCI/PRI support for VF, the response failure code
+ * should not be forwarded to the hardware due to PRI being a shared
+ * resource between PF and VFs. There is no coordination for this
+ * shared capability. This waits for a vPRI reset to recover.
+ */
+ if (dev_is_pci(dev)) {
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (pdev->is_virtfn && pci_pri_supported(pdev))
+ return -EINVAL;
+ }
+
+ mutex_lock(&idev->iopf_lock);
+ /* Device iopf has already been on. */
+ if (++idev->iopf_enabled > 1) {
+ mutex_unlock(&idev->iopf_lock);
+ return 0;
+ }
+
+ ret = iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_IOPF);
+ if (ret)
+ --idev->iopf_enabled;
+ mutex_unlock(&idev->iopf_lock);
+
+ return ret;
+}
+
+void iommufd_fault_iopf_disable(struct iommufd_device *idev)
+{
+ mutex_lock(&idev->iopf_lock);
+ if (!WARN_ON(idev->iopf_enabled == 0)) {
+ if (--idev->iopf_enabled == 0)
+ iommu_dev_disable_feature(idev->dev, IOMMU_DEV_FEAT_IOPF);
+ }
+ mutex_unlock(&idev->iopf_lock);
+}
+
+void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
+ struct iommufd_attach_handle *handle)
+{
+ struct iommufd_fault *fault = hwpt->fault;
+ struct iopf_group *group, *next;
+ struct list_head free_list;
+ unsigned long index;
+
+ if (!fault)
+ return;
+ INIT_LIST_HEAD(&free_list);
+
+ mutex_lock(&fault->mutex);
+ spin_lock(&fault->common.lock);
+ list_for_each_entry_safe(group, next, &fault->common.deliver, node) {
+ if (group->attach_handle != &handle->handle)
+ continue;
+ list_move(&group->node, &free_list);
+ }
+ spin_unlock(&fault->common.lock);
+
+ list_for_each_entry_safe(group, next, &free_list, node) {
+ list_del(&group->node);
+ iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
+ iopf_free_group(group);
+ }
+
+ xa_for_each(&fault->response, index, group) {
+ if (group->attach_handle != &handle->handle)
+ continue;
+ xa_erase(&fault->response, index);
+ iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
+ iopf_free_group(group);
+ }
+ mutex_unlock(&fault->mutex);
+}
+
+void iommufd_fault_destroy(struct iommufd_object *obj)
+{
+ struct iommufd_eventq *eventq =
+ container_of(obj, struct iommufd_eventq, obj);
+ struct iommufd_fault *fault = eventq_to_fault(eventq);
+ struct iopf_group *group, *next;
+ unsigned long index;
+
+ /*
+ * The iommufd object's reference count is zero at this point.
+ * We can be confident that no other threads are currently
+ * accessing this pointer. Therefore, acquiring the mutex here
+ * is unnecessary.
+ */
+ list_for_each_entry_safe(group, next, &fault->common.deliver, node) {
+ list_del(&group->node);
+ iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
+ iopf_free_group(group);
+ }
+ xa_for_each(&fault->response, index, group) {
+ xa_erase(&fault->response, index);
+ iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
+ iopf_free_group(group);
+ }
+ xa_destroy(&fault->response);
+ mutex_destroy(&fault->mutex);
+}
+
+static void iommufd_compose_fault_message(struct iommu_fault *fault,
+ struct iommu_hwpt_pgfault *hwpt_fault,
+ struct iommufd_device *idev,
+ u32 cookie)
+{
+ hwpt_fault->flags = fault->prm.flags;
+ hwpt_fault->dev_id = idev->obj.id;
+ hwpt_fault->pasid = fault->prm.pasid;
+ hwpt_fault->grpid = fault->prm.grpid;
+ hwpt_fault->perm = fault->prm.perm;
+ hwpt_fault->addr = fault->prm.addr;
+ hwpt_fault->length = 0;
+ hwpt_fault->cookie = cookie;
+}
+
+/* Fetch the first node out of the fault->deliver list */
+static struct iopf_group *
+iommufd_fault_deliver_fetch(struct iommufd_fault *fault)
+{
+ struct list_head *list = &fault->common.deliver;
+ struct iopf_group *group = NULL;
+
+ spin_lock(&fault->common.lock);
+ if (!list_empty(list)) {
+ group = list_first_entry(list, struct iopf_group, node);
+ list_del(&group->node);
+ }
+ spin_unlock(&fault->common.lock);
+ return group;
+}
+
+/* Restore a node back to the head of the fault->deliver list */
+static void iommufd_fault_deliver_restore(struct iommufd_fault *fault,
+ struct iopf_group *group)
+{
+ spin_lock(&fault->common.lock);
+ list_add(&group->node, &fault->common.deliver);
+ spin_unlock(&fault->common.lock);
+}
+
+static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ size_t fault_size = sizeof(struct iommu_hwpt_pgfault);
+ struct iommufd_eventq *eventq = filep->private_data;
+ struct iommufd_fault *fault = eventq_to_fault(eventq);
+ struct iommu_hwpt_pgfault data = {};
+ struct iommufd_device *idev;
+ struct iopf_group *group;
+ struct iopf_fault *iopf;
+ size_t done = 0;
+ int rc = 0;
+
+ if (*ppos || count % fault_size)
+ return -ESPIPE;
+
+ mutex_lock(&fault->mutex);
+ while ((group = iommufd_fault_deliver_fetch(fault))) {
+ if (done >= count ||
+ group->fault_count * fault_size > count - done) {
+ iommufd_fault_deliver_restore(fault, group);
+ break;
+ }
+
+ rc = xa_alloc(&fault->response, &group->cookie, group,
+ xa_limit_32b, GFP_KERNEL);
+ if (rc) {
+ iommufd_fault_deliver_restore(fault, group);
+ break;
+ }
+
+ idev = to_iommufd_handle(group->attach_handle)->idev;
+ list_for_each_entry(iopf, &group->faults, list) {
+ iommufd_compose_fault_message(&iopf->fault,
+ &data, idev,
+ group->cookie);
+ if (copy_to_user(buf + done, &data, fault_size)) {
+ xa_erase(&fault->response, group->cookie);
+ iommufd_fault_deliver_restore(fault, group);
+ rc = -EFAULT;
+ break;
+ }
+ done += fault_size;
+ }
+ }
+ mutex_unlock(&fault->mutex);
+
+ return done == 0 ? rc : done;
+}
+
+static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ size_t response_size = sizeof(struct iommu_hwpt_page_response);
+ struct iommufd_eventq *eventq = filep->private_data;
+ struct iommufd_fault *fault = eventq_to_fault(eventq);
+ struct iommu_hwpt_page_response response;
+ struct iopf_group *group;
+ size_t done = 0;
+ int rc = 0;
+
+ if (*ppos || count % response_size)
+ return -ESPIPE;
+
+ mutex_lock(&fault->mutex);
+ while (count > done) {
+ rc = copy_from_user(&response, buf + done, response_size);
+ if (rc)
+ break;
+
+ static_assert((int)IOMMUFD_PAGE_RESP_SUCCESS ==
+ (int)IOMMU_PAGE_RESP_SUCCESS);
+ static_assert((int)IOMMUFD_PAGE_RESP_INVALID ==
+ (int)IOMMU_PAGE_RESP_INVALID);
+ if (response.code != IOMMUFD_PAGE_RESP_SUCCESS &&
+ response.code != IOMMUFD_PAGE_RESP_INVALID) {
+ rc = -EINVAL;
+ break;
+ }
+
+ group = xa_erase(&fault->response, response.cookie);
+ if (!group) {
+ rc = -EINVAL;
+ break;
+ }
+
+ iopf_group_response(group, response.code);
+ iopf_free_group(group);
+ done += response_size;
+ }
+ mutex_unlock(&fault->mutex);
+
+ return done == 0 ? rc : done;
+}
+
+/* IOMMUFD_OBJ_VEVENTQ Functions */
+
+void iommufd_veventq_abort(struct iommufd_object *obj)
+{
+ struct iommufd_eventq *eventq =
+ container_of(obj, struct iommufd_eventq, obj);
+ struct iommufd_veventq *veventq = eventq_to_veventq(eventq);
+ struct iommufd_viommu *viommu = veventq->viommu;
+ struct iommufd_vevent *cur, *next;
+
+ lockdep_assert_held_write(&viommu->veventqs_rwsem);
+
+ list_for_each_entry_safe(cur, next, &eventq->deliver, node) {
+ list_del(&cur->node);
+ if (cur != &veventq->lost_events_header)
+ kfree(cur);
+ }
+
+ refcount_dec(&viommu->obj.users);
+ list_del(&veventq->node);
+}
+
+void iommufd_veventq_destroy(struct iommufd_object *obj)
+{
+ struct iommufd_veventq *veventq = eventq_to_veventq(
+ container_of(obj, struct iommufd_eventq, obj));
+
+ down_write(&veventq->viommu->veventqs_rwsem);
+ iommufd_veventq_abort(obj);
+ up_write(&veventq->viommu->veventqs_rwsem);
+}
+
+static struct iommufd_vevent *
+iommufd_veventq_deliver_fetch(struct iommufd_veventq *veventq)
+{
+ struct iommufd_eventq *eventq = &veventq->common;
+ struct list_head *list = &eventq->deliver;
+ struct iommufd_vevent *vevent = NULL;
+
+ spin_lock(&eventq->lock);
+ if (!list_empty(list)) {
+ struct iommufd_vevent *next;
+
+ next = list_first_entry(list, struct iommufd_vevent, node);
+ /* Make a copy of the lost_events_header for copy_to_user */
+ if (next == &veventq->lost_events_header) {
+ vevent = kzalloc(sizeof(*vevent), GFP_ATOMIC);
+ if (!vevent)
+ goto out_unlock;
+ }
+ list_del(&next->node);
+ if (vevent)
+ memcpy(vevent, next, sizeof(*vevent));
+ else
+ vevent = next;
+ }
+out_unlock:
+ spin_unlock(&eventq->lock);
+ return vevent;
+}
+
+static void iommufd_veventq_deliver_restore(struct iommufd_veventq *veventq,
+ struct iommufd_vevent *vevent)
+{
+ struct iommufd_eventq *eventq = &veventq->common;
+ struct list_head *list = &eventq->deliver;
+
+ spin_lock(&eventq->lock);
+ if (vevent_for_lost_events_header(vevent)) {
+ /* Remove the copy of the lost_events_header */
+ kfree(vevent);
+ vevent = NULL;
+ /* An empty list needs the lost_events_header back */
+ if (list_empty(list))
+ vevent = &veventq->lost_events_header;
+ }
+ if (vevent)
+ list_add(&vevent->node, list);
+ spin_unlock(&eventq->lock);
+}
+
+static ssize_t iommufd_veventq_fops_read(struct file *filep, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct iommufd_eventq *eventq = filep->private_data;
+ struct iommufd_veventq *veventq = eventq_to_veventq(eventq);
+ struct iommufd_vevent_header *hdr;
+ struct iommufd_vevent *cur;
+ size_t done = 0;
+ int rc = 0;
+
+ if (*ppos)
+ return -ESPIPE;
+
+ while ((cur = iommufd_veventq_deliver_fetch(veventq))) {
+ /* Validate the remaining bytes against the header size */
+ if (done >= count || sizeof(*hdr) > count - done) {
+ iommufd_veventq_deliver_restore(veventq, cur);
+ break;
+ }
+ hdr = &cur->header;
+
+ /* If being a normal vEVENT, validate against the full size */
+ if (!vevent_for_lost_events_header(cur) &&
+ sizeof(hdr) + cur->data_len > count - done) {
+ iommufd_veventq_deliver_restore(veventq, cur);
+ break;
+ }
+
+ if (copy_to_user(buf + done, hdr, sizeof(*hdr))) {
+ iommufd_veventq_deliver_restore(veventq, cur);
+ rc = -EFAULT;
+ break;
+ }
+ done += sizeof(*hdr);
+
+ if (cur->data_len &&
+ copy_to_user(buf + done, cur->event_data, cur->data_len)) {
+ iommufd_veventq_deliver_restore(veventq, cur);
+ rc = -EFAULT;
+ break;
+ }
+ spin_lock(&eventq->lock);
+ if (!vevent_for_lost_events_header(cur))
+ veventq->num_events--;
+ spin_unlock(&eventq->lock);
+ done += cur->data_len;
+ kfree(cur);
+ }
+
+ return done == 0 ? rc : done;
+}
+
+/* Common Event Queue Functions */
+
+static __poll_t iommufd_eventq_fops_poll(struct file *filep,
+ struct poll_table_struct *wait)
+{
+ struct iommufd_eventq *eventq = filep->private_data;
+ __poll_t pollflags = 0;
+
+ if (eventq->obj.type == IOMMUFD_OBJ_FAULT)
+ pollflags |= EPOLLOUT;
+
+ poll_wait(filep, &eventq->wait_queue, wait);
+ spin_lock(&eventq->lock);
+ if (!list_empty(&eventq->deliver))
+ pollflags |= EPOLLIN | EPOLLRDNORM;
+ spin_unlock(&eventq->lock);
+
+ return pollflags;
+}
+
+static int iommufd_eventq_fops_release(struct inode *inode, struct file *filep)
+{
+ struct iommufd_eventq *eventq = filep->private_data;
+
+ refcount_dec(&eventq->obj.users);
+ iommufd_ctx_put(eventq->ictx);
+ return 0;
+}
+
+#define INIT_EVENTQ_FOPS(read_op, write_op) \
+ ((const struct file_operations){ \
+ .owner = THIS_MODULE, \
+ .open = nonseekable_open, \
+ .read = read_op, \
+ .write = write_op, \
+ .poll = iommufd_eventq_fops_poll, \
+ .release = iommufd_eventq_fops_release, \
+ })
+
+static int iommufd_eventq_init(struct iommufd_eventq *eventq, char *name,
+ struct iommufd_ctx *ictx,
+ const struct file_operations *fops)
+{
+ struct file *filep;
+ int fdno;
+
+ spin_lock_init(&eventq->lock);
+ INIT_LIST_HEAD(&eventq->deliver);
+ init_waitqueue_head(&eventq->wait_queue);
+
+ filep = anon_inode_getfile(name, fops, eventq, O_RDWR);
+ if (IS_ERR(filep))
+ return PTR_ERR(filep);
+
+ eventq->ictx = ictx;
+ iommufd_ctx_get(eventq->ictx);
+ eventq->filep = filep;
+ refcount_inc(&eventq->obj.users);
+
+ fdno = get_unused_fd_flags(O_CLOEXEC);
+ if (fdno < 0)
+ fput(filep);
+ return fdno;
+}
+
+static const struct file_operations iommufd_fault_fops =
+ INIT_EVENTQ_FOPS(iommufd_fault_fops_read, iommufd_fault_fops_write);
+
+int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
+{
+ struct iommu_fault_alloc *cmd = ucmd->cmd;
+ struct iommufd_fault *fault;
+ int fdno;
+ int rc;
+
+ if (cmd->flags)
+ return -EOPNOTSUPP;
+
+ fault = __iommufd_object_alloc(ucmd->ictx, fault, IOMMUFD_OBJ_FAULT,
+ common.obj);
+ if (IS_ERR(fault))
+ return PTR_ERR(fault);
+
+ xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
+ mutex_init(&fault->mutex);
+
+ fdno = iommufd_eventq_init(&fault->common, "[iommufd-pgfault]",
+ ucmd->ictx, &iommufd_fault_fops);
+ if (fdno < 0) {
+ rc = fdno;
+ goto out_abort;
+ }
+
+ cmd->out_fault_id = fault->common.obj.id;
+ cmd->out_fault_fd = fdno;
+
+ rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+ if (rc)
+ goto out_put_fdno;
+ iommufd_object_finalize(ucmd->ictx, &fault->common.obj);
+
+ fd_install(fdno, fault->common.filep);
+
+ return 0;
+out_put_fdno:
+ put_unused_fd(fdno);
+ fput(fault->common.filep);
+out_abort:
+ iommufd_object_abort_and_destroy(ucmd->ictx, &fault->common.obj);
+
+ return rc;
+}
+
+int iommufd_fault_iopf_handler(struct iopf_group *group)
+{
+ struct iommufd_hw_pagetable *hwpt;
+ struct iommufd_fault *fault;
+
+ hwpt = group->attach_handle->domain->iommufd_hwpt;
+ fault = hwpt->fault;
+
+ spin_lock(&fault->common.lock);
+ list_add_tail(&group->node, &fault->common.deliver);
+ spin_unlock(&fault->common.lock);
+
+ wake_up_interruptible(&fault->common.wait_queue);
+
+ return 0;
+}
+
+static const struct file_operations iommufd_veventq_fops =
+ INIT_EVENTQ_FOPS(iommufd_veventq_fops_read, NULL);
+
+int iommufd_veventq_alloc(struct iommufd_ucmd *ucmd)
+{
+ struct iommu_veventq_alloc *cmd = ucmd->cmd;
+ struct iommufd_veventq *veventq;
+ struct iommufd_viommu *viommu;
+ int fdno;
+ int rc;
+
+ if (cmd->flags || cmd->__reserved ||
+ cmd->type == IOMMU_VEVENTQ_TYPE_DEFAULT)
+ return -EOPNOTSUPP;
+ if (!cmd->veventq_depth)
+ return -EINVAL;
+
+ viommu = iommufd_get_viommu(ucmd, cmd->viommu_id);
+ if (IS_ERR(viommu))
+ return PTR_ERR(viommu);
+
+ down_write(&viommu->veventqs_rwsem);
+
+ if (iommufd_viommu_find_veventq(viommu, cmd->type)) {
+ rc = -EEXIST;
+ goto out_unlock_veventqs;
+ }
+
+ veventq = __iommufd_object_alloc(ucmd->ictx, veventq,
+ IOMMUFD_OBJ_VEVENTQ, common.obj);
+ if (IS_ERR(veventq)) {
+ rc = PTR_ERR(veventq);
+ goto out_unlock_veventqs;
+ }
+
+ veventq->type = cmd->type;
+ veventq->viommu = viommu;
+ refcount_inc(&viommu->obj.users);
+ veventq->depth = cmd->veventq_depth;
+ list_add_tail(&veventq->node, &viommu->veventqs);
+ veventq->lost_events_header.header.flags =
+ IOMMU_VEVENTQ_FLAG_LOST_EVENTS;
+
+ fdno = iommufd_eventq_init(&veventq->common, "[iommufd-viommu-event]",
+ ucmd->ictx, &iommufd_veventq_fops);
+ if (fdno < 0) {
+ rc = fdno;
+ goto out_abort;
+ }
+
+ cmd->out_veventq_id = veventq->common.obj.id;
+ cmd->out_veventq_fd = fdno;
+
+ rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+ if (rc)
+ goto out_put_fdno;
+
+ iommufd_object_finalize(ucmd->ictx, &veventq->common.obj);
+ fd_install(fdno, veventq->common.filep);
+ goto out_unlock_veventqs;
+
+out_put_fdno:
+ put_unused_fd(fdno);
+ fput(veventq->common.filep);
+out_abort:
+ iommufd_object_abort_and_destroy(ucmd->ictx, &veventq->common.obj);
+out_unlock_veventqs:
+ up_write(&viommu->veventqs_rwsem);
+ iommufd_put_object(ucmd->ictx, &viommu->obj);
+ return rc;
+}
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
deleted file mode 100644
index c48d72c9668c..000000000000
--- a/drivers/iommu/iommufd/fault.c
+++ /dev/null
@@ -1,342 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (C) 2024 Intel Corporation
- */
-#define pr_fmt(fmt) "iommufd: " fmt
-
-#include <linux/anon_inodes.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/iommufd.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/pci-ats.h>
-#include <linux/poll.h>
-#include <uapi/linux/iommufd.h>
-
-#include "../iommu-priv.h"
-#include "iommufd_private.h"
-
-int iommufd_fault_iopf_enable(struct iommufd_device *idev)
-{
- struct device *dev = idev->dev;
- int ret;
-
- /*
- * Once we turn on PCI/PRI support for VF, the response failure code
- * should not be forwarded to the hardware due to PRI being a shared
- * resource between PF and VFs. There is no coordination for this
- * shared capability. This waits for a vPRI reset to recover.
- */
- if (dev_is_pci(dev)) {
- struct pci_dev *pdev = to_pci_dev(dev);
-
- if (pdev->is_virtfn && pci_pri_supported(pdev))
- return -EINVAL;
- }
-
- mutex_lock(&idev->iopf_lock);
- /* Device iopf has already been on. */
- if (++idev->iopf_enabled > 1) {
- mutex_unlock(&idev->iopf_lock);
- return 0;
- }
-
- ret = iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_IOPF);
- if (ret)
- --idev->iopf_enabled;
- mutex_unlock(&idev->iopf_lock);
-
- return ret;
-}
-
-void iommufd_fault_iopf_disable(struct iommufd_device *idev)
-{
- mutex_lock(&idev->iopf_lock);
- if (!WARN_ON(idev->iopf_enabled == 0)) {
- if (--idev->iopf_enabled == 0)
- iommu_dev_disable_feature(idev->dev, IOMMU_DEV_FEAT_IOPF);
- }
- mutex_unlock(&idev->iopf_lock);
-}
-
-void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
- struct iommufd_attach_handle *handle)
-{
- struct iommufd_fault *fault = hwpt->fault;
- struct iopf_group *group, *next;
- struct list_head free_list;
- unsigned long index;
-
- if (!fault)
- return;
- INIT_LIST_HEAD(&free_list);
-
- mutex_lock(&fault->mutex);
- spin_lock(&fault->lock);
- list_for_each_entry_safe(group, next, &fault->deliver, node) {
- if (group->attach_handle != &handle->handle)
- continue;
- list_move(&group->node, &free_list);
- }
- spin_unlock(&fault->lock);
-
- list_for_each_entry_safe(group, next, &free_list, node) {
- list_del(&group->node);
- iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
- iopf_free_group(group);
- }
-
- xa_for_each(&fault->response, index, group) {
- if (group->attach_handle != &handle->handle)
- continue;
- xa_erase(&fault->response, index);
- iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
- iopf_free_group(group);
- }
- mutex_unlock(&fault->mutex);
-}
-
-void iommufd_fault_destroy(struct iommufd_object *obj)
-{
- struct iommufd_fault *fault = container_of(obj, struct iommufd_fault, obj);
- struct iopf_group *group, *next;
- unsigned long index;
-
- /*
- * The iommufd object's reference count is zero at this point.
- * We can be confident that no other threads are currently
- * accessing this pointer. Therefore, acquiring the mutex here
- * is unnecessary.
- */
- list_for_each_entry_safe(group, next, &fault->deliver, node) {
- list_del(&group->node);
- iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
- iopf_free_group(group);
- }
- xa_for_each(&fault->response, index, group) {
- xa_erase(&fault->response, index);
- iopf_group_response(group, IOMMU_PAGE_RESP_INVALID);
- iopf_free_group(group);
- }
- xa_destroy(&fault->response);
- mutex_destroy(&fault->mutex);
-}
-
-static void iommufd_compose_fault_message(struct iommu_fault *fault,
- struct iommu_hwpt_pgfault *hwpt_fault,
- struct iommufd_device *idev,
- u32 cookie)
-{
- hwpt_fault->flags = fault->prm.flags;
- hwpt_fault->dev_id = idev->obj.id;
- hwpt_fault->pasid = fault->prm.pasid;
- hwpt_fault->grpid = fault->prm.grpid;
- hwpt_fault->perm = fault->prm.perm;
- hwpt_fault->addr = fault->prm.addr;
- hwpt_fault->length = 0;
- hwpt_fault->cookie = cookie;
-}
-
-static ssize_t iommufd_fault_fops_read(struct file *filep, char __user *buf,
- size_t count, loff_t *ppos)
-{
- size_t fault_size = sizeof(struct iommu_hwpt_pgfault);
- struct iommufd_fault *fault = filep->private_data;
- struct iommu_hwpt_pgfault data = {};
- struct iommufd_device *idev;
- struct iopf_group *group;
- struct iopf_fault *iopf;
- size_t done = 0;
- int rc = 0;
-
- if (*ppos || count % fault_size)
- return -ESPIPE;
-
- mutex_lock(&fault->mutex);
- while ((group = iommufd_fault_deliver_fetch(fault))) {
- if (done >= count ||
- group->fault_count * fault_size > count - done) {
- iommufd_fault_deliver_restore(fault, group);
- break;
- }
-
- rc = xa_alloc(&fault->response, &group->cookie, group,
- xa_limit_32b, GFP_KERNEL);
- if (rc) {
- iommufd_fault_deliver_restore(fault, group);
- break;
- }
-
- idev = to_iommufd_handle(group->attach_handle)->idev;
- list_for_each_entry(iopf, &group->faults, list) {
- iommufd_compose_fault_message(&iopf->fault,
- &data, idev,
- group->cookie);
- if (copy_to_user(buf + done, &data, fault_size)) {
- xa_erase(&fault->response, group->cookie);
- iommufd_fault_deliver_restore(fault, group);
- rc = -EFAULT;
- break;
- }
- done += fault_size;
- }
- }
- mutex_unlock(&fault->mutex);
-
- return done == 0 ? rc : done;
-}
-
-static ssize_t iommufd_fault_fops_write(struct file *filep, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- size_t response_size = sizeof(struct iommu_hwpt_page_response);
- struct iommufd_fault *fault = filep->private_data;
- struct iommu_hwpt_page_response response;
- struct iopf_group *group;
- size_t done = 0;
- int rc = 0;
-
- if (*ppos || count % response_size)
- return -ESPIPE;
-
- mutex_lock(&fault->mutex);
- while (count > done) {
- rc = copy_from_user(&response, buf + done, response_size);
- if (rc)
- break;
-
- static_assert((int)IOMMUFD_PAGE_RESP_SUCCESS ==
- (int)IOMMU_PAGE_RESP_SUCCESS);
- static_assert((int)IOMMUFD_PAGE_RESP_INVALID ==
- (int)IOMMU_PAGE_RESP_INVALID);
- if (response.code != IOMMUFD_PAGE_RESP_SUCCESS &&
- response.code != IOMMUFD_PAGE_RESP_INVALID) {
- rc = -EINVAL;
- break;
- }
-
- group = xa_erase(&fault->response, response.cookie);
- if (!group) {
- rc = -EINVAL;
- break;
- }
-
- iopf_group_response(group, response.code);
- iopf_free_group(group);
- done += response_size;
- }
- mutex_unlock(&fault->mutex);
-
- return done == 0 ? rc : done;
-}
-
-static __poll_t iommufd_fault_fops_poll(struct file *filep,
- struct poll_table_struct *wait)
-{
- struct iommufd_fault *fault = filep->private_data;
- __poll_t pollflags = EPOLLOUT;
-
- poll_wait(filep, &fault->wait_queue, wait);
- spin_lock(&fault->lock);
- if (!list_empty(&fault->deliver))
- pollflags |= EPOLLIN | EPOLLRDNORM;
- spin_unlock(&fault->lock);
-
- return pollflags;
-}
-
-static int iommufd_fault_fops_release(struct inode *inode, struct file *filep)
-{
- struct iommufd_fault *fault = filep->private_data;
-
- refcount_dec(&fault->obj.users);
- iommufd_ctx_put(fault->ictx);
- return 0;
-}
-
-static const struct file_operations iommufd_fault_fops = {
- .owner = THIS_MODULE,
- .open = nonseekable_open,
- .read = iommufd_fault_fops_read,
- .write = iommufd_fault_fops_write,
- .poll = iommufd_fault_fops_poll,
- .release = iommufd_fault_fops_release,
-};
-
-int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
-{
- struct iommu_fault_alloc *cmd = ucmd->cmd;
- struct iommufd_fault *fault;
- struct file *filep;
- int fdno;
- int rc;
-
- if (cmd->flags)
- return -EOPNOTSUPP;
-
- fault = iommufd_object_alloc(ucmd->ictx, fault, IOMMUFD_OBJ_FAULT);
- if (IS_ERR(fault))
- return PTR_ERR(fault);
-
- fault->ictx = ucmd->ictx;
- INIT_LIST_HEAD(&fault->deliver);
- xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
- mutex_init(&fault->mutex);
- spin_lock_init(&fault->lock);
- init_waitqueue_head(&fault->wait_queue);
-
- filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops,
- fault, O_RDWR);
- if (IS_ERR(filep)) {
- rc = PTR_ERR(filep);
- goto out_abort;
- }
-
- refcount_inc(&fault->obj.users);
- iommufd_ctx_get(fault->ictx);
- fault->filep = filep;
-
- fdno = get_unused_fd_flags(O_CLOEXEC);
- if (fdno < 0) {
- rc = fdno;
- goto out_fput;
- }
-
- cmd->out_fault_id = fault->obj.id;
- cmd->out_fault_fd = fdno;
-
- rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
- if (rc)
- goto out_put_fdno;
- iommufd_object_finalize(ucmd->ictx, &fault->obj);
-
- fd_install(fdno, fault->filep);
-
- return 0;
-out_put_fdno:
- put_unused_fd(fdno);
-out_fput:
- fput(filep);
-out_abort:
- iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
-
- return rc;
-}
-
-int iommufd_fault_iopf_handler(struct iopf_group *group)
-{
- struct iommufd_hw_pagetable *hwpt;
- struct iommufd_fault *fault;
-
- hwpt = group->attach_handle->domain->iommufd_hwpt;
- fault = hwpt->fault;
-
- spin_lock(&fault->lock);
- list_add_tail(&group->node, &fault->deliver);
- spin_unlock(&fault->lock);
-
- wake_up_interruptible(&fault->wait_queue);
-
- return 0;
-}
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index 7de6e914232e..487779470261 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -14,7 +14,7 @@ static void __iommufd_hwpt_destroy(struct iommufd_hw_pagetable *hwpt)
iommu_domain_free(hwpt->domain);
if (hwpt->fault)
- refcount_dec(&hwpt->fault->obj.users);
+ refcount_dec(&hwpt->fault->common.obj.users);
}
void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)
@@ -90,6 +90,7 @@ iommufd_hwpt_paging_enforce_cc(struct iommufd_hwpt_paging *hwpt_paging)
* @ictx: iommufd context
* @ioas: IOAS to associate the domain with
* @idev: Device to get an iommu_domain for
+ * @pasid: PASID to get an iommu_domain for
* @flags: Flags from userspace
* @immediate_attach: True if idev should be attached to the hwpt
* @user_data: The user provided driver specific data describing the domain to
@@ -105,13 +106,14 @@ iommufd_hwpt_paging_enforce_cc(struct iommufd_hwpt_paging *hwpt_paging)
*/
struct iommufd_hwpt_paging *
iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
- struct iommufd_device *idev, u32 flags,
- bool immediate_attach,
+ struct iommufd_device *idev, ioasid_t pasid,
+ u32 flags, bool immediate_attach,
const struct iommu_user_data *user_data)
{
const u32 valid_flags = IOMMU_HWPT_ALLOC_NEST_PARENT |
IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
- IOMMU_HWPT_FAULT_ID_VALID;
+ IOMMU_HWPT_FAULT_ID_VALID |
+ IOMMU_HWPT_ALLOC_PASID;
const struct iommu_ops *ops = dev_iommu_ops(idev->dev);
struct iommufd_hwpt_paging *hwpt_paging;
struct iommufd_hw_pagetable *hwpt;
@@ -126,12 +128,16 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
if ((flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) &&
!device_iommu_capable(idev->dev, IOMMU_CAP_DIRTY_TRACKING))
return ERR_PTR(-EOPNOTSUPP);
+ if ((flags & IOMMU_HWPT_FAULT_ID_VALID) &&
+ (flags & IOMMU_HWPT_ALLOC_NEST_PARENT))
+ return ERR_PTR(-EOPNOTSUPP);
hwpt_paging = __iommufd_object_alloc(
ictx, hwpt_paging, IOMMUFD_OBJ_HWPT_PAGING, common.obj);
if (IS_ERR(hwpt_paging))
return ERR_CAST(hwpt_paging);
hwpt = &hwpt_paging->common;
+ hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID;
INIT_LIST_HEAD(&hwpt_paging->hwpt_item);
/* Pairs with iommufd_hw_pagetable_destroy() */
@@ -156,7 +162,8 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
goto out_abort;
}
}
- iommu_domain_set_sw_msi(hwpt->domain, iommufd_sw_msi);
+ hwpt->domain->iommufd_hwpt = hwpt;
+ hwpt->domain->cookie_type = IOMMU_COOKIE_IOMMUFD;
/*
* Set the coherency mode before we do iopt_table_add_domain() as some
@@ -185,7 +192,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
* sequence. Once those drivers are fixed this should be removed.
*/
if (immediate_attach) {
- rc = iommufd_hw_pagetable_attach(hwpt, idev);
+ rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid);
if (rc)
goto out_abort;
}
@@ -198,7 +205,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
out_detach:
if (immediate_attach)
- iommufd_hw_pagetable_detach(idev);
+ iommufd_hw_pagetable_detach(idev, pasid);
out_abort:
iommufd_object_abort_and_destroy(ictx, &hwpt->obj);
return ERR_PTR(rc);
@@ -227,7 +234,7 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
struct iommufd_hw_pagetable *hwpt;
int rc;
- if ((flags & ~IOMMU_HWPT_FAULT_ID_VALID) ||
+ if ((flags & ~(IOMMU_HWPT_FAULT_ID_VALID | IOMMU_HWPT_ALLOC_PASID)) ||
!user_data->len || !ops->domain_alloc_nested)
return ERR_PTR(-EOPNOTSUPP);
if (parent->auto_domain || !parent->nest_parent ||
@@ -239,6 +246,7 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
if (IS_ERR(hwpt_nested))
return ERR_CAST(hwpt_nested);
hwpt = &hwpt_nested->common;
+ hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID;
refcount_inc(&parent->common.obj.users);
hwpt_nested->parent = parent;
@@ -252,7 +260,8 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
goto out_abort;
}
hwpt->domain->owner = ops;
- iommu_domain_set_sw_msi(hwpt->domain, iommufd_sw_msi);
+ hwpt->domain->iommufd_hwpt = hwpt;
+ hwpt->domain->cookie_type = IOMMU_COOKIE_IOMMUFD;
if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {
rc = -EINVAL;
@@ -282,7 +291,7 @@ iommufd_viommu_alloc_hwpt_nested(struct iommufd_viommu *viommu, u32 flags,
struct iommufd_hw_pagetable *hwpt;
int rc;
- if (flags & ~IOMMU_HWPT_FAULT_ID_VALID)
+ if (flags & ~(IOMMU_HWPT_FAULT_ID_VALID | IOMMU_HWPT_ALLOC_PASID))
return ERR_PTR(-EOPNOTSUPP);
if (!user_data->len)
return ERR_PTR(-EOPNOTSUPP);
@@ -294,6 +303,7 @@ iommufd_viommu_alloc_hwpt_nested(struct iommufd_viommu *viommu, u32 flags,
if (IS_ERR(hwpt_nested))
return ERR_CAST(hwpt_nested);
hwpt = &hwpt_nested->common;
+ hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID;
hwpt_nested->viommu = viommu;
refcount_inc(&viommu->obj.users);
@@ -308,8 +318,9 @@ iommufd_viommu_alloc_hwpt_nested(struct iommufd_viommu *viommu, u32 flags,
hwpt->domain = NULL;
goto out_abort;
}
+ hwpt->domain->iommufd_hwpt = hwpt;
hwpt->domain->owner = viommu->iommu_dev->ops;
- iommu_domain_set_sw_msi(hwpt->domain, iommufd_sw_msi);
+ hwpt->domain->cookie_type = IOMMU_COOKIE_IOMMUFD;
if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {
rc = -EINVAL;
@@ -358,8 +369,8 @@ int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
ioas = container_of(pt_obj, struct iommufd_ioas, obj);
mutex_lock(&ioas->mutex);
hwpt_paging = iommufd_hwpt_paging_alloc(
- ucmd->ictx, ioas, idev, cmd->flags, false,
- user_data.len ? &user_data : NULL);
+ ucmd->ictx, ioas, idev, IOMMU_NO_PASID, cmd->flags,
+ false, user_data.len ? &user_data : NULL);
if (IS_ERR(hwpt_paging)) {
rc = PTR_ERR(hwpt_paging);
goto out_unlock;
@@ -409,10 +420,9 @@ int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
}
hwpt->fault = fault;
hwpt->domain->iopf_handler = iommufd_fault_iopf_handler;
- refcount_inc(&fault->obj.users);
- iommufd_put_object(ucmd->ictx, &fault->obj);
+ refcount_inc(&fault->common.obj.users);
+ iommufd_put_object(ucmd->ictx, &fault->common.obj);
}
- hwpt->domain->iommufd_hwpt = hwpt;
cmd->out_hwpt_id = hwpt->obj.id;
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 246297452a44..80e8c76d25f2 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -32,8 +32,11 @@ struct iommufd_sw_msi_maps {
DECLARE_BITMAP(bitmap, 64);
};
-int iommufd_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,
- phys_addr_t msi_addr);
+#ifdef CONFIG_IRQ_MSI_IOMMU
+int iommufd_sw_msi_install(struct iommufd_ctx *ictx,
+ struct iommufd_hwpt_paging *hwpt_paging,
+ struct iommufd_sw_msi_map *msi_map);
+#endif
struct iommufd_ctx {
struct file *file;
@@ -296,6 +299,7 @@ struct iommufd_hw_pagetable {
struct iommufd_object obj;
struct iommu_domain *domain;
struct iommufd_fault *fault;
+ bool pasid_compat : 1;
};
struct iommufd_hwpt_paging {
@@ -366,13 +370,13 @@ int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd);
struct iommufd_hwpt_paging *
iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
- struct iommufd_device *idev, u32 flags,
- bool immediate_attach,
+ struct iommufd_device *idev, ioasid_t pasid,
+ u32 flags, bool immediate_attach,
const struct iommu_user_data *user_data);
int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
- struct iommufd_device *idev);
+ struct iommufd_device *idev, ioasid_t pasid);
struct iommufd_hw_pagetable *
-iommufd_hw_pagetable_detach(struct iommufd_device *idev);
+iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid);
void iommufd_hwpt_paging_destroy(struct iommufd_object *obj);
void iommufd_hwpt_paging_abort(struct iommufd_object *obj);
void iommufd_hwpt_nested_destroy(struct iommufd_object *obj);
@@ -396,13 +400,14 @@ static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx,
refcount_dec(&hwpt->obj.users);
}
+struct iommufd_attach;
+
struct iommufd_group {
struct kref ref;
struct mutex lock;
struct iommufd_ctx *ictx;
struct iommu_group *group;
- struct iommufd_hw_pagetable *hwpt;
- struct list_head device_list;
+ struct xarray pasid_attach;
struct iommufd_sw_msi_maps required_sw_msi;
phys_addr_t sw_msi_start;
};
@@ -454,49 +459,17 @@ void iopt_remove_access(struct io_pagetable *iopt,
u32 iopt_access_list_id);
void iommufd_access_destroy_object(struct iommufd_object *obj);
-/*
- * An iommufd_fault object represents an interface to deliver I/O page faults
- * to the user space. These objects are created/destroyed by the user space and
- * associated with hardware page table objects during page-table allocation.
- */
-struct iommufd_fault {
+struct iommufd_eventq {
struct iommufd_object obj;
struct iommufd_ctx *ictx;
struct file *filep;
spinlock_t lock; /* protects the deliver list */
struct list_head deliver;
- struct mutex mutex; /* serializes response flows */
- struct xarray response;
struct wait_queue_head wait_queue;
};
-/* Fetch the first node out of the fault->deliver list */
-static inline struct iopf_group *
-iommufd_fault_deliver_fetch(struct iommufd_fault *fault)
-{
- struct list_head *list = &fault->deliver;
- struct iopf_group *group = NULL;
-
- spin_lock(&fault->lock);
- if (!list_empty(list)) {
- group = list_first_entry(list, struct iopf_group, node);
- list_del(&group->node);
- }
- spin_unlock(&fault->lock);
- return group;
-}
-
-/* Restore a node back to the head of the fault->deliver list */
-static inline void iommufd_fault_deliver_restore(struct iommufd_fault *fault,
- struct iopf_group *group)
-{
- spin_lock(&fault->lock);
- list_add(&group->node, &fault->deliver);
- spin_unlock(&fault->lock);
-}
-
struct iommufd_attach_handle {
struct iommu_attach_handle handle;
struct iommufd_device *idev;
@@ -505,12 +478,29 @@ struct iommufd_attach_handle {
/* Convert an iommu attach handle to iommufd handle. */
#define to_iommufd_handle(hdl) container_of(hdl, struct iommufd_attach_handle, handle)
+/*
+ * An iommufd_fault object represents an interface to deliver I/O page faults
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with hardware page table objects during page-table allocation.
+ */
+struct iommufd_fault {
+ struct iommufd_eventq common;
+ struct mutex mutex; /* serializes response flows */
+ struct xarray response;
+};
+
+static inline struct iommufd_fault *
+eventq_to_fault(struct iommufd_eventq *eventq)
+{
+ return container_of(eventq, struct iommufd_fault, common);
+}
+
static inline struct iommufd_fault *
iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
{
return container_of(iommufd_get_object(ucmd->ictx, id,
IOMMUFD_OBJ_FAULT),
- struct iommufd_fault, obj);
+ struct iommufd_fault, common.obj);
}
int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
@@ -522,6 +512,74 @@ void iommufd_fault_iopf_disable(struct iommufd_device *idev);
void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
struct iommufd_attach_handle *handle);
+/* An iommufd_vevent represents a vIOMMU event in an iommufd_veventq */
+struct iommufd_vevent {
+ struct iommufd_vevent_header header;
+ struct list_head node; /* for iommufd_eventq::deliver */
+ ssize_t data_len;
+ u64 event_data[] __counted_by(data_len);
+};
+
+#define vevent_for_lost_events_header(vevent) \
+ (vevent->header.flags & IOMMU_VEVENTQ_FLAG_LOST_EVENTS)
+
+/*
+ * An iommufd_veventq object represents an interface to deliver vIOMMU events to
+ * the user space. It is created/destroyed by the user space and associated with
+ * a vIOMMU object during the allocations.
+ */
+struct iommufd_veventq {
+ struct iommufd_eventq common;
+ struct iommufd_viommu *viommu;
+ struct list_head node; /* for iommufd_viommu::veventqs */
+ struct iommufd_vevent lost_events_header;
+
+ unsigned int type;
+ unsigned int depth;
+
+ /* Use common.lock for protection */
+ u32 num_events;
+ u32 sequence;
+};
+
+static inline struct iommufd_veventq *
+eventq_to_veventq(struct iommufd_eventq *eventq)
+{
+ return container_of(eventq, struct iommufd_veventq, common);
+}
+
+static inline struct iommufd_veventq *
+iommufd_get_veventq(struct iommufd_ucmd *ucmd, u32 id)
+{
+ return container_of(iommufd_get_object(ucmd->ictx, id,
+ IOMMUFD_OBJ_VEVENTQ),
+ struct iommufd_veventq, common.obj);
+}
+
+int iommufd_veventq_alloc(struct iommufd_ucmd *ucmd);
+void iommufd_veventq_destroy(struct iommufd_object *obj);
+void iommufd_veventq_abort(struct iommufd_object *obj);
+
+static inline void iommufd_vevent_handler(struct iommufd_veventq *veventq,
+ struct iommufd_vevent *vevent)
+{
+ struct iommufd_eventq *eventq = &veventq->common;
+
+ lockdep_assert_held(&eventq->lock);
+
+ /*
+ * Remove the lost_events_header and add the new node at the same time.
+ * Note the new node can be lost_events_header, for a sequence update.
+ */
+ if (list_is_last(&veventq->lost_events_header.node, &eventq->deliver))
+ list_del(&veventq->lost_events_header.node);
+ list_add_tail(&vevent->node, &eventq->deliver);
+ vevent->header.sequence = veventq->sequence;
+ veventq->sequence = (veventq->sequence + 1) & INT_MAX;
+
+ wake_up_interruptible(&eventq->wait_queue);
+}
+
static inline struct iommufd_viommu *
iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
{
@@ -530,6 +588,20 @@ iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
struct iommufd_viommu, obj);
}
+static inline struct iommufd_veventq *
+iommufd_viommu_find_veventq(struct iommufd_viommu *viommu, u32 type)
+{
+ struct iommufd_veventq *veventq, *next;
+
+ lockdep_assert_held(&viommu->veventqs_rwsem);
+
+ list_for_each_entry_safe(veventq, next, &viommu->veventqs, node) {
+ if (veventq->type == type)
+ return veventq;
+ }
+ return NULL;
+}
+
int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd);
void iommufd_viommu_destroy(struct iommufd_object *obj);
int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd);
diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index a6b7a163f636..1cd7e8394129 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -24,6 +24,11 @@ enum {
IOMMU_TEST_OP_MD_CHECK_IOTLB,
IOMMU_TEST_OP_TRIGGER_IOPF,
IOMMU_TEST_OP_DEV_CHECK_CACHE,
+ IOMMU_TEST_OP_TRIGGER_VEVENT,
+ IOMMU_TEST_OP_PASID_ATTACH,
+ IOMMU_TEST_OP_PASID_REPLACE,
+ IOMMU_TEST_OP_PASID_DETACH,
+ IOMMU_TEST_OP_PASID_CHECK_HWPT,
};
enum {
@@ -48,6 +53,7 @@ enum {
enum {
MOCK_FLAGS_DEVICE_NO_DIRTY = 1 << 0,
MOCK_FLAGS_DEVICE_HUGE_IOVA = 1 << 1,
+ MOCK_FLAGS_DEVICE_PASID = 1 << 2,
};
enum {
@@ -60,6 +66,9 @@ enum {
MOCK_DEV_CACHE_NUM = 4,
};
+/* Reserved for special pasid replace test */
+#define IOMMU_TEST_PASID_RESERVED 1024
+
struct iommu_test_cmd {
__u32 size;
__u32 op;
@@ -145,11 +154,36 @@ struct iommu_test_cmd {
__u32 id;
__u32 cache;
} check_dev_cache;
+ struct {
+ __u32 dev_id;
+ } trigger_vevent;
+ struct {
+ __u32 pasid;
+ __u32 pt_id;
+ /* @id is stdev_id */
+ } pasid_attach;
+ struct {
+ __u32 pasid;
+ __u32 pt_id;
+ /* @id is stdev_id */
+ } pasid_replace;
+ struct {
+ __u32 pasid;
+ /* @id is stdev_id */
+ } pasid_detach;
+ struct {
+ __u32 pasid;
+ __u32 hwpt_id;
+ /* @id is stdev_id */
+ } pasid_check;
};
__u32 last;
};
#define IOMMU_TEST_CMD _IO(IOMMUFD_TYPE, IOMMUFD_CMD_BASE + 32)
+/* Mock device/iommu PASID width */
+#define MOCK_PASID_WIDTH 20
+
/* Mock structs for IOMMU_DEVICE_GET_HW_INFO ioctl */
#define IOMMU_HW_INFO_TYPE_SELFTEST 0xfeedbeef
#define IOMMU_HW_INFO_SELFTEST_REGVAL 0xdeadbeef
@@ -212,4 +246,10 @@ struct iommu_viommu_invalidate_selftest {
__u32 cache_id;
};
+#define IOMMU_VEVENTQ_TYPE_SELFTEST 0xbeefbeef
+
+struct iommu_viommu_event_selftest {
+ __u32 virt_id;
+};
+
#endif
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index b6fa9fd11bc1..3df468f64e7d 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -317,6 +317,7 @@ union ucmd_buffer {
struct iommu_ioas_unmap unmap;
struct iommu_option option;
struct iommu_vdevice_alloc vdev;
+ struct iommu_veventq_alloc veventq;
struct iommu_vfio_ioas vfio_ioas;
struct iommu_viommu_alloc viommu;
#ifdef CONFIG_IOMMUFD_TEST
@@ -372,6 +373,8 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
IOCTL_OP(IOMMU_OPTION, iommufd_option, struct iommu_option, val64),
IOCTL_OP(IOMMU_VDEVICE_ALLOC, iommufd_vdevice_alloc_ioctl,
struct iommu_vdevice_alloc, virt_id),
+ IOCTL_OP(IOMMU_VEVENTQ_ALLOC, iommufd_veventq_alloc,
+ struct iommu_veventq_alloc, out_veventq_fd),
IOCTL_OP(IOMMU_VFIO_IOAS, iommufd_vfio_ioas, struct iommu_vfio_ioas,
__reserved),
IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl,
@@ -514,6 +517,10 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
[IOMMUFD_OBJ_VDEVICE] = {
.destroy = iommufd_vdevice_destroy,
},
+ [IOMMUFD_OBJ_VEVENTQ] = {
+ .destroy = iommufd_veventq_destroy,
+ .abort = iommufd_veventq_abort,
+ },
[IOMMUFD_OBJ_VIOMMU] = {
.destroy = iommufd_viommu_destroy,
},
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index d40deb0a4f06..18d9a216eb30 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -161,9 +161,13 @@ enum selftest_obj_type {
struct mock_dev {
struct device dev;
+ struct mock_viommu *viommu;
+ struct rw_semaphore viommu_rwsem;
unsigned long flags;
+ unsigned long vdev_id;
int id;
u32 cache[MOCK_DEV_CACHE_NUM];
+ atomic_t pasid_1024_fake_error;
};
static inline struct mock_dev *to_mock_dev(struct device *dev)
@@ -193,15 +197,71 @@ static int mock_domain_nop_attach(struct iommu_domain *domain,
struct device *dev)
{
struct mock_dev *mdev = to_mock_dev(dev);
+ struct mock_viommu *new_viommu = NULL;
+ unsigned long vdev_id = 0;
+ int rc;
if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
return -EINVAL;
+ iommu_group_mutex_assert(dev);
+ if (domain->type == IOMMU_DOMAIN_NESTED) {
+ new_viommu = to_mock_nested(domain)->mock_viommu;
+ if (new_viommu) {
+ rc = iommufd_viommu_get_vdev_id(&new_viommu->core, dev,
+ &vdev_id);
+ if (rc)
+ return rc;
+ }
+ }
+ if (new_viommu != mdev->viommu) {
+ down_write(&mdev->viommu_rwsem);
+ mdev->viommu = new_viommu;
+ mdev->vdev_id = vdev_id;
+ up_write(&mdev->viommu_rwsem);
+ }
+
+ return 0;
+}
+
+static int mock_domain_set_dev_pasid_nop(struct iommu_domain *domain,
+ struct device *dev, ioasid_t pasid,
+ struct iommu_domain *old)
+{
+ struct mock_dev *mdev = to_mock_dev(dev);
+
+ /*
+ * Per the first attach with pasid 1024, set the
+ * mdev->pasid_1024_fake_error. Hence the second call of this op
+ * can fake an error to validate the error path of the core. This
+ * is helpful to test the case in which the iommu core needs to
+ * rollback to the old domain due to driver failure. e.g. replace.
+ * User should be careful about the third call of this op, it shall
+ * succeed since the mdev->pasid_1024_fake_error is cleared in the
+ * second call.
+ */
+ if (pasid == 1024) {
+ if (domain->type == IOMMU_DOMAIN_BLOCKED) {
+ atomic_set(&mdev->pasid_1024_fake_error, 0);
+ } else if (atomic_read(&mdev->pasid_1024_fake_error)) {
+ /*
+ * Clear the flag, and fake an error to fail the
+ * replacement.
+ */
+ atomic_set(&mdev->pasid_1024_fake_error, 0);
+ return -ENOMEM;
+ } else {
+ /* Set the flag to fake an error in next call */
+ atomic_set(&mdev->pasid_1024_fake_error, 1);
+ }
+ }
+
return 0;
}
static const struct iommu_domain_ops mock_blocking_ops = {
.attach_dev = mock_domain_nop_attach,
+ .set_dev_pasid = mock_domain_set_dev_pasid_nop
};
static struct iommu_domain mock_blocking_domain = {
@@ -343,7 +403,7 @@ mock_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
struct mock_iommu_domain_nested *mock_nested;
struct mock_iommu_domain *mock_parent;
- if (flags)
+ if (flags & ~IOMMU_HWPT_ALLOC_PASID)
return ERR_PTR(-EOPNOTSUPP);
if (!parent || parent->ops != mock_ops.default_domain_ops)
return ERR_PTR(-EINVAL);
@@ -365,7 +425,8 @@ mock_domain_alloc_paging_flags(struct device *dev, u32 flags,
{
bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
- IOMMU_HWPT_ALLOC_NEST_PARENT;
+ IOMMU_HWPT_ALLOC_NEST_PARENT |
+ IOMMU_HWPT_ALLOC_PASID;
struct mock_dev *mdev = to_mock_dev(dev);
bool no_dirty_ops = mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY;
struct mock_iommu_domain *mock;
@@ -585,7 +646,7 @@ mock_viommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
struct mock_viommu *mock_viommu = to_mock_viommu(viommu);
struct mock_iommu_domain_nested *mock_nested;
- if (flags)
+ if (flags & ~IOMMU_HWPT_ALLOC_PASID)
return ERR_PTR(-EOPNOTSUPP);
mock_nested = __mock_domain_alloc_nested(user_data);
@@ -720,6 +781,7 @@ static const struct iommu_ops mock_ops = {
.map_pages = mock_domain_map_pages,
.unmap_pages = mock_domain_unmap_pages,
.iova_to_phys = mock_domain_iova_to_phys,
+ .set_dev_pasid = mock_domain_set_dev_pasid_nop,
},
};
@@ -780,6 +842,7 @@ static struct iommu_domain_ops domain_nested_ops = {
.free = mock_domain_free_nested,
.attach_dev = mock_domain_nop_attach,
.cache_invalidate_user = mock_domain_cache_invalidate_user,
+ .set_dev_pasid = mock_domain_set_dev_pasid_nop,
};
static inline struct iommufd_hw_pagetable *
@@ -839,17 +902,24 @@ static void mock_dev_release(struct device *dev)
static struct mock_dev *mock_dev_create(unsigned long dev_flags)
{
+ struct property_entry prop[] = {
+ PROPERTY_ENTRY_U32("pasid-num-bits", 0),
+ {},
+ };
+ const u32 valid_flags = MOCK_FLAGS_DEVICE_NO_DIRTY |
+ MOCK_FLAGS_DEVICE_HUGE_IOVA |
+ MOCK_FLAGS_DEVICE_PASID;
struct mock_dev *mdev;
int rc, i;
- if (dev_flags &
- ~(MOCK_FLAGS_DEVICE_NO_DIRTY | MOCK_FLAGS_DEVICE_HUGE_IOVA))
+ if (dev_flags & ~valid_flags)
return ERR_PTR(-EINVAL);
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return ERR_PTR(-ENOMEM);
+ init_rwsem(&mdev->viommu_rwsem);
device_initialize(&mdev->dev);
mdev->flags = dev_flags;
mdev->dev.release = mock_dev_release;
@@ -866,6 +936,15 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
if (rc)
goto err_put;
+ if (dev_flags & MOCK_FLAGS_DEVICE_PASID)
+ prop[0] = PROPERTY_ENTRY_U32("pasid-num-bits", MOCK_PASID_WIDTH);
+
+ rc = device_create_managed_software_node(&mdev->dev, prop, NULL);
+ if (rc) {
+ dev_err(&mdev->dev, "add pasid-num-bits property failed, rc: %d", rc);
+ goto err_put;
+ }
+
rc = device_add(&mdev->dev);
if (rc)
goto err_put;
@@ -921,7 +1000,7 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
}
sobj->idev.idev = idev;
- rc = iommufd_device_attach(idev, &pt_id);
+ rc = iommufd_device_attach(idev, IOMMU_NO_PASID, &pt_id);
if (rc)
goto out_unbind;
@@ -936,7 +1015,7 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
return 0;
out_detach:
- iommufd_device_detach(idev);
+ iommufd_device_detach(idev, IOMMU_NO_PASID);
out_unbind:
iommufd_device_unbind(idev);
out_mdev:
@@ -946,39 +1025,49 @@ out_sobj:
return rc;
}
-/* Replace the mock domain with a manually allocated hw_pagetable */
-static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
- unsigned int device_id, u32 pt_id,
- struct iommu_test_cmd *cmd)
+static struct selftest_obj *
+iommufd_test_get_selftest_obj(struct iommufd_ctx *ictx, u32 id)
{
struct iommufd_object *dev_obj;
struct selftest_obj *sobj;
- int rc;
/*
* Prefer to use the OBJ_SELFTEST because the destroy_rwsem will ensure
* it doesn't race with detach, which is not allowed.
*/
- dev_obj =
- iommufd_get_object(ucmd->ictx, device_id, IOMMUFD_OBJ_SELFTEST);
+ dev_obj = iommufd_get_object(ictx, id, IOMMUFD_OBJ_SELFTEST);
if (IS_ERR(dev_obj))
- return PTR_ERR(dev_obj);
+ return ERR_CAST(dev_obj);
sobj = to_selftest_obj(dev_obj);
if (sobj->type != TYPE_IDEV) {
- rc = -EINVAL;
- goto out_dev_obj;
+ iommufd_put_object(ictx, dev_obj);
+ return ERR_PTR(-EINVAL);
}
+ return sobj;
+}
- rc = iommufd_device_replace(sobj->idev.idev, &pt_id);
+/* Replace the mock domain with a manually allocated hw_pagetable */
+static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
+ unsigned int device_id, u32 pt_id,
+ struct iommu_test_cmd *cmd)
+{
+ struct selftest_obj *sobj;
+ int rc;
+
+ sobj = iommufd_test_get_selftest_obj(ucmd->ictx, device_id);
+ if (IS_ERR(sobj))
+ return PTR_ERR(sobj);
+
+ rc = iommufd_device_replace(sobj->idev.idev, IOMMU_NO_PASID, &pt_id);
if (rc)
- goto out_dev_obj;
+ goto out_sobj;
cmd->mock_domain_replace.pt_id = pt_id;
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
-out_dev_obj:
- iommufd_put_object(ucmd->ictx, dev_obj);
+out_sobj:
+ iommufd_put_object(ucmd->ictx, &sobj->obj);
return rc;
}
@@ -1597,13 +1686,166 @@ static int iommufd_test_trigger_iopf(struct iommufd_ucmd *ucmd,
return 0;
}
+static int iommufd_test_trigger_vevent(struct iommufd_ucmd *ucmd,
+ struct iommu_test_cmd *cmd)
+{
+ struct iommu_viommu_event_selftest test = {};
+ struct iommufd_device *idev;
+ struct mock_dev *mdev;
+ int rc = -ENOENT;
+
+ idev = iommufd_get_device(ucmd, cmd->trigger_vevent.dev_id);
+ if (IS_ERR(idev))
+ return PTR_ERR(idev);
+ mdev = to_mock_dev(idev->dev);
+
+ down_read(&mdev->viommu_rwsem);
+ if (!mdev->viommu || !mdev->vdev_id)
+ goto out_unlock;
+
+ test.virt_id = mdev->vdev_id;
+ rc = iommufd_viommu_report_event(&mdev->viommu->core,
+ IOMMU_VEVENTQ_TYPE_SELFTEST, &test,
+ sizeof(test));
+out_unlock:
+ up_read(&mdev->viommu_rwsem);
+ iommufd_put_object(ucmd->ictx, &idev->obj);
+
+ return rc;
+}
+
+static inline struct iommufd_hw_pagetable *
+iommufd_get_hwpt(struct iommufd_ucmd *ucmd, u32 id)
+{
+ struct iommufd_object *pt_obj;
+
+ pt_obj = iommufd_get_object(ucmd->ictx, id, IOMMUFD_OBJ_ANY);
+ if (IS_ERR(pt_obj))
+ return ERR_CAST(pt_obj);
+
+ if (pt_obj->type != IOMMUFD_OBJ_HWPT_NESTED &&
+ pt_obj->type != IOMMUFD_OBJ_HWPT_PAGING) {
+ iommufd_put_object(ucmd->ictx, pt_obj);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return container_of(pt_obj, struct iommufd_hw_pagetable, obj);
+}
+
+static int iommufd_test_pasid_check_hwpt(struct iommufd_ucmd *ucmd,
+ struct iommu_test_cmd *cmd)
+{
+ u32 hwpt_id = cmd->pasid_check.hwpt_id;
+ struct iommu_domain *attached_domain;
+ struct iommu_attach_handle *handle;
+ struct iommufd_hw_pagetable *hwpt;
+ struct selftest_obj *sobj;
+ struct mock_dev *mdev;
+ int rc = 0;
+
+ sobj = iommufd_test_get_selftest_obj(ucmd->ictx, cmd->id);
+ if (IS_ERR(sobj))
+ return PTR_ERR(sobj);
+
+ mdev = sobj->idev.mock_dev;
+
+ handle = iommu_attach_handle_get(mdev->dev.iommu_group,
+ cmd->pasid_check.pasid, 0);
+ if (IS_ERR(handle))
+ attached_domain = NULL;
+ else
+ attached_domain = handle->domain;
+
+ /* hwpt_id == 0 means to check if pasid is detached */
+ if (!hwpt_id) {
+ if (attached_domain)
+ rc = -EINVAL;
+ goto out_sobj;
+ }
+
+ hwpt = iommufd_get_hwpt(ucmd, hwpt_id);
+ if (IS_ERR(hwpt)) {
+ rc = PTR_ERR(hwpt);
+ goto out_sobj;
+ }
+
+ if (attached_domain != hwpt->domain)
+ rc = -EINVAL;
+
+ iommufd_put_object(ucmd->ictx, &hwpt->obj);
+out_sobj:
+ iommufd_put_object(ucmd->ictx, &sobj->obj);
+ return rc;
+}
+
+static int iommufd_test_pasid_attach(struct iommufd_ucmd *ucmd,
+ struct iommu_test_cmd *cmd)
+{
+ struct selftest_obj *sobj;
+ int rc;
+
+ sobj = iommufd_test_get_selftest_obj(ucmd->ictx, cmd->id);
+ if (IS_ERR(sobj))
+ return PTR_ERR(sobj);
+
+ rc = iommufd_device_attach(sobj->idev.idev, cmd->pasid_attach.pasid,
+ &cmd->pasid_attach.pt_id);
+ if (rc)
+ goto out_sobj;
+
+ rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+ if (rc)
+ iommufd_device_detach(sobj->idev.idev,
+ cmd->pasid_attach.pasid);
+
+out_sobj:
+ iommufd_put_object(ucmd->ictx, &sobj->obj);
+ return rc;
+}
+
+static int iommufd_test_pasid_replace(struct iommufd_ucmd *ucmd,
+ struct iommu_test_cmd *cmd)
+{
+ struct selftest_obj *sobj;
+ int rc;
+
+ sobj = iommufd_test_get_selftest_obj(ucmd->ictx, cmd->id);
+ if (IS_ERR(sobj))
+ return PTR_ERR(sobj);
+
+ rc = iommufd_device_replace(sobj->idev.idev, cmd->pasid_attach.pasid,
+ &cmd->pasid_attach.pt_id);
+ if (rc)
+ goto out_sobj;
+
+ rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+
+out_sobj:
+ iommufd_put_object(ucmd->ictx, &sobj->obj);
+ return rc;
+}
+
+static int iommufd_test_pasid_detach(struct iommufd_ucmd *ucmd,
+ struct iommu_test_cmd *cmd)
+{
+ struct selftest_obj *sobj;
+
+ sobj = iommufd_test_get_selftest_obj(ucmd->ictx, cmd->id);
+ if (IS_ERR(sobj))
+ return PTR_ERR(sobj);
+
+ iommufd_device_detach(sobj->idev.idev, cmd->pasid_detach.pasid);
+ iommufd_put_object(ucmd->ictx, &sobj->obj);
+ return 0;
+}
+
void iommufd_selftest_destroy(struct iommufd_object *obj)
{
struct selftest_obj *sobj = to_selftest_obj(obj);
switch (sobj->type) {
case TYPE_IDEV:
- iommufd_device_detach(sobj->idev.idev);
+ iommufd_device_detach(sobj->idev.idev, IOMMU_NO_PASID);
iommufd_device_unbind(sobj->idev.idev);
mock_dev_destroy(sobj->idev.mock_dev);
break;
@@ -1678,6 +1920,16 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
cmd->dirty.flags);
case IOMMU_TEST_OP_TRIGGER_IOPF:
return iommufd_test_trigger_iopf(ucmd, cmd);
+ case IOMMU_TEST_OP_TRIGGER_VEVENT:
+ return iommufd_test_trigger_vevent(ucmd, cmd);
+ case IOMMU_TEST_OP_PASID_ATTACH:
+ return iommufd_test_pasid_attach(ucmd, cmd);
+ case IOMMU_TEST_OP_PASID_REPLACE:
+ return iommufd_test_pasid_replace(ucmd, cmd);
+ case IOMMU_TEST_OP_PASID_DETACH:
+ return iommufd_test_pasid_detach(ucmd, cmd);
+ case IOMMU_TEST_OP_PASID_CHECK_HWPT:
+ return iommufd_test_pasid_check_hwpt(ucmd, cmd);
default:
return -EOPNOTSUPP;
}
@@ -1724,6 +1976,7 @@ int __init iommufd_test_init(void)
init_completion(&mock_iommu.complete);
mock_iommu_iopf_queue = iopf_queue_alloc("mock-iopfq");
+ mock_iommu.iommu_dev.max_pasids = (1 << MOCK_PASID_WIDTH);
return 0;
diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
index 69b88e8c7c26..01df2b985f02 100644
--- a/drivers/iommu/iommufd/viommu.c
+++ b/drivers/iommu/iommufd/viommu.c
@@ -59,6 +59,8 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd)
viommu->ictx = ucmd->ictx;
viommu->hwpt = hwpt_paging;
refcount_inc(&viommu->hwpt->common.obj.users);
+ INIT_LIST_HEAD(&viommu->veventqs);
+ init_rwsem(&viommu->veventqs_rwsem);
/*
* It is the most likely case that a physical IOMMU is unpluggable. A
* pluggable IOMMU instance (if exists) is responsible for refcounting
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index d7c5ef248474..2aa6a51e05d0 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -564,7 +564,7 @@ static void mpic_reenable_percpu(struct mpic *mpic)
static int mpic_starting_cpu(unsigned int cpu)
{
- struct mpic *mpic = irq_get_default_host()->host_data;
+ struct mpic *mpic = irq_get_default_domain()->host_data;
mpic_perf_init(mpic);
mpic_smp_cpu_init(mpic);
@@ -700,7 +700,7 @@ static void mpic_handle_cascade_irq(struct irq_desc *desc)
static void __exception_irq_entry mpic_handle_irq(struct pt_regs *regs)
{
- struct mpic *mpic = irq_get_default_host()->host_data;
+ struct mpic *mpic = irq_get_default_domain()->host_data;
irq_hw_number_t i;
u32 irqstat;
@@ -880,7 +880,7 @@ static int __init mpic_of_init(struct device_node *node, struct device_node *par
}
if (mpic_is_ipi_available(mpic)) {
- irq_set_default_host(mpic->domain);
+ irq_set_default_domain(mpic->domain);
set_handle_irq(mpic_handle_irq);
#ifdef CONFIG_SMP
err = mpic_ipi_init(mpic, node);
diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c
index 806ebb1de201..48c73c948ddf 100644
--- a/drivers/irqchip/irq-clps711x.c
+++ b/drivers/irqchip/irq-clps711x.c
@@ -191,7 +191,7 @@ static int __init _clps711x_intc_init(struct device_node *np,
goto out_irqfree;
}
- irq_set_default_host(clps711x_intc->domain);
+ irq_set_default_domain(clps711x_intc->domain);
set_handle_irq(clps711x_irqh);
#ifdef CONFIG_FIQ
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index 8a0e82067924..095ae8e3217e 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -247,7 +247,7 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
kfree(cd);
return -ENOMEM;
}
- irq_set_default_host(domain);
+ irq_set_default_domain(domain);
/* Initially mask all interrupts */
for (i = 0; i < IMR_NUM; i++) {
diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c
index eb6ca516a166..b546b1036e12 100644
--- a/drivers/irqchip/irq-pic32-evic.c
+++ b/drivers/irqchip/irq-pic32-evic.c
@@ -291,7 +291,7 @@ static int __init pic32_of_init(struct device_node *node,
gc->private = &priv[i];
}
- irq_set_default_host(evic_irq_domain);
+ irq_set_default_domain(evic_irq_domain);
/*
* External interrupts have software configurable edge polarity. These
diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c
index 7e08714d507f..38727e9cc713 100644
--- a/drivers/irqchip/irq-xilinx-intc.c
+++ b/drivers/irqchip/irq-xilinx-intc.c
@@ -233,7 +233,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
}
} else {
primary_intc = irqc;
- irq_set_default_host(primary_intc->root_domain);
+ irq_set_default_domain(primary_intc->root_domain);
set_handle_irq(xil_intc_handle_irq);
}
diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c
index 7f314e58f3ce..9b441d180299 100644
--- a/drivers/irqchip/irq-xtensa-mx.c
+++ b/drivers/irqchip/irq-xtensa-mx.c
@@ -156,7 +156,7 @@ static void __init xtensa_mx_init_common(struct irq_domain *root_domain)
{
unsigned int i;
- irq_set_default_host(root_domain);
+ irq_set_default_domain(root_domain);
secondary_init_irq();
/* Initialize default IRQ routing to CPU 0 */
diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c
index f9d6fce4da33..9be7b7c5cd23 100644
--- a/drivers/irqchip/irq-xtensa-pic.c
+++ b/drivers/irqchip/irq-xtensa-pic.c
@@ -87,7 +87,7 @@ int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent)
struct irq_domain *root_domain =
irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,
&xtensa_irq_domain_ops, &xtensa_irq_chip);
- irq_set_default_host(root_domain);
+ irq_set_default_domain(root_domain);
return 0;
}
@@ -97,7 +97,7 @@ static int __init xtensa_pic_init(struct device_node *np,
struct irq_domain *root_domain =
irq_domain_add_linear(np, NR_IRQS, &xtensa_irq_domain_ops,
&xtensa_irq_chip);
- irq_set_default_host(root_domain);
+ irq_set_default_domain(root_domain);
return 0;
}
IRQCHIP_DECLARE(xtensa_irq_chip, "cdns,xtensa-pic", xtensa_pic_init);
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 45ff0e198f8f..f6c27ca92c01 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3249,7 +3249,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
spin_unlock_irqrestore(&hc->lock, flags);
__skb_queue_purge(&free_queue);
break;
@@ -3394,7 +3394,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
@@ -4522,7 +4522,7 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
spin_lock_irqsave(&hc->lock, flags);
if (dch->timer.function) {
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
dch->timer.function = NULL;
}
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index ce7bccc9faa3..e3870d942699 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -158,7 +158,7 @@ release_io_hfcpci(struct hfc_pci *hc)
{
/* disable memory mapped ports + busmaster */
pci_write_config_word(hc->pdev, PCI_COMMAND, 0);
- del_timer(&hc->hw.timer);
+ timer_delete(&hc->hw.timer);
dma_free_coherent(&hc->pdev->dev, 0x8000, hc->hw.fifos,
hc->hw.dmahandle);
iounmap(hc->hw.pci_io);
@@ -1087,7 +1087,7 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
break;
case HW_POWERUP_REQ:
Write_hfc(hc, HFCPCI_STATES, HFCPCI_DO_ACTION);
@@ -1216,7 +1216,7 @@ hfcpci_int(int intno, void *dev_id)
receive_dmsg(hc);
if (val & 0x04) { /* D tx */
if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags))
- del_timer(&hc->dch.timer);
+ timer_delete(&hc->dch.timer);
tx_dirq(&hc->dch);
}
spin_unlock(&hc->lock);
@@ -1635,7 +1635,7 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
@@ -2064,7 +2064,7 @@ release_card(struct hfc_pci *hc) {
mode_hfcpci(&hc->bch[0], 1, ISDN_P_NONE);
mode_hfcpci(&hc->bch[1], 2, ISDN_P_NONE);
if (hc->dch.timer.function != NULL) {
- del_timer(&hc->dch.timer);
+ timer_delete(&hc->dch.timer);
hc->dch.timer.function = NULL;
}
spin_unlock_irqrestore(&hc->lock, flags);
@@ -2342,7 +2342,7 @@ HFC_init(void)
err = pci_register_driver(&hfc_driver);
if (err) {
if (timer_pending(&hfc_tl))
- del_timer(&hfc_tl);
+ timer_delete(&hfc_tl);
}
return err;
@@ -2351,7 +2351,7 @@ HFC_init(void)
static void __exit
HFC_cleanup(void)
{
- del_timer_sync(&hfc_tl);
+ timer_delete_sync(&hfc_tl);
pci_unregister_driver(&hfc_driver);
}
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
index d0b7271fbda1..165a63994f04 100644
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -158,7 +158,7 @@ isac_fill_fifo(struct isac_hw *isac)
WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
- del_timer(&isac->dch.timer);
+ timer_delete(&isac->dch.timer);
}
isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&isac->dch.timer);
@@ -206,7 +206,7 @@ static void
isac_xpr_irq(struct isac_hw *isac)
{
if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
- del_timer(&isac->dch.timer);
+ timer_delete(&isac->dch.timer);
if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
isac_fill_fifo(isac);
} else {
@@ -220,7 +220,7 @@ static void
isac_retransmit(struct isac_hw *isac)
{
if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
- del_timer(&isac->dch.timer);
+ timer_delete(&isac->dch.timer);
if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
/* Restart frame */
isac->dch.tx_idx = 0;
@@ -665,7 +665,7 @@ isac_l1cmd(struct dchannel *dch, u32 cmd)
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
break;
case HW_POWERUP_REQ:
spin_lock_irqsave(isac->hwlock, flags);
@@ -698,7 +698,7 @@ isac_release(struct isac_hw *isac)
else if (isac->type != 0)
WriteISAC(isac, ISAC_MASK, 0xff);
if (isac->dch.timer.function != NULL) {
- del_timer(&isac->dch.timer);
+ timer_delete(&isac->dch.timer);
isac->dch.timer.function = NULL;
}
kfree(isac->mon_rx);
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index b3e03c410544..e48f89cbecf8 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -930,7 +930,7 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
/* 1s (200 ms) Flags before data */
if (test_and_set_bit(FLG_FTI_RUN,
&ch->bch.Flags))
- del_timer(&ch->ftimer);
+ timer_delete(&ch->ftimer);
ch->ftimer.expires =
jiffies + ((delay * HZ) / 1000);
test_and_set_bit(FLG_LL_CONN,
@@ -1603,8 +1603,8 @@ free_isar(struct isar_hw *isar)
{
modeisar(&isar->ch[0], ISDN_P_NONE);
modeisar(&isar->ch[1], ISDN_P_NONE);
- del_timer(&isar->ch[0].ftimer);
- del_timer(&isar->ch[1].ftimer);
+ timer_delete(&isar->ch[0].ftimer);
+ timer_delete(&isar->ch[1].ftimer);
test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
}
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index ee69212ac351..da933f4bdf4e 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -294,7 +294,7 @@ W6692_fill_Dfifo(struct w6692_hw *card)
WriteW6692(card, W_D_CMDR, cmd);
if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
}
dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
add_timer(&dch->timer);
@@ -311,7 +311,7 @@ d_retransmit(struct w6692_hw *card)
struct dchannel *dch = &card->dch;
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(dch, D_CLEARBUSY);
@@ -372,7 +372,7 @@ handle_rxD(struct w6692_hw *card) {
static void
handle_txD(struct w6692_hw *card) {
if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags))
- del_timer(&card->dch.timer);
+ timer_delete(&card->dch.timer);
if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) {
W6692_fill_Dfifo(card);
} else {
@@ -1130,7 +1130,7 @@ w6692_l1callback(struct dchannel *dch, u32 cmd)
}
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
- del_timer(&dch->timer);
+ timer_delete(&dch->timer);
break;
case HW_POWERUP_REQ:
spin_lock_irqsave(&card->lock, flags);
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 753232e9fc36..d0aa415a6b09 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -928,7 +928,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
dsp->tone.hardware = 0;
dsp->tone.software = 0;
if (timer_pending(&dsp->tone.tl))
- del_timer(&dsp->tone.tl);
+ timer_delete(&dsp->tone.tl);
if (dsp->conf)
dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be
called here */
@@ -975,7 +975,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
cancel_work_sync(&dsp->workq);
spin_lock_irqsave(&dsp_lock, flags);
if (timer_pending(&dsp->tone.tl))
- del_timer(&dsp->tone.tl);
+ timer_delete(&dsp->tone.tl);
skb_queue_purge(&dsp->sendq);
if (dsp_debug & DEBUG_DSP_CTRL)
printk(KERN_DEBUG "%s: releasing member %s\n",
@@ -1209,7 +1209,7 @@ static void __exit dsp_cleanup(void)
{
mISDN_unregister_Bprotocol(&DSP);
- del_timer_sync(&dsp_spl_tl);
+ timer_delete_sync(&dsp_spl_tl);
if (!list_empty(&dsp_ilist)) {
printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
index 8389e2105cdc..456b313bfa76 100644
--- a/drivers/isdn/mISDN/dsp_tones.c
+++ b/drivers/isdn/mISDN/dsp_tones.c
@@ -505,7 +505,7 @@ dsp_tone(struct dsp *dsp, int tone)
/* we turn off the tone */
if (!tone) {
if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
- del_timer(&tonet->tl);
+ timer_delete(&tonet->tl);
if (dsp->features.hfc_loops)
dsp_tone_hw_message(dsp, NULL, 0);
tonet->tone = 0;
@@ -539,7 +539,7 @@ dsp_tone(struct dsp *dsp, int tone)
dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
/* set timer */
if (timer_pending(&tonet->tl))
- del_timer(&tonet->tl);
+ timer_delete(&tonet->tl);
tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
add_timer(&tonet->tl);
} else {
diff --git a/drivers/isdn/mISDN/fsm.c b/drivers/isdn/mISDN/fsm.c
index 7c5c2ca6c6d8..5ed0a6110687 100644
--- a/drivers/isdn/mISDN/fsm.c
+++ b/drivers/isdn/mISDN/fsm.c
@@ -123,7 +123,7 @@ mISDN_FsmDelTimer(struct FsmTimer *ft, int where)
ft->fi->printdebug(ft->fi, "mISDN_FsmDelTimer %lx %d",
(long) ft, where);
#endif
- del_timer(&ft->tl);
+ timer_delete(&ft->tl);
}
EXPORT_SYMBOL(mISDN_FsmDelTimer);
@@ -167,7 +167,7 @@ mISDN_FsmRestartTimer(struct FsmTimer *ft,
#endif
if (timer_pending(&ft->tl))
- del_timer(&ft->tl);
+ timer_delete(&ft->tl);
ft->event = event;
ft->arg = arg;
ft->tl.expires = jiffies + (millisec * HZ) / 1000;
diff --git a/drivers/leds/flash/leds-rt8515.c b/drivers/leds/flash/leds-rt8515.c
index 6b051f182b72..32ba397a33d2 100644
--- a/drivers/leds/flash/leds-rt8515.c
+++ b/drivers/leds/flash/leds-rt8515.c
@@ -127,7 +127,7 @@ static int rt8515_led_flash_strobe_set(struct led_classdev_flash *fled,
mod_timer(&rt->powerdown_timer,
jiffies + usecs_to_jiffies(timeout->val));
} else {
- del_timer_sync(&rt->powerdown_timer);
+ timer_delete_sync(&rt->powerdown_timer);
/* Turn the LED off */
rt8515_gpio_led_off(rt);
}
@@ -372,7 +372,7 @@ static void rt8515_remove(struct platform_device *pdev)
struct rt8515 *rt = platform_get_drvdata(pdev);
rt8515_v4l2_flash_release(rt);
- del_timer_sync(&rt->powerdown_timer);
+ timer_delete_sync(&rt->powerdown_timer);
mutex_destroy(&rt->lock);
}
diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c
index 3c01739c0b46..48fb8a9ec703 100644
--- a/drivers/leds/flash/leds-sgm3140.c
+++ b/drivers/leds/flash/leds-sgm3140.c
@@ -55,7 +55,7 @@ static int sgm3140_strobe_set(struct led_classdev_flash *fled_cdev, bool state)
mod_timer(&priv->powerdown_timer,
jiffies + usecs_to_jiffies(priv->timeout));
} else {
- del_timer_sync(&priv->powerdown_timer);
+ timer_delete_sync(&priv->powerdown_timer);
gpiod_set_value_cansleep(priv->enable_gpio, 0);
gpiod_set_value_cansleep(priv->flash_gpio, 0);
ret = regulator_disable(priv->vin_regulator);
@@ -117,7 +117,7 @@ static int sgm3140_brightness_set(struct led_classdev *led_cdev,
gpiod_set_value_cansleep(priv->flash_gpio, 0);
gpiod_set_value_cansleep(priv->enable_gpio, 1);
} else {
- del_timer_sync(&priv->powerdown_timer);
+ timer_delete_sync(&priv->powerdown_timer);
gpiod_set_value_cansleep(priv->flash_gpio, 0);
gpiod_set_value_cansleep(priv->enable_gpio, 0);
ret = regulator_disable(priv->vin_regulator);
@@ -285,7 +285,7 @@ static void sgm3140_remove(struct platform_device *pdev)
{
struct sgm3140 *priv = platform_get_drvdata(pdev);
- del_timer_sync(&priv->powerdown_timer);
+ timer_delete_sync(&priv->powerdown_timer);
v4l2_flash_release(priv->v4l2_flash);
}
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index e3d8ddcff567..907fc703e0c5 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -245,7 +245,7 @@ void led_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
- del_timer_sync(&led_cdev->blink_timer);
+ timer_delete_sync(&led_cdev->blink_timer);
clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags);
@@ -294,7 +294,7 @@ EXPORT_SYMBOL_GPL(led_blink_set_nosleep);
void led_stop_software_blink(struct led_classdev *led_cdev)
{
- del_timer_sync(&led_cdev->blink_timer);
+ timer_delete_sync(&led_cdev->blink_timer);
led_cdev->blink_delay_on = 0;
led_cdev->blink_delay_off = 0;
clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c
index a594bd5e2233..06d052957d37 100644
--- a/drivers/leds/trigger/ledtrig-pattern.c
+++ b/drivers/leds/trigger/ledtrig-pattern.c
@@ -94,7 +94,7 @@ static void pattern_trig_timer_cancel(struct pattern_trig_data *data)
if (data->type == PATTERN_TYPE_HR)
hrtimer_cancel(&data->hrtimer);
else
- del_timer_sync(&data->timer);
+ timer_delete_sync(&data->timer);
}
static void pattern_trig_timer_restart(struct pattern_trig_data *data,
diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c
index f111fa7635e5..e103c7ed830b 100644
--- a/drivers/leds/trigger/ledtrig-transient.c
+++ b/drivers/leds/trigger/ledtrig-transient.c
@@ -66,7 +66,7 @@ static ssize_t transient_activate_store(struct device *dev,
/* cancel the running timer */
if (state == 0 && transient_data->activate == 1) {
- del_timer(&transient_data->timer);
+ timer_delete(&transient_data->timer);
transient_data->activate = state;
led_set_brightness_nosleep(led_cdev,
transient_data->restore_state);
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index b2fe7a3dc471..c5aabf238d0a 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -724,7 +724,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
int i;
for (i = 1; i < 16; i++) {
if (adbhid[i])
- del_timer_sync(&adbhid[i]->input->timer);
+ timer_delete_sync(&adbhid[i]->input->timer);
}
}
diff --git a/drivers/mailbox/mailbox-altera.c b/drivers/mailbox/mailbox-altera.c
index afb320e9d69c..748128661892 100644
--- a/drivers/mailbox/mailbox-altera.c
+++ b/drivers/mailbox/mailbox-altera.c
@@ -270,7 +270,7 @@ static void altera_mbox_shutdown(struct mbox_chan *chan)
writel_relaxed(~0, mbox->mbox_base + MAILBOX_INTMASK_REG);
free_irq(mbox->irq, chan);
} else if (!mbox->is_sender) {
- del_timer_sync(&mbox->rxpoll_timer);
+ timer_delete_sync(&mbox->rxpoll_timer);
}
}
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 0b1870a09e1f..06f809e70f15 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -267,6 +267,7 @@ config DM_CRYPT
depends on BLK_DEV_DM
depends on (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n)
depends on (TRUSTED_KEYS || TRUSTED_KEYS=n)
+ select CRC32
select CRYPTO
select CRYPTO_CBC
select CRYPTO_ESSIV
diff --git a/drivers/md/bcache/stats.c b/drivers/md/bcache/stats.c
index 68b02216033d..d39dec34b7a3 100644
--- a/drivers/md/bcache/stats.c
+++ b/drivers/md/bcache/stats.c
@@ -123,7 +123,7 @@ void bch_cache_accounting_destroy(struct cache_accounting *acc)
kobject_put(&acc->day.kobj);
atomic_set(&acc->closing, 1);
- if (del_timer_sync(&acc->timer))
+ if (timer_delete_sync(&acc->timer))
closure_return(&acc->cl);
}
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index aab8240429b0..9c8ed65cd87e 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -2234,7 +2234,7 @@ int dm_bufio_issue_discard(struct dm_bufio_client *c, sector_t block, sector_t c
}
EXPORT_SYMBOL_GPL(dm_bufio_issue_discard);
-static bool forget_buffer(struct dm_bufio_client *c, sector_t block)
+static void forget_buffer(struct dm_bufio_client *c, sector_t block)
{
struct dm_buffer *b;
@@ -2249,8 +2249,6 @@ static bool forget_buffer(struct dm_bufio_client *c, sector_t block)
cache_put_and_wake(c, b);
}
}
-
- return b ? true : false;
}
/*
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 9cb797a561d6..a10d75a562db 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -406,6 +406,12 @@ struct cache {
mempool_t migration_pool;
struct bio_set bs;
+
+ /*
+ * Cache_size entries. Set bits indicate blocks mapped beyond the
+ * target length, which are marked for invalidation.
+ */
+ unsigned long *invalid_bitset;
};
struct per_bio_data {
@@ -1922,6 +1928,9 @@ static void __destroy(struct cache *cache)
if (cache->discard_bitset)
free_bitset(cache->discard_bitset);
+ if (cache->invalid_bitset)
+ free_bitset(cache->invalid_bitset);
+
if (cache->copier)
dm_kcopyd_client_destroy(cache->copier);
@@ -2510,6 +2519,13 @@ static int cache_create(struct cache_args *ca, struct cache **result)
}
clear_bitset(cache->discard_bitset, from_dblock(cache->discard_nr_blocks));
+ cache->invalid_bitset = alloc_bitset(from_cblock(cache->cache_size));
+ if (!cache->invalid_bitset) {
+ *error = "could not allocate bitset for invalid blocks";
+ goto bad;
+ }
+ clear_bitset(cache->invalid_bitset, from_cblock(cache->cache_size));
+
cache->copier = dm_kcopyd_client_create(&dm_kcopyd_throttle);
if (IS_ERR(cache->copier)) {
*error = "could not create kcopyd client";
@@ -2808,6 +2824,24 @@ static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
return policy_load_mapping(cache->policy, oblock, cblock, dirty, hint, hint_valid);
}
+static int load_filtered_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
+ bool dirty, uint32_t hint, bool hint_valid)
+{
+ struct cache *cache = context;
+
+ if (from_oblock(oblock) >= from_oblock(cache->origin_blocks)) {
+ if (dirty) {
+ DMERR("%s: unable to shrink origin; cache block %u is dirty",
+ cache_device_name(cache), from_cblock(cblock));
+ return -EFBIG;
+ }
+ set_bit(from_cblock(cblock), cache->invalid_bitset);
+ return 0;
+ }
+
+ return load_mapping(context, oblock, cblock, dirty, hint, hint_valid);
+}
+
/*
* The discard block size in the on disk metadata is not
* necessarily the same as we're currently using. So we have to
@@ -2899,6 +2933,27 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache)
return to_cblock(size);
}
+static bool can_resume(struct cache *cache)
+{
+ /*
+ * Disallow retrying the resume operation for devices that failed the
+ * first resume attempt, as the failure leaves the policy object partially
+ * initialized. Retrying could trigger BUG_ON when loading cache mappings
+ * into the incomplete policy object.
+ */
+ if (cache->sized && !cache->loaded_mappings) {
+ if (get_cache_mode(cache) != CM_WRITE)
+ DMERR("%s: unable to resume a failed-loaded cache, please check metadata.",
+ cache_device_name(cache));
+ else
+ DMERR("%s: unable to resume cache due to missing proper cache table reload",
+ cache_device_name(cache));
+ return false;
+ }
+
+ return true;
+}
+
static bool can_resize(struct cache *cache, dm_cblock_t new_size)
{
if (from_cblock(new_size) > from_cblock(cache->cache_size)) {
@@ -2941,12 +2996,33 @@ static int resize_cache_dev(struct cache *cache, dm_cblock_t new_size)
return 0;
}
+static int truncate_oblocks(struct cache *cache)
+{
+ uint32_t nr_blocks = from_cblock(cache->cache_size);
+ uint32_t i;
+ int r;
+
+ for_each_set_bit(i, cache->invalid_bitset, nr_blocks) {
+ r = dm_cache_remove_mapping(cache->cmd, to_cblock(i));
+ if (r) {
+ DMERR_LIMIT("%s: invalidation failed; couldn't update on disk metadata",
+ cache_device_name(cache));
+ return r;
+ }
+ }
+
+ return 0;
+}
+
static int cache_preresume(struct dm_target *ti)
{
int r = 0;
struct cache *cache = ti->private;
dm_cblock_t csize = get_cache_dev_size(cache);
+ if (!can_resume(cache))
+ return -EINVAL;
+
/*
* Check to see if the cache has resized.
*/
@@ -2962,11 +3038,25 @@ static int cache_preresume(struct dm_target *ti)
}
if (!cache->loaded_mappings) {
+ /*
+ * The fast device could have been resized since the last
+ * failed preresume attempt. To be safe we start by a blank
+ * bitset for cache blocks.
+ */
+ clear_bitset(cache->invalid_bitset, from_cblock(cache->cache_size));
+
r = dm_cache_load_mappings(cache->cmd, cache->policy,
- load_mapping, cache);
+ load_filtered_mapping, cache);
if (r) {
DMERR("%s: could not load cache mappings", cache_device_name(cache));
- metadata_operation_failed(cache, "dm_cache_load_mappings", r);
+ if (r != -EFBIG)
+ metadata_operation_failed(cache, "dm_cache_load_mappings", r);
+ return r;
+ }
+
+ r = truncate_oblocks(cache);
+ if (r) {
+ metadata_operation_failed(cache, "dm_cache_remove_mapping", r);
return r;
}
@@ -3426,7 +3516,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
static struct target_type cache_target = {
.name = "cache",
- .version = {2, 2, 0},
+ .version = {2, 3, 0},
.module = THIS_MODULE,
.ctr = cache_ctr,
.dtr = cache_dtr,
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 02a2919f4e5a..9dfdb63220d7 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -17,6 +17,7 @@
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/blk-integrity.h>
+#include <linux/crc32.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include <linux/crypto.h>
@@ -125,7 +126,6 @@ struct iv_lmk_private {
#define TCW_WHITENING_SIZE 16
struct iv_tcw_private {
- struct crypto_shash *crc32_tfm;
u8 *iv_seed;
u8 *whitening;
};
@@ -607,10 +607,6 @@ static void crypt_iv_tcw_dtr(struct crypt_config *cc)
tcw->iv_seed = NULL;
kfree_sensitive(tcw->whitening);
tcw->whitening = NULL;
-
- if (tcw->crc32_tfm && !IS_ERR(tcw->crc32_tfm))
- crypto_free_shash(tcw->crc32_tfm);
- tcw->crc32_tfm = NULL;
}
static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti,
@@ -628,13 +624,6 @@ static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti,
return -EINVAL;
}
- tcw->crc32_tfm = crypto_alloc_shash("crc32", 0,
- CRYPTO_ALG_ALLOCATES_MEMORY);
- if (IS_ERR(tcw->crc32_tfm)) {
- ti->error = "Error initializing CRC32 in TCW";
- return PTR_ERR(tcw->crc32_tfm);
- }
-
tcw->iv_seed = kzalloc(cc->iv_size, GFP_KERNEL);
tcw->whitening = kzalloc(TCW_WHITENING_SIZE, GFP_KERNEL);
if (!tcw->iv_seed || !tcw->whitening) {
@@ -668,36 +657,28 @@ static int crypt_iv_tcw_wipe(struct crypt_config *cc)
return 0;
}
-static int crypt_iv_tcw_whitening(struct crypt_config *cc,
- struct dm_crypt_request *dmreq,
- u8 *data)
+static void crypt_iv_tcw_whitening(struct crypt_config *cc,
+ struct dm_crypt_request *dmreq, u8 *data)
{
struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
__le64 sector = cpu_to_le64(dmreq->iv_sector);
u8 buf[TCW_WHITENING_SIZE];
- SHASH_DESC_ON_STACK(desc, tcw->crc32_tfm);
- int i, r;
+ int i;
/* xor whitening with sector number */
crypto_xor_cpy(buf, tcw->whitening, (u8 *)&sector, 8);
crypto_xor_cpy(&buf[8], tcw->whitening + 8, (u8 *)&sector, 8);
/* calculate crc32 for every 32bit part and xor it */
- desc->tfm = tcw->crc32_tfm;
- for (i = 0; i < 4; i++) {
- r = crypto_shash_digest(desc, &buf[i * 4], 4, &buf[i * 4]);
- if (r)
- goto out;
- }
+ for (i = 0; i < 4; i++)
+ put_unaligned_le32(crc32(0, &buf[i * 4], 4), &buf[i * 4]);
crypto_xor(&buf[0], &buf[12], 4);
crypto_xor(&buf[4], &buf[8], 4);
/* apply whitening (8 bytes) to whole sector */
for (i = 0; i < ((1 << SECTOR_SHIFT) / 8); i++)
crypto_xor(data + i * 8, buf, 8);
-out:
memzero_explicit(buf, sizeof(buf));
- return r;
}
static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
@@ -707,13 +688,12 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
__le64 sector = cpu_to_le64(dmreq->iv_sector);
u8 *src;
- int r = 0;
/* Remove whitening from ciphertext */
if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) {
sg = crypt_get_sg_data(cc, dmreq->sg_in);
src = kmap_local_page(sg_page(sg));
- r = crypt_iv_tcw_whitening(cc, dmreq, src + sg->offset);
+ crypt_iv_tcw_whitening(cc, dmreq, src + sg->offset);
kunmap_local(src);
}
@@ -723,7 +703,7 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
crypto_xor_cpy(&iv[8], tcw->iv_seed + 8, (u8 *)&sector,
cc->iv_size - 8);
- return r;
+ return 0;
}
static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
@@ -731,7 +711,6 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
{
struct scatterlist *sg;
u8 *dst;
- int r;
if (bio_data_dir(dmreq->ctx->bio_in) != WRITE)
return 0;
@@ -739,10 +718,10 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
/* Apply whitening on ciphertext */
sg = crypt_get_sg_data(cc, dmreq->sg_out);
dst = kmap_local_page(sg_page(sg));
- r = crypt_iv_tcw_whitening(cc, dmreq, dst + sg->offset);
+ crypt_iv_tcw_whitening(cc, dmreq, dst + sg->offset);
kunmap_local(dst);
- return r;
+ return 0;
}
static int crypt_iv_random_gen(struct crypt_config *cc, u8 *iv,
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index 08f6387620c1..d4cf0ac2a7aa 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -369,6 +369,21 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
return delay_bio(dc, c, bio);
}
+#ifdef CONFIG_BLK_DEV_ZONED
+static int delay_report_zones(struct dm_target *ti,
+ struct dm_report_zones_args *args, unsigned int nr_zones)
+{
+ struct delay_c *dc = ti->private;
+ struct delay_class *c = &dc->read;
+
+ return dm_report_zones(c->dev->bdev, c->start,
+ c->start + dm_target_offset(ti, args->next_sector),
+ args, nr_zones);
+}
+#else
+#define delay_report_zones NULL
+#endif
+
#define DMEMIT_DELAY_CLASS(c) \
DMEMIT("%s %llu %u", (c)->dev->name, (unsigned long long)(c)->start, (c)->delay)
@@ -424,11 +439,12 @@ out:
static struct target_type delay_target = {
.name = "delay",
.version = {1, 4, 0},
- .features = DM_TARGET_PASSES_INTEGRITY,
+ .features = DM_TARGET_PASSES_INTEGRITY | DM_TARGET_ZONED_HM,
.module = THIS_MODULE,
.ctr = delay_ctr,
.dtr = delay_dtr,
.map = delay_map,
+ .report_zones = delay_report_zones,
.presuspend = delay_presuspend,
.resume = delay_resume,
.status = delay_status,
diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c
index 18ae45dcbfb2..b19b0142a690 100644
--- a/drivers/md/dm-ebs-target.c
+++ b/drivers/md/dm-ebs-target.c
@@ -390,6 +390,12 @@ static int ebs_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED;
}
+static void ebs_postsuspend(struct dm_target *ti)
+{
+ struct ebs_c *ec = ti->private;
+ dm_bufio_client_reset(ec->bufio);
+}
+
static void ebs_status(struct dm_target *ti, status_type_t type,
unsigned int status_flags, char *result, unsigned int maxlen)
{
@@ -447,6 +453,7 @@ static struct target_type ebs_target = {
.ctr = ebs_ctr,
.dtr = ebs_dtr,
.map = ebs_map,
+ .postsuspend = ebs_postsuspend,
.status = ebs_status,
.io_hints = ebs_io_hints,
.prepare_ioctl = ebs_prepare_ioctl,
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index c8c1a00e7d80..2a283feb3319 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -21,6 +21,7 @@
#include <linux/reboot.h>
#include <crypto/hash.h>
#include <crypto/skcipher.h>
+#include <crypto/utils.h>
#include <linux/async_tx.h>
#include <linux/dm-bufio.h>
@@ -516,7 +517,7 @@ static int sb_mac(struct dm_integrity_c *ic, bool wr)
dm_integrity_io_error(ic, "crypto_shash_digest", r);
return r;
}
- if (memcmp(mac, actual_mac, mac_size)) {
+ if (crypto_memneq(mac, actual_mac, mac_size)) {
dm_integrity_io_error(ic, "superblock mac", -EILSEQ);
dm_audit_log_target(DM_MSG_PREFIX, "mac-superblock", ic->ti, 0);
return -EILSEQ;
@@ -859,7 +860,7 @@ static void rw_section_mac(struct dm_integrity_c *ic, unsigned int section, bool
if (likely(wr))
memcpy(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR);
else {
- if (memcmp(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR)) {
+ if (crypto_memneq(&js->mac, result + (j * JOURNAL_MAC_PER_SECTOR), JOURNAL_MAC_PER_SECTOR)) {
dm_integrity_io_error(ic, "journal mac", -EILSEQ);
dm_audit_log_target(DM_MSG_PREFIX, "mac-journal", ic->ti, 0);
}
@@ -1401,10 +1402,9 @@ static bool find_newer_committed_node(struct dm_integrity_c *ic, struct journal_
static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, sector_t *metadata_block,
unsigned int *metadata_offset, unsigned int total_size, int op)
{
-#define MAY_BE_FILLER 1
-#define MAY_BE_HASH 2
unsigned int hash_offset = 0;
- unsigned int may_be = MAY_BE_HASH | (ic->discard ? MAY_BE_FILLER : 0);
+ unsigned char mismatch_hash = 0;
+ unsigned char mismatch_filler = !ic->discard;
do {
unsigned char *data, *dp;
@@ -1425,7 +1425,7 @@ static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, se
if (op == TAG_READ) {
memcpy(tag, dp, to_copy);
} else if (op == TAG_WRITE) {
- if (memcmp(dp, tag, to_copy)) {
+ if (crypto_memneq(dp, tag, to_copy)) {
memcpy(dp, tag, to_copy);
dm_bufio_mark_partial_buffer_dirty(b, *metadata_offset, *metadata_offset + to_copy);
}
@@ -1433,29 +1433,30 @@ static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, se
/* e.g.: op == TAG_CMP */
if (likely(is_power_of_2(ic->tag_size))) {
- if (unlikely(memcmp(dp, tag, to_copy)))
- if (unlikely(!ic->discard) ||
- unlikely(memchr_inv(dp, DISCARD_FILLER, to_copy) != NULL)) {
- goto thorough_test;
- }
+ if (unlikely(crypto_memneq(dp, tag, to_copy)))
+ goto thorough_test;
} else {
unsigned int i, ts;
thorough_test:
ts = total_size;
for (i = 0; i < to_copy; i++, ts--) {
- if (unlikely(dp[i] != tag[i]))
- may_be &= ~MAY_BE_HASH;
- if (likely(dp[i] != DISCARD_FILLER))
- may_be &= ~MAY_BE_FILLER;
+ /*
+ * Warning: the control flow must not be
+ * dependent on match/mismatch of
+ * individual bytes.
+ */
+ mismatch_hash |= dp[i] ^ tag[i];
+ mismatch_filler |= dp[i] ^ DISCARD_FILLER;
hash_offset++;
if (unlikely(hash_offset == ic->tag_size)) {
- if (unlikely(!may_be)) {
+ if (unlikely(mismatch_hash) && unlikely(mismatch_filler)) {
dm_bufio_release(b);
return ts;
}
hash_offset = 0;
- may_be = MAY_BE_HASH | (ic->discard ? MAY_BE_FILLER : 0);
+ mismatch_hash = 0;
+ mismatch_filler = !ic->discard;
}
}
}
@@ -1476,8 +1477,6 @@ thorough_test:
} while (unlikely(total_size));
return 0;
-#undef MAY_BE_FILLER
-#undef MAY_BE_HASH
}
struct flush_request {
@@ -2076,7 +2075,7 @@ retry_kmap:
char checksums_onstack[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)];
integrity_sector_checksum(ic, logical_sector, mem + bv.bv_offset, checksums_onstack);
- if (unlikely(memcmp(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) {
+ if (unlikely(crypto_memneq(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) {
DMERR_LIMIT("Checksum failed when reading from journal, at sector 0x%llx",
logical_sector);
dm_audit_log_bio(DM_MSG_PREFIX, "journal-checksum",
@@ -2595,7 +2594,7 @@ static void dm_integrity_inline_recheck(struct work_struct *w)
bio_put(outgoing_bio);
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, outgoing_data, digest);
- if (unlikely(memcmp(digest, dio->integrity_payload, min(crypto_shash_digestsize(ic->internal_hash), ic->tag_size)))) {
+ if (unlikely(crypto_memneq(digest, dio->integrity_payload, min(crypto_shash_digestsize(ic->internal_hash), ic->tag_size)))) {
DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx",
ic->dev->bdev, dio->bio_details.bi_iter.bi_sector);
atomic64_inc(&ic->number_of_mismatches);
@@ -2634,7 +2633,7 @@ static int dm_integrity_end_io(struct dm_target *ti, struct bio *bio, blk_status
char *mem = bvec_kmap_local(&bv);
//memset(mem, 0xff, ic->sectors_per_block << SECTOR_SHIFT);
integrity_sector_checksum(ic, dio->bio_details.bi_iter.bi_sector, mem, digest);
- if (unlikely(memcmp(digest, dio->integrity_payload + pos,
+ if (unlikely(crypto_memneq(digest, dio->integrity_payload + pos,
min(crypto_shash_digestsize(ic->internal_hash), ic->tag_size)))) {
kunmap_local(mem);
dm_integrity_free_payload(dio);
@@ -2708,7 +2707,7 @@ static void integrity_commit(struct work_struct *w)
unsigned int i, j, n;
struct bio *flushes;
- del_timer(&ic->autocommit_timer);
+ timer_delete(&ic->autocommit_timer);
if (ic->mode == 'I')
return;
@@ -2911,7 +2910,7 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned int write_start
integrity_sector_checksum(ic, sec + ((l - j) << ic->sb->log2_sectors_per_block),
(char *)access_journal_data(ic, i, l), test_tag);
- if (unlikely(memcmp(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) {
+ if (unlikely(crypto_memneq(test_tag, journal_entry_tag(ic, je2), ic->tag_size))) {
dm_integrity_io_error(ic, "tag mismatch when replaying journal", -EILSEQ);
dm_audit_log_target(DM_MSG_PREFIX, "integrity-replay-journal", ic->ti, 0);
}
@@ -3607,7 +3606,7 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
WARN_ON(unregister_reboot_notifier(&ic->reboot_notifier));
- del_timer_sync(&ic->autocommit_timer);
+ timer_delete_sync(&ic->autocommit_timer);
if (ic->recalc_wq)
drain_workqueue(ic->recalc_wq);
@@ -5072,16 +5071,19 @@ try_smaller_buffer:
ic->recalc_bitmap = dm_integrity_alloc_page_list(n_bitmap_pages);
if (!ic->recalc_bitmap) {
+ ti->error = "Could not allocate memory for bitmap";
r = -ENOMEM;
goto bad;
}
ic->may_write_bitmap = dm_integrity_alloc_page_list(n_bitmap_pages);
if (!ic->may_write_bitmap) {
+ ti->error = "Could not allocate memory for bitmap";
r = -ENOMEM;
goto bad;
}
ic->bbs = kvmalloc_array(ic->n_bitmap_blocks, sizeof(struct bitmap_block_status), GFP_KERNEL);
if (!ic->bbs) {
+ ti->error = "Could not allocate memory for bitmap";
r = -ENOMEM;
goto bad;
}
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 637977acc3dc..6c98f4ae5ea9 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -815,7 +815,7 @@ static void enable_nopath_timeout(struct multipath *m)
static void disable_nopath_timeout(struct multipath *m)
{
- del_timer_sync(&m->nopath_timer);
+ timer_delete_sync(&m->nopath_timer);
}
/*
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 8c6f1f7e6456..9e615b4f1f5e 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1182,7 +1182,7 @@ static void mirror_dtr(struct dm_target *ti)
{
struct mirror_set *ms = ti->private;
- del_timer_sync(&ms->timer);
+ timer_delete_sync(&ms->timer);
flush_workqueue(ms->kmirrord_wq);
flush_work(&ms->trigger_event);
dm_kcopyd_client_destroy(ms->kcopyd_client);
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 3786ac67cefe..a1b7535c508a 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -467,7 +467,7 @@ static struct target_type stripe_target = {
.name = "striped",
.version = {1, 7, 0},
.features = DM_TARGET_PASSES_INTEGRITY | DM_TARGET_NOWAIT |
- DM_TARGET_ATOMIC_WRITES,
+ DM_TARGET_ATOMIC_WRITES | DM_TARGET_PASSES_CRYPTO,
.module = THIS_MODULE,
.ctr = stripe_ctr,
.dtr = stripe_dtr,
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 453803f1edf5..35100a435c88 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -697,6 +697,10 @@ int dm_table_add_target(struct dm_table *t, const char *type,
DMERR("%s: zero-length target", dm_device_name(t->md));
return -EINVAL;
}
+ if (start + len < start || start + len > LLONG_MAX >> SECTOR_SHIFT) {
+ DMERR("%s: too large device", dm_device_name(t->md));
+ return -EINVAL;
+ }
ti->type = dm_get_target_type(type);
if (!ti->type) {
diff --git a/drivers/md/dm-vdo/block-map.c b/drivers/md/dm-vdo/block-map.c
index 89cb7942ec5c..baf683cabb1b 100644
--- a/drivers/md/dm-vdo/block-map.c
+++ b/drivers/md/dm-vdo/block-map.c
@@ -451,7 +451,7 @@ static struct page_info * __must_check find_page(struct vdo_page_cache *cache,
* select_lru_page() - Determine which page is least recently used.
*
* Picks the least recently used from among the non-busy entries at the front of each of the lru
- * ring. Since whenever we mark a page busy we also put it to the end of the ring it is unlikely
+ * list. Since whenever we mark a page busy we also put it to the end of the list it is unlikely
* that the entries at the front are busy unless the queue is very short, but not impossible.
*
* Return: A pointer to the info structure for a relevant page, or NULL if no such page can be
@@ -1544,7 +1544,7 @@ static void write_page_if_not_dirtied(struct vdo_waiter *waiter, void *context)
static void return_to_pool(struct block_map_zone *zone, struct pooled_vio *vio)
{
- return_vio_to_pool(zone->vio_pool, vio);
+ return_vio_to_pool(vio);
check_for_drain_complete(zone);
}
@@ -1837,7 +1837,7 @@ static void finish_block_map_page_load(struct vdo_completion *completion)
if (!vdo_copy_valid_page(vio->data, nonce, pbn, page))
vdo_format_block_map_page(page, nonce, pbn, false);
- return_vio_to_pool(zone->vio_pool, pooled);
+ return_vio_to_pool(pooled);
/* Release our claim to the load and wake any waiters */
release_page_lock(data_vio, "load");
@@ -1851,10 +1851,9 @@ static void handle_io_error(struct vdo_completion *completion)
struct vio *vio = as_vio(completion);
struct pooled_vio *pooled = container_of(vio, struct pooled_vio, vio);
struct data_vio *data_vio = completion->parent;
- struct block_map_zone *zone = pooled->context;
vio_record_metadata_io_error(vio);
- return_vio_to_pool(zone->vio_pool, pooled);
+ return_vio_to_pool(pooled);
abort_load(data_vio, result);
}
@@ -2499,7 +2498,7 @@ static void finish_cursor(struct cursor *cursor)
struct cursors *cursors = cursor->parent;
struct vdo_completion *completion = cursors->completion;
- return_vio_to_pool(cursors->pool, vdo_forget(cursor->vio));
+ return_vio_to_pool(vdo_forget(cursor->vio));
if (--cursors->active_roots > 0)
return;
@@ -2746,7 +2745,7 @@ static int __must_check initialize_block_map_zone(struct block_map *map,
if (result != VDO_SUCCESS)
return result;
- result = make_vio_pool(vdo, BLOCK_MAP_VIO_POOL_SIZE,
+ result = make_vio_pool(vdo, BLOCK_MAP_VIO_POOL_SIZE, 1,
zone->thread_id, VIO_TYPE_BLOCK_MAP_INTERIOR,
VIO_PRIORITY_METADATA, zone, &zone->vio_pool);
if (result != VDO_SUCCESS)
diff --git a/drivers/md/dm-vdo/constants.h b/drivers/md/dm-vdo/constants.h
index a8c4d6e24b38..2a8b03779f87 100644
--- a/drivers/md/dm-vdo/constants.h
+++ b/drivers/md/dm-vdo/constants.h
@@ -44,9 +44,6 @@ enum {
/* The default size of each slab journal, in blocks */
DEFAULT_VDO_SLAB_JOURNAL_SIZE = 224,
- /* Unit test minimum */
- MINIMUM_VDO_SLAB_JOURNAL_BLOCKS = 2,
-
/*
* The initial size of lbn_operations and pbn_operations, which is based upon the expected
* maximum number of outstanding VIOs. This value was chosen to make it highly unlikely
diff --git a/drivers/md/dm-vdo/dedupe.c b/drivers/md/dm-vdo/dedupe.c
index 3f3d29af1be4..3c58b941e067 100644
--- a/drivers/md/dm-vdo/dedupe.c
+++ b/drivers/md/dm-vdo/dedupe.c
@@ -226,7 +226,7 @@ struct hash_lock {
* A list containing the data VIOs sharing this lock, all having the same record name and
* data block contents, linked by their hash_lock_node fields.
*/
- struct list_head duplicate_ring;
+ struct list_head duplicate_vios;
/* The number of data_vios sharing this lock instance */
data_vio_count_t reference_count;
@@ -343,7 +343,7 @@ static void return_hash_lock_to_pool(struct hash_zone *zone, struct hash_lock *l
{
memset(lock, 0, sizeof(*lock));
INIT_LIST_HEAD(&lock->pool_node);
- INIT_LIST_HEAD(&lock->duplicate_ring);
+ INIT_LIST_HEAD(&lock->duplicate_vios);
vdo_waitq_init(&lock->waiters);
list_add_tail(&lock->pool_node, &zone->lock_pool);
}
@@ -441,7 +441,7 @@ static void set_hash_lock(struct data_vio *data_vio, struct hash_lock *new_lock)
VDO_ASSERT_LOG_ONLY(data_vio->hash_zone != NULL,
"must have a hash zone when holding a hash lock");
VDO_ASSERT_LOG_ONLY(!list_empty(&data_vio->hash_lock_entry),
- "must be on a hash lock ring when holding a hash lock");
+ "must be on a hash lock list when holding a hash lock");
VDO_ASSERT_LOG_ONLY(old_lock->reference_count > 0,
"hash lock reference must be counted");
@@ -464,10 +464,10 @@ static void set_hash_lock(struct data_vio *data_vio, struct hash_lock *new_lock)
if (new_lock != NULL) {
/*
- * Keep all data_vios sharing the lock on a ring since they can complete in any
+ * Keep all data_vios sharing the lock on a list since they can complete in any
* order and we'll always need a pointer to one to compare data.
*/
- list_move_tail(&data_vio->hash_lock_entry, &new_lock->duplicate_ring);
+ list_move_tail(&data_vio->hash_lock_entry, &new_lock->duplicate_vios);
new_lock->reference_count += 1;
if (new_lock->max_references < new_lock->reference_count)
new_lock->max_references = new_lock->reference_count;
@@ -1789,10 +1789,10 @@ static bool is_hash_collision(struct hash_lock *lock, struct data_vio *candidate
struct hash_zone *zone;
bool collides;
- if (list_empty(&lock->duplicate_ring))
+ if (list_empty(&lock->duplicate_vios))
return false;
- lock_holder = list_first_entry(&lock->duplicate_ring, struct data_vio,
+ lock_holder = list_first_entry(&lock->duplicate_vios, struct data_vio,
hash_lock_entry);
zone = candidate->hash_zone;
collides = !blocks_equal(lock_holder->vio.data, candidate->vio.data);
@@ -1815,7 +1815,7 @@ static inline int assert_hash_lock_preconditions(const struct data_vio *data_vio
return result;
result = VDO_ASSERT(list_empty(&data_vio->hash_lock_entry),
- "must not already be a member of a hash lock ring");
+ "must not already be a member of a hash lock list");
if (result != VDO_SUCCESS)
return result;
@@ -1942,8 +1942,8 @@ void vdo_release_hash_lock(struct data_vio *data_vio)
"returned hash lock must not be in use with state %s",
get_hash_lock_state_name(lock->state));
VDO_ASSERT_LOG_ONLY(list_empty(&lock->pool_node),
- "hash lock returned to zone must not be in a pool ring");
- VDO_ASSERT_LOG_ONLY(list_empty(&lock->duplicate_ring),
+ "hash lock returned to zone must not be in a pool list");
+ VDO_ASSERT_LOG_ONLY(list_empty(&lock->duplicate_vios),
"hash lock returned to zone must not reference DataVIOs");
return_hash_lock_to_pool(zone, lock);
@@ -2261,7 +2261,7 @@ static void check_for_drain_complete(struct hash_zone *zone)
if ((atomic_read(&zone->timer_state) == DEDUPE_QUERY_TIMER_IDLE) ||
change_timer_state(zone, DEDUPE_QUERY_TIMER_RUNNING,
DEDUPE_QUERY_TIMER_IDLE)) {
- del_timer_sync(&zone->timer);
+ timer_delete_sync(&zone->timer);
} else {
/*
* There is an in flight time-out, which must get processed before we can continue.
diff --git a/drivers/md/dm-vdo/encodings.c b/drivers/md/dm-vdo/encodings.c
index 100e92f8f866..b7cc0f41caca 100644
--- a/drivers/md/dm-vdo/encodings.c
+++ b/drivers/md/dm-vdo/encodings.c
@@ -711,24 +711,11 @@ int vdo_configure_slab(block_count_t slab_size, block_count_t slab_journal_block
ref_blocks = vdo_get_saved_reference_count_size(slab_size - slab_journal_blocks);
meta_blocks = (ref_blocks + slab_journal_blocks);
- /* Make sure test code hasn't configured slabs to be too small. */
+ /* Make sure configured slabs are not too small. */
if (meta_blocks >= slab_size)
return VDO_BAD_CONFIGURATION;
- /*
- * If the slab size is very small, assume this must be a unit test and override the number
- * of data blocks to be a power of two (wasting blocks in the slab). Many tests need their
- * data_blocks fields to be the exact capacity of the configured volume, and that used to
- * fall out since they use a power of two for the number of data blocks, the slab size was
- * a power of two, and every block in a slab was a data block.
- *
- * TODO: Try to figure out some way of structuring testParameters and unit tests so this
- * hack isn't needed without having to edit several unit tests every time the metadata size
- * changes by one block.
- */
data_blocks = slab_size - meta_blocks;
- if ((slab_size < 1024) && !is_power_of_2(data_blocks))
- data_blocks = ((block_count_t) 1 << ilog2(data_blocks));
/*
* Configure the slab journal thresholds. The flush threshold is 168 of 224 blocks in
@@ -1221,11 +1208,6 @@ int vdo_validate_config(const struct vdo_config *config,
if (result != VDO_SUCCESS)
return result;
- result = VDO_ASSERT(config->slab_journal_blocks >= MINIMUM_VDO_SLAB_JOURNAL_BLOCKS,
- "slab journal size meets minimum size");
- if (result != VDO_SUCCESS)
- return result;
-
result = VDO_ASSERT(config->slab_journal_blocks <= config->slab_size,
"slab journal size is within expected bound");
if (result != VDO_SUCCESS)
diff --git a/drivers/md/dm-vdo/indexer/index-layout.c b/drivers/md/dm-vdo/indexer/index-layout.c
index af8fab83b0f3..61edf2b72427 100644
--- a/drivers/md/dm-vdo/indexer/index-layout.c
+++ b/drivers/md/dm-vdo/indexer/index-layout.c
@@ -54,7 +54,6 @@
* Each save also has a unique nonce.
*/
-#define MAGIC_SIZE 32
#define NONCE_INFO_SIZE 32
#define MAX_SAVES 2
@@ -98,9 +97,11 @@ enum region_type {
#define SUPER_VERSION_CURRENT 3
#define SUPER_VERSION_MAXIMUM 7
-static const u8 LAYOUT_MAGIC[MAGIC_SIZE] = "*ALBIREO*SINGLE*FILE*LAYOUT*001*";
+static const u8 LAYOUT_MAGIC[] = "*ALBIREO*SINGLE*FILE*LAYOUT*001*";
static const u64 REGION_MAGIC = 0x416c6252676e3031; /* 'AlbRgn01' */
+#define MAGIC_SIZE (sizeof(LAYOUT_MAGIC) - 1)
+
struct region_header {
u64 magic;
u64 region_blocks;
diff --git a/drivers/md/dm-vdo/indexer/index-session.c b/drivers/md/dm-vdo/indexer/index-session.c
index aee0914d604a..aa575a24e0b2 100644
--- a/drivers/md/dm-vdo/indexer/index-session.c
+++ b/drivers/md/dm-vdo/indexer/index-session.c
@@ -100,7 +100,6 @@ static int get_index_session(struct uds_index_session *index_session)
int uds_launch_request(struct uds_request *request)
{
- size_t internal_size;
int result;
if (request->callback == NULL) {
@@ -121,10 +120,7 @@ int uds_launch_request(struct uds_request *request)
}
/* Reset all internal fields before processing. */
- internal_size =
- sizeof(struct uds_request) - offsetof(struct uds_request, zone_number);
- // FIXME should be using struct_group for this instead
- memset((char *) request + sizeof(*request) - internal_size, 0, internal_size);
+ memset(&request->internal, 0, sizeof(request->internal));
result = get_index_session(request->session);
if (result != UDS_SUCCESS)
diff --git a/drivers/md/dm-vdo/indexer/indexer.h b/drivers/md/dm-vdo/indexer/indexer.h
index 183a94eb7e92..7c1fc4577f5b 100644
--- a/drivers/md/dm-vdo/indexer/indexer.h
+++ b/drivers/md/dm-vdo/indexer/indexer.h
@@ -8,6 +8,7 @@
#include <linux/mutex.h>
#include <linux/sched.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/wait.h>
@@ -73,7 +74,7 @@ enum uds_request_type {
/* Remove any mapping for a name. */
UDS_DELETE,
-};
+} __packed;
enum uds_open_index_type {
/* Create a new index. */
@@ -226,7 +227,7 @@ struct uds_zone_message {
enum uds_zone_message_type type;
/* The virtual chapter number to which the message applies */
u64 virtual_chapter;
-};
+} __packed;
struct uds_index_session;
struct uds_index;
@@ -253,34 +254,32 @@ struct uds_request {
/* The existing data associated with the request name, if any */
struct uds_record_data old_metadata;
- /* Either UDS_SUCCESS or an error code for the request */
- int status;
/* True if the record name had an existing entry in the index */
bool found;
+ /* Either UDS_SUCCESS or an error code for the request */
+ int status;
- /*
- * The remaining fields are used internally and should not be altered by clients. The index
- * relies on zone_number being the first field in this section.
- */
-
- /* The number of the zone which will process this request*/
- unsigned int zone_number;
- /* A link for adding a request to a lock-free queue */
- struct funnel_queue_entry queue_link;
- /* A link for adding a request to a standard linked list */
- struct uds_request *next_request;
- /* A pointer to the index processing this request */
- struct uds_index *index;
- /* Control message for coordinating between zones */
- struct uds_zone_message zone_message;
- /* If true, process request immediately by waking the worker thread */
- bool unbatched;
- /* If true, continue this request before processing newer requests */
- bool requeued;
- /* The virtual chapter containing the record name, if known */
- u64 virtual_chapter;
- /* The region of the index containing the record name */
- enum uds_index_region location;
+ /* The remaining fields are used internally and should not be altered by clients. */
+ struct_group(internal,
+ /* The virtual chapter containing the record name, if known */
+ u64 virtual_chapter;
+ /* The region of the index containing the record name */
+ enum uds_index_region location;
+ /* If true, process request immediately by waking the worker thread */
+ bool unbatched;
+ /* If true, continue this request before processing newer requests */
+ bool requeued;
+ /* Control message for coordinating between zones */
+ struct uds_zone_message zone_message;
+ /* The number of the zone which will process this request*/
+ unsigned int zone_number;
+ /* A link for adding a request to a lock-free queue */
+ struct funnel_queue_entry queue_link;
+ /* A link for adding a request to a standard linked list */
+ struct uds_request *next_request;
+ /* A pointer to the index processing this request */
+ struct uds_index *index;
+ );
};
/* A session is required for most index operations. */
diff --git a/drivers/md/dm-vdo/io-submitter.c b/drivers/md/dm-vdo/io-submitter.c
index 421e5436c32c..11d47770b54d 100644
--- a/drivers/md/dm-vdo/io-submitter.c
+++ b/drivers/md/dm-vdo/io-submitter.c
@@ -327,6 +327,7 @@ void vdo_submit_data_vio(struct data_vio *data_vio)
* @error_handler: the handler for submission or I/O errors (may be NULL)
* @operation: the type of I/O to perform
* @data: the buffer to read or write (may be NULL)
+ * @size: the I/O amount in bytes
*
* The vio is enqueued on a vdo bio queue so that bio submission (which may block) does not block
* other vdo threads.
@@ -338,7 +339,7 @@ void vdo_submit_data_vio(struct data_vio *data_vio)
*/
void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical,
bio_end_io_t callback, vdo_action_fn error_handler,
- blk_opf_t operation, char *data)
+ blk_opf_t operation, char *data, int size)
{
int result;
struct vdo_completion *completion = &vio->completion;
@@ -349,7 +350,8 @@ void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical,
vdo_reset_completion(completion);
completion->error_handler = error_handler;
- result = vio_reset_bio(vio, data, callback, operation | REQ_META, physical);
+ result = vio_reset_bio_with_size(vio, data, size, callback, operation | REQ_META,
+ physical);
if (result != VDO_SUCCESS) {
continue_vio(vio, result);
return;
diff --git a/drivers/md/dm-vdo/io-submitter.h b/drivers/md/dm-vdo/io-submitter.h
index 80748699496f..3088f11055fd 100644
--- a/drivers/md/dm-vdo/io-submitter.h
+++ b/drivers/md/dm-vdo/io-submitter.h
@@ -8,6 +8,7 @@
#include <linux/bio.h>
+#include "constants.h"
#include "types.h"
struct io_submitter;
@@ -26,14 +27,25 @@ void vdo_submit_data_vio(struct data_vio *data_vio);
void __submit_metadata_vio(struct vio *vio, physical_block_number_t physical,
bio_end_io_t callback, vdo_action_fn error_handler,
- blk_opf_t operation, char *data);
+ blk_opf_t operation, char *data, int size);
static inline void vdo_submit_metadata_vio(struct vio *vio, physical_block_number_t physical,
bio_end_io_t callback, vdo_action_fn error_handler,
blk_opf_t operation)
{
__submit_metadata_vio(vio, physical, callback, error_handler,
- operation, vio->data);
+ operation, vio->data, vio->block_count * VDO_BLOCK_SIZE);
+}
+
+static inline void vdo_submit_metadata_vio_with_size(struct vio *vio,
+ physical_block_number_t physical,
+ bio_end_io_t callback,
+ vdo_action_fn error_handler,
+ blk_opf_t operation,
+ int size)
+{
+ __submit_metadata_vio(vio, physical, callback, error_handler,
+ operation, vio->data, size);
}
static inline void vdo_submit_flush_vio(struct vio *vio, bio_end_io_t callback,
@@ -41,7 +53,7 @@ static inline void vdo_submit_flush_vio(struct vio *vio, bio_end_io_t callback,
{
/* FIXME: Can we just use REQ_OP_FLUSH? */
__submit_metadata_vio(vio, 0, callback, error_handler,
- REQ_OP_WRITE | REQ_PREFLUSH, NULL);
+ REQ_OP_WRITE | REQ_PREFLUSH, NULL, 0);
}
#endif /* VDO_IO_SUBMITTER_H */
diff --git a/drivers/md/dm-vdo/packer.h b/drivers/md/dm-vdo/packer.h
index 0f3be44710b5..8c8d6892582d 100644
--- a/drivers/md/dm-vdo/packer.h
+++ b/drivers/md/dm-vdo/packer.h
@@ -46,7 +46,7 @@ struct compressed_block {
/*
* Each packer_bin holds an incomplete batch of data_vios that only partially fill a compressed
- * block. The bins are kept in a ring sorted by the amount of unused space so the first bin with
+ * block. The bins are kept in a list sorted by the amount of unused space so the first bin with
* enough space to hold a newly-compressed data_vio can easily be found. When the bin fills up or
* is flushed, the first uncanceled data_vio in the bin is selected to be the agent for that bin.
* Upon entering the packer, each data_vio already has its compressed data in the first slot of the
diff --git a/drivers/md/dm-vdo/priority-table.c b/drivers/md/dm-vdo/priority-table.c
index 42d3d8d0e4b5..9bae8256ba4e 100644
--- a/drivers/md/dm-vdo/priority-table.c
+++ b/drivers/md/dm-vdo/priority-table.c
@@ -199,7 +199,7 @@ void vdo_priority_table_remove(struct priority_table *table, struct list_head *e
/*
* Remove the entry from the bucket list, remembering a pointer to another entry in the
- * ring.
+ * list.
*/
next_entry = entry->next;
list_del_init(entry);
diff --git a/drivers/md/dm-vdo/recovery-journal.h b/drivers/md/dm-vdo/recovery-journal.h
index 899071173015..25e7ec6d19f6 100644
--- a/drivers/md/dm-vdo/recovery-journal.h
+++ b/drivers/md/dm-vdo/recovery-journal.h
@@ -43,9 +43,9 @@
* has a vio which is used to commit that block to disk. The vio's data is the on-disk
* representation of the journal block. In addition each in-memory block has a buffer which is used
* to accumulate entries while a partial commit of the block is in progress. In-memory blocks are
- * kept on two rings. Free blocks live on the 'free_tail_blocks' ring. When a block becomes active
- * (see below) it is moved to the 'active_tail_blocks' ring. When a block is fully committed, it is
- * moved back to the 'free_tail_blocks' ring.
+ * kept on two lists. Free blocks live on the 'free_tail_blocks' list. When a block becomes active
+ * (see below) it is moved to the 'active_tail_blocks' list. When a block is fully committed, it is
+ * moved back to the 'free_tail_blocks' list.
*
* When entries are added to the journal, they are added to the active in-memory block, as
* indicated by the 'active_block' field. If the caller wishes to wait for the entry to be
diff --git a/drivers/md/dm-vdo/slab-depot.c b/drivers/md/dm-vdo/slab-depot.c
index 8f0a35c63af6..f3d80ff7bef5 100644
--- a/drivers/md/dm-vdo/slab-depot.c
+++ b/drivers/md/dm-vdo/slab-depot.c
@@ -139,7 +139,7 @@ static bool is_slab_journal_blank(const struct vdo_slab *slab)
}
/**
- * mark_slab_journal_dirty() - Put a slab journal on the dirty ring of its allocator in the correct
+ * mark_slab_journal_dirty() - Put a slab journal on the dirty list of its allocator in the correct
* order.
* @journal: The journal to be marked dirty.
* @lock: The recovery journal lock held by the slab journal.
@@ -414,8 +414,7 @@ static void complete_reaping(struct vdo_completion *completion)
{
struct slab_journal *journal = completion->parent;
- return_vio_to_pool(journal->slab->allocator->vio_pool,
- vio_as_pooled_vio(as_vio(vdo_forget(completion))));
+ return_vio_to_pool(vio_as_pooled_vio(as_vio(completion)));
finish_reaping(journal);
reap_slab_journal(journal);
}
@@ -698,7 +697,7 @@ static void complete_write(struct vdo_completion *completion)
sequence_number_t committed = get_committing_sequence_number(pooled);
list_del_init(&pooled->list_entry);
- return_vio_to_pool(journal->slab->allocator->vio_pool, vdo_forget(pooled));
+ return_vio_to_pool(pooled);
if (result != VDO_SUCCESS) {
vio_record_metadata_io_error(as_vio(completion));
@@ -822,7 +821,7 @@ static void commit_tail(struct slab_journal *journal)
/*
* Since we are about to commit the tail block, this journal no longer needs to be on the
- * ring of journals which the recovery journal might ask to commit.
+ * list of journals which the recovery journal might ask to commit.
*/
mark_slab_journal_clean(journal);
@@ -1076,7 +1075,7 @@ static void finish_reference_block_write(struct vdo_completion *completion)
/* Release the slab journal lock. */
adjust_slab_journal_block_reference(&slab->journal,
block->slab_journal_lock_to_release, -1);
- return_vio_to_pool(slab->allocator->vio_pool, pooled);
+ return_vio_to_pool(pooled);
/*
* We can't clear the is_writing flag earlier as releasing the slab journal lock may cause
@@ -1170,8 +1169,8 @@ static void handle_io_error(struct vdo_completion *completion)
struct vdo_slab *slab = ((struct reference_block *) completion->parent)->slab;
vio_record_metadata_io_error(vio);
- return_vio_to_pool(slab->allocator->vio_pool, vio_as_pooled_vio(vio));
- slab->active_count--;
+ return_vio_to_pool(vio_as_pooled_vio(vio));
+ slab->active_count -= vio->io_size / VDO_BLOCK_SIZE;
vdo_enter_read_only_mode(slab->allocator->depot->vdo, result);
check_if_slab_drained(slab);
}
@@ -1372,7 +1371,7 @@ static unsigned int calculate_slab_priority(struct vdo_slab *slab)
static void prioritize_slab(struct vdo_slab *slab)
{
VDO_ASSERT_LOG_ONLY(list_empty(&slab->allocq_entry),
- "a slab must not already be on a ring when prioritizing");
+ "a slab must not already be on a list when prioritizing");
slab->priority = calculate_slab_priority(slab);
vdo_priority_table_enqueue(slab->allocator->prioritized_slabs,
slab->priority, &slab->allocq_entry);
@@ -2165,28 +2164,95 @@ static void dirty_all_reference_blocks(struct vdo_slab *slab)
dirty_block(&slab->reference_blocks[i]);
}
+static inline bool journal_points_equal(struct journal_point first,
+ struct journal_point second)
+{
+ return ((first.sequence_number == second.sequence_number) &&
+ (first.entry_count == second.entry_count));
+}
+
/**
- * clear_provisional_references() - Clear the provisional reference counts from a reference block.
- * @block: The block to clear.
+ * match_bytes() - Check an 8-byte word for bytes matching the value specified
+ * @input: A word to examine the bytes of
+ * @match: The byte value sought
+ *
+ * Return: 1 in each byte when the corresponding input byte matched, 0 otherwise
*/
-static void clear_provisional_references(struct reference_block *block)
+static inline u64 match_bytes(u64 input, u8 match)
{
- vdo_refcount_t *counters = get_reference_counters_for_block(block);
- block_count_t j;
+ u64 temp = input ^ (match * 0x0101010101010101ULL);
+ /* top bit of each byte is set iff top bit of temp byte is clear; rest are 0 */
+ u64 test_top_bits = ~temp & 0x8080808080808080ULL;
+ /* top bit of each byte is set iff low 7 bits of temp byte are clear; rest are useless */
+ u64 test_low_bits = 0x8080808080808080ULL - (temp & 0x7f7f7f7f7f7f7f7fULL);
+ /* return 1 when both tests indicate temp byte is 0 */
+ return (test_top_bits & test_low_bits) >> 7;
+}
+
+/**
+ * count_valid_references() - Process a newly loaded refcount array
+ * @counters: the array of counters from a metadata block
+ *
+ * Scan a 8-byte-aligned array of counters, fixing up any "provisional" values that weren't
+ * cleaned up at shutdown, changing them internally to "empty".
+ *
+ * Return: the number of blocks that are referenced (counters not "empty")
+ */
+static unsigned int count_valid_references(vdo_refcount_t *counters)
+{
+ u64 *words = (u64 *)counters;
+ /* It's easier to count occurrences of a specific byte than its absences. */
+ unsigned int empty_count = 0;
+ /* For speed, we process 8 bytes at once. */
+ unsigned int words_left = COUNTS_PER_BLOCK / sizeof(u64);
+
+ /*
+ * Sanity check assumptions used for optimizing this code: Counters are bytes. The counter
+ * array is a multiple of the word size.
+ */
+ BUILD_BUG_ON(sizeof(vdo_refcount_t) != 1);
+ BUILD_BUG_ON((COUNTS_PER_BLOCK % sizeof(u64)) != 0);
+
+ while (words_left > 0) {
+ /*
+ * This is used effectively as 8 byte-size counters. Byte 0 counts how many words
+ * had the target value found in byte 0, etc. We just have to avoid overflow.
+ */
+ u64 split_count = 0;
+ /*
+ * The counter "% 255" trick used below to fold split_count into empty_count
+ * imposes a limit of 254 bytes examined each iteration of the outer loop. We
+ * process a word at a time, so that limit gets rounded down to 31 u64 words.
+ */
+ const unsigned int max_words_per_iteration = 254 / sizeof(u64);
+ unsigned int iter_words_left = min_t(unsigned int, words_left,
+ max_words_per_iteration);
+
+ words_left -= iter_words_left;
+
+ while (iter_words_left--) {
+ u64 word = *words;
+ u64 temp;
+
+ /* First, if we have any provisional refcount values, clear them. */
+ temp = match_bytes(word, PROVISIONAL_REFERENCE_COUNT);
+ if (temp) {
+ /*
+ * 'temp' has 0x01 bytes where 'word' has PROVISIONAL; this xor
+ * will alter just those bytes, changing PROVISIONAL to EMPTY.
+ */
+ word ^= temp * (PROVISIONAL_REFERENCE_COUNT ^ EMPTY_REFERENCE_COUNT);
+ *words = word;
+ }
- for (j = 0; j < COUNTS_PER_BLOCK; j++) {
- if (counters[j] == PROVISIONAL_REFERENCE_COUNT) {
- counters[j] = EMPTY_REFERENCE_COUNT;
- block->allocated_count--;
+ /* Now count the EMPTY_REFERENCE_COUNT bytes, updating the 8 counters. */
+ split_count += match_bytes(word, EMPTY_REFERENCE_COUNT);
+ words++;
}
+ empty_count += split_count % 255;
}
-}
-static inline bool journal_points_equal(struct journal_point first,
- struct journal_point second)
-{
- return ((first.sequence_number == second.sequence_number) &&
- (first.entry_count == second.entry_count));
+ return COUNTS_PER_BLOCK - empty_count;
}
/**
@@ -2197,7 +2263,6 @@ static inline bool journal_points_equal(struct journal_point first,
static void unpack_reference_block(struct packed_reference_block *packed,
struct reference_block *block)
{
- block_count_t index;
sector_count_t i;
struct vdo_slab *slab = block->slab;
vdo_refcount_t *counters = get_reference_counters_for_block(block);
@@ -2223,11 +2288,7 @@ static void unpack_reference_block(struct packed_reference_block *packed,
}
}
- block->allocated_count = 0;
- for (index = 0; index < COUNTS_PER_BLOCK; index++) {
- if (counters[index] != EMPTY_REFERENCE_COUNT)
- block->allocated_count++;
- }
+ block->allocated_count = count_valid_references(counters);
}
/**
@@ -2240,13 +2301,19 @@ static void finish_reference_block_load(struct vdo_completion *completion)
struct pooled_vio *pooled = vio_as_pooled_vio(vio);
struct reference_block *block = completion->parent;
struct vdo_slab *slab = block->slab;
+ unsigned int block_count = vio->io_size / VDO_BLOCK_SIZE;
+ unsigned int i;
+ char *data = vio->data;
- unpack_reference_block((struct packed_reference_block *) vio->data, block);
- return_vio_to_pool(slab->allocator->vio_pool, pooled);
- slab->active_count--;
- clear_provisional_references(block);
+ for (i = 0; i < block_count; i++, block++, data += VDO_BLOCK_SIZE) {
+ struct packed_reference_block *packed = (struct packed_reference_block *) data;
+
+ unpack_reference_block(packed, block);
+ slab->free_blocks -= block->allocated_count;
+ }
+ return_vio_to_pool(pooled);
+ slab->active_count -= block_count;
- slab->free_blocks -= block->allocated_count;
check_if_slab_drained(slab);
}
@@ -2260,23 +2327,25 @@ static void load_reference_block_endio(struct bio *bio)
}
/**
- * load_reference_block() - After a block waiter has gotten a VIO from the VIO pool, load the
- * block.
- * @waiter: The waiter of the block to load.
+ * load_reference_block_group() - After a block waiter has gotten a VIO from the VIO pool, load
+ * a set of blocks.
+ * @waiter: The waiter of the first block to load.
* @context: The VIO returned by the pool.
*/
-static void load_reference_block(struct vdo_waiter *waiter, void *context)
+static void load_reference_block_group(struct vdo_waiter *waiter, void *context)
{
struct pooled_vio *pooled = context;
struct vio *vio = &pooled->vio;
struct reference_block *block =
container_of(waiter, struct reference_block, waiter);
- size_t block_offset = (block - block->slab->reference_blocks);
+ u32 block_offset = block - block->slab->reference_blocks;
+ u32 max_block_count = block->slab->reference_block_count - block_offset;
+ u32 block_count = min_t(int, vio->block_count, max_block_count);
vio->completion.parent = block;
- vdo_submit_metadata_vio(vio, block->slab->ref_counts_origin + block_offset,
- load_reference_block_endio, handle_io_error,
- REQ_OP_READ);
+ vdo_submit_metadata_vio_with_size(vio, block->slab->ref_counts_origin + block_offset,
+ load_reference_block_endio, handle_io_error,
+ REQ_OP_READ, block_count * VDO_BLOCK_SIZE);
}
/**
@@ -2286,14 +2355,21 @@ static void load_reference_block(struct vdo_waiter *waiter, void *context)
static void load_reference_blocks(struct vdo_slab *slab)
{
block_count_t i;
+ u64 blocks_per_vio = slab->allocator->refcount_blocks_per_big_vio;
+ struct vio_pool *pool = slab->allocator->refcount_big_vio_pool;
+
+ if (!pool) {
+ pool = slab->allocator->vio_pool;
+ blocks_per_vio = 1;
+ }
slab->free_blocks = slab->block_count;
slab->active_count = slab->reference_block_count;
- for (i = 0; i < slab->reference_block_count; i++) {
+ for (i = 0; i < slab->reference_block_count; i += blocks_per_vio) {
struct vdo_waiter *waiter = &slab->reference_blocks[i].waiter;
- waiter->callback = load_reference_block;
- acquire_vio_from_pool(slab->allocator->vio_pool, waiter);
+ waiter->callback = load_reference_block_group;
+ acquire_vio_from_pool(pool, waiter);
}
}
@@ -2429,7 +2505,7 @@ static void finish_loading_journal(struct vdo_completion *completion)
initialize_journal_state(journal);
}
- return_vio_to_pool(slab->allocator->vio_pool, vio_as_pooled_vio(vio));
+ return_vio_to_pool(vio_as_pooled_vio(vio));
vdo_finish_loading_with_result(&slab->state, allocate_counters_if_clean(slab));
}
@@ -2449,7 +2525,7 @@ static void handle_load_error(struct vdo_completion *completion)
struct vio *vio = as_vio(completion);
vio_record_metadata_io_error(vio);
- return_vio_to_pool(journal->slab->allocator->vio_pool, vio_as_pooled_vio(vio));
+ return_vio_to_pool(vio_as_pooled_vio(vio));
vdo_finish_loading_with_result(&journal->slab->state, result);
}
@@ -2547,7 +2623,7 @@ static void queue_slab(struct vdo_slab *slab)
int result;
VDO_ASSERT_LOG_ONLY(list_empty(&slab->allocq_entry),
- "a requeued slab must not already be on a ring");
+ "a requeued slab must not already be on a list");
if (vdo_is_read_only(allocator->depot->vdo))
return;
@@ -2700,6 +2776,7 @@ static void finish_scrubbing(struct slab_scrubber *scrubber, int result)
vdo_log_info("VDO commencing normal operation");
else if (prior_state == VDO_RECOVERING)
vdo_log_info("Exiting recovery mode");
+ free_vio_pool(vdo_forget(allocator->refcount_big_vio_pool));
}
/*
@@ -3281,7 +3358,7 @@ int vdo_release_block_reference(struct block_allocator *allocator,
* This is a min_heap callback function orders slab_status structures using the 'is_clean' field as
* the primary key and the 'emptiness' field as the secondary key.
*
- * Slabs need to be pushed onto the rings in the same order they are to be popped off. Popping
+ * Slabs need to be pushed onto the lists in the same order they are to be popped off. Popping
* should always get the most empty first, so pushing should be from most empty to least empty.
* Thus, the ordering is reversed from the usual sense since min_heap returns smaller elements
* before larger ones.
@@ -3983,6 +4060,7 @@ static int __must_check initialize_block_allocator(struct slab_depot *depot,
struct vdo *vdo = depot->vdo;
block_count_t max_free_blocks = depot->slab_config.data_blocks;
unsigned int max_priority = (2 + ilog2(max_free_blocks));
+ u32 reference_block_count, refcount_reads_needed, refcount_blocks_per_vio;
*allocator = (struct block_allocator) {
.depot = depot,
@@ -4000,12 +4078,24 @@ static int __must_check initialize_block_allocator(struct slab_depot *depot,
return result;
vdo_initialize_completion(&allocator->completion, vdo, VDO_BLOCK_ALLOCATOR_COMPLETION);
- result = make_vio_pool(vdo, BLOCK_ALLOCATOR_VIO_POOL_SIZE, allocator->thread_id,
+ result = make_vio_pool(vdo, BLOCK_ALLOCATOR_VIO_POOL_SIZE, 1, allocator->thread_id,
VIO_TYPE_SLAB_JOURNAL, VIO_PRIORITY_METADATA,
allocator, &allocator->vio_pool);
if (result != VDO_SUCCESS)
return result;
+ /* Initialize the refcount-reading vio pool. */
+ reference_block_count = vdo_get_saved_reference_count_size(depot->slab_config.slab_blocks);
+ refcount_reads_needed = DIV_ROUND_UP(reference_block_count, MAX_BLOCKS_PER_VIO);
+ refcount_blocks_per_vio = DIV_ROUND_UP(reference_block_count, refcount_reads_needed);
+ allocator->refcount_blocks_per_big_vio = refcount_blocks_per_vio;
+ result = make_vio_pool(vdo, BLOCK_ALLOCATOR_REFCOUNT_VIO_POOL_SIZE,
+ allocator->refcount_blocks_per_big_vio, allocator->thread_id,
+ VIO_TYPE_SLAB_JOURNAL, VIO_PRIORITY_METADATA,
+ NULL, &allocator->refcount_big_vio_pool);
+ if (result != VDO_SUCCESS)
+ return result;
+
result = initialize_slab_scrubber(allocator);
if (result != VDO_SUCCESS)
return result;
@@ -4223,6 +4313,7 @@ void vdo_free_slab_depot(struct slab_depot *depot)
uninitialize_allocator_summary(allocator);
uninitialize_scrubber_vio(&allocator->scrubber);
free_vio_pool(vdo_forget(allocator->vio_pool));
+ free_vio_pool(vdo_forget(allocator->refcount_big_vio_pool));
vdo_free_priority_table(vdo_forget(allocator->prioritized_slabs));
}
diff --git a/drivers/md/dm-vdo/slab-depot.h b/drivers/md/dm-vdo/slab-depot.h
index f234853501ca..fadc0c9d4dc4 100644
--- a/drivers/md/dm-vdo/slab-depot.h
+++ b/drivers/md/dm-vdo/slab-depot.h
@@ -45,6 +45,13 @@
enum {
/* The number of vios in the vio pool is proportional to the throughput of the VDO. */
BLOCK_ALLOCATOR_VIO_POOL_SIZE = 128,
+
+ /*
+ * The number of vios in the vio pool used for loading reference count data. A slab's
+ * refcounts is capped at ~8MB, and we process one at a time in a zone, so 9 should be
+ * plenty.
+ */
+ BLOCK_ALLOCATOR_REFCOUNT_VIO_POOL_SIZE = 9,
};
/*
@@ -248,7 +255,7 @@ struct vdo_slab {
/* A list of the dirty blocks waiting to be written out */
struct vdo_wait_queue dirty_blocks;
- /* The number of blocks which are currently writing */
+ /* The number of blocks which are currently reading or writing */
size_t active_count;
/* A waiter object for updating the slab summary */
@@ -425,6 +432,10 @@ struct block_allocator {
/* The vio pool for reading and writing block allocator metadata */
struct vio_pool *vio_pool;
+ /* The vio pool for large initial reads of ref count areas */
+ struct vio_pool *refcount_big_vio_pool;
+ /* How many ref count blocks are read per vio at initial load */
+ u32 refcount_blocks_per_big_vio;
/* The dm_kcopyd client for erasing slab journals */
struct dm_kcopyd_client *eraser;
/* Iterator over the slabs to be erased */
diff --git a/drivers/md/dm-vdo/types.h b/drivers/md/dm-vdo/types.h
index dbe892b10f26..cdf36e7d7702 100644
--- a/drivers/md/dm-vdo/types.h
+++ b/drivers/md/dm-vdo/types.h
@@ -376,6 +376,9 @@ struct vio {
/* The size of this vio in blocks */
unsigned int block_count;
+ /* The amount of data to be read or written, in bytes */
+ unsigned int io_size;
+
/* The data being read or written. */
char *data;
diff --git a/drivers/md/dm-vdo/vdo.c b/drivers/md/dm-vdo/vdo.c
index a7e32baab4af..80b608674022 100644
--- a/drivers/md/dm-vdo/vdo.c
+++ b/drivers/md/dm-vdo/vdo.c
@@ -31,9 +31,7 @@
#include <linux/completion.h>
#include <linux/device-mapper.h>
-#include <linux/kernel.h>
#include <linux/lz4.h>
-#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/types.h>
@@ -142,12 +140,6 @@ static void finish_vdo_request_queue(void *ptr)
vdo_unregister_allocating_thread();
}
-#ifdef MODULE
-#define MODULE_NAME THIS_MODULE->name
-#else
-#define MODULE_NAME "dm-vdo"
-#endif /* MODULE */
-
static const struct vdo_work_queue_type default_queue_type = {
.start = start_vdo_request_queue,
.finish = finish_vdo_request_queue,
@@ -559,8 +551,7 @@ int vdo_make(unsigned int instance, struct device_config *config, char **reason,
*vdo_ptr = vdo;
snprintf(vdo->thread_name_prefix, sizeof(vdo->thread_name_prefix),
- "%s%u", MODULE_NAME, instance);
- BUG_ON(vdo->thread_name_prefix[0] == '\0');
+ "vdo%u", instance);
result = vdo_allocate(vdo->thread_config.thread_count,
struct vdo_thread, __func__, &vdo->threads);
if (result != VDO_SUCCESS) {
diff --git a/drivers/md/dm-vdo/vio.c b/drivers/md/dm-vdo/vio.c
index e710f3c5a972..e7f4153e55e3 100644
--- a/drivers/md/dm-vdo/vio.c
+++ b/drivers/md/dm-vdo/vio.c
@@ -188,14 +188,23 @@ void vdo_set_bio_properties(struct bio *bio, struct vio *vio, bio_end_io_t callb
/*
* Prepares the bio to perform IO with the specified buffer. May only be used on a VDO-allocated
- * bio, as it assumes the bio wraps a 4k buffer that is 4k aligned, but there does not have to be a
- * vio associated with the bio.
+ * bio, as it assumes the bio wraps a 4k-multiple buffer that is 4k aligned, but there does not
+ * have to be a vio associated with the bio.
*/
int vio_reset_bio(struct vio *vio, char *data, bio_end_io_t callback,
blk_opf_t bi_opf, physical_block_number_t pbn)
{
- int bvec_count, offset, len, i;
+ return vio_reset_bio_with_size(vio, data, vio->block_count * VDO_BLOCK_SIZE,
+ callback, bi_opf, pbn);
+}
+
+int vio_reset_bio_with_size(struct vio *vio, char *data, int size, bio_end_io_t callback,
+ blk_opf_t bi_opf, physical_block_number_t pbn)
+{
+ int bvec_count, offset, i;
struct bio *bio = vio->bio;
+ int vio_size = vio->block_count * VDO_BLOCK_SIZE;
+ int remaining;
bio_reset(bio, bio->bi_bdev, bi_opf);
vdo_set_bio_properties(bio, vio, callback, bi_opf, pbn);
@@ -205,22 +214,21 @@ int vio_reset_bio(struct vio *vio, char *data, bio_end_io_t callback,
bio->bi_ioprio = 0;
bio->bi_io_vec = bio->bi_inline_vecs;
bio->bi_max_vecs = vio->block_count + 1;
- len = VDO_BLOCK_SIZE * vio->block_count;
+ if (VDO_ASSERT(size <= vio_size, "specified size %d is not greater than allocated %d",
+ size, vio_size) != VDO_SUCCESS)
+ size = vio_size;
+ vio->io_size = size;
offset = offset_in_page(data);
- bvec_count = DIV_ROUND_UP(offset + len, PAGE_SIZE);
+ bvec_count = DIV_ROUND_UP(offset + size, PAGE_SIZE);
+ remaining = size;
- /*
- * If we knew that data was always on one page, or contiguous pages, we wouldn't need the
- * loop. But if we're using vmalloc, it's not impossible that the data is in different
- * pages that can't be merged in bio_add_page...
- */
- for (i = 0; (i < bvec_count) && (len > 0); i++) {
+ for (i = 0; (i < bvec_count) && (remaining > 0); i++) {
struct page *page;
int bytes_added;
int bytes = PAGE_SIZE - offset;
- if (bytes > len)
- bytes = len;
+ if (bytes > remaining)
+ bytes = remaining;
page = is_vmalloc_addr(data) ? vmalloc_to_page(data) : virt_to_page(data);
bytes_added = bio_add_page(bio, page, bytes, offset);
@@ -232,7 +240,7 @@ int vio_reset_bio(struct vio *vio, char *data, bio_end_io_t callback,
}
data += bytes;
- len -= bytes;
+ remaining -= bytes;
offset = 0;
}
@@ -301,6 +309,7 @@ void vio_record_metadata_io_error(struct vio *vio)
* make_vio_pool() - Create a new vio pool.
* @vdo: The vdo.
* @pool_size: The number of vios in the pool.
+ * @block_count: The number of 4k blocks per vio.
* @thread_id: The ID of the thread using this pool.
* @vio_type: The type of vios in the pool.
* @priority: The priority with which vios from the pool should be enqueued.
@@ -309,13 +318,14 @@ void vio_record_metadata_io_error(struct vio *vio)
*
* Return: A success or error code.
*/
-int make_vio_pool(struct vdo *vdo, size_t pool_size, thread_id_t thread_id,
+int make_vio_pool(struct vdo *vdo, size_t pool_size, size_t block_count, thread_id_t thread_id,
enum vio_type vio_type, enum vio_priority priority, void *context,
struct vio_pool **pool_ptr)
{
struct vio_pool *pool;
char *ptr;
int result;
+ size_t per_vio_size = VDO_BLOCK_SIZE * block_count;
result = vdo_allocate_extended(struct vio_pool, pool_size, struct pooled_vio,
__func__, &pool);
@@ -326,7 +336,7 @@ int make_vio_pool(struct vdo *vdo, size_t pool_size, thread_id_t thread_id,
INIT_LIST_HEAD(&pool->available);
INIT_LIST_HEAD(&pool->busy);
- result = vdo_allocate(pool_size * VDO_BLOCK_SIZE, char,
+ result = vdo_allocate(pool_size * per_vio_size, char,
"VIO pool buffer", &pool->buffer);
if (result != VDO_SUCCESS) {
free_vio_pool(pool);
@@ -334,10 +344,10 @@ int make_vio_pool(struct vdo *vdo, size_t pool_size, thread_id_t thread_id,
}
ptr = pool->buffer;
- for (pool->size = 0; pool->size < pool_size; pool->size++, ptr += VDO_BLOCK_SIZE) {
+ for (pool->size = 0; pool->size < pool_size; pool->size++, ptr += per_vio_size) {
struct pooled_vio *pooled = &pool->vios[pool->size];
- result = allocate_vio_components(vdo, vio_type, priority, NULL, 1, ptr,
+ result = allocate_vio_components(vdo, vio_type, priority, NULL, block_count, ptr,
&pooled->vio);
if (result != VDO_SUCCESS) {
free_vio_pool(pool);
@@ -345,6 +355,7 @@ int make_vio_pool(struct vdo *vdo, size_t pool_size, thread_id_t thread_id,
}
pooled->context = context;
+ pooled->pool = pool;
list_add_tail(&pooled->pool_entry, &pool->available);
}
@@ -419,12 +430,13 @@ void acquire_vio_from_pool(struct vio_pool *pool, struct vdo_waiter *waiter)
}
/**
- * return_vio_to_pool() - Return a vio to the pool
- * @pool: The vio pool.
+ * return_vio_to_pool() - Return a vio to its pool
* @vio: The pooled vio to return.
*/
-void return_vio_to_pool(struct vio_pool *pool, struct pooled_vio *vio)
+void return_vio_to_pool(struct pooled_vio *vio)
{
+ struct vio_pool *pool = vio->pool;
+
VDO_ASSERT_LOG_ONLY((pool->thread_id == vdo_get_callback_thread_id()),
"vio pool entry returned on same thread as it was acquired");
diff --git a/drivers/md/dm-vdo/vio.h b/drivers/md/dm-vdo/vio.h
index 3490e9f59b04..4bfcb21901f1 100644
--- a/drivers/md/dm-vdo/vio.h
+++ b/drivers/md/dm-vdo/vio.h
@@ -30,6 +30,8 @@ struct pooled_vio {
void *context;
/* The list entry used by the pool */
struct list_head pool_entry;
+ /* The pool this vio is allocated from */
+ struct vio_pool *pool;
};
/**
@@ -123,6 +125,8 @@ void vdo_set_bio_properties(struct bio *bio, struct vio *vio, bio_end_io_t callb
int vio_reset_bio(struct vio *vio, char *data, bio_end_io_t callback,
blk_opf_t bi_opf, physical_block_number_t pbn);
+int vio_reset_bio_with_size(struct vio *vio, char *data, int size, bio_end_io_t callback,
+ blk_opf_t bi_opf, physical_block_number_t pbn);
void update_vio_error_stats(struct vio *vio, const char *format, ...)
__printf(2, 3);
@@ -188,12 +192,13 @@ static inline struct pooled_vio *vio_as_pooled_vio(struct vio *vio)
struct vio_pool;
-int __must_check make_vio_pool(struct vdo *vdo, size_t pool_size, thread_id_t thread_id,
- enum vio_type vio_type, enum vio_priority priority,
- void *context, struct vio_pool **pool_ptr);
+int __must_check make_vio_pool(struct vdo *vdo, size_t pool_size, size_t block_count,
+ thread_id_t thread_id, enum vio_type vio_type,
+ enum vio_priority priority, void *context,
+ struct vio_pool **pool_ptr);
void free_vio_pool(struct vio_pool *pool);
bool __must_check is_vio_pool_busy(struct vio_pool *pool);
void acquire_vio_from_pool(struct vio_pool *pool, struct vdo_waiter *waiter);
-void return_vio_to_pool(struct vio_pool *pool, struct pooled_vio *vio);
+void return_vio_to_pool(struct pooled_vio *vio);
#endif /* VIO_H */
diff --git a/drivers/md/dm-vdo/wait-queue.c b/drivers/md/dm-vdo/wait-queue.c
index 6e1e739277ef..f81ed0cee2bf 100644
--- a/drivers/md/dm-vdo/wait-queue.c
+++ b/drivers/md/dm-vdo/wait-queue.c
@@ -34,7 +34,7 @@ void vdo_waitq_enqueue_waiter(struct vdo_wait_queue *waitq, struct vdo_waiter *w
waitq->last_waiter->next_waiter = waiter;
}
- /* In both cases, the waiter we added to the ring becomes the last waiter. */
+ /* In both cases, the waiter we added to the list becomes the last waiter. */
waitq->last_waiter = waiter;
waitq->length += 1;
}
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index e86c1431b108..3c427f18a04b 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -30,6 +30,7 @@
#define DM_VERITY_ENV_VAR_NAME "DM_VERITY_ERR_BLOCK_NR"
#define DM_VERITY_DEFAULT_PREFETCH_SIZE 262144
+#define DM_VERITY_USE_BH_DEFAULT_BYTES 8192
#define DM_VERITY_MAX_CORRUPTED_ERRS 100
@@ -49,6 +50,15 @@ static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE
module_param_named(prefetch_cluster, dm_verity_prefetch_cluster, uint, 0644);
+static unsigned int dm_verity_use_bh_bytes[4] = {
+ DM_VERITY_USE_BH_DEFAULT_BYTES, // IOPRIO_CLASS_NONE
+ DM_VERITY_USE_BH_DEFAULT_BYTES, // IOPRIO_CLASS_RT
+ DM_VERITY_USE_BH_DEFAULT_BYTES, // IOPRIO_CLASS_BE
+ 0 // IOPRIO_CLASS_IDLE
+};
+
+module_param_array_named(use_bh_bytes, dm_verity_use_bh_bytes, uint, NULL, 0644);
+
static DEFINE_STATIC_KEY_FALSE(use_bh_wq_enabled);
/* Is at least one dm-verity instance using ahash_tfm instead of shash_tfm? */
@@ -311,7 +321,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
if (static_branch_unlikely(&use_bh_wq_enabled) && io->in_bh) {
data = dm_bufio_get(v->bufio, hash_block, &buf);
- if (data == NULL) {
+ if (IS_ERR_OR_NULL(data)) {
/*
* In tasklet and the hash was not in the bufio cache.
* Return early and resume execution from a work-queue
@@ -324,8 +334,24 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
&buf, bio->bi_ioprio);
}
- if (IS_ERR(data))
- return PTR_ERR(data);
+ if (IS_ERR(data)) {
+ if (skip_unverified)
+ return 1;
+ r = PTR_ERR(data);
+ data = dm_bufio_new(v->bufio, hash_block, &buf);
+ if (IS_ERR(data))
+ return r;
+ if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_METADATA,
+ hash_block, data) == 0) {
+ aux = dm_bufio_get_aux_data(buf);
+ aux->hash_verified = 1;
+ goto release_ok;
+ } else {
+ dm_bufio_release(buf);
+ dm_bufio_forget(v->bufio, hash_block);
+ return r;
+ }
+ }
aux = dm_bufio_get_aux_data(buf);
@@ -366,6 +392,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
}
}
+release_ok:
data += offset;
memcpy(want_digest, data, v->digest_size);
r = 0;
@@ -652,9 +679,17 @@ static void verity_bh_work(struct work_struct *w)
verity_finish_io(io, errno_to_blk_status(err));
}
+static inline bool verity_use_bh(unsigned int bytes, unsigned short ioprio)
+{
+ return ioprio <= IOPRIO_CLASS_IDLE &&
+ bytes <= READ_ONCE(dm_verity_use_bh_bytes[ioprio]);
+}
+
static void verity_end_io(struct bio *bio)
{
struct dm_verity_io *io = bio->bi_private;
+ unsigned short ioprio = IOPRIO_PRIO_CLASS(bio->bi_ioprio);
+ unsigned int bytes = io->n_blocks << io->v->data_dev_block_bits;
if (bio->bi_status &&
(!verity_fec_is_enabled(io->v) ||
@@ -664,9 +699,14 @@ static void verity_end_io(struct bio *bio)
return;
}
- if (static_branch_unlikely(&use_bh_wq_enabled) && io->v->use_bh_wq) {
- INIT_WORK(&io->bh_work, verity_bh_work);
- queue_work(system_bh_wq, &io->bh_work);
+ if (static_branch_unlikely(&use_bh_wq_enabled) && io->v->use_bh_wq &&
+ verity_use_bh(bytes, ioprio)) {
+ if (in_hardirq() || irqs_disabled()) {
+ INIT_WORK(&io->bh_work, verity_bh_work);
+ queue_work(system_bh_wq, &io->bh_work);
+ } else {
+ verity_bh_work(&io->bh_work);
+ }
} else {
INIT_WORK(&io->work, verity_work);
queue_work(io->v->verify_wq, &io->work);
@@ -796,6 +836,13 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_SUBMITTED;
}
+static void verity_postsuspend(struct dm_target *ti)
+{
+ struct dm_verity *v = ti->private;
+ flush_workqueue(v->verify_wq);
+ dm_bufio_client_reset(v->bufio);
+}
+
/*
* Status: V (valid) or C (corruption found)
*/
@@ -1761,11 +1808,12 @@ static struct target_type verity_target = {
.name = "verity",
/* Note: the LSMs depend on the singleton and immutable features */
.features = DM_TARGET_SINGLETON | DM_TARGET_IMMUTABLE,
- .version = {1, 10, 0},
+ .version = {1, 11, 0},
.module = THIS_MODULE,
.ctr = verity_ctr,
.dtr = verity_dtr,
.map = verity_map,
+ .postsuspend = verity_postsuspend,
.status = verity_status,
.prepare_ioctl = verity_prepare_ioctl,
.iterate_devices = verity_iterate_devices,
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index 7ce8847b3404..d6a04a57472d 100644
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -797,7 +797,7 @@ static void writecache_flush(struct dm_writecache *wc)
bool need_flush_after_free;
wc->uncommitted_blocks = 0;
- del_timer(&wc->autocommit_timer);
+ timer_delete(&wc->autocommit_timer);
if (list_empty(&wc->lru))
return;
@@ -927,8 +927,8 @@ static void writecache_suspend(struct dm_target *ti)
struct dm_writecache *wc = ti->private;
bool flush_on_suspend;
- del_timer_sync(&wc->autocommit_timer);
- del_timer_sync(&wc->max_age_timer);
+ timer_delete_sync(&wc->autocommit_timer);
+ timer_delete_sync(&wc->max_age_timer);
wc_lock(wc);
writecache_flush(wc);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 4d1e42891d24..5ab7574c0c76 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1540,14 +1540,18 @@ static void __send_empty_flush(struct clone_info *ci)
{
struct dm_table *t = ci->map;
struct bio flush_bio;
+ blk_opf_t opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC;
+
+ if ((ci->io->orig_bio->bi_opf & (REQ_IDLE | REQ_SYNC)) ==
+ (REQ_IDLE | REQ_SYNC))
+ opf |= REQ_IDLE;
/*
* Use an on-stack bio for this, it's safe since we don't
* need to reference it after submit. It's just used as
* the basis for the clone(s).
*/
- bio_init(&flush_bio, ci->io->md->disk->part0, NULL, 0,
- REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC);
+ bio_init(&flush_bio, ci->io->md->disk->part0, NULL, 0, opf);
ci->bio = &flush_bio;
ci->sector_count = 0;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 438e71e45c16..9daa78c5fe33 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4064,7 +4064,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
* it must always be in_sync
*/
mddev->in_sync = 1;
- del_timer_sync(&mddev->safemode_timer);
+ timer_delete_sync(&mddev->safemode_timer);
}
pers->run(mddev);
set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
@@ -6405,7 +6405,7 @@ static void md_clean(struct mddev *mddev)
static void __md_stop_writes(struct mddev *mddev)
{
- del_timer_sync(&mddev->safemode_timer);
+ timer_delete_sync(&mddev->safemode_timer);
if (mddev->pers && mddev->pers->quiesce) {
mddev->pers->quiesce(mddev, 1);
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index a7047e548245..2952678cce45 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -147,7 +147,7 @@ void saa7146_buffer_next(struct saa7146_dev *dev,
printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
*/
}
- del_timer(&q->timeout);
+ timer_delete(&q->timeout);
}
}
diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c
index a1854b3dd004..6c324a683be9 100644
--- a/drivers/media/common/saa7146/saa7146_vbi.c
+++ b/drivers/media/common/saa7146/saa7146_vbi.c
@@ -322,8 +322,8 @@ static void vbi_stop(struct saa7146_dev *dev)
/* shut down dma 3 transfers */
saa7146_write(dev, MC1, MASK_20);
- del_timer(&vv->vbi_dmaq.timeout);
- del_timer(&vv->vbi_read_timeout);
+ timer_delete(&vv->vbi_dmaq.timeout);
+ timer_delete(&vv->vbi_read_timeout);
spin_unlock_irqrestore(&dev->slock, flags);
}
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 94e1cd4eaedb..733e18001d0d 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -668,7 +668,7 @@ static void stop_streaming(struct vb2_queue *q)
struct saa7146_dev *dev = vb2_get_drv_priv(q);
struct saa7146_dmaqueue *dq = &dev->vv_data->video_dmaq;
- del_timer(&dq->timeout);
+ timer_delete(&dq->timeout);
video_end(dev);
return_buffers(q, VB2_BUF_STATE_ERROR);
}
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 6063782e937a..1e985f943944 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -365,7 +365,7 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
{
struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec;
- del_timer(&dmxdevfilter->timer);
+ timer_delete(&dmxdevfilter->timer);
if (para->timeout) {
dmxdevfilter->timer.expires =
jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
@@ -391,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
- del_timer(&dmxdevfilter->timer);
+ timer_delete(&dmxdevfilter->timer);
dprintk("section callback %*ph\n", 6, buffer1);
if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
@@ -482,7 +482,7 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
switch (dmxdevfilter->type) {
case DMXDEV_TYPE_SEC:
- del_timer(&dmxdevfilter->timer);
+ timer_delete(&dmxdevfilter->timer);
dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
break;
case DMXDEV_TYPE_PES:
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 2f5165918163..cfe59c3255f7 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
u8 ratio;
if (state->revision == 0x8090) {
+ u32 internal = dib8000_read32(state, 23) / 1000;
+
ratio = 4;
- unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
+
+ unit_khz_dds_val = (1<<26) / (internal ?: 1);
if (offset_khz < 0)
dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
else
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index c50d4e85dfd1..2d5f42f11158 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -2201,7 +2201,7 @@ static int tc358743_probe(struct i2c_client *client)
err_work_queues:
cec_unregister_adapter(state->cec_adap);
if (!state->i2c_client->irq) {
- del_timer(&state->timer);
+ timer_delete(&state->timer);
flush_work(&state->work_i2c_poll);
}
cancel_delayed_work(&state->delayed_work_enable_hotplug);
@@ -2218,7 +2218,7 @@ static void tc358743_remove(struct i2c_client *client)
struct tc358743_state *state = to_state(sd);
if (!state->i2c_client->irq) {
- del_timer_sync(&state->timer);
+ timer_delete_sync(&state->timer);
flush_work(&state->work_i2c_poll);
}
cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index 654725dfafac..42115118a0bd 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -1787,7 +1787,7 @@ static int tvaudio_s_radio(struct v4l2_subdev *sd)
struct CHIPSTATE *chip = to_state(sd);
chip->radio = 1;
- /* del_timer(&chip->wt); */
+ /* timer_delete(&chip->wt); */
return 0;
}
@@ -2071,7 +2071,7 @@ static void tvaudio_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct CHIPSTATE *chip = to_state(sd);
- del_timer_sync(&chip->wt);
+ timer_delete_sync(&chip->wt);
if (chip->thread) {
/* shutdown async thread */
kthread_stop(chip->thread);
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 2782832f5eb8..377a7e7f0499 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3491,7 +3491,7 @@ static void bttv_remove(struct pci_dev *pci_dev)
/* free resources */
free_irq(btv->c.pci->irq,btv);
- del_timer_sync(&btv->timeout);
+ timer_delete_sync(&btv->timeout);
iounmap(btv->bt848_mmio);
release_mem_region(pci_resource_start(btv->c.pci,0),
pci_resource_len(btv->c.pci,0));
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index 41226f1d0e5b..9eb7a5356b4c 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -304,12 +304,12 @@ static void bttv_ir_start(struct bttv_ir *ir)
static void bttv_ir_stop(struct bttv *btv)
{
if (btv->remote->polling)
- del_timer_sync(&btv->remote->timer);
+ timer_delete_sync(&btv->remote->timer);
if (btv->remote->rc5_gpio) {
u32 gpio;
- del_timer_sync(&btv->remote->timer);
+ timer_delete_sync(&btv->remote->timer);
gpio = bttv_gpio_read(&btv->c);
bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
diff --git a/drivers/media/pci/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c
index 241a696e374a..79581cd7bd59 100644
--- a/drivers/media/pci/bt8xx/bttv-risc.c
+++ b/drivers/media/pci/bt8xx/bttv-risc.c
@@ -376,7 +376,7 @@ static void bttv_set_irq_timer(struct bttv *btv)
if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi)
mod_timer(&btv->timeout, jiffies + BTTV_TIMEOUT);
else
- del_timer(&btv->timeout);
+ timer_delete(&btv->timeout);
}
static int bttv_set_capture_control(struct bttv *btv, int start_capture)
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c
index b7aaa8b4a784..b3b670b6ef70 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -532,7 +532,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv)
IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");
- del_timer(&itv->dma_timer);
+ timer_delete(&itv->dma_timer);
if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0)
return;
@@ -597,7 +597,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
- del_timer(&itv->dma_timer);
+ timer_delete(&itv->dma_timer);
if (itv->cur_dma_stream < 0)
return;
@@ -670,7 +670,7 @@ static void ivtv_irq_dma_err(struct ivtv *itv)
u32 data[CX2341X_MBOX_MAX_DATA];
u32 status;
- del_timer(&itv->dma_timer);
+ timer_delete(&itv->dma_timer);
ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
status = read_reg(IVTV_REG_DMASTATUS);
diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c
index af9e6235c74d..ac085925d3cb 100644
--- a/drivers/media/pci/ivtv/ivtv-streams.c
+++ b/drivers/media/pci/ivtv/ivtv-streams.c
@@ -891,7 +891,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
/* Set the following Interrupt mask bits for capture */
ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
- del_timer(&itv->dma_timer);
+ timer_delete(&itv->dma_timer);
/* event notification (off) */
if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
@@ -956,7 +956,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
- del_timer(&itv->dma_timer);
+ timer_delete(&itv->dma_timer);
clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 557985ba25db..16338d13d9c8 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -698,7 +698,7 @@ static void netup_unidvb_dma_fini(struct netup_unidvb_dev *ndev, int num)
netup_unidvb_dma_enable(dma, 0);
msleep(50);
cancel_work_sync(&dma->work);
- del_timer_sync(&dma->timeout);
+ timer_delete_sync(&dma->timeout);
}
static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev)
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index ea0585e43abb..84295bdb8ce4 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -322,7 +322,7 @@ void saa7134_buffer_next(struct saa7134_dev *dev,
/* nothing to do -- just stop DMA */
core_dbg("buffer_next %p\n", NULL);
saa7134_set_dmabits(dev);
- del_timer(&q->timeout);
+ timer_delete(&q->timeout);
}
}
@@ -364,7 +364,7 @@ void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q)
tmp = NULL;
}
spin_unlock_irqrestore(&dev->slock, flags);
- saa7134_buffer_timeout(&q->timeout); /* also calls del_timer(&q->timeout) */
+ saa7134_buffer_timeout(&q->timeout); /* also calls timer_delete(&q->timeout) */
}
EXPORT_SYMBOL_GPL(saa7134_stop_streaming);
@@ -1390,9 +1390,9 @@ static int __maybe_unused saa7134_suspend(struct device *dev_d)
/* Disable timeout timers - if we have active buffers, we will
fill them on resume*/
- del_timer(&dev->video_q.timeout);
- del_timer(&dev->vbi_q.timeout);
- del_timer(&dev->ts_q.timeout);
+ timer_delete(&dev->video_q.timeout);
+ timer_delete(&dev->vbi_q.timeout);
+ timer_delete(&dev->ts_q.timeout);
if (dev->remote && dev->remote->dev->users)
saa7134_ir_close(dev->remote->dev);
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 8610eb473b39..d7d97c7d4a2b 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -496,7 +496,7 @@ void saa7134_ir_close(struct rc_dev *rc)
struct saa7134_card_ir *ir = dev->remote;
if (ir->polling)
- del_timer_sync(&ir->timer);
+ timer_delete_sync(&ir->timer);
ir->running = false;
}
diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c
index ec699ea14799..1b44033067c5 100644
--- a/drivers/media/pci/saa7134/saa7134-ts.c
+++ b/drivers/media/pci/saa7134/saa7134-ts.c
@@ -298,7 +298,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
int saa7134_ts_fini(struct saa7134_dev *dev)
{
- del_timer_sync(&dev->ts_q.timeout);
+ timer_delete_sync(&dev->ts_q.timeout);
saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);
return 0;
}
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index efa6e4fa423a..28bf77449bdb 100644
--- a/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -183,7 +183,7 @@ int saa7134_vbi_init1(struct saa7134_dev *dev)
int saa7134_vbi_fini(struct saa7134_dev *dev)
{
/* nothing */
- del_timer_sync(&dev->vbi_q.timeout);
+ timer_delete_sync(&dev->vbi_q.timeout);
return 0;
}
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 43e7b006eb59..c88939bce56b 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1741,7 +1741,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
void saa7134_video_fini(struct saa7134_dev *dev)
{
- del_timer_sync(&dev->video_q.timeout);
+ timer_delete_sync(&dev->video_q.timeout);
/* free stuff */
saa7134_pgtable_free(dev->pci, &dev->video_q.pt);
saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt);
diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c
index c53099c958ca..80bd268926cc 100644
--- a/drivers/media/pci/tw686x/tw686x-core.c
+++ b/drivers/media/pci/tw686x/tw686x-core.c
@@ -373,7 +373,7 @@ static void tw686x_remove(struct pci_dev *pci_dev)
tw686x_video_free(dev);
tw686x_audio_free(dev);
- del_timer_sync(&dev->dma_delay_timer);
+ timer_delete_sync(&dev->dma_delay_timer);
pci_iounmap(pci_dev, dev->mmio);
pci_release_regions(pci_dev);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index 5f80931f056d..c8e0ee383af3 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -935,7 +935,7 @@ err_pwr_enable:
if (dev->num_inst == 1) {
if (s5p_mfc_power_off(dev) < 0)
mfc_err("power off failed\n");
- del_timer_sync(&dev->watchdog_timer);
+ timer_delete_sync(&dev->watchdog_timer);
}
err_ctrls_setup:
s5p_mfc_dec_ctrls_delete(ctx);
@@ -985,7 +985,7 @@ static int s5p_mfc_release(struct file *file)
if (dev->num_inst == 0) {
mfc_debug(2, "Last instance\n");
s5p_mfc_deinit_hw(dev);
- del_timer_sync(&dev->watchdog_timer);
+ timer_delete_sync(&dev->watchdog_timer);
s5p_mfc_clock_off(dev);
if (s5p_mfc_power_off(dev) < 0)
mfc_err("Power off failed\n");
@@ -1461,7 +1461,7 @@ static void s5p_mfc_remove(struct platform_device *pdev)
}
mutex_unlock(&dev->mfc_mutex);
- del_timer_sync(&dev->watchdog_timer);
+ timer_delete_sync(&dev->watchdog_timer);
flush_work(&dev->watchdog_work);
video_unregister_device(dev->vfd_enc);
diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
index d151d2ed1f64..87a817dda4a9 100644
--- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
@@ -351,7 +351,7 @@ static int c8sectpfe_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
dev_dbg(fei->dev, "%s:%d global_feed_count=%d\n"
, __func__, __LINE__, fei->global_feed_count);
- del_timer(&fei->timer);
+ timer_delete(&fei->timer);
}
mutex_unlock(&fei->lock);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index a5db9b4dc3de..2ddf1dfa0522 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -471,7 +471,7 @@ static int cadet_release(struct file *file)
mutex_lock(&dev->lock);
if (v4l2_fh_is_singular_file(file) && dev->rdsstat) {
- del_timer_sync(&dev->readtimer);
+ timer_delete_sync(&dev->readtimer);
dev->rdsstat = 0;
}
v4l2_fh_release(file);
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index 67722e2e47ff..9435cba3f4d9 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -1104,7 +1104,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
unsigned long flags;
rc_unregister_device(dev->rdev);
- del_timer_sync(&dev->tx_sim_timer);
+ timer_delete_sync(&dev->tx_sim_timer);
spin_lock_irqsave(&dev->hw_lock, flags);
ene_rx_disable(dev);
ene_rx_restore_hw_buffer(dev);
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index 1464ef9c55bc..bfe86588c69b 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -223,7 +223,7 @@ static int igorplugusb_probe(struct usb_interface *intf,
return 0;
fail:
usb_poison_urb(ir->urb);
- del_timer(&ir->timer);
+ timer_delete(&ir->timer);
usb_unpoison_urb(ir->urb);
usb_free_urb(ir->urb);
rc_free_device(ir->rc);
@@ -238,7 +238,7 @@ static void igorplugusb_disconnect(struct usb_interface *intf)
rc_unregister_device(ir->rc);
usb_poison_urb(ir->urb);
- del_timer_sync(&ir->timer);
+ timer_delete_sync(&ir->timer);
usb_set_intfdata(intf, NULL);
usb_unpoison_urb(ir->urb);
usb_free_urb(ir->urb);
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
index 5da7479c1793..da89ddf771c3 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -556,8 +556,8 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
* acquires the lock and we don't want to deadlock waiting for it.
*/
spin_unlock_irq(&priv->lock);
- del_timer_sync(&hw->end_timer);
- del_timer_sync(&hw->suspend_timer);
+ timer_delete_sync(&hw->end_timer);
+ timer_delete_sync(&hw->suspend_timer);
spin_lock_irq(&priv->lock);
hw->stopping = false;
diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
index 8b0bdd9603b3..669f3309e237 100644
--- a/drivers/media/rc/img-ir/img-ir-raw.c
+++ b/drivers/media/rc/img-ir/img-ir-raw.c
@@ -147,5 +147,5 @@ void img_ir_remove_raw(struct img_ir_priv *priv)
rc_unregister_device(rdev);
- del_timer_sync(&raw->timer);
+ timer_delete_sync(&raw->timer);
}
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 8f1361bcce3a..cb6f36ebe5c8 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -2534,7 +2534,7 @@ static void imon_disconnect(struct usb_interface *interface)
ictx->dev_present_intf1 = false;
usb_kill_urb(ictx->rx_urb_intf1);
if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
- del_timer_sync(&ictx->ttimer);
+ timer_delete_sync(&ictx->ttimer);
input_unregister_device(ictx->touch);
}
usb_put_dev(ictx->usbdev_intf1);
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index 66e8feb9a569..817030fb50c9 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -324,7 +324,7 @@ again:
msecs_to_jiffies(100);
mod_timer(&data->rx_timeout, jiffies + delay);
} else {
- del_timer(&data->rx_timeout);
+ timer_delete(&data->rx_timeout);
}
/* Pass data to keyboard buffer parser */
ir_mce_kbd_process_keyboard_data(dev, scancode);
@@ -372,7 +372,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
{
struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
- del_timer_sync(&mce_kbd->rx_timeout);
+ timer_delete_sync(&mce_kbd->rx_timeout);
return 0;
}
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 16e33d7eaaa2..aa4ac43c66fa 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -662,7 +662,7 @@ void ir_raw_event_unregister(struct rc_dev *dev)
return;
kthread_stop(dev->raw->thread);
- del_timer_sync(&dev->raw->edge_handle);
+ timer_delete_sync(&dev->raw->edge_handle);
mutex_lock(&ir_raw_handler_lock);
list_del(&dev->raw->list);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index a4c539b17cf3..e46358fb8ac0 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -639,7 +639,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync)
return;
dev_dbg(&dev->dev, "keyup key 0x%04x\n", dev->last_keycode);
- del_timer(&dev->timer_repeat);
+ timer_delete(&dev->timer_repeat);
input_report_key(dev->input_dev, dev->last_keycode, 0);
led_trigger_event(led_feedback, LED_OFF);
if (sync)
@@ -2021,8 +2021,8 @@ void rc_unregister_device(struct rc_dev *dev)
if (dev->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(dev);
- del_timer_sync(&dev->timer_keyup);
- del_timer_sync(&dev->timer_repeat);
+ timer_delete_sync(&dev->timer_keyup);
+ timer_delete_sync(&dev->timer_repeat);
mutex_lock(&dev->lock);
if (dev->users && dev->close)
diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c
index fc5fd3927177..992fff82b524 100644
--- a/drivers/media/rc/serial_ir.c
+++ b/drivers/media/rc/serial_ir.c
@@ -798,7 +798,7 @@ static int __init serial_ir_init_module(void)
static void __exit serial_ir_exit_module(void)
{
- del_timer_sync(&serial_ir.timeout_timer);
+ timer_delete_sync(&serial_ir.timeout_timer);
serial_ir_exit();
}
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 09f9948c6f8e..3666f4452d11 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -143,7 +143,7 @@ static void urb_completion(struct urb *purb)
*/
dprintk(1, "%s cancelling bulk timeout\n", __func__);
dev->bulk_timeout_running = 0;
- del_timer(&dev->bulk_timeout);
+ timer_delete(&dev->bulk_timeout);
}
/* Feed the transport payload into the kernel demux */
@@ -168,7 +168,7 @@ static int stop_urb_transfer(struct au0828_dev *dev)
if (dev->bulk_timeout_running == 1) {
dev->bulk_timeout_running = 0;
- del_timer(&dev->bulk_timeout);
+ timer_delete(&dev->bulk_timeout);
}
dev->urb_streaming = false;
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index e9cd2a335f7f..33d1fad0f7b8 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -857,7 +857,7 @@ static void au0828_stop_streaming(struct vb2_queue *vq)
}
dev->vid_timeout_running = 0;
- del_timer_sync(&dev->vid_timeout);
+ timer_delete_sync(&dev->vid_timeout);
spin_lock_irqsave(&dev->slock, flags);
if (dev->isoc_ctl.buf != NULL) {
@@ -905,7 +905,7 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq)
spin_unlock_irqrestore(&dev->slock, flags);
dev->vbi_timeout_running = 0;
- del_timer_sync(&dev->vbi_timeout);
+ timer_delete_sync(&dev->vbi_timeout);
}
static const struct vb2_ops au0828_video_qops = {
@@ -1040,12 +1040,12 @@ static int au0828_v4l2_close(struct file *filp)
if (vdev->vfl_type == VFL_TYPE_VIDEO && dev->vid_timeout_running) {
/* Cancel timeout thread in case they didn't call streamoff */
dev->vid_timeout_running = 0;
- del_timer_sync(&dev->vid_timeout);
+ timer_delete_sync(&dev->vid_timeout);
} else if (vdev->vfl_type == VFL_TYPE_VBI &&
dev->vbi_timeout_running) {
/* Cancel timeout thread in case they didn't call streamoff */
dev->vbi_timeout_running = 0;
- del_timer_sync(&dev->vbi_timeout);
+ timer_delete_sync(&dev->vbi_timeout);
}
if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
@@ -1694,9 +1694,9 @@ void au0828_v4l2_suspend(struct au0828_dev *dev)
}
if (dev->vid_timeout_running)
- del_timer_sync(&dev->vid_timeout);
+ timer_delete_sync(&dev->vid_timeout);
if (dev->vbi_timeout_running)
- del_timer_sync(&dev->vbi_timeout);
+ timer_delete_sync(&dev->vbi_timeout);
}
void au0828_v4l2_resume(struct au0828_dev *dev)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
index c8102772344b..a5eabac1ec6e 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
@@ -257,7 +257,7 @@ rdData[0]);
ret = -EBUSY;
}
if (ret) {
- del_timer_sync(&hdw->encoder_run_timer);
+ timer_delete_sync(&hdw->encoder_run_timer);
hdw->state_encoder_ok = 0;
pvr2_trace(PVR2_TRACE_STBITS,
"State bit %s <-- %s",
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 29cc207194b9..9a583eeaa329 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -1527,7 +1527,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
/* Encoder is about to be reset so note that as far as we're
concerned now, the encoder has never been run. */
- del_timer_sync(&hdw->encoder_run_timer);
+ timer_delete_sync(&hdw->encoder_run_timer);
if (hdw->state_encoder_runok) {
hdw->state_encoder_runok = 0;
trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
@@ -3724,7 +3724,7 @@ status);
hdw->cmd_debug_state = 5;
/* Stop timer */
- del_timer_sync(&timer.timer);
+ timer_delete_sync(&timer.timer);
hdw->cmd_debug_state = 6;
status = 0;
@@ -4248,7 +4248,7 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw)
hdw->state_encoder_waitok = 0;
trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
/* paranoia - solve race if timer just completed */
- del_timer_sync(&hdw->encoder_wait_timer);
+ timer_delete_sync(&hdw->encoder_wait_timer);
} else {
if (!hdw->state_pathway_ok ||
(hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
@@ -4261,7 +4261,7 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw)
anything has happened that might have disturbed
the encoder. This should be a rare case. */
if (timer_pending(&hdw->encoder_wait_timer)) {
- del_timer_sync(&hdw->encoder_wait_timer);
+ timer_delete_sync(&hdw->encoder_wait_timer);
}
if (hdw->state_encoder_waitok) {
/* Must clear the state - therefore we did
@@ -4399,7 +4399,7 @@ static int state_eval_encoder_run(struct pvr2_hdw *hdw)
if (hdw->state_encoder_run) {
if (!state_check_disable_encoder_run(hdw)) return 0;
if (hdw->state_encoder_ok) {
- del_timer_sync(&hdw->encoder_run_timer);
+ timer_delete_sync(&hdw->encoder_run_timer);
if (pvr2_encoder_stop(hdw) < 0) return !0;
}
hdw->state_encoder_run = 0;
@@ -4479,11 +4479,11 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
hdw->state_decoder_quiescent = 0;
hdw->state_decoder_run = 0;
/* paranoia - solve race if timer(s) just completed */
- del_timer_sync(&hdw->quiescent_timer);
+ timer_delete_sync(&hdw->quiescent_timer);
/* Kill the stabilization timer, in case we're killing the
encoder before the previous stabilization interval has
been properly timed. */
- del_timer_sync(&hdw->decoder_stabilization_timer);
+ timer_delete_sync(&hdw->decoder_stabilization_timer);
hdw->state_decoder_ready = 0;
} else {
if (!hdw->state_decoder_quiescent) {
@@ -4517,7 +4517,7 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
!hdw->state_pipeline_config ||
!hdw->state_encoder_config ||
!hdw->state_encoder_ok) return 0;
- del_timer_sync(&hdw->quiescent_timer);
+ timer_delete_sync(&hdw->quiescent_timer);
if (hdw->flag_decoder_missed) return 0;
if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
hdw->state_decoder_quiescent = 0;
diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
index 2d5d8245a1d3..e63f62690571 100644
--- a/drivers/memory/tegra/tegra210-emc-core.c
+++ b/drivers/memory/tegra/tegra210-emc-core.c
@@ -583,7 +583,7 @@ static void tegra210_emc_training_start(struct tegra210_emc *emc)
static void tegra210_emc_training_stop(struct tegra210_emc *emc)
{
- del_timer(&emc->training);
+ timer_delete(&emc->training);
}
static unsigned int tegra210_emc_get_temperature(struct tegra210_emc *emc)
@@ -666,7 +666,7 @@ reset:
static void tegra210_emc_poll_refresh_stop(struct tegra210_emc *emc)
{
atomic_set(&emc->refresh_poll, 0);
- del_timer_sync(&emc->refresh_timer);
+ timer_delete_sync(&emc->refresh_timer);
}
static void tegra210_emc_poll_refresh_start(struct tegra210_emc *emc)
diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
index f4398383ae06..7dc2c9987982 100644
--- a/drivers/memstick/core/ms_block.c
+++ b/drivers/memstick/core/ms_block.c
@@ -1510,7 +1510,7 @@ static void msb_cache_discard(struct msb_data *msb)
if (msb->cache_block_lba == MS_BLOCK_INVALID)
return;
- del_timer_sync(&msb->cache_flush_timer);
+ timer_delete_sync(&msb->cache_flush_timer);
dbg_verbose("Discarding the write cache");
msb->cache_block_lba = MS_BLOCK_INVALID;
@@ -2027,7 +2027,7 @@ static void msb_stop(struct memstick_dev *card)
msb->io_queue_stopped = true;
spin_unlock_irqrestore(&msb->q_lock, flags);
- del_timer_sync(&msb->cache_flush_timer);
+ timer_delete_sync(&msb->cache_flush_timer);
flush_workqueue(msb->io_queue);
spin_lock_irqsave(&msb->q_lock, flags);
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index e77eb8b0eb12..a5a9bb3f16be 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -469,7 +469,7 @@ static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
unsigned int t_val = 0;
int rc;
- del_timer(&host->timer);
+ timer_delete(&host->timer);
dev_dbg(&msh->dev, "c control %08x\n",
readl(host->addr + HOST_CONTROL));
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c
index 544a31ff46e5..488ef8eecb26 100644
--- a/drivers/memstick/host/r592.c
+++ b/drivers/memstick/host/r592.c
@@ -827,7 +827,7 @@ static void r592_remove(struct pci_dev *pdev)
/* Stop the processing thread.
That ensures that we won't take any more requests */
kthread_stop(dev->io_thread);
- del_timer_sync(&dev->detect_timer);
+ timer_delete_sync(&dev->detect_timer);
r592_enable_device(dev, false);
while (!error && dev->req) {
@@ -854,7 +854,7 @@ static int r592_suspend(struct device *core_dev)
r592_clear_interrupts(dev);
memstick_suspend_host(dev->host);
- del_timer_sync(&dev->detect_timer);
+ timer_delete_sync(&dev->detect_timer);
return 0;
}
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index c272453670be..676348eee015 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -337,7 +337,7 @@ static void tifm_ms_complete_cmd(struct tifm_ms *host)
struct memstick_host *msh = tifm_get_drvdata(sock);
int rc;
- del_timer(&host->timer);
+ timer_delete(&host->timer);
host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff;
host->req->int_reg = (host->req->int_reg & 1)
@@ -600,7 +600,7 @@ static void tifm_ms_remove(struct tifm_dev *sock)
spin_lock_irqsave(&sock->lock, flags);
host->eject = 1;
if (host->req) {
- del_timer(&host->timer);
+ timer_delete(&host->timer);
writel(TIFM_FIFO_INT_SETALL,
sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 56bc72c7ce4a..6b37d61150ee 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -641,7 +641,6 @@ source "drivers/misc/mei/Kconfig"
source "drivers/misc/vmw_vmci/Kconfig"
source "drivers/misc/genwqe/Kconfig"
source "drivers/misc/echo/Kconfig"
-source "drivers/misc/cxl/Kconfig"
source "drivers/misc/ocxl/Kconfig"
source "drivers/misc/bcm-vk/Kconfig"
source "drivers/misc/cardreader/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 545aad06d088..d6c917229c45 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -50,7 +50,6 @@ obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_SRAM_EXEC) += sram-exec.o
obj-$(CONFIG_GENWQE) += genwqe/
obj-$(CONFIG_ECHO) += echo/
-obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
obj-$(CONFIG_OCXL) += ocxl/
diff --git a/drivers/misc/bcm-vk/bcm_vk_tty.c b/drivers/misc/bcm-vk/bcm_vk_tty.c
index 59bab76ff0a9..44a2dd80054d 100644
--- a/drivers/misc/bcm-vk/bcm_vk_tty.c
+++ b/drivers/misc/bcm-vk/bcm_vk_tty.c
@@ -177,7 +177,7 @@ static void bcm_vk_tty_close(struct tty_struct *tty, struct file *file)
vk->tty[tty->index].is_opened = false;
if (tty->count == 1)
- del_timer_sync(&vk->serial_timer);
+ timer_delete_sync(&vk->serial_timer);
}
static void bcm_vk_tty_doorbell(struct bcm_vk *vk, u32 db_val)
@@ -304,7 +304,7 @@ void bcm_vk_tty_exit(struct bcm_vk *vk)
{
int i;
- del_timer_sync(&vk->serial_timer);
+ timer_delete_sync(&vk->serial_timer);
for (i = 0; i < BCM_VK_NUM_TTY; ++i) {
tty_port_unregister_device(&vk->tty[i].port,
vk->tty_drv,
diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
index 77b0490a1b38..7314c8d9ae75 100644
--- a/drivers/misc/cardreader/rtsx_usb.c
+++ b/drivers/misc/cardreader/rtsx_usb.c
@@ -53,7 +53,7 @@ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
add_timer(&ucr->sg_timer);
usb_sg_wait(&ucr->current_sg);
- if (!del_timer_sync(&ucr->sg_timer))
+ if (!timer_delete_sync(&ucr->sg_timer))
ret = -ETIMEDOUT;
else
ret = ucr->current_sg.status;
diff --git a/drivers/misc/cxl/Kconfig b/drivers/misc/cxl/Kconfig
deleted file mode 100644
index 15307f5e4307..000000000000
--- a/drivers/misc/cxl/Kconfig
+++ /dev/null
@@ -1,28 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# IBM Coherent Accelerator (CXL) compatible devices
-#
-
-config CXL_BASE
- bool
- select PPC_COPRO_BASE
- select PPC_64S_HASH_MMU
-
-config CXL
- tristate "Support for IBM Coherent Accelerators (CXL) (DEPRECATED)"
- depends on PPC_POWERNV && PCI_MSI && EEH
- select CXL_BASE
- help
- The cxl driver is deprecated and will be removed in a future
- kernel release.
-
- Select this option to enable driver support for IBM Coherent
- Accelerators (CXL). CXL is otherwise known as Coherent Accelerator
- Processor Interface (CAPI). CAPI allows accelerators in FPGAs to be
- coherently attached to a CPU via an MMU. This driver enables
- userspace programs to access these accelerators via /dev/cxl/afuM.N
- devices.
-
- CAPI adapters are found in POWER8 based systems.
-
- If unsure, say N.
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
deleted file mode 100644
index 5eea61b9584f..000000000000
--- a/drivers/misc/cxl/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ccflags-y := $(call cc-disable-warning, unused-const-variable)
-ccflags-$(CONFIG_PPC_WERROR) += -Werror
-
-cxl-y += main.o file.o irq.o fault.o native.o
-cxl-y += context.o sysfs.o pci.o trace.o
-cxl-y += vphb.o api.o cxllib.o
-cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o
-cxl-$(CONFIG_DEBUG_FS) += debugfs.o
-obj-$(CONFIG_CXL) += cxl.o
-obj-$(CONFIG_CXL_BASE) += base.o
-
-# For tracepoints to include our trace.h from tracepoint infrastructure:
-CFLAGS_trace.o := -I$(src)
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
deleted file mode 100644
index d85c56530863..000000000000
--- a/drivers/misc/cxl/api.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/file.h>
-#include <misc/cxl.h>
-#include <linux/module.h>
-#include <linux/mount.h>
-#include <linux/pseudo_fs.h>
-#include <linux/sched/mm.h>
-#include <linux/mmu_context.h>
-#include <linux/irqdomain.h>
-
-#include "cxl.h"
-
-/*
- * Since we want to track memory mappings to be able to force-unmap
- * when the AFU is no longer reachable, we need an inode. For devices
- * opened through the cxl user API, this is not a problem, but a
- * userland process can also get a cxl fd through the cxl_get_fd()
- * API, which is used by the cxlflash driver.
- *
- * Therefore we implement our own simple pseudo-filesystem and inode
- * allocator. We don't use the anonymous inode, as we need the
- * meta-data associated with it (address_space) and it is shared by
- * other drivers/processes, so it could lead to cxl unmapping VMAs
- * from random processes.
- */
-
-#define CXL_PSEUDO_FS_MAGIC 0x1697697f
-
-static int cxl_fs_cnt;
-static struct vfsmount *cxl_vfs_mount;
-
-static int cxl_fs_init_fs_context(struct fs_context *fc)
-{
- return init_pseudo(fc, CXL_PSEUDO_FS_MAGIC) ? 0 : -ENOMEM;
-}
-
-static struct file_system_type cxl_fs_type = {
- .name = "cxl",
- .owner = THIS_MODULE,
- .init_fs_context = cxl_fs_init_fs_context,
- .kill_sb = kill_anon_super,
-};
-
-
-void cxl_release_mapping(struct cxl_context *ctx)
-{
- if (ctx->kernelapi && ctx->mapping)
- simple_release_fs(&cxl_vfs_mount, &cxl_fs_cnt);
-}
-
-static struct file *cxl_getfile(const char *name,
- const struct file_operations *fops,
- void *priv, int flags)
-{
- struct file *file;
- struct inode *inode;
- int rc;
-
- /* strongly inspired by anon_inode_getfile() */
-
- if (fops->owner && !try_module_get(fops->owner))
- return ERR_PTR(-ENOENT);
-
- rc = simple_pin_fs(&cxl_fs_type, &cxl_vfs_mount, &cxl_fs_cnt);
- if (rc < 0) {
- pr_err("Cannot mount cxl pseudo filesystem: %d\n", rc);
- file = ERR_PTR(rc);
- goto err_module;
- }
-
- inode = alloc_anon_inode(cxl_vfs_mount->mnt_sb);
- if (IS_ERR(inode)) {
- file = ERR_CAST(inode);
- goto err_fs;
- }
-
- file = alloc_file_pseudo(inode, cxl_vfs_mount, name,
- flags & (O_ACCMODE | O_NONBLOCK), fops);
- if (IS_ERR(file))
- goto err_inode;
-
- file->private_data = priv;
-
- return file;
-
-err_inode:
- iput(inode);
-err_fs:
- simple_release_fs(&cxl_vfs_mount, &cxl_fs_cnt);
-err_module:
- module_put(fops->owner);
- return file;
-}
-
-struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
-{
- struct cxl_afu *afu;
- struct cxl_context *ctx;
- int rc;
-
- afu = cxl_pci_to_afu(dev);
- if (IS_ERR(afu))
- return ERR_CAST(afu);
-
- ctx = cxl_context_alloc();
- if (!ctx)
- return ERR_PTR(-ENOMEM);
-
- ctx->kernelapi = true;
-
- /* Make it a slave context. We can promote it later? */
- rc = cxl_context_init(ctx, afu, false);
- if (rc)
- goto err_ctx;
-
- return ctx;
-
-err_ctx:
- kfree(ctx);
- return ERR_PTR(rc);
-}
-EXPORT_SYMBOL_GPL(cxl_dev_context_init);
-
-struct cxl_context *cxl_get_context(struct pci_dev *dev)
-{
- return dev->dev.archdata.cxl_ctx;
-}
-EXPORT_SYMBOL_GPL(cxl_get_context);
-
-int cxl_release_context(struct cxl_context *ctx)
-{
- if (ctx->status >= STARTED)
- return -EBUSY;
-
- cxl_context_free(ctx);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxl_release_context);
-
-static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
-{
- __u16 range;
- int r;
-
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- range = ctx->irqs.range[r];
- if (num < range) {
- return ctx->irqs.offset[r] + num;
- }
- num -= range;
- }
- return 0;
-}
-
-
-int cxl_set_priv(struct cxl_context *ctx, void *priv)
-{
- if (!ctx)
- return -EINVAL;
-
- ctx->priv = priv;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxl_set_priv);
-
-void *cxl_get_priv(struct cxl_context *ctx)
-{
- if (!ctx)
- return ERR_PTR(-EINVAL);
-
- return ctx->priv;
-}
-EXPORT_SYMBOL_GPL(cxl_get_priv);
-
-int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
-{
- int res;
- irq_hw_number_t hwirq;
-
- if (num == 0)
- num = ctx->afu->pp_irqs;
- res = afu_allocate_irqs(ctx, num);
- if (res)
- return res;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE)) {
- /* In a guest, the PSL interrupt is not multiplexed. It was
- * allocated above, and we need to set its handler
- */
- hwirq = cxl_find_afu_irq(ctx, 0);
- if (hwirq)
- cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl");
- }
-
- if (ctx->status == STARTED) {
- if (cxl_ops->update_ivtes)
- cxl_ops->update_ivtes(ctx);
- else WARN(1, "BUG: cxl_allocate_afu_irqs must be called prior to starting the context on this platform\n");
- }
-
- return res;
-}
-EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
-
-void cxl_free_afu_irqs(struct cxl_context *ctx)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE)) {
- hwirq = cxl_find_afu_irq(ctx, 0);
- if (hwirq) {
- virq = irq_find_mapping(NULL, hwirq);
- if (virq)
- cxl_unmap_irq(virq, ctx);
- }
- }
- afu_irq_name_free(ctx);
- cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
-}
-EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
-
-int cxl_map_afu_irq(struct cxl_context *ctx, int num,
- irq_handler_t handler, void *cookie, char *name)
-{
- irq_hw_number_t hwirq;
-
- /*
- * Find interrupt we are to register.
- */
- hwirq = cxl_find_afu_irq(ctx, num);
- if (!hwirq)
- return -ENOENT;
-
- return cxl_map_irq(ctx->afu->adapter, hwirq, handler, cookie, name);
-}
-EXPORT_SYMBOL_GPL(cxl_map_afu_irq);
-
-void cxl_unmap_afu_irq(struct cxl_context *ctx, int num, void *cookie)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
-
- hwirq = cxl_find_afu_irq(ctx, num);
- if (!hwirq)
- return;
-
- virq = irq_find_mapping(NULL, hwirq);
- if (virq)
- cxl_unmap_irq(virq, cookie);
-}
-EXPORT_SYMBOL_GPL(cxl_unmap_afu_irq);
-
-/*
- * Start a context
- * Code here similar to afu_ioctl_start_work().
- */
-int cxl_start_context(struct cxl_context *ctx, u64 wed,
- struct task_struct *task)
-{
- int rc = 0;
- bool kernel = true;
-
- pr_devel("%s: pe: %i\n", __func__, ctx->pe);
-
- mutex_lock(&ctx->status_mutex);
- if (ctx->status == STARTED)
- goto out; /* already started */
-
- /*
- * Increment the mapped context count for adapter. This also checks
- * if adapter_context_lock is taken.
- */
- rc = cxl_adapter_context_get(ctx->afu->adapter);
- if (rc)
- goto out;
-
- if (task) {
- ctx->pid = get_task_pid(task, PIDTYPE_PID);
- kernel = false;
-
- /* acquire a reference to the task's mm */
- ctx->mm = get_task_mm(current);
-
- /* ensure this mm_struct can't be freed */
- cxl_context_mm_count_get(ctx);
-
- if (ctx->mm) {
- /* decrement the use count from above */
- mmput(ctx->mm);
- /* make TLBIs for this context global */
- mm_context_add_copro(ctx->mm);
- }
- }
-
- /*
- * Increment driver use count. Enables global TLBIs for hash
- * and callbacks to handle the segment table
- */
- cxl_ctx_get();
-
- /* See the comment in afu_ioctl_start_work() */
- smp_mb();
-
- if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
- put_pid(ctx->pid);
- ctx->pid = NULL;
- cxl_adapter_context_put(ctx->afu->adapter);
- cxl_ctx_put();
- if (task) {
- cxl_context_mm_count_put(ctx);
- if (ctx->mm)
- mm_context_remove_copro(ctx->mm);
- }
- goto out;
- }
-
- ctx->status = STARTED;
-out:
- mutex_unlock(&ctx->status_mutex);
- return rc;
-}
-EXPORT_SYMBOL_GPL(cxl_start_context);
-
-int cxl_process_element(struct cxl_context *ctx)
-{
- return ctx->external_pe;
-}
-EXPORT_SYMBOL_GPL(cxl_process_element);
-
-/* Stop a context. Returns 0 on success, otherwise -Errno */
-int cxl_stop_context(struct cxl_context *ctx)
-{
- return __detach_context(ctx);
-}
-EXPORT_SYMBOL_GPL(cxl_stop_context);
-
-void cxl_set_master(struct cxl_context *ctx)
-{
- ctx->master = true;
-}
-EXPORT_SYMBOL_GPL(cxl_set_master);
-
-/* wrappers around afu_* file ops which are EXPORTED */
-int cxl_fd_open(struct inode *inode, struct file *file)
-{
- return afu_open(inode, file);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_open);
-int cxl_fd_release(struct inode *inode, struct file *file)
-{
- return afu_release(inode, file);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_release);
-long cxl_fd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- return afu_ioctl(file, cmd, arg);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_ioctl);
-int cxl_fd_mmap(struct file *file, struct vm_area_struct *vm)
-{
- return afu_mmap(file, vm);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_mmap);
-__poll_t cxl_fd_poll(struct file *file, struct poll_table_struct *poll)
-{
- return afu_poll(file, poll);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_poll);
-ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
- loff_t *off)
-{
- return afu_read(file, buf, count, off);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_read);
-
-#define PATCH_FOPS(NAME) if (!fops->NAME) fops->NAME = afu_fops.NAME
-
-/* Get a struct file and fd for a context and attach the ops */
-struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops,
- int *fd)
-{
- struct file *file;
- int rc, flags, fdtmp;
- char *name = NULL;
-
- /* only allow one per context */
- if (ctx->mapping)
- return ERR_PTR(-EEXIST);
-
- flags = O_RDWR | O_CLOEXEC;
-
- /* This code is similar to anon_inode_getfd() */
- rc = get_unused_fd_flags(flags);
- if (rc < 0)
- return ERR_PTR(rc);
- fdtmp = rc;
-
- /*
- * Patch the file ops. Needs to be careful that this is rentrant safe.
- */
- if (fops) {
- PATCH_FOPS(open);
- PATCH_FOPS(poll);
- PATCH_FOPS(read);
- PATCH_FOPS(release);
- PATCH_FOPS(unlocked_ioctl);
- PATCH_FOPS(compat_ioctl);
- PATCH_FOPS(mmap);
- } else /* use default ops */
- fops = (struct file_operations *)&afu_fops;
-
- name = kasprintf(GFP_KERNEL, "cxl:%d", ctx->pe);
- file = cxl_getfile(name, fops, ctx, flags);
- kfree(name);
- if (IS_ERR(file))
- goto err_fd;
-
- cxl_context_set_mapping(ctx, file->f_mapping);
- *fd = fdtmp;
- return file;
-
-err_fd:
- put_unused_fd(fdtmp);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(cxl_get_fd);
-
-struct cxl_context *cxl_fops_get_context(struct file *file)
-{
- return file->private_data;
-}
-EXPORT_SYMBOL_GPL(cxl_fops_get_context);
-
-void cxl_set_driver_ops(struct cxl_context *ctx,
- struct cxl_afu_driver_ops *ops)
-{
- WARN_ON(!ops->fetch_event || !ops->event_delivered);
- atomic_set(&ctx->afu_driver_events, 0);
- ctx->afu_driver_ops = ops;
-}
-EXPORT_SYMBOL_GPL(cxl_set_driver_ops);
-
-void cxl_context_events_pending(struct cxl_context *ctx,
- unsigned int new_events)
-{
- atomic_add(new_events, &ctx->afu_driver_events);
- wake_up_all(&ctx->wq);
-}
-EXPORT_SYMBOL_GPL(cxl_context_events_pending);
-
-int cxl_start_work(struct cxl_context *ctx,
- struct cxl_ioctl_start_work *work)
-{
- int rc;
-
- /* code taken from afu_ioctl_start_work */
- if (!(work->flags & CXL_START_WORK_NUM_IRQS))
- work->num_interrupts = ctx->afu->pp_irqs;
- else if ((work->num_interrupts < ctx->afu->pp_irqs) ||
- (work->num_interrupts > ctx->afu->irqs_max)) {
- return -EINVAL;
- }
-
- rc = afu_register_irqs(ctx, work->num_interrupts);
- if (rc)
- return rc;
-
- rc = cxl_start_context(ctx, work->work_element_descriptor, current);
- if (rc < 0) {
- afu_release_irqs(ctx, ctx);
- return rc;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxl_start_work);
-
-void __iomem *cxl_psa_map(struct cxl_context *ctx)
-{
- if (ctx->status != STARTED)
- return NULL;
-
- pr_devel("%s: psn_phys%llx size:%llx\n",
- __func__, ctx->psn_phys, ctx->psn_size);
- return ioremap(ctx->psn_phys, ctx->psn_size);
-}
-EXPORT_SYMBOL_GPL(cxl_psa_map);
-
-void cxl_psa_unmap(void __iomem *addr)
-{
- iounmap(addr);
-}
-EXPORT_SYMBOL_GPL(cxl_psa_unmap);
-
-int cxl_afu_reset(struct cxl_context *ctx)
-{
- struct cxl_afu *afu = ctx->afu;
- int rc;
-
- rc = cxl_ops->afu_reset(afu);
- if (rc)
- return rc;
-
- return cxl_ops->afu_check_and_enable(afu);
-}
-EXPORT_SYMBOL_GPL(cxl_afu_reset);
-
-void cxl_perst_reloads_same_image(struct cxl_afu *afu,
- bool perst_reloads_same_image)
-{
- afu->adapter->perst_same_image = perst_reloads_same_image;
-}
-EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
-
-ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count)
-{
- struct cxl_afu *afu = cxl_pci_to_afu(dev);
- if (IS_ERR(afu))
- return -ENODEV;
-
- return cxl_ops->read_adapter_vpd(afu->adapter, buf, count);
-}
-EXPORT_SYMBOL_GPL(cxl_read_adapter_vpd);
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c
deleted file mode 100644
index b054562c046e..000000000000
--- a/drivers/misc/cxl/base.c
+++ /dev/null
@@ -1,126 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/module.h>
-#include <linux/rcupdate.h>
-#include <asm/errno.h>
-#include <misc/cxl-base.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include "cxl.h"
-
-/* protected by rcu */
-static struct cxl_calls *cxl_calls;
-
-atomic_t cxl_use_count = ATOMIC_INIT(0);
-EXPORT_SYMBOL(cxl_use_count);
-
-#ifdef CONFIG_CXL_MODULE
-
-static inline struct cxl_calls *cxl_calls_get(void)
-{
- struct cxl_calls *calls = NULL;
-
- rcu_read_lock();
- calls = rcu_dereference(cxl_calls);
- if (calls && !try_module_get(calls->owner))
- calls = NULL;
- rcu_read_unlock();
-
- return calls;
-}
-
-static inline void cxl_calls_put(struct cxl_calls *calls)
-{
- BUG_ON(calls != cxl_calls);
-
- /* we don't need to rcu this, as we hold a reference to the module */
- module_put(cxl_calls->owner);
-}
-
-#else /* !defined CONFIG_CXL_MODULE */
-
-static inline struct cxl_calls *cxl_calls_get(void)
-{
- return cxl_calls;
-}
-
-static inline void cxl_calls_put(struct cxl_calls *calls) { }
-
-#endif /* CONFIG_CXL_MODULE */
-
-/* AFU refcount management */
-struct cxl_afu *cxl_afu_get(struct cxl_afu *afu)
-{
- return (get_device(&afu->dev) == NULL) ? NULL : afu;
-}
-EXPORT_SYMBOL_GPL(cxl_afu_get);
-
-void cxl_afu_put(struct cxl_afu *afu)
-{
- put_device(&afu->dev);
-}
-EXPORT_SYMBOL_GPL(cxl_afu_put);
-
-void cxl_slbia(struct mm_struct *mm)
-{
- struct cxl_calls *calls;
-
- calls = cxl_calls_get();
- if (!calls)
- return;
-
- if (cxl_ctx_in_use())
- calls->cxl_slbia(mm);
-
- cxl_calls_put(calls);
-}
-
-int register_cxl_calls(struct cxl_calls *calls)
-{
- if (cxl_calls)
- return -EBUSY;
-
- rcu_assign_pointer(cxl_calls, calls);
- return 0;
-}
-EXPORT_SYMBOL_GPL(register_cxl_calls);
-
-void unregister_cxl_calls(struct cxl_calls *calls)
-{
- BUG_ON(cxl_calls->owner != calls->owner);
- RCU_INIT_POINTER(cxl_calls, NULL);
- synchronize_rcu();
-}
-EXPORT_SYMBOL_GPL(unregister_cxl_calls);
-
-int cxl_update_properties(struct device_node *dn,
- struct property *new_prop)
-{
- return of_update_property(dn, new_prop);
-}
-EXPORT_SYMBOL_GPL(cxl_update_properties);
-
-static int __init cxl_base_init(void)
-{
- struct device_node *np;
- struct platform_device *dev;
- int count = 0;
-
- /*
- * Scan for compatible devices in guest only
- */
- if (cpu_has_feature(CPU_FTR_HVMODE))
- return 0;
-
- for_each_compatible_node(np, NULL, "ibm,coherent-platform-facility") {
- dev = of_platform_device_create(np, NULL, NULL);
- if (dev)
- count++;
- }
- pr_devel("Found %d cxl device(s)\n", count);
- return 0;
-}
-device_initcall(cxl_base_init);
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
deleted file mode 100644
index 76b5ea66dfa1..000000000000
--- a/drivers/misc/cxl/context.c
+++ /dev/null
@@ -1,362 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/sched.h>
-#include <linux/pid.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/idr.h>
-#include <linux/sched/mm.h>
-#include <linux/mmu_context.h>
-#include <asm/cputable.h>
-#include <asm/current.h>
-#include <asm/copro.h>
-
-#include "cxl.h"
-
-/*
- * Allocates space for a CXL context.
- */
-struct cxl_context *cxl_context_alloc(void)
-{
- return kzalloc(sizeof(struct cxl_context), GFP_KERNEL);
-}
-
-/*
- * Initialises a CXL context.
- */
-int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
-{
- int i;
-
- ctx->afu = afu;
- ctx->master = master;
- ctx->pid = NULL; /* Set in start work ioctl */
- mutex_init(&ctx->mapping_lock);
- ctx->mapping = NULL;
- ctx->tidr = 0;
- ctx->assign_tidr = false;
-
- if (cxl_is_power8()) {
- spin_lock_init(&ctx->sste_lock);
-
- /*
- * Allocate the segment table before we put it in the IDR so that we
- * can always access it when dereferenced from IDR. For the same
- * reason, the segment table is only destroyed after the context is
- * removed from the IDR. Access to this in the IOCTL is protected by
- * Linux filesystem semantics (can't IOCTL until open is complete).
- */
- i = cxl_alloc_sst(ctx);
- if (i)
- return i;
- }
-
- INIT_WORK(&ctx->fault_work, cxl_handle_fault);
-
- init_waitqueue_head(&ctx->wq);
- spin_lock_init(&ctx->lock);
-
- ctx->irq_bitmap = NULL;
- ctx->pending_irq = false;
- ctx->pending_fault = false;
- ctx->pending_afu_err = false;
-
- INIT_LIST_HEAD(&ctx->irq_names);
-
- /*
- * When we have to destroy all contexts in cxl_context_detach_all() we
- * end up with afu_release_irqs() called from inside a
- * idr_for_each_entry(). Hence we need to make sure that anything
- * dereferenced from this IDR is ok before we allocate the IDR here.
- * This clears out the IRQ ranges to ensure this.
- */
- for (i = 0; i < CXL_IRQ_RANGES; i++)
- ctx->irqs.range[i] = 0;
-
- mutex_init(&ctx->status_mutex);
-
- ctx->status = OPENED;
-
- /*
- * Allocating IDR! We better make sure everything's setup that
- * dereferences from it.
- */
- mutex_lock(&afu->contexts_lock);
- idr_preload(GFP_KERNEL);
- i = idr_alloc(&ctx->afu->contexts_idr, ctx, 0,
- ctx->afu->num_procs, GFP_NOWAIT);
- idr_preload_end();
- mutex_unlock(&afu->contexts_lock);
- if (i < 0)
- return i;
-
- ctx->pe = i;
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- ctx->elem = &ctx->afu->native->spa[i];
- ctx->external_pe = ctx->pe;
- } else {
- ctx->external_pe = -1; /* assigned when attaching */
- }
- ctx->pe_inserted = false;
-
- /*
- * take a ref on the afu so that it stays alive at-least till
- * this context is reclaimed inside reclaim_ctx.
- */
- cxl_afu_get(afu);
- return 0;
-}
-
-void cxl_context_set_mapping(struct cxl_context *ctx,
- struct address_space *mapping)
-{
- mutex_lock(&ctx->mapping_lock);
- ctx->mapping = mapping;
- mutex_unlock(&ctx->mapping_lock);
-}
-
-static vm_fault_t cxl_mmap_fault(struct vm_fault *vmf)
-{
- struct vm_area_struct *vma = vmf->vma;
- struct cxl_context *ctx = vma->vm_file->private_data;
- u64 area, offset;
- vm_fault_t ret;
-
- offset = vmf->pgoff << PAGE_SHIFT;
-
- pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n",
- __func__, ctx->pe, vmf->address, offset);
-
- if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
- area = ctx->afu->psn_phys;
- if (offset >= ctx->afu->adapter->ps_size)
- return VM_FAULT_SIGBUS;
- } else {
- area = ctx->psn_phys;
- if (offset >= ctx->psn_size)
- return VM_FAULT_SIGBUS;
- }
-
- mutex_lock(&ctx->status_mutex);
-
- if (ctx->status != STARTED) {
- mutex_unlock(&ctx->status_mutex);
- pr_devel("%s: Context not started, failing problem state access\n", __func__);
- if (ctx->mmio_err_ff) {
- if (!ctx->ff_page) {
- ctx->ff_page = alloc_page(GFP_USER);
- if (!ctx->ff_page)
- return VM_FAULT_OOM;
- memset(page_address(ctx->ff_page), 0xff, PAGE_SIZE);
- }
- get_page(ctx->ff_page);
- vmf->page = ctx->ff_page;
- vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
- return 0;
- }
- return VM_FAULT_SIGBUS;
- }
-
- ret = vmf_insert_pfn(vma, vmf->address, (area + offset) >> PAGE_SHIFT);
-
- mutex_unlock(&ctx->status_mutex);
-
- return ret;
-}
-
-static const struct vm_operations_struct cxl_mmap_vmops = {
- .fault = cxl_mmap_fault,
-};
-
-/*
- * Map a per-context mmio space into the given vma.
- */
-int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
-{
- u64 start = vma->vm_pgoff << PAGE_SHIFT;
- u64 len = vma->vm_end - vma->vm_start;
-
- if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
- if (start + len > ctx->afu->adapter->ps_size)
- return -EINVAL;
-
- if (cxl_is_power9()) {
- /*
- * Make sure there is a valid problem state
- * area space for this AFU.
- */
- if (ctx->master && !ctx->afu->psa) {
- pr_devel("AFU doesn't support mmio space\n");
- return -EINVAL;
- }
-
- /* Can't mmap until the AFU is enabled */
- if (!ctx->afu->enabled)
- return -EBUSY;
- }
- } else {
- if (start + len > ctx->psn_size)
- return -EINVAL;
-
- /* Make sure there is a valid per process space for this AFU */
- if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) {
- pr_devel("AFU doesn't support mmio space\n");
- return -EINVAL;
- }
-
- /* Can't mmap until the AFU is enabled */
- if (!ctx->afu->enabled)
- return -EBUSY;
- }
-
- pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__,
- ctx->psn_phys, ctx->pe , ctx->master);
-
- vm_flags_set(vma, VM_IO | VM_PFNMAP);
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- vma->vm_ops = &cxl_mmap_vmops;
- return 0;
-}
-
-/*
- * Detach a context from the hardware. This disables interrupts and doesn't
- * return until all outstanding interrupts for this context have completed. The
- * hardware should no longer access *ctx after this has returned.
- */
-int __detach_context(struct cxl_context *ctx)
-{
- enum cxl_context_status status;
-
- mutex_lock(&ctx->status_mutex);
- status = ctx->status;
- ctx->status = CLOSED;
- mutex_unlock(&ctx->status_mutex);
- if (status != STARTED)
- return -EBUSY;
-
- /* Only warn if we detached while the link was OK.
- * If detach fails when hw is down, we don't care.
- */
- WARN_ON(cxl_ops->detach_process(ctx) &&
- cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
- flush_work(&ctx->fault_work); /* Only needed for dedicated process */
-
- /*
- * Wait until no further interrupts are presented by the PSL
- * for this context.
- */
- if (cxl_ops->irq_wait)
- cxl_ops->irq_wait(ctx);
-
- /* release the reference to the group leader and mm handling pid */
- put_pid(ctx->pid);
-
- cxl_ctx_put();
-
- /* Decrease the attached context count on the adapter */
- cxl_adapter_context_put(ctx->afu->adapter);
-
- /* Decrease the mm count on the context */
- cxl_context_mm_count_put(ctx);
- if (ctx->mm)
- mm_context_remove_copro(ctx->mm);
- ctx->mm = NULL;
-
- return 0;
-}
-
-/*
- * Detach the given context from the AFU. This doesn't actually
- * free the context but it should stop the context running in hardware
- * (ie. prevent this context from generating any further interrupts
- * so that it can be freed).
- */
-void cxl_context_detach(struct cxl_context *ctx)
-{
- int rc;
-
- rc = __detach_context(ctx);
- if (rc)
- return;
-
- afu_release_irqs(ctx, ctx);
- wake_up_all(&ctx->wq);
-}
-
-/*
- * Detach all contexts on the given AFU.
- */
-void cxl_context_detach_all(struct cxl_afu *afu)
-{
- struct cxl_context *ctx;
- int tmp;
-
- mutex_lock(&afu->contexts_lock);
- idr_for_each_entry(&afu->contexts_idr, ctx, tmp) {
- /*
- * Anything done in here needs to be setup before the IDR is
- * created and torn down after the IDR removed
- */
- cxl_context_detach(ctx);
-
- /*
- * We are force detaching - remove any active PSA mappings so
- * userspace cannot interfere with the card if it comes back.
- * Easiest way to exercise this is to unbind and rebind the
- * driver via sysfs while it is in use.
- */
- mutex_lock(&ctx->mapping_lock);
- if (ctx->mapping)
- unmap_mapping_range(ctx->mapping, 0, 0, 1);
- mutex_unlock(&ctx->mapping_lock);
- }
- mutex_unlock(&afu->contexts_lock);
-}
-
-static void reclaim_ctx(struct rcu_head *rcu)
-{
- struct cxl_context *ctx = container_of(rcu, struct cxl_context, rcu);
-
- if (cxl_is_power8())
- free_page((u64)ctx->sstp);
- if (ctx->ff_page)
- __free_page(ctx->ff_page);
- ctx->sstp = NULL;
-
- bitmap_free(ctx->irq_bitmap);
-
- /* Drop ref to the afu device taken during cxl_context_init */
- cxl_afu_put(ctx->afu);
-
- kfree(ctx);
-}
-
-void cxl_context_free(struct cxl_context *ctx)
-{
- if (ctx->kernelapi && ctx->mapping)
- cxl_release_mapping(ctx);
- mutex_lock(&ctx->afu->contexts_lock);
- idr_remove(&ctx->afu->contexts_idr, ctx->pe);
- mutex_unlock(&ctx->afu->contexts_lock);
- call_rcu(&ctx->rcu, reclaim_ctx);
-}
-
-void cxl_context_mm_count_get(struct cxl_context *ctx)
-{
- if (ctx->mm)
- mmgrab(ctx->mm);
-}
-
-void cxl_context_mm_count_put(struct cxl_context *ctx)
-{
- if (ctx->mm)
- mmdrop(ctx->mm);
-}
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
deleted file mode 100644
index 6ad0ab892675..000000000000
--- a/drivers/misc/cxl/cxl.h
+++ /dev/null
@@ -1,1135 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#ifndef _CXL_H_
-#define _CXL_H_
-
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/device.h>
-#include <linux/types.h>
-#include <linux/cdev.h>
-#include <linux/pid.h>
-#include <linux/io.h>
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <asm/cputable.h>
-#include <asm/mmu.h>
-#include <asm/reg.h>
-#include <misc/cxl-base.h>
-
-#include <misc/cxl.h>
-#include <uapi/misc/cxl.h>
-
-extern uint cxl_verbose;
-
-struct property;
-
-#define CXL_TIMEOUT 5
-
-/*
- * Bump version each time a user API change is made, whether it is
- * backwards compatible ot not.
- */
-#define CXL_API_VERSION 3
-#define CXL_API_VERSION_COMPATIBLE 1
-
-/*
- * Opaque types to avoid accidentally passing registers for the wrong MMIO
- *
- * At the end of the day, I'm not married to using typedef here, but it might
- * (and has!) help avoid bugs like mixing up CXL_PSL_CtxTime and
- * CXL_PSL_CtxTime_An, or calling cxl_p1n_write instead of cxl_p1_write.
- *
- * I'm quite happy if these are changed back to #defines before upstreaming, it
- * should be little more than a regexp search+replace operation in this file.
- */
-typedef struct {
- const int x;
-} cxl_p1_reg_t;
-typedef struct {
- const int x;
-} cxl_p1n_reg_t;
-typedef struct {
- const int x;
-} cxl_p2n_reg_t;
-#define cxl_reg_off(reg) \
- (reg.x)
-
-/* Memory maps. Ref CXL Appendix A */
-
-/* PSL Privilege 1 Memory Map */
-/* Configuration and Control area - CAIA 1&2 */
-static const cxl_p1_reg_t CXL_PSL_CtxTime = {0x0000};
-static const cxl_p1_reg_t CXL_PSL_ErrIVTE = {0x0008};
-static const cxl_p1_reg_t CXL_PSL_KEY1 = {0x0010};
-static const cxl_p1_reg_t CXL_PSL_KEY2 = {0x0018};
-static const cxl_p1_reg_t CXL_PSL_Control = {0x0020};
-/* Downloading */
-static const cxl_p1_reg_t CXL_PSL_DLCNTL = {0x0060};
-static const cxl_p1_reg_t CXL_PSL_DLADDR = {0x0068};
-
-/* PSL Lookaside Buffer Management Area - CAIA 1 */
-static const cxl_p1_reg_t CXL_PSL_LBISEL = {0x0080};
-static const cxl_p1_reg_t CXL_PSL_SLBIE = {0x0088};
-static const cxl_p1_reg_t CXL_PSL_SLBIA = {0x0090};
-static const cxl_p1_reg_t CXL_PSL_TLBIE = {0x00A0};
-static const cxl_p1_reg_t CXL_PSL_TLBIA = {0x00A8};
-static const cxl_p1_reg_t CXL_PSL_AFUSEL = {0x00B0};
-
-/* 0x00C0:7EFF Implementation dependent area */
-/* PSL registers - CAIA 1 */
-static const cxl_p1_reg_t CXL_PSL_FIR1 = {0x0100};
-static const cxl_p1_reg_t CXL_PSL_FIR2 = {0x0108};
-static const cxl_p1_reg_t CXL_PSL_Timebase = {0x0110};
-static const cxl_p1_reg_t CXL_PSL_VERSION = {0x0118};
-static const cxl_p1_reg_t CXL_PSL_RESLCKTO = {0x0128};
-static const cxl_p1_reg_t CXL_PSL_TB_CTLSTAT = {0x0140};
-static const cxl_p1_reg_t CXL_PSL_FIR_CNTL = {0x0148};
-static const cxl_p1_reg_t CXL_PSL_DSNDCTL = {0x0150};
-static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158};
-static const cxl_p1_reg_t CXL_PSL_TRACE = {0x0170};
-/* PSL registers - CAIA 2 */
-static const cxl_p1_reg_t CXL_PSL9_CONTROL = {0x0020};
-static const cxl_p1_reg_t CXL_XSL9_INV = {0x0110};
-static const cxl_p1_reg_t CXL_XSL9_DBG = {0x0130};
-static const cxl_p1_reg_t CXL_XSL9_DEF = {0x0140};
-static const cxl_p1_reg_t CXL_XSL9_DSNCTL = {0x0168};
-static const cxl_p1_reg_t CXL_PSL9_FIR1 = {0x0300};
-static const cxl_p1_reg_t CXL_PSL9_FIR_MASK = {0x0308};
-static const cxl_p1_reg_t CXL_PSL9_Timebase = {0x0310};
-static const cxl_p1_reg_t CXL_PSL9_DEBUG = {0x0320};
-static const cxl_p1_reg_t CXL_PSL9_FIR_CNTL = {0x0348};
-static const cxl_p1_reg_t CXL_PSL9_DSNDCTL = {0x0350};
-static const cxl_p1_reg_t CXL_PSL9_TB_CTLSTAT = {0x0340};
-static const cxl_p1_reg_t CXL_PSL9_TRACECFG = {0x0368};
-static const cxl_p1_reg_t CXL_PSL9_APCDEDALLOC = {0x0378};
-static const cxl_p1_reg_t CXL_PSL9_APCDEDTYPE = {0x0380};
-static const cxl_p1_reg_t CXL_PSL9_TNR_ADDR = {0x0388};
-static const cxl_p1_reg_t CXL_PSL9_CTCCFG = {0x0390};
-static const cxl_p1_reg_t CXL_PSL9_GP_CT = {0x0398};
-static const cxl_p1_reg_t CXL_XSL9_IERAT = {0x0588};
-static const cxl_p1_reg_t CXL_XSL9_ILPP = {0x0590};
-
-/* 0x7F00:7FFF Reserved PCIe MSI-X Pending Bit Array area */
-/* 0x8000:FFFF Reserved PCIe MSI-X Table Area */
-
-/* PSL Slice Privilege 1 Memory Map */
-/* Configuration Area - CAIA 1&2 */
-static const cxl_p1n_reg_t CXL_PSL_SR_An = {0x00};
-static const cxl_p1n_reg_t CXL_PSL_LPID_An = {0x08};
-static const cxl_p1n_reg_t CXL_PSL_AMBAR_An = {0x10};
-static const cxl_p1n_reg_t CXL_PSL_SPOffset_An = {0x18};
-static const cxl_p1n_reg_t CXL_PSL_ID_An = {0x20};
-static const cxl_p1n_reg_t CXL_PSL_SERR_An = {0x28};
-/* Memory Management and Lookaside Buffer Management - CAIA 1*/
-static const cxl_p1n_reg_t CXL_PSL_SDR_An = {0x30};
-/* Memory Management and Lookaside Buffer Management - CAIA 1&2 */
-static const cxl_p1n_reg_t CXL_PSL_AMOR_An = {0x38};
-/* Pointer Area - CAIA 1&2 */
-static const cxl_p1n_reg_t CXL_HAURP_An = {0x80};
-static const cxl_p1n_reg_t CXL_PSL_SPAP_An = {0x88};
-static const cxl_p1n_reg_t CXL_PSL_LLCMD_An = {0x90};
-/* Control Area - CAIA 1&2 */
-static const cxl_p1n_reg_t CXL_PSL_SCNTL_An = {0xA0};
-static const cxl_p1n_reg_t CXL_PSL_CtxTime_An = {0xA8};
-static const cxl_p1n_reg_t CXL_PSL_IVTE_Offset_An = {0xB0};
-static const cxl_p1n_reg_t CXL_PSL_IVTE_Limit_An = {0xB8};
-/* 0xC0:FF Implementation Dependent Area - CAIA 1&2 */
-static const cxl_p1n_reg_t CXL_PSL_FIR_SLICE_An = {0xC0};
-static const cxl_p1n_reg_t CXL_AFU_DEBUG_An = {0xC8};
-/* 0xC0:FF Implementation Dependent Area - CAIA 1 */
-static const cxl_p1n_reg_t CXL_PSL_APCALLOC_A = {0xD0};
-static const cxl_p1n_reg_t CXL_PSL_COALLOC_A = {0xD8};
-static const cxl_p1n_reg_t CXL_PSL_RXCTL_A = {0xE0};
-static const cxl_p1n_reg_t CXL_PSL_SLICE_TRACE = {0xE8};
-
-/* PSL Slice Privilege 2 Memory Map */
-/* Configuration and Control Area - CAIA 1&2 */
-static const cxl_p2n_reg_t CXL_PSL_PID_TID_An = {0x000};
-static const cxl_p2n_reg_t CXL_CSRP_An = {0x008};
-/* Configuration and Control Area - CAIA 1 */
-static const cxl_p2n_reg_t CXL_AURP0_An = {0x010};
-static const cxl_p2n_reg_t CXL_AURP1_An = {0x018};
-static const cxl_p2n_reg_t CXL_SSTP0_An = {0x020};
-static const cxl_p2n_reg_t CXL_SSTP1_An = {0x028};
-/* Configuration and Control Area - CAIA 1 */
-static const cxl_p2n_reg_t CXL_PSL_AMR_An = {0x030};
-/* Segment Lookaside Buffer Management - CAIA 1 */
-static const cxl_p2n_reg_t CXL_SLBIE_An = {0x040};
-static const cxl_p2n_reg_t CXL_SLBIA_An = {0x048};
-static const cxl_p2n_reg_t CXL_SLBI_Select_An = {0x050};
-/* Interrupt Registers - CAIA 1&2 */
-static const cxl_p2n_reg_t CXL_PSL_DSISR_An = {0x060};
-static const cxl_p2n_reg_t CXL_PSL_DAR_An = {0x068};
-static const cxl_p2n_reg_t CXL_PSL_DSR_An = {0x070};
-static const cxl_p2n_reg_t CXL_PSL_TFC_An = {0x078};
-static const cxl_p2n_reg_t CXL_PSL_PEHandle_An = {0x080};
-static const cxl_p2n_reg_t CXL_PSL_ErrStat_An = {0x088};
-/* AFU Registers - CAIA 1&2 */
-static const cxl_p2n_reg_t CXL_AFU_Cntl_An = {0x090};
-static const cxl_p2n_reg_t CXL_AFU_ERR_An = {0x098};
-/* Work Element Descriptor - CAIA 1&2 */
-static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
-/* 0x0C0:FFF Implementation Dependent Area */
-
-#define CXL_PSL_SPAP_Addr 0x0ffffffffffff000ULL
-#define CXL_PSL_SPAP_Size 0x0000000000000ff0ULL
-#define CXL_PSL_SPAP_Size_Shift 4
-#define CXL_PSL_SPAP_V 0x0000000000000001ULL
-
-/****** CXL_PSL_Control ****************************************************/
-#define CXL_PSL_Control_tb (0x1ull << (63-63))
-#define CXL_PSL_Control_Fr (0x1ull << (63-31))
-#define CXL_PSL_Control_Fs_MASK (0x3ull << (63-29))
-#define CXL_PSL_Control_Fs_Complete (0x3ull << (63-29))
-
-/****** CXL_PSL_DLCNTL *****************************************************/
-#define CXL_PSL_DLCNTL_D (0x1ull << (63-28))
-#define CXL_PSL_DLCNTL_C (0x1ull << (63-29))
-#define CXL_PSL_DLCNTL_E (0x1ull << (63-30))
-#define CXL_PSL_DLCNTL_S (0x1ull << (63-31))
-#define CXL_PSL_DLCNTL_CE (CXL_PSL_DLCNTL_C | CXL_PSL_DLCNTL_E)
-#define CXL_PSL_DLCNTL_DCES (CXL_PSL_DLCNTL_D | CXL_PSL_DLCNTL_CE | CXL_PSL_DLCNTL_S)
-
-/****** CXL_PSL_SR_An ******************************************************/
-#define CXL_PSL_SR_An_SF MSR_SF /* 64bit */
-#define CXL_PSL_SR_An_TA (1ull << (63-1)) /* Tags active, GA1: 0 */
-#define CXL_PSL_SR_An_HV MSR_HV /* Hypervisor, GA1: 0 */
-#define CXL_PSL_SR_An_XLAT_hpt (0ull << (63-6))/* Hashed page table (HPT) mode */
-#define CXL_PSL_SR_An_XLAT_roh (2ull << (63-6))/* Radix on HPT mode */
-#define CXL_PSL_SR_An_XLAT_ror (3ull << (63-6))/* Radix on Radix mode */
-#define CXL_PSL_SR_An_BOT (1ull << (63-10)) /* Use the in-memory segment table */
-#define CXL_PSL_SR_An_PR MSR_PR /* Problem state, GA1: 1 */
-#define CXL_PSL_SR_An_ISL (1ull << (63-53)) /* Ignore Segment Large Page */
-#define CXL_PSL_SR_An_TC (1ull << (63-54)) /* Page Table secondary hash */
-#define CXL_PSL_SR_An_US (1ull << (63-56)) /* User state, GA1: X */
-#define CXL_PSL_SR_An_SC (1ull << (63-58)) /* Segment Table secondary hash */
-#define CXL_PSL_SR_An_R MSR_DR /* Relocate, GA1: 1 */
-#define CXL_PSL_SR_An_MP (1ull << (63-62)) /* Master Process */
-#define CXL_PSL_SR_An_LE (1ull << (63-63)) /* Little Endian */
-
-/****** CXL_PSL_ID_An ****************************************************/
-#define CXL_PSL_ID_An_F (1ull << (63-31))
-#define CXL_PSL_ID_An_L (1ull << (63-30))
-
-/****** CXL_PSL_SERR_An ****************************************************/
-#define CXL_PSL_SERR_An_afuto (1ull << (63-0))
-#define CXL_PSL_SERR_An_afudis (1ull << (63-1))
-#define CXL_PSL_SERR_An_afuov (1ull << (63-2))
-#define CXL_PSL_SERR_An_badsrc (1ull << (63-3))
-#define CXL_PSL_SERR_An_badctx (1ull << (63-4))
-#define CXL_PSL_SERR_An_llcmdis (1ull << (63-5))
-#define CXL_PSL_SERR_An_llcmdto (1ull << (63-6))
-#define CXL_PSL_SERR_An_afupar (1ull << (63-7))
-#define CXL_PSL_SERR_An_afudup (1ull << (63-8))
-#define CXL_PSL_SERR_An_IRQS ( \
- CXL_PSL_SERR_An_afuto | CXL_PSL_SERR_An_afudis | CXL_PSL_SERR_An_afuov | \
- CXL_PSL_SERR_An_badsrc | CXL_PSL_SERR_An_badctx | CXL_PSL_SERR_An_llcmdis | \
- CXL_PSL_SERR_An_llcmdto | CXL_PSL_SERR_An_afupar | CXL_PSL_SERR_An_afudup)
-#define CXL_PSL_SERR_An_afuto_mask (1ull << (63-32))
-#define CXL_PSL_SERR_An_afudis_mask (1ull << (63-33))
-#define CXL_PSL_SERR_An_afuov_mask (1ull << (63-34))
-#define CXL_PSL_SERR_An_badsrc_mask (1ull << (63-35))
-#define CXL_PSL_SERR_An_badctx_mask (1ull << (63-36))
-#define CXL_PSL_SERR_An_llcmdis_mask (1ull << (63-37))
-#define CXL_PSL_SERR_An_llcmdto_mask (1ull << (63-38))
-#define CXL_PSL_SERR_An_afupar_mask (1ull << (63-39))
-#define CXL_PSL_SERR_An_afudup_mask (1ull << (63-40))
-#define CXL_PSL_SERR_An_IRQ_MASKS ( \
- CXL_PSL_SERR_An_afuto_mask | CXL_PSL_SERR_An_afudis_mask | CXL_PSL_SERR_An_afuov_mask | \
- CXL_PSL_SERR_An_badsrc_mask | CXL_PSL_SERR_An_badctx_mask | CXL_PSL_SERR_An_llcmdis_mask | \
- CXL_PSL_SERR_An_llcmdto_mask | CXL_PSL_SERR_An_afupar_mask | CXL_PSL_SERR_An_afudup_mask)
-
-#define CXL_PSL_SERR_An_AE (1ull << (63-30))
-
-/****** CXL_PSL_SCNTL_An ****************************************************/
-#define CXL_PSL_SCNTL_An_CR (0x1ull << (63-15))
-/* Programming Modes: */
-#define CXL_PSL_SCNTL_An_PM_MASK (0xffffull << (63-31))
-#define CXL_PSL_SCNTL_An_PM_Shared (0x0000ull << (63-31))
-#define CXL_PSL_SCNTL_An_PM_OS (0x0001ull << (63-31))
-#define CXL_PSL_SCNTL_An_PM_Process (0x0002ull << (63-31))
-#define CXL_PSL_SCNTL_An_PM_AFU (0x0004ull << (63-31))
-#define CXL_PSL_SCNTL_An_PM_AFU_PBT (0x0104ull << (63-31))
-/* Purge Status (ro) */
-#define CXL_PSL_SCNTL_An_Ps_MASK (0x3ull << (63-39))
-#define CXL_PSL_SCNTL_An_Ps_Pending (0x1ull << (63-39))
-#define CXL_PSL_SCNTL_An_Ps_Complete (0x3ull << (63-39))
-/* Purge */
-#define CXL_PSL_SCNTL_An_Pc (0x1ull << (63-48))
-/* Suspend Status (ro) */
-#define CXL_PSL_SCNTL_An_Ss_MASK (0x3ull << (63-55))
-#define CXL_PSL_SCNTL_An_Ss_Pending (0x1ull << (63-55))
-#define CXL_PSL_SCNTL_An_Ss_Complete (0x3ull << (63-55))
-/* Suspend Control */
-#define CXL_PSL_SCNTL_An_Sc (0x1ull << (63-63))
-
-/* AFU Slice Enable Status (ro) */
-#define CXL_AFU_Cntl_An_ES_MASK (0x7ull << (63-2))
-#define CXL_AFU_Cntl_An_ES_Disabled (0x0ull << (63-2))
-#define CXL_AFU_Cntl_An_ES_Enabled (0x4ull << (63-2))
-/* AFU Slice Enable */
-#define CXL_AFU_Cntl_An_E (0x1ull << (63-3))
-/* AFU Slice Reset status (ro) */
-#define CXL_AFU_Cntl_An_RS_MASK (0x3ull << (63-5))
-#define CXL_AFU_Cntl_An_RS_Pending (0x1ull << (63-5))
-#define CXL_AFU_Cntl_An_RS_Complete (0x2ull << (63-5))
-/* AFU Slice Reset */
-#define CXL_AFU_Cntl_An_RA (0x1ull << (63-7))
-
-/****** CXL_SSTP0/1_An ******************************************************/
-/* These top bits are for the segment that CONTAINS the segment table */
-#define CXL_SSTP0_An_B_SHIFT SLB_VSID_SSIZE_SHIFT
-#define CXL_SSTP0_An_KS (1ull << (63-2))
-#define CXL_SSTP0_An_KP (1ull << (63-3))
-#define CXL_SSTP0_An_N (1ull << (63-4))
-#define CXL_SSTP0_An_L (1ull << (63-5))
-#define CXL_SSTP0_An_C (1ull << (63-6))
-#define CXL_SSTP0_An_TA (1ull << (63-7))
-#define CXL_SSTP0_An_LP_SHIFT (63-9) /* 2 Bits */
-/* And finally, the virtual address & size of the segment table: */
-#define CXL_SSTP0_An_SegTableSize_SHIFT (63-31) /* 12 Bits */
-#define CXL_SSTP0_An_SegTableSize_MASK \
- (((1ull << 12) - 1) << CXL_SSTP0_An_SegTableSize_SHIFT)
-#define CXL_SSTP0_An_STVA_U_MASK ((1ull << (63-49))-1)
-#define CXL_SSTP1_An_STVA_L_MASK (~((1ull << (63-55))-1))
-#define CXL_SSTP1_An_V (1ull << (63-63))
-
-/****** CXL_PSL_SLBIE_[An] - CAIA 1 **************************************************/
-/* write: */
-#define CXL_SLBIE_C PPC_BIT(36) /* Class */
-#define CXL_SLBIE_SS PPC_BITMASK(37, 38) /* Segment Size */
-#define CXL_SLBIE_SS_SHIFT PPC_BITLSHIFT(38)
-#define CXL_SLBIE_TA PPC_BIT(38) /* Tags Active */
-/* read: */
-#define CXL_SLBIE_MAX PPC_BITMASK(24, 31)
-#define CXL_SLBIE_PENDING PPC_BITMASK(56, 63)
-
-/****** Common to all CXL_TLBIA/SLBIA_[An] - CAIA 1 **********************************/
-#define CXL_TLB_SLB_P (1ull) /* Pending (read) */
-
-/****** Common to all CXL_TLB/SLB_IA/IE_[An] registers - CAIA 1 **********************/
-#define CXL_TLB_SLB_IQ_ALL (0ull) /* Inv qualifier */
-#define CXL_TLB_SLB_IQ_LPID (1ull) /* Inv qualifier */
-#define CXL_TLB_SLB_IQ_LPIDPID (3ull) /* Inv qualifier */
-
-/****** CXL_PSL_AFUSEL ******************************************************/
-#define CXL_PSL_AFUSEL_A (1ull << (63-55)) /* Adapter wide invalidates affect all AFUs */
-
-/****** CXL_PSL_DSISR_An - CAIA 1 ****************************************************/
-#define CXL_PSL_DSISR_An_DS (1ull << (63-0)) /* Segment not found */
-#define CXL_PSL_DSISR_An_DM (1ull << (63-1)) /* PTE not found (See also: M) or protection fault */
-#define CXL_PSL_DSISR_An_ST (1ull << (63-2)) /* Segment Table PTE not found */
-#define CXL_PSL_DSISR_An_UR (1ull << (63-3)) /* AURP PTE not found */
-#define CXL_PSL_DSISR_TRANS (CXL_PSL_DSISR_An_DS | CXL_PSL_DSISR_An_DM | CXL_PSL_DSISR_An_ST | CXL_PSL_DSISR_An_UR)
-#define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */
-#define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */
-#define CXL_PSL_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */
-#define CXL_PSL_DSISR_PENDING (CXL_PSL_DSISR_TRANS | CXL_PSL_DSISR_An_PE | CXL_PSL_DSISR_An_AE | CXL_PSL_DSISR_An_OC)
-/* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */
-#define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */
-#define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */
-#define CXL_PSL_DSISR_An_A (1ull << (63-37)) /* AFU lock access to write through or cache inhibited storage */
-#define CXL_PSL_DSISR_An_S DSISR_ISSTORE /* Access was afu_wr or afu_zero */
-#define CXL_PSL_DSISR_An_K DSISR_KEYFAULT /* Access not permitted by virtual page class key protection */
-
-/****** CXL_PSL_DSISR_An - CAIA 2 ****************************************************/
-#define CXL_PSL9_DSISR_An_TF (1ull << (63-3)) /* Translation fault */
-#define CXL_PSL9_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */
-#define CXL_PSL9_DSISR_An_AE (1ull << (63-5)) /* AFU Error */
-#define CXL_PSL9_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */
-#define CXL_PSL9_DSISR_An_S (1ull << (63-38)) /* TF for a write operation */
-#define CXL_PSL9_DSISR_PENDING (CXL_PSL9_DSISR_An_TF | CXL_PSL9_DSISR_An_PE | CXL_PSL9_DSISR_An_AE | CXL_PSL9_DSISR_An_OC)
-/*
- * NOTE: Bits 56:63 (Checkout Response Status) are valid when DSISR_An[TF] = 1
- * Status (0:7) Encoding
- */
-#define CXL_PSL9_DSISR_An_CO_MASK 0x00000000000000ffULL
-#define CXL_PSL9_DSISR_An_SF 0x0000000000000080ULL /* Segment Fault 0b10000000 */
-#define CXL_PSL9_DSISR_An_PF_SLR 0x0000000000000088ULL /* PTE not found (Single Level Radix) 0b10001000 */
-#define CXL_PSL9_DSISR_An_PF_RGC 0x000000000000008CULL /* PTE not found (Radix Guest (child)) 0b10001100 */
-#define CXL_PSL9_DSISR_An_PF_RGP 0x0000000000000090ULL /* PTE not found (Radix Guest (parent)) 0b10010000 */
-#define CXL_PSL9_DSISR_An_PF_HRH 0x0000000000000094ULL /* PTE not found (HPT/Radix Host) 0b10010100 */
-#define CXL_PSL9_DSISR_An_PF_STEG 0x000000000000009CULL /* PTE not found (STEG VA) 0b10011100 */
-#define CXL_PSL9_DSISR_An_URTCH 0x00000000000000B4ULL /* Unsupported Radix Tree Configuration 0b10110100 */
-
-/****** CXL_PSL_TFC_An ******************************************************/
-#define CXL_PSL_TFC_An_A (1ull << (63-28)) /* Acknowledge non-translation fault */
-#define CXL_PSL_TFC_An_C (1ull << (63-29)) /* Continue (abort transaction) */
-#define CXL_PSL_TFC_An_AE (1ull << (63-30)) /* Restart PSL with address error */
-#define CXL_PSL_TFC_An_R (1ull << (63-31)) /* Restart PSL transaction */
-
-/****** CXL_PSL_DEBUG *****************************************************/
-#define CXL_PSL_DEBUG_CDC (1ull << (63-27)) /* Coherent Data cache support */
-
-/****** CXL_XSL9_IERAT_ERAT - CAIA 2 **********************************/
-#define CXL_XSL9_IERAT_MLPID (1ull << (63-0)) /* Match LPID */
-#define CXL_XSL9_IERAT_MPID (1ull << (63-1)) /* Match PID */
-#define CXL_XSL9_IERAT_PRS (1ull << (63-4)) /* PRS bit for Radix invalidations */
-#define CXL_XSL9_IERAT_INVR (1ull << (63-3)) /* Invalidate Radix */
-#define CXL_XSL9_IERAT_IALL (1ull << (63-8)) /* Invalidate All */
-#define CXL_XSL9_IERAT_IINPROG (1ull << (63-63)) /* Invalidate in progress */
-
-/* cxl_process_element->software_status */
-#define CXL_PE_SOFTWARE_STATE_V (1ul << (31 - 0)) /* Valid */
-#define CXL_PE_SOFTWARE_STATE_C (1ul << (31 - 29)) /* Complete */
-#define CXL_PE_SOFTWARE_STATE_S (1ul << (31 - 30)) /* Suspend */
-#define CXL_PE_SOFTWARE_STATE_T (1ul << (31 - 31)) /* Terminate */
-
-/****** CXL_PSL_RXCTL_An (Implementation Specific) **************************
- * Controls AFU Hang Pulse, which sets the timeout for the AFU to respond to
- * the PSL for any response (except MMIO). Timeouts will occur between 1x to 2x
- * of the hang pulse frequency.
- */
-#define CXL_PSL_RXCTL_AFUHP_4S 0x7000000000000000ULL
-
-/* SPA->sw_command_status */
-#define CXL_SPA_SW_CMD_MASK 0xffff000000000000ULL
-#define CXL_SPA_SW_CMD_TERMINATE 0x0001000000000000ULL
-#define CXL_SPA_SW_CMD_REMOVE 0x0002000000000000ULL
-#define CXL_SPA_SW_CMD_SUSPEND 0x0003000000000000ULL
-#define CXL_SPA_SW_CMD_RESUME 0x0004000000000000ULL
-#define CXL_SPA_SW_CMD_ADD 0x0005000000000000ULL
-#define CXL_SPA_SW_CMD_UPDATE 0x0006000000000000ULL
-#define CXL_SPA_SW_STATE_MASK 0x0000ffff00000000ULL
-#define CXL_SPA_SW_STATE_TERMINATED 0x0000000100000000ULL
-#define CXL_SPA_SW_STATE_REMOVED 0x0000000200000000ULL
-#define CXL_SPA_SW_STATE_SUSPENDED 0x0000000300000000ULL
-#define CXL_SPA_SW_STATE_RESUMED 0x0000000400000000ULL
-#define CXL_SPA_SW_STATE_ADDED 0x0000000500000000ULL
-#define CXL_SPA_SW_STATE_UPDATED 0x0000000600000000ULL
-#define CXL_SPA_SW_PSL_ID_MASK 0x00000000ffff0000ULL
-#define CXL_SPA_SW_LINK_MASK 0x000000000000ffffULL
-
-#define CXL_MAX_SLICES 4
-#define MAX_AFU_MMIO_REGS 3
-
-#define CXL_MODE_TIME_SLICED 0x4
-#define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED)
-
-#define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
-#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
-#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
-
-#define CXL_PSL9_TRACEID_MAX 0xAU
-#define CXL_PSL9_TRACESTATE_FIN 0x3U
-
-enum cxl_context_status {
- CLOSED,
- OPENED,
- STARTED
-};
-
-enum prefault_modes {
- CXL_PREFAULT_NONE,
- CXL_PREFAULT_WED,
- CXL_PREFAULT_ALL,
-};
-
-enum cxl_attrs {
- CXL_ADAPTER_ATTRS,
- CXL_AFU_MASTER_ATTRS,
- CXL_AFU_ATTRS,
-};
-
-struct cxl_sste {
- __be64 esid_data;
- __be64 vsid_data;
-};
-
-#define to_cxl_adapter(d) container_of(d, struct cxl, dev)
-#define to_cxl_afu(d) container_of(d, struct cxl_afu, dev)
-
-struct cxl_afu_native {
- void __iomem *p1n_mmio;
- void __iomem *afu_desc_mmio;
- irq_hw_number_t psl_hwirq;
- unsigned int psl_virq;
- struct mutex spa_mutex;
- /*
- * Only the first part of the SPA is used for the process element
- * linked list. The only other part that software needs to worry about
- * is sw_command_status, which we store a separate pointer to.
- * Everything else in the SPA is only used by hardware
- */
- struct cxl_process_element *spa;
- __be64 *sw_command_status;
- unsigned int spa_size;
- int spa_order;
- int spa_max_procs;
- u64 pp_offset;
-};
-
-struct cxl_afu_guest {
- struct cxl_afu *parent;
- u64 handle;
- phys_addr_t p2n_phys;
- u64 p2n_size;
- int max_ints;
- bool handle_err;
- struct delayed_work work_err;
- int previous_state;
-};
-
-struct cxl_afu {
- struct cxl_afu_native *native;
- struct cxl_afu_guest *guest;
- irq_hw_number_t serr_hwirq;
- unsigned int serr_virq;
- char *psl_irq_name;
- char *err_irq_name;
- void __iomem *p2n_mmio;
- phys_addr_t psn_phys;
- u64 pp_size;
-
- struct cxl *adapter;
- struct device dev;
- struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d;
- struct device *chardev_s, *chardev_m, *chardev_d;
- struct idr contexts_idr;
- struct dentry *debugfs;
- struct mutex contexts_lock;
- spinlock_t afu_cntl_lock;
-
- /* -1: AFU deconfigured/locked, >= 0: number of readers */
- atomic_t configured_state;
-
- /* AFU error buffer fields and bin attribute for sysfs */
- u64 eb_len, eb_offset;
- struct bin_attribute attr_eb;
-
- /* pointer to the vphb */
- struct pci_controller *phb;
-
- int pp_irqs;
- int irqs_max;
- int num_procs;
- int max_procs_virtualised;
- int slice;
- int modes_supported;
- int current_mode;
- int crs_num;
- u64 crs_len;
- u64 crs_offset;
- struct list_head crs;
- enum prefault_modes prefault_mode;
- bool psa;
- bool pp_psa;
- bool enabled;
-};
-
-
-struct cxl_irq_name {
- struct list_head list;
- char *name;
-};
-
-struct irq_avail {
- irq_hw_number_t offset;
- irq_hw_number_t range;
- unsigned long *bitmap;
-};
-
-/*
- * This is a cxl context. If the PSL is in dedicated mode, there will be one
- * of these per AFU. If in AFU directed there can be lots of these.
- */
-struct cxl_context {
- struct cxl_afu *afu;
-
- /* Problem state MMIO */
- phys_addr_t psn_phys;
- u64 psn_size;
-
- /* Used to unmap any mmaps when force detaching */
- struct address_space *mapping;
- struct mutex mapping_lock;
- struct page *ff_page;
- bool mmio_err_ff;
- bool kernelapi;
-
- spinlock_t sste_lock; /* Protects segment table entries */
- struct cxl_sste *sstp;
- u64 sstp0, sstp1;
- unsigned int sst_size, sst_lru;
-
- wait_queue_head_t wq;
- /* use mm context associated with this pid for ds faults */
- struct pid *pid;
- spinlock_t lock; /* Protects pending_irq_mask, pending_fault and fault_addr */
- /* Only used in PR mode */
- u64 process_token;
-
- /* driver private data */
- void *priv;
-
- unsigned long *irq_bitmap; /* Accessed from IRQ context */
- struct cxl_irq_ranges irqs;
- struct list_head irq_names;
- u64 fault_addr;
- u64 fault_dsisr;
- u64 afu_err;
-
- /*
- * This status and it's lock pretects start and detach context
- * from racing. It also prevents detach from racing with
- * itself
- */
- enum cxl_context_status status;
- struct mutex status_mutex;
-
-
- /* XXX: Is it possible to need multiple work items at once? */
- struct work_struct fault_work;
- u64 dsisr;
- u64 dar;
-
- struct cxl_process_element *elem;
-
- /*
- * pe is the process element handle, assigned by this driver when the
- * context is initialized.
- *
- * external_pe is the PE shown outside of cxl.
- * On bare-metal, pe=external_pe, because we decide what the handle is.
- * In a guest, we only find out about the pe used by pHyp when the
- * context is attached, and that's the value we want to report outside
- * of cxl.
- */
- int pe;
- int external_pe;
-
- u32 irq_count;
- bool pe_inserted;
- bool master;
- bool kernel;
- bool pending_irq;
- bool pending_fault;
- bool pending_afu_err;
-
- /* Used by AFU drivers for driver specific event delivery */
- struct cxl_afu_driver_ops *afu_driver_ops;
- atomic_t afu_driver_events;
-
- struct rcu_head rcu;
-
- struct mm_struct *mm;
-
- u16 tidr;
- bool assign_tidr;
-};
-
-struct cxl_irq_info;
-
-struct cxl_service_layer_ops {
- int (*adapter_regs_init)(struct cxl *adapter, struct pci_dev *dev);
- int (*invalidate_all)(struct cxl *adapter);
- int (*afu_regs_init)(struct cxl_afu *afu);
- int (*sanitise_afu_regs)(struct cxl_afu *afu);
- int (*register_serr_irq)(struct cxl_afu *afu);
- void (*release_serr_irq)(struct cxl_afu *afu);
- irqreturn_t (*handle_interrupt)(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);
- irqreturn_t (*fail_irq)(struct cxl_afu *afu, struct cxl_irq_info *irq_info);
- int (*activate_dedicated_process)(struct cxl_afu *afu);
- int (*attach_afu_directed)(struct cxl_context *ctx, u64 wed, u64 amr);
- int (*attach_dedicated_process)(struct cxl_context *ctx, u64 wed, u64 amr);
- void (*update_dedicated_ivtes)(struct cxl_context *ctx);
- void (*debugfs_add_adapter_regs)(struct cxl *adapter, struct dentry *dir);
- void (*debugfs_add_afu_regs)(struct cxl_afu *afu, struct dentry *dir);
- void (*psl_irq_dump_registers)(struct cxl_context *ctx);
- void (*err_irq_dump_registers)(struct cxl *adapter);
- void (*debugfs_stop_trace)(struct cxl *adapter);
- void (*write_timebase_ctrl)(struct cxl *adapter);
- u64 (*timebase_read)(struct cxl *adapter);
- int capi_mode;
- bool needs_reset_before_disable;
-};
-
-struct cxl_native {
- u64 afu_desc_off;
- u64 afu_desc_size;
- void __iomem *p1_mmio;
- void __iomem *p2_mmio;
- irq_hw_number_t err_hwirq;
- unsigned int err_virq;
- u64 ps_off;
- bool no_data_cache; /* set if no data cache on the card */
- const struct cxl_service_layer_ops *sl_ops;
-};
-
-struct cxl_guest {
- struct platform_device *pdev;
- int irq_nranges;
- struct cdev cdev;
- irq_hw_number_t irq_base_offset;
- struct irq_avail *irq_avail;
- spinlock_t irq_alloc_lock;
- u64 handle;
- char *status;
- u16 vendor;
- u16 device;
- u16 subsystem_vendor;
- u16 subsystem;
-};
-
-struct cxl {
- struct cxl_native *native;
- struct cxl_guest *guest;
- spinlock_t afu_list_lock;
- struct cxl_afu *afu[CXL_MAX_SLICES];
- struct device dev;
- struct dentry *trace;
- struct dentry *psl_err_chk;
- struct dentry *debugfs;
- char *irq_name;
- struct bin_attribute cxl_attr;
- int adapter_num;
- int user_irqs;
- u64 ps_size;
- u16 psl_rev;
- u16 base_image;
- u8 vsec_status;
- u8 caia_major;
- u8 caia_minor;
- u8 slices;
- bool user_image_loaded;
- bool perst_loads_image;
- bool perst_select_user;
- bool perst_same_image;
- bool psl_timebase_synced;
- bool tunneled_ops_supported;
-
- /*
- * number of contexts mapped on to this card. Possible values are:
- * >0: Number of contexts mapped and new one can be mapped.
- * 0: No active contexts and new ones can be mapped.
- * -1: No contexts mapped and new ones cannot be mapped.
- */
- atomic_t contexts_num;
-};
-
-int cxl_pci_alloc_one_irq(struct cxl *adapter);
-void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq);
-int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num);
-void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter);
-int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq);
-int cxl_update_image_control(struct cxl *adapter);
-int cxl_pci_reset(struct cxl *adapter);
-void cxl_pci_release_afu(struct device *dev);
-ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);
-
-/* common == phyp + powernv - CAIA 1&2 */
-struct cxl_process_element_common {
- __be32 tid;
- __be32 pid;
- __be64 csrp;
- union {
- struct {
- __be64 aurp0;
- __be64 aurp1;
- __be64 sstp0;
- __be64 sstp1;
- } psl8; /* CAIA 1 */
- struct {
- u8 reserved2[8];
- u8 reserved3[8];
- u8 reserved4[8];
- u8 reserved5[8];
- } psl9; /* CAIA 2 */
- } u;
- __be64 amr;
- u8 reserved6[4];
- __be64 wed;
-} __packed;
-
-/* just powernv - CAIA 1&2 */
-struct cxl_process_element {
- __be64 sr;
- __be64 SPOffset;
- union {
- __be64 sdr; /* CAIA 1 */
- u8 reserved1[8]; /* CAIA 2 */
- } u;
- __be64 haurp;
- __be32 ctxtime;
- __be16 ivte_offsets[4];
- __be16 ivte_ranges[4];
- __be32 lpid;
- struct cxl_process_element_common common;
- __be32 software_state;
-} __packed;
-
-static inline bool cxl_adapter_link_ok(struct cxl *cxl, struct cxl_afu *afu)
-{
- struct pci_dev *pdev;
-
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- pdev = to_pci_dev(cxl->dev.parent);
- return !pci_channel_offline(pdev);
- }
- return true;
-}
-
-static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg)
-{
- WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
- return cxl->native->p1_mmio + cxl_reg_off(reg);
-}
-
-static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val)
-{
- if (likely(cxl_adapter_link_ok(cxl, NULL)))
- out_be64(_cxl_p1_addr(cxl, reg), val);
-}
-
-static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg)
-{
- if (likely(cxl_adapter_link_ok(cxl, NULL)))
- return in_be64(_cxl_p1_addr(cxl, reg));
- else
- return ~0ULL;
-}
-
-static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg)
-{
- WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
- return afu->native->p1n_mmio + cxl_reg_off(reg);
-}
-
-static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val)
-{
- if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
- out_be64(_cxl_p1n_addr(afu, reg), val);
-}
-
-static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg)
-{
- if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
- return in_be64(_cxl_p1n_addr(afu, reg));
- else
- return ~0ULL;
-}
-
-static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg)
-{
- return afu->p2n_mmio + cxl_reg_off(reg);
-}
-
-static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val)
-{
- if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
- out_be64(_cxl_p2n_addr(afu, reg), val);
-}
-
-static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
-{
- if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
- return in_be64(_cxl_p2n_addr(afu, reg));
- else
- return ~0ULL;
-}
-
-static inline bool cxl_is_power8(void)
-{
- if ((pvr_version_is(PVR_POWER8E)) ||
- (pvr_version_is(PVR_POWER8NVL)) ||
- (pvr_version_is(PVR_POWER8)) ||
- (pvr_version_is(PVR_HX_C2000)))
- return true;
- return false;
-}
-
-static inline bool cxl_is_power9(void)
-{
- if (pvr_version_is(PVR_POWER9))
- return true;
- return false;
-}
-
-ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
- loff_t off, size_t count);
-
-
-struct cxl_calls {
- void (*cxl_slbia)(struct mm_struct *mm);
- struct module *owner;
-};
-int register_cxl_calls(struct cxl_calls *calls);
-void unregister_cxl_calls(struct cxl_calls *calls);
-int cxl_update_properties(struct device_node *dn, struct property *new_prop);
-
-void cxl_remove_adapter_nr(struct cxl *adapter);
-
-void cxl_release_spa(struct cxl_afu *afu);
-
-dev_t cxl_get_dev(void);
-int cxl_file_init(void);
-void cxl_file_exit(void);
-int cxl_register_adapter(struct cxl *adapter);
-int cxl_register_afu(struct cxl_afu *afu);
-int cxl_chardev_d_afu_add(struct cxl_afu *afu);
-int cxl_chardev_m_afu_add(struct cxl_afu *afu);
-int cxl_chardev_s_afu_add(struct cxl_afu *afu);
-void cxl_chardev_afu_remove(struct cxl_afu *afu);
-
-void cxl_context_detach_all(struct cxl_afu *afu);
-void cxl_context_free(struct cxl_context *ctx);
-void cxl_context_detach(struct cxl_context *ctx);
-
-int cxl_sysfs_adapter_add(struct cxl *adapter);
-void cxl_sysfs_adapter_remove(struct cxl *adapter);
-int cxl_sysfs_afu_add(struct cxl_afu *afu);
-void cxl_sysfs_afu_remove(struct cxl_afu *afu);
-int cxl_sysfs_afu_m_add(struct cxl_afu *afu);
-void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);
-
-struct cxl *cxl_alloc_adapter(void);
-struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);
-int cxl_afu_select_best_mode(struct cxl_afu *afu);
-
-int cxl_native_register_psl_irq(struct cxl_afu *afu);
-void cxl_native_release_psl_irq(struct cxl_afu *afu);
-int cxl_native_register_psl_err_irq(struct cxl *adapter);
-void cxl_native_release_psl_err_irq(struct cxl *adapter);
-int cxl_native_register_serr_irq(struct cxl_afu *afu);
-void cxl_native_release_serr_irq(struct cxl_afu *afu);
-int afu_register_irqs(struct cxl_context *ctx, u32 count);
-void afu_release_irqs(struct cxl_context *ctx, void *cookie);
-void afu_irq_name_free(struct cxl_context *ctx);
-
-int cxl_attach_afu_directed_psl9(struct cxl_context *ctx, u64 wed, u64 amr);
-int cxl_attach_afu_directed_psl8(struct cxl_context *ctx, u64 wed, u64 amr);
-int cxl_activate_dedicated_process_psl9(struct cxl_afu *afu);
-int cxl_activate_dedicated_process_psl8(struct cxl_afu *afu);
-int cxl_attach_dedicated_process_psl9(struct cxl_context *ctx, u64 wed, u64 amr);
-int cxl_attach_dedicated_process_psl8(struct cxl_context *ctx, u64 wed, u64 amr);
-void cxl_update_dedicated_ivtes_psl9(struct cxl_context *ctx);
-void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx);
-
-#ifdef CONFIG_DEBUG_FS
-
-void cxl_debugfs_init(void);
-void cxl_debugfs_exit(void);
-void cxl_debugfs_adapter_add(struct cxl *adapter);
-void cxl_debugfs_adapter_remove(struct cxl *adapter);
-void cxl_debugfs_afu_add(struct cxl_afu *afu);
-void cxl_debugfs_afu_remove(struct cxl_afu *afu);
-void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir);
-void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir);
-void cxl_debugfs_add_afu_regs_psl9(struct cxl_afu *afu, struct dentry *dir);
-void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir);
-
-#else /* CONFIG_DEBUG_FS */
-
-static inline void __init cxl_debugfs_init(void)
-{
-}
-
-static inline void cxl_debugfs_exit(void)
-{
-}
-
-static inline void cxl_debugfs_adapter_add(struct cxl *adapter)
-{
-}
-
-static inline void cxl_debugfs_adapter_remove(struct cxl *adapter)
-{
-}
-
-static inline void cxl_debugfs_afu_add(struct cxl_afu *afu)
-{
-}
-
-static inline void cxl_debugfs_afu_remove(struct cxl_afu *afu)
-{
-}
-
-static inline void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter,
- struct dentry *dir)
-{
-}
-
-static inline void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter,
- struct dentry *dir)
-{
-}
-
-static inline void cxl_debugfs_add_afu_regs_psl9(struct cxl_afu *afu, struct dentry *dir)
-{
-}
-
-static inline void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir)
-{
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-void cxl_handle_fault(struct work_struct *work);
-void cxl_prefault(struct cxl_context *ctx, u64 wed);
-int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar);
-
-struct cxl *get_cxl_adapter(int num);
-int cxl_alloc_sst(struct cxl_context *ctx);
-void cxl_dump_debug_buffer(void *addr, size_t size);
-
-void init_cxl_native(void);
-
-struct cxl_context *cxl_context_alloc(void);
-int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master);
-void cxl_context_set_mapping(struct cxl_context *ctx,
- struct address_space *mapping);
-void cxl_context_free(struct cxl_context *ctx);
-int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma);
-unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
- irq_handler_t handler, void *cookie, const char *name);
-void cxl_unmap_irq(unsigned int virq, void *cookie);
-int __detach_context(struct cxl_context *ctx);
-
-/*
- * This must match the layout of the H_COLLECT_CA_INT_INFO retbuf defined
- * in PAPR.
- * Field pid_tid is now 'reserved' because it's no more used on bare-metal.
- * On a guest environment, PSL_PID_An is located on the upper 32 bits and
- * PSL_TID_An register in the lower 32 bits.
- */
-struct cxl_irq_info {
- u64 dsisr;
- u64 dar;
- u64 dsr;
- u64 reserved;
- u64 afu_err;
- u64 errstat;
- u64 proc_handle;
- u64 padding[2]; /* to match the expected retbuf size for plpar_hcall9 */
-};
-
-void cxl_assign_psn_space(struct cxl_context *ctx);
-int cxl_invalidate_all_psl9(struct cxl *adapter);
-int cxl_invalidate_all_psl8(struct cxl *adapter);
-irqreturn_t cxl_irq_psl9(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);
-irqreturn_t cxl_irq_psl8(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);
-irqreturn_t cxl_fail_irq_psl(struct cxl_afu *afu, struct cxl_irq_info *irq_info);
-int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
- void *cookie, irq_hw_number_t *dest_hwirq,
- unsigned int *dest_virq, const char *name);
-
-int cxl_check_error(struct cxl_afu *afu);
-int cxl_afu_slbia(struct cxl_afu *afu);
-int cxl_data_cache_flush(struct cxl *adapter);
-int cxl_afu_disable(struct cxl_afu *afu);
-int cxl_psl_purge(struct cxl_afu *afu);
-int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
- u32 *phb_index, u64 *capp_unit_id);
-int cxl_slot_is_switched(struct pci_dev *dev);
-int cxl_get_xsl9_dsnctl(struct pci_dev *dev, u64 capp_unit_id, u64 *reg);
-u64 cxl_calculate_sr(bool master, bool kernel, bool real_mode, bool p9);
-
-void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx);
-void cxl_native_irq_dump_regs_psl8(struct cxl_context *ctx);
-void cxl_native_err_irq_dump_regs_psl8(struct cxl *adapter);
-void cxl_native_err_irq_dump_regs_psl9(struct cxl *adapter);
-int cxl_pci_vphb_add(struct cxl_afu *afu);
-void cxl_pci_vphb_remove(struct cxl_afu *afu);
-void cxl_release_mapping(struct cxl_context *ctx);
-
-extern struct pci_driver cxl_pci_driver;
-extern struct platform_driver cxl_of_driver;
-int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
-
-int afu_open(struct inode *inode, struct file *file);
-int afu_release(struct inode *inode, struct file *file);
-long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-int afu_mmap(struct file *file, struct vm_area_struct *vm);
-__poll_t afu_poll(struct file *file, struct poll_table_struct *poll);
-ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
-extern const struct file_operations afu_fops;
-
-struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *dev);
-void cxl_guest_remove_adapter(struct cxl *adapter);
-int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np);
-int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np);
-ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);
-ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len);
-int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np);
-void cxl_guest_remove_afu(struct cxl_afu *afu);
-int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np);
-int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *afu_np);
-int cxl_guest_add_chardev(struct cxl *adapter);
-void cxl_guest_remove_chardev(struct cxl *adapter);
-void cxl_guest_reload_module(struct cxl *adapter);
-int cxl_of_probe(struct platform_device *pdev);
-
-struct cxl_backend_ops {
- struct module *module;
- int (*adapter_reset)(struct cxl *adapter);
- int (*alloc_one_irq)(struct cxl *adapter);
- void (*release_one_irq)(struct cxl *adapter, int hwirq);
- int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs,
- struct cxl *adapter, unsigned int num);
- void (*release_irq_ranges)(struct cxl_irq_ranges *irqs,
- struct cxl *adapter);
- int (*setup_irq)(struct cxl *adapter, unsigned int hwirq,
- unsigned int virq);
- irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx,
- u64 dsisr, u64 errstat);
- irqreturn_t (*psl_interrupt)(int irq, void *data);
- int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
- void (*irq_wait)(struct cxl_context *ctx);
- int (*attach_process)(struct cxl_context *ctx, bool kernel,
- u64 wed, u64 amr);
- int (*detach_process)(struct cxl_context *ctx);
- void (*update_ivtes)(struct cxl_context *ctx);
- bool (*support_attributes)(const char *attr_name, enum cxl_attrs type);
- bool (*link_ok)(struct cxl *cxl, struct cxl_afu *afu);
- void (*release_afu)(struct device *dev);
- ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
- loff_t off, size_t count);
- int (*afu_check_and_enable)(struct cxl_afu *afu);
- int (*afu_activate_mode)(struct cxl_afu *afu, int mode);
- int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode);
- int (*afu_reset)(struct cxl_afu *afu);
- int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val);
- int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val);
- int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val);
- int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val);
- int (*afu_cr_write8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 val);
- int (*afu_cr_write16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 val);
- int (*afu_cr_write32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 val);
- ssize_t (*read_adapter_vpd)(struct cxl *adapter, void *buf, size_t count);
-};
-extern const struct cxl_backend_ops cxl_native_ops;
-extern const struct cxl_backend_ops cxl_guest_ops;
-extern const struct cxl_backend_ops *cxl_ops;
-
-/* check if the given pci_dev is on the cxl vphb bus */
-bool cxl_pci_is_vphb_device(struct pci_dev *dev);
-
-/* decode AFU error bits in the PSL register PSL_SERR_An */
-void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr);
-
-/*
- * Increments the number of attached contexts on an adapter.
- * In case an adapter_context_lock is taken the return -EBUSY.
- */
-int cxl_adapter_context_get(struct cxl *adapter);
-
-/* Decrements the number of attached contexts on an adapter */
-void cxl_adapter_context_put(struct cxl *adapter);
-
-/* If no active contexts then prevents contexts from being attached */
-int cxl_adapter_context_lock(struct cxl *adapter);
-
-/* Unlock the contexts-lock if taken. Warn and force unlock otherwise */
-void cxl_adapter_context_unlock(struct cxl *adapter);
-
-/* Increases the reference count to "struct mm_struct" */
-void cxl_context_mm_count_get(struct cxl_context *ctx);
-
-/* Decrements the reference count to "struct mm_struct" */
-void cxl_context_mm_count_put(struct cxl_context *ctx);
-
-#endif
diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c
deleted file mode 100644
index e5fe0a171472..000000000000
--- a/drivers/misc/cxl/cxllib.c
+++ /dev/null
@@ -1,271 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2017 IBM Corp.
- */
-
-#include <linux/hugetlb.h>
-#include <linux/sched/mm.h>
-#include <asm/opal-api.h>
-#include <asm/pnv-pci.h>
-#include <misc/cxllib.h>
-
-#include "cxl.h"
-
-#define CXL_INVALID_DRA ~0ull
-#define CXL_DUMMY_READ_SIZE 128
-#define CXL_DUMMY_READ_ALIGN 8
-#define CXL_CAPI_WINDOW_START 0x2000000000000ull
-#define CXL_CAPI_WINDOW_LOG_SIZE 48
-#define CXL_XSL_CONFIG_CURRENT_VERSION CXL_XSL_CONFIG_VERSION1
-
-
-bool cxllib_slot_is_supported(struct pci_dev *dev, unsigned long flags)
-{
- int rc;
- u32 phb_index;
- u64 chip_id, capp_unit_id;
-
- /* No flags currently supported */
- if (flags)
- return false;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE))
- return false;
-
- if (!cxl_is_power9())
- return false;
-
- if (cxl_slot_is_switched(dev))
- return false;
-
- /* on p9, some pci slots are not connected to a CAPP unit */
- rc = cxl_calc_capp_routing(dev, &chip_id, &phb_index, &capp_unit_id);
- if (rc)
- return false;
-
- return true;
-}
-EXPORT_SYMBOL_GPL(cxllib_slot_is_supported);
-
-static DEFINE_MUTEX(dra_mutex);
-static u64 dummy_read_addr = CXL_INVALID_DRA;
-
-static int allocate_dummy_read_buf(void)
-{
- u64 buf, vaddr;
- size_t buf_size;
-
- /*
- * Dummy read buffer is 128-byte long, aligned on a
- * 256-byte boundary and we need the physical address.
- */
- buf_size = CXL_DUMMY_READ_SIZE + (1ull << CXL_DUMMY_READ_ALIGN);
- buf = (u64) kzalloc(buf_size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- vaddr = (buf + (1ull << CXL_DUMMY_READ_ALIGN) - 1) &
- (~0ull << CXL_DUMMY_READ_ALIGN);
-
- WARN((vaddr + CXL_DUMMY_READ_SIZE) > (buf + buf_size),
- "Dummy read buffer alignment issue");
- dummy_read_addr = virt_to_phys((void *) vaddr);
- return 0;
-}
-
-int cxllib_get_xsl_config(struct pci_dev *dev, struct cxllib_xsl_config *cfg)
-{
- int rc;
- u32 phb_index;
- u64 chip_id, capp_unit_id;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE))
- return -EINVAL;
-
- mutex_lock(&dra_mutex);
- if (dummy_read_addr == CXL_INVALID_DRA) {
- rc = allocate_dummy_read_buf();
- if (rc) {
- mutex_unlock(&dra_mutex);
- return rc;
- }
- }
- mutex_unlock(&dra_mutex);
-
- rc = cxl_calc_capp_routing(dev, &chip_id, &phb_index, &capp_unit_id);
- if (rc)
- return rc;
-
- rc = cxl_get_xsl9_dsnctl(dev, capp_unit_id, &cfg->dsnctl);
- if (rc)
- return rc;
-
- cfg->version = CXL_XSL_CONFIG_CURRENT_VERSION;
- cfg->log_bar_size = CXL_CAPI_WINDOW_LOG_SIZE;
- cfg->bar_addr = CXL_CAPI_WINDOW_START;
- cfg->dra = dummy_read_addr;
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxllib_get_xsl_config);
-
-int cxllib_switch_phb_mode(struct pci_dev *dev, enum cxllib_mode mode,
- unsigned long flags)
-{
- int rc = 0;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE))
- return -EINVAL;
-
- switch (mode) {
- case CXL_MODE_PCI:
- /*
- * We currently don't support going back to PCI mode
- * However, we'll turn the invalidations off, so that
- * the firmware doesn't have to ack them and can do
- * things like reset, etc.. with no worries.
- * So always return EPERM (can't go back to PCI) or
- * EBUSY if we couldn't even turn off snooping
- */
- rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_OFF);
- if (rc)
- rc = -EBUSY;
- else
- rc = -EPERM;
- break;
- case CXL_MODE_CXL:
- /* DMA only supported on TVT1 for the time being */
- if (flags != CXL_MODE_DMA_TVT1)
- return -EINVAL;
- rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_DMA_TVT1);
- if (rc)
- return rc;
- rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_ON);
- break;
- default:
- rc = -EINVAL;
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(cxllib_switch_phb_mode);
-
-/*
- * When switching the PHB to capi mode, the TVT#1 entry for
- * the Partitionable Endpoint is set in bypass mode, like
- * in PCI mode.
- * Configure the device dma to use TVT#1, which is done
- * by calling dma_set_mask() with a mask large enough.
- */
-int cxllib_set_device_dma(struct pci_dev *dev, unsigned long flags)
-{
- int rc;
-
- if (flags)
- return -EINVAL;
-
- rc = dma_set_mask(&dev->dev, DMA_BIT_MASK(64));
- return rc;
-}
-EXPORT_SYMBOL_GPL(cxllib_set_device_dma);
-
-int cxllib_get_PE_attributes(struct task_struct *task,
- unsigned long translation_mode,
- struct cxllib_pe_attributes *attr)
-{
- if (translation_mode != CXL_TRANSLATED_MODE &&
- translation_mode != CXL_REAL_MODE)
- return -EINVAL;
-
- attr->sr = cxl_calculate_sr(false,
- task == NULL,
- translation_mode == CXL_REAL_MODE,
- true);
- attr->lpid = mfspr(SPRN_LPID);
- if (task) {
- struct mm_struct *mm = get_task_mm(task);
- if (mm == NULL)
- return -EINVAL;
- /*
- * Caller is keeping a reference on mm_users for as long
- * as XSL uses the memory context
- */
- attr->pid = mm->context.id;
- mmput(mm);
- attr->tid = task->thread.tidr;
- } else {
- attr->pid = 0;
- attr->tid = 0;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes);
-
-static int get_vma_info(struct mm_struct *mm, u64 addr,
- u64 *vma_start, u64 *vma_end,
- unsigned long *page_size)
-{
- struct vm_area_struct *vma = NULL;
- int rc = 0;
-
- mmap_read_lock(mm);
-
- vma = find_vma(mm, addr);
- if (!vma) {
- rc = -EFAULT;
- goto out;
- }
- *page_size = vma_kernel_pagesize(vma);
- *vma_start = vma->vm_start;
- *vma_end = vma->vm_end;
-out:
- mmap_read_unlock(mm);
- return rc;
-}
-
-int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags)
-{
- int rc;
- u64 dar, vma_start, vma_end;
- unsigned long page_size;
-
- if (mm == NULL)
- return -EFAULT;
-
- /*
- * The buffer we have to process can extend over several pages
- * and may also cover several VMAs.
- * We iterate over all the pages. The page size could vary
- * between VMAs.
- */
- rc = get_vma_info(mm, addr, &vma_start, &vma_end, &page_size);
- if (rc)
- return rc;
-
- for (dar = (addr & ~(page_size - 1)); dar < (addr + size);
- dar += page_size) {
- if (dar < vma_start || dar >= vma_end) {
- /*
- * We don't hold mm->mmap_lock while iterating, since
- * the lock is required by one of the lower-level page
- * fault processing functions and it could
- * create a deadlock.
- *
- * It means the VMAs can be altered between 2
- * loop iterations and we could theoretically
- * miss a page (however unlikely). But that's
- * not really a problem, as the driver will
- * retry access, get another page fault on the
- * missing page and call us again.
- */
- rc = get_vma_info(mm, dar, &vma_start, &vma_end,
- &page_size);
- if (rc)
- return rc;
- }
-
- rc = cxl_handle_mm_fault(mm, flags, dar);
- if (rc)
- return -EFAULT;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxllib_handle_fault);
diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c
deleted file mode 100644
index 7b987bf498b5..000000000000
--- a/drivers/misc/cxl/debugfs.c
+++ /dev/null
@@ -1,134 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/debugfs.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "cxl.h"
-
-static struct dentry *cxl_debugfs;
-
-/* Helpers to export CXL mmaped IO registers via debugfs */
-static int debugfs_io_u64_get(void *data, u64 *val)
-{
- *val = in_be64((u64 __iomem *)data);
- return 0;
-}
-
-static int debugfs_io_u64_set(void *data, u64 val)
-{
- out_be64((u64 __iomem *)data, val);
- return 0;
-}
-DEFINE_DEBUGFS_ATTRIBUTE(fops_io_x64, debugfs_io_u64_get, debugfs_io_u64_set,
- "0x%016llx\n");
-
-static void debugfs_create_io_x64(const char *name, umode_t mode,
- struct dentry *parent, u64 __iomem *value)
-{
- debugfs_create_file_unsafe(name, mode, parent, (void __force *)value,
- &fops_io_x64);
-}
-
-void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir)
-{
- debugfs_create_io_x64("fir1", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR1));
- debugfs_create_io_x64("fir_mask", 0400, dir,
- _cxl_p1_addr(adapter, CXL_PSL9_FIR_MASK));
- debugfs_create_io_x64("fir_cntl", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR_CNTL));
- debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_TRACECFG));
- debugfs_create_io_x64("debug", 0600, dir,
- _cxl_p1_addr(adapter, CXL_PSL9_DEBUG));
- debugfs_create_io_x64("xsl-debug", 0600, dir,
- _cxl_p1_addr(adapter, CXL_XSL9_DBG));
-}
-
-void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir)
-{
- debugfs_create_io_x64("fir1", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR1));
- debugfs_create_io_x64("fir2", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR2));
- debugfs_create_io_x64("fir_cntl", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR_CNTL));
- debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_TRACE));
-}
-
-void cxl_debugfs_adapter_add(struct cxl *adapter)
-{
- struct dentry *dir;
- char buf[32];
-
- if (!cxl_debugfs)
- return;
-
- snprintf(buf, 32, "card%i", adapter->adapter_num);
- dir = debugfs_create_dir(buf, cxl_debugfs);
- adapter->debugfs = dir;
-
- debugfs_create_io_x64("err_ivte", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_ErrIVTE));
-
- if (adapter->native->sl_ops->debugfs_add_adapter_regs)
- adapter->native->sl_ops->debugfs_add_adapter_regs(adapter, dir);
-}
-
-void cxl_debugfs_adapter_remove(struct cxl *adapter)
-{
- debugfs_remove_recursive(adapter->debugfs);
-}
-
-void cxl_debugfs_add_afu_regs_psl9(struct cxl_afu *afu, struct dentry *dir)
-{
- debugfs_create_io_x64("serr", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SERR_An));
-}
-
-void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir)
-{
- debugfs_create_io_x64("sstp0", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_SSTP0_An));
- debugfs_create_io_x64("sstp1", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_SSTP1_An));
-
- debugfs_create_io_x64("fir", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_FIR_SLICE_An));
- debugfs_create_io_x64("serr", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SERR_An));
- debugfs_create_io_x64("afu_debug", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_AFU_DEBUG_An));
- debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SLICE_TRACE));
-}
-
-void cxl_debugfs_afu_add(struct cxl_afu *afu)
-{
- struct dentry *dir;
- char buf[32];
-
- if (!afu->adapter->debugfs)
- return;
-
- snprintf(buf, 32, "psl%i.%i", afu->adapter->adapter_num, afu->slice);
- dir = debugfs_create_dir(buf, afu->adapter->debugfs);
- afu->debugfs = dir;
-
- debugfs_create_io_x64("sr", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SR_An));
- debugfs_create_io_x64("dsisr", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_PSL_DSISR_An));
- debugfs_create_io_x64("dar", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_PSL_DAR_An));
-
- debugfs_create_io_x64("err_status", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_PSL_ErrStat_An));
-
- if (afu->adapter->native->sl_ops->debugfs_add_afu_regs)
- afu->adapter->native->sl_ops->debugfs_add_afu_regs(afu, dir);
-}
-
-void cxl_debugfs_afu_remove(struct cxl_afu *afu)
-{
- debugfs_remove_recursive(afu->debugfs);
-}
-
-void __init cxl_debugfs_init(void)
-{
- if (!cpu_has_feature(CPU_FTR_HVMODE))
- return;
-
- cxl_debugfs = debugfs_create_dir("cxl", NULL);
-}
-
-void cxl_debugfs_exit(void)
-{
- debugfs_remove_recursive(cxl_debugfs);
-}
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
deleted file mode 100644
index 2c64f55cf01f..000000000000
--- a/drivers/misc/cxl/fault.c
+++ /dev/null
@@ -1,341 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/workqueue.h>
-#include <linux/sched/signal.h>
-#include <linux/sched/mm.h>
-#include <linux/pid.h>
-#include <linux/mm.h>
-#include <linux/moduleparam.h>
-
-#undef MODULE_PARAM_PREFIX
-#define MODULE_PARAM_PREFIX "cxl" "."
-#include <asm/current.h>
-#include <asm/copro.h>
-#include <asm/mmu.h>
-
-#include "cxl.h"
-#include "trace.h"
-
-static bool sste_matches(struct cxl_sste *sste, struct copro_slb *slb)
-{
- return ((sste->vsid_data == cpu_to_be64(slb->vsid)) &&
- (sste->esid_data == cpu_to_be64(slb->esid)));
-}
-
-/*
- * This finds a free SSTE for the given SLB, or returns NULL if it's already in
- * the segment table.
- */
-static struct cxl_sste *find_free_sste(struct cxl_context *ctx,
- struct copro_slb *slb)
-{
- struct cxl_sste *primary, *sste, *ret = NULL;
- unsigned int mask = (ctx->sst_size >> 7) - 1; /* SSTP0[SegTableSize] */
- unsigned int entry;
- unsigned int hash;
-
- if (slb->vsid & SLB_VSID_B_1T)
- hash = (slb->esid >> SID_SHIFT_1T) & mask;
- else /* 256M */
- hash = (slb->esid >> SID_SHIFT) & mask;
-
- primary = ctx->sstp + (hash << 3);
-
- for (entry = 0, sste = primary; entry < 8; entry++, sste++) {
- if (!ret && !(be64_to_cpu(sste->esid_data) & SLB_ESID_V))
- ret = sste;
- if (sste_matches(sste, slb))
- return NULL;
- }
- if (ret)
- return ret;
-
- /* Nothing free, select an entry to cast out */
- ret = primary + ctx->sst_lru;
- ctx->sst_lru = (ctx->sst_lru + 1) & 0x7;
-
- return ret;
-}
-
-static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb)
-{
- /* mask is the group index, we search primary and secondary here. */
- struct cxl_sste *sste;
- unsigned long flags;
-
- spin_lock_irqsave(&ctx->sste_lock, flags);
- sste = find_free_sste(ctx, slb);
- if (!sste)
- goto out_unlock;
-
- pr_devel("CXL Populating SST[%li]: %#llx %#llx\n",
- sste - ctx->sstp, slb->vsid, slb->esid);
- trace_cxl_ste_write(ctx, sste - ctx->sstp, slb->esid, slb->vsid);
-
- sste->vsid_data = cpu_to_be64(slb->vsid);
- sste->esid_data = cpu_to_be64(slb->esid);
-out_unlock:
- spin_unlock_irqrestore(&ctx->sste_lock, flags);
-}
-
-static int cxl_fault_segment(struct cxl_context *ctx, struct mm_struct *mm,
- u64 ea)
-{
- struct copro_slb slb = {0,0};
- int rc;
-
- if (!(rc = copro_calculate_slb(mm, ea, &slb))) {
- cxl_load_segment(ctx, &slb);
- }
-
- return rc;
-}
-
-static void cxl_ack_ae(struct cxl_context *ctx)
-{
- unsigned long flags;
-
- cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
-
- spin_lock_irqsave(&ctx->lock, flags);
- ctx->pending_fault = true;
- ctx->fault_addr = ctx->dar;
- ctx->fault_dsisr = ctx->dsisr;
- spin_unlock_irqrestore(&ctx->lock, flags);
-
- wake_up_all(&ctx->wq);
-}
-
-static int cxl_handle_segment_miss(struct cxl_context *ctx,
- struct mm_struct *mm, u64 ea)
-{
- int rc;
-
- pr_devel("CXL interrupt: Segment fault pe: %i ea: %#llx\n", ctx->pe, ea);
- trace_cxl_ste_miss(ctx, ea);
-
- if ((rc = cxl_fault_segment(ctx, mm, ea)))
- cxl_ack_ae(ctx);
- else {
-
- mb(); /* Order seg table write to TFC MMIO write */
- cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
- }
-
- return IRQ_HANDLED;
-}
-
-int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar)
-{
- vm_fault_t flt = 0;
- int result;
- unsigned long access, flags, inv_flags = 0;
-
- /*
- * Add the fault handling cpu to task mm cpumask so that we
- * can do a safe lockless page table walk when inserting the
- * hash page table entry. This function get called with a
- * valid mm for user space addresses. Hence using the if (mm)
- * check is sufficient here.
- */
- if (mm && !cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
- cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
- /*
- * We need to make sure we walk the table only after
- * we update the cpumask. The other side of the barrier
- * is explained in serialize_against_pte_lookup()
- */
- smp_mb();
- }
- if ((result = copro_handle_mm_fault(mm, dar, dsisr, &flt))) {
- pr_devel("copro_handle_mm_fault failed: %#x\n", result);
- return result;
- }
-
- if (!radix_enabled()) {
- /*
- * update_mmu_cache() will not have loaded the hash since current->trap
- * is not a 0x400 or 0x300, so just call hash_page_mm() here.
- */
- access = _PAGE_PRESENT | _PAGE_READ;
- if (dsisr & CXL_PSL_DSISR_An_S)
- access |= _PAGE_WRITE;
-
- if (!mm && (get_region_id(dar) != USER_REGION_ID))
- access |= _PAGE_PRIVILEGED;
-
- if (dsisr & DSISR_NOHPTE)
- inv_flags |= HPTE_NOHPTE_UPDATE;
-
- local_irq_save(flags);
- hash_page_mm(mm, dar, access, 0x300, inv_flags);
- local_irq_restore(flags);
- }
- return 0;
-}
-
-static void cxl_handle_page_fault(struct cxl_context *ctx,
- struct mm_struct *mm,
- u64 dsisr, u64 dar)
-{
- trace_cxl_pte_miss(ctx, dsisr, dar);
-
- if (cxl_handle_mm_fault(mm, dsisr, dar)) {
- cxl_ack_ae(ctx);
- } else {
- pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
- cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
- }
-}
-
-/*
- * Returns the mm_struct corresponding to the context ctx.
- * mm_users == 0, the context may be in the process of being closed.
- */
-static struct mm_struct *get_mem_context(struct cxl_context *ctx)
-{
- if (ctx->mm == NULL)
- return NULL;
-
- if (!mmget_not_zero(ctx->mm))
- return NULL;
-
- return ctx->mm;
-}
-
-static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr)
-{
- if ((cxl_is_power8() && (dsisr & CXL_PSL_DSISR_An_DS)))
- return true;
-
- return false;
-}
-
-static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr)
-{
- if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_An_DM))
- return true;
-
- if (cxl_is_power9())
- return true;
-
- return false;
-}
-
-void cxl_handle_fault(struct work_struct *fault_work)
-{
- struct cxl_context *ctx =
- container_of(fault_work, struct cxl_context, fault_work);
- u64 dsisr = ctx->dsisr;
- u64 dar = ctx->dar;
- struct mm_struct *mm = NULL;
-
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr ||
- cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar ||
- cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) != ctx->pe) {
- /* Most likely explanation is harmless - a dedicated
- * process has detached and these were cleared by the
- * PSL purge, but warn about it just in case
- */
- dev_notice(&ctx->afu->dev, "cxl_handle_fault: Translation fault regs changed\n");
- return;
- }
- }
-
- /* Early return if the context is being / has been detached */
- if (ctx->status == CLOSED) {
- cxl_ack_ae(ctx);
- return;
- }
-
- pr_devel("CXL BOTTOM HALF handling fault for afu pe: %i. "
- "DSISR: %#llx DAR: %#llx\n", ctx->pe, dsisr, dar);
-
- if (!ctx->kernel) {
-
- mm = get_mem_context(ctx);
- if (mm == NULL) {
- pr_devel("%s: unable to get mm for pe=%d pid=%i\n",
- __func__, ctx->pe, pid_nr(ctx->pid));
- cxl_ack_ae(ctx);
- return;
- } else {
- pr_devel("Handling page fault for pe=%d pid=%i\n",
- ctx->pe, pid_nr(ctx->pid));
- }
- }
-
- if (cxl_is_segment_miss(ctx, dsisr))
- cxl_handle_segment_miss(ctx, mm, dar);
- else if (cxl_is_page_fault(ctx, dsisr))
- cxl_handle_page_fault(ctx, mm, dsisr, dar);
- else
- WARN(1, "cxl_handle_fault has nothing to handle\n");
-
- if (mm)
- mmput(mm);
-}
-
-static u64 next_segment(u64 ea, u64 vsid)
-{
- if (vsid & SLB_VSID_B_1T)
- ea |= (1ULL << 40) - 1;
- else
- ea |= (1ULL << 28) - 1;
-
- return ea + 1;
-}
-
-static void cxl_prefault_vma(struct cxl_context *ctx, struct mm_struct *mm)
-{
- u64 ea, last_esid = 0;
- struct copro_slb slb;
- VMA_ITERATOR(vmi, mm, 0);
- struct vm_area_struct *vma;
- int rc;
-
- mmap_read_lock(mm);
- for_each_vma(vmi, vma) {
- for (ea = vma->vm_start; ea < vma->vm_end;
- ea = next_segment(ea, slb.vsid)) {
- rc = copro_calculate_slb(mm, ea, &slb);
- if (rc)
- continue;
-
- if (last_esid == slb.esid)
- continue;
-
- cxl_load_segment(ctx, &slb);
- last_esid = slb.esid;
- }
- }
- mmap_read_unlock(mm);
-}
-
-void cxl_prefault(struct cxl_context *ctx, u64 wed)
-{
- struct mm_struct *mm = get_mem_context(ctx);
-
- if (mm == NULL) {
- pr_devel("cxl_prefault unable to get mm %i\n",
- pid_nr(ctx->pid));
- return;
- }
-
- switch (ctx->afu->prefault_mode) {
- case CXL_PREFAULT_WED:
- cxl_fault_segment(ctx, mm, wed);
- break;
- case CXL_PREFAULT_ALL:
- cxl_prefault_vma(ctx, mm);
- break;
- default:
- break;
- }
-
- mmput(mm);
-}
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
deleted file mode 100644
index 012e11b959bc..000000000000
--- a/drivers/misc/cxl/file.c
+++ /dev/null
@@ -1,699 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/sched/signal.h>
-#include <linux/poll.h>
-#include <linux/pid.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/sched/mm.h>
-#include <linux/mmu_context.h>
-#include <asm/cputable.h>
-#include <asm/current.h>
-#include <asm/copro.h>
-
-#include "cxl.h"
-#include "trace.h"
-
-#define CXL_NUM_MINORS 256 /* Total to reserve */
-
-#define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice))
-#define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1)
-#define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2)
-#define CXL_AFU_MKDEV_D(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_D(afu))
-#define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu))
-#define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu))
-
-#define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3)
-
-#define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0)
-
-static dev_t cxl_dev;
-
-static int __afu_open(struct inode *inode, struct file *file, bool master)
-{
- struct cxl *adapter;
- struct cxl_afu *afu;
- struct cxl_context *ctx;
- int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
- int slice = CXL_DEVT_AFU(inode->i_rdev);
- int rc = -ENODEV;
-
- pr_devel("afu_open afu%i.%i\n", slice, adapter_num);
-
- if (!(adapter = get_cxl_adapter(adapter_num)))
- return -ENODEV;
-
- if (slice > adapter->slices)
- goto err_put_adapter;
-
- spin_lock(&adapter->afu_list_lock);
- if (!(afu = adapter->afu[slice])) {
- spin_unlock(&adapter->afu_list_lock);
- goto err_put_adapter;
- }
-
- /*
- * taking a ref to the afu so that it doesn't go away
- * for rest of the function. This ref is released before
- * we return.
- */
- cxl_afu_get(afu);
- spin_unlock(&adapter->afu_list_lock);
-
- if (!afu->current_mode)
- goto err_put_afu;
-
- if (!cxl_ops->link_ok(adapter, afu)) {
- rc = -EIO;
- goto err_put_afu;
- }
-
- if (!(ctx = cxl_context_alloc())) {
- rc = -ENOMEM;
- goto err_put_afu;
- }
-
- rc = cxl_context_init(ctx, afu, master);
- if (rc)
- goto err_put_afu;
-
- cxl_context_set_mapping(ctx, inode->i_mapping);
-
- pr_devel("afu_open pe: %i\n", ctx->pe);
- file->private_data = ctx;
-
- /* indicate success */
- rc = 0;
-
-err_put_afu:
- /* release the ref taken earlier */
- cxl_afu_put(afu);
-err_put_adapter:
- put_device(&adapter->dev);
- return rc;
-}
-
-int afu_open(struct inode *inode, struct file *file)
-{
- return __afu_open(inode, file, false);
-}
-
-static int afu_master_open(struct inode *inode, struct file *file)
-{
- return __afu_open(inode, file, true);
-}
-
-int afu_release(struct inode *inode, struct file *file)
-{
- struct cxl_context *ctx = file->private_data;
-
- pr_devel("%s: closing cxl file descriptor. pe: %i\n",
- __func__, ctx->pe);
- cxl_context_detach(ctx);
-
-
- /*
- * Delete the context's mapping pointer, unless it's created by the
- * kernel API, in which case leave it so it can be freed by reclaim_ctx()
- */
- if (!ctx->kernelapi) {
- mutex_lock(&ctx->mapping_lock);
- ctx->mapping = NULL;
- mutex_unlock(&ctx->mapping_lock);
- }
-
- /*
- * At this this point all bottom halfs have finished and we should be
- * getting no more IRQs from the hardware for this context. Once it's
- * removed from the IDR (and RCU synchronised) it's safe to free the
- * sstp and context.
- */
- cxl_context_free(ctx);
-
- return 0;
-}
-
-static long afu_ioctl_start_work(struct cxl_context *ctx,
- struct cxl_ioctl_start_work __user *uwork)
-{
- struct cxl_ioctl_start_work work;
- u64 amr = 0;
- int rc;
-
- pr_devel("%s: pe: %i\n", __func__, ctx->pe);
-
- /* Do this outside the status_mutex to avoid a circular dependency with
- * the locking in cxl_mmap_fault() */
- if (copy_from_user(&work, uwork, sizeof(work)))
- return -EFAULT;
-
- mutex_lock(&ctx->status_mutex);
- if (ctx->status != OPENED) {
- rc = -EIO;
- goto out;
- }
-
- /*
- * if any of the reserved fields are set or any of the unused
- * flags are set it's invalid
- */
- if (work.reserved1 || work.reserved2 || work.reserved3 ||
- work.reserved4 || work.reserved5 ||
- (work.flags & ~CXL_START_WORK_ALL)) {
- rc = -EINVAL;
- goto out;
- }
-
- if (!(work.flags & CXL_START_WORK_NUM_IRQS))
- work.num_interrupts = ctx->afu->pp_irqs;
- else if ((work.num_interrupts < ctx->afu->pp_irqs) ||
- (work.num_interrupts > ctx->afu->irqs_max)) {
- rc = -EINVAL;
- goto out;
- }
-
- if ((rc = afu_register_irqs(ctx, work.num_interrupts)))
- goto out;
-
- if (work.flags & CXL_START_WORK_AMR)
- amr = work.amr & mfspr(SPRN_UAMOR);
-
- if (work.flags & CXL_START_WORK_TID)
- ctx->assign_tidr = true;
-
- ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF);
-
- /*
- * Increment the mapped context count for adapter. This also checks
- * if adapter_context_lock is taken.
- */
- rc = cxl_adapter_context_get(ctx->afu->adapter);
- if (rc) {
- afu_release_irqs(ctx, ctx);
- goto out;
- }
-
- /*
- * We grab the PID here and not in the file open to allow for the case
- * where a process (master, some daemon, etc) has opened the chardev on
- * behalf of another process, so the AFU's mm gets bound to the process
- * that performs this ioctl and not the process that opened the file.
- * Also we grab the PID of the group leader so that if the task that
- * has performed the attach operation exits the mm context of the
- * process is still accessible.
- */
- ctx->pid = get_task_pid(current, PIDTYPE_PID);
-
- /* acquire a reference to the task's mm */
- ctx->mm = get_task_mm(current);
-
- /* ensure this mm_struct can't be freed */
- cxl_context_mm_count_get(ctx);
-
- if (ctx->mm) {
- /* decrement the use count from above */
- mmput(ctx->mm);
- /* make TLBIs for this context global */
- mm_context_add_copro(ctx->mm);
- }
-
- /*
- * Increment driver use count. Enables global TLBIs for hash
- * and callbacks to handle the segment table
- */
- cxl_ctx_get();
-
- /*
- * A barrier is needed to make sure all TLBIs are global
- * before we attach and the context starts being used by the
- * adapter.
- *
- * Needed after mm_context_add_copro() for radix and
- * cxl_ctx_get() for hash/p8.
- *
- * The barrier should really be mb(), since it involves a
- * device. However, it's only useful when we have local
- * vs. global TLBIs, i.e SMP=y. So keep smp_mb().
- */
- smp_mb();
-
- trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
-
- if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
- amr))) {
- afu_release_irqs(ctx, ctx);
- cxl_adapter_context_put(ctx->afu->adapter);
- put_pid(ctx->pid);
- ctx->pid = NULL;
- cxl_ctx_put();
- cxl_context_mm_count_put(ctx);
- if (ctx->mm)
- mm_context_remove_copro(ctx->mm);
- goto out;
- }
-
- rc = 0;
- if (work.flags & CXL_START_WORK_TID) {
- work.tid = ctx->tidr;
- if (copy_to_user(uwork, &work, sizeof(work)))
- rc = -EFAULT;
- }
-
- ctx->status = STARTED;
-
-out:
- mutex_unlock(&ctx->status_mutex);
- return rc;
-}
-
-static long afu_ioctl_process_element(struct cxl_context *ctx,
- int __user *upe)
-{
- pr_devel("%s: pe: %i\n", __func__, ctx->pe);
-
- if (copy_to_user(upe, &ctx->external_pe, sizeof(__u32)))
- return -EFAULT;
-
- return 0;
-}
-
-static long afu_ioctl_get_afu_id(struct cxl_context *ctx,
- struct cxl_afu_id __user *upafuid)
-{
- struct cxl_afu_id afuid = { 0 };
-
- afuid.card_id = ctx->afu->adapter->adapter_num;
- afuid.afu_offset = ctx->afu->slice;
- afuid.afu_mode = ctx->afu->current_mode;
-
- /* set the flag bit in case the afu is a slave */
- if (ctx->afu->current_mode == CXL_MODE_DIRECTED && !ctx->master)
- afuid.flags |= CXL_AFUID_FLAG_SLAVE;
-
- if (copy_to_user(upafuid, &afuid, sizeof(afuid)))
- return -EFAULT;
-
- return 0;
-}
-
-long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct cxl_context *ctx = file->private_data;
-
- if (ctx->status == CLOSED)
- return -EIO;
-
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
- return -EIO;
-
- pr_devel("afu_ioctl\n");
- switch (cmd) {
- case CXL_IOCTL_START_WORK:
- return afu_ioctl_start_work(ctx, (struct cxl_ioctl_start_work __user *)arg);
- case CXL_IOCTL_GET_PROCESS_ELEMENT:
- return afu_ioctl_process_element(ctx, (__u32 __user *)arg);
- case CXL_IOCTL_GET_AFU_ID:
- return afu_ioctl_get_afu_id(ctx, (struct cxl_afu_id __user *)
- arg);
- }
- return -EINVAL;
-}
-
-static long afu_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return afu_ioctl(file, cmd, arg);
-}
-
-int afu_mmap(struct file *file, struct vm_area_struct *vm)
-{
- struct cxl_context *ctx = file->private_data;
-
- /* AFU must be started before we can MMIO */
- if (ctx->status != STARTED)
- return -EIO;
-
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
- return -EIO;
-
- return cxl_context_iomap(ctx, vm);
-}
-
-static inline bool ctx_event_pending(struct cxl_context *ctx)
-{
- if (ctx->pending_irq || ctx->pending_fault || ctx->pending_afu_err)
- return true;
-
- if (ctx->afu_driver_ops && atomic_read(&ctx->afu_driver_events))
- return true;
-
- return false;
-}
-
-__poll_t afu_poll(struct file *file, struct poll_table_struct *poll)
-{
- struct cxl_context *ctx = file->private_data;
- __poll_t mask = 0;
- unsigned long flags;
-
-
- poll_wait(file, &ctx->wq, poll);
-
- pr_devel("afu_poll wait done pe: %i\n", ctx->pe);
-
- spin_lock_irqsave(&ctx->lock, flags);
- if (ctx_event_pending(ctx))
- mask |= EPOLLIN | EPOLLRDNORM;
- else if (ctx->status == CLOSED)
- /* Only error on closed when there are no futher events pending
- */
- mask |= EPOLLERR;
- spin_unlock_irqrestore(&ctx->lock, flags);
-
- pr_devel("afu_poll pe: %i returning %#x\n", ctx->pe, mask);
-
- return mask;
-}
-
-static ssize_t afu_driver_event_copy(struct cxl_context *ctx,
- char __user *buf,
- struct cxl_event *event,
- struct cxl_event_afu_driver_reserved *pl)
-{
- /* Check event */
- if (!pl) {
- ctx->afu_driver_ops->event_delivered(ctx, pl, -EINVAL);
- return -EFAULT;
- }
-
- /* Check event size */
- event->header.size += pl->data_size;
- if (event->header.size > CXL_READ_MIN_SIZE) {
- ctx->afu_driver_ops->event_delivered(ctx, pl, -EINVAL);
- return -EFAULT;
- }
-
- /* Copy event header */
- if (copy_to_user(buf, event, sizeof(struct cxl_event_header))) {
- ctx->afu_driver_ops->event_delivered(ctx, pl, -EFAULT);
- return -EFAULT;
- }
-
- /* Copy event data */
- buf += sizeof(struct cxl_event_header);
- if (copy_to_user(buf, &pl->data, pl->data_size)) {
- ctx->afu_driver_ops->event_delivered(ctx, pl, -EFAULT);
- return -EFAULT;
- }
-
- ctx->afu_driver_ops->event_delivered(ctx, pl, 0); /* Success */
- return event->header.size;
-}
-
-ssize_t afu_read(struct file *file, char __user *buf, size_t count,
- loff_t *off)
-{
- struct cxl_context *ctx = file->private_data;
- struct cxl_event_afu_driver_reserved *pl = NULL;
- struct cxl_event event;
- unsigned long flags;
- int rc;
- DEFINE_WAIT(wait);
-
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
- return -EIO;
-
- if (count < CXL_READ_MIN_SIZE)
- return -EINVAL;
-
- spin_lock_irqsave(&ctx->lock, flags);
-
- for (;;) {
- prepare_to_wait(&ctx->wq, &wait, TASK_INTERRUPTIBLE);
- if (ctx_event_pending(ctx) || (ctx->status == CLOSED))
- break;
-
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
- rc = -EIO;
- goto out;
- }
-
- if (file->f_flags & O_NONBLOCK) {
- rc = -EAGAIN;
- goto out;
- }
-
- if (signal_pending(current)) {
- rc = -ERESTARTSYS;
- goto out;
- }
-
- spin_unlock_irqrestore(&ctx->lock, flags);
- pr_devel("afu_read going to sleep...\n");
- schedule();
- pr_devel("afu_read woken up\n");
- spin_lock_irqsave(&ctx->lock, flags);
- }
-
- finish_wait(&ctx->wq, &wait);
-
- memset(&event, 0, sizeof(event));
- event.header.process_element = ctx->pe;
- event.header.size = sizeof(struct cxl_event_header);
- if (ctx->afu_driver_ops && atomic_read(&ctx->afu_driver_events)) {
- pr_devel("afu_read delivering AFU driver specific event\n");
- pl = ctx->afu_driver_ops->fetch_event(ctx);
- atomic_dec(&ctx->afu_driver_events);
- event.header.type = CXL_EVENT_AFU_DRIVER;
- } else if (ctx->pending_irq) {
- pr_devel("afu_read delivering AFU interrupt\n");
- event.header.size += sizeof(struct cxl_event_afu_interrupt);
- event.header.type = CXL_EVENT_AFU_INTERRUPT;
- event.irq.irq = find_first_bit(ctx->irq_bitmap, ctx->irq_count) + 1;
- clear_bit(event.irq.irq - 1, ctx->irq_bitmap);
- if (bitmap_empty(ctx->irq_bitmap, ctx->irq_count))
- ctx->pending_irq = false;
- } else if (ctx->pending_fault) {
- pr_devel("afu_read delivering data storage fault\n");
- event.header.size += sizeof(struct cxl_event_data_storage);
- event.header.type = CXL_EVENT_DATA_STORAGE;
- event.fault.addr = ctx->fault_addr;
- event.fault.dsisr = ctx->fault_dsisr;
- ctx->pending_fault = false;
- } else if (ctx->pending_afu_err) {
- pr_devel("afu_read delivering afu error\n");
- event.header.size += sizeof(struct cxl_event_afu_error);
- event.header.type = CXL_EVENT_AFU_ERROR;
- event.afu_error.error = ctx->afu_err;
- ctx->pending_afu_err = false;
- } else if (ctx->status == CLOSED) {
- pr_devel("afu_read fatal error\n");
- spin_unlock_irqrestore(&ctx->lock, flags);
- return -EIO;
- } else
- WARN(1, "afu_read must be buggy\n");
-
- spin_unlock_irqrestore(&ctx->lock, flags);
-
- if (event.header.type == CXL_EVENT_AFU_DRIVER)
- return afu_driver_event_copy(ctx, buf, &event, pl);
-
- if (copy_to_user(buf, &event, event.header.size))
- return -EFAULT;
- return event.header.size;
-
-out:
- finish_wait(&ctx->wq, &wait);
- spin_unlock_irqrestore(&ctx->lock, flags);
- return rc;
-}
-
-/*
- * Note: if this is updated, we need to update api.c to patch the new ones in
- * too
- */
-const struct file_operations afu_fops = {
- .owner = THIS_MODULE,
- .open = afu_open,
- .poll = afu_poll,
- .read = afu_read,
- .release = afu_release,
- .unlocked_ioctl = afu_ioctl,
- .compat_ioctl = afu_compat_ioctl,
- .mmap = afu_mmap,
-};
-
-static const struct file_operations afu_master_fops = {
- .owner = THIS_MODULE,
- .open = afu_master_open,
- .poll = afu_poll,
- .read = afu_read,
- .release = afu_release,
- .unlocked_ioctl = afu_ioctl,
- .compat_ioctl = afu_compat_ioctl,
- .mmap = afu_mmap,
-};
-
-
-static char *cxl_devnode(const struct device *dev, umode_t *mode)
-{
- if (cpu_has_feature(CPU_FTR_HVMODE) &&
- CXL_DEVT_IS_CARD(dev->devt)) {
- /*
- * These minor numbers will eventually be used to program the
- * PSL and AFUs once we have dynamic reprogramming support
- */
- return NULL;
- }
- return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev));
-}
-
-static const struct class cxl_class = {
- .name = "cxl",
- .devnode = cxl_devnode,
-};
-
-static int cxl_add_chardev(struct cxl_afu *afu, dev_t devt, struct cdev *cdev,
- struct device **chardev, char *postfix, char *desc,
- const struct file_operations *fops)
-{
- struct device *dev;
- int rc;
-
- cdev_init(cdev, fops);
- rc = cdev_add(cdev, devt, 1);
- if (rc) {
- dev_err(&afu->dev, "Unable to add %s chardev: %i\n", desc, rc);
- return rc;
- }
-
- dev = device_create(&cxl_class, &afu->dev, devt, afu,
- "afu%i.%i%s", afu->adapter->adapter_num, afu->slice, postfix);
- if (IS_ERR(dev)) {
- rc = PTR_ERR(dev);
- dev_err(&afu->dev, "Unable to create %s chardev in sysfs: %i\n", desc, rc);
- goto err;
- }
-
- *chardev = dev;
-
- return 0;
-err:
- cdev_del(cdev);
- return rc;
-}
-
-int cxl_chardev_d_afu_add(struct cxl_afu *afu)
-{
- return cxl_add_chardev(afu, CXL_AFU_MKDEV_D(afu), &afu->afu_cdev_d,
- &afu->chardev_d, "d", "dedicated",
- &afu_master_fops); /* Uses master fops */
-}
-
-int cxl_chardev_m_afu_add(struct cxl_afu *afu)
-{
- return cxl_add_chardev(afu, CXL_AFU_MKDEV_M(afu), &afu->afu_cdev_m,
- &afu->chardev_m, "m", "master",
- &afu_master_fops);
-}
-
-int cxl_chardev_s_afu_add(struct cxl_afu *afu)
-{
- return cxl_add_chardev(afu, CXL_AFU_MKDEV_S(afu), &afu->afu_cdev_s,
- &afu->chardev_s, "s", "shared",
- &afu_fops);
-}
-
-void cxl_chardev_afu_remove(struct cxl_afu *afu)
-{
- if (afu->chardev_d) {
- cdev_del(&afu->afu_cdev_d);
- device_unregister(afu->chardev_d);
- afu->chardev_d = NULL;
- }
- if (afu->chardev_m) {
- cdev_del(&afu->afu_cdev_m);
- device_unregister(afu->chardev_m);
- afu->chardev_m = NULL;
- }
- if (afu->chardev_s) {
- cdev_del(&afu->afu_cdev_s);
- device_unregister(afu->chardev_s);
- afu->chardev_s = NULL;
- }
-}
-
-int cxl_register_afu(struct cxl_afu *afu)
-{
- afu->dev.class = &cxl_class;
-
- return device_register(&afu->dev);
-}
-
-int cxl_register_adapter(struct cxl *adapter)
-{
- adapter->dev.class = &cxl_class;
-
- /*
- * Future: When we support dynamically reprogramming the PSL & AFU we
- * will expose the interface to do that via a chardev:
- * adapter->dev.devt = CXL_CARD_MKDEV(adapter);
- */
-
- return device_register(&adapter->dev);
-}
-
-dev_t cxl_get_dev(void)
-{
- return cxl_dev;
-}
-
-int __init cxl_file_init(void)
-{
- int rc;
-
- /*
- * If these change we really need to update API. Either change some
- * flags or update API version number CXL_API_VERSION.
- */
- BUILD_BUG_ON(CXL_API_VERSION != 3);
- BUILD_BUG_ON(sizeof(struct cxl_ioctl_start_work) != 64);
- BUILD_BUG_ON(sizeof(struct cxl_event_header) != 8);
- BUILD_BUG_ON(sizeof(struct cxl_event_afu_interrupt) != 8);
- BUILD_BUG_ON(sizeof(struct cxl_event_data_storage) != 32);
- BUILD_BUG_ON(sizeof(struct cxl_event_afu_error) != 16);
-
- if ((rc = alloc_chrdev_region(&cxl_dev, 0, CXL_NUM_MINORS, "cxl"))) {
- pr_err("Unable to allocate CXL major number: %i\n", rc);
- return rc;
- }
-
- pr_devel("CXL device allocated, MAJOR %i\n", MAJOR(cxl_dev));
-
- rc = class_register(&cxl_class);
- if (rc) {
- pr_err("Unable to create CXL class\n");
- goto err;
- }
-
- return 0;
-
-err:
- unregister_chrdev_region(cxl_dev, CXL_NUM_MINORS);
- return rc;
-}
-
-void cxl_file_exit(void)
-{
- unregister_chrdev_region(cxl_dev, CXL_NUM_MINORS);
- class_unregister(&cxl_class);
-}
diff --git a/drivers/misc/cxl/flash.c b/drivers/misc/cxl/flash.c
deleted file mode 100644
index eee9decc121e..000000000000
--- a/drivers/misc/cxl/flash.c
+++ /dev/null
@@ -1,538 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/semaphore.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/of.h>
-#include <asm/rtas.h>
-
-#include "cxl.h"
-#include "hcalls.h"
-
-#define DOWNLOAD_IMAGE 1
-#define VALIDATE_IMAGE 2
-
-struct ai_header {
- u16 version;
- u8 reserved0[6];
- u16 vendor;
- u16 device;
- u16 subsystem_vendor;
- u16 subsystem;
- u64 image_offset;
- u64 image_length;
- u8 reserved1[96];
-};
-
-static struct semaphore sem;
-static unsigned long *buffer[CXL_AI_MAX_ENTRIES];
-static struct sg_list *le;
-static u64 continue_token;
-static unsigned int transfer;
-
-struct update_props_workarea {
- __be32 phandle;
- __be32 state;
- __be64 reserved;
- __be32 nprops;
-} __packed;
-
-struct update_nodes_workarea {
- __be32 state;
- __be64 unit_address;
- __be32 reserved;
-} __packed;
-
-#define DEVICE_SCOPE 3
-#define NODE_ACTION_MASK 0xff000000
-#define NODE_COUNT_MASK 0x00ffffff
-#define OPCODE_DELETE 0x01000000
-#define OPCODE_UPDATE 0x02000000
-#define OPCODE_ADD 0x03000000
-
-static int rcall(int token, char *buf, s32 scope)
-{
- int rc;
-
- spin_lock(&rtas_data_buf_lock);
-
- memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
- rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
- memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
-
- spin_unlock(&rtas_data_buf_lock);
- return rc;
-}
-
-static int update_property(struct device_node *dn, const char *name,
- u32 vd, char *value)
-{
- struct property *new_prop;
- u32 *val;
- int rc;
-
- new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
- if (!new_prop)
- return -ENOMEM;
-
- new_prop->name = kstrdup(name, GFP_KERNEL);
- if (!new_prop->name) {
- kfree(new_prop);
- return -ENOMEM;
- }
-
- new_prop->length = vd;
- new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
- if (!new_prop->value) {
- kfree(new_prop->name);
- kfree(new_prop);
- return -ENOMEM;
- }
- memcpy(new_prop->value, value, vd);
-
- val = (u32 *)new_prop->value;
- rc = cxl_update_properties(dn, new_prop);
- pr_devel("%pOFn: update property (%s, length: %i, value: %#x)\n",
- dn, name, vd, be32_to_cpu(*val));
-
- if (rc) {
- kfree(new_prop->name);
- kfree(new_prop->value);
- kfree(new_prop);
- }
- return rc;
-}
-
-static int update_node(__be32 phandle, s32 scope)
-{
- struct update_props_workarea *upwa;
- struct device_node *dn;
- int i, rc, ret;
- char *prop_data;
- char *buf;
- int token;
- u32 nprops;
- u32 vd;
-
- token = rtas_token("ibm,update-properties");
- if (token == RTAS_UNKNOWN_SERVICE)
- return -EINVAL;
-
- buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- dn = of_find_node_by_phandle(be32_to_cpu(phandle));
- if (!dn) {
- kfree(buf);
- return -ENOENT;
- }
-
- upwa = (struct update_props_workarea *)&buf[0];
- upwa->phandle = phandle;
- do {
- rc = rcall(token, buf, scope);
- if (rc < 0)
- break;
-
- prop_data = buf + sizeof(*upwa);
- nprops = be32_to_cpu(upwa->nprops);
-
- if (*prop_data == 0) {
- prop_data++;
- vd = be32_to_cpu(*(__be32 *)prop_data);
- prop_data += vd + sizeof(vd);
- nprops--;
- }
-
- for (i = 0; i < nprops; i++) {
- char *prop_name;
-
- prop_name = prop_data;
- prop_data += strlen(prop_name) + 1;
- vd = be32_to_cpu(*(__be32 *)prop_data);
- prop_data += sizeof(vd);
-
- if ((vd != 0x00000000) && (vd != 0x80000000)) {
- ret = update_property(dn, prop_name, vd,
- prop_data);
- if (ret)
- pr_err("cxl: Could not update property %s - %i\n",
- prop_name, ret);
-
- prop_data += vd;
- }
- }
- } while (rc == 1);
-
- of_node_put(dn);
- kfree(buf);
- return rc;
-}
-
-static int update_devicetree(struct cxl *adapter, s32 scope)
-{
- struct update_nodes_workarea *unwa;
- u32 action, node_count;
- int token, rc, i;
- __be32 *data, phandle;
- char *buf;
-
- token = rtas_token("ibm,update-nodes");
- if (token == RTAS_UNKNOWN_SERVICE)
- return -EINVAL;
-
- buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- unwa = (struct update_nodes_workarea *)&buf[0];
- unwa->unit_address = cpu_to_be64(adapter->guest->handle);
- do {
- rc = rcall(token, buf, scope);
- if (rc && rc != 1)
- break;
-
- data = (__be32 *)buf + 4;
- while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
- action = be32_to_cpu(*data) & NODE_ACTION_MASK;
- node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;
- pr_devel("device reconfiguration - action: %#x, nodes: %#x\n",
- action, node_count);
- data++;
-
- for (i = 0; i < node_count; i++) {
- phandle = *data++;
-
- switch (action) {
- case OPCODE_DELETE:
- /* nothing to do */
- break;
- case OPCODE_UPDATE:
- update_node(phandle, scope);
- break;
- case OPCODE_ADD:
- /* nothing to do, just move pointer */
- data++;
- break;
- }
- }
- }
- } while (rc == 1);
-
- kfree(buf);
- return 0;
-}
-
-static int handle_image(struct cxl *adapter, int operation,
- long (*fct)(u64, u64, u64, u64 *),
- struct cxl_adapter_image *ai)
-{
- size_t mod, s_copy, len_chunk = 0;
- struct ai_header *header = NULL;
- unsigned int entries = 0, i;
- void *dest, *from;
- int rc = 0, need_header;
-
- /* base adapter image header */
- need_header = (ai->flags & CXL_AI_NEED_HEADER);
- if (need_header) {
- header = kzalloc(sizeof(struct ai_header), GFP_KERNEL);
- if (!header)
- return -ENOMEM;
- header->version = cpu_to_be16(1);
- header->vendor = cpu_to_be16(adapter->guest->vendor);
- header->device = cpu_to_be16(adapter->guest->device);
- header->subsystem_vendor = cpu_to_be16(adapter->guest->subsystem_vendor);
- header->subsystem = cpu_to_be16(adapter->guest->subsystem);
- header->image_offset = cpu_to_be64(CXL_AI_HEADER_SIZE);
- header->image_length = cpu_to_be64(ai->len_image);
- }
-
- /* number of entries in the list */
- len_chunk = ai->len_data;
- if (need_header)
- len_chunk += CXL_AI_HEADER_SIZE;
-
- entries = len_chunk / CXL_AI_BUFFER_SIZE;
- mod = len_chunk % CXL_AI_BUFFER_SIZE;
- if (mod)
- entries++;
-
- if (entries > CXL_AI_MAX_ENTRIES) {
- rc = -EINVAL;
- goto err;
- }
-
- /* < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes -->
- * chunk 0 ----------------------------------------------------
- * | header | data |
- * ----------------------------------------------------
- * chunk 1 ----------------------------------------------------
- * | data |
- * ----------------------------------------------------
- * ....
- * chunk n ----------------------------------------------------
- * | data |
- * ----------------------------------------------------
- */
- from = (void *) ai->data;
- for (i = 0; i < entries; i++) {
- dest = buffer[i];
- s_copy = CXL_AI_BUFFER_SIZE;
-
- if ((need_header) && (i == 0)) {
- /* add adapter image header */
- memcpy(buffer[i], header, sizeof(struct ai_header));
- s_copy = CXL_AI_BUFFER_SIZE - CXL_AI_HEADER_SIZE;
- dest += CXL_AI_HEADER_SIZE; /* image offset */
- }
- if ((i == (entries - 1)) && mod)
- s_copy = mod;
-
- /* copy data */
- if (copy_from_user(dest, from, s_copy))
- goto err;
-
- /* fill in the list */
- le[i].phys_addr = cpu_to_be64(virt_to_phys(buffer[i]));
- le[i].len = cpu_to_be64(CXL_AI_BUFFER_SIZE);
- if ((i == (entries - 1)) && mod)
- le[i].len = cpu_to_be64(mod);
- from += s_copy;
- }
- pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n",
- __func__, operation, need_header, entries, continue_token);
-
- /*
- * download/validate the adapter image to the coherent
- * platform facility
- */
- rc = fct(adapter->guest->handle, virt_to_phys(le), entries,
- &continue_token);
- if (rc == 0) /* success of download/validation operation */
- continue_token = 0;
-
-err:
- kfree(header);
-
- return rc;
-}
-
-static int transfer_image(struct cxl *adapter, int operation,
- struct cxl_adapter_image *ai)
-{
- int rc = 0;
- int afu;
-
- switch (operation) {
- case DOWNLOAD_IMAGE:
- rc = handle_image(adapter, operation,
- &cxl_h_download_adapter_image, ai);
- if (rc < 0) {
- pr_devel("resetting adapter\n");
- cxl_h_reset_adapter(adapter->guest->handle);
- }
- return rc;
-
- case VALIDATE_IMAGE:
- rc = handle_image(adapter, operation,
- &cxl_h_validate_adapter_image, ai);
- if (rc < 0) {
- pr_devel("resetting adapter\n");
- cxl_h_reset_adapter(adapter->guest->handle);
- return rc;
- }
- if (rc == 0) {
- pr_devel("remove current afu\n");
- for (afu = 0; afu < adapter->slices; afu++)
- cxl_guest_remove_afu(adapter->afu[afu]);
-
- pr_devel("resetting adapter\n");
- cxl_h_reset_adapter(adapter->guest->handle);
-
- /* The entire image has now been
- * downloaded and the validation has
- * been successfully performed.
- * After that, the partition should call
- * ibm,update-nodes and
- * ibm,update-properties to receive the
- * current configuration
- */
- rc = update_devicetree(adapter, DEVICE_SCOPE);
- transfer = 1;
- }
- return rc;
- }
-
- return -EINVAL;
-}
-
-static long ioctl_transfer_image(struct cxl *adapter, int operation,
- struct cxl_adapter_image __user *uai)
-{
- struct cxl_adapter_image ai;
-
- pr_devel("%s\n", __func__);
-
- if (copy_from_user(&ai, uai, sizeof(struct cxl_adapter_image)))
- return -EFAULT;
-
- /*
- * Make sure reserved fields and bits are set to 0
- */
- if (ai.reserved1 || ai.reserved2 || ai.reserved3 || ai.reserved4 ||
- (ai.flags & ~CXL_AI_ALL))
- return -EINVAL;
-
- return transfer_image(adapter, operation, &ai);
-}
-
-static int device_open(struct inode *inode, struct file *file)
-{
- int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev);
- struct cxl *adapter;
- int rc = 0, i;
-
- pr_devel("in %s\n", __func__);
-
- BUG_ON(sizeof(struct ai_header) != CXL_AI_HEADER_SIZE);
-
- /* Allows one process to open the device by using a semaphore */
- if (down_interruptible(&sem) != 0)
- return -EPERM;
-
- if (!(adapter = get_cxl_adapter(adapter_num))) {
- rc = -ENODEV;
- goto err_unlock;
- }
-
- file->private_data = adapter;
- continue_token = 0;
- transfer = 0;
-
- for (i = 0; i < CXL_AI_MAX_ENTRIES; i++)
- buffer[i] = NULL;
-
- /* aligned buffer containing list entries which describes up to
- * 1 megabyte of data (256 entries of 4096 bytes each)
- * Logical real address of buffer 0 - Buffer 0 length in bytes
- * Logical real address of buffer 1 - Buffer 1 length in bytes
- * Logical real address of buffer 2 - Buffer 2 length in bytes
- * ....
- * ....
- * Logical real address of buffer N - Buffer N length in bytes
- */
- le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
- if (!le) {
- rc = -ENOMEM;
- goto err;
- }
-
- for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
- buffer[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
- if (!buffer[i]) {
- rc = -ENOMEM;
- goto err1;
- }
- }
-
- return 0;
-
-err1:
- for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
- if (buffer[i])
- free_page((unsigned long) buffer[i]);
- }
-
- if (le)
- free_page((unsigned long) le);
-err:
- put_device(&adapter->dev);
-err_unlock:
- up(&sem);
-
- return rc;
-}
-
-static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct cxl *adapter = file->private_data;
-
- pr_devel("in %s\n", __func__);
-
- if (cmd == CXL_IOCTL_DOWNLOAD_IMAGE)
- return ioctl_transfer_image(adapter,
- DOWNLOAD_IMAGE,
- (struct cxl_adapter_image __user *)arg);
- else if (cmd == CXL_IOCTL_VALIDATE_IMAGE)
- return ioctl_transfer_image(adapter,
- VALIDATE_IMAGE,
- (struct cxl_adapter_image __user *)arg);
- else
- return -EINVAL;
-}
-
-static int device_close(struct inode *inode, struct file *file)
-{
- struct cxl *adapter = file->private_data;
- int i;
-
- pr_devel("in %s\n", __func__);
-
- for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) {
- if (buffer[i])
- free_page((unsigned long) buffer[i]);
- }
-
- if (le)
- free_page((unsigned long) le);
-
- up(&sem);
- put_device(&adapter->dev);
- continue_token = 0;
-
- /* reload the module */
- if (transfer)
- cxl_guest_reload_module(adapter);
- else {
- pr_devel("resetting adapter\n");
- cxl_h_reset_adapter(adapter->guest->handle);
- }
-
- transfer = 0;
- return 0;
-}
-
-static const struct file_operations fops = {
- .owner = THIS_MODULE,
- .open = device_open,
- .unlocked_ioctl = device_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
- .release = device_close,
-};
-
-void cxl_guest_remove_chardev(struct cxl *adapter)
-{
- cdev_del(&adapter->guest->cdev);
-}
-
-int cxl_guest_add_chardev(struct cxl *adapter)
-{
- dev_t devt;
- int rc;
-
- devt = MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter));
- cdev_init(&adapter->guest->cdev, &fops);
- if ((rc = cdev_add(&adapter->guest->cdev, devt, 1))) {
- dev_err(&adapter->dev,
- "Unable to add chardev on adapter (card%i): %i\n",
- adapter->adapter_num, rc);
- goto err;
- }
- adapter->dev.devt = devt;
- sema_init(&sem, 1);
-err:
- return rc;
-}
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
deleted file mode 100644
index fb95a2d5cef4..000000000000
--- a/drivers/misc/cxl/guest.c
+++ /dev/null
@@ -1,1208 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2015 IBM Corp.
- */
-
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/irqdomain.h>
-#include <linux/platform_device.h>
-
-#include "cxl.h"
-#include "hcalls.h"
-#include "trace.h"
-
-#define CXL_ERROR_DETECTED_EVENT 1
-#define CXL_SLOT_RESET_EVENT 2
-#define CXL_RESUME_EVENT 3
-
-static void pci_error_handlers(struct cxl_afu *afu,
- int bus_error_event,
- pci_channel_state_t state)
-{
- struct pci_dev *afu_dev;
- struct pci_driver *afu_drv;
- const struct pci_error_handlers *err_handler;
-
- if (afu->phb == NULL)
- return;
-
- list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- afu_drv = to_pci_driver(afu_dev->dev.driver);
- if (!afu_drv)
- continue;
-
- err_handler = afu_drv->err_handler;
- switch (bus_error_event) {
- case CXL_ERROR_DETECTED_EVENT:
- afu_dev->error_state = state;
-
- if (err_handler &&
- err_handler->error_detected)
- err_handler->error_detected(afu_dev, state);
- break;
- case CXL_SLOT_RESET_EVENT:
- afu_dev->error_state = state;
-
- if (err_handler &&
- err_handler->slot_reset)
- err_handler->slot_reset(afu_dev);
- break;
- case CXL_RESUME_EVENT:
- if (err_handler &&
- err_handler->resume)
- err_handler->resume(afu_dev);
- break;
- }
- }
-}
-
-static irqreturn_t guest_handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
- u64 errstat)
-{
- pr_devel("in %s\n", __func__);
- dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%.16llx\n", errstat);
-
- return cxl_ops->ack_irq(ctx, 0, errstat);
-}
-
-static ssize_t guest_collect_vpd(struct cxl *adapter, struct cxl_afu *afu,
- void *buf, size_t len)
-{
- unsigned int entries, mod;
- unsigned long **vpd_buf = NULL;
- struct sg_list *le;
- int rc = 0, i, tocopy;
- u64 out = 0;
-
- if (buf == NULL)
- return -EINVAL;
-
- /* number of entries in the list */
- entries = len / SG_BUFFER_SIZE;
- mod = len % SG_BUFFER_SIZE;
- if (mod)
- entries++;
-
- if (entries > SG_MAX_ENTRIES) {
- entries = SG_MAX_ENTRIES;
- len = SG_MAX_ENTRIES * SG_BUFFER_SIZE;
- mod = 0;
- }
-
- vpd_buf = kcalloc(entries, sizeof(unsigned long *), GFP_KERNEL);
- if (!vpd_buf)
- return -ENOMEM;
-
- le = (struct sg_list *)get_zeroed_page(GFP_KERNEL);
- if (!le) {
- rc = -ENOMEM;
- goto err1;
- }
-
- for (i = 0; i < entries; i++) {
- vpd_buf[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL);
- if (!vpd_buf[i]) {
- rc = -ENOMEM;
- goto err2;
- }
- le[i].phys_addr = cpu_to_be64(virt_to_phys(vpd_buf[i]));
- le[i].len = cpu_to_be64(SG_BUFFER_SIZE);
- if ((i == (entries - 1)) && mod)
- le[i].len = cpu_to_be64(mod);
- }
-
- if (adapter)
- rc = cxl_h_collect_vpd_adapter(adapter->guest->handle,
- virt_to_phys(le), entries, &out);
- else
- rc = cxl_h_collect_vpd(afu->guest->handle, 0,
- virt_to_phys(le), entries, &out);
- pr_devel("length of available (entries: %i), vpd: %#llx\n",
- entries, out);
-
- if (!rc) {
- /*
- * hcall returns in 'out' the size of available VPDs.
- * It fills the buffer with as much data as possible.
- */
- if (out < len)
- len = out;
- rc = len;
- if (out) {
- for (i = 0; i < entries; i++) {
- if (len < SG_BUFFER_SIZE)
- tocopy = len;
- else
- tocopy = SG_BUFFER_SIZE;
- memcpy(buf, vpd_buf[i], tocopy);
- buf += tocopy;
- len -= tocopy;
- }
- }
- }
-err2:
- for (i = 0; i < entries; i++) {
- if (vpd_buf[i])
- free_page((unsigned long) vpd_buf[i]);
- }
- free_page((unsigned long) le);
-err1:
- kfree(vpd_buf);
- return rc;
-}
-
-static int guest_get_irq_info(struct cxl_context *ctx, struct cxl_irq_info *info)
-{
- return cxl_h_collect_int_info(ctx->afu->guest->handle, ctx->process_token, info);
-}
-
-static irqreturn_t guest_psl_irq(int irq, void *data)
-{
- struct cxl_context *ctx = data;
- struct cxl_irq_info irq_info;
- int rc;
-
- pr_devel("%d: received PSL interrupt %i\n", ctx->pe, irq);
- rc = guest_get_irq_info(ctx, &irq_info);
- if (rc) {
- WARN(1, "Unable to get IRQ info: %i\n", rc);
- return IRQ_HANDLED;
- }
-
- rc = cxl_irq_psl8(irq, ctx, &irq_info);
- return rc;
-}
-
-static int afu_read_error_state(struct cxl_afu *afu, int *state_out)
-{
- u64 state;
- int rc = 0;
-
- if (!afu)
- return -EIO;
-
- rc = cxl_h_read_error_state(afu->guest->handle, &state);
- if (!rc) {
- WARN_ON(state != H_STATE_NORMAL &&
- state != H_STATE_DISABLE &&
- state != H_STATE_TEMP_UNAVAILABLE &&
- state != H_STATE_PERM_UNAVAILABLE);
- *state_out = state & 0xffffffff;
- }
- return rc;
-}
-
-static irqreturn_t guest_slice_irq_err(int irq, void *data)
-{
- struct cxl_afu *afu = data;
- int rc;
- u64 serr, afu_error, dsisr;
-
- rc = cxl_h_get_fn_error_interrupt(afu->guest->handle, &serr);
- if (rc) {
- dev_crit(&afu->dev, "Couldn't read PSL_SERR_An: %d\n", rc);
- return IRQ_HANDLED;
- }
- afu_error = cxl_p2n_read(afu, CXL_AFU_ERR_An);
- dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- cxl_afu_decode_psl_serr(afu, serr);
- dev_crit(&afu->dev, "AFU_ERR_An: 0x%.16llx\n", afu_error);
- dev_crit(&afu->dev, "PSL_DSISR_An: 0x%.16llx\n", dsisr);
-
- rc = cxl_h_ack_fn_error_interrupt(afu->guest->handle, serr);
- if (rc)
- dev_crit(&afu->dev, "Couldn't ack slice error interrupt: %d\n",
- rc);
-
- return IRQ_HANDLED;
-}
-
-
-static int irq_alloc_range(struct cxl *adapter, int len, int *irq)
-{
- int i, n;
- struct irq_avail *cur;
-
- for (i = 0; i < adapter->guest->irq_nranges; i++) {
- cur = &adapter->guest->irq_avail[i];
- n = bitmap_find_next_zero_area(cur->bitmap, cur->range,
- 0, len, 0);
- if (n < cur->range) {
- bitmap_set(cur->bitmap, n, len);
- *irq = cur->offset + n;
- pr_devel("guest: allocate IRQs %#x->%#x\n",
- *irq, *irq + len - 1);
-
- return 0;
- }
- }
- return -ENOSPC;
-}
-
-static int irq_free_range(struct cxl *adapter, int irq, int len)
-{
- int i, n;
- struct irq_avail *cur;
-
- if (len == 0)
- return -ENOENT;
-
- for (i = 0; i < adapter->guest->irq_nranges; i++) {
- cur = &adapter->guest->irq_avail[i];
- if (irq >= cur->offset &&
- (irq + len) <= (cur->offset + cur->range)) {
- n = irq - cur->offset;
- bitmap_clear(cur->bitmap, n, len);
- pr_devel("guest: release IRQs %#x->%#x\n",
- irq, irq + len - 1);
- return 0;
- }
- }
- return -ENOENT;
-}
-
-static int guest_reset(struct cxl *adapter)
-{
- struct cxl_afu *afu = NULL;
- int i, rc;
-
- pr_devel("Adapter reset request\n");
- spin_lock(&adapter->afu_list_lock);
- for (i = 0; i < adapter->slices; i++) {
- if ((afu = adapter->afu[i])) {
- pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
- pci_channel_io_frozen);
- cxl_context_detach_all(afu);
- }
- }
-
- rc = cxl_h_reset_adapter(adapter->guest->handle);
- for (i = 0; i < adapter->slices; i++) {
- if (!rc && (afu = adapter->afu[i])) {
- pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
- pci_channel_io_normal);
- pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
- }
- }
- spin_unlock(&adapter->afu_list_lock);
- return rc;
-}
-
-static int guest_alloc_one_irq(struct cxl *adapter)
-{
- int irq;
-
- spin_lock(&adapter->guest->irq_alloc_lock);
- if (irq_alloc_range(adapter, 1, &irq))
- irq = -ENOSPC;
- spin_unlock(&adapter->guest->irq_alloc_lock);
- return irq;
-}
-
-static void guest_release_one_irq(struct cxl *adapter, int irq)
-{
- spin_lock(&adapter->guest->irq_alloc_lock);
- irq_free_range(adapter, irq, 1);
- spin_unlock(&adapter->guest->irq_alloc_lock);
-}
-
-static int guest_alloc_irq_ranges(struct cxl_irq_ranges *irqs,
- struct cxl *adapter, unsigned int num)
-{
- int i, try, irq;
-
- memset(irqs, 0, sizeof(struct cxl_irq_ranges));
-
- spin_lock(&adapter->guest->irq_alloc_lock);
- for (i = 0; i < CXL_IRQ_RANGES && num; i++) {
- try = num;
- while (try) {
- if (irq_alloc_range(adapter, try, &irq) == 0)
- break;
- try /= 2;
- }
- if (!try)
- goto error;
- irqs->offset[i] = irq;
- irqs->range[i] = try;
- num -= try;
- }
- if (num)
- goto error;
- spin_unlock(&adapter->guest->irq_alloc_lock);
- return 0;
-
-error:
- for (i = 0; i < CXL_IRQ_RANGES; i++)
- irq_free_range(adapter, irqs->offset[i], irqs->range[i]);
- spin_unlock(&adapter->guest->irq_alloc_lock);
- return -ENOSPC;
-}
-
-static void guest_release_irq_ranges(struct cxl_irq_ranges *irqs,
- struct cxl *adapter)
-{
- int i;
-
- spin_lock(&adapter->guest->irq_alloc_lock);
- for (i = 0; i < CXL_IRQ_RANGES; i++)
- irq_free_range(adapter, irqs->offset[i], irqs->range[i]);
- spin_unlock(&adapter->guest->irq_alloc_lock);
-}
-
-static int guest_register_serr_irq(struct cxl_afu *afu)
-{
- afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
- dev_name(&afu->dev));
- if (!afu->err_irq_name)
- return -ENOMEM;
-
- if (!(afu->serr_virq = cxl_map_irq(afu->adapter, afu->serr_hwirq,
- guest_slice_irq_err, afu, afu->err_irq_name))) {
- kfree(afu->err_irq_name);
- afu->err_irq_name = NULL;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void guest_release_serr_irq(struct cxl_afu *afu)
-{
- cxl_unmap_irq(afu->serr_virq, afu);
- cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
- kfree(afu->err_irq_name);
-}
-
-static int guest_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
-{
- return cxl_h_control_faults(ctx->afu->guest->handle, ctx->process_token,
- tfc >> 32, (psl_reset_mask != 0));
-}
-
-static void disable_afu_irqs(struct cxl_context *ctx)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
- int r, i;
-
- pr_devel("Disabling AFU(%d) interrupts\n", ctx->afu->slice);
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- hwirq = ctx->irqs.offset[r];
- for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
- virq = irq_find_mapping(NULL, hwirq);
- disable_irq(virq);
- }
- }
-}
-
-static void enable_afu_irqs(struct cxl_context *ctx)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
- int r, i;
-
- pr_devel("Enabling AFU(%d) interrupts\n", ctx->afu->slice);
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- hwirq = ctx->irqs.offset[r];
- for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
- virq = irq_find_mapping(NULL, hwirq);
- enable_irq(virq);
- }
- }
-}
-
-static int _guest_afu_cr_readXX(int sz, struct cxl_afu *afu, int cr_idx,
- u64 offset, u64 *val)
-{
- unsigned long cr;
- char c;
- int rc = 0;
-
- if (afu->crs_len < sz)
- return -ENOENT;
-
- if (unlikely(offset >= afu->crs_len))
- return -ERANGE;
-
- cr = get_zeroed_page(GFP_KERNEL);
- if (!cr)
- return -ENOMEM;
-
- rc = cxl_h_get_config(afu->guest->handle, cr_idx, offset,
- virt_to_phys((void *)cr), sz);
- if (rc)
- goto err;
-
- switch (sz) {
- case 1:
- c = *((char *) cr);
- *val = c;
- break;
- case 2:
- *val = in_le16((u16 *)cr);
- break;
- case 4:
- *val = in_le32((unsigned *)cr);
- break;
- case 8:
- *val = in_le64((u64 *)cr);
- break;
- default:
- WARN_ON(1);
- }
-err:
- free_page(cr);
- return rc;
-}
-
-static int guest_afu_cr_read32(struct cxl_afu *afu, int cr_idx, u64 offset,
- u32 *out)
-{
- int rc;
- u64 val;
-
- rc = _guest_afu_cr_readXX(4, afu, cr_idx, offset, &val);
- if (!rc)
- *out = (u32) val;
- return rc;
-}
-
-static int guest_afu_cr_read16(struct cxl_afu *afu, int cr_idx, u64 offset,
- u16 *out)
-{
- int rc;
- u64 val;
-
- rc = _guest_afu_cr_readXX(2, afu, cr_idx, offset, &val);
- if (!rc)
- *out = (u16) val;
- return rc;
-}
-
-static int guest_afu_cr_read8(struct cxl_afu *afu, int cr_idx, u64 offset,
- u8 *out)
-{
- int rc;
- u64 val;
-
- rc = _guest_afu_cr_readXX(1, afu, cr_idx, offset, &val);
- if (!rc)
- *out = (u8) val;
- return rc;
-}
-
-static int guest_afu_cr_read64(struct cxl_afu *afu, int cr_idx, u64 offset,
- u64 *out)
-{
- return _guest_afu_cr_readXX(8, afu, cr_idx, offset, out);
-}
-
-static int guest_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
-{
- /* config record is not writable from guest */
- return -EPERM;
-}
-
-static int guest_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
-{
- /* config record is not writable from guest */
- return -EPERM;
-}
-
-static int guest_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
-{
- /* config record is not writable from guest */
- return -EPERM;
-}
-
-static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
-{
- struct cxl_process_element_hcall *elem;
- struct cxl *adapter = ctx->afu->adapter;
- const struct cred *cred;
- u32 pid, idx;
- int rc, r, i;
- u64 mmio_addr, mmio_size;
- __be64 flags = 0;
-
- /* Must be 8 byte aligned and cannot cross a 4096 byte boundary */
- if (!(elem = (struct cxl_process_element_hcall *)
- get_zeroed_page(GFP_KERNEL)))
- return -ENOMEM;
-
- elem->version = cpu_to_be64(CXL_PROCESS_ELEMENT_VERSION);
- if (ctx->kernel) {
- pid = 0;
- flags |= CXL_PE_TRANSLATION_ENABLED;
- flags |= CXL_PE_PRIVILEGED_PROCESS;
- if (mfmsr() & MSR_SF)
- flags |= CXL_PE_64_BIT;
- } else {
- pid = current->pid;
- flags |= CXL_PE_PROBLEM_STATE;
- flags |= CXL_PE_TRANSLATION_ENABLED;
- if (!test_tsk_thread_flag(current, TIF_32BIT))
- flags |= CXL_PE_64_BIT;
- cred = get_current_cred();
- if (uid_eq(cred->euid, GLOBAL_ROOT_UID))
- flags |= CXL_PE_PRIVILEGED_PROCESS;
- put_cred(cred);
- }
- elem->flags = cpu_to_be64(flags);
- elem->common.tid = cpu_to_be32(0); /* Unused */
- elem->common.pid = cpu_to_be32(pid);
- elem->common.csrp = cpu_to_be64(0); /* disable */
- elem->common.u.psl8.aurp0 = cpu_to_be64(0); /* disable */
- elem->common.u.psl8.aurp1 = cpu_to_be64(0); /* disable */
-
- cxl_prefault(ctx, wed);
-
- elem->common.u.psl8.sstp0 = cpu_to_be64(ctx->sstp0);
- elem->common.u.psl8.sstp1 = cpu_to_be64(ctx->sstp1);
-
- /*
- * Ensure we have at least one interrupt allocated to take faults for
- * kernel contexts that may not have allocated any AFU IRQs at all:
- */
- if (ctx->irqs.range[0] == 0) {
- rc = afu_register_irqs(ctx, 0);
- if (rc)
- goto out_free;
- }
-
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- for (i = 0; i < ctx->irqs.range[r]; i++) {
- if (r == 0 && i == 0) {
- elem->pslVirtualIsn = cpu_to_be32(ctx->irqs.offset[0]);
- } else {
- idx = ctx->irqs.offset[r] + i - adapter->guest->irq_base_offset;
- elem->applicationVirtualIsnBitmap[idx / 8] |= 0x80 >> (idx % 8);
- }
- }
- }
- elem->common.amr = cpu_to_be64(amr);
- elem->common.wed = cpu_to_be64(wed);
-
- disable_afu_irqs(ctx);
-
- rc = cxl_h_attach_process(ctx->afu->guest->handle, elem,
- &ctx->process_token, &mmio_addr, &mmio_size);
- if (rc == H_SUCCESS) {
- if (ctx->master || !ctx->afu->pp_psa) {
- ctx->psn_phys = ctx->afu->psn_phys;
- ctx->psn_size = ctx->afu->adapter->ps_size;
- } else {
- ctx->psn_phys = mmio_addr;
- ctx->psn_size = mmio_size;
- }
- if (ctx->afu->pp_psa && mmio_size &&
- ctx->afu->pp_size == 0) {
- /*
- * There's no property in the device tree to read the
- * pp_size. We only find out at the 1st attach.
- * Compared to bare-metal, it is too late and we
- * should really lock here. However, on powerVM,
- * pp_size is really only used to display in /sys.
- * Being discussed with pHyp for their next release.
- */
- ctx->afu->pp_size = mmio_size;
- }
- /* from PAPR: process element is bytes 4-7 of process token */
- ctx->external_pe = ctx->process_token & 0xFFFFFFFF;
- pr_devel("CXL pe=%i is known as %i for pHyp, mmio_size=%#llx",
- ctx->pe, ctx->external_pe, ctx->psn_size);
- ctx->pe_inserted = true;
- enable_afu_irqs(ctx);
- }
-
-out_free:
- free_page((u64)elem);
- return rc;
-}
-
-static int guest_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
-{
- pr_devel("in %s\n", __func__);
-
- ctx->kernel = kernel;
- if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
- return attach_afu_directed(ctx, wed, amr);
-
- /* dedicated mode not supported on FW840 */
-
- return -EINVAL;
-}
-
-static int detach_afu_directed(struct cxl_context *ctx)
-{
- if (!ctx->pe_inserted)
- return 0;
- if (cxl_h_detach_process(ctx->afu->guest->handle, ctx->process_token))
- return -1;
- return 0;
-}
-
-static int guest_detach_process(struct cxl_context *ctx)
-{
- pr_devel("in %s\n", __func__);
- trace_cxl_detach(ctx);
-
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
- return -EIO;
-
- if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
- return detach_afu_directed(ctx);
-
- return -EINVAL;
-}
-
-static void guest_release_afu(struct device *dev)
-{
- struct cxl_afu *afu = to_cxl_afu(dev);
-
- pr_devel("%s\n", __func__);
-
- idr_destroy(&afu->contexts_idr);
-
- kfree(afu->guest);
- kfree(afu);
-}
-
-ssize_t cxl_guest_read_afu_vpd(struct cxl_afu *afu, void *buf, size_t len)
-{
- return guest_collect_vpd(NULL, afu, buf, len);
-}
-
-#define ERR_BUFF_MAX_COPY_SIZE PAGE_SIZE
-static ssize_t guest_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
- loff_t off, size_t count)
-{
- void *tbuf = NULL;
- int rc = 0;
-
- tbuf = (void *) get_zeroed_page(GFP_KERNEL);
- if (!tbuf)
- return -ENOMEM;
-
- rc = cxl_h_get_afu_err(afu->guest->handle,
- off & 0x7,
- virt_to_phys(tbuf),
- count);
- if (rc)
- goto err;
-
- if (count > ERR_BUFF_MAX_COPY_SIZE)
- count = ERR_BUFF_MAX_COPY_SIZE - (off & 0x7);
- memcpy(buf, tbuf, count);
-err:
- free_page((u64)tbuf);
-
- return rc;
-}
-
-static int guest_afu_check_and_enable(struct cxl_afu *afu)
-{
- return 0;
-}
-
-static bool guest_support_attributes(const char *attr_name,
- enum cxl_attrs type)
-{
- switch (type) {
- case CXL_ADAPTER_ATTRS:
- if ((strcmp(attr_name, "base_image") == 0) ||
- (strcmp(attr_name, "load_image_on_perst") == 0) ||
- (strcmp(attr_name, "perst_reloads_same_image") == 0) ||
- (strcmp(attr_name, "image_loaded") == 0))
- return false;
- break;
- case CXL_AFU_MASTER_ATTRS:
- if ((strcmp(attr_name, "pp_mmio_off") == 0))
- return false;
- break;
- case CXL_AFU_ATTRS:
- break;
- default:
- break;
- }
-
- return true;
-}
-
-static int activate_afu_directed(struct cxl_afu *afu)
-{
- int rc;
-
- dev_info(&afu->dev, "Activating AFU(%d) directed mode\n", afu->slice);
-
- afu->current_mode = CXL_MODE_DIRECTED;
-
- afu->num_procs = afu->max_procs_virtualised;
-
- if ((rc = cxl_chardev_m_afu_add(afu)))
- return rc;
-
- if ((rc = cxl_sysfs_afu_m_add(afu)))
- goto err;
-
- if ((rc = cxl_chardev_s_afu_add(afu)))
- goto err1;
-
- return 0;
-err1:
- cxl_sysfs_afu_m_remove(afu);
-err:
- cxl_chardev_afu_remove(afu);
- return rc;
-}
-
-static int guest_afu_activate_mode(struct cxl_afu *afu, int mode)
-{
- if (!mode)
- return 0;
- if (!(mode & afu->modes_supported))
- return -EINVAL;
-
- if (mode == CXL_MODE_DIRECTED)
- return activate_afu_directed(afu);
-
- if (mode == CXL_MODE_DEDICATED)
- dev_err(&afu->dev, "Dedicated mode not supported\n");
-
- return -EINVAL;
-}
-
-static int deactivate_afu_directed(struct cxl_afu *afu)
-{
- dev_info(&afu->dev, "Deactivating AFU(%d) directed mode\n", afu->slice);
-
- afu->current_mode = 0;
- afu->num_procs = 0;
-
- cxl_sysfs_afu_m_remove(afu);
- cxl_chardev_afu_remove(afu);
-
- cxl_ops->afu_reset(afu);
-
- return 0;
-}
-
-static int guest_afu_deactivate_mode(struct cxl_afu *afu, int mode)
-{
- if (!mode)
- return 0;
- if (!(mode & afu->modes_supported))
- return -EINVAL;
-
- if (mode == CXL_MODE_DIRECTED)
- return deactivate_afu_directed(afu);
- return 0;
-}
-
-static int guest_afu_reset(struct cxl_afu *afu)
-{
- pr_devel("AFU(%d) reset request\n", afu->slice);
- return cxl_h_reset_afu(afu->guest->handle);
-}
-
-static int guest_map_slice_regs(struct cxl_afu *afu)
-{
- if (!(afu->p2n_mmio = ioremap(afu->guest->p2n_phys, afu->guest->p2n_size))) {
- dev_err(&afu->dev, "Error mapping AFU(%d) MMIO regions\n",
- afu->slice);
- return -ENOMEM;
- }
- return 0;
-}
-
-static void guest_unmap_slice_regs(struct cxl_afu *afu)
-{
- if (afu->p2n_mmio)
- iounmap(afu->p2n_mmio);
-}
-
-static int afu_update_state(struct cxl_afu *afu)
-{
- int rc, cur_state;
-
- rc = afu_read_error_state(afu, &cur_state);
- if (rc)
- return rc;
-
- if (afu->guest->previous_state == cur_state)
- return 0;
-
- pr_devel("AFU(%d) update state to %#x\n", afu->slice, cur_state);
-
- switch (cur_state) {
- case H_STATE_NORMAL:
- afu->guest->previous_state = cur_state;
- break;
-
- case H_STATE_DISABLE:
- pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
- pci_channel_io_frozen);
-
- cxl_context_detach_all(afu);
- if ((rc = cxl_ops->afu_reset(afu)))
- pr_devel("reset hcall failed %d\n", rc);
-
- rc = afu_read_error_state(afu, &cur_state);
- if (!rc && cur_state == H_STATE_NORMAL) {
- pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
- pci_channel_io_normal);
- pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
- }
- afu->guest->previous_state = 0;
- break;
-
- case H_STATE_TEMP_UNAVAILABLE:
- afu->guest->previous_state = cur_state;
- break;
-
- case H_STATE_PERM_UNAVAILABLE:
- dev_err(&afu->dev, "AFU is in permanent error state\n");
- pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
- pci_channel_io_perm_failure);
- afu->guest->previous_state = cur_state;
- break;
-
- default:
- pr_err("Unexpected AFU(%d) error state: %#x\n",
- afu->slice, cur_state);
- return -EINVAL;
- }
-
- return rc;
-}
-
-static void afu_handle_errstate(struct work_struct *work)
-{
- struct cxl_afu_guest *afu_guest =
- container_of(to_delayed_work(work), struct cxl_afu_guest, work_err);
-
- if (!afu_update_state(afu_guest->parent) &&
- afu_guest->previous_state == H_STATE_PERM_UNAVAILABLE)
- return;
-
- if (afu_guest->handle_err)
- schedule_delayed_work(&afu_guest->work_err,
- msecs_to_jiffies(3000));
-}
-
-static bool guest_link_ok(struct cxl *cxl, struct cxl_afu *afu)
-{
- int state;
-
- if (afu && (!afu_read_error_state(afu, &state))) {
- if (state == H_STATE_NORMAL)
- return true;
- }
-
- return false;
-}
-
-static int afu_properties_look_ok(struct cxl_afu *afu)
-{
- if (afu->pp_irqs < 0) {
- dev_err(&afu->dev, "Unexpected per-process minimum interrupt value\n");
- return -EINVAL;
- }
-
- if (afu->max_procs_virtualised < 1) {
- dev_err(&afu->dev, "Unexpected max number of processes virtualised value\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_np)
-{
- struct cxl_afu *afu;
- bool free = true;
- int rc;
-
- pr_devel("in %s - AFU(%d)\n", __func__, slice);
- if (!(afu = cxl_alloc_afu(adapter, slice)))
- return -ENOMEM;
-
- if (!(afu->guest = kzalloc(sizeof(struct cxl_afu_guest), GFP_KERNEL))) {
- kfree(afu);
- return -ENOMEM;
- }
-
- if ((rc = dev_set_name(&afu->dev, "afu%i.%i",
- adapter->adapter_num,
- slice)))
- goto err1;
-
- adapter->slices++;
-
- if ((rc = cxl_of_read_afu_handle(afu, afu_np)))
- goto err1;
-
- if ((rc = cxl_ops->afu_reset(afu)))
- goto err1;
-
- if ((rc = cxl_of_read_afu_properties(afu, afu_np)))
- goto err1;
-
- if ((rc = afu_properties_look_ok(afu)))
- goto err1;
-
- if ((rc = guest_map_slice_regs(afu)))
- goto err1;
-
- if ((rc = guest_register_serr_irq(afu)))
- goto err2;
-
- /*
- * After we call this function we must not free the afu directly, even
- * if it returns an error!
- */
- if ((rc = cxl_register_afu(afu)))
- goto err_put_dev;
-
- if ((rc = cxl_sysfs_afu_add(afu)))
- goto err_del_dev;
-
- /*
- * pHyp doesn't expose the programming models supported by the
- * AFU. pHyp currently only supports directed mode. If it adds
- * dedicated mode later, this version of cxl has no way to
- * detect it. So we'll initialize the driver, but the first
- * attach will fail.
- * Being discussed with pHyp to do better (likely new property)
- */
- if (afu->max_procs_virtualised == 1)
- afu->modes_supported = CXL_MODE_DEDICATED;
- else
- afu->modes_supported = CXL_MODE_DIRECTED;
-
- if ((rc = cxl_afu_select_best_mode(afu)))
- goto err_remove_sysfs;
-
- adapter->afu[afu->slice] = afu;
-
- afu->enabled = true;
-
- /*
- * wake up the cpu periodically to check the state
- * of the AFU using "afu" stored in the guest structure.
- */
- afu->guest->parent = afu;
- afu->guest->handle_err = true;
- INIT_DELAYED_WORK(&afu->guest->work_err, afu_handle_errstate);
- schedule_delayed_work(&afu->guest->work_err, msecs_to_jiffies(1000));
-
- if ((rc = cxl_pci_vphb_add(afu)))
- dev_info(&afu->dev, "Can't register vPHB\n");
-
- return 0;
-
-err_remove_sysfs:
- cxl_sysfs_afu_remove(afu);
-err_del_dev:
- device_del(&afu->dev);
-err_put_dev:
- put_device(&afu->dev);
- free = false;
- guest_release_serr_irq(afu);
-err2:
- guest_unmap_slice_regs(afu);
-err1:
- if (free) {
- kfree(afu->guest);
- kfree(afu);
- }
- return rc;
-}
-
-void cxl_guest_remove_afu(struct cxl_afu *afu)
-{
- if (!afu)
- return;
-
- /* flush and stop pending job */
- afu->guest->handle_err = false;
- flush_delayed_work(&afu->guest->work_err);
-
- cxl_pci_vphb_remove(afu);
- cxl_sysfs_afu_remove(afu);
-
- spin_lock(&afu->adapter->afu_list_lock);
- afu->adapter->afu[afu->slice] = NULL;
- spin_unlock(&afu->adapter->afu_list_lock);
-
- cxl_context_detach_all(afu);
- cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
- guest_release_serr_irq(afu);
- guest_unmap_slice_regs(afu);
-
- device_unregister(&afu->dev);
-}
-
-static void free_adapter(struct cxl *adapter)
-{
- struct irq_avail *cur;
- int i;
-
- if (adapter->guest) {
- if (adapter->guest->irq_avail) {
- for (i = 0; i < adapter->guest->irq_nranges; i++) {
- cur = &adapter->guest->irq_avail[i];
- bitmap_free(cur->bitmap);
- }
- kfree(adapter->guest->irq_avail);
- }
- kfree(adapter->guest->status);
- kfree(adapter->guest);
- }
- cxl_remove_adapter_nr(adapter);
- kfree(adapter);
-}
-
-static int properties_look_ok(struct cxl *adapter)
-{
- /* The absence of this property means that the operational
- * status is unknown or okay
- */
- if (strlen(adapter->guest->status) &&
- strcmp(adapter->guest->status, "okay")) {
- pr_err("ABORTING:Bad operational status of the device\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-ssize_t cxl_guest_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len)
-{
- return guest_collect_vpd(adapter, NULL, buf, len);
-}
-
-void cxl_guest_remove_adapter(struct cxl *adapter)
-{
- pr_devel("in %s\n", __func__);
-
- cxl_sysfs_adapter_remove(adapter);
-
- cxl_guest_remove_chardev(adapter);
- device_unregister(&adapter->dev);
-}
-
-static void release_adapter(struct device *dev)
-{
- free_adapter(to_cxl_adapter(dev));
-}
-
-struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_device *pdev)
-{
- struct cxl *adapter;
- bool free = true;
- int rc;
-
- if (!(adapter = cxl_alloc_adapter()))
- return ERR_PTR(-ENOMEM);
-
- if (!(adapter->guest = kzalloc(sizeof(struct cxl_guest), GFP_KERNEL))) {
- free_adapter(adapter);
- return ERR_PTR(-ENOMEM);
- }
-
- adapter->slices = 0;
- adapter->guest->pdev = pdev;
- adapter->dev.parent = &pdev->dev;
- adapter->dev.release = release_adapter;
- dev_set_drvdata(&pdev->dev, adapter);
-
- /*
- * Hypervisor controls PSL timebase initialization (p1 register).
- * On FW840, PSL is initialized.
- */
- adapter->psl_timebase_synced = true;
-
- if ((rc = cxl_of_read_adapter_handle(adapter, np)))
- goto err1;
-
- if ((rc = cxl_of_read_adapter_properties(adapter, np)))
- goto err1;
-
- if ((rc = properties_look_ok(adapter)))
- goto err1;
-
- if ((rc = cxl_guest_add_chardev(adapter)))
- goto err1;
-
- /*
- * After we call this function we must not free the adapter directly,
- * even if it returns an error!
- */
- if ((rc = cxl_register_adapter(adapter)))
- goto err_put_dev;
-
- if ((rc = cxl_sysfs_adapter_add(adapter)))
- goto err_del_dev;
-
- /* release the context lock as the adapter is configured */
- cxl_adapter_context_unlock(adapter);
-
- return adapter;
-
-err_del_dev:
- device_del(&adapter->dev);
-err_put_dev:
- put_device(&adapter->dev);
- free = false;
- cxl_guest_remove_chardev(adapter);
-err1:
- if (free)
- free_adapter(adapter);
- return ERR_PTR(rc);
-}
-
-void cxl_guest_reload_module(struct cxl *adapter)
-{
- struct platform_device *pdev;
-
- pdev = adapter->guest->pdev;
- cxl_guest_remove_adapter(adapter);
-
- cxl_of_probe(pdev);
-}
-
-const struct cxl_backend_ops cxl_guest_ops = {
- .module = THIS_MODULE,
- .adapter_reset = guest_reset,
- .alloc_one_irq = guest_alloc_one_irq,
- .release_one_irq = guest_release_one_irq,
- .alloc_irq_ranges = guest_alloc_irq_ranges,
- .release_irq_ranges = guest_release_irq_ranges,
- .setup_irq = NULL,
- .handle_psl_slice_error = guest_handle_psl_slice_error,
- .psl_interrupt = guest_psl_irq,
- .ack_irq = guest_ack_irq,
- .attach_process = guest_attach_process,
- .detach_process = guest_detach_process,
- .update_ivtes = NULL,
- .support_attributes = guest_support_attributes,
- .link_ok = guest_link_ok,
- .release_afu = guest_release_afu,
- .afu_read_err_buffer = guest_afu_read_err_buffer,
- .afu_check_and_enable = guest_afu_check_and_enable,
- .afu_activate_mode = guest_afu_activate_mode,
- .afu_deactivate_mode = guest_afu_deactivate_mode,
- .afu_reset = guest_afu_reset,
- .afu_cr_read8 = guest_afu_cr_read8,
- .afu_cr_read16 = guest_afu_cr_read16,
- .afu_cr_read32 = guest_afu_cr_read32,
- .afu_cr_read64 = guest_afu_cr_read64,
- .afu_cr_write8 = guest_afu_cr_write8,
- .afu_cr_write16 = guest_afu_cr_write16,
- .afu_cr_write32 = guest_afu_cr_write32,
- .read_adapter_vpd = cxl_guest_read_adapter_vpd,
-};
diff --git a/drivers/misc/cxl/hcalls.c b/drivers/misc/cxl/hcalls.c
deleted file mode 100644
index aba5e20eeb1f..000000000000
--- a/drivers/misc/cxl/hcalls.c
+++ /dev/null
@@ -1,643 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2015 IBM Corp.
- */
-
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <asm/byteorder.h>
-#include "hcalls.h"
-#include "trace.h"
-
-#define CXL_HCALL_TIMEOUT 60000
-#define CXL_HCALL_TIMEOUT_DOWNLOAD 120000
-
-#define H_ATTACH_CA_PROCESS 0x344
-#define H_CONTROL_CA_FUNCTION 0x348
-#define H_DETACH_CA_PROCESS 0x34C
-#define H_COLLECT_CA_INT_INFO 0x350
-#define H_CONTROL_CA_FAULTS 0x354
-#define H_DOWNLOAD_CA_FUNCTION 0x35C
-#define H_DOWNLOAD_CA_FACILITY 0x364
-#define H_CONTROL_CA_FACILITY 0x368
-
-#define H_CONTROL_CA_FUNCTION_RESET 1 /* perform a reset */
-#define H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS 2 /* suspend a process from being executed */
-#define H_CONTROL_CA_FUNCTION_RESUME_PROCESS 3 /* resume a process to be executed */
-#define H_CONTROL_CA_FUNCTION_READ_ERR_STATE 4 /* read the error state */
-#define H_CONTROL_CA_FUNCTION_GET_AFU_ERR 5 /* collect the AFU error buffer */
-#define H_CONTROL_CA_FUNCTION_GET_CONFIG 6 /* collect configuration record */
-#define H_CONTROL_CA_FUNCTION_GET_DOWNLOAD_STATE 7 /* query to return download status */
-#define H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS 8 /* terminate the process before completion */
-#define H_CONTROL_CA_FUNCTION_COLLECT_VPD 9 /* collect VPD */
-#define H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT 11 /* read the function-wide error data based on an interrupt */
-#define H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT 12 /* acknowledge function-wide error data based on an interrupt */
-#define H_CONTROL_CA_FUNCTION_GET_ERROR_LOG 13 /* retrieve the Platform Log ID (PLID) of an error log */
-
-#define H_CONTROL_CA_FAULTS_RESPOND_PSL 1
-#define H_CONTROL_CA_FAULTS_RESPOND_AFU 2
-
-#define H_CONTROL_CA_FACILITY_RESET 1 /* perform a reset */
-#define H_CONTROL_CA_FACILITY_COLLECT_VPD 2 /* collect VPD */
-
-#define H_DOWNLOAD_CA_FACILITY_DOWNLOAD 1 /* download adapter image */
-#define H_DOWNLOAD_CA_FACILITY_VALIDATE 2 /* validate adapter image */
-
-
-#define _CXL_LOOP_HCALL(call, rc, retbuf, fn, ...) \
- { \
- unsigned int delay, total_delay = 0; \
- u64 token = 0; \
- \
- memset(retbuf, 0, sizeof(retbuf)); \
- while (1) { \
- rc = call(fn, retbuf, __VA_ARGS__, token); \
- token = retbuf[0]; \
- if (rc != H_BUSY && !H_IS_LONG_BUSY(rc)) \
- break; \
- \
- if (rc == H_BUSY) \
- delay = 10; \
- else \
- delay = get_longbusy_msecs(rc); \
- \
- total_delay += delay; \
- if (total_delay > CXL_HCALL_TIMEOUT) { \
- WARN(1, "Warning: Giving up waiting for CXL hcall " \
- "%#x after %u msec\n", fn, total_delay); \
- rc = H_BUSY; \
- break; \
- } \
- msleep(delay); \
- } \
- }
-#define CXL_H_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall, __VA_ARGS__)
-#define CXL_H9_WAIT_UNTIL_DONE(...) _CXL_LOOP_HCALL(plpar_hcall9, __VA_ARGS__)
-
-#define _PRINT_MSG(rc, format, ...) \
- { \
- if ((rc != H_SUCCESS) && (rc != H_CONTINUE)) \
- pr_err(format, __VA_ARGS__); \
- else \
- pr_devel(format, __VA_ARGS__); \
- } \
-
-
-static char *afu_op_names[] = {
- "UNKNOWN_OP", /* 0 undefined */
- "RESET", /* 1 */
- "SUSPEND_PROCESS", /* 2 */
- "RESUME_PROCESS", /* 3 */
- "READ_ERR_STATE", /* 4 */
- "GET_AFU_ERR", /* 5 */
- "GET_CONFIG", /* 6 */
- "GET_DOWNLOAD_STATE", /* 7 */
- "TERMINATE_PROCESS", /* 8 */
- "COLLECT_VPD", /* 9 */
- "UNKNOWN_OP", /* 10 undefined */
- "GET_FUNCTION_ERR_INT", /* 11 */
- "ACK_FUNCTION_ERR_INT", /* 12 */
- "GET_ERROR_LOG", /* 13 */
-};
-
-static char *control_adapter_op_names[] = {
- "UNKNOWN_OP", /* 0 undefined */
- "RESET", /* 1 */
- "COLLECT_VPD", /* 2 */
-};
-
-static char *download_op_names[] = {
- "UNKNOWN_OP", /* 0 undefined */
- "DOWNLOAD", /* 1 */
- "VALIDATE", /* 2 */
-};
-
-static char *op_str(unsigned int op, char *name_array[], int array_len)
-{
- if (op >= array_len)
- return "UNKNOWN_OP";
- return name_array[op];
-}
-
-#define OP_STR(op, name_array) op_str(op, name_array, ARRAY_SIZE(name_array))
-
-#define OP_STR_AFU(op) OP_STR(op, afu_op_names)
-#define OP_STR_CONTROL_ADAPTER(op) OP_STR(op, control_adapter_op_names)
-#define OP_STR_DOWNLOAD_ADAPTER(op) OP_STR(op, download_op_names)
-
-
-long cxl_h_attach_process(u64 unit_address,
- struct cxl_process_element_hcall *element,
- u64 *process_token, u64 *mmio_addr, u64 *mmio_size)
-{
- unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
- long rc;
-
- CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_ATTACH_CA_PROCESS, unit_address, virt_to_phys(element));
- _PRINT_MSG(rc, "cxl_h_attach_process(%#.16llx, %#.16lx): %li\n",
- unit_address, virt_to_phys(element), rc);
- trace_cxl_hcall_attach(unit_address, virt_to_phys(element), retbuf[0], retbuf[1], retbuf[2], rc);
-
- pr_devel("token: 0x%.8lx mmio_addr: 0x%lx mmio_size: 0x%lx\nProcess Element Structure:\n",
- retbuf[0], retbuf[1], retbuf[2]);
- cxl_dump_debug_buffer(element, sizeof(*element));
-
- switch (rc) {
- case H_SUCCESS: /* The process info is attached to the coherent platform function */
- *process_token = retbuf[0];
- if (mmio_addr)
- *mmio_addr = retbuf[1];
- if (mmio_size)
- *mmio_size = retbuf[2];
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied. */
- case H_FUNCTION: /* The function is not supported. */
- return -EINVAL;
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
- case H_RESOURCE: /* The coherent platform function does not have enough additional resource to attach the process */
- case H_HARDWARE: /* A hardware event prevented the attach operation */
- case H_STATE: /* The coherent platform function is not in a valid state */
- case H_BUSY:
- return -EBUSY;
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_detach_process - Detach a process element from a coherent
- * platform function.
- */
-long cxl_h_detach_process(u64 unit_address, u64 process_token)
-{
- unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
- long rc;
-
- CXL_H_WAIT_UNTIL_DONE(rc, retbuf, H_DETACH_CA_PROCESS, unit_address, process_token);
- _PRINT_MSG(rc, "cxl_h_detach_process(%#.16llx, 0x%.8llx): %li\n", unit_address, process_token, rc);
- trace_cxl_hcall_detach(unit_address, process_token, rc);
-
- switch (rc) {
- case H_SUCCESS: /* The process was detached from the coherent platform function */
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied. */
- return -EINVAL;
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
- case H_RESOURCE: /* The function has page table mappings for MMIO */
- case H_HARDWARE: /* A hardware event prevented the detach operation */
- case H_STATE: /* The coherent platform function is not in a valid state */
- case H_BUSY:
- return -EBUSY;
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_control_function - This H_CONTROL_CA_FUNCTION hypervisor call allows
- * the partition to manipulate or query
- * certain coherent platform function behaviors.
- */
-static long cxl_h_control_function(u64 unit_address, u64 op,
- u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
-{
- unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
- long rc;
-
- CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FUNCTION, unit_address, op, p1, p2, p3, p4);
- _PRINT_MSG(rc, "cxl_h_control_function(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
- unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
- trace_cxl_hcall_control_function(unit_address, OP_STR_AFU(op), p1, p2, p3, p4, retbuf[0], rc);
-
- switch (rc) {
- case H_SUCCESS: /* The operation is completed for the coherent platform function */
- if ((op == H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT ||
- op == H_CONTROL_CA_FUNCTION_READ_ERR_STATE ||
- op == H_CONTROL_CA_FUNCTION_COLLECT_VPD))
- *out = retbuf[0];
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied. */
- case H_FUNCTION: /* The function is not supported. */
- case H_NOT_FOUND: /* The operation supplied was not valid */
- case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
- case H_SG_LIST: /* An block list entry was invalid */
- return -EINVAL;
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
- case H_RESOURCE: /* The function has page table mappings for MMIO */
- case H_HARDWARE: /* A hardware event prevented the attach operation */
- case H_STATE: /* The coherent platform function is not in a valid state */
- case H_BUSY:
- return -EBUSY;
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_reset_afu - Perform a reset to the coherent platform function.
- */
-long cxl_h_reset_afu(u64 unit_address)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_RESET,
- 0, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_suspend_process - Suspend a process from being executed
- * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
- * process was attached.
- */
-long cxl_h_suspend_process(u64 unit_address, u64 process_token)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_SUSPEND_PROCESS,
- process_token, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_resume_process - Resume a process to be executed
- * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
- * process was attached.
- */
-long cxl_h_resume_process(u64 unit_address, u64 process_token)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_RESUME_PROCESS,
- process_token, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_read_error_state - Checks the error state of the coherent
- * platform function.
- * R4 contains the error state
- */
-long cxl_h_read_error_state(u64 unit_address, u64 *state)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_READ_ERR_STATE,
- 0, 0, 0, 0,
- state);
-}
-
-/*
- * cxl_h_get_afu_err - collect the AFU error buffer
- * Parameter1 = byte offset into error buffer to retrieve, valid values
- * are between 0 and (ibm,error-buffer-size - 1)
- * Parameter2 = 4K aligned real address of error buffer, to be filled in
- * Parameter3 = length of error buffer, valid values are 4K or less
- */
-long cxl_h_get_afu_err(u64 unit_address, u64 offset,
- u64 buf_address, u64 len)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_GET_AFU_ERR,
- offset, buf_address, len, 0,
- NULL);
-}
-
-/*
- * cxl_h_get_config - collect configuration record for the
- * coherent platform function
- * Parameter1 = # of configuration record to retrieve, valid values are
- * between 0 and (ibm,#config-records - 1)
- * Parameter2 = byte offset into configuration record to retrieve,
- * valid values are between 0 and (ibm,config-record-size - 1)
- * Parameter3 = 4K aligned real address of configuration record buffer,
- * to be filled in
- * Parameter4 = length of configuration buffer, valid values are 4K or less
- */
-long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
- u64 buf_address, u64 len)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_GET_CONFIG,
- cr_num, offset, buf_address, len,
- NULL);
-}
-
-/*
- * cxl_h_terminate_process - Terminate the process before completion
- * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
- * process was attached.
- */
-long cxl_h_terminate_process(u64 unit_address, u64 process_token)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_TERMINATE_PROCESS,
- process_token, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
- * Parameter1 = # of VPD record to retrieve, valid values are between 0
- * and (ibm,#config-records - 1).
- * Parameter2 = 4K naturally aligned real buffer containing block
- * list entries
- * Parameter3 = number of block list entries in the block list, valid
- * values are between 0 and 256
- */
-long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
- u64 num, u64 *out)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_COLLECT_VPD,
- record, list_address, num, 0,
- out);
-}
-
-/*
- * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
- */
-long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_GET_FUNCTION_ERR_INT,
- 0, 0, 0, 0, reg);
-}
-
-/*
- * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
- * based on an interrupt
- * Parameter1 = value to write to the function-wide error interrupt register
- */
-long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_ACK_FUNCTION_ERR_INT,
- value, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
- * an error log
- */
-long cxl_h_get_error_log(u64 unit_address, u64 value)
-{
- return cxl_h_control_function(unit_address,
- H_CONTROL_CA_FUNCTION_GET_ERROR_LOG,
- 0, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_collect_int_info - Collect interrupt info about a coherent
- * platform function after an interrupt occurred.
- */
-long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
- struct cxl_irq_info *info)
-{
- long rc;
-
- BUG_ON(sizeof(*info) != sizeof(unsigned long[PLPAR_HCALL9_BUFSIZE]));
-
- rc = plpar_hcall9(H_COLLECT_CA_INT_INFO, (unsigned long *) info,
- unit_address, process_token);
- _PRINT_MSG(rc, "cxl_h_collect_int_info(%#.16llx, 0x%llx): %li\n",
- unit_address, process_token, rc);
- trace_cxl_hcall_collect_int_info(unit_address, process_token, rc);
-
- switch (rc) {
- case H_SUCCESS: /* The interrupt info is returned in return registers. */
- pr_devel("dsisr:%#llx, dar:%#llx, dsr:%#llx, pid_tid:%#llx, afu_err:%#llx, errstat:%#llx\n",
- info->dsisr, info->dar, info->dsr, info->reserved,
- info->afu_err, info->errstat);
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied. */
- return -EINVAL;
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall. */
- case H_HARDWARE: /* A hardware event prevented the collection of the interrupt info.*/
- case H_STATE: /* The coherent platform function is not in a valid state to collect interrupt info. */
- return -EBUSY;
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_control_faults - Control the operation of a coherent platform
- * function after a fault occurs.
- *
- * Parameters
- * control-mask: value to control the faults
- * looks like PSL_TFC_An shifted >> 32
- * reset-mask: mask to control reset of function faults
- * Set reset_mask = 1 to reset PSL errors
- */
-long cxl_h_control_faults(u64 unit_address, u64 process_token,
- u64 control_mask, u64 reset_mask)
-{
- unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
- long rc;
-
- memset(retbuf, 0, sizeof(retbuf));
-
- rc = plpar_hcall(H_CONTROL_CA_FAULTS, retbuf, unit_address,
- H_CONTROL_CA_FAULTS_RESPOND_PSL, process_token,
- control_mask, reset_mask);
- _PRINT_MSG(rc, "cxl_h_control_faults(%#.16llx, 0x%llx, %#llx, %#llx): %li (%#lx)\n",
- unit_address, process_token, control_mask, reset_mask,
- rc, retbuf[0]);
- trace_cxl_hcall_control_faults(unit_address, process_token,
- control_mask, reset_mask, retbuf[0], rc);
-
- switch (rc) {
- case H_SUCCESS: /* Faults were successfully controlled for the function. */
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied. */
- return -EINVAL;
- case H_HARDWARE: /* A hardware event prevented the control of faults. */
- case H_STATE: /* The function was in an invalid state. */
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall; the coherent platform facilities may need to be licensed. */
- return -EBUSY;
- case H_FUNCTION: /* The function is not supported */
- case H_NOT_FOUND: /* The operation supplied was not valid */
- return -EINVAL;
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_control_facility - This H_CONTROL_CA_FACILITY hypervisor call
- * allows the partition to manipulate or query
- * certain coherent platform facility behaviors.
- */
-static long cxl_h_control_facility(u64 unit_address, u64 op,
- u64 p1, u64 p2, u64 p3, u64 p4, u64 *out)
-{
- unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
- long rc;
-
- CXL_H9_WAIT_UNTIL_DONE(rc, retbuf, H_CONTROL_CA_FACILITY, unit_address, op, p1, p2, p3, p4);
- _PRINT_MSG(rc, "cxl_h_control_facility(%#.16llx, %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li\n",
- unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
- trace_cxl_hcall_control_facility(unit_address, OP_STR_CONTROL_ADAPTER(op), p1, p2, p3, p4, retbuf[0], rc);
-
- switch (rc) {
- case H_SUCCESS: /* The operation is completed for the coherent platform facility */
- if (op == H_CONTROL_CA_FACILITY_COLLECT_VPD)
- *out = retbuf[0];
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied. */
- case H_FUNCTION: /* The function is not supported. */
- case H_NOT_FOUND: /* The operation supplied was not valid */
- case H_NOT_AVAILABLE: /* The operation cannot be performed because the AFU has not been downloaded */
- case H_SG_LIST: /* An block list entry was invalid */
- return -EINVAL;
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
- case H_RESOURCE: /* The function has page table mappings for MMIO */
- case H_HARDWARE: /* A hardware event prevented the attach operation */
- case H_STATE: /* The coherent platform facility is not in a valid state */
- case H_BUSY:
- return -EBUSY;
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
- */
-long cxl_h_reset_adapter(u64 unit_address)
-{
- return cxl_h_control_facility(unit_address,
- H_CONTROL_CA_FACILITY_RESET,
- 0, 0, 0, 0,
- NULL);
-}
-
-/*
- * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
- * Parameter1 = 4K naturally aligned real buffer containing block
- * list entries
- * Parameter2 = number of block list entries in the block list, valid
- * values are between 0 and 256
- */
-long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
- u64 num, u64 *out)
-{
- return cxl_h_control_facility(unit_address,
- H_CONTROL_CA_FACILITY_COLLECT_VPD,
- list_address, num, 0, 0,
- out);
-}
-
-/*
- * cxl_h_download_facility - This H_DOWNLOAD_CA_FACILITY
- * hypervisor call provide platform support for
- * downloading a base adapter image to the coherent
- * platform facility, and for validating the entire
- * image after the download.
- * Parameters
- * op: operation to perform to the coherent platform function
- * Download: operation = 1, the base image in the coherent platform
- * facility is first erased, and then
- * programmed using the image supplied
- * in the scatter/gather list.
- * Validate: operation = 2, the base image in the coherent platform
- * facility is compared with the image
- * supplied in the scatter/gather list.
- * list_address: 4K naturally aligned real buffer containing
- * scatter/gather list entries.
- * num: number of block list entries in the scatter/gather list.
- */
-static long cxl_h_download_facility(u64 unit_address, u64 op,
- u64 list_address, u64 num,
- u64 *out)
-{
- unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
- unsigned int delay, total_delay = 0;
- u64 token = 0;
- long rc;
-
- if (*out != 0)
- token = *out;
-
- memset(retbuf, 0, sizeof(retbuf));
- while (1) {
- rc = plpar_hcall(H_DOWNLOAD_CA_FACILITY, retbuf,
- unit_address, op, list_address, num,
- token);
- token = retbuf[0];
- if (rc != H_BUSY && !H_IS_LONG_BUSY(rc))
- break;
-
- if (rc != H_BUSY) {
- delay = get_longbusy_msecs(rc);
- total_delay += delay;
- if (total_delay > CXL_HCALL_TIMEOUT_DOWNLOAD) {
- WARN(1, "Warning: Giving up waiting for CXL hcall "
- "%#x after %u msec\n",
- H_DOWNLOAD_CA_FACILITY, total_delay);
- rc = H_BUSY;
- break;
- }
- msleep(delay);
- }
- }
- _PRINT_MSG(rc, "cxl_h_download_facility(%#.16llx, %s(%#llx, %#llx), %#lx): %li\n",
- unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
- trace_cxl_hcall_download_facility(unit_address, OP_STR_DOWNLOAD_ADAPTER(op), list_address, num, retbuf[0], rc);
-
- switch (rc) {
- case H_SUCCESS: /* The operation is completed for the coherent platform facility */
- return 0;
- case H_PARAMETER: /* An incorrect parameter was supplied */
- case H_FUNCTION: /* The function is not supported. */
- case H_SG_LIST: /* An block list entry was invalid */
- case H_BAD_DATA: /* Image verification failed */
- return -EINVAL;
- case H_AUTHORITY: /* The partition does not have authority to perform this hcall */
- case H_RESOURCE: /* The function has page table mappings for MMIO */
- case H_HARDWARE: /* A hardware event prevented the attach operation */
- case H_STATE: /* The coherent platform facility is not in a valid state */
- case H_BUSY:
- return -EBUSY;
- case H_CONTINUE:
- *out = retbuf[0];
- return 1; /* More data is needed for the complete image */
- default:
- WARN(1, "Unexpected return code: %lx", rc);
- return -EINVAL;
- }
-}
-
-/*
- * cxl_h_download_adapter_image - Download the base image to the coherent
- * platform facility.
- */
-long cxl_h_download_adapter_image(u64 unit_address,
- u64 list_address, u64 num,
- u64 *out)
-{
- return cxl_h_download_facility(unit_address,
- H_DOWNLOAD_CA_FACILITY_DOWNLOAD,
- list_address, num, out);
-}
-
-/*
- * cxl_h_validate_adapter_image - Validate the base image in the coherent
- * platform facility.
- */
-long cxl_h_validate_adapter_image(u64 unit_address,
- u64 list_address, u64 num,
- u64 *out)
-{
- return cxl_h_download_facility(unit_address,
- H_DOWNLOAD_CA_FACILITY_VALIDATE,
- list_address, num, out);
-}
diff --git a/drivers/misc/cxl/hcalls.h b/drivers/misc/cxl/hcalls.h
deleted file mode 100644
index d200465dc6ac..000000000000
--- a/drivers/misc/cxl/hcalls.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright 2015 IBM Corp.
- */
-
-#ifndef _HCALLS_H
-#define _HCALLS_H
-
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <asm/hvcall.h>
-#include "cxl.h"
-
-#define SG_BUFFER_SIZE 4096
-#define SG_MAX_ENTRIES 256
-
-struct sg_list {
- u64 phys_addr;
- u64 len;
-};
-
-/*
- * This is straight out of PAPR, but replacing some of the compound fields with
- * a single field, where they were identical to the register layout.
- *
- * The 'flags' parameter regroups the various bit-fields
- */
-#define CXL_PE_CSRP_VALID (1ULL << 63)
-#define CXL_PE_PROBLEM_STATE (1ULL << 62)
-#define CXL_PE_SECONDARY_SEGMENT_TBL_SRCH (1ULL << 61)
-#define CXL_PE_TAGS_ACTIVE (1ULL << 60)
-#define CXL_PE_USER_STATE (1ULL << 59)
-#define CXL_PE_TRANSLATION_ENABLED (1ULL << 58)
-#define CXL_PE_64_BIT (1ULL << 57)
-#define CXL_PE_PRIVILEGED_PROCESS (1ULL << 56)
-
-#define CXL_PROCESS_ELEMENT_VERSION 1
-struct cxl_process_element_hcall {
- __be64 version;
- __be64 flags;
- u8 reserved0[12];
- __be32 pslVirtualIsn;
- u8 applicationVirtualIsnBitmap[256];
- u8 reserved1[144];
- struct cxl_process_element_common common;
- u8 reserved4[12];
-} __packed;
-
-#define H_STATE_NORMAL 1
-#define H_STATE_DISABLE 2
-#define H_STATE_TEMP_UNAVAILABLE 3
-#define H_STATE_PERM_UNAVAILABLE 4
-
-/* NOTE: element must be a logical real address, and must be pinned */
-long cxl_h_attach_process(u64 unit_address, struct cxl_process_element_hcall *element,
- u64 *process_token, u64 *mmio_addr, u64 *mmio_size);
-
-/**
- * cxl_h_detach_process - Detach a process element from a coherent
- * platform function.
- */
-long cxl_h_detach_process(u64 unit_address, u64 process_token);
-
-/**
- * cxl_h_reset_afu - Perform a reset to the coherent platform function.
- */
-long cxl_h_reset_afu(u64 unit_address);
-
-/**
- * cxl_h_suspend_process - Suspend a process from being executed
- * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
- * process was attached.
- */
-long cxl_h_suspend_process(u64 unit_address, u64 process_token);
-
-/**
- * cxl_h_resume_process - Resume a process to be executed
- * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
- * process was attached.
- */
-long cxl_h_resume_process(u64 unit_address, u64 process_token);
-
-/**
- * cxl_h_read_error_state - Reads the error state of the coherent
- * platform function.
- * R4 contains the error state
- */
-long cxl_h_read_error_state(u64 unit_address, u64 *state);
-
-/**
- * cxl_h_get_afu_err - collect the AFU error buffer
- * Parameter1 = byte offset into error buffer to retrieve, valid values
- * are between 0 and (ibm,error-buffer-size - 1)
- * Parameter2 = 4K aligned real address of error buffer, to be filled in
- * Parameter3 = length of error buffer, valid values are 4K or less
- */
-long cxl_h_get_afu_err(u64 unit_address, u64 offset, u64 buf_address, u64 len);
-
-/**
- * cxl_h_get_config - collect configuration record for the
- * coherent platform function
- * Parameter1 = # of configuration record to retrieve, valid values are
- * between 0 and (ibm,#config-records - 1)
- * Parameter2 = byte offset into configuration record to retrieve,
- * valid values are between 0 and (ibm,config-record-size - 1)
- * Parameter3 = 4K aligned real address of configuration record buffer,
- * to be filled in
- * Parameter4 = length of configuration buffer, valid values are 4K or less
- */
-long cxl_h_get_config(u64 unit_address, u64 cr_num, u64 offset,
- u64 buf_address, u64 len);
-
-/**
- * cxl_h_terminate_process - Terminate the process before completion
- * Parameter1 = process-token as returned from H_ATTACH_CA_PROCESS when
- * process was attached.
- */
-long cxl_h_terminate_process(u64 unit_address, u64 process_token);
-
-/**
- * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
- * Parameter1 = # of VPD record to retrieve, valid values are between 0
- * and (ibm,#config-records - 1).
- * Parameter2 = 4K naturally aligned real buffer containing block
- * list entries
- * Parameter3 = number of block list entries in the block list, valid
- * values are between 0 and 256
- */
-long cxl_h_collect_vpd(u64 unit_address, u64 record, u64 list_address,
- u64 num, u64 *out);
-
-/**
- * cxl_h_get_fn_error_interrupt - Read the function-wide error data based on an interrupt
- */
-long cxl_h_get_fn_error_interrupt(u64 unit_address, u64 *reg);
-
-/**
- * cxl_h_ack_fn_error_interrupt - Acknowledge function-wide error data
- * based on an interrupt
- * Parameter1 = value to write to the function-wide error interrupt register
- */
-long cxl_h_ack_fn_error_interrupt(u64 unit_address, u64 value);
-
-/**
- * cxl_h_get_error_log - Retrieve the Platform Log ID (PLID) of
- * an error log
- */
-long cxl_h_get_error_log(u64 unit_address, u64 value);
-
-/**
- * cxl_h_collect_int_info - Collect interrupt info about a coherent
- * platform function after an interrupt occurred.
- */
-long cxl_h_collect_int_info(u64 unit_address, u64 process_token,
- struct cxl_irq_info *info);
-
-/**
- * cxl_h_control_faults - Control the operation of a coherent platform
- * function after a fault occurs.
- *
- * Parameters
- * control-mask: value to control the faults
- * looks like PSL_TFC_An shifted >> 32
- * reset-mask: mask to control reset of function faults
- * Set reset_mask = 1 to reset PSL errors
- */
-long cxl_h_control_faults(u64 unit_address, u64 process_token,
- u64 control_mask, u64 reset_mask);
-
-/**
- * cxl_h_reset_adapter - Perform a reset to the coherent platform facility.
- */
-long cxl_h_reset_adapter(u64 unit_address);
-
-/**
- * cxl_h_collect_vpd - Collect VPD for the coherent platform function.
- * Parameter1 = 4K naturally aligned real buffer containing block
- * list entries
- * Parameter2 = number of block list entries in the block list, valid
- * values are between 0 and 256
- */
-long cxl_h_collect_vpd_adapter(u64 unit_address, u64 list_address,
- u64 num, u64 *out);
-
-/**
- * cxl_h_download_adapter_image - Download the base image to the coherent
- * platform facility.
- */
-long cxl_h_download_adapter_image(u64 unit_address,
- u64 list_address, u64 num,
- u64 *out);
-
-/**
- * cxl_h_validate_adapter_image - Validate the base image in the coherent
- * platform facility.
- */
-long cxl_h_validate_adapter_image(u64 unit_address,
- u64 list_address, u64 num,
- u64 *out);
-#endif /* _HCALLS_H */
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
deleted file mode 100644
index b730e022a48e..000000000000
--- a/drivers/misc/cxl/irq.c
+++ /dev/null
@@ -1,450 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/pid.h>
-#include <asm/cputable.h>
-#include <misc/cxl-base.h>
-
-#include "cxl.h"
-#include "trace.h"
-
-static int afu_irq_range_start(void)
-{
- if (cpu_has_feature(CPU_FTR_HVMODE))
- return 1;
- return 0;
-}
-
-static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 dar)
-{
- ctx->dsisr = dsisr;
- ctx->dar = dar;
- schedule_work(&ctx->fault_work);
- return IRQ_HANDLED;
-}
-
-irqreturn_t cxl_irq_psl9(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info)
-{
- u64 dsisr, dar;
-
- dsisr = irq_info->dsisr;
- dar = irq_info->dar;
-
- trace_cxl_psl9_irq(ctx, irq, dsisr, dar);
-
- pr_devel("CXL interrupt %i for afu pe: %i DSISR: %#llx DAR: %#llx\n", irq, ctx->pe, dsisr, dar);
-
- if (dsisr & CXL_PSL9_DSISR_An_TF) {
- pr_devel("CXL interrupt: Scheduling translation fault handling for later (pe: %i)\n", ctx->pe);
- return schedule_cxl_fault(ctx, dsisr, dar);
- }
-
- if (dsisr & CXL_PSL9_DSISR_An_PE)
- return cxl_ops->handle_psl_slice_error(ctx, dsisr,
- irq_info->errstat);
- if (dsisr & CXL_PSL9_DSISR_An_AE) {
- pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);
-
- if (ctx->pending_afu_err) {
- /*
- * This shouldn't happen - the PSL treats these errors
- * as fatal and will have reset the AFU, so there's not
- * much point buffering multiple AFU errors.
- * OTOH if we DO ever see a storm of these come in it's
- * probably best that we log them somewhere:
- */
- dev_err_ratelimited(&ctx->afu->dev, "CXL AFU Error undelivered to pe %i: 0x%016llx\n",
- ctx->pe, irq_info->afu_err);
- } else {
- spin_lock(&ctx->lock);
- ctx->afu_err = irq_info->afu_err;
- ctx->pending_afu_err = 1;
- spin_unlock(&ctx->lock);
-
- wake_up_all(&ctx->wq);
- }
-
- cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
- return IRQ_HANDLED;
- }
- if (dsisr & CXL_PSL9_DSISR_An_OC)
- pr_devel("CXL interrupt: OS Context Warning\n");
-
- WARN(1, "Unhandled CXL PSL IRQ\n");
- return IRQ_HANDLED;
-}
-
-irqreturn_t cxl_irq_psl8(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info)
-{
- u64 dsisr, dar;
-
- dsisr = irq_info->dsisr;
- dar = irq_info->dar;
-
- trace_cxl_psl_irq(ctx, irq, dsisr, dar);
-
- pr_devel("CXL interrupt %i for afu pe: %i DSISR: %#llx DAR: %#llx\n", irq, ctx->pe, dsisr, dar);
-
- if (dsisr & CXL_PSL_DSISR_An_DS) {
- /*
- * We don't inherently need to sleep to handle this, but we do
- * need to get a ref to the task's mm, which we can't do from
- * irq context without the potential for a deadlock since it
- * takes the task_lock. An alternate option would be to keep a
- * reference to the task's mm the entire time it has cxl open,
- * but to do that we need to solve the issue where we hold a
- * ref to the mm, but the mm can hold a ref to the fd after an
- * mmap preventing anything from being cleaned up.
- */
- pr_devel("Scheduling segment miss handling for later pe: %i\n", ctx->pe);
- return schedule_cxl_fault(ctx, dsisr, dar);
- }
-
- if (dsisr & CXL_PSL_DSISR_An_M)
- pr_devel("CXL interrupt: PTE not found\n");
- if (dsisr & CXL_PSL_DSISR_An_P)
- pr_devel("CXL interrupt: Storage protection violation\n");
- if (dsisr & CXL_PSL_DSISR_An_A)
- pr_devel("CXL interrupt: AFU lock access to write through or cache inhibited storage\n");
- if (dsisr & CXL_PSL_DSISR_An_S)
- pr_devel("CXL interrupt: Access was afu_wr or afu_zero\n");
- if (dsisr & CXL_PSL_DSISR_An_K)
- pr_devel("CXL interrupt: Access not permitted by virtual page class key protection\n");
-
- if (dsisr & CXL_PSL_DSISR_An_DM) {
- /*
- * In some cases we might be able to handle the fault
- * immediately if hash_page would succeed, but we still need
- * the task's mm, which as above we can't get without a lock
- */
- pr_devel("Scheduling page fault handling for later pe: %i\n", ctx->pe);
- return schedule_cxl_fault(ctx, dsisr, dar);
- }
- if (dsisr & CXL_PSL_DSISR_An_ST)
- WARN(1, "CXL interrupt: Segment Table PTE not found\n");
- if (dsisr & CXL_PSL_DSISR_An_UR)
- pr_devel("CXL interrupt: AURP PTE not found\n");
- if (dsisr & CXL_PSL_DSISR_An_PE)
- return cxl_ops->handle_psl_slice_error(ctx, dsisr,
- irq_info->errstat);
- if (dsisr & CXL_PSL_DSISR_An_AE) {
- pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);
-
- if (ctx->pending_afu_err) {
- /*
- * This shouldn't happen - the PSL treats these errors
- * as fatal and will have reset the AFU, so there's not
- * much point buffering multiple AFU errors.
- * OTOH if we DO ever see a storm of these come in it's
- * probably best that we log them somewhere:
- */
- dev_err_ratelimited(&ctx->afu->dev, "CXL AFU Error "
- "undelivered to pe %i: 0x%016llx\n",
- ctx->pe, irq_info->afu_err);
- } else {
- spin_lock(&ctx->lock);
- ctx->afu_err = irq_info->afu_err;
- ctx->pending_afu_err = true;
- spin_unlock(&ctx->lock);
-
- wake_up_all(&ctx->wq);
- }
-
- cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
- return IRQ_HANDLED;
- }
- if (dsisr & CXL_PSL_DSISR_An_OC)
- pr_devel("CXL interrupt: OS Context Warning\n");
-
- WARN(1, "Unhandled CXL PSL IRQ\n");
- return IRQ_HANDLED;
-}
-
-static irqreturn_t cxl_irq_afu(int irq, void *data)
-{
- struct cxl_context *ctx = data;
- irq_hw_number_t hwirq = irqd_to_hwirq(irq_get_irq_data(irq));
- int irq_off, afu_irq = 0;
- __u16 range;
- int r;
-
- /*
- * Look for the interrupt number.
- * On bare-metal, we know range 0 only contains the PSL
- * interrupt so we could start counting at range 1 and initialize
- * afu_irq at 1.
- * In a guest, range 0 also contains AFU interrupts, so it must
- * be counted for. Therefore we initialize afu_irq at 0 to take into
- * account the PSL interrupt.
- *
- * For code-readability, it just seems easier to go over all
- * the ranges on bare-metal and guest. The end result is the same.
- */
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- irq_off = hwirq - ctx->irqs.offset[r];
- range = ctx->irqs.range[r];
- if (irq_off >= 0 && irq_off < range) {
- afu_irq += irq_off;
- break;
- }
- afu_irq += range;
- }
- if (unlikely(r >= CXL_IRQ_RANGES)) {
- WARN(1, "Received AFU IRQ out of range for pe %i (virq %i hwirq %lx)\n",
- ctx->pe, irq, hwirq);
- return IRQ_HANDLED;
- }
-
- trace_cxl_afu_irq(ctx, afu_irq, irq, hwirq);
- pr_devel("Received AFU interrupt %i for pe: %i (virq %i hwirq %lx)\n",
- afu_irq, ctx->pe, irq, hwirq);
-
- if (unlikely(!ctx->irq_bitmap)) {
- WARN(1, "Received AFU IRQ for context with no IRQ bitmap\n");
- return IRQ_HANDLED;
- }
- spin_lock(&ctx->lock);
- set_bit(afu_irq - 1, ctx->irq_bitmap);
- ctx->pending_irq = true;
- spin_unlock(&ctx->lock);
-
- wake_up_all(&ctx->wq);
-
- return IRQ_HANDLED;
-}
-
-unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
- irq_handler_t handler, void *cookie, const char *name)
-{
- unsigned int virq;
- int result;
-
- /* IRQ Domain? */
- virq = irq_create_mapping(NULL, hwirq);
- if (!virq) {
- dev_warn(&adapter->dev, "cxl_map_irq: irq_create_mapping failed\n");
- return 0;
- }
-
- if (cxl_ops->setup_irq)
- cxl_ops->setup_irq(adapter, hwirq, virq);
-
- pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);
-
- result = request_irq(virq, handler, 0, name, cookie);
- if (result) {
- dev_warn(&adapter->dev, "cxl_map_irq: request_irq failed: %i\n", result);
- return 0;
- }
-
- return virq;
-}
-
-void cxl_unmap_irq(unsigned int virq, void *cookie)
-{
- free_irq(virq, cookie);
-}
-
-int cxl_register_one_irq(struct cxl *adapter,
- irq_handler_t handler,
- void *cookie,
- irq_hw_number_t *dest_hwirq,
- unsigned int *dest_virq,
- const char *name)
-{
- int hwirq, virq;
-
- if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0)
- return hwirq;
-
- if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
- goto err;
-
- *dest_hwirq = hwirq;
- *dest_virq = virq;
-
- return 0;
-
-err:
- cxl_ops->release_one_irq(adapter, hwirq);
- return -ENOMEM;
-}
-
-void afu_irq_name_free(struct cxl_context *ctx)
-{
- struct cxl_irq_name *irq_name, *tmp;
-
- list_for_each_entry_safe(irq_name, tmp, &ctx->irq_names, list) {
- kfree(irq_name->name);
- list_del(&irq_name->list);
- kfree(irq_name);
- }
-}
-
-int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
-{
- int rc, r, i, j = 1;
- struct cxl_irq_name *irq_name;
- int alloc_count;
-
- /*
- * In native mode, range 0 is reserved for the multiplexed
- * PSL interrupt. It has been allocated when the AFU was initialized.
- *
- * In a guest, the PSL interrupt is not mutliplexed, but per-context,
- * and is the first interrupt from range 0. It still needs to be
- * allocated, so bump the count by one.
- */
- if (cpu_has_feature(CPU_FTR_HVMODE))
- alloc_count = count;
- else
- alloc_count = count + 1;
-
- if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter,
- alloc_count)))
- return rc;
-
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- /* Multiplexed PSL Interrupt */
- ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq;
- ctx->irqs.range[0] = 1;
- }
-
- ctx->irq_count = count;
- ctx->irq_bitmap = bitmap_zalloc(count, GFP_KERNEL);
- if (!ctx->irq_bitmap)
- goto out;
-
- /*
- * Allocate names first. If any fail, bail out before allocating
- * actual hardware IRQs.
- */
- for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
- for (i = 0; i < ctx->irqs.range[r]; i++) {
- irq_name = kmalloc(sizeof(struct cxl_irq_name),
- GFP_KERNEL);
- if (!irq_name)
- goto out;
- irq_name->name = kasprintf(GFP_KERNEL, "cxl-%s-pe%i-%i",
- dev_name(&ctx->afu->dev),
- ctx->pe, j);
- if (!irq_name->name) {
- kfree(irq_name);
- goto out;
- }
- /* Add to tail so next look get the correct order */
- list_add_tail(&irq_name->list, &ctx->irq_names);
- j++;
- }
- }
- return 0;
-
-out:
- cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
- bitmap_free(ctx->irq_bitmap);
- afu_irq_name_free(ctx);
- return -ENOMEM;
-}
-
-static void afu_register_hwirqs(struct cxl_context *ctx)
-{
- irq_hw_number_t hwirq;
- struct cxl_irq_name *irq_name;
- int r, i;
- irqreturn_t (*handler)(int irq, void *data);
-
- /* We've allocated all memory now, so let's do the irq allocations */
- irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list);
- for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
- hwirq = ctx->irqs.offset[r];
- for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
- if (r == 0 && i == 0)
- /*
- * The very first interrupt of range 0 is
- * always the PSL interrupt, but we only
- * need to connect a handler for guests,
- * because there's one PSL interrupt per
- * context.
- * On bare-metal, the PSL interrupt is
- * multiplexed and was setup when the AFU
- * was configured.
- */
- handler = cxl_ops->psl_interrupt;
- else
- handler = cxl_irq_afu;
- cxl_map_irq(ctx->afu->adapter, hwirq, handler, ctx,
- irq_name->name);
- irq_name = list_next_entry(irq_name, list);
- }
- }
-}
-
-int afu_register_irqs(struct cxl_context *ctx, u32 count)
-{
- int rc;
-
- rc = afu_allocate_irqs(ctx, count);
- if (rc)
- return rc;
-
- afu_register_hwirqs(ctx);
- return 0;
-}
-
-void afu_release_irqs(struct cxl_context *ctx, void *cookie)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
- int r, i;
-
- for (r = afu_irq_range_start(); r < CXL_IRQ_RANGES; r++) {
- hwirq = ctx->irqs.offset[r];
- for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
- virq = irq_find_mapping(NULL, hwirq);
- if (virq)
- cxl_unmap_irq(virq, cookie);
- }
- }
-
- afu_irq_name_free(ctx);
- cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
-
- ctx->irq_count = 0;
-}
-
-void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr)
-{
- dev_crit(&afu->dev,
- "PSL Slice error received. Check AFU for root cause.\n");
- dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
- if (serr & CXL_PSL_SERR_An_afuto)
- dev_crit(&afu->dev, "AFU MMIO Timeout\n");
- if (serr & CXL_PSL_SERR_An_afudis)
- dev_crit(&afu->dev,
- "MMIO targeted Accelerator that was not enabled\n");
- if (serr & CXL_PSL_SERR_An_afuov)
- dev_crit(&afu->dev, "AFU CTAG Overflow\n");
- if (serr & CXL_PSL_SERR_An_badsrc)
- dev_crit(&afu->dev, "Bad Interrupt Source\n");
- if (serr & CXL_PSL_SERR_An_badctx)
- dev_crit(&afu->dev, "Bad Context Handle\n");
- if (serr & CXL_PSL_SERR_An_llcmdis)
- dev_crit(&afu->dev, "LLCMD to Disabled AFU\n");
- if (serr & CXL_PSL_SERR_An_llcmdto)
- dev_crit(&afu->dev, "LLCMD Timeout to AFU\n");
- if (serr & CXL_PSL_SERR_An_afupar)
- dev_crit(&afu->dev, "AFU MMIO Parity Error\n");
- if (serr & CXL_PSL_SERR_An_afudup)
- dev_crit(&afu->dev, "AFU MMIO Duplicate CTAG Error\n");
- if (serr & CXL_PSL_SERR_An_AE)
- dev_crit(&afu->dev,
- "AFU asserted JDONE with JERROR in AFU Directed Mode\n");
-}
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
deleted file mode 100644
index c1fbf6f588f7..000000000000
--- a/drivers/misc/cxl/main.c
+++ /dev/null
@@ -1,383 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-#include <linux/idr.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/sched/task.h>
-
-#include <asm/cputable.h>
-#include <asm/mmu.h>
-#include <misc/cxl-base.h>
-
-#include "cxl.h"
-#include "trace.h"
-
-static DEFINE_SPINLOCK(adapter_idr_lock);
-static DEFINE_IDR(cxl_adapter_idr);
-
-uint cxl_verbose;
-module_param_named(verbose, cxl_verbose, uint, 0600);
-MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
-
-const struct cxl_backend_ops *cxl_ops;
-
-int cxl_afu_slbia(struct cxl_afu *afu)
-{
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
-
- pr_devel("cxl_afu_slbia issuing SLBIA command\n");
- cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
- while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
- return -EBUSY;
- }
- /* If the adapter has gone down, we can assume that we
- * will PERST it and that will invalidate everything.
- */
- if (!cxl_ops->link_ok(afu->adapter, afu))
- return -EIO;
- cpu_relax();
- }
- return 0;
-}
-
-static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm)
-{
- unsigned long flags;
-
- if (ctx->mm != mm)
- return;
-
- pr_devel("%s matched mm - card: %i afu: %i pe: %i\n", __func__,
- ctx->afu->adapter->adapter_num, ctx->afu->slice, ctx->pe);
-
- spin_lock_irqsave(&ctx->sste_lock, flags);
- trace_cxl_slbia(ctx);
- memset(ctx->sstp, 0, ctx->sst_size);
- spin_unlock_irqrestore(&ctx->sste_lock, flags);
- mb();
- cxl_afu_slbia(ctx->afu);
-}
-
-static inline void cxl_slbia_core(struct mm_struct *mm)
-{
- struct cxl *adapter;
- struct cxl_afu *afu;
- struct cxl_context *ctx;
- int card, slice, id;
-
- pr_devel("%s called\n", __func__);
-
- spin_lock(&adapter_idr_lock);
- idr_for_each_entry(&cxl_adapter_idr, adapter, card) {
- /* XXX: Make this lookup faster with link from mm to ctx */
- spin_lock(&adapter->afu_list_lock);
- for (slice = 0; slice < adapter->slices; slice++) {
- afu = adapter->afu[slice];
- if (!afu || !afu->enabled)
- continue;
- rcu_read_lock();
- idr_for_each_entry(&afu->contexts_idr, ctx, id)
- _cxl_slbia(ctx, mm);
- rcu_read_unlock();
- }
- spin_unlock(&adapter->afu_list_lock);
- }
- spin_unlock(&adapter_idr_lock);
-}
-
-static struct cxl_calls cxl_calls = {
- .cxl_slbia = cxl_slbia_core,
- .owner = THIS_MODULE,
-};
-
-int cxl_alloc_sst(struct cxl_context *ctx)
-{
- unsigned long vsid;
- u64 ea_mask, size, sstp0, sstp1;
-
- sstp0 = 0;
- sstp1 = 0;
-
- ctx->sst_size = PAGE_SIZE;
- ctx->sst_lru = 0;
- ctx->sstp = (struct cxl_sste *)get_zeroed_page(GFP_KERNEL);
- if (!ctx->sstp) {
- pr_err("cxl_alloc_sst: Unable to allocate segment table\n");
- return -ENOMEM;
- }
- pr_devel("SSTP allocated at 0x%p\n", ctx->sstp);
-
- vsid = get_kernel_vsid((u64)ctx->sstp, mmu_kernel_ssize) << 12;
-
- sstp0 |= (u64)mmu_kernel_ssize << CXL_SSTP0_An_B_SHIFT;
- sstp0 |= (SLB_VSID_KERNEL | mmu_psize_defs[mmu_linear_psize].sllp) << 50;
-
- size = (((u64)ctx->sst_size >> 8) - 1) << CXL_SSTP0_An_SegTableSize_SHIFT;
- if (unlikely(size & ~CXL_SSTP0_An_SegTableSize_MASK)) {
- WARN(1, "Impossible segment table size\n");
- return -EINVAL;
- }
- sstp0 |= size;
-
- if (mmu_kernel_ssize == MMU_SEGSIZE_256M)
- ea_mask = 0xfffff00ULL;
- else
- ea_mask = 0xffffffff00ULL;
-
- sstp0 |= vsid >> (50-14); /* Top 14 bits of VSID */
- sstp1 |= (vsid << (64-(50-14))) & ~ea_mask;
- sstp1 |= (u64)ctx->sstp & ea_mask;
- sstp1 |= CXL_SSTP1_An_V;
-
- pr_devel("Looked up %#llx: slbfee. %#llx (ssize: %x, vsid: %#lx), copied to SSTP0: %#llx, SSTP1: %#llx\n",
- (u64)ctx->sstp, (u64)ctx->sstp & ESID_MASK, mmu_kernel_ssize, vsid, sstp0, sstp1);
-
- /* Store calculated sstp hardware points for use later */
- ctx->sstp0 = sstp0;
- ctx->sstp1 = sstp1;
-
- return 0;
-}
-
-/* print buffer content as integers when debugging */
-void cxl_dump_debug_buffer(void *buf, size_t buf_len)
-{
-#ifdef DEBUG
- int i, *ptr;
-
- /*
- * We want to regroup up to 4 integers per line, which means they
- * need to be in the same pr_devel() statement
- */
- ptr = (int *) buf;
- for (i = 0; i * 4 < buf_len; i += 4) {
- if ((i + 3) * 4 < buf_len)
- pr_devel("%.8x %.8x %.8x %.8x\n", ptr[i], ptr[i + 1],
- ptr[i + 2], ptr[i + 3]);
- else if ((i + 2) * 4 < buf_len)
- pr_devel("%.8x %.8x %.8x\n", ptr[i], ptr[i + 1],
- ptr[i + 2]);
- else if ((i + 1) * 4 < buf_len)
- pr_devel("%.8x %.8x\n", ptr[i], ptr[i + 1]);
- else
- pr_devel("%.8x\n", ptr[i]);
- }
-#endif /* DEBUG */
-}
-
-/* Find a CXL adapter by it's number and increase it's refcount */
-struct cxl *get_cxl_adapter(int num)
-{
- struct cxl *adapter;
-
- spin_lock(&adapter_idr_lock);
- if ((adapter = idr_find(&cxl_adapter_idr, num)))
- get_device(&adapter->dev);
- spin_unlock(&adapter_idr_lock);
-
- return adapter;
-}
-
-static int cxl_alloc_adapter_nr(struct cxl *adapter)
-{
- int i;
-
- idr_preload(GFP_KERNEL);
- spin_lock(&adapter_idr_lock);
- i = idr_alloc(&cxl_adapter_idr, adapter, 0, 0, GFP_NOWAIT);
- spin_unlock(&adapter_idr_lock);
- idr_preload_end();
- if (i < 0)
- return i;
-
- adapter->adapter_num = i;
-
- return 0;
-}
-
-void cxl_remove_adapter_nr(struct cxl *adapter)
-{
- idr_remove(&cxl_adapter_idr, adapter->adapter_num);
-}
-
-struct cxl *cxl_alloc_adapter(void)
-{
- struct cxl *adapter;
-
- if (!(adapter = kzalloc(sizeof(struct cxl), GFP_KERNEL)))
- return NULL;
-
- spin_lock_init(&adapter->afu_list_lock);
-
- if (cxl_alloc_adapter_nr(adapter))
- goto err1;
-
- if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
- goto err2;
-
- /* start with context lock taken */
- atomic_set(&adapter->contexts_num, -1);
-
- return adapter;
-err2:
- cxl_remove_adapter_nr(adapter);
-err1:
- kfree(adapter);
- return NULL;
-}
-
-struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
-{
- struct cxl_afu *afu;
-
- if (!(afu = kzalloc(sizeof(struct cxl_afu), GFP_KERNEL)))
- return NULL;
-
- afu->adapter = adapter;
- afu->dev.parent = &adapter->dev;
- afu->dev.release = cxl_ops->release_afu;
- afu->slice = slice;
- idr_init(&afu->contexts_idr);
- mutex_init(&afu->contexts_lock);
- spin_lock_init(&afu->afu_cntl_lock);
- atomic_set(&afu->configured_state, -1);
- afu->prefault_mode = CXL_PREFAULT_NONE;
- afu->irqs_max = afu->adapter->user_irqs;
-
- return afu;
-}
-
-int cxl_afu_select_best_mode(struct cxl_afu *afu)
-{
- if (afu->modes_supported & CXL_MODE_DIRECTED)
- return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED);
-
- if (afu->modes_supported & CXL_MODE_DEDICATED)
- return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED);
-
- dev_warn(&afu->dev, "No supported programming modes available\n");
- /* We don't fail this so the user can inspect sysfs */
- return 0;
-}
-
-int cxl_adapter_context_get(struct cxl *adapter)
-{
- int rc;
-
- rc = atomic_inc_unless_negative(&adapter->contexts_num);
- return rc ? 0 : -EBUSY;
-}
-
-void cxl_adapter_context_put(struct cxl *adapter)
-{
- atomic_dec_if_positive(&adapter->contexts_num);
-}
-
-int cxl_adapter_context_lock(struct cxl *adapter)
-{
- int rc;
- /* no active contexts -> contexts_num == 0 */
- rc = atomic_cmpxchg(&adapter->contexts_num, 0, -1);
- return rc ? -EBUSY : 0;
-}
-
-void cxl_adapter_context_unlock(struct cxl *adapter)
-{
- int val = atomic_cmpxchg(&adapter->contexts_num, -1, 0);
-
- /*
- * contexts lock taken -> contexts_num == -1
- * If not true then show a warning and force reset the lock.
- * This will happen when context_unlock was requested without
- * doing a context_lock.
- */
- if (val != -1) {
- atomic_set(&adapter->contexts_num, 0);
- WARN(1, "Adapter context unlocked with %d active contexts",
- val);
- }
-}
-
-static int __init init_cxl(void)
-{
- int rc = 0;
-
- if (!tlbie_capable)
- return -EINVAL;
-
- if ((rc = cxl_file_init()))
- return rc;
-
- cxl_debugfs_init();
-
- /*
- * we don't register the callback on P9. slb callack is only
- * used for the PSL8 MMU and CX4.
- */
- if (cxl_is_power8()) {
- rc = register_cxl_calls(&cxl_calls);
- if (rc)
- goto err;
- }
-
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- cxl_ops = &cxl_native_ops;
- rc = pci_register_driver(&cxl_pci_driver);
- }
-#ifdef CONFIG_PPC_PSERIES
- else {
- cxl_ops = &cxl_guest_ops;
- rc = platform_driver_register(&cxl_of_driver);
- }
-#endif
- if (rc)
- goto err1;
-
- return 0;
-err1:
- if (cxl_is_power8())
- unregister_cxl_calls(&cxl_calls);
-err:
- cxl_debugfs_exit();
- cxl_file_exit();
-
- return rc;
-}
-
-static void exit_cxl(void)
-{
- if (cpu_has_feature(CPU_FTR_HVMODE))
- pci_unregister_driver(&cxl_pci_driver);
-#ifdef CONFIG_PPC_PSERIES
- else
- platform_driver_unregister(&cxl_of_driver);
-#endif
-
- cxl_debugfs_exit();
- cxl_file_exit();
- if (cxl_is_power8())
- unregister_cxl_calls(&cxl_calls);
- idr_destroy(&cxl_adapter_idr);
-}
-
-module_init(init_cxl);
-module_exit(exit_cxl);
-
-MODULE_DESCRIPTION("IBM Coherent Accelerator");
-MODULE_AUTHOR("Ian Munsie <imunsie@au1.ibm.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
deleted file mode 100644
index fbe16a6ab7ad..000000000000
--- a/drivers/misc/cxl/native.c
+++ /dev/null
@@ -1,1592 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/sched/clock.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/irqdomain.h>
-#include <asm/synch.h>
-#include <asm/switch_to.h>
-#include <misc/cxl-base.h>
-
-#include "cxl.h"
-#include "trace.h"
-
-static int afu_control(struct cxl_afu *afu, u64 command, u64 clear,
- u64 result, u64 mask, bool enabled)
-{
- u64 AFU_Cntl;
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
- int rc = 0;
-
- spin_lock(&afu->afu_cntl_lock);
- pr_devel("AFU command starting: %llx\n", command);
-
- trace_cxl_afu_ctrl(afu, command);
-
- AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
- cxl_p2n_write(afu, CXL_AFU_Cntl_An, (AFU_Cntl & ~clear) | command);
-
- AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
- while ((AFU_Cntl & mask) != result) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&afu->dev, "WARNING: AFU control timed out!\n");
- rc = -EBUSY;
- goto out;
- }
-
- if (!cxl_ops->link_ok(afu->adapter, afu)) {
- afu->enabled = enabled;
- rc = -EIO;
- goto out;
- }
-
- pr_devel_ratelimited("AFU control... (0x%016llx)\n",
- AFU_Cntl | command);
- cpu_relax();
- AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
- }
-
- if (AFU_Cntl & CXL_AFU_Cntl_An_RA) {
- /*
- * Workaround for a bug in the XSL used in the Mellanox CX4
- * that fails to clear the RA bit after an AFU reset,
- * preventing subsequent AFU resets from working.
- */
- cxl_p2n_write(afu, CXL_AFU_Cntl_An, AFU_Cntl & ~CXL_AFU_Cntl_An_RA);
- }
-
- pr_devel("AFU command complete: %llx\n", command);
- afu->enabled = enabled;
-out:
- trace_cxl_afu_ctrl_done(afu, command, rc);
- spin_unlock(&afu->afu_cntl_lock);
-
- return rc;
-}
-
-static int afu_enable(struct cxl_afu *afu)
-{
- pr_devel("AFU enable request\n");
-
- return afu_control(afu, CXL_AFU_Cntl_An_E, 0,
- CXL_AFU_Cntl_An_ES_Enabled,
- CXL_AFU_Cntl_An_ES_MASK, true);
-}
-
-int cxl_afu_disable(struct cxl_afu *afu)
-{
- pr_devel("AFU disable request\n");
-
- return afu_control(afu, 0, CXL_AFU_Cntl_An_E,
- CXL_AFU_Cntl_An_ES_Disabled,
- CXL_AFU_Cntl_An_ES_MASK, false);
-}
-
-/* This will disable as well as reset */
-static int native_afu_reset(struct cxl_afu *afu)
-{
- int rc;
- u64 serr;
-
- pr_devel("AFU reset request\n");
-
- rc = afu_control(afu, CXL_AFU_Cntl_An_RA, 0,
- CXL_AFU_Cntl_An_RS_Complete | CXL_AFU_Cntl_An_ES_Disabled,
- CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
- false);
-
- /*
- * Re-enable any masked interrupts when the AFU is not
- * activated to avoid side effects after attaching a process
- * in dedicated mode.
- */
- if (afu->current_mode == 0) {
- serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
- serr &= ~CXL_PSL_SERR_An_IRQ_MASKS;
- cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
- }
-
- return rc;
-}
-
-static int native_afu_check_and_enable(struct cxl_afu *afu)
-{
- if (!cxl_ops->link_ok(afu->adapter, afu)) {
- WARN(1, "Refusing to enable afu while link down!\n");
- return -EIO;
- }
- if (afu->enabled)
- return 0;
- return afu_enable(afu);
-}
-
-int cxl_psl_purge(struct cxl_afu *afu)
-{
- u64 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
- u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
- u64 dsisr, dar;
- u64 start, end;
- u64 trans_fault = 0x0ULL;
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
- int rc = 0;
-
- trace_cxl_psl_ctrl(afu, CXL_PSL_SCNTL_An_Pc);
-
- pr_devel("PSL purge request\n");
-
- if (cxl_is_power8())
- trans_fault = CXL_PSL_DSISR_TRANS;
- if (cxl_is_power9())
- trans_fault = CXL_PSL9_DSISR_An_TF;
-
- if (!cxl_ops->link_ok(afu->adapter, afu)) {
- dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
- rc = -EIO;
- goto out;
- }
-
- if ((AFU_Cntl & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
- WARN(1, "psl_purge request while AFU not disabled!\n");
- cxl_afu_disable(afu);
- }
-
- cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
- PSL_CNTL | CXL_PSL_SCNTL_An_Pc);
- start = local_clock();
- PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
- while ((PSL_CNTL & CXL_PSL_SCNTL_An_Ps_MASK)
- == CXL_PSL_SCNTL_An_Ps_Pending) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n");
- rc = -EBUSY;
- goto out;
- }
- if (!cxl_ops->link_ok(afu->adapter, afu)) {
- rc = -EIO;
- goto out;
- }
-
- dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%016llx PSL_DSISR: 0x%016llx\n",
- PSL_CNTL, dsisr);
-
- if (dsisr & trans_fault) {
- dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
- dev_notice(&afu->dev, "PSL purge terminating pending translation, DSISR: 0x%016llx, DAR: 0x%016llx\n",
- dsisr, dar);
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
- } else if (dsisr) {
- dev_notice(&afu->dev, "PSL purge acknowledging pending non-translation fault, DSISR: 0x%016llx\n",
- dsisr);
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
- } else {
- cpu_relax();
- }
- PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
- }
- end = local_clock();
- pr_devel("PSL purged in %lld ns\n", end - start);
-
- cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
- PSL_CNTL & ~CXL_PSL_SCNTL_An_Pc);
-out:
- trace_cxl_psl_ctrl_done(afu, CXL_PSL_SCNTL_An_Pc, rc);
- return rc;
-}
-
-static int spa_max_procs(int spa_size)
-{
- /*
- * From the CAIA:
- * end_of_SPA_area = SPA_Base + ((n+4) * 128) + (( ((n*8) + 127) >> 7) * 128) + 255
- * Most of that junk is really just an overly-complicated way of saying
- * the last 256 bytes are __aligned(128), so it's really:
- * end_of_SPA_area = end_of_PSL_queue_area + __aligned(128) 255
- * and
- * end_of_PSL_queue_area = SPA_Base + ((n+4) * 128) + (n*8) - 1
- * so
- * sizeof(SPA) = ((n+4) * 128) + (n*8) + __aligned(128) 256
- * Ignore the alignment (which is safe in this case as long as we are
- * careful with our rounding) and solve for n:
- */
- return ((spa_size / 8) - 96) / 17;
-}
-
-static int cxl_alloc_spa(struct cxl_afu *afu, int mode)
-{
- unsigned spa_size;
-
- /* Work out how many pages to allocate */
- afu->native->spa_order = -1;
- do {
- afu->native->spa_order++;
- spa_size = (1 << afu->native->spa_order) * PAGE_SIZE;
-
- if (spa_size > 0x100000) {
- dev_warn(&afu->dev, "num_of_processes too large for the SPA, limiting to %i (0x%x)\n",
- afu->native->spa_max_procs, afu->native->spa_size);
- if (mode != CXL_MODE_DEDICATED)
- afu->num_procs = afu->native->spa_max_procs;
- break;
- }
-
- afu->native->spa_size = spa_size;
- afu->native->spa_max_procs = spa_max_procs(afu->native->spa_size);
- } while (afu->native->spa_max_procs < afu->num_procs);
-
- if (!(afu->native->spa = (struct cxl_process_element *)
- __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->native->spa_order))) {
- pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n");
- return -ENOMEM;
- }
- pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n",
- 1<<afu->native->spa_order, afu->native->spa_max_procs, afu->num_procs);
-
- return 0;
-}
-
-static void attach_spa(struct cxl_afu *afu)
-{
- u64 spap;
-
- afu->native->sw_command_status = (__be64 *)((char *)afu->native->spa +
- ((afu->native->spa_max_procs + 3) * 128));
-
- spap = virt_to_phys(afu->native->spa) & CXL_PSL_SPAP_Addr;
- spap |= ((afu->native->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size;
- spap |= CXL_PSL_SPAP_V;
- pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n",
- afu->native->spa, afu->native->spa_max_procs,
- afu->native->sw_command_status, spap);
- cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap);
-}
-
-void cxl_release_spa(struct cxl_afu *afu)
-{
- if (afu->native->spa) {
- free_pages((unsigned long) afu->native->spa,
- afu->native->spa_order);
- afu->native->spa = NULL;
- }
-}
-
-/*
- * Invalidation of all ERAT entries is no longer required by CAIA2. Use
- * only for debug.
- */
-int cxl_invalidate_all_psl9(struct cxl *adapter)
-{
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
- u64 ierat;
-
- pr_devel("CXL adapter - invalidation of all ERAT entries\n");
-
- /* Invalidates all ERAT entries for Radix or HPT */
- ierat = CXL_XSL9_IERAT_IALL;
- if (radix_enabled())
- ierat |= CXL_XSL9_IERAT_INVR;
- cxl_p1_write(adapter, CXL_XSL9_IERAT, ierat);
-
- while (cxl_p1_read(adapter, CXL_XSL9_IERAT) & CXL_XSL9_IERAT_IINPROG) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&adapter->dev,
- "WARNING: CXL adapter invalidation of all ERAT entries timed out!\n");
- return -EBUSY;
- }
- if (!cxl_ops->link_ok(adapter, NULL))
- return -EIO;
- cpu_relax();
- }
- return 0;
-}
-
-int cxl_invalidate_all_psl8(struct cxl *adapter)
-{
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
-
- pr_devel("CXL adapter wide TLBIA & SLBIA\n");
-
- cxl_p1_write(adapter, CXL_PSL_AFUSEL, CXL_PSL_AFUSEL_A);
-
- cxl_p1_write(adapter, CXL_PSL_TLBIA, CXL_TLB_SLB_IQ_ALL);
- while (cxl_p1_read(adapter, CXL_PSL_TLBIA) & CXL_TLB_SLB_P) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
- return -EBUSY;
- }
- if (!cxl_ops->link_ok(adapter, NULL))
- return -EIO;
- cpu_relax();
- }
-
- cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_ALL);
- while (cxl_p1_read(adapter, CXL_PSL_SLBIA) & CXL_TLB_SLB_P) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
- return -EBUSY;
- }
- if (!cxl_ops->link_ok(adapter, NULL))
- return -EIO;
- cpu_relax();
- }
- return 0;
-}
-
-int cxl_data_cache_flush(struct cxl *adapter)
-{
- u64 reg;
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
-
- /*
- * Do a datacache flush only if datacache is available.
- * In case of PSL9D datacache absent hence flush operation.
- * would timeout.
- */
- if (adapter->native->no_data_cache) {
- pr_devel("No PSL data cache. Ignoring cache flush req.\n");
- return 0;
- }
-
- pr_devel("Flushing data cache\n");
- reg = cxl_p1_read(adapter, CXL_PSL_Control);
- reg |= CXL_PSL_Control_Fr;
- cxl_p1_write(adapter, CXL_PSL_Control, reg);
-
- reg = cxl_p1_read(adapter, CXL_PSL_Control);
- while ((reg & CXL_PSL_Control_Fs_MASK) != CXL_PSL_Control_Fs_Complete) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&adapter->dev, "WARNING: cache flush timed out!\n");
- return -EBUSY;
- }
-
- if (!cxl_ops->link_ok(adapter, NULL)) {
- dev_warn(&adapter->dev, "WARNING: link down when flushing cache\n");
- return -EIO;
- }
- cpu_relax();
- reg = cxl_p1_read(adapter, CXL_PSL_Control);
- }
-
- reg &= ~CXL_PSL_Control_Fr;
- cxl_p1_write(adapter, CXL_PSL_Control, reg);
- return 0;
-}
-
-static int cxl_write_sstp(struct cxl_afu *afu, u64 sstp0, u64 sstp1)
-{
- int rc;
-
- /* 1. Disable SSTP by writing 0 to SSTP1[V] */
- cxl_p2n_write(afu, CXL_SSTP1_An, 0);
-
- /* 2. Invalidate all SLB entries */
- if ((rc = cxl_afu_slbia(afu)))
- return rc;
-
- /* 3. Set SSTP0_An */
- cxl_p2n_write(afu, CXL_SSTP0_An, sstp0);
-
- /* 4. Set SSTP1_An */
- cxl_p2n_write(afu, CXL_SSTP1_An, sstp1);
-
- return 0;
-}
-
-/* Using per slice version may improve performance here. (ie. SLBIA_An) */
-static void slb_invalid(struct cxl_context *ctx)
-{
- struct cxl *adapter = ctx->afu->adapter;
- u64 slbia;
-
- WARN_ON(!mutex_is_locked(&ctx->afu->native->spa_mutex));
-
- cxl_p1_write(adapter, CXL_PSL_LBISEL,
- ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
- be32_to_cpu(ctx->elem->lpid));
- cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
-
- while (1) {
- if (!cxl_ops->link_ok(adapter, NULL))
- break;
- slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
- if (!(slbia & CXL_TLB_SLB_P))
- break;
- cpu_relax();
- }
-}
-
-static int do_process_element_cmd(struct cxl_context *ctx,
- u64 cmd, u64 pe_state)
-{
- u64 state;
- unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
- int rc = 0;
-
- trace_cxl_llcmd(ctx, cmd);
-
- WARN_ON(!ctx->afu->enabled);
-
- ctx->elem->software_state = cpu_to_be32(pe_state);
- smp_wmb();
- *(ctx->afu->native->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe);
- smp_mb();
- cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
- while (1) {
- if (time_after_eq(jiffies, timeout)) {
- dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n");
- rc = -EBUSY;
- goto out;
- }
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
- dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
- rc = -EIO;
- goto out;
- }
- state = be64_to_cpup(ctx->afu->native->sw_command_status);
- if (state == ~0ULL) {
- pr_err("cxl: Error adding process element to AFU\n");
- rc = -1;
- goto out;
- }
- if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) ==
- (cmd | (cmd >> 16) | ctx->pe))
- break;
- /*
- * The command won't finish in the PSL if there are
- * outstanding DSIs. Hence we need to yield here in
- * case there are outstanding DSIs that we need to
- * service. Tuning possiblity: we could wait for a
- * while before sched
- */
- schedule();
-
- }
-out:
- trace_cxl_llcmd_done(ctx, cmd, rc);
- return rc;
-}
-
-static int add_process_element(struct cxl_context *ctx)
-{
- int rc = 0;
-
- mutex_lock(&ctx->afu->native->spa_mutex);
- pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe);
- if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V)))
- ctx->pe_inserted = true;
- pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe);
- mutex_unlock(&ctx->afu->native->spa_mutex);
- return rc;
-}
-
-static int terminate_process_element(struct cxl_context *ctx)
-{
- int rc = 0;
-
- /* fast path terminate if it's already invalid */
- if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
- return rc;
-
- mutex_lock(&ctx->afu->native->spa_mutex);
- pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
- /* We could be asked to terminate when the hw is down. That
- * should always succeed: it's not running if the hw has gone
- * away and is being reset.
- */
- if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
- rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
- CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
- ctx->elem->software_state = 0; /* Remove Valid bit */
- pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
- mutex_unlock(&ctx->afu->native->spa_mutex);
- return rc;
-}
-
-static int remove_process_element(struct cxl_context *ctx)
-{
- int rc = 0;
-
- mutex_lock(&ctx->afu->native->spa_mutex);
- pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
-
- /* We could be asked to remove when the hw is down. Again, if
- * the hw is down, the PE is gone, so we succeed.
- */
- if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
- rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
-
- if (!rc)
- ctx->pe_inserted = false;
- if (cxl_is_power8())
- slb_invalid(ctx);
- pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
- mutex_unlock(&ctx->afu->native->spa_mutex);
-
- return rc;
-}
-
-void cxl_assign_psn_space(struct cxl_context *ctx)
-{
- if (!ctx->afu->pp_size || ctx->master) {
- ctx->psn_phys = ctx->afu->psn_phys;
- ctx->psn_size = ctx->afu->adapter->ps_size;
- } else {
- ctx->psn_phys = ctx->afu->psn_phys +
- (ctx->afu->native->pp_offset + ctx->afu->pp_size * ctx->pe);
- ctx->psn_size = ctx->afu->pp_size;
- }
-}
-
-static int activate_afu_directed(struct cxl_afu *afu)
-{
- int rc;
-
- dev_info(&afu->dev, "Activating AFU directed mode\n");
-
- afu->num_procs = afu->max_procs_virtualised;
- if (afu->native->spa == NULL) {
- if (cxl_alloc_spa(afu, CXL_MODE_DIRECTED))
- return -ENOMEM;
- }
- attach_spa(afu);
-
- cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_AFU);
- if (cxl_is_power8())
- cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
- cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
-
- afu->current_mode = CXL_MODE_DIRECTED;
-
- if ((rc = cxl_chardev_m_afu_add(afu)))
- return rc;
-
- if ((rc = cxl_sysfs_afu_m_add(afu)))
- goto err;
-
- if ((rc = cxl_chardev_s_afu_add(afu)))
- goto err1;
-
- return 0;
-err1:
- cxl_sysfs_afu_m_remove(afu);
-err:
- cxl_chardev_afu_remove(afu);
- return rc;
-}
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-#define set_endian(sr) ((sr) |= CXL_PSL_SR_An_LE)
-#else
-#define set_endian(sr) ((sr) &= ~(CXL_PSL_SR_An_LE))
-#endif
-
-u64 cxl_calculate_sr(bool master, bool kernel, bool real_mode, bool p9)
-{
- u64 sr = 0;
-
- set_endian(sr);
- if (master)
- sr |= CXL_PSL_SR_An_MP;
- if (mfspr(SPRN_LPCR) & LPCR_TC)
- sr |= CXL_PSL_SR_An_TC;
-
- if (kernel) {
- if (!real_mode)
- sr |= CXL_PSL_SR_An_R;
- sr |= (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV;
- } else {
- sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
- if (radix_enabled())
- sr |= CXL_PSL_SR_An_HV;
- else
- sr &= ~(CXL_PSL_SR_An_HV);
- if (!test_tsk_thread_flag(current, TIF_32BIT))
- sr |= CXL_PSL_SR_An_SF;
- }
- if (p9) {
- if (radix_enabled())
- sr |= CXL_PSL_SR_An_XLAT_ror;
- else
- sr |= CXL_PSL_SR_An_XLAT_hpt;
- }
- return sr;
-}
-
-static u64 calculate_sr(struct cxl_context *ctx)
-{
- return cxl_calculate_sr(ctx->master, ctx->kernel, false,
- cxl_is_power9());
-}
-
-static void update_ivtes_directed(struct cxl_context *ctx)
-{
- bool need_update = (ctx->status == STARTED);
- int r;
-
- if (need_update) {
- WARN_ON(terminate_process_element(ctx));
- WARN_ON(remove_process_element(ctx));
- }
-
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- ctx->elem->ivte_offsets[r] = cpu_to_be16(ctx->irqs.offset[r]);
- ctx->elem->ivte_ranges[r] = cpu_to_be16(ctx->irqs.range[r]);
- }
-
- /*
- * Theoretically we could use the update llcmd, instead of a
- * terminate/remove/add (or if an atomic update was required we could
- * do a suspend/update/resume), however it seems there might be issues
- * with the update llcmd on some cards (including those using an XSL on
- * an ASIC) so for now it's safest to go with the commands that are
- * known to work. In the future if we come across a situation where the
- * card may be performing transactions using the same PE while we are
- * doing this update we might need to revisit this.
- */
- if (need_update)
- WARN_ON(add_process_element(ctx));
-}
-
-static int process_element_entry_psl9(struct cxl_context *ctx, u64 wed, u64 amr)
-{
- u32 pid;
- int rc;
-
- cxl_assign_psn_space(ctx);
-
- ctx->elem->ctxtime = 0; /* disable */
- ctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));
- ctx->elem->haurp = 0; /* disable */
-
- if (ctx->kernel)
- pid = 0;
- else {
- if (ctx->mm == NULL) {
- pr_devel("%s: unable to get mm for pe=%d pid=%i\n",
- __func__, ctx->pe, pid_nr(ctx->pid));
- return -EINVAL;
- }
- pid = ctx->mm->context.id;
- }
-
- /* Assign a unique TIDR (thread id) for the current thread */
- if (!(ctx->tidr) && (ctx->assign_tidr)) {
- rc = set_thread_tidr(current);
- if (rc)
- return -ENODEV;
- ctx->tidr = current->thread.tidr;
- pr_devel("%s: current tidr: %d\n", __func__, ctx->tidr);
- }
-
- ctx->elem->common.tid = cpu_to_be32(ctx->tidr);
- ctx->elem->common.pid = cpu_to_be32(pid);
-
- ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
-
- ctx->elem->common.csrp = 0; /* disable */
-
- cxl_prefault(ctx, wed);
-
- /*
- * Ensure we have the multiplexed PSL interrupt set up to take faults
- * for kernel contexts that may not have allocated any AFU IRQs at all:
- */
- if (ctx->irqs.range[0] == 0) {
- ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq;
- ctx->irqs.range[0] = 1;
- }
-
- ctx->elem->common.amr = cpu_to_be64(amr);
- ctx->elem->common.wed = cpu_to_be64(wed);
-
- return 0;
-}
-
-int cxl_attach_afu_directed_psl9(struct cxl_context *ctx, u64 wed, u64 amr)
-{
- int result;
-
- /* fill the process element entry */
- result = process_element_entry_psl9(ctx, wed, amr);
- if (result)
- return result;
-
- update_ivtes_directed(ctx);
-
- /* first guy needs to enable */
- result = cxl_ops->afu_check_and_enable(ctx->afu);
- if (result)
- return result;
-
- return add_process_element(ctx);
-}
-
-int cxl_attach_afu_directed_psl8(struct cxl_context *ctx, u64 wed, u64 amr)
-{
- u32 pid;
- int result;
-
- cxl_assign_psn_space(ctx);
-
- ctx->elem->ctxtime = 0; /* disable */
- ctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));
- ctx->elem->haurp = 0; /* disable */
- ctx->elem->u.sdr = cpu_to_be64(mfspr(SPRN_SDR1));
-
- pid = current->pid;
- if (ctx->kernel)
- pid = 0;
- ctx->elem->common.tid = 0;
- ctx->elem->common.pid = cpu_to_be32(pid);
-
- ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
-
- ctx->elem->common.csrp = 0; /* disable */
- ctx->elem->common.u.psl8.aurp0 = 0; /* disable */
- ctx->elem->common.u.psl8.aurp1 = 0; /* disable */
-
- cxl_prefault(ctx, wed);
-
- ctx->elem->common.u.psl8.sstp0 = cpu_to_be64(ctx->sstp0);
- ctx->elem->common.u.psl8.sstp1 = cpu_to_be64(ctx->sstp1);
-
- /*
- * Ensure we have the multiplexed PSL interrupt set up to take faults
- * for kernel contexts that may not have allocated any AFU IRQs at all:
- */
- if (ctx->irqs.range[0] == 0) {
- ctx->irqs.offset[0] = ctx->afu->native->psl_hwirq;
- ctx->irqs.range[0] = 1;
- }
-
- update_ivtes_directed(ctx);
-
- ctx->elem->common.amr = cpu_to_be64(amr);
- ctx->elem->common.wed = cpu_to_be64(wed);
-
- /* first guy needs to enable */
- if ((result = cxl_ops->afu_check_and_enable(ctx->afu)))
- return result;
-
- return add_process_element(ctx);
-}
-
-static int deactivate_afu_directed(struct cxl_afu *afu)
-{
- dev_info(&afu->dev, "Deactivating AFU directed mode\n");
-
- afu->current_mode = 0;
- afu->num_procs = 0;
-
- cxl_sysfs_afu_m_remove(afu);
- cxl_chardev_afu_remove(afu);
-
- /*
- * The CAIA section 2.2.1 indicates that the procedure for starting and
- * stopping an AFU in AFU directed mode is AFU specific, which is not
- * ideal since this code is generic and with one exception has no
- * knowledge of the AFU. This is in contrast to the procedure for
- * disabling a dedicated process AFU, which is documented to just
- * require a reset. The architecture does indicate that both an AFU
- * reset and an AFU disable should result in the AFU being disabled and
- * we do both followed by a PSL purge for safety.
- *
- * Notably we used to have some issues with the disable sequence on PSL
- * cards, which is why we ended up using this heavy weight procedure in
- * the first place, however a bug was discovered that had rendered the
- * disable operation ineffective, so it is conceivable that was the
- * sole explanation for those difficulties. Careful regression testing
- * is recommended if anyone attempts to remove or reorder these
- * operations.
- *
- * The XSL on the Mellanox CX4 behaves a little differently from the
- * PSL based cards and will time out an AFU reset if the AFU is still
- * enabled. That card is special in that we do have a means to identify
- * it from this code, so in that case we skip the reset and just use a
- * disable/purge to avoid the timeout and corresponding noise in the
- * kernel log.
- */
- if (afu->adapter->native->sl_ops->needs_reset_before_disable)
- cxl_ops->afu_reset(afu);
- cxl_afu_disable(afu);
- cxl_psl_purge(afu);
-
- return 0;
-}
-
-int cxl_activate_dedicated_process_psl9(struct cxl_afu *afu)
-{
- dev_info(&afu->dev, "Activating dedicated process mode\n");
-
- /*
- * If XSL is set to dedicated mode (Set in PSL_SCNTL reg), the
- * XSL and AFU are programmed to work with a single context.
- * The context information should be configured in the SPA area
- * index 0 (so PSL_SPAP must be configured before enabling the
- * AFU).
- */
- afu->num_procs = 1;
- if (afu->native->spa == NULL) {
- if (cxl_alloc_spa(afu, CXL_MODE_DEDICATED))
- return -ENOMEM;
- }
- attach_spa(afu);
-
- cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_Process);
- cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
-
- afu->current_mode = CXL_MODE_DEDICATED;
-
- return cxl_chardev_d_afu_add(afu);
-}
-
-int cxl_activate_dedicated_process_psl8(struct cxl_afu *afu)
-{
- dev_info(&afu->dev, "Activating dedicated process mode\n");
-
- cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_Process);
-
- cxl_p1n_write(afu, CXL_PSL_CtxTime_An, 0); /* disable */
- cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0); /* disable */
- cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
- cxl_p1n_write(afu, CXL_PSL_LPID_An, mfspr(SPRN_LPID));
- cxl_p1n_write(afu, CXL_HAURP_An, 0); /* disable */
- cxl_p1n_write(afu, CXL_PSL_SDR_An, mfspr(SPRN_SDR1));
-
- cxl_p2n_write(afu, CXL_CSRP_An, 0); /* disable */
- cxl_p2n_write(afu, CXL_AURP0_An, 0); /* disable */
- cxl_p2n_write(afu, CXL_AURP1_An, 0); /* disable */
-
- afu->current_mode = CXL_MODE_DEDICATED;
- afu->num_procs = 1;
-
- return cxl_chardev_d_afu_add(afu);
-}
-
-void cxl_update_dedicated_ivtes_psl9(struct cxl_context *ctx)
-{
- int r;
-
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- ctx->elem->ivte_offsets[r] = cpu_to_be16(ctx->irqs.offset[r]);
- ctx->elem->ivte_ranges[r] = cpu_to_be16(ctx->irqs.range[r]);
- }
-}
-
-void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx)
-{
- struct cxl_afu *afu = ctx->afu;
-
- cxl_p1n_write(afu, CXL_PSL_IVTE_Offset_An,
- (((u64)ctx->irqs.offset[0] & 0xffff) << 48) |
- (((u64)ctx->irqs.offset[1] & 0xffff) << 32) |
- (((u64)ctx->irqs.offset[2] & 0xffff) << 16) |
- ((u64)ctx->irqs.offset[3] & 0xffff));
- cxl_p1n_write(afu, CXL_PSL_IVTE_Limit_An, (u64)
- (((u64)ctx->irqs.range[0] & 0xffff) << 48) |
- (((u64)ctx->irqs.range[1] & 0xffff) << 32) |
- (((u64)ctx->irqs.range[2] & 0xffff) << 16) |
- ((u64)ctx->irqs.range[3] & 0xffff));
-}
-
-int cxl_attach_dedicated_process_psl9(struct cxl_context *ctx, u64 wed, u64 amr)
-{
- struct cxl_afu *afu = ctx->afu;
- int result;
-
- /* fill the process element entry */
- result = process_element_entry_psl9(ctx, wed, amr);
- if (result)
- return result;
-
- if (ctx->afu->adapter->native->sl_ops->update_dedicated_ivtes)
- afu->adapter->native->sl_ops->update_dedicated_ivtes(ctx);
-
- ctx->elem->software_state = cpu_to_be32(CXL_PE_SOFTWARE_STATE_V);
- /*
- * Ideally we should do a wmb() here to make sure the changes to the
- * PE are visible to the card before we call afu_enable.
- * On ppc64 though all mmios are preceded by a 'sync' instruction hence
- * we dont dont need one here.
- */
-
- result = cxl_ops->afu_reset(afu);
- if (result)
- return result;
-
- return afu_enable(afu);
-}
-
-int cxl_attach_dedicated_process_psl8(struct cxl_context *ctx, u64 wed, u64 amr)
-{
- struct cxl_afu *afu = ctx->afu;
- u64 pid;
- int rc;
-
- pid = (u64)current->pid << 32;
- if (ctx->kernel)
- pid = 0;
- cxl_p2n_write(afu, CXL_PSL_PID_TID_An, pid);
-
- cxl_p1n_write(afu, CXL_PSL_SR_An, calculate_sr(ctx));
-
- if ((rc = cxl_write_sstp(afu, ctx->sstp0, ctx->sstp1)))
- return rc;
-
- cxl_prefault(ctx, wed);
-
- if (ctx->afu->adapter->native->sl_ops->update_dedicated_ivtes)
- afu->adapter->native->sl_ops->update_dedicated_ivtes(ctx);
-
- cxl_p2n_write(afu, CXL_PSL_AMR_An, amr);
-
- /* master only context for dedicated */
- cxl_assign_psn_space(ctx);
-
- if ((rc = cxl_ops->afu_reset(afu)))
- return rc;
-
- cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
-
- return afu_enable(afu);
-}
-
-static int deactivate_dedicated_process(struct cxl_afu *afu)
-{
- dev_info(&afu->dev, "Deactivating dedicated process mode\n");
-
- afu->current_mode = 0;
- afu->num_procs = 0;
-
- cxl_chardev_afu_remove(afu);
-
- return 0;
-}
-
-static int native_afu_deactivate_mode(struct cxl_afu *afu, int mode)
-{
- if (mode == CXL_MODE_DIRECTED)
- return deactivate_afu_directed(afu);
- if (mode == CXL_MODE_DEDICATED)
- return deactivate_dedicated_process(afu);
- return 0;
-}
-
-static int native_afu_activate_mode(struct cxl_afu *afu, int mode)
-{
- if (!mode)
- return 0;
- if (!(mode & afu->modes_supported))
- return -EINVAL;
-
- if (!cxl_ops->link_ok(afu->adapter, afu)) {
- WARN(1, "Device link is down, refusing to activate!\n");
- return -EIO;
- }
-
- if (mode == CXL_MODE_DIRECTED)
- return activate_afu_directed(afu);
- if ((mode == CXL_MODE_DEDICATED) &&
- (afu->adapter->native->sl_ops->activate_dedicated_process))
- return afu->adapter->native->sl_ops->activate_dedicated_process(afu);
-
- return -EINVAL;
-}
-
-static int native_attach_process(struct cxl_context *ctx, bool kernel,
- u64 wed, u64 amr)
-{
- if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
- WARN(1, "Device link is down, refusing to attach process!\n");
- return -EIO;
- }
-
- ctx->kernel = kernel;
- if ((ctx->afu->current_mode == CXL_MODE_DIRECTED) &&
- (ctx->afu->adapter->native->sl_ops->attach_afu_directed))
- return ctx->afu->adapter->native->sl_ops->attach_afu_directed(ctx, wed, amr);
-
- if ((ctx->afu->current_mode == CXL_MODE_DEDICATED) &&
- (ctx->afu->adapter->native->sl_ops->attach_dedicated_process))
- return ctx->afu->adapter->native->sl_ops->attach_dedicated_process(ctx, wed, amr);
-
- return -EINVAL;
-}
-
-static inline int detach_process_native_dedicated(struct cxl_context *ctx)
-{
- /*
- * The CAIA section 2.1.1 indicates that we need to do an AFU reset to
- * stop the AFU in dedicated mode (we therefore do not make that
- * optional like we do in the afu directed path). It does not indicate
- * that we need to do an explicit disable (which should occur
- * implicitly as part of the reset) or purge, but we do these as well
- * to be on the safe side.
- *
- * Notably we used to have some issues with the disable sequence
- * (before the sequence was spelled out in the architecture) which is
- * why we were so heavy weight in the first place, however a bug was
- * discovered that had rendered the disable operation ineffective, so
- * it is conceivable that was the sole explanation for those
- * difficulties. Point is, we should be careful and do some regression
- * testing if we ever attempt to remove any part of this procedure.
- */
- cxl_ops->afu_reset(ctx->afu);
- cxl_afu_disable(ctx->afu);
- cxl_psl_purge(ctx->afu);
- return 0;
-}
-
-static void native_update_ivtes(struct cxl_context *ctx)
-{
- if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
- return update_ivtes_directed(ctx);
- if ((ctx->afu->current_mode == CXL_MODE_DEDICATED) &&
- (ctx->afu->adapter->native->sl_ops->update_dedicated_ivtes))
- return ctx->afu->adapter->native->sl_ops->update_dedicated_ivtes(ctx);
- WARN(1, "native_update_ivtes: Bad mode\n");
-}
-
-static inline int detach_process_native_afu_directed(struct cxl_context *ctx)
-{
- if (!ctx->pe_inserted)
- return 0;
- if (terminate_process_element(ctx))
- return -1;
- if (remove_process_element(ctx))
- return -1;
-
- return 0;
-}
-
-static int native_detach_process(struct cxl_context *ctx)
-{
- trace_cxl_detach(ctx);
-
- if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
- return detach_process_native_dedicated(ctx);
-
- return detach_process_native_afu_directed(ctx);
-}
-
-static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)
-{
- /* If the adapter has gone away, we can't get any meaningful
- * information.
- */
- if (!cxl_ops->link_ok(afu->adapter, afu))
- return -EIO;
-
- info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- info->dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
- if (cxl_is_power8())
- info->dsr = cxl_p2n_read(afu, CXL_PSL_DSR_An);
- info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An);
- info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
- info->proc_handle = 0;
-
- return 0;
-}
-
-void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx)
-{
- u64 fir1, serr;
-
- fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL9_FIR1);
-
- dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
- if (ctx->afu->adapter->native->sl_ops->register_serr_irq) {
- serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
- cxl_afu_decode_psl_serr(ctx->afu, serr);
- }
-}
-
-void cxl_native_irq_dump_regs_psl8(struct cxl_context *ctx)
-{
- u64 fir1, fir2, fir_slice, serr, afu_debug;
-
- fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1);
- fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
- fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
- afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
-
- dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
- dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
- if (ctx->afu->adapter->native->sl_ops->register_serr_irq) {
- serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
- cxl_afu_decode_psl_serr(ctx->afu, serr);
- }
- dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
- dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
-}
-
-static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
- u64 dsisr, u64 errstat)
-{
-
- dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
-
- if (ctx->afu->adapter->native->sl_ops->psl_irq_dump_registers)
- ctx->afu->adapter->native->sl_ops->psl_irq_dump_registers(ctx);
-
- if (ctx->afu->adapter->native->sl_ops->debugfs_stop_trace) {
- dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
- ctx->afu->adapter->native->sl_ops->debugfs_stop_trace(ctx->afu->adapter);
- }
-
- return cxl_ops->ack_irq(ctx, 0, errstat);
-}
-
-static bool cxl_is_translation_fault(struct cxl_afu *afu, u64 dsisr)
-{
- if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_TRANS))
- return true;
-
- if ((cxl_is_power9()) && (dsisr & CXL_PSL9_DSISR_An_TF))
- return true;
-
- return false;
-}
-
-irqreturn_t cxl_fail_irq_psl(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
-{
- if (cxl_is_translation_fault(afu, irq_info->dsisr))
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
- else
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t native_irq_multiplexed(int irq, void *data)
-{
- struct cxl_afu *afu = data;
- struct cxl_context *ctx;
- struct cxl_irq_info irq_info;
- u64 phreg = cxl_p2n_read(afu, CXL_PSL_PEHandle_An);
- int ph, ret = IRQ_HANDLED, res;
-
- /* check if eeh kicked in while the interrupt was in flight */
- if (unlikely(phreg == ~0ULL)) {
- dev_warn(&afu->dev,
- "Ignoring slice interrupt(%d) due to fenced card",
- irq);
- return IRQ_HANDLED;
- }
- /* Mask the pe-handle from register value */
- ph = phreg & 0xffff;
- if ((res = native_get_irq_info(afu, &irq_info))) {
- WARN(1, "Unable to get CXL IRQ Info: %i\n", res);
- if (afu->adapter->native->sl_ops->fail_irq)
- return afu->adapter->native->sl_ops->fail_irq(afu, &irq_info);
- return ret;
- }
-
- rcu_read_lock();
- ctx = idr_find(&afu->contexts_idr, ph);
- if (ctx) {
- if (afu->adapter->native->sl_ops->handle_interrupt)
- ret = afu->adapter->native->sl_ops->handle_interrupt(irq, ctx, &irq_info);
- rcu_read_unlock();
- return ret;
- }
- rcu_read_unlock();
-
- WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR"
- " %016llx\n(Possible AFU HW issue - was a term/remove acked"
- " with outstanding transactions?)\n", ph, irq_info.dsisr,
- irq_info.dar);
- if (afu->adapter->native->sl_ops->fail_irq)
- ret = afu->adapter->native->sl_ops->fail_irq(afu, &irq_info);
- return ret;
-}
-
-static void native_irq_wait(struct cxl_context *ctx)
-{
- u64 dsisr;
- int timeout = 1000;
- int ph;
-
- /*
- * Wait until no further interrupts are presented by the PSL
- * for this context.
- */
- while (timeout--) {
- ph = cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) & 0xffff;
- if (ph != ctx->pe)
- return;
- dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An);
- if (cxl_is_power8() &&
- ((dsisr & CXL_PSL_DSISR_PENDING) == 0))
- return;
- if (cxl_is_power9() &&
- ((dsisr & CXL_PSL9_DSISR_PENDING) == 0))
- return;
- /*
- * We are waiting for the workqueue to process our
- * irq, so need to let that run here.
- */
- msleep(1);
- }
-
- dev_warn(&ctx->afu->dev, "WARNING: waiting on DSI for PE %i"
- " DSISR %016llx!\n", ph, dsisr);
- return;
-}
-
-static irqreturn_t native_slice_irq_err(int irq, void *data)
-{
- struct cxl_afu *afu = data;
- u64 errstat, serr, afu_error, dsisr;
- u64 fir_slice, afu_debug, irq_mask;
-
- /*
- * slice err interrupt is only used with full PSL (no XSL)
- */
- serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
- errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
- afu_error = cxl_p2n_read(afu, CXL_AFU_ERR_An);
- dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- cxl_afu_decode_psl_serr(afu, serr);
-
- if (cxl_is_power8()) {
- fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An);
- afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An);
- dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
- dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
- }
- dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat);
- dev_crit(&afu->dev, "AFU_ERR_An: 0x%.16llx\n", afu_error);
- dev_crit(&afu->dev, "PSL_DSISR_An: 0x%.16llx\n", dsisr);
-
- /* mask off the IRQ so it won't retrigger until the AFU is reset */
- irq_mask = (serr & CXL_PSL_SERR_An_IRQS) >> 32;
- serr |= irq_mask;
- cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
- dev_info(&afu->dev, "Further such interrupts will be masked until the AFU is reset\n");
-
- return IRQ_HANDLED;
-}
-
-void cxl_native_err_irq_dump_regs_psl9(struct cxl *adapter)
-{
- u64 fir1;
-
- fir1 = cxl_p1_read(adapter, CXL_PSL9_FIR1);
- dev_crit(&adapter->dev, "PSL_FIR: 0x%016llx\n", fir1);
-}
-
-void cxl_native_err_irq_dump_regs_psl8(struct cxl *adapter)
-{
- u64 fir1, fir2;
-
- fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
- fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
- dev_crit(&adapter->dev,
- "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n",
- fir1, fir2);
-}
-
-static irqreturn_t native_irq_err(int irq, void *data)
-{
- struct cxl *adapter = data;
- u64 err_ivte;
-
- WARN(1, "CXL ERROR interrupt %i\n", irq);
-
- err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
- dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
-
- if (adapter->native->sl_ops->debugfs_stop_trace) {
- dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
- adapter->native->sl_ops->debugfs_stop_trace(adapter);
- }
-
- if (adapter->native->sl_ops->err_irq_dump_registers)
- adapter->native->sl_ops->err_irq_dump_registers(adapter);
-
- return IRQ_HANDLED;
-}
-
-int cxl_native_register_psl_err_irq(struct cxl *adapter)
-{
- int rc;
-
- adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
- dev_name(&adapter->dev));
- if (!adapter->irq_name)
- return -ENOMEM;
-
- if ((rc = cxl_register_one_irq(adapter, native_irq_err, adapter,
- &adapter->native->err_hwirq,
- &adapter->native->err_virq,
- adapter->irq_name))) {
- kfree(adapter->irq_name);
- adapter->irq_name = NULL;
- return rc;
- }
-
- cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->native->err_hwirq & 0xffff);
-
- return 0;
-}
-
-void cxl_native_release_psl_err_irq(struct cxl *adapter)
-{
- if (adapter->native->err_virq == 0 ||
- adapter->native->err_virq !=
- irq_find_mapping(NULL, adapter->native->err_hwirq))
- return;
-
- cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
- cxl_unmap_irq(adapter->native->err_virq, adapter);
- cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);
- kfree(adapter->irq_name);
- adapter->native->err_virq = 0;
-}
-
-int cxl_native_register_serr_irq(struct cxl_afu *afu)
-{
- u64 serr;
- int rc;
-
- afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
- dev_name(&afu->dev));
- if (!afu->err_irq_name)
- return -ENOMEM;
-
- if ((rc = cxl_register_one_irq(afu->adapter, native_slice_irq_err, afu,
- &afu->serr_hwirq,
- &afu->serr_virq, afu->err_irq_name))) {
- kfree(afu->err_irq_name);
- afu->err_irq_name = NULL;
- return rc;
- }
-
- serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
- if (cxl_is_power8())
- serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
- if (cxl_is_power9()) {
- /*
- * By default, all errors are masked. So don't set all masks.
- * Slice errors will be transfered.
- */
- serr = (serr & ~0xff0000007fffffffULL) | (afu->serr_hwirq & 0xffff);
- }
- cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
-
- return 0;
-}
-
-void cxl_native_release_serr_irq(struct cxl_afu *afu)
-{
- if (afu->serr_virq == 0 ||
- afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
- return;
-
- cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
- cxl_unmap_irq(afu->serr_virq, afu);
- cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
- kfree(afu->err_irq_name);
- afu->serr_virq = 0;
-}
-
-int cxl_native_register_psl_irq(struct cxl_afu *afu)
-{
- int rc;
-
- afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
- dev_name(&afu->dev));
- if (!afu->psl_irq_name)
- return -ENOMEM;
-
- if ((rc = cxl_register_one_irq(afu->adapter, native_irq_multiplexed,
- afu, &afu->native->psl_hwirq, &afu->native->psl_virq,
- afu->psl_irq_name))) {
- kfree(afu->psl_irq_name);
- afu->psl_irq_name = NULL;
- }
- return rc;
-}
-
-void cxl_native_release_psl_irq(struct cxl_afu *afu)
-{
- if (afu->native->psl_virq == 0 ||
- afu->native->psl_virq !=
- irq_find_mapping(NULL, afu->native->psl_hwirq))
- return;
-
- cxl_unmap_irq(afu->native->psl_virq, afu);
- cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);
- kfree(afu->psl_irq_name);
- afu->native->psl_virq = 0;
-}
-
-static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
-{
- u64 dsisr;
-
- pr_devel("RECOVERING FROM PSL ERROR... (0x%016llx)\n", errstat);
-
- /* Clear PSL_DSISR[PE] */
- dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- cxl_p2n_write(afu, CXL_PSL_DSISR_An, dsisr & ~CXL_PSL_DSISR_An_PE);
-
- /* Write 1s to clear error status bits */
- cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
-}
-
-static int native_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
-{
- trace_cxl_psl_irq_ack(ctx, tfc);
- if (tfc)
- cxl_p2n_write(ctx->afu, CXL_PSL_TFC_An, tfc);
- if (psl_reset_mask)
- recover_psl_err(ctx->afu, psl_reset_mask);
-
- return 0;
-}
-
-int cxl_check_error(struct cxl_afu *afu)
-{
- return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
-}
-
-static bool native_support_attributes(const char *attr_name,
- enum cxl_attrs type)
-{
- return true;
-}
-
-static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
-{
- if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
- return -EIO;
- if (unlikely(off >= afu->crs_len))
- return -ERANGE;
- *out = in_le64(afu->native->afu_desc_mmio + afu->crs_offset +
- (cr * afu->crs_len) + off);
- return 0;
-}
-
-static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
-{
- if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
- return -EIO;
- if (unlikely(off >= afu->crs_len))
- return -ERANGE;
- *out = in_le32(afu->native->afu_desc_mmio + afu->crs_offset +
- (cr * afu->crs_len) + off);
- return 0;
-}
-
-static int native_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out)
-{
- u64 aligned_off = off & ~0x3L;
- u32 val;
- int rc;
-
- rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
- if (!rc)
- *out = (val >> ((off & 0x3) * 8)) & 0xffff;
- return rc;
-}
-
-static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
-{
- u64 aligned_off = off & ~0x3L;
- u32 val;
- int rc;
-
- rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
- if (!rc)
- *out = (val >> ((off & 0x3) * 8)) & 0xff;
- return rc;
-}
-
-static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
-{
- if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
- return -EIO;
- if (unlikely(off >= afu->crs_len))
- return -ERANGE;
- out_le32(afu->native->afu_desc_mmio + afu->crs_offset +
- (cr * afu->crs_len) + off, in);
- return 0;
-}
-
-static int native_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
-{
- u64 aligned_off = off & ~0x3L;
- u32 val32, mask, shift;
- int rc;
-
- rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
- if (rc)
- return rc;
- shift = (off & 0x3) * 8;
- WARN_ON(shift == 24);
- mask = 0xffff << shift;
- val32 = (val32 & ~mask) | (in << shift);
-
- rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
- return rc;
-}
-
-static int native_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
-{
- u64 aligned_off = off & ~0x3L;
- u32 val32, mask, shift;
- int rc;
-
- rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
- if (rc)
- return rc;
- shift = (off & 0x3) * 8;
- mask = 0xff << shift;
- val32 = (val32 & ~mask) | (in << shift);
-
- rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
- return rc;
-}
-
-const struct cxl_backend_ops cxl_native_ops = {
- .module = THIS_MODULE,
- .adapter_reset = cxl_pci_reset,
- .alloc_one_irq = cxl_pci_alloc_one_irq,
- .release_one_irq = cxl_pci_release_one_irq,
- .alloc_irq_ranges = cxl_pci_alloc_irq_ranges,
- .release_irq_ranges = cxl_pci_release_irq_ranges,
- .setup_irq = cxl_pci_setup_irq,
- .handle_psl_slice_error = native_handle_psl_slice_error,
- .psl_interrupt = NULL,
- .ack_irq = native_ack_irq,
- .irq_wait = native_irq_wait,
- .attach_process = native_attach_process,
- .detach_process = native_detach_process,
- .update_ivtes = native_update_ivtes,
- .support_attributes = native_support_attributes,
- .link_ok = cxl_adapter_link_ok,
- .release_afu = cxl_pci_release_afu,
- .afu_read_err_buffer = cxl_pci_afu_read_err_buffer,
- .afu_check_and_enable = native_afu_check_and_enable,
- .afu_activate_mode = native_afu_activate_mode,
- .afu_deactivate_mode = native_afu_deactivate_mode,
- .afu_reset = native_afu_reset,
- .afu_cr_read8 = native_afu_cr_read8,
- .afu_cr_read16 = native_afu_cr_read16,
- .afu_cr_read32 = native_afu_cr_read32,
- .afu_cr_read64 = native_afu_cr_read64,
- .afu_cr_write8 = native_afu_cr_write8,
- .afu_cr_write16 = native_afu_cr_write16,
- .afu_cr_write32 = native_afu_cr_write32,
- .read_adapter_vpd = cxl_pci_read_adapter_vpd,
-};
diff --git a/drivers/misc/cxl/of.c b/drivers/misc/cxl/of.c
deleted file mode 100644
index e26ee85279fa..000000000000
--- a/drivers/misc/cxl/of.c
+++ /dev/null
@@ -1,346 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2015 IBM Corp.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-
-#include "cxl.h"
-
-static int read_phys_addr(struct device_node *np, char *prop_name,
- struct cxl_afu *afu)
-{
- int i, len, entry_size, naddr, nsize, type;
- u64 addr, size;
- const __be32 *prop;
-
- naddr = of_n_addr_cells(np);
- nsize = of_n_size_cells(np);
-
- prop = of_get_property(np, prop_name, &len);
- if (prop) {
- entry_size = naddr + nsize;
- for (i = 0; i < (len / 4); i += entry_size, prop += entry_size) {
- type = be32_to_cpu(prop[0]);
- addr = of_read_number(prop, naddr);
- size = of_read_number(&prop[naddr], nsize);
- switch (type) {
- case 0: /* unit address */
- afu->guest->handle = addr;
- break;
- case 1: /* p2 area */
- afu->guest->p2n_phys += addr;
- afu->guest->p2n_size = size;
- break;
- case 2: /* problem state area */
- afu->psn_phys += addr;
- afu->adapter->ps_size = size;
- break;
- default:
- pr_err("Invalid address type %d found in %s property of AFU\n",
- type, prop_name);
- return -EINVAL;
- }
- }
- }
- return 0;
-}
-
-static int read_vpd(struct cxl *adapter, struct cxl_afu *afu)
-{
- char vpd[256];
- int rc;
- size_t len = sizeof(vpd);
-
- memset(vpd, 0, len);
-
- if (adapter)
- rc = cxl_guest_read_adapter_vpd(adapter, vpd, len);
- else
- rc = cxl_guest_read_afu_vpd(afu, vpd, len);
-
- if (rc > 0) {
- cxl_dump_debug_buffer(vpd, rc);
- rc = 0;
- }
- return rc;
-}
-
-int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np)
-{
- return of_property_read_reg(afu_np, 0, &afu->guest->handle, NULL);
-}
-
-int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *np)
-{
- int i, rc;
- u16 device_id, vendor_id;
- u32 val = 0, class_code;
-
- /* Properties are read in the same order as listed in PAPR */
-
- rc = read_phys_addr(np, "reg", afu);
- if (rc)
- return rc;
-
- rc = read_phys_addr(np, "assigned-addresses", afu);
- if (rc)
- return rc;
-
- if (afu->psn_phys == 0)
- afu->psa = false;
- else
- afu->psa = true;
-
- of_property_read_u32(np, "ibm,#processes", &afu->max_procs_virtualised);
-
- if (cxl_verbose)
- read_vpd(NULL, afu);
-
- of_property_read_u32(np, "ibm,max-ints-per-process", &afu->guest->max_ints);
- afu->irqs_max = afu->guest->max_ints;
-
- if (!of_property_read_u32(np, "ibm,min-ints-per-process", &afu->pp_irqs)) {
- /* One extra interrupt for the PSL interrupt is already
- * included. Remove it now to keep only AFU interrupts and
- * match the native case.
- */
- afu->pp_irqs--;
- }
-
- of_property_read_u64(np, "ibm,error-buffer-size", &afu->eb_len);
- afu->eb_offset = 0;
-
- of_property_read_u64(np, "ibm,config-record-size", &afu->crs_len);
- afu->crs_offset = 0;
-
- of_property_read_u32(np, "ibm,#config-records", &afu->crs_num);
-
- if (cxl_verbose) {
- for (i = 0; i < afu->crs_num; i++) {
- rc = cxl_ops->afu_cr_read16(afu, i, PCI_DEVICE_ID,
- &device_id);
- if (!rc)
- pr_info("record %d - device-id: %#x\n",
- i, device_id);
- rc = cxl_ops->afu_cr_read16(afu, i, PCI_VENDOR_ID,
- &vendor_id);
- if (!rc)
- pr_info("record %d - vendor-id: %#x\n",
- i, vendor_id);
- rc = cxl_ops->afu_cr_read32(afu, i, PCI_CLASS_REVISION,
- &class_code);
- if (!rc) {
- class_code >>= 8;
- pr_info("record %d - class-code: %#x\n",
- i, class_code);
- }
- }
- }
- /*
- * if "ibm,process-mmio" doesn't exist then per-process mmio is
- * not supported
- */
- val = 0;
- if (!of_property_read_u32(np, "ibm,process-mmio", &val) && val == 1)
- afu->pp_psa = true;
- else
- afu->pp_psa = false;
-
- if (!of_property_read_u32(np, "ibm,function-error-interrupt", &val))
- afu->serr_hwirq = val;
-
- pr_devel("AFU handle: %#llx\n", afu->guest->handle);
- pr_devel("p2n_phys: %#llx (size %#llx)\n",
- afu->guest->p2n_phys, afu->guest->p2n_size);
- pr_devel("psn_phys: %#llx (size %#llx)\n",
- afu->psn_phys, afu->adapter->ps_size);
- pr_devel("Max number of processes virtualised=%i\n",
- afu->max_procs_virtualised);
- pr_devel("Per-process irqs min=%i, max=%i\n", afu->pp_irqs,
- afu->irqs_max);
- pr_devel("Slice error interrupt=%#lx\n", afu->serr_hwirq);
-
- return 0;
-}
-
-static int read_adapter_irq_config(struct cxl *adapter, struct device_node *np)
-{
- const __be32 *ranges;
- int len, nranges, i;
- struct irq_avail *cur;
-
- ranges = of_get_property(np, "interrupt-ranges", &len);
- if (ranges == NULL || len < (2 * sizeof(int)))
- return -EINVAL;
-
- /*
- * encoded array of two cells per entry, each cell encoded as
- * with encode-int
- */
- nranges = len / (2 * sizeof(int));
- if (nranges == 0 || (nranges * 2 * sizeof(int)) != len)
- return -EINVAL;
-
- adapter->guest->irq_avail = kcalloc(nranges, sizeof(struct irq_avail),
- GFP_KERNEL);
- if (adapter->guest->irq_avail == NULL)
- return -ENOMEM;
-
- adapter->guest->irq_base_offset = be32_to_cpu(ranges[0]);
- for (i = 0; i < nranges; i++) {
- cur = &adapter->guest->irq_avail[i];
- cur->offset = be32_to_cpu(ranges[i * 2]);
- cur->range = be32_to_cpu(ranges[i * 2 + 1]);
- cur->bitmap = bitmap_zalloc(cur->range, GFP_KERNEL);
- if (cur->bitmap == NULL)
- goto err;
- if (cur->offset < adapter->guest->irq_base_offset)
- adapter->guest->irq_base_offset = cur->offset;
- if (cxl_verbose)
- pr_info("available IRQ range: %#lx-%#lx (%lu)\n",
- cur->offset, cur->offset + cur->range - 1,
- cur->range);
- }
- adapter->guest->irq_nranges = nranges;
- spin_lock_init(&adapter->guest->irq_alloc_lock);
-
- return 0;
-err:
- for (i--; i >= 0; i--) {
- cur = &adapter->guest->irq_avail[i];
- bitmap_free(cur->bitmap);
- }
- kfree(adapter->guest->irq_avail);
- adapter->guest->irq_avail = NULL;
- return -ENOMEM;
-}
-
-int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np)
-{
- return of_property_read_reg(np, 0, &adapter->guest->handle, NULL);
-}
-
-int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np)
-{
- int rc;
- const char *p;
- u32 val = 0;
-
- /* Properties are read in the same order as listed in PAPR */
-
- if ((rc = read_adapter_irq_config(adapter, np)))
- return rc;
-
- if (!of_property_read_u32(np, "ibm,caia-version", &val)) {
- adapter->caia_major = (val & 0xFF00) >> 8;
- adapter->caia_minor = val & 0xFF;
- }
-
- if (!of_property_read_u32(np, "ibm,psl-revision", &val))
- adapter->psl_rev = val;
-
- if (!of_property_read_string(np, "status", &p)) {
- adapter->guest->status = kasprintf(GFP_KERNEL, "%s", p);
- if (adapter->guest->status == NULL)
- return -ENOMEM;
- }
-
- if (!of_property_read_u32(np, "vendor-id", &val))
- adapter->guest->vendor = val;
-
- if (!of_property_read_u32(np, "device-id", &val))
- adapter->guest->device = val;
-
- if (!of_property_read_u32(np, "subsystem-vendor-id", &val))
- adapter->guest->subsystem_vendor = val;
-
- if (!of_property_read_u32(np, "subsystem-id", &val))
- adapter->guest->subsystem = val;
-
- if (cxl_verbose)
- read_vpd(adapter, NULL);
-
- return 0;
-}
-
-static void cxl_of_remove(struct platform_device *pdev)
-{
- struct cxl *adapter;
- int afu;
-
- adapter = dev_get_drvdata(&pdev->dev);
- for (afu = 0; afu < adapter->slices; afu++)
- cxl_guest_remove_afu(adapter->afu[afu]);
-
- cxl_guest_remove_adapter(adapter);
-}
-
-static void cxl_of_shutdown(struct platform_device *pdev)
-{
- cxl_of_remove(pdev);
-}
-
-int cxl_of_probe(struct platform_device *pdev)
-{
- struct device_node *np = NULL;
- struct device_node *afu_np = NULL;
- struct cxl *adapter = NULL;
- int ret;
- int slice = 0, slice_ok = 0;
-
- dev_err_once(&pdev->dev, "DEPRECATION: cxl is deprecated and will be removed in a future kernel release\n");
-
- pr_devel("in %s\n", __func__);
-
- np = pdev->dev.of_node;
- if (np == NULL)
- return -ENODEV;
-
- /* init adapter */
- adapter = cxl_guest_init_adapter(np, pdev);
- if (IS_ERR(adapter)) {
- dev_err(&pdev->dev, "guest_init_adapter failed: %li\n", PTR_ERR(adapter));
- return PTR_ERR(adapter);
- }
-
- /* init afu */
- for_each_child_of_node(np, afu_np) {
- if ((ret = cxl_guest_init_afu(adapter, slice, afu_np)))
- dev_err(&pdev->dev, "AFU %i failed to initialise: %i\n",
- slice, ret);
- else
- slice_ok++;
- slice++;
- }
-
- if (slice_ok == 0) {
- dev_info(&pdev->dev, "No active AFU");
- adapter->slices = 0;
- }
-
- return 0;
-}
-
-static const struct of_device_id cxl_of_match[] = {
- { .compatible = "ibm,coherent-platform-facility",},
- {},
-};
-MODULE_DEVICE_TABLE(of, cxl_of_match);
-
-struct platform_driver cxl_of_driver = {
- .driver = {
- .name = "cxl_of",
- .of_match_table = cxl_of_match,
- .owner = THIS_MODULE
- },
- .probe = cxl_of_probe,
- .remove = cxl_of_remove,
- .shutdown = cxl_of_shutdown,
-};
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
deleted file mode 100644
index 92bf7c5c7b35..000000000000
--- a/drivers/misc/cxl/pci.c
+++ /dev/null
@@ -1,2103 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/pci_regs.h>
-#include <linux/pci_ids.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sort.h>
-#include <linux/pci.h>
-#include <linux/of.h>
-#include <linux/delay.h>
-#include <asm/opal.h>
-#include <asm/msi_bitmap.h>
-#include <asm/pnv-pci.h>
-#include <asm/io.h>
-#include <asm/reg.h>
-
-#include "cxl.h"
-#include <misc/cxl.h>
-
-
-#define CXL_PCI_VSEC_ID 0x1280
-#define CXL_VSEC_MIN_SIZE 0x80
-
-#define CXL_READ_VSEC_LENGTH(dev, vsec, dest) \
- { \
- pci_read_config_word(dev, vsec + 0x6, dest); \
- *dest >>= 4; \
- }
-#define CXL_READ_VSEC_NAFUS(dev, vsec, dest) \
- pci_read_config_byte(dev, vsec + 0x8, dest)
-
-#define CXL_READ_VSEC_STATUS(dev, vsec, dest) \
- pci_read_config_byte(dev, vsec + 0x9, dest)
-#define CXL_STATUS_SECOND_PORT 0x80
-#define CXL_STATUS_MSI_X_FULL 0x40
-#define CXL_STATUS_MSI_X_SINGLE 0x20
-#define CXL_STATUS_FLASH_RW 0x08
-#define CXL_STATUS_FLASH_RO 0x04
-#define CXL_STATUS_LOADABLE_AFU 0x02
-#define CXL_STATUS_LOADABLE_PSL 0x01
-/* If we see these features we won't try to use the card */
-#define CXL_UNSUPPORTED_FEATURES \
- (CXL_STATUS_MSI_X_FULL | CXL_STATUS_MSI_X_SINGLE)
-
-#define CXL_READ_VSEC_MODE_CONTROL(dev, vsec, dest) \
- pci_read_config_byte(dev, vsec + 0xa, dest)
-#define CXL_WRITE_VSEC_MODE_CONTROL(dev, vsec, val) \
- pci_write_config_byte(dev, vsec + 0xa, val)
-#define CXL_VSEC_PROTOCOL_MASK 0xe0
-#define CXL_VSEC_PROTOCOL_1024TB 0x80
-#define CXL_VSEC_PROTOCOL_512TB 0x40
-#define CXL_VSEC_PROTOCOL_256TB 0x20 /* Power 8/9 uses this */
-#define CXL_VSEC_PROTOCOL_ENABLE 0x01
-
-#define CXL_READ_VSEC_PSL_REVISION(dev, vsec, dest) \
- pci_read_config_word(dev, vsec + 0xc, dest)
-#define CXL_READ_VSEC_CAIA_MINOR(dev, vsec, dest) \
- pci_read_config_byte(dev, vsec + 0xe, dest)
-#define CXL_READ_VSEC_CAIA_MAJOR(dev, vsec, dest) \
- pci_read_config_byte(dev, vsec + 0xf, dest)
-#define CXL_READ_VSEC_BASE_IMAGE(dev, vsec, dest) \
- pci_read_config_word(dev, vsec + 0x10, dest)
-
-#define CXL_READ_VSEC_IMAGE_STATE(dev, vsec, dest) \
- pci_read_config_byte(dev, vsec + 0x13, dest)
-#define CXL_WRITE_VSEC_IMAGE_STATE(dev, vsec, val) \
- pci_write_config_byte(dev, vsec + 0x13, val)
-#define CXL_VSEC_USER_IMAGE_LOADED 0x80 /* RO */
-#define CXL_VSEC_PERST_LOADS_IMAGE 0x20 /* RW */
-#define CXL_VSEC_PERST_SELECT_USER 0x10 /* RW */
-
-#define CXL_READ_VSEC_AFU_DESC_OFF(dev, vsec, dest) \
- pci_read_config_dword(dev, vsec + 0x20, dest)
-#define CXL_READ_VSEC_AFU_DESC_SIZE(dev, vsec, dest) \
- pci_read_config_dword(dev, vsec + 0x24, dest)
-#define CXL_READ_VSEC_PS_OFF(dev, vsec, dest) \
- pci_read_config_dword(dev, vsec + 0x28, dest)
-#define CXL_READ_VSEC_PS_SIZE(dev, vsec, dest) \
- pci_read_config_dword(dev, vsec + 0x2c, dest)
-
-
-/* This works a little different than the p1/p2 register accesses to make it
- * easier to pull out individual fields */
-#define AFUD_READ(afu, off) in_be64(afu->native->afu_desc_mmio + off)
-#define AFUD_READ_LE(afu, off) in_le64(afu->native->afu_desc_mmio + off)
-#define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit)))
-#define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be))
-
-#define AFUD_READ_INFO(afu) AFUD_READ(afu, 0x0)
-#define AFUD_NUM_INTS_PER_PROC(val) EXTRACT_PPC_BITS(val, 0, 15)
-#define AFUD_NUM_PROCS(val) EXTRACT_PPC_BITS(val, 16, 31)
-#define AFUD_NUM_CRS(val) EXTRACT_PPC_BITS(val, 32, 47)
-#define AFUD_MULTIMODE(val) EXTRACT_PPC_BIT(val, 48)
-#define AFUD_PUSH_BLOCK_TRANSFER(val) EXTRACT_PPC_BIT(val, 55)
-#define AFUD_DEDICATED_PROCESS(val) EXTRACT_PPC_BIT(val, 59)
-#define AFUD_AFU_DIRECTED(val) EXTRACT_PPC_BIT(val, 61)
-#define AFUD_TIME_SLICED(val) EXTRACT_PPC_BIT(val, 63)
-#define AFUD_READ_CR(afu) AFUD_READ(afu, 0x20)
-#define AFUD_CR_LEN(val) EXTRACT_PPC_BITS(val, 8, 63)
-#define AFUD_READ_CR_OFF(afu) AFUD_READ(afu, 0x28)
-#define AFUD_READ_PPPSA(afu) AFUD_READ(afu, 0x30)
-#define AFUD_PPPSA_PP(val) EXTRACT_PPC_BIT(val, 6)
-#define AFUD_PPPSA_PSA(val) EXTRACT_PPC_BIT(val, 7)
-#define AFUD_PPPSA_LEN(val) EXTRACT_PPC_BITS(val, 8, 63)
-#define AFUD_READ_PPPSA_OFF(afu) AFUD_READ(afu, 0x38)
-#define AFUD_READ_EB(afu) AFUD_READ(afu, 0x40)
-#define AFUD_EB_LEN(val) EXTRACT_PPC_BITS(val, 8, 63)
-#define AFUD_READ_EB_OFF(afu) AFUD_READ(afu, 0x48)
-
-static const struct pci_device_id cxl_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0477), },
- { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x044b), },
- { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x04cf), },
- { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0601), },
- { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0623), },
- { PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x0628), },
- { }
-};
-MODULE_DEVICE_TABLE(pci, cxl_pci_tbl);
-
-
-/*
- * Mostly using these wrappers to avoid confusion:
- * priv 1 is BAR2, while priv 2 is BAR0
- */
-static inline resource_size_t p1_base(struct pci_dev *dev)
-{
- return pci_resource_start(dev, 2);
-}
-
-static inline resource_size_t p1_size(struct pci_dev *dev)
-{
- return pci_resource_len(dev, 2);
-}
-
-static inline resource_size_t p2_base(struct pci_dev *dev)
-{
- return pci_resource_start(dev, 0);
-}
-
-static inline resource_size_t p2_size(struct pci_dev *dev)
-{
- return pci_resource_len(dev, 0);
-}
-
-static int find_cxl_vsec(struct pci_dev *dev)
-{
- return pci_find_vsec_capability(dev, PCI_VENDOR_ID_IBM, CXL_PCI_VSEC_ID);
-}
-
-static void dump_cxl_config_space(struct pci_dev *dev)
-{
- int vsec;
- u32 val;
-
- dev_info(&dev->dev, "dump_cxl_config_space\n");
-
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &val);
- dev_info(&dev->dev, "BAR0: %#.8x\n", val);
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &val);
- dev_info(&dev->dev, "BAR1: %#.8x\n", val);
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_2, &val);
- dev_info(&dev->dev, "BAR2: %#.8x\n", val);
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_3, &val);
- dev_info(&dev->dev, "BAR3: %#.8x\n", val);
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_4, &val);
- dev_info(&dev->dev, "BAR4: %#.8x\n", val);
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_5, &val);
- dev_info(&dev->dev, "BAR5: %#.8x\n", val);
-
- dev_info(&dev->dev, "p1 regs: %#llx, len: %#llx\n",
- p1_base(dev), p1_size(dev));
- dev_info(&dev->dev, "p2 regs: %#llx, len: %#llx\n",
- p2_base(dev), p2_size(dev));
- dev_info(&dev->dev, "BAR 4/5: %#llx, len: %#llx\n",
- pci_resource_start(dev, 4), pci_resource_len(dev, 4));
-
- if (!(vsec = find_cxl_vsec(dev)))
- return;
-
-#define show_reg(name, what) \
- dev_info(&dev->dev, "cxl vsec: %30s: %#x\n", name, what)
-
- pci_read_config_dword(dev, vsec + 0x0, &val);
- show_reg("Cap ID", (val >> 0) & 0xffff);
- show_reg("Cap Ver", (val >> 16) & 0xf);
- show_reg("Next Cap Ptr", (val >> 20) & 0xfff);
- pci_read_config_dword(dev, vsec + 0x4, &val);
- show_reg("VSEC ID", (val >> 0) & 0xffff);
- show_reg("VSEC Rev", (val >> 16) & 0xf);
- show_reg("VSEC Length", (val >> 20) & 0xfff);
- pci_read_config_dword(dev, vsec + 0x8, &val);
- show_reg("Num AFUs", (val >> 0) & 0xff);
- show_reg("Status", (val >> 8) & 0xff);
- show_reg("Mode Control", (val >> 16) & 0xff);
- show_reg("Reserved", (val >> 24) & 0xff);
- pci_read_config_dword(dev, vsec + 0xc, &val);
- show_reg("PSL Rev", (val >> 0) & 0xffff);
- show_reg("CAIA Ver", (val >> 16) & 0xffff);
- pci_read_config_dword(dev, vsec + 0x10, &val);
- show_reg("Base Image Rev", (val >> 0) & 0xffff);
- show_reg("Reserved", (val >> 16) & 0x0fff);
- show_reg("Image Control", (val >> 28) & 0x3);
- show_reg("Reserved", (val >> 30) & 0x1);
- show_reg("Image Loaded", (val >> 31) & 0x1);
-
- pci_read_config_dword(dev, vsec + 0x14, &val);
- show_reg("Reserved", val);
- pci_read_config_dword(dev, vsec + 0x18, &val);
- show_reg("Reserved", val);
- pci_read_config_dword(dev, vsec + 0x1c, &val);
- show_reg("Reserved", val);
-
- pci_read_config_dword(dev, vsec + 0x20, &val);
- show_reg("AFU Descriptor Offset", val);
- pci_read_config_dword(dev, vsec + 0x24, &val);
- show_reg("AFU Descriptor Size", val);
- pci_read_config_dword(dev, vsec + 0x28, &val);
- show_reg("Problem State Offset", val);
- pci_read_config_dword(dev, vsec + 0x2c, &val);
- show_reg("Problem State Size", val);
-
- pci_read_config_dword(dev, vsec + 0x30, &val);
- show_reg("Reserved", val);
- pci_read_config_dword(dev, vsec + 0x34, &val);
- show_reg("Reserved", val);
- pci_read_config_dword(dev, vsec + 0x38, &val);
- show_reg("Reserved", val);
- pci_read_config_dword(dev, vsec + 0x3c, &val);
- show_reg("Reserved", val);
-
- pci_read_config_dword(dev, vsec + 0x40, &val);
- show_reg("PSL Programming Port", val);
- pci_read_config_dword(dev, vsec + 0x44, &val);
- show_reg("PSL Programming Control", val);
-
- pci_read_config_dword(dev, vsec + 0x48, &val);
- show_reg("Reserved", val);
- pci_read_config_dword(dev, vsec + 0x4c, &val);
- show_reg("Reserved", val);
-
- pci_read_config_dword(dev, vsec + 0x50, &val);
- show_reg("Flash Address Register", val);
- pci_read_config_dword(dev, vsec + 0x54, &val);
- show_reg("Flash Size Register", val);
- pci_read_config_dword(dev, vsec + 0x58, &val);
- show_reg("Flash Status/Control Register", val);
- pci_read_config_dword(dev, vsec + 0x58, &val);
- show_reg("Flash Data Port", val);
-
-#undef show_reg
-}
-
-static void dump_afu_descriptor(struct cxl_afu *afu)
-{
- u64 val, afu_cr_num, afu_cr_off, afu_cr_len;
- int i;
-
-#define show_reg(name, what) \
- dev_info(&afu->dev, "afu desc: %30s: %#llx\n", name, what)
-
- val = AFUD_READ_INFO(afu);
- show_reg("num_ints_per_process", AFUD_NUM_INTS_PER_PROC(val));
- show_reg("num_of_processes", AFUD_NUM_PROCS(val));
- show_reg("num_of_afu_CRs", AFUD_NUM_CRS(val));
- show_reg("req_prog_mode", val & 0xffffULL);
- afu_cr_num = AFUD_NUM_CRS(val);
-
- val = AFUD_READ(afu, 0x8);
- show_reg("Reserved", val);
- val = AFUD_READ(afu, 0x10);
- show_reg("Reserved", val);
- val = AFUD_READ(afu, 0x18);
- show_reg("Reserved", val);
-
- val = AFUD_READ_CR(afu);
- show_reg("Reserved", (val >> (63-7)) & 0xff);
- show_reg("AFU_CR_len", AFUD_CR_LEN(val));
- afu_cr_len = AFUD_CR_LEN(val) * 256;
-
- val = AFUD_READ_CR_OFF(afu);
- afu_cr_off = val;
- show_reg("AFU_CR_offset", val);
-
- val = AFUD_READ_PPPSA(afu);
- show_reg("PerProcessPSA_control", (val >> (63-7)) & 0xff);
- show_reg("PerProcessPSA Length", AFUD_PPPSA_LEN(val));
-
- val = AFUD_READ_PPPSA_OFF(afu);
- show_reg("PerProcessPSA_offset", val);
-
- val = AFUD_READ_EB(afu);
- show_reg("Reserved", (val >> (63-7)) & 0xff);
- show_reg("AFU_EB_len", AFUD_EB_LEN(val));
-
- val = AFUD_READ_EB_OFF(afu);
- show_reg("AFU_EB_offset", val);
-
- for (i = 0; i < afu_cr_num; i++) {
- val = AFUD_READ_LE(afu, afu_cr_off + i * afu_cr_len);
- show_reg("CR Vendor", val & 0xffff);
- show_reg("CR Device", (val >> 16) & 0xffff);
- }
-#undef show_reg
-}
-
-#define P8_CAPP_UNIT0_ID 0xBA
-#define P8_CAPP_UNIT1_ID 0XBE
-#define P9_CAPP_UNIT0_ID 0xC0
-#define P9_CAPP_UNIT1_ID 0xE0
-
-static int get_phb_index(struct device_node *np, u32 *phb_index)
-{
- if (of_property_read_u32(np, "ibm,phb-index", phb_index))
- return -ENODEV;
- return 0;
-}
-
-static u64 get_capp_unit_id(struct device_node *np, u32 phb_index)
-{
- /*
- * POWER 8:
- * - For chips other than POWER8NVL, we only have CAPP 0,
- * irrespective of which PHB is used.
- * - For POWER8NVL, assume CAPP 0 is attached to PHB0 and
- * CAPP 1 is attached to PHB1.
- */
- if (cxl_is_power8()) {
- if (!pvr_version_is(PVR_POWER8NVL))
- return P8_CAPP_UNIT0_ID;
-
- if (phb_index == 0)
- return P8_CAPP_UNIT0_ID;
-
- if (phb_index == 1)
- return P8_CAPP_UNIT1_ID;
- }
-
- /*
- * POWER 9:
- * PEC0 (PHB0). Capp ID = CAPP0 (0b1100_0000)
- * PEC1 (PHB1 - PHB2). No capi mode
- * PEC2 (PHB3 - PHB4 - PHB5): Capi mode on PHB3 only. Capp ID = CAPP1 (0b1110_0000)
- */
- if (cxl_is_power9()) {
- if (phb_index == 0)
- return P9_CAPP_UNIT0_ID;
-
- if (phb_index == 3)
- return P9_CAPP_UNIT1_ID;
- }
-
- return 0;
-}
-
-int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
- u32 *phb_index, u64 *capp_unit_id)
-{
- int rc;
- struct device_node *np;
- u32 id;
-
- if (!(np = pnv_pci_get_phb_node(dev)))
- return -ENODEV;
-
- while (np && of_property_read_u32(np, "ibm,chip-id", &id))
- np = of_get_next_parent(np);
- if (!np)
- return -ENODEV;
-
- *chipid = id;
-
- rc = get_phb_index(np, phb_index);
- if (rc) {
- pr_err("cxl: invalid phb index\n");
- of_node_put(np);
- return rc;
- }
-
- *capp_unit_id = get_capp_unit_id(np, *phb_index);
- of_node_put(np);
- if (!*capp_unit_id) {
- pr_err("cxl: No capp unit found for PHB[%lld,%d]. Make sure the adapter is on a capi-compatible slot\n",
- *chipid, *phb_index);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static DEFINE_MUTEX(indications_mutex);
-
-static int get_phb_indications(struct pci_dev *dev, u64 *capiind, u64 *asnind,
- u64 *nbwind)
-{
- static u32 val[3];
- struct device_node *np;
-
- mutex_lock(&indications_mutex);
- if (!val[0]) {
- if (!(np = pnv_pci_get_phb_node(dev))) {
- mutex_unlock(&indications_mutex);
- return -ENODEV;
- }
-
- if (of_property_read_u32_array(np, "ibm,phb-indications", val, 3)) {
- val[2] = 0x0300UL; /* legacy values */
- val[1] = 0x0400UL;
- val[0] = 0x0200UL;
- }
- of_node_put(np);
- }
- *capiind = val[0];
- *asnind = val[1];
- *nbwind = val[2];
- mutex_unlock(&indications_mutex);
- return 0;
-}
-
-int cxl_get_xsl9_dsnctl(struct pci_dev *dev, u64 capp_unit_id, u64 *reg)
-{
- u64 xsl_dsnctl;
- u64 capiind, asnind, nbwind;
-
- /*
- * CAPI Identifier bits [0:7]
- * bit 61:60 MSI bits --> 0
- * bit 59 TVT selector --> 0
- */
- if (get_phb_indications(dev, &capiind, &asnind, &nbwind))
- return -ENODEV;
-
- /*
- * Tell XSL where to route data to.
- * The field chipid should match the PHB CAPI_CMPM register
- */
- xsl_dsnctl = (capiind << (63-15)); /* Bit 57 */
- xsl_dsnctl |= (capp_unit_id << (63-15));
-
- /* nMMU_ID Defaults to: b’000001001’*/
- xsl_dsnctl |= ((u64)0x09 << (63-28));
-
- /*
- * Used to identify CAPI packets which should be sorted into
- * the Non-Blocking queues by the PHB. This field should match
- * the PHB PBL_NBW_CMPM register
- * nbwind=0x03, bits [57:58], must include capi indicator.
- * Not supported on P9 DD1.
- */
- xsl_dsnctl |= (nbwind << (63-55));
-
- /*
- * Upper 16b address bits of ASB_Notify messages sent to the
- * system. Need to match the PHB’s ASN Compare/Mask Register.
- * Not supported on P9 DD1.
- */
- xsl_dsnctl |= asnind;
-
- *reg = xsl_dsnctl;
- return 0;
-}
-
-static int init_implementation_adapter_regs_psl9(struct cxl *adapter,
- struct pci_dev *dev)
-{
- u64 xsl_dsnctl, psl_fircntl;
- u64 chipid;
- u32 phb_index;
- u64 capp_unit_id;
- u64 psl_debug;
- int rc;
-
- rc = cxl_calc_capp_routing(dev, &chipid, &phb_index, &capp_unit_id);
- if (rc)
- return rc;
-
- rc = cxl_get_xsl9_dsnctl(dev, capp_unit_id, &xsl_dsnctl);
- if (rc)
- return rc;
-
- cxl_p1_write(adapter, CXL_XSL9_DSNCTL, xsl_dsnctl);
-
- /* Set fir_cntl to recommended value for production env */
- psl_fircntl = (0x2ULL << (63-3)); /* ce_report */
- psl_fircntl |= (0x1ULL << (63-6)); /* FIR_report */
- psl_fircntl |= 0x1ULL; /* ce_thresh */
- cxl_p1_write(adapter, CXL_PSL9_FIR_CNTL, psl_fircntl);
-
- /* Setup the PSL to transmit packets on the PCIe before the
- * CAPP is enabled. Make sure that CAPP virtual machines are disabled
- */
- cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0001001000012A10ULL);
-
- /*
- * A response to an ASB_Notify request is returned by the
- * system as an MMIO write to the address defined in
- * the PSL_TNR_ADDR register.
- * keep the Reset Value: 0x00020000E0000000
- */
-
- /* Enable XSL rty limit */
- cxl_p1_write(adapter, CXL_XSL9_DEF, 0x51F8000000000005ULL);
-
- /* Change XSL_INV dummy read threshold */
- cxl_p1_write(adapter, CXL_XSL9_INV, 0x0000040007FFC200ULL);
-
- if (phb_index == 3) {
- /* disable machines 31-47 and 20-27 for DMA */
- cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000FF3FFFF0000ULL);
- }
-
- /* Snoop machines */
- cxl_p1_write(adapter, CXL_PSL9_APCDEDALLOC, 0x800F000200000000ULL);
-
- /* Enable NORST and DD2 features */
- cxl_p1_write(adapter, CXL_PSL9_DEBUG, 0xC000000000000000ULL);
-
- /*
- * Check if PSL has data-cache. We need to flush adapter datacache
- * when as its about to be removed.
- */
- psl_debug = cxl_p1_read(adapter, CXL_PSL9_DEBUG);
- if (psl_debug & CXL_PSL_DEBUG_CDC) {
- dev_dbg(&dev->dev, "No data-cache present\n");
- adapter->native->no_data_cache = true;
- }
-
- return 0;
-}
-
-static int init_implementation_adapter_regs_psl8(struct cxl *adapter, struct pci_dev *dev)
-{
- u64 psl_dsnctl, psl_fircntl;
- u64 chipid;
- u32 phb_index;
- u64 capp_unit_id;
- int rc;
-
- rc = cxl_calc_capp_routing(dev, &chipid, &phb_index, &capp_unit_id);
- if (rc)
- return rc;
-
- psl_dsnctl = 0x0000900000000000ULL; /* pteupd ttype, scdone */
- psl_dsnctl |= (0x2ULL << (63-38)); /* MMIO hang pulse: 256 us */
- /* Tell PSL where to route data to */
- psl_dsnctl |= (chipid << (63-5));
- psl_dsnctl |= (capp_unit_id << (63-13));
-
- cxl_p1_write(adapter, CXL_PSL_DSNDCTL, psl_dsnctl);
- cxl_p1_write(adapter, CXL_PSL_RESLCKTO, 0x20000000200ULL);
- /* snoop write mask */
- cxl_p1_write(adapter, CXL_PSL_SNWRALLOC, 0x00000000FFFFFFFFULL);
- /* set fir_cntl to recommended value for production env */
- psl_fircntl = (0x2ULL << (63-3)); /* ce_report */
- psl_fircntl |= (0x1ULL << (63-6)); /* FIR_report */
- psl_fircntl |= 0x1ULL; /* ce_thresh */
- cxl_p1_write(adapter, CXL_PSL_FIR_CNTL, psl_fircntl);
- /* for debugging with trace arrays */
- cxl_p1_write(adapter, CXL_PSL_TRACE, 0x0000FF7C00000000ULL);
-
- return 0;
-}
-
-/* PSL */
-#define TBSYNC_CAL(n) (((u64)n & 0x7) << (63-3))
-#define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6))
-/* For the PSL this is a multiple for 0 < n <= 7: */
-#define PSL_2048_250MHZ_CYCLES 1
-
-static void write_timebase_ctrl_psl8(struct cxl *adapter)
-{
- cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT,
- TBSYNC_CNT(2 * PSL_2048_250MHZ_CYCLES));
-}
-
-static u64 timebase_read_psl9(struct cxl *adapter)
-{
- return cxl_p1_read(adapter, CXL_PSL9_Timebase);
-}
-
-static u64 timebase_read_psl8(struct cxl *adapter)
-{
- return cxl_p1_read(adapter, CXL_PSL_Timebase);
-}
-
-static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
-{
- struct device_node *np;
-
- adapter->psl_timebase_synced = false;
-
- if (!(np = pnv_pci_get_phb_node(dev)))
- return;
-
- /* Do not fail when CAPP timebase sync is not supported by OPAL */
- of_node_get(np);
- if (!of_property_present(np, "ibm,capp-timebase-sync")) {
- of_node_put(np);
- dev_info(&dev->dev, "PSL timebase inactive: OPAL support missing\n");
- return;
- }
- of_node_put(np);
-
- /*
- * Setup PSL Timebase Control and Status register
- * with the recommended Timebase Sync Count value
- */
- if (adapter->native->sl_ops->write_timebase_ctrl)
- adapter->native->sl_ops->write_timebase_ctrl(adapter);
-
- /* Enable PSL Timebase */
- cxl_p1_write(adapter, CXL_PSL_Control, 0x0000000000000000);
- cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb);
-
- return;
-}
-
-static int init_implementation_afu_regs_psl9(struct cxl_afu *afu)
-{
- return 0;
-}
-
-static int init_implementation_afu_regs_psl8(struct cxl_afu *afu)
-{
- /* read/write masks for this slice */
- cxl_p1n_write(afu, CXL_PSL_APCALLOC_A, 0xFFFFFFFEFEFEFEFEULL);
- /* APC read/write masks for this slice */
- cxl_p1n_write(afu, CXL_PSL_COALLOC_A, 0xFF000000FEFEFEFEULL);
- /* for debugging with trace arrays */
- cxl_p1n_write(afu, CXL_PSL_SLICE_TRACE, 0x0000FFFF00000000ULL);
- cxl_p1n_write(afu, CXL_PSL_RXCTL_A, CXL_PSL_RXCTL_AFUHP_4S);
-
- return 0;
-}
-
-int cxl_pci_setup_irq(struct cxl *adapter, unsigned int hwirq,
- unsigned int virq)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
-
- return pnv_cxl_ioda_msi_setup(dev, hwirq, virq);
-}
-
-int cxl_update_image_control(struct cxl *adapter)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
- int rc;
- int vsec;
- u8 image_state;
-
- if (!(vsec = find_cxl_vsec(dev))) {
- dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
- return -ENODEV;
- }
-
- if ((rc = CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state))) {
- dev_err(&dev->dev, "failed to read image state: %i\n", rc);
- return rc;
- }
-
- if (adapter->perst_loads_image)
- image_state |= CXL_VSEC_PERST_LOADS_IMAGE;
- else
- image_state &= ~CXL_VSEC_PERST_LOADS_IMAGE;
-
- if (adapter->perst_select_user)
- image_state |= CXL_VSEC_PERST_SELECT_USER;
- else
- image_state &= ~CXL_VSEC_PERST_SELECT_USER;
-
- if ((rc = CXL_WRITE_VSEC_IMAGE_STATE(dev, vsec, image_state))) {
- dev_err(&dev->dev, "failed to update image control: %i\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-int cxl_pci_alloc_one_irq(struct cxl *adapter)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
-
- return pnv_cxl_alloc_hwirqs(dev, 1);
-}
-
-void cxl_pci_release_one_irq(struct cxl *adapter, int hwirq)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
-
- return pnv_cxl_release_hwirqs(dev, hwirq, 1);
-}
-
-int cxl_pci_alloc_irq_ranges(struct cxl_irq_ranges *irqs,
- struct cxl *adapter, unsigned int num)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
-
- return pnv_cxl_alloc_hwirq_ranges(irqs, dev, num);
-}
-
-void cxl_pci_release_irq_ranges(struct cxl_irq_ranges *irqs,
- struct cxl *adapter)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
-
- pnv_cxl_release_hwirq_ranges(irqs, dev);
-}
-
-static int setup_cxl_bars(struct pci_dev *dev)
-{
- /* Safety check in case we get backported to < 3.17 without M64 */
- if ((p1_base(dev) < 0x100000000ULL) ||
- (p2_base(dev) < 0x100000000ULL)) {
- dev_err(&dev->dev, "ABORTING: M32 BAR assignment incompatible with CXL\n");
- return -ENODEV;
- }
-
- /*
- * BAR 4/5 has a special meaning for CXL and must be programmed with a
- * special value corresponding to the CXL protocol address range.
- * For POWER 8/9 that means bits 48:49 must be set to 10
- */
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_4, 0x00000000);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, 0x00020000);
-
- return 0;
-}
-
-/* pciex node: ibm,opal-m64-window = <0x3d058 0x0 0x3d058 0x0 0x8 0x0>; */
-static int switch_card_to_cxl(struct pci_dev *dev)
-{
- int vsec;
- u8 val;
- int rc;
-
- dev_info(&dev->dev, "switch card to CXL\n");
-
- if (!(vsec = find_cxl_vsec(dev))) {
- dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
- return -ENODEV;
- }
-
- if ((rc = CXL_READ_VSEC_MODE_CONTROL(dev, vsec, &val))) {
- dev_err(&dev->dev, "failed to read current mode control: %i", rc);
- return rc;
- }
- val &= ~CXL_VSEC_PROTOCOL_MASK;
- val |= CXL_VSEC_PROTOCOL_256TB | CXL_VSEC_PROTOCOL_ENABLE;
- if ((rc = CXL_WRITE_VSEC_MODE_CONTROL(dev, vsec, val))) {
- dev_err(&dev->dev, "failed to enable CXL protocol: %i", rc);
- return rc;
- }
- /*
- * The CAIA spec (v0.12 11.6 Bi-modal Device Support) states
- * we must wait 100ms after this mode switch before touching
- * PCIe config space.
- */
- msleep(100);
-
- return 0;
-}
-
-static int pci_map_slice_regs(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
-{
- u64 p1n_base, p2n_base, afu_desc;
- const u64 p1n_size = 0x100;
- const u64 p2n_size = 0x1000;
-
- p1n_base = p1_base(dev) + 0x10000 + (afu->slice * p1n_size);
- p2n_base = p2_base(dev) + (afu->slice * p2n_size);
- afu->psn_phys = p2_base(dev) + (adapter->native->ps_off + (afu->slice * adapter->ps_size));
- afu_desc = p2_base(dev) + adapter->native->afu_desc_off + (afu->slice * adapter->native->afu_desc_size);
-
- if (!(afu->native->p1n_mmio = ioremap(p1n_base, p1n_size)))
- goto err;
- if (!(afu->p2n_mmio = ioremap(p2n_base, p2n_size)))
- goto err1;
- if (afu_desc) {
- if (!(afu->native->afu_desc_mmio = ioremap(afu_desc, adapter->native->afu_desc_size)))
- goto err2;
- }
-
- return 0;
-err2:
- iounmap(afu->p2n_mmio);
-err1:
- iounmap(afu->native->p1n_mmio);
-err:
- dev_err(&afu->dev, "Error mapping AFU MMIO regions\n");
- return -ENOMEM;
-}
-
-static void pci_unmap_slice_regs(struct cxl_afu *afu)
-{
- if (afu->p2n_mmio) {
- iounmap(afu->p2n_mmio);
- afu->p2n_mmio = NULL;
- }
- if (afu->native->p1n_mmio) {
- iounmap(afu->native->p1n_mmio);
- afu->native->p1n_mmio = NULL;
- }
- if (afu->native->afu_desc_mmio) {
- iounmap(afu->native->afu_desc_mmio);
- afu->native->afu_desc_mmio = NULL;
- }
-}
-
-void cxl_pci_release_afu(struct device *dev)
-{
- struct cxl_afu *afu = to_cxl_afu(dev);
-
- pr_devel("%s\n", __func__);
-
- idr_destroy(&afu->contexts_idr);
- cxl_release_spa(afu);
-
- kfree(afu->native);
- kfree(afu);
-}
-
-/* Expects AFU struct to have recently been zeroed out */
-static int cxl_read_afu_descriptor(struct cxl_afu *afu)
-{
- u64 val;
-
- val = AFUD_READ_INFO(afu);
- afu->pp_irqs = AFUD_NUM_INTS_PER_PROC(val);
- afu->max_procs_virtualised = AFUD_NUM_PROCS(val);
- afu->crs_num = AFUD_NUM_CRS(val);
-
- if (AFUD_AFU_DIRECTED(val))
- afu->modes_supported |= CXL_MODE_DIRECTED;
- if (AFUD_DEDICATED_PROCESS(val))
- afu->modes_supported |= CXL_MODE_DEDICATED;
- if (AFUD_TIME_SLICED(val))
- afu->modes_supported |= CXL_MODE_TIME_SLICED;
-
- val = AFUD_READ_PPPSA(afu);
- afu->pp_size = AFUD_PPPSA_LEN(val) * 4096;
- afu->psa = AFUD_PPPSA_PSA(val);
- if ((afu->pp_psa = AFUD_PPPSA_PP(val)))
- afu->native->pp_offset = AFUD_READ_PPPSA_OFF(afu);
-
- val = AFUD_READ_CR(afu);
- afu->crs_len = AFUD_CR_LEN(val) * 256;
- afu->crs_offset = AFUD_READ_CR_OFF(afu);
-
-
- /* eb_len is in multiple of 4K */
- afu->eb_len = AFUD_EB_LEN(AFUD_READ_EB(afu)) * 4096;
- afu->eb_offset = AFUD_READ_EB_OFF(afu);
-
- /* eb_off is 4K aligned so lower 12 bits are always zero */
- if (EXTRACT_PPC_BITS(afu->eb_offset, 0, 11) != 0) {
- dev_warn(&afu->dev,
- "Invalid AFU error buffer offset %Lx\n",
- afu->eb_offset);
- dev_info(&afu->dev,
- "Ignoring AFU error buffer in the descriptor\n");
- /* indicate that no afu buffer exists */
- afu->eb_len = 0;
- }
-
- return 0;
-}
-
-static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
-{
- int i, rc;
- u32 val;
-
- if (afu->psa && afu->adapter->ps_size <
- (afu->native->pp_offset + afu->pp_size*afu->max_procs_virtualised)) {
- dev_err(&afu->dev, "per-process PSA can't fit inside the PSA!\n");
- return -ENODEV;
- }
-
- if (afu->pp_psa && (afu->pp_size < PAGE_SIZE))
- dev_warn(&afu->dev, "AFU uses pp_size(%#016llx) < PAGE_SIZE per-process PSA!\n", afu->pp_size);
-
- for (i = 0; i < afu->crs_num; i++) {
- rc = cxl_ops->afu_cr_read32(afu, i, 0, &val);
- if (rc || val == 0) {
- dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i);
- return -EINVAL;
- }
- }
-
- if ((afu->modes_supported & ~CXL_MODE_DEDICATED) && afu->max_procs_virtualised == 0) {
- /*
- * We could also check this for the dedicated process model
- * since the architecture indicates it should be set to 1, but
- * in that case we ignore the value and I'd rather not risk
- * breaking any existing dedicated process AFUs that left it as
- * 0 (not that I'm aware of any). It is clearly an error for an
- * AFU directed AFU to set this to 0, and would have previously
- * triggered a bug resulting in the maximum not being enforced
- * at all since idr_alloc treats 0 as no maximum.
- */
- dev_err(&afu->dev, "AFU does not support any processes\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int sanitise_afu_regs_psl9(struct cxl_afu *afu)
-{
- u64 reg;
-
- /*
- * Clear out any regs that contain either an IVTE or address or may be
- * waiting on an acknowledgment to try to be a bit safer as we bring
- * it online
- */
- reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
- if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
- dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg);
- if (cxl_ops->afu_reset(afu))
- return -EIO;
- if (cxl_afu_disable(afu))
- return -EIO;
- if (cxl_psl_purge(afu))
- return -EIO;
- }
- cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0x0000000000000000);
- cxl_p1n_write(afu, CXL_PSL_AMBAR_An, 0x0000000000000000);
- reg = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- if (reg) {
- dev_warn(&afu->dev, "AFU had pending DSISR: %#016llx\n", reg);
- if (reg & CXL_PSL9_DSISR_An_TF)
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
- else
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
- }
- if (afu->adapter->native->sl_ops->register_serr_irq) {
- reg = cxl_p1n_read(afu, CXL_PSL_SERR_An);
- if (reg) {
- if (reg & ~0x000000007fffffff)
- dev_warn(&afu->dev, "AFU had pending SERR: %#016llx\n", reg);
- cxl_p1n_write(afu, CXL_PSL_SERR_An, reg & ~0xffff);
- }
- }
- reg = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
- if (reg) {
- dev_warn(&afu->dev, "AFU had pending error status: %#016llx\n", reg);
- cxl_p2n_write(afu, CXL_PSL_ErrStat_An, reg);
- }
-
- return 0;
-}
-
-static int sanitise_afu_regs_psl8(struct cxl_afu *afu)
-{
- u64 reg;
-
- /*
- * Clear out any regs that contain either an IVTE or address or may be
- * waiting on an acknowledgement to try to be a bit safer as we bring
- * it online
- */
- reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
- if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
- dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg);
- if (cxl_ops->afu_reset(afu))
- return -EIO;
- if (cxl_afu_disable(afu))
- return -EIO;
- if (cxl_psl_purge(afu))
- return -EIO;
- }
- cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0x0000000000000000);
- cxl_p1n_write(afu, CXL_PSL_IVTE_Limit_An, 0x0000000000000000);
- cxl_p1n_write(afu, CXL_PSL_IVTE_Offset_An, 0x0000000000000000);
- cxl_p1n_write(afu, CXL_PSL_AMBAR_An, 0x0000000000000000);
- cxl_p1n_write(afu, CXL_PSL_SPOffset_An, 0x0000000000000000);
- cxl_p1n_write(afu, CXL_HAURP_An, 0x0000000000000000);
- cxl_p2n_write(afu, CXL_CSRP_An, 0x0000000000000000);
- cxl_p2n_write(afu, CXL_AURP1_An, 0x0000000000000000);
- cxl_p2n_write(afu, CXL_AURP0_An, 0x0000000000000000);
- cxl_p2n_write(afu, CXL_SSTP1_An, 0x0000000000000000);
- cxl_p2n_write(afu, CXL_SSTP0_An, 0x0000000000000000);
- reg = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
- if (reg) {
- dev_warn(&afu->dev, "AFU had pending DSISR: %#016llx\n", reg);
- if (reg & CXL_PSL_DSISR_TRANS)
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
- else
- cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
- }
- if (afu->adapter->native->sl_ops->register_serr_irq) {
- reg = cxl_p1n_read(afu, CXL_PSL_SERR_An);
- if (reg) {
- if (reg & ~0xffff)
- dev_warn(&afu->dev, "AFU had pending SERR: %#016llx\n", reg);
- cxl_p1n_write(afu, CXL_PSL_SERR_An, reg & ~0xffff);
- }
- }
- reg = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
- if (reg) {
- dev_warn(&afu->dev, "AFU had pending error status: %#016llx\n", reg);
- cxl_p2n_write(afu, CXL_PSL_ErrStat_An, reg);
- }
-
- return 0;
-}
-
-#define ERR_BUFF_MAX_COPY_SIZE PAGE_SIZE
-/*
- * afu_eb_read:
- * Called from sysfs and reads the afu error info buffer. The h/w only supports
- * 4/8 bytes aligned access. So in case the requested offset/count arent 8 byte
- * aligned the function uses a bounce buffer which can be max PAGE_SIZE.
- */
-ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
- loff_t off, size_t count)
-{
- loff_t aligned_start, aligned_end;
- size_t aligned_length;
- void *tbuf;
- const void __iomem *ebuf = afu->native->afu_desc_mmio + afu->eb_offset;
-
- if (count == 0 || off < 0 || (size_t)off >= afu->eb_len)
- return 0;
-
- /* calculate aligned read window */
- count = min((size_t)(afu->eb_len - off), count);
- aligned_start = round_down(off, 8);
- aligned_end = round_up(off + count, 8);
- aligned_length = aligned_end - aligned_start;
-
- /* max we can copy in one read is PAGE_SIZE */
- if (aligned_length > ERR_BUFF_MAX_COPY_SIZE) {
- aligned_length = ERR_BUFF_MAX_COPY_SIZE;
- count = ERR_BUFF_MAX_COPY_SIZE - (off & 0x7);
- }
-
- /* use bounce buffer for copy */
- tbuf = (void *)__get_free_page(GFP_KERNEL);
- if (!tbuf)
- return -ENOMEM;
-
- /* perform aligned read from the mmio region */
- memcpy_fromio(tbuf, ebuf + aligned_start, aligned_length);
- memcpy(buf, tbuf + (off & 0x7), count);
-
- free_page((unsigned long)tbuf);
-
- return count;
-}
-
-static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pci_dev *dev)
-{
- int rc;
-
- if ((rc = pci_map_slice_regs(afu, adapter, dev)))
- return rc;
-
- if (adapter->native->sl_ops->sanitise_afu_regs) {
- rc = adapter->native->sl_ops->sanitise_afu_regs(afu);
- if (rc)
- goto err1;
- }
-
- /* We need to reset the AFU before we can read the AFU descriptor */
- if ((rc = cxl_ops->afu_reset(afu)))
- goto err1;
-
- if (cxl_verbose)
- dump_afu_descriptor(afu);
-
- if ((rc = cxl_read_afu_descriptor(afu)))
- goto err1;
-
- if ((rc = cxl_afu_descriptor_looks_ok(afu)))
- goto err1;
-
- if (adapter->native->sl_ops->afu_regs_init)
- if ((rc = adapter->native->sl_ops->afu_regs_init(afu)))
- goto err1;
-
- if (adapter->native->sl_ops->register_serr_irq)
- if ((rc = adapter->native->sl_ops->register_serr_irq(afu)))
- goto err1;
-
- if ((rc = cxl_native_register_psl_irq(afu)))
- goto err2;
-
- atomic_set(&afu->configured_state, 0);
- return 0;
-
-err2:
- if (adapter->native->sl_ops->release_serr_irq)
- adapter->native->sl_ops->release_serr_irq(afu);
-err1:
- pci_unmap_slice_regs(afu);
- return rc;
-}
-
-static void pci_deconfigure_afu(struct cxl_afu *afu)
-{
- /*
- * It's okay to deconfigure when AFU is already locked, otherwise wait
- * until there are no readers
- */
- if (atomic_read(&afu->configured_state) != -1) {
- while (atomic_cmpxchg(&afu->configured_state, 0, -1) != -1)
- schedule();
- }
- cxl_native_release_psl_irq(afu);
- if (afu->adapter->native->sl_ops->release_serr_irq)
- afu->adapter->native->sl_ops->release_serr_irq(afu);
- pci_unmap_slice_regs(afu);
-}
-
-static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
-{
- struct cxl_afu *afu;
- int rc = -ENOMEM;
-
- afu = cxl_alloc_afu(adapter, slice);
- if (!afu)
- return -ENOMEM;
-
- afu->native = kzalloc(sizeof(struct cxl_afu_native), GFP_KERNEL);
- if (!afu->native)
- goto err_free_afu;
-
- mutex_init(&afu->native->spa_mutex);
-
- rc = dev_set_name(&afu->dev, "afu%i.%i", adapter->adapter_num, slice);
- if (rc)
- goto err_free_native;
-
- rc = pci_configure_afu(afu, adapter, dev);
- if (rc)
- goto err_free_native;
-
- /* Don't care if this fails */
- cxl_debugfs_afu_add(afu);
-
- /*
- * After we call this function we must not free the afu directly, even
- * if it returns an error!
- */
- if ((rc = cxl_register_afu(afu)))
- goto err_put_dev;
-
- if ((rc = cxl_sysfs_afu_add(afu)))
- goto err_del_dev;
-
- adapter->afu[afu->slice] = afu;
-
- if ((rc = cxl_pci_vphb_add(afu)))
- dev_info(&afu->dev, "Can't register vPHB\n");
-
- return 0;
-
-err_del_dev:
- device_del(&afu->dev);
-err_put_dev:
- pci_deconfigure_afu(afu);
- cxl_debugfs_afu_remove(afu);
- put_device(&afu->dev);
- return rc;
-
-err_free_native:
- kfree(afu->native);
-err_free_afu:
- kfree(afu);
- return rc;
-
-}
-
-static void cxl_pci_remove_afu(struct cxl_afu *afu)
-{
- pr_devel("%s\n", __func__);
-
- if (!afu)
- return;
-
- cxl_pci_vphb_remove(afu);
- cxl_sysfs_afu_remove(afu);
- cxl_debugfs_afu_remove(afu);
-
- spin_lock(&afu->adapter->afu_list_lock);
- afu->adapter->afu[afu->slice] = NULL;
- spin_unlock(&afu->adapter->afu_list_lock);
-
- cxl_context_detach_all(afu);
- cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
-
- pci_deconfigure_afu(afu);
- device_unregister(&afu->dev);
-}
-
-int cxl_pci_reset(struct cxl *adapter)
-{
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
- int rc;
-
- if (adapter->perst_same_image) {
- dev_warn(&dev->dev,
- "cxl: refusing to reset/reflash when perst_reloads_same_image is set.\n");
- return -EINVAL;
- }
-
- dev_info(&dev->dev, "CXL reset\n");
-
- /*
- * The adapter is about to be reset, so ignore errors.
- */
- cxl_data_cache_flush(adapter);
-
- /* pcie_warm_reset requests a fundamental pci reset which includes a
- * PERST assert/deassert. PERST triggers a loading of the image
- * if "user" or "factory" is selected in sysfs */
- if ((rc = pci_set_pcie_reset_state(dev, pcie_warm_reset))) {
- dev_err(&dev->dev, "cxl: pcie_warm_reset failed\n");
- return rc;
- }
-
- return rc;
-}
-
-static int cxl_map_adapter_regs(struct cxl *adapter, struct pci_dev *dev)
-{
- if (pci_request_region(dev, 2, "priv 2 regs"))
- goto err1;
- if (pci_request_region(dev, 0, "priv 1 regs"))
- goto err2;
-
- pr_devel("cxl_map_adapter_regs: p1: %#016llx %#llx, p2: %#016llx %#llx",
- p1_base(dev), p1_size(dev), p2_base(dev), p2_size(dev));
-
- if (!(adapter->native->p1_mmio = ioremap(p1_base(dev), p1_size(dev))))
- goto err3;
-
- if (!(adapter->native->p2_mmio = ioremap(p2_base(dev), p2_size(dev))))
- goto err4;
-
- return 0;
-
-err4:
- iounmap(adapter->native->p1_mmio);
- adapter->native->p1_mmio = NULL;
-err3:
- pci_release_region(dev, 0);
-err2:
- pci_release_region(dev, 2);
-err1:
- return -ENOMEM;
-}
-
-static void cxl_unmap_adapter_regs(struct cxl *adapter)
-{
- if (adapter->native->p1_mmio) {
- iounmap(adapter->native->p1_mmio);
- adapter->native->p1_mmio = NULL;
- pci_release_region(to_pci_dev(adapter->dev.parent), 2);
- }
- if (adapter->native->p2_mmio) {
- iounmap(adapter->native->p2_mmio);
- adapter->native->p2_mmio = NULL;
- pci_release_region(to_pci_dev(adapter->dev.parent), 0);
- }
-}
-
-static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
-{
- int vsec;
- u32 afu_desc_off, afu_desc_size;
- u32 ps_off, ps_size;
- u16 vseclen;
- u8 image_state;
-
- if (!(vsec = find_cxl_vsec(dev))) {
- dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
- return -ENODEV;
- }
-
- CXL_READ_VSEC_LENGTH(dev, vsec, &vseclen);
- if (vseclen < CXL_VSEC_MIN_SIZE) {
- dev_err(&dev->dev, "ABORTING: CXL VSEC too short\n");
- return -EINVAL;
- }
-
- CXL_READ_VSEC_STATUS(dev, vsec, &adapter->vsec_status);
- CXL_READ_VSEC_PSL_REVISION(dev, vsec, &adapter->psl_rev);
- CXL_READ_VSEC_CAIA_MAJOR(dev, vsec, &adapter->caia_major);
- CXL_READ_VSEC_CAIA_MINOR(dev, vsec, &adapter->caia_minor);
- CXL_READ_VSEC_BASE_IMAGE(dev, vsec, &adapter->base_image);
- CXL_READ_VSEC_IMAGE_STATE(dev, vsec, &image_state);
- adapter->user_image_loaded = !!(image_state & CXL_VSEC_USER_IMAGE_LOADED);
- adapter->perst_select_user = !!(image_state & CXL_VSEC_USER_IMAGE_LOADED);
- adapter->perst_loads_image = !!(image_state & CXL_VSEC_PERST_LOADS_IMAGE);
-
- CXL_READ_VSEC_NAFUS(dev, vsec, &adapter->slices);
- CXL_READ_VSEC_AFU_DESC_OFF(dev, vsec, &afu_desc_off);
- CXL_READ_VSEC_AFU_DESC_SIZE(dev, vsec, &afu_desc_size);
- CXL_READ_VSEC_PS_OFF(dev, vsec, &ps_off);
- CXL_READ_VSEC_PS_SIZE(dev, vsec, &ps_size);
-
- /* Convert everything to bytes, because there is NO WAY I'd look at the
- * code a month later and forget what units these are in ;-) */
- adapter->native->ps_off = ps_off * 64 * 1024;
- adapter->ps_size = ps_size * 64 * 1024;
- adapter->native->afu_desc_off = afu_desc_off * 64 * 1024;
- adapter->native->afu_desc_size = afu_desc_size * 64 * 1024;
-
- /* Total IRQs - 1 PSL ERROR - #AFU*(1 slice error + 1 DSI) */
- adapter->user_irqs = pnv_cxl_get_irq_count(dev) - 1 - 2*adapter->slices;
-
- return 0;
-}
-
-/*
- * Workaround a PCIe Host Bridge defect on some cards, that can cause
- * malformed Transaction Layer Packet (TLP) errors to be erroneously
- * reported. Mask this error in the Uncorrectable Error Mask Register.
- *
- * The upper nibble of the PSL revision is used to distinguish between
- * different cards. The affected ones have it set to 0.
- */
-static void cxl_fixup_malformed_tlp(struct cxl *adapter, struct pci_dev *dev)
-{
- int aer;
- u32 data;
-
- if (adapter->psl_rev & 0xf000)
- return;
- if (!(aer = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)))
- return;
- pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &data);
- if (data & PCI_ERR_UNC_MALF_TLP)
- if (data & PCI_ERR_UNC_INTN)
- return;
- data |= PCI_ERR_UNC_MALF_TLP;
- data |= PCI_ERR_UNC_INTN;
- pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, data);
-}
-
-static bool cxl_compatible_caia_version(struct cxl *adapter)
-{
- if (cxl_is_power8() && (adapter->caia_major == 1))
- return true;
-
- if (cxl_is_power9() && (adapter->caia_major == 2))
- return true;
-
- return false;
-}
-
-static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
-{
- if (adapter->vsec_status & CXL_STATUS_SECOND_PORT)
- return -EBUSY;
-
- if (adapter->vsec_status & CXL_UNSUPPORTED_FEATURES) {
- dev_err(&dev->dev, "ABORTING: CXL requires unsupported features\n");
- return -EINVAL;
- }
-
- if (!cxl_compatible_caia_version(adapter)) {
- dev_info(&dev->dev, "Ignoring card. PSL type is not supported (caia version: %d)\n",
- adapter->caia_major);
- return -ENODEV;
- }
-
- if (!adapter->slices) {
- /* Once we support dynamic reprogramming we can use the card if
- * it supports loadable AFUs */
- dev_err(&dev->dev, "ABORTING: Device has no AFUs\n");
- return -EINVAL;
- }
-
- if (!adapter->native->afu_desc_off || !adapter->native->afu_desc_size) {
- dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n");
- return -EINVAL;
- }
-
- if (adapter->ps_size > p2_size(dev) - adapter->native->ps_off) {
- dev_err(&dev->dev, "ABORTING: Problem state size larger than "
- "available in BAR2: 0x%llx > 0x%llx\n",
- adapter->ps_size, p2_size(dev) - adapter->native->ps_off);
- return -EINVAL;
- }
-
- return 0;
-}
-
-ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len)
-{
- return pci_read_vpd(to_pci_dev(adapter->dev.parent), 0, len, buf);
-}
-
-static void cxl_release_adapter(struct device *dev)
-{
- struct cxl *adapter = to_cxl_adapter(dev);
-
- pr_devel("cxl_release_adapter\n");
-
- cxl_remove_adapter_nr(adapter);
-
- kfree(adapter->native);
- kfree(adapter);
-}
-
-#define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31))
-
-static int sanitise_adapter_regs(struct cxl *adapter)
-{
- int rc = 0;
-
- /* Clear PSL tberror bit by writing 1 to it */
- cxl_p1_write(adapter, CXL_PSL_ErrIVTE, CXL_PSL_ErrIVTE_tberror);
-
- if (adapter->native->sl_ops->invalidate_all) {
- /* do not invalidate ERAT entries when not reloading on PERST */
- if (cxl_is_power9() && (adapter->perst_loads_image))
- return 0;
- rc = adapter->native->sl_ops->invalidate_all(adapter);
- }
-
- return rc;
-}
-
-/* This should contain *only* operations that can safely be done in
- * both creation and recovery.
- */
-static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
-{
- int rc;
-
- adapter->dev.parent = &dev->dev;
- adapter->dev.release = cxl_release_adapter;
- pci_set_drvdata(dev, adapter);
-
- rc = pci_enable_device(dev);
- if (rc) {
- dev_err(&dev->dev, "pci_enable_device failed: %i\n", rc);
- return rc;
- }
-
- if ((rc = cxl_read_vsec(adapter, dev)))
- return rc;
-
- if ((rc = cxl_vsec_looks_ok(adapter, dev)))
- return rc;
-
- cxl_fixup_malformed_tlp(adapter, dev);
-
- if ((rc = setup_cxl_bars(dev)))
- return rc;
-
- if ((rc = switch_card_to_cxl(dev)))
- return rc;
-
- if ((rc = cxl_update_image_control(adapter)))
- return rc;
-
- if ((rc = cxl_map_adapter_regs(adapter, dev)))
- return rc;
-
- if ((rc = sanitise_adapter_regs(adapter)))
- goto err;
-
- if ((rc = adapter->native->sl_ops->adapter_regs_init(adapter, dev)))
- goto err;
-
- /* Required for devices using CAPP DMA mode, harmless for others */
- pci_set_master(dev);
-
- adapter->tunneled_ops_supported = false;
-
- if (cxl_is_power9()) {
- if (pnv_pci_set_tunnel_bar(dev, 0x00020000E0000000ull, 1))
- dev_info(&dev->dev, "Tunneled operations unsupported\n");
- else
- adapter->tunneled_ops_supported = true;
- }
-
- if ((rc = pnv_phb_to_cxl_mode(dev, adapter->native->sl_ops->capi_mode)))
- goto err;
-
- /* If recovery happened, the last step is to turn on snooping.
- * In the non-recovery case this has no effect */
- if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_ON)))
- goto err;
-
- /* Ignore error, adapter init is not dependant on timebase sync */
- cxl_setup_psl_timebase(adapter, dev);
-
- if ((rc = cxl_native_register_psl_err_irq(adapter)))
- goto err;
-
- return 0;
-
-err:
- cxl_unmap_adapter_regs(adapter);
- return rc;
-
-}
-
-static void cxl_deconfigure_adapter(struct cxl *adapter)
-{
- struct pci_dev *pdev = to_pci_dev(adapter->dev.parent);
-
- if (cxl_is_power9())
- pnv_pci_set_tunnel_bar(pdev, 0x00020000E0000000ull, 0);
-
- cxl_native_release_psl_err_irq(adapter);
- cxl_unmap_adapter_regs(adapter);
-
- pci_disable_device(pdev);
-}
-
-static void cxl_stop_trace_psl9(struct cxl *adapter)
-{
- int traceid;
- u64 trace_state, trace_mask;
- struct pci_dev *dev = to_pci_dev(adapter->dev.parent);
-
- /* read each tracearray state and issue mmio to stop them is needed */
- for (traceid = 0; traceid <= CXL_PSL9_TRACEID_MAX; ++traceid) {
- trace_state = cxl_p1_read(adapter, CXL_PSL9_CTCCFG);
- trace_mask = (0x3ULL << (62 - traceid * 2));
- trace_state = (trace_state & trace_mask) >> (62 - traceid * 2);
- dev_dbg(&dev->dev, "cxl: Traceid-%d trace_state=0x%0llX\n",
- traceid, trace_state);
-
- /* issue mmio if the trace array isn't in FIN state */
- if (trace_state != CXL_PSL9_TRACESTATE_FIN)
- cxl_p1_write(adapter, CXL_PSL9_TRACECFG,
- 0x8400000000000000ULL | traceid);
- }
-}
-
-static void cxl_stop_trace_psl8(struct cxl *adapter)
-{
- int slice;
-
- /* Stop the trace */
- cxl_p1_write(adapter, CXL_PSL_TRACE, 0x8000000000000017LL);
-
- /* Stop the slice traces */
- spin_lock(&adapter->afu_list_lock);
- for (slice = 0; slice < adapter->slices; slice++) {
- if (adapter->afu[slice])
- cxl_p1n_write(adapter->afu[slice], CXL_PSL_SLICE_TRACE,
- 0x8000000000000000LL);
- }
- spin_unlock(&adapter->afu_list_lock);
-}
-
-static const struct cxl_service_layer_ops psl9_ops = {
- .adapter_regs_init = init_implementation_adapter_regs_psl9,
- .invalidate_all = cxl_invalidate_all_psl9,
- .afu_regs_init = init_implementation_afu_regs_psl9,
- .sanitise_afu_regs = sanitise_afu_regs_psl9,
- .register_serr_irq = cxl_native_register_serr_irq,
- .release_serr_irq = cxl_native_release_serr_irq,
- .handle_interrupt = cxl_irq_psl9,
- .fail_irq = cxl_fail_irq_psl,
- .activate_dedicated_process = cxl_activate_dedicated_process_psl9,
- .attach_afu_directed = cxl_attach_afu_directed_psl9,
- .attach_dedicated_process = cxl_attach_dedicated_process_psl9,
- .update_dedicated_ivtes = cxl_update_dedicated_ivtes_psl9,
- .debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl9,
- .debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl9,
- .psl_irq_dump_registers = cxl_native_irq_dump_regs_psl9,
- .err_irq_dump_registers = cxl_native_err_irq_dump_regs_psl9,
- .debugfs_stop_trace = cxl_stop_trace_psl9,
- .timebase_read = timebase_read_psl9,
- .capi_mode = OPAL_PHB_CAPI_MODE_CAPI,
- .needs_reset_before_disable = true,
-};
-
-static const struct cxl_service_layer_ops psl8_ops = {
- .adapter_regs_init = init_implementation_adapter_regs_psl8,
- .invalidate_all = cxl_invalidate_all_psl8,
- .afu_regs_init = init_implementation_afu_regs_psl8,
- .sanitise_afu_regs = sanitise_afu_regs_psl8,
- .register_serr_irq = cxl_native_register_serr_irq,
- .release_serr_irq = cxl_native_release_serr_irq,
- .handle_interrupt = cxl_irq_psl8,
- .fail_irq = cxl_fail_irq_psl,
- .activate_dedicated_process = cxl_activate_dedicated_process_psl8,
- .attach_afu_directed = cxl_attach_afu_directed_psl8,
- .attach_dedicated_process = cxl_attach_dedicated_process_psl8,
- .update_dedicated_ivtes = cxl_update_dedicated_ivtes_psl8,
- .debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl8,
- .debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl8,
- .psl_irq_dump_registers = cxl_native_irq_dump_regs_psl8,
- .err_irq_dump_registers = cxl_native_err_irq_dump_regs_psl8,
- .debugfs_stop_trace = cxl_stop_trace_psl8,
- .write_timebase_ctrl = write_timebase_ctrl_psl8,
- .timebase_read = timebase_read_psl8,
- .capi_mode = OPAL_PHB_CAPI_MODE_CAPI,
- .needs_reset_before_disable = true,
-};
-
-static void set_sl_ops(struct cxl *adapter, struct pci_dev *dev)
-{
- if (cxl_is_power8()) {
- dev_info(&dev->dev, "Device uses a PSL8\n");
- adapter->native->sl_ops = &psl8_ops;
- } else {
- dev_info(&dev->dev, "Device uses a PSL9\n");
- adapter->native->sl_ops = &psl9_ops;
- }
-}
-
-
-static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
-{
- struct cxl *adapter;
- int rc;
-
- adapter = cxl_alloc_adapter();
- if (!adapter)
- return ERR_PTR(-ENOMEM);
-
- adapter->native = kzalloc(sizeof(struct cxl_native), GFP_KERNEL);
- if (!adapter->native) {
- rc = -ENOMEM;
- goto err_release;
- }
-
- set_sl_ops(adapter, dev);
-
- /* Set defaults for parameters which need to persist over
- * configure/reconfigure
- */
- adapter->perst_loads_image = true;
- adapter->perst_same_image = false;
-
- rc = cxl_configure_adapter(adapter, dev);
- if (rc) {
- pci_disable_device(dev);
- goto err_release;
- }
-
- /* Don't care if this one fails: */
- cxl_debugfs_adapter_add(adapter);
-
- /*
- * After we call this function we must not free the adapter directly,
- * even if it returns an error!
- */
- if ((rc = cxl_register_adapter(adapter)))
- goto err_put_dev;
-
- if ((rc = cxl_sysfs_adapter_add(adapter)))
- goto err_del_dev;
-
- /* Release the context lock as adapter is configured */
- cxl_adapter_context_unlock(adapter);
-
- return adapter;
-
-err_del_dev:
- device_del(&adapter->dev);
-err_put_dev:
- /* This should mirror cxl_remove_adapter, except without the
- * sysfs parts
- */
- cxl_debugfs_adapter_remove(adapter);
- cxl_deconfigure_adapter(adapter);
- put_device(&adapter->dev);
- return ERR_PTR(rc);
-
-err_release:
- cxl_release_adapter(&adapter->dev);
- return ERR_PTR(rc);
-}
-
-static void cxl_pci_remove_adapter(struct cxl *adapter)
-{
- pr_devel("cxl_remove_adapter\n");
-
- cxl_sysfs_adapter_remove(adapter);
- cxl_debugfs_adapter_remove(adapter);
-
- /*
- * Flush adapter datacache as its about to be removed.
- */
- cxl_data_cache_flush(adapter);
-
- cxl_deconfigure_adapter(adapter);
-
- device_unregister(&adapter->dev);
-}
-
-#define CXL_MAX_PCIEX_PARENT 2
-
-int cxl_slot_is_switched(struct pci_dev *dev)
-{
- struct device_node *np;
- int depth = 0;
-
- if (!(np = pci_device_to_OF_node(dev))) {
- pr_err("cxl: np = NULL\n");
- return -ENODEV;
- }
- of_node_get(np);
- while (np) {
- np = of_get_next_parent(np);
- if (!of_node_is_type(np, "pciex"))
- break;
- depth++;
- }
- of_node_put(np);
- return (depth > CXL_MAX_PCIEX_PARENT);
-}
-
-static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- struct cxl *adapter;
- int slice;
- int rc;
-
- dev_err_once(&dev->dev, "DEPRECATED: cxl is deprecated and will be removed in a future kernel release\n");
-
- if (cxl_pci_is_vphb_device(dev)) {
- dev_dbg(&dev->dev, "cxl_init_adapter: Ignoring cxl vphb device\n");
- return -ENODEV;
- }
-
- if (cxl_slot_is_switched(dev)) {
- dev_info(&dev->dev, "Ignoring card on incompatible PCI slot\n");
- return -ENODEV;
- }
-
- if (cxl_is_power9() && !radix_enabled()) {
- dev_info(&dev->dev, "Only Radix mode supported\n");
- return -ENODEV;
- }
-
- if (cxl_verbose)
- dump_cxl_config_space(dev);
-
- adapter = cxl_pci_init_adapter(dev);
- if (IS_ERR(adapter)) {
- dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter));
- return PTR_ERR(adapter);
- }
-
- for (slice = 0; slice < adapter->slices; slice++) {
- if ((rc = pci_init_afu(adapter, slice, dev))) {
- dev_err(&dev->dev, "AFU %i failed to initialise: %i\n", slice, rc);
- continue;
- }
-
- rc = cxl_afu_select_best_mode(adapter->afu[slice]);
- if (rc)
- dev_err(&dev->dev, "AFU %i failed to start: %i\n", slice, rc);
- }
-
- return 0;
-}
-
-static void cxl_remove(struct pci_dev *dev)
-{
- struct cxl *adapter = pci_get_drvdata(dev);
- struct cxl_afu *afu;
- int i;
-
- /*
- * Lock to prevent someone grabbing a ref through the adapter list as
- * we are removing it
- */
- for (i = 0; i < adapter->slices; i++) {
- afu = adapter->afu[i];
- cxl_pci_remove_afu(afu);
- }
- cxl_pci_remove_adapter(adapter);
-}
-
-static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
- pci_channel_state_t state)
-{
- struct pci_dev *afu_dev;
- struct pci_driver *afu_drv;
- const struct pci_error_handlers *err_handler;
- pci_ers_result_t result = PCI_ERS_RESULT_NEED_RESET;
- pci_ers_result_t afu_result = PCI_ERS_RESULT_NEED_RESET;
-
- /* There should only be one entry, but go through the list
- * anyway
- */
- if (afu == NULL || afu->phb == NULL)
- return result;
-
- list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- afu_drv = to_pci_driver(afu_dev->dev.driver);
- if (!afu_drv)
- continue;
-
- afu_dev->error_state = state;
-
- err_handler = afu_drv->err_handler;
- if (err_handler)
- afu_result = err_handler->error_detected(afu_dev,
- state);
- /* Disconnect trumps all, NONE trumps NEED_RESET */
- if (afu_result == PCI_ERS_RESULT_DISCONNECT)
- result = PCI_ERS_RESULT_DISCONNECT;
- else if ((afu_result == PCI_ERS_RESULT_NONE) &&
- (result == PCI_ERS_RESULT_NEED_RESET))
- result = PCI_ERS_RESULT_NONE;
- }
- return result;
-}
-
-static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- struct cxl *adapter = pci_get_drvdata(pdev);
- struct cxl_afu *afu;
- pci_ers_result_t result = PCI_ERS_RESULT_NEED_RESET;
- pci_ers_result_t afu_result = PCI_ERS_RESULT_NEED_RESET;
- int i;
-
- /* At this point, we could still have an interrupt pending.
- * Let's try to get them out of the way before they do
- * anything we don't like.
- */
- schedule();
-
- /* If we're permanently dead, give up. */
- if (state == pci_channel_io_perm_failure) {
- spin_lock(&adapter->afu_list_lock);
- for (i = 0; i < adapter->slices; i++) {
- afu = adapter->afu[i];
- /*
- * Tell the AFU drivers; but we don't care what they
- * say, we're going away.
- */
- cxl_vphb_error_detected(afu, state);
- }
- spin_unlock(&adapter->afu_list_lock);
- return PCI_ERS_RESULT_DISCONNECT;
- }
-
- /* Are we reflashing?
- *
- * If we reflash, we could come back as something entirely
- * different, including a non-CAPI card. As such, by default
- * we don't participate in the process. We'll be unbound and
- * the slot re-probed. (TODO: check EEH doesn't blindly rebind
- * us!)
- *
- * However, this isn't the entire story: for reliablity
- * reasons, we usually want to reflash the FPGA on PERST in
- * order to get back to a more reliable known-good state.
- *
- * This causes us a bit of a problem: if we reflash we can't
- * trust that we'll come back the same - we could have a new
- * image and been PERSTed in order to load that
- * image. However, most of the time we actually *will* come
- * back the same - for example a regular EEH event.
- *
- * Therefore, we allow the user to assert that the image is
- * indeed the same and that we should continue on into EEH
- * anyway.
- */
- if (adapter->perst_loads_image && !adapter->perst_same_image) {
- /* TODO take the PHB out of CXL mode */
- dev_info(&pdev->dev, "reflashing, so opting out of EEH!\n");
- return PCI_ERS_RESULT_NONE;
- }
-
- /*
- * At this point, we want to try to recover. We'll always
- * need a complete slot reset: we don't trust any other reset.
- *
- * Now, we go through each AFU:
- * - We send the driver, if bound, an error_detected callback.
- * We expect it to clean up, but it can also tell us to give
- * up and permanently detach the card. To simplify things, if
- * any bound AFU driver doesn't support EEH, we give up on EEH.
- *
- * - We detach all contexts associated with the AFU. This
- * does not free them, but puts them into a CLOSED state
- * which causes any the associated files to return useful
- * errors to userland. It also unmaps, but does not free,
- * any IRQs.
- *
- * - We clean up our side: releasing and unmapping resources we hold
- * so we can wire them up again when the hardware comes back up.
- *
- * Driver authors should note:
- *
- * - Any contexts you create in your kernel driver (except
- * those associated with anonymous file descriptors) are
- * your responsibility to free and recreate. Likewise with
- * any attached resources.
- *
- * - We will take responsibility for re-initialising the
- * device context (the one set up for you in
- * cxl_pci_enable_device_hook and accessed through
- * cxl_get_context). If you've attached IRQs or other
- * resources to it, they remains yours to free.
- *
- * You can call the same functions to release resources as you
- * normally would: we make sure that these functions continue
- * to work when the hardware is down.
- *
- * Two examples:
- *
- * 1) If you normally free all your resources at the end of
- * each request, or if you use anonymous FDs, your
- * error_detected callback can simply set a flag to tell
- * your driver not to start any new calls. You can then
- * clear the flag in the resume callback.
- *
- * 2) If you normally allocate your resources on startup:
- * * Set a flag in error_detected as above.
- * * Let CXL detach your contexts.
- * * In slot_reset, free the old resources and allocate new ones.
- * * In resume, clear the flag to allow things to start.
- */
-
- /* Make sure no one else changes the afu list */
- spin_lock(&adapter->afu_list_lock);
-
- for (i = 0; i < adapter->slices; i++) {
- afu = adapter->afu[i];
-
- if (afu == NULL)
- continue;
-
- afu_result = cxl_vphb_error_detected(afu, state);
- cxl_context_detach_all(afu);
- cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
- pci_deconfigure_afu(afu);
-
- /* Disconnect trumps all, NONE trumps NEED_RESET */
- if (afu_result == PCI_ERS_RESULT_DISCONNECT)
- result = PCI_ERS_RESULT_DISCONNECT;
- else if ((afu_result == PCI_ERS_RESULT_NONE) &&
- (result == PCI_ERS_RESULT_NEED_RESET))
- result = PCI_ERS_RESULT_NONE;
- }
- spin_unlock(&adapter->afu_list_lock);
-
- /* should take the context lock here */
- if (cxl_adapter_context_lock(adapter) != 0)
- dev_warn(&adapter->dev,
- "Couldn't take context lock with %d active-contexts\n",
- atomic_read(&adapter->contexts_num));
-
- cxl_deconfigure_adapter(adapter);
-
- return result;
-}
-
-static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
-{
- struct cxl *adapter = pci_get_drvdata(pdev);
- struct cxl_afu *afu;
- struct cxl_context *ctx;
- struct pci_dev *afu_dev;
- struct pci_driver *afu_drv;
- const struct pci_error_handlers *err_handler;
- pci_ers_result_t afu_result = PCI_ERS_RESULT_RECOVERED;
- pci_ers_result_t result = PCI_ERS_RESULT_RECOVERED;
- int i;
-
- if (cxl_configure_adapter(adapter, pdev))
- goto err;
-
- /*
- * Unlock context activation for the adapter. Ideally this should be
- * done in cxl_pci_resume but cxlflash module tries to activate the
- * master context as part of slot_reset callback.
- */
- cxl_adapter_context_unlock(adapter);
-
- spin_lock(&adapter->afu_list_lock);
- for (i = 0; i < adapter->slices; i++) {
- afu = adapter->afu[i];
-
- if (afu == NULL)
- continue;
-
- if (pci_configure_afu(afu, adapter, pdev))
- goto err_unlock;
-
- if (cxl_afu_select_best_mode(afu))
- goto err_unlock;
-
- if (afu->phb == NULL)
- continue;
-
- list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- /* Reset the device context.
- * TODO: make this less disruptive
- */
- ctx = cxl_get_context(afu_dev);
-
- if (ctx && cxl_release_context(ctx))
- goto err_unlock;
-
- ctx = cxl_dev_context_init(afu_dev);
- if (IS_ERR(ctx))
- goto err_unlock;
-
- afu_dev->dev.archdata.cxl_ctx = ctx;
-
- if (cxl_ops->afu_check_and_enable(afu))
- goto err_unlock;
-
- afu_dev->error_state = pci_channel_io_normal;
-
- /* If there's a driver attached, allow it to
- * chime in on recovery. Drivers should check
- * if everything has come back OK, but
- * shouldn't start new work until we call
- * their resume function.
- */
- afu_drv = to_pci_driver(afu_dev->dev.driver);
- if (!afu_drv)
- continue;
-
- err_handler = afu_drv->err_handler;
- if (err_handler && err_handler->slot_reset)
- afu_result = err_handler->slot_reset(afu_dev);
-
- if (afu_result == PCI_ERS_RESULT_DISCONNECT)
- result = PCI_ERS_RESULT_DISCONNECT;
- }
- }
-
- spin_unlock(&adapter->afu_list_lock);
- return result;
-
-err_unlock:
- spin_unlock(&adapter->afu_list_lock);
-
-err:
- /* All the bits that happen in both error_detected and cxl_remove
- * should be idempotent, so we don't need to worry about leaving a mix
- * of unconfigured and reconfigured resources.
- */
- dev_err(&pdev->dev, "EEH recovery failed. Asking to be disconnected.\n");
- return PCI_ERS_RESULT_DISCONNECT;
-}
-
-static void cxl_pci_resume(struct pci_dev *pdev)
-{
- struct cxl *adapter = pci_get_drvdata(pdev);
- struct cxl_afu *afu;
- struct pci_dev *afu_dev;
- struct pci_driver *afu_drv;
- const struct pci_error_handlers *err_handler;
- int i;
-
- /* Everything is back now. Drivers should restart work now.
- * This is not the place to be checking if everything came back up
- * properly, because there's no return value: do that in slot_reset.
- */
- spin_lock(&adapter->afu_list_lock);
- for (i = 0; i < adapter->slices; i++) {
- afu = adapter->afu[i];
-
- if (afu == NULL || afu->phb == NULL)
- continue;
-
- list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- afu_drv = to_pci_driver(afu_dev->dev.driver);
- if (!afu_drv)
- continue;
-
- err_handler = afu_drv->err_handler;
- if (err_handler && err_handler->resume)
- err_handler->resume(afu_dev);
- }
- }
- spin_unlock(&adapter->afu_list_lock);
-}
-
-static const struct pci_error_handlers cxl_err_handler = {
- .error_detected = cxl_pci_error_detected,
- .slot_reset = cxl_pci_slot_reset,
- .resume = cxl_pci_resume,
-};
-
-struct pci_driver cxl_pci_driver = {
- .name = "cxl-pci",
- .id_table = cxl_pci_tbl,
- .probe = cxl_probe,
- .remove = cxl_remove,
- .shutdown = cxl_remove,
- .err_handler = &cxl_err_handler,
-};
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
deleted file mode 100644
index b1fc6446bd4b..000000000000
--- a/drivers/misc/cxl/sysfs.c
+++ /dev/null
@@ -1,771 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/sysfs.h>
-#include <linux/pci_regs.h>
-
-#include "cxl.h"
-
-#define to_afu_chardev_m(d) dev_get_drvdata(d)
-
-/********* Adapter attributes **********************************************/
-
-static ssize_t caia_version_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i.%i\n", adapter->caia_major,
- adapter->caia_minor);
-}
-
-static ssize_t psl_revision_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_rev);
-}
-
-static ssize_t base_image_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->base_image);
-}
-
-static ssize_t image_loaded_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- if (adapter->user_image_loaded)
- return scnprintf(buf, PAGE_SIZE, "user\n");
- return scnprintf(buf, PAGE_SIZE, "factory\n");
-}
-
-static ssize_t psl_timebase_synced_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
- u64 psl_tb, delta;
-
- /* Recompute the status only in native mode */
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- psl_tb = adapter->native->sl_ops->timebase_read(adapter);
- delta = abs(mftb() - psl_tb);
-
- /* CORE TB and PSL TB difference <= 16usecs ? */
- adapter->psl_timebase_synced = (tb_to_ns(delta) < 16000) ? true : false;
- pr_devel("PSL timebase %s - delta: 0x%016llx\n",
- (tb_to_ns(delta) < 16000) ? "synchronized" :
- "not synchronized", tb_to_ns(delta));
- }
- return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced);
-}
-
-static ssize_t tunneled_ops_supported_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->tunneled_ops_supported);
-}
-
-static ssize_t reset_adapter_store(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl *adapter = to_cxl_adapter(device);
- int rc;
- int val;
-
- rc = sscanf(buf, "%i", &val);
- if ((rc != 1) || (val != 1 && val != -1))
- return -EINVAL;
-
- /*
- * See if we can lock the context mapping that's only allowed
- * when there are no contexts attached to the adapter. Once
- * taken this will also prevent any context from getting activated.
- */
- if (val == 1) {
- rc = cxl_adapter_context_lock(adapter);
- if (rc)
- goto out;
-
- rc = cxl_ops->adapter_reset(adapter);
- /* In case reset failed release context lock */
- if (rc)
- cxl_adapter_context_unlock(adapter);
-
- } else if (val == -1) {
- /* Perform a forced adapter reset */
- rc = cxl_ops->adapter_reset(adapter);
- }
-
-out:
- return rc ? rc : count;
-}
-
-static ssize_t load_image_on_perst_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- if (!adapter->perst_loads_image)
- return scnprintf(buf, PAGE_SIZE, "none\n");
-
- if (adapter->perst_select_user)
- return scnprintf(buf, PAGE_SIZE, "user\n");
- return scnprintf(buf, PAGE_SIZE, "factory\n");
-}
-
-static ssize_t load_image_on_perst_store(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl *adapter = to_cxl_adapter(device);
- int rc;
-
- if (!strncmp(buf, "none", 4))
- adapter->perst_loads_image = false;
- else if (!strncmp(buf, "user", 4)) {
- adapter->perst_select_user = true;
- adapter->perst_loads_image = true;
- } else if (!strncmp(buf, "factory", 7)) {
- adapter->perst_select_user = false;
- adapter->perst_loads_image = true;
- } else
- return -EINVAL;
-
- if ((rc = cxl_update_image_control(adapter)))
- return rc;
-
- return count;
-}
-
-static ssize_t perst_reloads_same_image_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl *adapter = to_cxl_adapter(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->perst_same_image);
-}
-
-static ssize_t perst_reloads_same_image_store(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl *adapter = to_cxl_adapter(device);
- int rc;
- int val;
-
- rc = sscanf(buf, "%i", &val);
- if ((rc != 1) || !(val == 1 || val == 0))
- return -EINVAL;
-
- adapter->perst_same_image = (val == 1);
- return count;
-}
-
-static struct device_attribute adapter_attrs[] = {
- __ATTR_RO(caia_version),
- __ATTR_RO(psl_revision),
- __ATTR_RO(base_image),
- __ATTR_RO(image_loaded),
- __ATTR_RO(psl_timebase_synced),
- __ATTR_RO(tunneled_ops_supported),
- __ATTR_RW(load_image_on_perst),
- __ATTR_RW(perst_reloads_same_image),
- __ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
-};
-
-
-/********* AFU master specific attributes **********************************/
-
-static ssize_t mmio_size_show_master(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_afu_chardev_m(device);
-
- return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size);
-}
-
-static ssize_t pp_mmio_off_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_afu_chardev_m(device);
-
- return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->native->pp_offset);
-}
-
-static ssize_t pp_mmio_len_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_afu_chardev_m(device);
-
- return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size);
-}
-
-static struct device_attribute afu_master_attrs[] = {
- __ATTR(mmio_size, S_IRUGO, mmio_size_show_master, NULL),
- __ATTR_RO(pp_mmio_off),
- __ATTR_RO(pp_mmio_len),
-};
-
-
-/********* AFU attributes **************************************************/
-
-static ssize_t mmio_size_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
-
- if (afu->pp_size)
- return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size);
- return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size);
-}
-
-static ssize_t reset_store_afu(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
- int rc;
-
- /* Not safe to reset if it is currently in use */
- mutex_lock(&afu->contexts_lock);
- if (!idr_is_empty(&afu->contexts_idr)) {
- rc = -EBUSY;
- goto err;
- }
-
- if ((rc = cxl_ops->afu_reset(afu)))
- goto err;
-
- rc = count;
-err:
- mutex_unlock(&afu->contexts_lock);
- return rc;
-}
-
-static ssize_t irqs_min_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i\n", afu->pp_irqs);
-}
-
-static ssize_t irqs_max_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
-
- return scnprintf(buf, PAGE_SIZE, "%i\n", afu->irqs_max);
-}
-
-static ssize_t irqs_max_store(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
- ssize_t ret;
- int irqs_max;
-
- ret = sscanf(buf, "%i", &irqs_max);
- if (ret != 1)
- return -EINVAL;
-
- if (irqs_max < afu->pp_irqs)
- return -EINVAL;
-
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- if (irqs_max > afu->adapter->user_irqs)
- return -EINVAL;
- } else {
- /* pHyp sets a per-AFU limit */
- if (irqs_max > afu->guest->max_ints)
- return -EINVAL;
- }
-
- afu->irqs_max = irqs_max;
- return count;
-}
-
-static ssize_t modes_supported_show(struct device *device,
- struct device_attribute *attr, char *buf)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
- char *p = buf, *end = buf + PAGE_SIZE;
-
- if (afu->modes_supported & CXL_MODE_DEDICATED)
- p += scnprintf(p, end - p, "dedicated_process\n");
- if (afu->modes_supported & CXL_MODE_DIRECTED)
- p += scnprintf(p, end - p, "afu_directed\n");
- return (p - buf);
-}
-
-static ssize_t prefault_mode_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
-
- switch (afu->prefault_mode) {
- case CXL_PREFAULT_WED:
- return scnprintf(buf, PAGE_SIZE, "work_element_descriptor\n");
- case CXL_PREFAULT_ALL:
- return scnprintf(buf, PAGE_SIZE, "all\n");
- default:
- return scnprintf(buf, PAGE_SIZE, "none\n");
- }
-}
-
-static ssize_t prefault_mode_store(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
- enum prefault_modes mode = -1;
-
- if (!strncmp(buf, "none", 4))
- mode = CXL_PREFAULT_NONE;
- else {
- if (!radix_enabled()) {
-
- /* only allowed when not in radix mode */
- if (!strncmp(buf, "work_element_descriptor", 23))
- mode = CXL_PREFAULT_WED;
- if (!strncmp(buf, "all", 3))
- mode = CXL_PREFAULT_ALL;
- } else {
- dev_err(device, "Cannot prefault with radix enabled\n");
- }
- }
-
- if (mode == -1)
- return -EINVAL;
-
- afu->prefault_mode = mode;
- return count;
-}
-
-static ssize_t mode_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
-
- if (afu->current_mode == CXL_MODE_DEDICATED)
- return scnprintf(buf, PAGE_SIZE, "dedicated_process\n");
- if (afu->current_mode == CXL_MODE_DIRECTED)
- return scnprintf(buf, PAGE_SIZE, "afu_directed\n");
- return scnprintf(buf, PAGE_SIZE, "none\n");
-}
-
-static ssize_t mode_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cxl_afu *afu = to_cxl_afu(device);
- int old_mode, mode = -1;
- int rc = -EBUSY;
-
- /* can't change this if we have a user */
- mutex_lock(&afu->contexts_lock);
- if (!idr_is_empty(&afu->contexts_idr))
- goto err;
-
- if (!strncmp(buf, "dedicated_process", 17))
- mode = CXL_MODE_DEDICATED;
- if (!strncmp(buf, "afu_directed", 12))
- mode = CXL_MODE_DIRECTED;
- if (!strncmp(buf, "none", 4))
- mode = 0;
-
- if (mode == -1) {
- rc = -EINVAL;
- goto err;
- }
-
- /*
- * afu_deactivate_mode needs to be done outside the lock, prevent
- * other contexts coming in before we are ready:
- */
- old_mode = afu->current_mode;
- afu->current_mode = 0;
- afu->num_procs = 0;
-
- mutex_unlock(&afu->contexts_lock);
-
- if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode)))
- return rc;
- if ((rc = cxl_ops->afu_activate_mode(afu, mode)))
- return rc;
-
- return count;
-err:
- mutex_unlock(&afu->contexts_lock);
- return rc;
-}
-
-static ssize_t api_version_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION);
-}
-
-static ssize_t api_version_compatible_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION_COMPATIBLE);
-}
-
-static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj,
- const struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
-{
- struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj));
-
- return cxl_ops->afu_read_err_buffer(afu, buf, off, count);
-}
-
-static struct device_attribute afu_attrs[] = {
- __ATTR_RO(mmio_size),
- __ATTR_RO(irqs_min),
- __ATTR_RW(irqs_max),
- __ATTR_RO(modes_supported),
- __ATTR_RW(mode),
- __ATTR_RW(prefault_mode),
- __ATTR_RO(api_version),
- __ATTR_RO(api_version_compatible),
- __ATTR(reset, S_IWUSR, NULL, reset_store_afu),
-};
-
-int cxl_sysfs_adapter_add(struct cxl *adapter)
-{
- struct device_attribute *dev_attr;
- int i, rc;
-
- for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
- dev_attr = &adapter_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_ADAPTER_ATTRS)) {
- if ((rc = device_create_file(&adapter->dev, dev_attr)))
- goto err;
- }
- }
- return 0;
-err:
- for (i--; i >= 0; i--) {
- dev_attr = &adapter_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_ADAPTER_ATTRS))
- device_remove_file(&adapter->dev, dev_attr);
- }
- return rc;
-}
-
-void cxl_sysfs_adapter_remove(struct cxl *adapter)
-{
- struct device_attribute *dev_attr;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
- dev_attr = &adapter_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_ADAPTER_ATTRS))
- device_remove_file(&adapter->dev, dev_attr);
- }
-}
-
-struct afu_config_record {
- struct kobject kobj;
- struct bin_attribute config_attr;
- struct list_head list;
- int cr;
- u16 device;
- u16 vendor;
- u32 class;
-};
-
-#define to_cr(obj) container_of(obj, struct afu_config_record, kobj)
-
-static ssize_t vendor_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- struct afu_config_record *cr = to_cr(kobj);
-
- return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->vendor);
-}
-
-static ssize_t device_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- struct afu_config_record *cr = to_cr(kobj);
-
- return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->device);
-}
-
-static ssize_t class_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- struct afu_config_record *cr = to_cr(kobj);
-
- return scnprintf(buf, PAGE_SIZE, "0x%.6x\n", cr->class);
-}
-
-static ssize_t afu_read_config(struct file *filp, struct kobject *kobj,
- const struct bin_attribute *bin_attr, char *buf,
- loff_t off, size_t count)
-{
- struct afu_config_record *cr = to_cr(kobj);
- struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent));
-
- u64 i, j, val, rc;
-
- for (i = 0; i < count;) {
- rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val);
- if (rc)
- val = ~0ULL;
- for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
- buf[i] = (val >> (j * 8)) & 0xff;
- }
-
- return count;
-}
-
-static struct kobj_attribute vendor_attribute =
- __ATTR_RO(vendor);
-static struct kobj_attribute device_attribute =
- __ATTR_RO(device);
-static struct kobj_attribute class_attribute =
- __ATTR_RO(class);
-
-static struct attribute *afu_cr_attrs[] = {
- &vendor_attribute.attr,
- &device_attribute.attr,
- &class_attribute.attr,
- NULL,
-};
-ATTRIBUTE_GROUPS(afu_cr);
-
-static void release_afu_config_record(struct kobject *kobj)
-{
- struct afu_config_record *cr = to_cr(kobj);
-
- kfree(cr);
-}
-
-static const struct kobj_type afu_config_record_type = {
- .sysfs_ops = &kobj_sysfs_ops,
- .release = release_afu_config_record,
- .default_groups = afu_cr_groups,
-};
-
-static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int cr_idx)
-{
- struct afu_config_record *cr;
- int rc;
-
- cr = kzalloc(sizeof(struct afu_config_record), GFP_KERNEL);
- if (!cr)
- return ERR_PTR(-ENOMEM);
-
- cr->cr = cr_idx;
-
- rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device);
- if (rc)
- goto err;
- rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor);
- if (rc)
- goto err;
- rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class);
- if (rc)
- goto err;
- cr->class >>= 8;
-
- /*
- * Export raw AFU PCIe like config record. For now this is read only by
- * root - we can expand that later to be readable by non-root and maybe
- * even writable provided we have a good use-case. Once we support
- * exposing AFUs through a virtual PHB they will get that for free from
- * Linux' PCI infrastructure, but until then it's not clear that we
- * need it for anything since the main use case is just identifying
- * AFUs, which can be done via the vendor, device and class attributes.
- */
- sysfs_bin_attr_init(&cr->config_attr);
- cr->config_attr.attr.name = "config";
- cr->config_attr.attr.mode = S_IRUSR;
- cr->config_attr.size = afu->crs_len;
- cr->config_attr.read_new = afu_read_config;
-
- rc = kobject_init_and_add(&cr->kobj, &afu_config_record_type,
- &afu->dev.kobj, "cr%i", cr->cr);
- if (rc)
- goto err1;
-
- rc = sysfs_create_bin_file(&cr->kobj, &cr->config_attr);
- if (rc)
- goto err1;
-
- rc = kobject_uevent(&cr->kobj, KOBJ_ADD);
- if (rc)
- goto err2;
-
- return cr;
-err2:
- sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
-err1:
- kobject_put(&cr->kobj);
- return ERR_PTR(rc);
-err:
- kfree(cr);
- return ERR_PTR(rc);
-}
-
-void cxl_sysfs_afu_remove(struct cxl_afu *afu)
-{
- struct device_attribute *dev_attr;
- struct afu_config_record *cr, *tmp;
- int i;
-
- /* remove the err buffer bin attribute */
- if (afu->eb_len)
- device_remove_bin_file(&afu->dev, &afu->attr_eb);
-
- for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
- dev_attr = &afu_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_AFU_ATTRS))
- device_remove_file(&afu->dev, &afu_attrs[i]);
- }
-
- list_for_each_entry_safe(cr, tmp, &afu->crs, list) {
- sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
- kobject_put(&cr->kobj);
- }
-}
-
-int cxl_sysfs_afu_add(struct cxl_afu *afu)
-{
- struct device_attribute *dev_attr;
- struct afu_config_record *cr;
- int i, rc;
-
- INIT_LIST_HEAD(&afu->crs);
-
- for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
- dev_attr = &afu_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_AFU_ATTRS)) {
- if ((rc = device_create_file(&afu->dev, &afu_attrs[i])))
- goto err;
- }
- }
-
- /* conditionally create the add the binary file for error info buffer */
- if (afu->eb_len) {
- sysfs_attr_init(&afu->attr_eb.attr);
-
- afu->attr_eb.attr.name = "afu_err_buff";
- afu->attr_eb.attr.mode = S_IRUGO;
- afu->attr_eb.size = afu->eb_len;
- afu->attr_eb.read_new = afu_eb_read;
-
- rc = device_create_bin_file(&afu->dev, &afu->attr_eb);
- if (rc) {
- dev_err(&afu->dev,
- "Unable to create eb attr for the afu. Err(%d)\n",
- rc);
- goto err;
- }
- }
-
- for (i = 0; i < afu->crs_num; i++) {
- cr = cxl_sysfs_afu_new_cr(afu, i);
- if (IS_ERR(cr)) {
- rc = PTR_ERR(cr);
- goto err1;
- }
- list_add(&cr->list, &afu->crs);
- }
-
- return 0;
-
-err1:
- cxl_sysfs_afu_remove(afu);
- return rc;
-err:
- /* reset the eb_len as we havent created the bin attr */
- afu->eb_len = 0;
-
- for (i--; i >= 0; i--) {
- dev_attr = &afu_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_AFU_ATTRS))
- device_remove_file(&afu->dev, &afu_attrs[i]);
- }
- return rc;
-}
-
-int cxl_sysfs_afu_m_add(struct cxl_afu *afu)
-{
- struct device_attribute *dev_attr;
- int i, rc;
-
- for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
- dev_attr = &afu_master_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_AFU_MASTER_ATTRS)) {
- if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i])))
- goto err;
- }
- }
-
- return 0;
-
-err:
- for (i--; i >= 0; i--) {
- dev_attr = &afu_master_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_AFU_MASTER_ATTRS))
- device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
- }
- return rc;
-}
-
-void cxl_sysfs_afu_m_remove(struct cxl_afu *afu)
-{
- struct device_attribute *dev_attr;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
- dev_attr = &afu_master_attrs[i];
- if (cxl_ops->support_attributes(dev_attr->attr.name,
- CXL_AFU_MASTER_ATTRS))
- device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
- }
-}
diff --git a/drivers/misc/cxl/trace.c b/drivers/misc/cxl/trace.c
deleted file mode 100644
index 86f654b99efb..000000000000
--- a/drivers/misc/cxl/trace.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2015 IBM Corp.
- */
-
-#ifndef __CHECKER__
-#define CREATE_TRACE_POINTS
-#include "trace.h"
-#endif
diff --git a/drivers/misc/cxl/trace.h b/drivers/misc/cxl/trace.h
deleted file mode 100644
index c474157c6857..000000000000
--- a/drivers/misc/cxl/trace.h
+++ /dev/null
@@ -1,691 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright 2015 IBM Corp.
- */
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM cxl
-
-#if !defined(_CXL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _CXL_TRACE_H
-
-#include <linux/tracepoint.h>
-
-#include "cxl.h"
-
-#define dsisr_psl9_flags(flags) \
- __print_flags(flags, "|", \
- { CXL_PSL9_DSISR_An_CO_MASK, "FR" }, \
- { CXL_PSL9_DSISR_An_TF, "TF" }, \
- { CXL_PSL9_DSISR_An_PE, "PE" }, \
- { CXL_PSL9_DSISR_An_AE, "AE" }, \
- { CXL_PSL9_DSISR_An_OC, "OC" }, \
- { CXL_PSL9_DSISR_An_S, "S" })
-
-#define DSISR_FLAGS \
- { CXL_PSL_DSISR_An_DS, "DS" }, \
- { CXL_PSL_DSISR_An_DM, "DM" }, \
- { CXL_PSL_DSISR_An_ST, "ST" }, \
- { CXL_PSL_DSISR_An_UR, "UR" }, \
- { CXL_PSL_DSISR_An_PE, "PE" }, \
- { CXL_PSL_DSISR_An_AE, "AE" }, \
- { CXL_PSL_DSISR_An_OC, "OC" }, \
- { CXL_PSL_DSISR_An_M, "M" }, \
- { CXL_PSL_DSISR_An_P, "P" }, \
- { CXL_PSL_DSISR_An_A, "A" }, \
- { CXL_PSL_DSISR_An_S, "S" }, \
- { CXL_PSL_DSISR_An_K, "K" }
-
-#define TFC_FLAGS \
- { CXL_PSL_TFC_An_A, "A" }, \
- { CXL_PSL_TFC_An_C, "C" }, \
- { CXL_PSL_TFC_An_AE, "AE" }, \
- { CXL_PSL_TFC_An_R, "R" }
-
-#define LLCMD_NAMES \
- { CXL_SPA_SW_CMD_TERMINATE, "TERMINATE" }, \
- { CXL_SPA_SW_CMD_REMOVE, "REMOVE" }, \
- { CXL_SPA_SW_CMD_SUSPEND, "SUSPEND" }, \
- { CXL_SPA_SW_CMD_RESUME, "RESUME" }, \
- { CXL_SPA_SW_CMD_ADD, "ADD" }, \
- { CXL_SPA_SW_CMD_UPDATE, "UPDATE" }
-
-#define AFU_COMMANDS \
- { 0, "DISABLE" }, \
- { CXL_AFU_Cntl_An_E, "ENABLE" }, \
- { CXL_AFU_Cntl_An_RA, "RESET" }
-
-#define PSL_COMMANDS \
- { CXL_PSL_SCNTL_An_Pc, "PURGE" }, \
- { CXL_PSL_SCNTL_An_Sc, "SUSPEND" }
-
-
-DECLARE_EVENT_CLASS(cxl_pe_class,
- TP_PROTO(struct cxl_context *ctx),
-
- TP_ARGS(ctx),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- ),
-
- TP_printk("afu%i.%i pe=%i",
- __entry->card,
- __entry->afu,
- __entry->pe
- )
-);
-
-
-TRACE_EVENT(cxl_attach,
- TP_PROTO(struct cxl_context *ctx, u64 wed, s16 num_interrupts, u64 amr),
-
- TP_ARGS(ctx, wed, num_interrupts, amr),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(pid_t, pid)
- __field(u64, wed)
- __field(u64, amr)
- __field(s16, num_interrupts)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->pid = pid_nr(ctx->pid);
- __entry->wed = wed;
- __entry->amr = amr;
- __entry->num_interrupts = num_interrupts;
- ),
-
- TP_printk("afu%i.%i pid=%i pe=%i wed=0x%016llx irqs=%i amr=0x%llx",
- __entry->card,
- __entry->afu,
- __entry->pid,
- __entry->pe,
- __entry->wed,
- __entry->num_interrupts,
- __entry->amr
- )
-);
-
-DEFINE_EVENT(cxl_pe_class, cxl_detach,
- TP_PROTO(struct cxl_context *ctx),
- TP_ARGS(ctx)
-);
-
-TRACE_EVENT(cxl_afu_irq,
- TP_PROTO(struct cxl_context *ctx, int afu_irq, int virq, irq_hw_number_t hwirq),
-
- TP_ARGS(ctx, afu_irq, virq, hwirq),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(u16, afu_irq)
- __field(int, virq)
- __field(irq_hw_number_t, hwirq)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->afu_irq = afu_irq;
- __entry->virq = virq;
- __entry->hwirq = hwirq;
- ),
-
- TP_printk("afu%i.%i pe=%i afu_irq=%i virq=%i hwirq=0x%lx",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __entry->afu_irq,
- __entry->virq,
- __entry->hwirq
- )
-);
-
-TRACE_EVENT(cxl_psl9_irq,
- TP_PROTO(struct cxl_context *ctx, int irq, u64 dsisr, u64 dar),
-
- TP_ARGS(ctx, irq, dsisr, dar),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(int, irq)
- __field(u64, dsisr)
- __field(u64, dar)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->irq = irq;
- __entry->dsisr = dsisr;
- __entry->dar = dar;
- ),
-
- TP_printk("afu%i.%i pe=%i irq=%i dsisr=0x%016llx dsisr=%s dar=0x%016llx",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __entry->irq,
- __entry->dsisr,
- dsisr_psl9_flags(__entry->dsisr),
- __entry->dar
- )
-);
-
-TRACE_EVENT(cxl_psl_irq,
- TP_PROTO(struct cxl_context *ctx, int irq, u64 dsisr, u64 dar),
-
- TP_ARGS(ctx, irq, dsisr, dar),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(int, irq)
- __field(u64, dsisr)
- __field(u64, dar)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->irq = irq;
- __entry->dsisr = dsisr;
- __entry->dar = dar;
- ),
-
- TP_printk("afu%i.%i pe=%i irq=%i dsisr=%s dar=0x%016llx",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __entry->irq,
- __print_flags(__entry->dsisr, "|", DSISR_FLAGS),
- __entry->dar
- )
-);
-
-TRACE_EVENT(cxl_psl_irq_ack,
- TP_PROTO(struct cxl_context *ctx, u64 tfc),
-
- TP_ARGS(ctx, tfc),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(u64, tfc)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->tfc = tfc;
- ),
-
- TP_printk("afu%i.%i pe=%i tfc=%s",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __print_flags(__entry->tfc, "|", TFC_FLAGS)
- )
-);
-
-TRACE_EVENT(cxl_ste_miss,
- TP_PROTO(struct cxl_context *ctx, u64 dar),
-
- TP_ARGS(ctx, dar),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(u64, dar)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->dar = dar;
- ),
-
- TP_printk("afu%i.%i pe=%i dar=0x%016llx",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __entry->dar
- )
-);
-
-TRACE_EVENT(cxl_ste_write,
- TP_PROTO(struct cxl_context *ctx, unsigned int idx, u64 e, u64 v),
-
- TP_ARGS(ctx, idx, e, v),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(unsigned int, idx)
- __field(u64, e)
- __field(u64, v)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->idx = idx;
- __entry->e = e;
- __entry->v = v;
- ),
-
- TP_printk("afu%i.%i pe=%i SSTE[%i] E=0x%016llx V=0x%016llx",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __entry->idx,
- __entry->e,
- __entry->v
- )
-);
-
-TRACE_EVENT(cxl_pte_miss,
- TP_PROTO(struct cxl_context *ctx, u64 dsisr, u64 dar),
-
- TP_ARGS(ctx, dsisr, dar),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(u64, dsisr)
- __field(u64, dar)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->dsisr = dsisr;
- __entry->dar = dar;
- ),
-
- TP_printk("afu%i.%i pe=%i dsisr=%s dar=0x%016llx",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __print_flags(__entry->dsisr, "|", DSISR_FLAGS),
- __entry->dar
- )
-);
-
-TRACE_EVENT(cxl_llcmd,
- TP_PROTO(struct cxl_context *ctx, u64 cmd),
-
- TP_ARGS(ctx, cmd),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(u64, cmd)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->cmd = cmd;
- ),
-
- TP_printk("afu%i.%i pe=%i cmd=%s",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __print_symbolic_u64(__entry->cmd, LLCMD_NAMES)
- )
-);
-
-TRACE_EVENT(cxl_llcmd_done,
- TP_PROTO(struct cxl_context *ctx, u64 cmd, int rc),
-
- TP_ARGS(ctx, cmd, rc),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u16, pe)
- __field(u64, cmd)
- __field(int, rc)
- ),
-
- TP_fast_assign(
- __entry->card = ctx->afu->adapter->adapter_num;
- __entry->afu = ctx->afu->slice;
- __entry->pe = ctx->pe;
- __entry->rc = rc;
- __entry->cmd = cmd;
- ),
-
- TP_printk("afu%i.%i pe=%i cmd=%s rc=%i",
- __entry->card,
- __entry->afu,
- __entry->pe,
- __print_symbolic_u64(__entry->cmd, LLCMD_NAMES),
- __entry->rc
- )
-);
-
-DECLARE_EVENT_CLASS(cxl_afu_psl_ctrl,
- TP_PROTO(struct cxl_afu *afu, u64 cmd),
-
- TP_ARGS(afu, cmd),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u64, cmd)
- ),
-
- TP_fast_assign(
- __entry->card = afu->adapter->adapter_num;
- __entry->afu = afu->slice;
- __entry->cmd = cmd;
- ),
-
- TP_printk("afu%i.%i cmd=%s",
- __entry->card,
- __entry->afu,
- __print_symbolic_u64(__entry->cmd, AFU_COMMANDS)
- )
-);
-
-DECLARE_EVENT_CLASS(cxl_afu_psl_ctrl_done,
- TP_PROTO(struct cxl_afu *afu, u64 cmd, int rc),
-
- TP_ARGS(afu, cmd, rc),
-
- TP_STRUCT__entry(
- __field(u8, card)
- __field(u8, afu)
- __field(u64, cmd)
- __field(int, rc)
- ),
-
- TP_fast_assign(
- __entry->card = afu->adapter->adapter_num;
- __entry->afu = afu->slice;
- __entry->rc = rc;
- __entry->cmd = cmd;
- ),
-
- TP_printk("afu%i.%i cmd=%s rc=%i",
- __entry->card,
- __entry->afu,
- __print_symbolic_u64(__entry->cmd, AFU_COMMANDS),
- __entry->rc
- )
-);
-
-DEFINE_EVENT(cxl_afu_psl_ctrl, cxl_afu_ctrl,
- TP_PROTO(struct cxl_afu *afu, u64 cmd),
- TP_ARGS(afu, cmd)
-);
-
-DEFINE_EVENT(cxl_afu_psl_ctrl_done, cxl_afu_ctrl_done,
- TP_PROTO(struct cxl_afu *afu, u64 cmd, int rc),
- TP_ARGS(afu, cmd, rc)
-);
-
-DEFINE_EVENT_PRINT(cxl_afu_psl_ctrl, cxl_psl_ctrl,
- TP_PROTO(struct cxl_afu *afu, u64 cmd),
- TP_ARGS(afu, cmd),
-
- TP_printk("psl%i.%i cmd=%s",
- __entry->card,
- __entry->afu,
- __print_symbolic_u64(__entry->cmd, PSL_COMMANDS)
- )
-);
-
-DEFINE_EVENT_PRINT(cxl_afu_psl_ctrl_done, cxl_psl_ctrl_done,
- TP_PROTO(struct cxl_afu *afu, u64 cmd, int rc),
- TP_ARGS(afu, cmd, rc),
-
- TP_printk("psl%i.%i cmd=%s rc=%i",
- __entry->card,
- __entry->afu,
- __print_symbolic_u64(__entry->cmd, PSL_COMMANDS),
- __entry->rc
- )
-);
-
-DEFINE_EVENT(cxl_pe_class, cxl_slbia,
- TP_PROTO(struct cxl_context *ctx),
- TP_ARGS(ctx)
-);
-
-TRACE_EVENT(cxl_hcall,
- TP_PROTO(u64 unit_address, u64 process_token, long rc),
-
- TP_ARGS(unit_address, process_token, rc),
-
- TP_STRUCT__entry(
- __field(u64, unit_address)
- __field(u64, process_token)
- __field(long, rc)
- ),
-
- TP_fast_assign(
- __entry->unit_address = unit_address;
- __entry->process_token = process_token;
- __entry->rc = rc;
- ),
-
- TP_printk("unit_address=0x%016llx process_token=0x%016llx rc=%li",
- __entry->unit_address,
- __entry->process_token,
- __entry->rc
- )
-);
-
-TRACE_EVENT(cxl_hcall_control,
- TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
- u64 p4, unsigned long r4, long rc),
-
- TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc),
-
- TP_STRUCT__entry(
- __field(u64, unit_address)
- __field(char *, fct)
- __field(u64, p1)
- __field(u64, p2)
- __field(u64, p3)
- __field(u64, p4)
- __field(unsigned long, r4)
- __field(long, rc)
- ),
-
- TP_fast_assign(
- __entry->unit_address = unit_address;
- __entry->fct = fct;
- __entry->p1 = p1;
- __entry->p2 = p2;
- __entry->p3 = p3;
- __entry->p4 = p4;
- __entry->r4 = r4;
- __entry->rc = rc;
- ),
-
- TP_printk("unit_address=%#.16llx %s(%#llx, %#llx, %#llx, %#llx, R4: %#lx)): %li",
- __entry->unit_address,
- __entry->fct,
- __entry->p1,
- __entry->p2,
- __entry->p3,
- __entry->p4,
- __entry->r4,
- __entry->rc
- )
-);
-
-TRACE_EVENT(cxl_hcall_attach,
- TP_PROTO(u64 unit_address, u64 phys_addr, unsigned long process_token,
- unsigned long mmio_addr, unsigned long mmio_size, long rc),
-
- TP_ARGS(unit_address, phys_addr, process_token,
- mmio_addr, mmio_size, rc),
-
- TP_STRUCT__entry(
- __field(u64, unit_address)
- __field(u64, phys_addr)
- __field(unsigned long, process_token)
- __field(unsigned long, mmio_addr)
- __field(unsigned long, mmio_size)
- __field(long, rc)
- ),
-
- TP_fast_assign(
- __entry->unit_address = unit_address;
- __entry->phys_addr = phys_addr;
- __entry->process_token = process_token;
- __entry->mmio_addr = mmio_addr;
- __entry->mmio_size = mmio_size;
- __entry->rc = rc;
- ),
-
- TP_printk("unit_address=0x%016llx phys_addr=0x%016llx "
- "token=0x%.8lx mmio_addr=0x%lx mmio_size=0x%lx rc=%li",
- __entry->unit_address,
- __entry->phys_addr,
- __entry->process_token,
- __entry->mmio_addr,
- __entry->mmio_size,
- __entry->rc
- )
-);
-
-DEFINE_EVENT(cxl_hcall, cxl_hcall_detach,
- TP_PROTO(u64 unit_address, u64 process_token, long rc),
- TP_ARGS(unit_address, process_token, rc)
-);
-
-DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_function,
- TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
- u64 p4, unsigned long r4, long rc),
- TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc)
-);
-
-DEFINE_EVENT(cxl_hcall, cxl_hcall_collect_int_info,
- TP_PROTO(u64 unit_address, u64 process_token, long rc),
- TP_ARGS(unit_address, process_token, rc)
-);
-
-TRACE_EVENT(cxl_hcall_control_faults,
- TP_PROTO(u64 unit_address, u64 process_token,
- u64 control_mask, u64 reset_mask, unsigned long r4,
- long rc),
-
- TP_ARGS(unit_address, process_token,
- control_mask, reset_mask, r4, rc),
-
- TP_STRUCT__entry(
- __field(u64, unit_address)
- __field(u64, process_token)
- __field(u64, control_mask)
- __field(u64, reset_mask)
- __field(unsigned long, r4)
- __field(long, rc)
- ),
-
- TP_fast_assign(
- __entry->unit_address = unit_address;
- __entry->process_token = process_token;
- __entry->control_mask = control_mask;
- __entry->reset_mask = reset_mask;
- __entry->r4 = r4;
- __entry->rc = rc;
- ),
-
- TP_printk("unit_address=0x%016llx process_token=0x%llx "
- "control_mask=%#llx reset_mask=%#llx r4=%#lx rc=%li",
- __entry->unit_address,
- __entry->process_token,
- __entry->control_mask,
- __entry->reset_mask,
- __entry->r4,
- __entry->rc
- )
-);
-
-DEFINE_EVENT(cxl_hcall_control, cxl_hcall_control_facility,
- TP_PROTO(u64 unit_address, char *fct, u64 p1, u64 p2, u64 p3,
- u64 p4, unsigned long r4, long rc),
- TP_ARGS(unit_address, fct, p1, p2, p3, p4, r4, rc)
-);
-
-TRACE_EVENT(cxl_hcall_download_facility,
- TP_PROTO(u64 unit_address, char *fct, u64 list_address, u64 num,
- unsigned long r4, long rc),
-
- TP_ARGS(unit_address, fct, list_address, num, r4, rc),
-
- TP_STRUCT__entry(
- __field(u64, unit_address)
- __field(char *, fct)
- __field(u64, list_address)
- __field(u64, num)
- __field(unsigned long, r4)
- __field(long, rc)
- ),
-
- TP_fast_assign(
- __entry->unit_address = unit_address;
- __entry->fct = fct;
- __entry->list_address = list_address;
- __entry->num = num;
- __entry->r4 = r4;
- __entry->rc = rc;
- ),
-
- TP_printk("%#.16llx, %s(%#llx, %#llx), %#lx): %li",
- __entry->unit_address,
- __entry->fct,
- __entry->list_address,
- __entry->num,
- __entry->r4,
- __entry->rc
- )
-);
-
-#endif /* _CXL_TRACE_H */
-
-/* This part must be outside protection */
-#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace
-#include <trace/define_trace.h>
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
deleted file mode 100644
index 6332db8044bd..000000000000
--- a/drivers/misc/cxl/vphb.c
+++ /dev/null
@@ -1,309 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/pci.h>
-#include <misc/cxl.h>
-#include "cxl.h"
-
-static int cxl_pci_probe_mode(struct pci_bus *bus)
-{
- return PCI_PROBE_NORMAL;
-}
-
-static int cxl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
-{
- return -ENODEV;
-}
-
-static void cxl_teardown_msi_irqs(struct pci_dev *pdev)
-{
- /*
- * MSI should never be set but need still need to provide this call
- * back.
- */
-}
-
-static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
-{
- struct pci_controller *phb;
- struct cxl_afu *afu;
- struct cxl_context *ctx;
-
- phb = pci_bus_to_host(dev->bus);
- afu = (struct cxl_afu *)phb->private_data;
-
- if (!cxl_ops->link_ok(afu->adapter, afu)) {
- dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
- return false;
- }
-
- dev->dev.archdata.dma_offset = PAGE_OFFSET;
-
- /*
- * Allocate a context to do cxl things too. If we eventually do real
- * DMA ops, we'll need a default context to attach them to
- */
- ctx = cxl_dev_context_init(dev);
- if (IS_ERR(ctx))
- return false;
- dev->dev.archdata.cxl_ctx = ctx;
-
- return (cxl_ops->afu_check_and_enable(afu) == 0);
-}
-
-static void cxl_pci_disable_device(struct pci_dev *dev)
-{
- struct cxl_context *ctx = cxl_get_context(dev);
-
- if (ctx) {
- if (ctx->status == STARTED) {
- dev_err(&dev->dev, "Default context started\n");
- return;
- }
- dev->dev.archdata.cxl_ctx = NULL;
- cxl_release_context(ctx);
- }
-}
-
-static void cxl_pci_reset_secondary_bus(struct pci_dev *dev)
-{
- /* Should we do an AFU reset here ? */
-}
-
-static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
-{
- return (bus << 8) + devfn;
-}
-
-static inline struct cxl_afu *pci_bus_to_afu(struct pci_bus *bus)
-{
- struct pci_controller *phb = bus ? pci_bus_to_host(bus) : NULL;
-
- return phb ? phb->private_data : NULL;
-}
-
-static void cxl_afu_configured_put(struct cxl_afu *afu)
-{
- atomic_dec_if_positive(&afu->configured_state);
-}
-
-static bool cxl_afu_configured_get(struct cxl_afu *afu)
-{
- return atomic_inc_unless_negative(&afu->configured_state);
-}
-
-static inline int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
- struct cxl_afu *afu, int *_record)
-{
- int record;
-
- record = cxl_pcie_cfg_record(bus->number, devfn);
- if (record > afu->crs_num)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *_record = record;
- return 0;
-}
-
-static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- int rc, record;
- struct cxl_afu *afu;
- u8 val8;
- u16 val16;
- u32 val32;
-
- afu = pci_bus_to_afu(bus);
- /* Grab a reader lock on afu. */
- if (afu == NULL || !cxl_afu_configured_get(afu))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- rc = cxl_pcie_config_info(bus, devfn, afu, &record);
- if (rc)
- goto out;
-
- switch (len) {
- case 1:
- rc = cxl_ops->afu_cr_read8(afu, record, offset, &val8);
- *val = val8;
- break;
- case 2:
- rc = cxl_ops->afu_cr_read16(afu, record, offset, &val16);
- *val = val16;
- break;
- case 4:
- rc = cxl_ops->afu_cr_read32(afu, record, offset, &val32);
- *val = val32;
- break;
- default:
- WARN_ON(1);
- }
-
-out:
- cxl_afu_configured_put(afu);
- return rc ? PCIBIOS_DEVICE_NOT_FOUND : 0;
-}
-
-static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- int rc, record;
- struct cxl_afu *afu;
-
- afu = pci_bus_to_afu(bus);
- /* Grab a reader lock on afu. */
- if (afu == NULL || !cxl_afu_configured_get(afu))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- rc = cxl_pcie_config_info(bus, devfn, afu, &record);
- if (rc)
- goto out;
-
- switch (len) {
- case 1:
- rc = cxl_ops->afu_cr_write8(afu, record, offset, val & 0xff);
- break;
- case 2:
- rc = cxl_ops->afu_cr_write16(afu, record, offset, val & 0xffff);
- break;
- case 4:
- rc = cxl_ops->afu_cr_write32(afu, record, offset, val);
- break;
- default:
- WARN_ON(1);
- }
-
-out:
- cxl_afu_configured_put(afu);
- return rc ? PCIBIOS_SET_FAILED : 0;
-}
-
-static struct pci_ops cxl_pcie_pci_ops =
-{
- .read = cxl_pcie_read_config,
- .write = cxl_pcie_write_config,
-};
-
-
-static struct pci_controller_ops cxl_pci_controller_ops =
-{
- .probe_mode = cxl_pci_probe_mode,
- .enable_device_hook = cxl_pci_enable_device_hook,
- .disable_device = cxl_pci_disable_device,
- .release_device = cxl_pci_disable_device,
- .reset_secondary_bus = cxl_pci_reset_secondary_bus,
- .setup_msi_irqs = cxl_setup_msi_irqs,
- .teardown_msi_irqs = cxl_teardown_msi_irqs,
-};
-
-int cxl_pci_vphb_add(struct cxl_afu *afu)
-{
- struct pci_controller *phb;
- struct device_node *vphb_dn;
- struct device *parent;
-
- /*
- * If there are no AFU configuration records we won't have anything to
- * expose under the vPHB, so skip creating one, returning success since
- * this is still a valid case. This will also opt us out of EEH
- * handling since we won't have anything special to do if there are no
- * kernel drivers attached to the vPHB, and EEH handling is not yet
- * supported in the peer model.
- */
- if (!afu->crs_num)
- return 0;
-
- /* The parent device is the adapter. Reuse the device node of
- * the adapter.
- * We don't seem to care what device node is used for the vPHB,
- * but tools such as lsvpd walk up the device parents looking
- * for a valid location code, so we might as well show devices
- * attached to the adapter as being located on that adapter.
- */
- parent = afu->adapter->dev.parent;
- vphb_dn = parent->of_node;
-
- /* Alloc and setup PHB data structure */
- phb = pcibios_alloc_controller(vphb_dn);
- if (!phb)
- return -ENODEV;
-
- /* Setup parent in sysfs */
- phb->parent = parent;
-
- /* Setup the PHB using arch provided callback */
- phb->ops = &cxl_pcie_pci_ops;
- phb->cfg_addr = NULL;
- phb->cfg_data = NULL;
- phb->private_data = afu;
- phb->controller_ops = cxl_pci_controller_ops;
-
- /* Scan the bus */
- pcibios_scan_phb(phb);
- if (phb->bus == NULL)
- return -ENXIO;
-
- /* Set release hook on root bus */
- pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge),
- pcibios_free_controller_deferred,
- (void *) phb);
-
- /* Claim resources. This might need some rework as well depending
- * whether we are doing probe-only or not, like assigning unassigned
- * resources etc...
- */
- pcibios_claim_one_bus(phb->bus);
-
- /* Add probed PCI devices to the device model */
- pci_bus_add_devices(phb->bus);
-
- afu->phb = phb;
-
- return 0;
-}
-
-void cxl_pci_vphb_remove(struct cxl_afu *afu)
-{
- struct pci_controller *phb;
-
- /* If there is no configuration record we won't have one of these */
- if (!afu || !afu->phb)
- return;
-
- phb = afu->phb;
- afu->phb = NULL;
-
- pci_remove_root_bus(phb->bus);
- /*
- * We don't free phb here - that's handled by
- * pcibios_free_controller_deferred()
- */
-}
-
-bool cxl_pci_is_vphb_device(struct pci_dev *dev)
-{
- struct pci_controller *phb;
-
- phb = pci_bus_to_host(dev->bus);
-
- return (phb->ops == &cxl_pcie_pci_ops);
-}
-
-struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev)
-{
- struct pci_controller *phb;
-
- phb = pci_bus_to_host(dev->bus);
-
- return (struct cxl_afu *)phb->private_data;
-}
-EXPORT_SYMBOL_GPL(cxl_pci_to_afu);
-
-unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev)
-{
- return cxl_pcie_cfg_record(dev->bus->number, dev->devfn);
-}
-EXPORT_SYMBOL_GPL(cxl_pci_to_cfg_record);
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 0a7c7f29406c..f721825199ce 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -18,8 +18,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/nvmem-provider.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regmap.h>
@@ -252,7 +250,7 @@ static const struct i2c_device_id at24_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, at24_ids);
-static const struct of_device_id __maybe_unused at24_of_match[] = {
+static const struct of_device_id at24_of_match[] = {
{ .compatible = "atmel,24c00", .data = &at24_data_24c00 },
{ .compatible = "atmel,24c01", .data = &at24_data_24c01 },
{ .compatible = "atmel,24cs01", .data = &at24_data_24cs01 },
@@ -286,7 +284,7 @@ static const struct of_device_id __maybe_unused at24_of_match[] = {
};
MODULE_DEVICE_TABLE(of, at24_of_match);
-static const struct acpi_device_id __maybe_unused at24_acpi_ids[] = {
+static const struct acpi_device_id at24_acpi_ids[] = {
{ "INT3499", (kernel_ulong_t)&at24_data_INT3499 },
{ "TPF0001", (kernel_ulong_t)&at24_data_24c1024 },
{ /* END OF LIST */ }
@@ -848,8 +846,8 @@ static struct i2c_driver at24_driver = {
.driver = {
.name = "at24",
.pm = &at24_pm_ops,
- .of_match_table = of_match_ptr(at24_of_match),
- .acpi_match_table = ACPI_PTR(at24_acpi_ids),
+ .of_match_table = at24_of_match,
+ .acpi_match_table = at24_acpi_ids,
},
.probe = at24_probe,
.remove = at24_remove,
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861dbff27e..6c24426104ba 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -29,6 +29,13 @@ static const unsigned long rodata = 0xAA55AA55;
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
/*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
+/*
* This just returns to the caller. It is designed to be copied into
* non-executable memory regions.
*/
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
{
void (*func)(void);
func_desc_t fdesc;
- void *do_nothing_text = dereference_function_descriptor(do_nothing);
- pr_info("attempting ok execution at %px\n", do_nothing_text);
+ pr_info("attempting ok execution at %px\n", do_nothing_ptr);
do_nothing();
if (write == CODE_WRITE) {
- memcpy(dst, do_nothing_text, EXEC_SIZE);
+ memcpy(dst, do_nothing_ptr, EXEC_SIZE);
flush_icache_range((unsigned long)dst,
(unsigned long)dst + EXEC_SIZE);
}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
void __init lkdtm_perms_init(void)
{
+ do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
/* Make sure we can write to __ro_after_init values during __init */
ro_after_init |= 0xAA;
}
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 7a3c34306de9..697a008c14d3 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -202,7 +202,7 @@ xpc_start_hb_beater(void)
static void
xpc_stop_hb_beater(void)
{
- del_timer_sync(&xpc_hb_timer);
+ timer_delete_sync(&xpc_hb_timer);
xpc_arch_ops.heartbeat_exit();
}
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 1999d02923de..d0467010558c 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -291,7 +291,7 @@ static int __xpc_partition_disengaged(struct xpc_partition *part,
/* Cancel the timer function if not called from it */
if (!from_timer)
- del_timer_sync(&part->disengage_timer);
+ timer_delete_sync(&part->disengage_timer);
DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING &&
part->act_state != XPC_P_AS_INACTIVE);
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index bdb22998357e..dacb5bd9bb71 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -147,13 +147,13 @@ void mmc_retune_disable(struct mmc_host *host)
{
mmc_retune_unpause(host);
host->can_retune = 0;
- del_timer_sync(&host->retune_timer);
+ timer_delete_sync(&host->retune_timer);
mmc_retune_clear(host);
}
void mmc_retune_timer_stop(struct mmc_host *host)
{
- del_timer_sync(&host->retune_timer);
+ timer_delete_sync(&host->retune_timer);
}
EXPORT_SYMBOL(mmc_retune_timer_stop);
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 24fffc702a94..14e981b834b6 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1592,7 +1592,7 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq)
WARN_ON(host->cmd || host->data);
- del_timer(&host->timer);
+ timer_delete(&host->timer);
/*
* Update the MMC clock rate if necessary. This may be
@@ -2357,7 +2357,7 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
if (slot->detect_pin) {
free_irq(gpiod_to_irq(slot->detect_pin), slot);
- del_timer_sync(&slot->detect_timer);
+ timer_delete_sync(&slot->detect_timer);
}
slot->host->slot[id] = NULL;
@@ -2585,7 +2585,7 @@ err_init_slot:
pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
- del_timer_sync(&host->timer);
+ timer_delete_sync(&host->timer);
if (!IS_ERR(host->dma.chan))
dma_release_channel(host->dma.chan);
err_dma_probe_defer:
@@ -2613,7 +2613,7 @@ static void atmci_remove(struct platform_device *pdev)
atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
atmci_readl(host, ATMCI_SR);
- del_timer_sync(&host->timer);
+ timer_delete_sync(&host->timer);
if (!IS_ERR(host->dma.chan))
dma_release_channel(host->dma.chan);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index bb596d169420..578290015e5b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2040,10 +2040,10 @@ static bool dw_mci_clear_pending_cmd_complete(struct dw_mci *host)
* Really be certain that the timer has stopped. This is a bit of
* paranoia and could only really happen if we had really bad
* interrupt latency and the interrupt routine and timeout were
- * running concurrently so that the del_timer() in the interrupt
+ * running concurrently so that the timer_delete() in the interrupt
* handler couldn't run.
*/
- WARN_ON(del_timer_sync(&host->cto_timer));
+ WARN_ON(timer_delete_sync(&host->cto_timer));
clear_bit(EVENT_CMD_COMPLETE, &host->pending_events);
return true;
@@ -2055,7 +2055,7 @@ static bool dw_mci_clear_pending_data_complete(struct dw_mci *host)
return false;
/* Extra paranoia just like dw_mci_clear_pending_cmd_complete() */
- WARN_ON(del_timer_sync(&host->dto_timer));
+ WARN_ON(timer_delete_sync(&host->dto_timer));
clear_bit(EVENT_DATA_COMPLETE, &host->pending_events);
return true;
@@ -2788,7 +2788,7 @@ done:
static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)
{
- del_timer(&host->cto_timer);
+ timer_delete(&host->cto_timer);
if (!host->cmd_status)
host->cmd_status = status;
@@ -2832,13 +2832,13 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
dw_mci_cmd_interrupt(host, pending);
spin_unlock(&host->irq_lock);
- del_timer(&host->cmd11_timer);
+ timer_delete(&host->cmd11_timer);
}
if (pending & DW_MCI_CMD_ERROR_FLAGS) {
spin_lock(&host->irq_lock);
- del_timer(&host->cto_timer);
+ timer_delete(&host->cto_timer);
mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
host->cmd_status = pending;
smp_wmb(); /* drain writebuffer */
@@ -2851,7 +2851,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
spin_lock(&host->irq_lock);
if (host->quirks & DW_MMC_QUIRK_EXTENDED_TMOUT)
- del_timer(&host->dto_timer);
+ timer_delete(&host->dto_timer);
/* if there is an error report DATA_ERROR */
mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS);
@@ -2872,7 +2872,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
if (pending & SDMMC_INT_DATA_OVER) {
spin_lock(&host->irq_lock);
- del_timer(&host->dto_timer);
+ timer_delete(&host->dto_timer);
mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);
if (!host->data_status)
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 596012d5afac..bd1662e275d4 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -862,7 +862,7 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
if (host->req && cmd && irq_reg) {
if (test_and_clear_bit(0, &host->waiting)) {
- del_timer(&host->timeout_timer);
+ timer_delete(&host->timeout_timer);
if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
cmd->error = -ETIMEDOUT;
@@ -1162,7 +1162,7 @@ static void jz4740_mmc_remove(struct platform_device *pdev)
{
struct jz4740_mmc_host *host = platform_get_drvdata(pdev);
- del_timer_sync(&host->timeout_timer);
+ timer_delete_sync(&host->timeout_timer);
jz4740_mmc_set_irq_enabled(host, 0xff, false);
jz4740_mmc_reset(host);
diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c
index ad351805eed4..e0ae5a0c9670 100644
--- a/drivers/mmc/host/meson-mx-sdio.c
+++ b/drivers/mmc/host/meson-mx-sdio.c
@@ -446,7 +446,7 @@ static irqreturn_t meson_mx_mmc_irq_thread(int irq, void *irq_data)
if (WARN_ON(!cmd))
return IRQ_HANDLED;
- del_timer_sync(&host->cmd_timeout);
+ timer_delete_sync(&host->cmd_timeout);
if (cmd->data) {
dma_unmap_sg(mmc_dev(host->mmc), cmd->data->sg,
@@ -733,7 +733,7 @@ static void meson_mx_mmc_remove(struct platform_device *pdev)
struct meson_mx_mmc_host *host = platform_get_drvdata(pdev);
struct device *slot_dev = mmc_dev(host->mmc);
- del_timer_sync(&host->cmd_timeout);
+ timer_delete_sync(&host->cmd_timeout);
mmc_remove_host(host->mmc);
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index b92f3ba38663..912ffacbad88 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -464,7 +464,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
struct mmc_command *cmd = mrq->cmd;
u32 err_status = 0;
- del_timer(&host->timer);
+ timer_delete(&host->timer);
host->mrq = NULL;
host->intr_en &= MVSD_NOR_CARD_INT;
@@ -803,7 +803,7 @@ static void mvsd_remove(struct platform_device *pdev)
struct mvsd_host *host = mmc_priv(mmc);
mmc_remove_host(mmc);
- del_timer_sync(&host->timer);
+ timer_delete_sync(&host->timer);
mvsd_power_down(host);
if (!IS_ERR(host->clk))
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 0a9affd12532..95d8d40a06a8 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -352,7 +352,7 @@ static void mxcmci_dma_callback(void *data)
struct mxcmci_host *host = data;
u32 stat;
- del_timer(&host->watchdog);
+ timer_delete(&host->watchdog);
stat = mxcmci_readl(host, MMC_REG_STATUS);
@@ -737,7 +737,7 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
mxcmci_cmd_done(host, stat);
if (mxcmci_use_dma(host) && (stat & STATUS_WRITE_OP_DONE)) {
- del_timer(&host->watchdog);
+ timer_delete(&host->watchdog);
mxcmci_data_done(host, stat);
}
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 3cdb2fc44965..c50617d03709 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -214,7 +214,7 @@ static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed)
host->mmc = slot->mmc;
spin_unlock_irqrestore(&host->slot_lock, flags);
no_claim:
- del_timer(&host->clk_timer);
+ timer_delete(&host->clk_timer);
if (host->current_slot != slot || !claimed)
mmc_omap_fclk_offdelay(host->current_slot);
@@ -273,7 +273,7 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled)
/* Keeps clock running for at least 8 cycles on valid freq */
mod_timer(&host->clk_timer, jiffies + HZ/10);
else {
- del_timer(&host->clk_timer);
+ timer_delete(&host->clk_timer);
mmc_omap_fclk_offdelay(slot);
mmc_omap_fclk_enable(host, 0);
}
@@ -564,7 +564,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
{
host->cmd = NULL;
- del_timer(&host->cmd_abort_timer);
+ timer_delete(&host->cmd_abort_timer);
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136) {
@@ -836,7 +836,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
if (cmd_error && host->data) {
- del_timer(&host->cmd_abort_timer);
+ timer_delete(&host->cmd_abort_timer);
host->abort = 1;
OMAP_MMC_WRITE(host, IE, 0);
disable_irq_nosync(host->irq);
@@ -1365,7 +1365,7 @@ static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
cancel_work_sync(&slot->cover_bh_work);
- del_timer_sync(&slot->cover_timer);
+ timer_delete_sync(&slot->cover_timer);
flush_workqueue(slot->host->mmc_omap_wq);
mmc_remove_host(mmc);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5f91b44891f9..5f78be7ae16d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -517,9 +517,9 @@ EXPORT_SYMBOL_GPL(sdhci_mod_timer);
static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq)
{
if (sdhci_data_line_cmd(mrq->cmd))
- del_timer(&host->data_timer);
+ timer_delete(&host->data_timer);
else
- del_timer(&host->timer);
+ timer_delete(&host->timer);
}
static inline bool sdhci_has_requests(struct sdhci_host *host)
@@ -4976,8 +4976,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
free_irq(host->irq, host);
- del_timer_sync(&host->timer);
- del_timer_sync(&host->data_timer);
+ timer_delete_sync(&host->timer);
+ timer_delete_sync(&host->data_timer);
destroy_workqueue(host->complete_wq);
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index aea14bf3e2e8..713223f2d377 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -735,7 +735,7 @@ static void tifm_sd_end_cmd(struct work_struct *t)
spin_lock_irqsave(&sock->lock, flags);
- del_timer(&host->timer);
+ timer_delete(&host->timer);
mrq = host->req;
host->req = NULL;
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index f77457105ec3..909d80a02824 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -971,7 +971,7 @@ static void via_sdc_finish_bh_work(struct work_struct *t)
spin_lock_irqsave(&host->lock, flags);
- del_timer(&host->timer);
+ timer_delete(&host->timer);
mrq = host->mrq;
host->mrq = NULL;
host->cmd = NULL;
@@ -1202,7 +1202,7 @@ static void via_sd_remove(struct pci_dev *pcidev)
free_irq(pcidev->irq, sdhost);
- del_timer_sync(&sdhost->timer);
+ timer_delete_sync(&sdhost->timer);
cancel_work_sync(&sdhost->finish_bh_work);
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index fd67c0682b38..dd71e5b8e1a5 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -1452,7 +1452,7 @@ static int __command_read_data(struct vub300_mmc_host *vub300,
(linear_length / 16384));
add_timer(&vub300->sg_transfer_timer);
usb_sg_wait(&vub300->sg_request);
- del_timer(&vub300->sg_transfer_timer);
+ timer_delete(&vub300->sg_transfer_timer);
if (vub300->sg_request.status < 0) {
cmd->error = vub300->sg_request.status;
data->bytes_xfered = 0;
@@ -1572,7 +1572,7 @@ static int __command_write_data(struct vub300_mmc_host *vub300,
if (cmd->error) {
data->bytes_xfered = 0;
} else {
- del_timer(&vub300->sg_transfer_timer);
+ timer_delete(&vub300->sg_transfer_timer);
if (vub300->sg_request.status < 0) {
cmd->error = vub300->sg_request.status;
data->bytes_xfered = 0;
@@ -2339,7 +2339,7 @@ static int vub300_probe(struct usb_interface *interface,
return 0;
error6:
- del_timer_sync(&vub300->inactivity_timer);
+ timer_delete_sync(&vub300->inactivity_timer);
error5:
mmc_free_host(mmc);
/*
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 8b268e8a0ec9..d5974b355a5a 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1261,7 +1261,7 @@ static void wbsd_free_mmc(struct device *dev)
host = mmc_priv(mmc);
BUG_ON(host == NULL);
- del_timer_sync(&host->ignore_timer);
+ timer_delete_sync(&host->ignore_timer);
mmc_free_host(mmc);
}
diff --git a/drivers/most/most_usb.c b/drivers/most/most_usb.c
index 485d5ca39951..2199ba821922 100644
--- a/drivers/most/most_usb.c
+++ b/drivers/most/most_usb.c
@@ -257,7 +257,7 @@ static int hdm_poison_channel(struct most_interface *iface, int channel)
mdev->padding_active[channel] = false;
if (mdev->conf[channel].data_type == MOST_CH_ASYNC) {
- del_timer_sync(&mdev->link_stat_timer);
+ timer_delete_sync(&mdev->link_stat_timer);
cancel_work_sync(&mdev->poll_work_obj);
}
mutex_unlock(&mdev->io_mutex);
@@ -1115,7 +1115,7 @@ static void hdm_disconnect(struct usb_interface *interface)
mdev->usb_device = NULL;
mutex_unlock(&mdev->io_mutex);
- del_timer_sync(&mdev->link_stat_timer);
+ timer_delete_sync(&mdev->link_stat_timer);
cancel_work_sync(&mdev->poll_work_obj);
if (mdev->dci)
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
index b5b3c4c44a94..d28d4f1790f5 100644
--- a/drivers/mtd/sm_ftl.c
+++ b/drivers/mtd/sm_ftl.c
@@ -1067,7 +1067,7 @@ static int sm_write(struct mtd_blktrans_dev *dev,
sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);
/* No need in flush thread running now */
- del_timer(&ftl->timer);
+ timer_delete(&ftl->timer);
mutex_lock(&ftl->mutex);
zone = sm_get_zone(ftl, zone_num);
@@ -1111,7 +1111,7 @@ static void sm_release(struct mtd_blktrans_dev *dev)
{
struct sm_ftl *ftl = dev->priv;
- del_timer_sync(&ftl->timer);
+ timer_delete_sync(&ftl->timer);
cancel_work_sync(&ftl->flush_work);
mutex_lock(&ftl->mutex);
sm_cache_flush(ftl);
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 530c15d6a5eb..602e6e1adf00 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -616,7 +616,7 @@ int arcnet_close(struct net_device *dev)
struct arcnet_local *lp = netdev_priv(dev);
arcnet_led_event(dev, ARCNET_LED_EVENT_STOP);
- del_timer_sync(&lp->timer);
+ timer_delete_sync(&lp->timer);
netif_stop_queue(dev);
netif_carrier_off(dev);
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index c5e571ec94c9..0472bcdff130 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -251,18 +251,33 @@ static int com20020pci_probe(struct pci_dev *pdev,
card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
GFP_KERNEL, "arc%d-%d-tx",
dev->dev_id, i);
+ if (!card->tx_led.default_trigger) {
+ ret = -ENOMEM;
+ goto err_free_arcdev;
+ }
card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"pci:green:tx:%d-%d",
dev->dev_id, i);
-
+ if (!card->tx_led.name) {
+ ret = -ENOMEM;
+ goto err_free_arcdev;
+ }
card->tx_led.dev = &dev->dev;
card->recon_led.brightness_set = led_recon_set;
card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
GFP_KERNEL, "arc%d-%d-recon",
dev->dev_id, i);
+ if (!card->recon_led.default_trigger) {
+ ret = -ENOMEM;
+ goto err_free_arcdev;
+ }
card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"pci:red:recon:%d-%d",
dev->dev_id, i);
+ if (!card->recon_led.name) {
+ ret = -ENOMEM;
+ goto err_free_arcdev;
+ }
card->recon_led.dev = &dev->dev;
ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
index 90ea3dc0fb10..c398ac42eae9 100644
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -330,7 +330,7 @@ static int ldisc_open(struct tty_struct *tty)
ser->tty = tty_kref_get(tty);
ser->dev = dev;
debugfs_init(ser, tty);
- tty->receive_room = N_TTY_BUF_SIZE;
+ tty->receive_room = 4096;
tty->disc_data = ser;
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
rtnl_lock();
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
index 21a61b86f67d..adf3970f070f 100644
--- a/drivers/net/can/grcan.c
+++ b/drivers/net/can/grcan.c
@@ -778,7 +778,7 @@ static irqreturn_t grcan_interrupt(int irq, void *dev_id)
*/
if (priv->need_txbug_workaround &&
(sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
- del_timer(&priv->hang_timer);
+ timer_delete(&priv->hang_timer);
}
/* Frame(s) received or transmitted */
@@ -817,8 +817,8 @@ static void grcan_running_reset(struct timer_list *t)
spin_lock_irqsave(&priv->lock, flags);
priv->resetting = false;
- del_timer(&priv->hang_timer);
- del_timer(&priv->rr_timer);
+ timer_delete(&priv->hang_timer);
+ timer_delete(&priv->rr_timer);
if (!priv->closing) {
/* Save and reset - config register preserved by grcan_reset */
@@ -1108,8 +1108,8 @@ static int grcan_close(struct net_device *dev)
priv->closing = true;
if (priv->need_txbug_workaround) {
spin_unlock_irqrestore(&priv->lock, flags);
- del_timer_sync(&priv->hang_timer);
- del_timer_sync(&priv->rr_timer);
+ timer_delete_sync(&priv->hang_timer);
+ timer_delete_sync(&priv->rr_timer);
spin_lock_irqsave(&priv->lock, flags);
}
netif_stop_queue(dev);
@@ -1147,7 +1147,7 @@ static void grcan_transmit_catch_up(struct net_device *dev)
* so prevent a running reset while catching up
*/
if (priv->need_txbug_workaround)
- del_timer(&priv->hang_timer);
+ timer_delete(&priv->hang_timer);
}
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index fa04a7ced02b..cf0d51805272 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -631,7 +631,7 @@ static int kvaser_pciefd_bus_on(struct kvaser_pciefd_can *can)
u32 mode;
unsigned long irq;
- del_timer(&can->bec_poll_timer);
+ timer_delete(&can->bec_poll_timer);
if (!completion_done(&can->flush_comp))
kvaser_pciefd_start_controller_flush(can);
@@ -742,7 +742,7 @@ static int kvaser_pciefd_stop(struct net_device *netdev)
ret = -ETIMEDOUT;
} else {
iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
- del_timer(&can->bec_poll_timer);
+ timer_delete(&can->bec_poll_timer);
}
can->can.state = CAN_STATE_STOPPED;
close_candev(netdev);
@@ -1854,7 +1854,7 @@ static void kvaser_pciefd_remove_all_ctrls(struct kvaser_pciefd *pcie)
if (can) {
iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
unregister_candev(can->can.dev);
- del_timer(&can->bec_poll_timer);
+ timer_delete(&can->bec_poll_timer);
kvaser_pciefd_pwm_stop(can);
free_candev(can->can.dev);
}
diff --git a/drivers/net/can/sja1000/peak_pcmcia.c b/drivers/net/can/sja1000/peak_pcmcia.c
index ebd5941c3f53..6c7b1c58f85f 100644
--- a/drivers/net/can/sja1000/peak_pcmcia.c
+++ b/drivers/net/can/sja1000/peak_pcmcia.c
@@ -167,7 +167,7 @@ static void pcan_start_led_timer(struct pcan_pccard *card)
*/
static void pcan_stop_led_timer(struct pcan_pccard *card)
{
- del_timer_sync(&card->led_timer);
+ timer_delete_sync(&card->led_timer);
}
/*
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 901929f96b38..29a89ab4b789 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -7350,13 +7350,13 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
err = mv88e6xxx_switch_reset(chip);
mv88e6xxx_reg_unlock(chip);
if (err)
- goto out;
+ goto out_phy;
if (np) {
chip->irq = of_irq_get(np, 0);
if (chip->irq == -EPROBE_DEFER) {
err = chip->irq;
- goto out;
+ goto out_phy;
}
}
@@ -7375,7 +7375,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
mv88e6xxx_reg_unlock(chip);
if (err)
- goto out;
+ goto out_phy;
if (chip->info->g2_irqs > 0) {
err = mv88e6xxx_g2_irq_setup(chip);
@@ -7409,6 +7409,8 @@ out_g1_irq:
mv88e6xxx_g1_irq_free(chip);
else
mv88e6xxx_irq_poll_free(chip);
+out_phy:
+ mv88e6xxx_phy_destroy(chip);
out:
if (pdata)
dev_put(pdata->netdev);
@@ -7431,7 +7433,6 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
mv88e6xxx_ptp_free(chip);
}
- mv88e6xxx_phy_destroy(chip);
mv88e6xxx_unregister_switch(chip);
mv88e6xxx_g1_vtu_prob_irq_free(chip);
@@ -7444,6 +7445,8 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
mv88e6xxx_g1_irq_free(chip);
else
mv88e6xxx_irq_poll_free(chip);
+
+ mv88e6xxx_phy_destroy(chip);
}
static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
diff --git a/drivers/net/dsa/mv88e6xxx/phy.c b/drivers/net/dsa/mv88e6xxx/phy.c
index 8bb88b3d900d..b6d249eb64e7 100644
--- a/drivers/net/dsa/mv88e6xxx/phy.c
+++ b/drivers/net/dsa/mv88e6xxx/phy.c
@@ -206,7 +206,7 @@ static int mv88e6xxx_phy_ppu_access_get(struct mv88e6xxx_chip *chip)
}
chip->ppu_disabled = 1;
} else {
- del_timer(&chip->ppu_timer);
+ timer_delete(&chip->ppu_timer);
ret = 0;
}
@@ -229,7 +229,10 @@ static void mv88e6xxx_phy_ppu_state_init(struct mv88e6xxx_chip *chip)
static void mv88e6xxx_phy_ppu_state_destroy(struct mv88e6xxx_chip *chip)
{
- del_timer_sync(&chip->ppu_timer);
+ mutex_lock(&chip->ppu_mutex);
+ timer_delete_sync(&chip->ppu_timer);
+ cancel_work_sync(&chip->ppu_work);
+ mutex_unlock(&chip->ppu_mutex);
}
int mv88e6185_phy_ppu_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
index 08b45fdd1d24..198e787e8560 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.c
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
@@ -842,7 +842,7 @@ static int sja1105_extts_enable(struct sja1105_private *priv,
if (on)
sja1105_ptp_extts_setup_timer(&priv->ptp_data);
else
- del_timer_sync(&priv->ptp_data.extts_timer);
+ timer_delete_sync(&priv->ptp_data.extts_timer);
return 0;
}
@@ -939,7 +939,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
if (IS_ERR_OR_NULL(ptp_data->clock))
return;
- del_timer_sync(&ptp_data->extts_timer);
+ timer_delete_sync(&ptp_data->extts_timer);
ptp_cancel_worker_sync(ptp_data->clock);
skb_queue_purge(&ptp_data->skb_txtstamp_queue);
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index a4938c6a5ebb..d6bdad4baadd 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -105,6 +105,7 @@ static void dummy_setup(struct net_device *dev)
dev->netdev_ops = &dummy_netdev_ops;
dev->ethtool_ops = &dummy_ethtool_ops;
dev->needs_free_netdev = true;
+ dev->request_ops_lock = true;
/* Fill in device structure with ethernet-generic values. */
dev->flags |= IFF_NOARP;
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 3c2efda916f1..5889759b8d83 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -254,7 +254,7 @@ static int eql_close(struct net_device *dev)
* at the data structure it scans every so often...
*/
- del_timer_sync(&eql->timer);
+ timer_delete_sync(&eql->timer);
eql_kill_slave_queue(&eql->queue);
diff --git a/drivers/net/ethernet/3com/3c515.c b/drivers/net/ethernet/3com/3c515.c
index 4725a8cfd695..8ba2ed87fe7c 100644
--- a/drivers/net/ethernet/3com/3c515.c
+++ b/drivers/net/ethernet/3com/3c515.c
@@ -1414,7 +1414,7 @@ static int corkscrew_close(struct net_device *dev)
dev->name, rx_nocopy, rx_copy, queued_packet);
}
- del_timer_sync(&vp->timer);
+ timer_delete_sync(&vp->timer);
/* Turn off statistics ASAP. We update lp->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);
diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c
index dc3b7c960611..b295d528a237 100644
--- a/drivers/net/ethernet/3com/3c574_cs.c
+++ b/drivers/net/ethernet/3com/3c574_cs.c
@@ -1140,7 +1140,7 @@ static int el3_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
- del_timer_sync(&lp->media);
+ timer_delete_sync(&lp->media);
return 0;
}
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
index be58dac0502a..ff331a3bde73 100644
--- a/drivers/net/ethernet/3com/3c589_cs.c
+++ b/drivers/net/ethernet/3com/3c589_cs.c
@@ -946,7 +946,7 @@ static int el3_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
- del_timer_sync(&lp->media);
+ timer_delete_sync(&lp->media);
return 0;
}
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 790270912913..1a10f5dbc4d7 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -2691,7 +2691,7 @@ vortex_down(struct net_device *dev, int final_down)
netdev_reset_queue(dev);
netif_stop_queue(dev);
- del_timer_sync(&vp->timer);
+ timer_delete_sync(&vp->timer);
/* Turn off statistics ASAP. We update dev->stats below. */
iowrite16(StatsDisable, ioaddr + EL3_CMD);
diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c
index fea489af72fb..e5be5044e1d4 100644
--- a/drivers/net/ethernet/8390/axnet_cs.c
+++ b/drivers/net/ethernet/8390/axnet_cs.c
@@ -504,7 +504,7 @@ static int axnet_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
- del_timer_sync(&info->watchdog);
+ timer_delete_sync(&info->watchdog);
return 0;
} /* axnet_close */
diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c
index 780fb4afb6af..a326f25dda09 100644
--- a/drivers/net/ethernet/8390/pcnet_cs.c
+++ b/drivers/net/ethernet/8390/pcnet_cs.c
@@ -947,7 +947,7 @@ static int pcnet_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
- del_timer_sync(&info->watchdog);
+ timer_delete_sync(&info->watchdog);
return 0;
} /* pcnet_close */
diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
index b325e0cef120..b398adacda91 100644
--- a/drivers/net/ethernet/agere/et131x.c
+++ b/drivers/net/ethernet/agere/et131x.c
@@ -3639,7 +3639,7 @@ static int et131x_close(struct net_device *netdev)
free_irq(adapter->pdev->irq, netdev);
/* Stop the error timer */
- return del_timer_sync(&adapter->error_timer);
+ return timer_delete_sync(&adapter->error_timer);
}
/* et131x_set_packet_filter - Configures the Rx Packet filtering */
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index c0a642568ac1..d748dc6de923 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2028,7 +2028,7 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
enum tx_sched_mode mode = TC_SCH_SP;
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
- int i, nstrict = 0, nwrr, qidx;
+ int i, nstrict = 0;
if (p->bands > AIROHA_NUM_QOS_QUEUES)
return -EINVAL;
@@ -2046,17 +2046,17 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
* lowest priorities with respect to SP ones.
* e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
*/
- nwrr = p->bands - nstrict;
- qidx = nstrict && nwrr ? nstrict : 0;
- for (i = 1; i <= p->bands; i++) {
- if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx)
+ for (i = 0; i < nstrict; i++) {
+ if (p->priomap[p->bands - i - 1] != i)
return -EINVAL;
-
- qidx = i == nwrr ? 0 : qidx + 1;
}
- for (i = 0; i < nwrr; i++)
+ for (i = 0; i < p->bands - nstrict; i++) {
+ if (p->priomap[i] != nstrict + i)
+ return -EINVAL;
+
w[i] = p->weights[nstrict + i];
+ }
if (!nstrict)
mode = TC_SCH_WRR8;
@@ -2358,7 +2358,7 @@ static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
return -EINVAL;
}
- opt->qid = channel;
+ opt->qid = AIROHA_NUM_TX_RING + channel;
return 0;
}
@@ -2454,6 +2454,19 @@ static void airoha_metadata_dst_free(struct airoha_gdm_port *port)
}
}
+bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
+ struct airoha_gdm_port *port)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ if (eth->ports[i] == port)
+ return true;
+ }
+
+ return false;
+}
+
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np, int index)
{
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 60690b685710..ec8908f904c6 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -532,6 +532,9 @@ u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val);
#define airoha_qdma_clear(qdma, offset, val) \
airoha_rmw((qdma)->regs, (offset), (val), 0)
+bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
+ struct airoha_gdm_port *port);
+
void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash);
int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
void *cb_priv);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 8b55e871352d..f10dab935cab 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -197,7 +197,8 @@ static int airoha_get_dsa_port(struct net_device **dev)
#endif
}
-static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe,
+static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
+ struct airoha_foe_entry *hwe,
struct net_device *dev, int type,
struct airoha_flow_data *data,
int l4proto)
@@ -225,6 +226,9 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe,
struct airoha_gdm_port *port = netdev_priv(dev);
u8 pse_port;
+ if (!airoha_is_valid_gdm_port(eth, port))
+ return -EINVAL;
+
if (dsa_port >= 0)
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
else
@@ -633,7 +637,7 @@ static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port,
!is_valid_ether_addr(data.eth.h_dest))
return -EINVAL;
- err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type,
+ err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type,
&data, l4proto);
if (err)
return err;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 70fa3adb4934..897720fdf5d8 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -3245,7 +3245,7 @@ static int ena_destroy_device(struct ena_adapter *adapter, bool graceful)
netif_carrier_off(netdev);
- del_timer_sync(&adapter->timer_service);
+ timer_delete_sync(&adapter->timer_service);
dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
adapter->dev_up_before_reset = dev_up;
@@ -4065,7 +4065,7 @@ err_free_msix:
ena_free_mgmnt_irq(adapter);
ena_disable_msix(adapter);
err_worker_destroy:
- del_timer(&adapter->timer_service);
+ timer_delete(&adapter->timer_service);
err_device_destroy:
ena_com_delete_host_info(ena_dev);
ena_com_admin_destroy(ena_dev);
@@ -4104,7 +4104,7 @@ static void __ena_shutoff(struct pci_dev *pdev, bool shutdown)
/* Make sure timer and reset routine won't be called after
* freeing device resources.
*/
- del_timer_sync(&adapter->timer_service);
+ timer_delete_sync(&adapter->timer_service);
cancel_work_sync(&adapter->reset_task);
rtnl_lock(); /* lock released inside the below if-else block */
diff --git a/drivers/net/ethernet/amd/a2065.c b/drivers/net/ethernet/amd/a2065.c
index 1ca26a8c40eb..b923ad9e1581 100644
--- a/drivers/net/ethernet/amd/a2065.c
+++ b/drivers/net/ethernet/amd/a2065.c
@@ -486,7 +486,7 @@ static int lance_close(struct net_device *dev)
volatile struct lance_regs *ll = lp->ll;
netif_stop_queue(dev);
- del_timer_sync(&lp->multicast_timer);
+ timer_delete_sync(&lp->multicast_timer);
/* Stop the card */
ll->rap = LE_CSR0;
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index f64f96fa17cf..86522e8574cb 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -1173,7 +1173,7 @@ static int amd8111e_close(struct net_device *dev)
/* Delete ipg timer */
if (lp->options & OPTION_DYN_IPG_ENABLE)
- del_timer_sync(&lp->ipg_data.ipg_timer);
+ timer_delete_sync(&lp->ipg_data.ipg_timer);
spin_unlock_irq(&lp->lock);
free_irq(dev->irq, dev);
@@ -1598,7 +1598,7 @@ static int __maybe_unused amd8111e_suspend(struct device *dev_d)
/* stop chip */
spin_lock_irq(&lp->lock);
if (lp->options & OPTION_DYN_IPG_ENABLE)
- del_timer_sync(&lp->ipg_data.ipg_timer);
+ timer_delete_sync(&lp->ipg_data.ipg_timer);
amd8111e_stop_chip(lp);
spin_unlock_irq(&lp->lock);
diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c
index ec8df05e7bf6..b072ca5930fc 100644
--- a/drivers/net/ethernet/amd/declance.c
+++ b/drivers/net/ethernet/amd/declance.c
@@ -842,7 +842,7 @@ static int lance_close(struct net_device *dev)
volatile struct lance_regs *ll = lp->ll;
netif_stop_queue(dev);
- del_timer_sync(&lp->multicast_timer);
+ timer_delete_sync(&lp->multicast_timer);
/* Stop the card */
writereg(&ll->rap, LE_CSR0);
diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c
index c6bd803f5b0c..e5adafecc686 100644
--- a/drivers/net/ethernet/amd/pcnet32.c
+++ b/drivers/net/ethernet/amd/pcnet32.c
@@ -2630,7 +2630,7 @@ static int pcnet32_close(struct net_device *dev)
struct pcnet32_private *lp = netdev_priv(dev);
unsigned long flags;
- del_timer_sync(&lp->watchdog_timer);
+ timer_delete_sync(&lp->watchdog_timer);
netif_stop_queue(dev);
napi_disable(&lp->napi);
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index 0f98b92408ed..3cd31855a5f6 100644
--- a/drivers/net/ethernet/amd/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -963,7 +963,7 @@ static int lance_close(struct net_device *dev)
struct lance_private *lp = netdev_priv(dev);
netif_stop_queue(dev);
- del_timer_sync(&lp->multicast_timer);
+ timer_delete_sync(&lp->multicast_timer);
STOP_LANCE(lp);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 5475867708f4..d84a310dfcd4 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -728,7 +728,7 @@ static void xgbe_stop_timers(struct xgbe_prv_data *pdata)
struct xgbe_channel *channel;
unsigned int i;
- del_timer_sync(&pdata->service_timer);
+ timer_delete_sync(&pdata->service_timer);
for (i = 0; i < pdata->channel_count; i++) {
channel = pdata->channel[i];
@@ -736,7 +736,7 @@ static void xgbe_stop_timers(struct xgbe_prv_data *pdata)
break;
/* Deactivate the Tx timer */
- del_timer_sync(&channel->tx_timer);
+ timer_delete_sync(&channel->tx_timer);
channel->tx_timer_active = 0;
}
}
diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
index 785f4b4ff758..b9fdd61f1fdb 100644
--- a/drivers/net/ethernet/apple/bmac.c
+++ b/drivers/net/ethernet/apple/bmac.c
@@ -461,7 +461,7 @@ static int bmac_suspend(struct macio_dev *mdev, pm_message_t state)
/* prolly should wait for dma to finish & turn off the chip */
spin_lock_irqsave(&bp->lock, flags);
if (bp->timeout_active) {
- del_timer(&bp->tx_timeout);
+ timer_delete(&bp->tx_timeout);
bp->timeout_active = 0;
}
disable_irq(dev->irq);
@@ -546,7 +546,7 @@ static inline void bmac_set_timeout(struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);
if (bp->timeout_active)
- del_timer(&bp->tx_timeout);
+ timer_delete(&bp->tx_timeout);
bp->tx_timeout.expires = jiffies + TX_TIMEOUT;
add_timer(&bp->tx_timeout);
bp->timeout_active = 1;
@@ -755,7 +755,7 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id)
XXDEBUG(("bmac_txdma_intr\n"));
}
- /* del_timer(&bp->tx_timeout); */
+ /* timer_delete(&bp->tx_timeout); */
/* bp->timeout_active = 0; */
while (1) {
diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
index e6350971c707..1fed112f4e68 100644
--- a/drivers/net/ethernet/apple/mace.c
+++ b/drivers/net/ethernet/apple/mace.c
@@ -523,7 +523,7 @@ static inline void mace_set_timeout(struct net_device *dev)
struct mace_data *mp = netdev_priv(dev);
if (mp->timeout_active)
- del_timer(&mp->tx_timeout);
+ timer_delete(&mp->tx_timeout);
mp->tx_timeout.expires = jiffies + TX_TIMEOUT;
add_timer(&mp->tx_timeout);
mp->timeout_active = 1;
@@ -676,7 +676,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
i = mp->tx_empty;
while (in_8(&mb->pr) & XMTSV) {
- del_timer(&mp->tx_timeout);
+ timer_delete(&mp->tx_timeout);
mp->timeout_active = 0;
/*
* Clear any interrupt indication associated with this status
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 71e50fc65c14..bf3aa46887a1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -1389,13 +1389,13 @@ int aq_nic_stop(struct aq_nic_s *self)
netif_tx_disable(self->ndev);
netif_carrier_off(self->ndev);
- del_timer_sync(&self->service_timer);
+ timer_delete_sync(&self->service_timer);
cancel_work_sync(&self->service_task);
self->aq_hw_ops->hw_irq_disable(self->aq_hw, AQ_CFG_IRQ_MASK);
if (self->aq_nic_cfg.is_polling)
- del_timer_sync(&self->polling_timer);
+ timer_delete_sync(&self->polling_timer);
else
aq_pci_func_free_irqs(self);
diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
index 3d4c3d8698e2..67b654889cae 100644
--- a/drivers/net/ethernet/atheros/ag71xx.c
+++ b/drivers/net/ethernet/atheros/ag71xx.c
@@ -1391,7 +1391,7 @@ static void ag71xx_hw_disable(struct ag71xx *ag)
ag71xx_dma_reset(ag);
napi_disable(&ag->napi);
- del_timer_sync(&ag->oom_timer);
+ timer_delete_sync(&ag->oom_timer);
ag71xx_rings_cleanup(ag);
}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index c571614b1d50..82137f9deae9 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -357,7 +357,7 @@ static void atl1c_common_task(struct work_struct *work)
static void atl1c_del_timer(struct atl1c_adapter *adapter)
{
- del_timer_sync(&adapter->phy_config_timer);
+ timer_delete_sync(&adapter->phy_config_timer);
}
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 9b778b34b67e..f664a0edbc49 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -232,7 +232,7 @@ static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
static void atl1e_del_timer(struct atl1e_adapter *adapter)
{
- del_timer_sync(&adapter->phy_config_timer);
+ timer_delete_sync(&adapter->phy_config_timer);
}
static void atl1e_cancel_work(struct atl1e_adapter *adapter)
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 3afd3627ce48..38cd84b7677c 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2641,7 +2641,7 @@ static void atl1_down(struct atl1_adapter *adapter)
napi_disable(&adapter->napi);
netif_stop_queue(netdev);
- del_timer_sync(&adapter->phy_config_timer);
+ timer_delete_sync(&adapter->phy_config_timer);
adapter->phy_timer_pending = false;
atlx_irq_disable(adapter);
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index fa9a4919f25d..88f65f8cf4d3 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -752,8 +752,8 @@ static void atl2_down(struct atl2_adapter *adapter)
atl2_irq_disable(adapter);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_config_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_config_timer);
clear_bit(0, &adapter->cfg_phy);
netif_carrier_off(netdev);
@@ -1468,8 +1468,8 @@ static void atl2_remove(struct pci_dev *pdev)
* explicitly disable watchdog tasks from being rescheduled */
set_bit(__ATL2_DOWN, &adapter->flags);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_config_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_config_timer);
cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->link_chg_task);
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index e5809ad5eb82..c91884373429 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -1628,7 +1628,7 @@ static int b44_close(struct net_device *dev)
napi_disable(&bp->napi);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
spin_lock_irq(&bp->lock);
@@ -2473,7 +2473,7 @@ static int b44_suspend(struct ssb_device *sdev, pm_message_t state)
if (!netif_running(dev))
return 0;
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
spin_lock_irq(&bp->lock);
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 65e3a0656a4c..19611bdd86e6 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1195,7 +1195,7 @@ static int bcm_enet_stop(struct net_device *dev)
napi_disable(&priv->napi);
if (priv->has_phy)
phy_stop(dev->phydev);
- del_timer_sync(&priv->rx_timeout);
+ timer_delete_sync(&priv->rx_timeout);
/* mask all interrupts */
enet_writel(priv, 0, ENET_IRMASK_REG);
@@ -2346,10 +2346,10 @@ static int bcm_enetsw_stop(struct net_device *dev)
priv = netdev_priv(dev);
kdev = &priv->pdev->dev;
- del_timer_sync(&priv->swphy_poll);
+ timer_delete_sync(&priv->swphy_poll);
netif_stop_queue(dev);
napi_disable(&priv->napi);
- del_timer_sync(&priv->rx_timeout);
+ timer_delete_sync(&priv->rx_timeout);
/* mask all interrupts */
enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 6ec773e61182..ec0c9584f3bb 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -6400,7 +6400,7 @@ bnx2_open(struct net_device *dev)
rc = bnx2_request_irq(bp);
if (rc) {
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
goto open_err;
}
bnx2_enable_int(bp);
@@ -6752,7 +6752,7 @@ bnx2_close(struct net_device *dev)
bnx2_disable_int_sync(bp);
bnx2_napi_disable(bp);
netif_tx_disable(dev);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
bnx2_shutdown_chip(bp);
bnx2_free_irq(bp);
bnx2_free_skbs(bp);
@@ -8602,7 +8602,7 @@ bnx2_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
cancel_work_sync(&bp->reset_task);
pci_iounmap(bp->pdev, bp->regview);
@@ -8629,7 +8629,7 @@ bnx2_suspend(struct device *device)
cancel_work_sync(&bp->reset_task);
bnx2_netif_stop(bp, true);
netif_device_detach(dev);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
bnx2_shutdown_chip(bp);
__bnx2_free_irq(bp);
bnx2_free_skbs(bp);
@@ -8687,7 +8687,7 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
if (netif_running(dev)) {
bnx2_netif_stop(bp, true);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index a8e07e51418f..e59530357e2c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3059,7 +3059,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
bp->rx_mode = BNX2X_RX_MODE_NONE;
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
if (IS_PF(bp) && !BP_NOMCP(bp)) {
/* Set ALWAYS_ALIVE bit in shmem */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 678829646cec..f522ca8ff66b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -14140,7 +14140,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
bnx2x_tx_disable(bp);
netdev_reset_tc(bp->dev);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
cancel_delayed_work_sync(&bp->sp_task);
cancel_delayed_work_sync(&bp->period_task);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 934ba9425857..8725e1e13908 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -12958,7 +12958,7 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
bnxt_debug_dev_exit(bp);
bnxt_disable_napi(bp);
- del_timer_sync(&bp->timer);
+ timer_delete_sync(&bp->timer);
bnxt_free_skbs(bp);
/* Save ring stats before shutdown */
@@ -15909,7 +15909,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
goto err_reset;
}
- napi_enable(&bnapi->napi);
+ napi_enable_locked(&bnapi->napi);
bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
for (i = 0; i < bp->nr_vnics; i++) {
@@ -15931,7 +15931,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
err_reset:
netdev_err(bp->dev, "Unexpected HWRM error during queue start rc: %d\n",
rc);
- napi_enable(&bnapi->napi);
+ napi_enable_locked(&bnapi->napi);
bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
bnxt_reset_task(bp, true);
return rc;
@@ -15971,7 +15971,7 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
* completion is handled in NAPI to guarantee no more DMA on that ring
* after seeing the completion.
*/
- napi_disable(&bnapi->napi);
+ napi_disable_locked(&bnapi->napi);
if (bp->tph_mode) {
bnxt_hwrm_cp_ring_free(bp, rxr->rx_cpr);
@@ -16698,6 +16698,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
if (!dev)
return;
+ rtnl_lock();
netdev_lock(dev);
bp = netdev_priv(dev);
if (!bp)
@@ -16717,6 +16718,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
shutdown_exit:
netdev_unlock(dev);
+ rtnl_unlock();
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index d9d675f1ebfe..d1f541af4e3b 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -11252,7 +11252,7 @@ static void tg3_timer_start(struct tg3 *tp)
static void tg3_timer_stop(struct tg3 *tp)
{
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
}
/* Restart hardware after configuration changes, self-test, etc.
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index 9c80ab07a735..92c7639d1fc7 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -314,13 +314,13 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
{
switch (event) {
case IOC_E_FWRSP_GETATTR:
- del_timer(&ioc->ioc_timer);
+ timer_delete(&ioc->ioc_timer);
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
case IOC_E_PFFAILED:
case IOC_E_HWERROR:
- del_timer(&ioc->ioc_timer);
+ timer_delete(&ioc->ioc_timer);
fallthrough;
case IOC_E_TIMEOUT:
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
@@ -330,7 +330,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
break;
case IOC_E_DISABLE:
- del_timer(&ioc->ioc_timer);
+ timer_delete(&ioc->ioc_timer);
bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
break;
@@ -659,13 +659,13 @@ bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event)
break;
case IOCPF_E_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
bfa_ioc_pf_disabled(ioc);
break;
case IOCPF_E_STOP:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
break;
@@ -741,7 +741,7 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
break;
case IOCPF_E_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
bfa_ioc_sync_leave(ioc);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
@@ -774,13 +774,13 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWRSP_ENABLE:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
break;
case IOCPF_E_INITFAIL:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
fallthrough;
case IOCPF_E_TIMEOUT:
@@ -791,7 +791,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
break;
case IOCPF_E_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
break;
@@ -844,12 +844,12 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWRSP_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
case IOCPF_E_FAIL:
- del_timer(&ioc->iocpf_timer);
+ timer_delete(&ioc->iocpf_timer);
fallthrough;
case IOCPF_E_TIMEOUT:
@@ -1210,7 +1210,7 @@ bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc)
static void
bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc)
{
- del_timer(&ioc->sem_timer);
+ timer_delete(&ioc->sem_timer);
}
/* Initialize LPU local memory (aka secondary memory / SRAM) */
@@ -1982,7 +1982,7 @@ bfa_ioc_hb_monitor(struct bfa_ioc *ioc)
static void
bfa_ioc_hb_stop(struct bfa_ioc *ioc)
{
- del_timer(&ioc->hb_timer);
+ timer_delete(&ioc->hb_timer);
}
/* Initiate a full firmware download. */
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index 3b9107003b00..a03eff3d4425 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -1837,7 +1837,7 @@ bnad_stats_timer_stop(struct bnad *bnad)
to_del = 1;
spin_unlock_irqrestore(&bnad->bna_lock, flags);
if (to_del)
- del_timer_sync(&bnad->stats_timer);
+ timer_delete_sync(&bnad->stats_timer);
}
/* Utilities */
@@ -2160,7 +2160,7 @@ bnad_destroy_rx(struct bnad *bnad, u32 rx_id)
}
spin_unlock_irqrestore(&bnad->bna_lock, flags);
if (to_del)
- del_timer_sync(&bnad->dim_timer);
+ timer_delete_sync(&bnad->dim_timer);
}
init_completion(&bnad->bnad_completions.rx_comp);
@@ -3726,9 +3726,9 @@ probe_uninit:
bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
disable_ioceth:
bnad_ioceth_disable(bnad);
- del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
+ timer_delete_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+ timer_delete_sync(&bnad->bna.ioceth.ioc.sem_timer);
+ timer_delete_sync(&bnad->bna.ioceth.ioc.hb_timer);
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -3769,9 +3769,9 @@ bnad_pci_remove(struct pci_dev *pdev)
mutex_lock(&bnad->conf_mutex);
bnad_ioceth_disable(bnad);
- del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
- del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
+ timer_delete_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+ timer_delete_sync(&bnad->bna.ioceth.ioc.sem_timer);
+ timer_delete_sync(&bnad->bna.ioceth.ioc.hb_timer);
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index d1ad6c9f8140..216e25f26dbb 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -373,7 +373,7 @@ static int bnad_set_coalesce(struct net_device *netdev,
}
spin_unlock_irqrestore(&bnad->bna_lock, flags);
if (to_del)
- del_timer_sync(&bnad->dim_timer);
+ timer_delete_sync(&bnad->dim_timer);
spin_lock_irqsave(&bnad->bna_lock, flags);
bnad_rx_coalescing_timeo_set(bnad);
}
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c
index 861edff5ed89..a10923c7e25c 100644
--- a/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -1984,9 +1984,9 @@ void t1_sge_stop(struct sge *sge)
readl(sge->adapter->regs + A_SG_CONTROL); /* flush */
if (is_T2(sge->adapter))
- del_timer_sync(&sge->espibug_timer);
+ timer_delete_sync(&sge->espibug_timer);
- del_timer_sync(&sge->tx_reclaim_timer);
+ timer_delete_sync(&sge->tx_reclaim_timer);
if (sge->tx_sched)
tx_sched_stop(sge);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/sge.c b/drivers/net/ethernet/chelsio/cxgb3/sge.c
index 6268f96cb4aa..bd5c3b3fa5e3 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c
@@ -3223,9 +3223,9 @@ void t3_stop_sge_timers(struct adapter *adap)
struct sge_qset *q = &adap->sge.qs[i];
if (q->tx_reclaim_timer.function)
- del_timer_sync(&q->tx_reclaim_timer);
+ timer_delete_sync(&q->tx_reclaim_timer);
if (q->rx_reclaim_timer.function)
- del_timer_sync(&q->rx_reclaim_timer);
+ timer_delete_sync(&q->rx_reclaim_timer);
}
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index a7d76a8ed050..f991a28a71c3 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -4996,9 +4996,9 @@ void t4_sge_stop(struct adapter *adap)
struct sge *s = &adap->sge;
if (s->rx_timer.function)
- del_timer_sync(&s->rx_timer);
+ timer_delete_sync(&s->rx_timer);
if (s->tx_timer.function)
- del_timer_sync(&s->tx_timer);
+ timer_delete_sync(&s->tx_timer);
if (is_offload(adap)) {
struct sge_uld_txq_info *txq_info;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index 5b1d746e6563..f42af01f4114 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -2609,9 +2609,9 @@ void t4vf_sge_stop(struct adapter *adapter)
struct sge *s = &adapter->sge;
if (s->rx_timer.function)
- del_timer_sync(&s->rx_timer);
+ timer_delete_sync(&s->rx_timer);
if (s->tx_timer.function)
- del_timer_sync(&s->tx_timer);
+ timer_delete_sync(&s->tx_timer);
}
/**
diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.h b/drivers/net/ethernet/cisco/enic/enic_clsf.h
index 8c4ce50da6e1..5f5284102fb0 100644
--- a/drivers/net/ethernet/cisco/enic/enic_clsf.h
+++ b/drivers/net/ethernet/cisco/enic/enic_clsf.h
@@ -26,7 +26,7 @@ static inline void enic_rfs_timer_start(struct enic *enic)
static inline void enic_rfs_timer_stop(struct enic *enic)
{
- del_timer_sync(&enic->rfs_h.rfs_may_expire);
+ timer_delete_sync(&enic->rfs_h.rfs_may_expire);
}
#else
static inline void enic_rfs_timer_start(struct enic *enic) {}
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 54aa3953bf7b..c753c35b26eb 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1787,7 +1787,7 @@ static int enic_stop(struct net_device *netdev)
enic_synchronize_irqs(enic);
- del_timer_sync(&enic->notify_timer);
+ timer_delete_sync(&enic->notify_timer);
enic_rfs_flw_tbl_free(enic);
enic_dev_disable(enic);
diff --git a/drivers/net/ethernet/dec/tulip/21142.c b/drivers/net/ethernet/dec/tulip/21142.c
index 369858272650..76767dec216d 100644
--- a/drivers/net/ethernet/dec/tulip/21142.c
+++ b/drivers/net/ethernet/dec/tulip/21142.c
@@ -216,7 +216,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
(csr12 & 2) == 2) ||
(tp->nway && (csr5 & (TPLnkFail)))) {
/* Link blew? Maybe restart NWay. */
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
t21142_start_nway(dev);
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
@@ -226,7 +226,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
medianame[dev->if_port],
(csr12 & 2) ? "failed" : "good");
if ((csr12 & 2) && ! tp->medialock) {
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
t21142_start_nway(dev);
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c
index 0a161a4db242..f9339d0772b5 100644
--- a/drivers/net/ethernet/dec/tulip/de2104x.c
+++ b/drivers/net/ethernet/dec/tulip/de2104x.c
@@ -1428,7 +1428,7 @@ static int de_close (struct net_device *dev)
netif_dbg(de, ifdown, dev, "disabling interface\n");
- del_timer_sync(&de->media_timer);
+ timer_delete_sync(&de->media_timer);
spin_lock_irqsave(&de->lock, flags);
de_stop_hw(de);
@@ -1452,7 +1452,7 @@ static void de_tx_timeout (struct net_device *dev, unsigned int txqueue)
dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
de->rx_tail, de->tx_head, de->tx_tail);
- del_timer_sync(&de->media_timer);
+ timer_delete_sync(&de->media_timer);
disable_irq(irq);
spin_lock_irq(&de->lock);
@@ -2126,7 +2126,7 @@ static int __maybe_unused de_suspend(struct device *dev_d)
if (netif_running (dev)) {
const int irq = pdev->irq;
- del_timer_sync(&de->media_timer);
+ timer_delete_sync(&de->media_timer);
disable_irq(irq);
spin_lock_irq(&de->lock);
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index 3188ba7b450f..ae34b95ed676 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -745,7 +745,7 @@ static int dmfe_stop(struct net_device *dev)
netif_stop_queue(dev);
/* deleted timer */
- del_timer_sync(&db->timer);
+ timer_delete_sync(&db->timer);
/* Reset & stop DM910X board */
dw32(DCR0, DM910X_RESET);
diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c
index 54560f9a1651..2d926a26fbb9 100644
--- a/drivers/net/ethernet/dec/tulip/interrupt.c
+++ b/drivers/net/ethernet/dec/tulip/interrupt.c
@@ -699,8 +699,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
tulip_start_rxtx(tp);
}
/*
- * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
- * call is ever done under the spinlock
+ * NB: t21142_lnk_change() does a timer_delete_sync(), so be careful
+ * if this call is ever done under the spinlock
*/
if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) {
if (tp->link_change)
diff --git a/drivers/net/ethernet/dec/tulip/pnic2.c b/drivers/net/ethernet/dec/tulip/pnic2.c
index 72a09156b48b..2e3bdc0fcdc0 100644
--- a/drivers/net/ethernet/dec/tulip/pnic2.c
+++ b/drivers/net/ethernet/dec/tulip/pnic2.c
@@ -323,7 +323,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5)
if (tulip_debug > 2)
netdev_dbg(dev, "Ugh! Link blew?\n");
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
pnic2_start_nway(dev);
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
@@ -348,7 +348,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5)
/* if failed then try doing an nway to get in sync */
if ((csr12 & 2) && ! tp->medialock) {
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
pnic2_start_nway(dev);
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
@@ -372,7 +372,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5)
/* if failed, try doing an nway to get in sync */
if ((csr12 & 4) && ! tp->medialock) {
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
pnic2_start_nway(dev);
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 75eac18ff246..c8c53121557f 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -747,9 +747,9 @@ static void tulip_down (struct net_device *dev)
napi_disable(&tp->napi);
#endif
- del_timer_sync (&tp->timer);
+ timer_delete_sync(&tp->timer);
#ifdef CONFIG_TULIP_NAPI
- del_timer_sync (&tp->oom_timer);
+ timer_delete_sync(&tp->oom_timer);
#endif
spin_lock_irqsave (&tp->lock, flags);
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
index ff080ab0f116..3f1bd670700b 100644
--- a/drivers/net/ethernet/dec/tulip/uli526x.c
+++ b/drivers/net/ethernet/dec/tulip/uli526x.c
@@ -656,7 +656,7 @@ static int uli526x_stop(struct net_device *dev)
netif_stop_queue(dev);
/* deleted timer */
- del_timer_sync(&db->timer);
+ timer_delete_sync(&db->timer);
/* Reset & stop ULI526X board */
uw32(DCR0, ULI526X_RESET);
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 37fba39c0056..5930cdec6f2f 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -1509,7 +1509,7 @@ static int netdev_close(struct net_device *dev)
}
#endif /* __i386__ debugging only */
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
free_rxtx_rings(np);
free_ringdesc(np);
@@ -1560,7 +1560,7 @@ static int __maybe_unused w840_suspend(struct device *dev_d)
rtnl_lock();
if (netif_running (dev)) {
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
spin_lock_irq(&np->lock);
netif_device_detach(dev);
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index d0ea92607870..d88fbecdab4b 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -1778,7 +1778,7 @@ rio_close (struct net_device *dev)
rio_hw_stop(dev);
free_irq(pdev->irq, dev);
- del_timer_sync (&np->timer);
+ timer_delete_sync(&np->timer);
free_list(dev);
@@ -1818,7 +1818,7 @@ static int rio_suspend(struct device *device)
return 0;
netif_device_detach(dev);
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
rio_hw_stop(dev);
return 0;
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
index ed18450fd2cc..670b68201376 100644
--- a/drivers/net/ethernet/fealnx.c
+++ b/drivers/net/ethernet/fealnx.c
@@ -1900,8 +1900,8 @@ static int netdev_close(struct net_device *dev)
/* Stop the chip's Tx and Rx processes. */
stop_nic_rxtx(ioaddr, 0);
- del_timer_sync(&np->timer);
- del_timer_sync(&np->reset_timer);
+ timer_delete_sync(&np->timer);
+ timer_delete_sync(&np->reset_timer);
free_irq(np->pci_dev->irq, dev);
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
index 31a21ccf4863..eae1a7595a69 100644
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -392,7 +392,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
*/
data[i++] = 0;
data[i++] = 0;
- data[i++] = tx->dqo_tx.tail - tx->dqo_tx.head;
+ data[i++] =
+ (tx->dqo_tx.tail - tx->dqo_tx.head) &
+ tx->mask;
}
do {
start =
@@ -703,7 +705,7 @@ static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
memset(priv->stats_report->stats, 0, (tx_stats_num + rx_stats_num) *
sizeof(struct stats));
- del_timer_sync(&priv->stats_report_timer);
+ timer_delete_sync(&priv->stats_report_timer);
}
return 0;
}
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index cb2f9978f45e..c3791cf23c87 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -302,7 +302,7 @@ static void gve_free_stats_report(struct gve_priv *priv)
if (!priv->stats_report)
return;
- del_timer_sync(&priv->stats_report_timer);
+ timer_delete_sync(&priv->stats_report_timer);
dma_free_coherent(&priv->pdev->dev, priv->stats_report_len,
priv->stats_report, priv->stats_report_bus);
priv->stats_report = NULL;
@@ -1408,7 +1408,7 @@ static int gve_queues_stop(struct gve_priv *priv)
goto err;
gve_clear_device_rings_ok(priv);
}
- del_timer_sync(&priv->stats_report_timer);
+ timer_delete_sync(&priv->stats_report_timer);
gve_unreg_xdp_info(priv);
@@ -2077,7 +2077,9 @@ static void gve_handle_reset(struct gve_priv *priv)
if (gve_get_do_reset(priv)) {
rtnl_lock();
+ netdev_lock(priv->dev);
gve_reset(priv, false);
+ netdev_unlock(priv->dev);
rtnl_unlock();
}
}
@@ -2714,6 +2716,7 @@ static void gve_shutdown(struct pci_dev *pdev)
bool was_up = netif_running(priv->dev);
rtnl_lock();
+ netdev_lock(netdev);
if (was_up && gve_close(priv->dev)) {
/* If the dev was up, attempt to close, if close fails, reset */
gve_reset_and_teardown(priv, was_up);
@@ -2721,6 +2724,7 @@ static void gve_shutdown(struct pci_dev *pdev)
/* If the dev wasn't up or close worked, finish tearing down */
gve_teardown_priv_resources(priv);
}
+ netdev_unlock(netdev);
rtnl_unlock();
}
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 42bb341fd80b..d98f8d3ce7c8 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1402,7 +1402,7 @@ static void hns_nic_net_down(struct net_device *ndev)
if (test_and_set_bit(NIC_STATE_DOWN, &priv->state))
return;
- (void)del_timer_sync(&priv->service_timer);
+ (void) timer_delete_sync(&priv->service_timer);
netif_tx_stop_all_queues(ndev);
netif_carrier_off(ndev);
netif_tx_disable(ndev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 92f9b8ec76d9..3e28a08934ab 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -11492,7 +11492,7 @@ static void hclge_state_uninit(struct hclge_dev *hdev)
set_bit(HCLGE_STATE_REMOVING, &hdev->state);
if (hdev->reset_timer.function)
- del_timer_sync(&hdev->reset_timer);
+ timer_delete_sync(&hdev->reset_timer);
if (hdev->service_task.work.func)
cancel_delayed_work_sync(&hdev->service_task);
}
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index b619a3ec245b..04192190beba 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1802,18 +1802,22 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
long value = simple_strtol(buf, NULL, 10);
long rc;
+ rtnl_lock();
+
if (attr == &veth_active_attr) {
if (value && !pool->active) {
if (netif_running(netdev)) {
if (ibmveth_alloc_buffer_pool(pool)) {
netdev_err(netdev,
"unable to alloc pool\n");
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto unlock_err;
}
pool->active = 1;
ibmveth_close(netdev);
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
} else {
pool->active = 1;
}
@@ -1833,48 +1837,59 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
if (i == IBMVETH_NUM_BUFF_POOLS) {
netdev_err(netdev, "no active pool >= MTU\n");
- return -EPERM;
+ rc = -EPERM;
+ goto unlock_err;
}
if (netif_running(netdev)) {
ibmveth_close(netdev);
pool->active = 0;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
}
pool->active = 0;
}
} else if (attr == &veth_num_attr) {
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
- return -EINVAL;
+ rc = -EINVAL;
+ goto unlock_err;
} else {
if (netif_running(netdev)) {
ibmveth_close(netdev);
pool->size = value;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
} else {
pool->size = value;
}
}
} else if (attr == &veth_size_attr) {
if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
- return -EINVAL;
+ rc = -EINVAL;
+ goto unlock_err;
} else {
if (netif_running(netdev)) {
ibmveth_close(netdev);
pool->buff_size = value;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ rc = ibmveth_open(netdev);
+ if (rc)
+ goto unlock_err;
} else {
pool->buff_size = value;
}
}
}
+ rtnl_unlock();
/* kick the interrupt handler to allocate/deallocate pools */
ibmveth_interrupt(netdev->irq, netdev);
return count;
+
+unlock_err:
+ rtnl_unlock();
+ return rc;
}
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 3a5bbda235cb..c0ead54ea186 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -2293,7 +2293,7 @@ static int e100_up(struct nic *nic)
return 0;
err_no_irq:
- del_timer_sync(&nic->watchdog);
+ timer_delete_sync(&nic->watchdog);
err_clean_cbs:
e100_clean_cbs(nic);
err_rx_clean_list:
@@ -2308,7 +2308,7 @@ static void e100_down(struct nic *nic)
netif_stop_queue(nic->netdev);
e100_hw_reset(nic);
free_irq(nic->pdev->irq, nic->netdev);
- del_timer_sync(&nic->watchdog);
+ timer_delete_sync(&nic->watchdog);
netif_carrier_off(nic->netdev);
e100_clean_cbs(nic);
e100_rx_clean_list(nic);
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h
index 5e2cfa73f889..8294a7c4f122 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -803,4 +803,7 @@
/* SerDes Control */
#define E1000_GEN_POLL_TIMEOUT 640
+#define E1000_FEXTNVM12_PHYPD_CTRL_MASK 0x00C00000
+#define E1000_FEXTNVM12_PHYPD_CTRL_P1 0x00800000
+
#endif /* _E1000_DEFINES_H_ */
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 2f9655cf5dd9..364378133526 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -286,6 +286,45 @@ static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
}
/**
+ * e1000_reconfigure_k1_exit_timeout - reconfigure K1 exit timeout to
+ * align to MTP and later platform requirements.
+ * @hw: pointer to the HW structure
+ *
+ * Context: PHY semaphore must be held by caller.
+ * Return: 0 on success, negative on failure
+ */
+static s32 e1000_reconfigure_k1_exit_timeout(struct e1000_hw *hw)
+{
+ u16 phy_timeout;
+ u32 fextnvm12;
+ s32 ret_val;
+
+ if (hw->mac.type < e1000_pch_mtp)
+ return 0;
+
+ /* Change Kumeran K1 power down state from P0s to P1 */
+ fextnvm12 = er32(FEXTNVM12);
+ fextnvm12 &= ~E1000_FEXTNVM12_PHYPD_CTRL_MASK;
+ fextnvm12 |= E1000_FEXTNVM12_PHYPD_CTRL_P1;
+ ew32(FEXTNVM12, fextnvm12);
+
+ /* Wait for the interface the settle */
+ usleep_range(1000, 1100);
+
+ /* Change K1 exit timeout */
+ ret_val = e1e_rphy_locked(hw, I217_PHY_TIMEOUTS_REG,
+ &phy_timeout);
+ if (ret_val)
+ return ret_val;
+
+ phy_timeout &= ~I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK;
+ phy_timeout |= 0xF00;
+
+ return e1e_wphy_locked(hw, I217_PHY_TIMEOUTS_REG,
+ phy_timeout);
+}
+
+/**
* e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
* @hw: pointer to the HW structure
*
@@ -327,15 +366,22 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
* LANPHYPC Value bit to force the interconnect to PCIe mode.
*/
switch (hw->mac.type) {
+ case e1000_pch_mtp:
+ case e1000_pch_lnp:
+ case e1000_pch_ptp:
+ case e1000_pch_nvp:
+ /* At this point the PHY might be inaccessible so don't
+ * propagate the failure
+ */
+ if (e1000_reconfigure_k1_exit_timeout(hw))
+ e_dbg("Failed to reconfigure K1 exit timeout\n");
+
+ fallthrough;
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
- case e1000_pch_mtp:
- case e1000_pch_lnp:
- case e1000_pch_ptp:
- case e1000_pch_nvp:
if (e1000_phy_is_accessible_pchlan(hw))
break;
@@ -419,8 +465,20 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
* the PHY is in.
*/
ret_val = hw->phy.ops.check_reset_block(hw);
- if (ret_val)
+ if (ret_val) {
e_err("ME blocked access to PHY after reset\n");
+ goto out;
+ }
+
+ if (hw->mac.type >= e1000_pch_mtp) {
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val) {
+ e_err("Failed to reconfigure K1 exit timeout\n");
+ goto out;
+ }
+ ret_val = e1000_reconfigure_k1_exit_timeout(hw);
+ hw->phy.ops.release(hw);
+ }
}
out:
@@ -4888,6 +4946,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
u16 i;
e1000_initialize_hw_bits_ich8lan(hw);
+ if (hw->mac.type >= e1000_pch_mtp) {
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ ret_val = e1000_reconfigure_k1_exit_timeout(hw);
+ hw->phy.ops.release(hw);
+ if (ret_val) {
+ e_dbg("Error failed to reconfigure K1 exit timeout\n");
+ return ret_val;
+ }
+ }
/* Initialize identification LED */
ret_val = mac->ops.id_led_init(hw);
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
index 2504b11c3169..5feb589a9b5f 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
@@ -219,6 +219,10 @@
#define I217_PLL_CLOCK_GATE_REG PHY_REG(772, 28)
#define I217_PLL_CLOCK_GATE_MASK 0x07FF
+/* PHY Timeouts */
+#define I217_PHY_TIMEOUTS_REG PHY_REG(770, 21)
+#define I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK 0x0FC0
+
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
/* Inband Control */
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 286155efcedf..8ebcb6a7d608 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -4287,8 +4287,8 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
napi_synchronize(&adapter->napi);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_info_timer);
spin_lock(&adapter->stats64_lock);
e1000e_update_stats(adapter);
@@ -7741,8 +7741,8 @@ static void e1000_remove(struct pci_dev *pdev)
* from being rescheduled.
*/
set_bit(__E1000_DOWN, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_info_timer);
cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->watchdog_task);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index 92de609b7218..21267ab603ef 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -2245,7 +2245,7 @@ static void fm10k_remove(struct pci_dev *pdev)
struct fm10k_intfc *interface = pci_get_drvdata(pdev);
struct net_device *netdev = interface->netdev;
- del_timer_sync(&interface->service_timer);
+ timer_delete_sync(&interface->service_timer);
fm10k_stop_service_event(interface);
fm10k_stop_macvlan_task(interface);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 65a702668e21..120d68654e3f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -16382,7 +16382,7 @@ static int i40e_io_suspend(struct i40e_pf *pf)
set_bit(__I40E_DOWN, pf->state);
/* Ensure service task will not be running */
- del_timer_sync(&pf->service_timer);
+ timer_delete_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task);
/* Client close must be called explicitly here because the timer
@@ -16581,7 +16581,7 @@ static void i40e_shutdown(struct pci_dev *pdev)
set_bit(__I40E_SUSPENDED, pf->state);
set_bit(__I40E_DOWN, pf->state);
- del_timer_sync(&pf->service_timer);
+ timer_delete_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task);
i40e_cloud_filter_exit(pf);
i40e_fdir_teardown(pf);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 049edeb60104..d390157b59fe 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -1717,7 +1717,7 @@ static int ice_service_task_stop(struct ice_pf *pf)
ret = test_and_set_bit(ICE_SERVICE_DIS, pf->state);
if (pf->serv_tmr.function)
- del_timer_sync(&pf->serv_tmr);
+ timer_delete_sync(&pf->serv_tmr);
if (pf->serv_task.func)
cancel_work_sync(&pf->serv_task);
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
index 9be4bd717512..7752920d7a8e 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
@@ -1521,7 +1521,7 @@ ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi,
memcpy(&ctx_done->rx_desc, rx_desc, sizeof(*rx_desc));
spin_unlock_irqrestore(&fdir->ctx_lock, flags);
- ret = del_timer(&ctx_irq->rx_tmr);
+ ret = timer_delete(&ctx_irq->rx_tmr);
if (!ret)
dev_err(dev, "VF %d: Unexpected inactive timer!\n", vf->vf_id);
@@ -1916,7 +1916,7 @@ static void ice_vc_fdir_clear_irq_ctx(struct ice_vf *vf)
struct ice_vf_fdir_ctx *ctx = &vf->fdir.ctx_irq;
unsigned long flags;
- del_timer(&ctx->rx_tmr);
+ timer_delete(&ctx->rx_tmr);
spin_lock_irqsave(&vf->fdir.ctx_lock, flags);
ctx->flags &= ~ICE_VF_FDIR_CTX_VALID;
spin_unlock_irqrestore(&vf->fdir.ctx_lock, flags);
diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
index b6c515d14cbf..bec4a02c5373 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -87,7 +87,11 @@ destroy_wqs:
*/
static void idpf_shutdown(struct pci_dev *pdev)
{
- idpf_remove(pdev);
+ struct idpf_adapter *adapter = pci_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&adapter->vc_event_task);
+ idpf_vc_core_deinit(adapter);
+ idpf_deinit_dflt_mbx(adapter);
if (system_state == SYSTEM_POWER_OFF)
pci_set_power_state(pdev, PCI_D3hot);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index d368b753a467..c646c71915f0 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2185,8 +2185,8 @@ void igb_down(struct igb_adapter *adapter)
}
}
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_info_timer);
/* record the stats before reset*/
spin_lock(&adapter->stats64_lock);
@@ -3860,8 +3860,8 @@ static void igb_remove(struct pci_dev *pdev)
* disable watchdog from being rescheduled.
*/
set_bit(__IGB_DOWN, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_info_timer);
cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->watchdog_task);
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 02044aa2181b..beb01248600f 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -1592,7 +1592,7 @@ void igbvf_down(struct igbvf_adapter *adapter)
igbvf_irq_disable(adapter);
- del_timer_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
/* record the stats before reset*/
igbvf_update_stats(adapter);
@@ -2912,7 +2912,7 @@ static void igbvf_remove(struct pci_dev *pdev)
* disable it from being rescheduled.
*/
set_bit(__IGBVF_DOWN, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->watchdog_task);
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
index cd1d7b6c1782..c35cc5cb1185 100644
--- a/drivers/net/ethernet/intel/igc/igc.h
+++ b/drivers/net/ethernet/intel/igc/igc.h
@@ -337,8 +337,6 @@ struct igc_adapter {
struct igc_led_classdev *leds;
};
-void igc_set_queue_napi(struct igc_adapter *adapter, int q_idx,
- struct napi_struct *napi);
void igc_up(struct igc_adapter *adapter);
void igc_down(struct igc_adapter *adapter);
int igc_open(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 491d942cefca..f1330379e6bb 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -3042,7 +3042,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
* descriptors. Therefore, to be safe, we always ensure we have at least
* 4 descriptors available.
*/
- while (xsk_tx_peek_desc(pool, &xdp_desc) && budget >= 4) {
+ while (budget >= 4 && xsk_tx_peek_desc(pool, &xdp_desc)) {
struct igc_metadata_request meta_req;
struct xsk_tx_metadata *meta = NULL;
struct igc_tx_buffer *bi;
@@ -5022,8 +5022,8 @@ static int igc_sw_init(struct igc_adapter *adapter)
return 0;
}
-void igc_set_queue_napi(struct igc_adapter *adapter, int vector,
- struct napi_struct *napi)
+static void igc_set_queue_napi(struct igc_adapter *adapter, int vector,
+ struct napi_struct *napi)
{
struct igc_q_vector *q_vector = adapter->q_vector[vector];
@@ -5291,8 +5291,8 @@ void igc_down(struct igc_adapter *adapter)
}
}
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_info_timer);
/* record the stats before reset*/
spin_lock(&adapter->stats64_lock);
@@ -7272,8 +7272,8 @@ static void igc_remove(struct pci_dev *pdev)
set_bit(__IGC_DOWN, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->phy_info_timer);
cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->watchdog_task);
diff --git a/drivers/net/ethernet/intel/igc/igc_xdp.c b/drivers/net/ethernet/intel/igc/igc_xdp.c
index c538e6b18aad..9eb47b4beb06 100644
--- a/drivers/net/ethernet/intel/igc/igc_xdp.c
+++ b/drivers/net/ethernet/intel/igc/igc_xdp.c
@@ -97,7 +97,6 @@ static int igc_xdp_enable_pool(struct igc_adapter *adapter,
napi_disable(napi);
}
- igc_set_queue_napi(adapter, queue_id, NULL);
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
@@ -147,7 +146,6 @@ static int igc_xdp_disable_pool(struct igc_adapter *adapter, u16 queue_id)
xsk_pool_dma_unmap(pool, IGC_RX_DMA_ATTR);
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
- igc_set_queue_napi(adapter, queue_id, napi);
if (needs_reset) {
napi_enable(napi);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index cb07ecd8937d..00935747c8c5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -1453,9 +1453,11 @@ enum ixgbe_media_type ixgbe_get_media_type_e610(struct ixgbe_hw *hw)
hw->link.link_info.phy_type_low = 0;
} else {
highest_bit = fls64(le64_to_cpu(pcaps.phy_type_low));
- if (highest_bit)
+ if (highest_bit) {
hw->link.link_info.phy_type_low =
BIT_ULL(highest_bit - 1);
+ hw->link.link_info.phy_type_high = 0;
+ }
}
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 481f917f7ed2..a2718218963e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6538,7 +6538,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
- del_timer_sync(&adapter->service_timer);
+ timer_delete_sync(&adapter->service_timer);
if (adapter->num_vfs) {
/* Clear EITR Select mapping */
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 6442f115a262..a217c5c04804 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -2514,7 +2514,7 @@ void ixgbevf_down(struct ixgbevf_adapter *adapter)
ixgbevf_napi_disable_all(adapter);
- del_timer_sync(&adapter->service_timer);
+ timer_delete_sync(&adapter->service_timer);
/* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) {
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 87c7e6251a4f..1e2ac1a5f099 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1239,7 +1239,7 @@ static int korina_close(struct net_device *dev)
struct korina_private *lp = netdev_priv(dev);
u32 tmp;
- del_timer(&lp->media_check_timer);
+ timer_delete(&lp->media_check_timer);
/* Disable interrupts */
disable_irq(lp->rx_irq);
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 67a6ff07c83d..8cc888bf6094 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2247,7 +2247,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (unlikely(mp->oom)) {
mp->oom = 0;
- del_timer(&mp->rx_oom);
+ timer_delete(&mp->rx_oom);
}
work_done = 0;
@@ -2521,7 +2521,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
napi_disable(&mp->napi);
- del_timer_sync(&mp->rx_oom);
+ timer_delete_sync(&mp->rx_oom);
netif_carrier_off(dev);
if (dev->phydev)
@@ -2531,7 +2531,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
port_reset(mp);
mv643xx_eth_get_stats(dev);
mib_counters_update(mp);
- del_timer_sync(&mp->mib_counters_timer);
+ timer_delete_sync(&mp->mib_counters_timer);
for (i = 0; i < mp->rxq_count; i++)
rxq_deinit(mp->rxq + i);
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
index 44fe9b68d1c2..061fcd444d50 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -1113,6 +1113,9 @@ struct mvpp2 {
/* Spinlocks for CM3 shared memory configuration */
spinlock_t mss_spinlock;
+
+ /* Spinlock for shared PRS parser memory and shadow table */
+ spinlock_t prs_spinlock;
};
struct mvpp2_pcpu_stats {
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 566c12c89520..416a926a8281 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -7723,8 +7723,9 @@ static int mvpp2_probe(struct platform_device *pdev)
if (mvpp2_read(priv, MVPP2_VER_ID_REG) == MVPP2_VER_PP23)
priv->hw_version = MVPP23;
- /* Init mss lock */
+ /* Init locks for shared packet processor resources */
spin_lock_init(&priv->mss_spinlock);
+ spin_lock_init(&priv->prs_spinlock);
/* Initialize network controller */
err = mvpp2_init(pdev, priv);
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
index 9af22f497a40..93e978bdf303 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
@@ -23,6 +23,8 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
{
int i;
+ lockdep_assert_held(&priv->prs_spinlock);
+
if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
return -EINVAL;
@@ -43,11 +45,13 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
}
/* Initialize tcam entry from hw */
-int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
- int tid)
+static int __mvpp2_prs_init_from_hw(struct mvpp2 *priv,
+ struct mvpp2_prs_entry *pe, int tid)
{
int i;
+ lockdep_assert_held(&priv->prs_spinlock);
+
if (tid > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
return -EINVAL;
@@ -73,6 +77,18 @@ int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
return 0;
}
+int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
+ int tid)
+{
+ int err;
+
+ spin_lock_bh(&priv->prs_spinlock);
+ err = __mvpp2_prs_init_from_hw(priv, pe, tid);
+ spin_unlock_bh(&priv->prs_spinlock);
+
+ return err;
+}
+
/* Invalidate tcam hw entry */
static void mvpp2_prs_hw_inv(struct mvpp2 *priv, int index)
{
@@ -374,7 +390,7 @@ static int mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
bits = mvpp2_prs_sram_ai_get(&pe);
/* Sram store classification lookup ID in AI bits [5:0] */
@@ -441,7 +457,7 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) {
/* Entry exist - update port only */
- mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
+ __mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
} else {
/* Entry doesn't exist - create new */
memset(&pe, 0, sizeof(pe));
@@ -469,14 +485,17 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
}
/* Set port to unicast or multicast promiscuous mode */
-void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
- enum mvpp2_prs_l2_cast l2_cast, bool add)
+static void __mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
+ enum mvpp2_prs_l2_cast l2_cast,
+ bool add)
{
struct mvpp2_prs_entry pe;
unsigned char cast_match;
unsigned int ri;
int tid;
+ lockdep_assert_held(&priv->prs_spinlock);
+
if (l2_cast == MVPP2_PRS_L2_UNI_CAST) {
cast_match = MVPP2_PRS_UCAST_VAL;
tid = MVPP2_PE_MAC_UC_PROMISCUOUS;
@@ -489,7 +508,7 @@ void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
/* promiscuous mode - Accept unknown unicast or multicast packets */
if (priv->prs_shadow[tid].valid) {
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
} else {
memset(&pe, 0, sizeof(pe));
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
@@ -522,6 +541,14 @@ void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
mvpp2_prs_hw_write(priv, &pe);
}
+void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
+ enum mvpp2_prs_l2_cast l2_cast, bool add)
+{
+ spin_lock_bh(&priv->prs_spinlock);
+ __mvpp2_prs_mac_promisc_set(priv, port, l2_cast, add);
+ spin_unlock_bh(&priv->prs_spinlock);
+}
+
/* Set entry for dsa packets */
static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
bool tagged, bool extend)
@@ -539,7 +566,7 @@ static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
if (priv->prs_shadow[tid].valid) {
/* Entry exist - update port only */
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
} else {
/* Entry doesn't exist - create new */
memset(&pe, 0, sizeof(pe));
@@ -610,7 +637,7 @@ static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,
if (priv->prs_shadow[tid].valid) {
/* Entry exist - update port only */
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
} else {
/* Entry doesn't exist - create new */
memset(&pe, 0, sizeof(pe));
@@ -673,7 +700,7 @@ static int mvpp2_prs_vlan_find(struct mvpp2 *priv, unsigned short tpid, int ai)
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid);
if (!match)
continue;
@@ -726,7 +753,7 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
ri_bits = mvpp2_prs_sram_ri_get(&pe);
if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==
MVPP2_PRS_RI_VLAN_DOUBLE)
@@ -760,7 +787,7 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
} else {
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
}
/* Update ports' mask */
mvpp2_prs_tcam_port_map_set(&pe, port_map);
@@ -800,7 +827,7 @@ static int mvpp2_prs_double_vlan_find(struct mvpp2 *priv, unsigned short tpid1,
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid1) &&
mvpp2_prs_tcam_data_cmp(&pe, 4, tpid2);
@@ -849,7 +876,7 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
ri_bits = mvpp2_prs_sram_ri_get(&pe);
ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
@@ -880,7 +907,7 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
} else {
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
}
/* Update ports' mask */
@@ -1213,8 +1240,8 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv)
/* Create dummy entries for drop all and promiscuous modes */
mvpp2_prs_drop_fc(priv);
mvpp2_prs_mac_drop_all_set(priv, 0, false);
- mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
- mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
+ __mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
+ __mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
}
/* Set default entries for various types of dsa packets */
@@ -1533,12 +1560,6 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
struct mvpp2_prs_entry pe;
int err;
- priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
- MVPP2_PRS_DBL_VLANS_MAX,
- GFP_KERNEL);
- if (!priv->prs_double_vlans)
- return -ENOMEM;
-
/* Double VLAN: 0x88A8, 0x8100 */
err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021AD, ETH_P_8021Q,
MVPP2_PRS_PORT_MASK);
@@ -1941,7 +1962,7 @@ static int mvpp2_prs_vid_range_find(struct mvpp2_port *port, u16 vid, u16 mask)
port->priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
continue;
- mvpp2_prs_init_from_hw(port->priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(port->priv, &pe, tid);
mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
@@ -1970,6 +1991,8 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
memset(&pe, 0, sizeof(pe));
+ spin_lock_bh(&priv->prs_spinlock);
+
/* Scan TCAM and see if entry with this <vid,port> already exist */
tid = mvpp2_prs_vid_range_find(port, vid, mask);
@@ -1988,8 +2011,10 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
MVPP2_PRS_VLAN_FILT_MAX_ENTRY);
/* There isn't room for a new VID filter */
- if (tid < 0)
+ if (tid < 0) {
+ spin_unlock_bh(&priv->prs_spinlock);
return tid;
+ }
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
pe.index = tid;
@@ -1997,7 +2022,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
/* Mask all ports */
mvpp2_prs_tcam_port_map_set(&pe, 0);
} else {
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
}
/* Enable the current port */
@@ -2019,6 +2044,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
mvpp2_prs_hw_write(priv, &pe);
+ spin_unlock_bh(&priv->prs_spinlock);
return 0;
}
@@ -2028,15 +2054,16 @@ void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)
struct mvpp2 *priv = port->priv;
int tid;
- /* Scan TCAM and see if entry with this <vid,port> already exist */
- tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);
+ spin_lock_bh(&priv->prs_spinlock);
- /* No such entry */
- if (tid < 0)
- return;
+ /* Invalidate TCAM entry with this <vid,port>, if it exists */
+ tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);
+ if (tid >= 0) {
+ mvpp2_prs_hw_inv(priv, tid);
+ priv->prs_shadow[tid].valid = false;
+ }
- mvpp2_prs_hw_inv(priv, tid);
- priv->prs_shadow[tid].valid = false;
+ spin_unlock_bh(&priv->prs_spinlock);
}
/* Remove all existing VID filters on this port */
@@ -2045,6 +2072,8 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
struct mvpp2 *priv = port->priv;
int tid;
+ spin_lock_bh(&priv->prs_spinlock);
+
for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
if (priv->prs_shadow[tid].valid) {
@@ -2052,6 +2081,8 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
priv->prs_shadow[tid].valid = false;
}
}
+
+ spin_unlock_bh(&priv->prs_spinlock);
}
/* Remove VID filering entry for this port */
@@ -2060,10 +2091,14 @@ void mvpp2_prs_vid_disable_filtering(struct mvpp2_port *port)
unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);
struct mvpp2 *priv = port->priv;
+ spin_lock_bh(&priv->prs_spinlock);
+
/* Invalidate the guard entry */
mvpp2_prs_hw_inv(priv, tid);
priv->prs_shadow[tid].valid = false;
+
+ spin_unlock_bh(&priv->prs_spinlock);
}
/* Add guard entry that drops packets when no VID is matched on this port */
@@ -2079,6 +2114,8 @@ void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
memset(&pe, 0, sizeof(pe));
+ spin_lock_bh(&priv->prs_spinlock);
+
pe.index = tid;
reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
@@ -2111,6 +2148,8 @@ void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
/* Update shadow table */
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
mvpp2_prs_hw_write(priv, &pe);
+
+ spin_unlock_bh(&priv->prs_spinlock);
}
/* Parser default initialization */
@@ -2118,6 +2157,20 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
{
int err, index, i;
+ priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
+ sizeof(*priv->prs_shadow),
+ GFP_KERNEL);
+ if (!priv->prs_shadow)
+ return -ENOMEM;
+
+ priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
+ MVPP2_PRS_DBL_VLANS_MAX,
+ GFP_KERNEL);
+ if (!priv->prs_double_vlans)
+ return -ENOMEM;
+
+ spin_lock_bh(&priv->prs_spinlock);
+
/* Enable tcam table */
mvpp2_write(priv, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);
@@ -2136,12 +2189,6 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++)
mvpp2_prs_hw_inv(priv, index);
- priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
- sizeof(*priv->prs_shadow),
- GFP_KERNEL);
- if (!priv->prs_shadow)
- return -ENOMEM;
-
/* Always start from lookup = 0 */
for (index = 0; index < MVPP2_MAX_PORTS; index++)
mvpp2_prs_hw_port_init(priv, index, MVPP2_PRS_LU_MH,
@@ -2158,26 +2205,13 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
mvpp2_prs_vid_init(priv);
err = mvpp2_prs_etype_init(priv);
- if (err)
- return err;
-
- err = mvpp2_prs_vlan_init(pdev, priv);
- if (err)
- return err;
-
- err = mvpp2_prs_pppoe_init(priv);
- if (err)
- return err;
-
- err = mvpp2_prs_ip6_init(priv);
- if (err)
- return err;
-
- err = mvpp2_prs_ip4_init(priv);
- if (err)
- return err;
+ err = err ? : mvpp2_prs_vlan_init(pdev, priv);
+ err = err ? : mvpp2_prs_pppoe_init(priv);
+ err = err ? : mvpp2_prs_ip6_init(priv);
+ err = err ? : mvpp2_prs_ip4_init(priv);
- return 0;
+ spin_unlock_bh(&priv->prs_spinlock);
+ return err;
}
/* Compare MAC DA with tcam entry data */
@@ -2217,7 +2251,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
(priv->prs_shadow[tid].udf != udf_type))
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
entry_pmap = mvpp2_prs_tcam_port_map_get(&pe);
if (mvpp2_prs_mac_range_equals(&pe, da, mask) &&
@@ -2229,7 +2263,8 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
}
/* Update parser's mac da entry */
-int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
+static int __mvpp2_prs_mac_da_accept(struct mvpp2_port *port,
+ const u8 *da, bool add)
{
unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
struct mvpp2 *priv = port->priv;
@@ -2261,7 +2296,7 @@ int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
/* Mask all ports */
mvpp2_prs_tcam_port_map_set(&pe, 0);
} else {
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
}
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
@@ -2317,6 +2352,17 @@ int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
return 0;
}
+int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
+{
+ int err;
+
+ spin_lock_bh(&port->priv->prs_spinlock);
+ err = __mvpp2_prs_mac_da_accept(port, da, add);
+ spin_unlock_bh(&port->priv->prs_spinlock);
+
+ return err;
+}
+
int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)
{
struct mvpp2_port *port = netdev_priv(dev);
@@ -2345,6 +2391,8 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
unsigned long pmap;
int index, tid;
+ spin_lock_bh(&priv->prs_spinlock);
+
for (tid = MVPP2_PE_MAC_RANGE_START;
tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
@@ -2354,7 +2402,7 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
(priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))
continue;
- mvpp2_prs_init_from_hw(priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(priv, &pe, tid);
pmap = mvpp2_prs_tcam_port_map_get(&pe);
@@ -2375,14 +2423,17 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
continue;
/* Remove entry from TCAM */
- mvpp2_prs_mac_da_accept(port, da, false);
+ __mvpp2_prs_mac_da_accept(port, da, false);
}
+
+ spin_unlock_bh(&priv->prs_spinlock);
}
int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
{
switch (type) {
case MVPP2_TAG_TYPE_EDSA:
+ spin_lock_bh(&priv->prs_spinlock);
/* Add port to EDSA entries */
mvpp2_prs_dsa_tag_set(priv, port, true,
MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
@@ -2393,9 +2444,11 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
mvpp2_prs_dsa_tag_set(priv, port, false,
MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+ spin_unlock_bh(&priv->prs_spinlock);
break;
case MVPP2_TAG_TYPE_DSA:
+ spin_lock_bh(&priv->prs_spinlock);
/* Add port to DSA entries */
mvpp2_prs_dsa_tag_set(priv, port, true,
MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
@@ -2406,10 +2459,12 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
mvpp2_prs_dsa_tag_set(priv, port, false,
MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ spin_unlock_bh(&priv->prs_spinlock);
break;
case MVPP2_TAG_TYPE_MH:
case MVPP2_TAG_TYPE_NONE:
+ spin_lock_bh(&priv->prs_spinlock);
/* Remove port form EDSA and DSA entries */
mvpp2_prs_dsa_tag_set(priv, port, false,
MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
@@ -2419,6 +2474,7 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
mvpp2_prs_dsa_tag_set(priv, port, false,
MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ spin_unlock_bh(&priv->prs_spinlock);
break;
default:
@@ -2437,11 +2493,15 @@ int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)
memset(&pe, 0, sizeof(pe));
+ spin_lock_bh(&priv->prs_spinlock);
+
tid = mvpp2_prs_tcam_first_free(priv,
MVPP2_PE_LAST_FREE_TID,
MVPP2_PE_FIRST_FREE_TID);
- if (tid < 0)
+ if (tid < 0) {
+ spin_unlock_bh(&priv->prs_spinlock);
return tid;
+ }
pe.index = tid;
@@ -2461,6 +2521,7 @@ int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)
mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
mvpp2_prs_hw_write(priv, &pe);
+ spin_unlock_bh(&priv->prs_spinlock);
return 0;
}
@@ -2472,6 +2533,8 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
memset(&pe, 0, sizeof(pe));
+ spin_lock_bh(&port->priv->prs_spinlock);
+
tid = mvpp2_prs_flow_find(port->priv, port->id);
/* Such entry not exist */
@@ -2480,8 +2543,10 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
tid = mvpp2_prs_tcam_first_free(port->priv,
MVPP2_PE_LAST_FREE_TID,
MVPP2_PE_FIRST_FREE_TID);
- if (tid < 0)
+ if (tid < 0) {
+ spin_unlock_bh(&port->priv->prs_spinlock);
return tid;
+ }
pe.index = tid;
@@ -2492,13 +2557,14 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
/* Update shadow table */
mvpp2_prs_shadow_set(port->priv, pe.index, MVPP2_PRS_LU_FLOWS);
} else {
- mvpp2_prs_init_from_hw(port->priv, &pe, tid);
+ __mvpp2_prs_init_from_hw(port->priv, &pe, tid);
}
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
mvpp2_prs_tcam_port_map_set(&pe, (1 << port->id));
mvpp2_prs_hw_write(port->priv, &pe);
+ spin_unlock_bh(&port->priv->prs_spinlock);
return 0;
}
@@ -2509,11 +2575,14 @@ int mvpp2_prs_hits(struct mvpp2 *priv, int index)
if (index > MVPP2_PRS_TCAM_SRAM_SIZE)
return -EINVAL;
+ spin_lock_bh(&priv->prs_spinlock);
+
mvpp2_write(priv, MVPP2_PRS_TCAM_HIT_IDX_REG, index);
val = mvpp2_read(priv, MVPP2_PRS_TCAM_HIT_CNT_REG);
val &= MVPP2_PRS_TCAM_HIT_CNT_MASK;
+ spin_unlock_bh(&priv->prs_spinlock);
return val;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index cd0d7b7774f1..6575c422635b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -2634,7 +2634,7 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
rvupf_write64(rvu, RVU_PF_VFPF_MBOX_INTX(1), intr);
rvu_queue_work(&rvu->afvf_wq_info, 64, vfs, intr);
- vfs -= 64;
+ vfs = 64;
}
intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(0));
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
index dab4deca893f..27c3a2daaaa9 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
@@ -207,7 +207,7 @@ static void rvu_nix_unregister_interrupts(struct rvu *rvu)
rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
}
- for (i = NIX_AF_INT_VEC_AF_ERR; i < NIX_AF_INT_VEC_CNT; i++)
+ for (i = NIX_AF_INT_VEC_GEN; i < NIX_AF_INT_VEC_CNT; i++)
if (rvu->irq_allocated[offs + i]) {
free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
rvu->irq_allocated[offs + i] = false;
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
index af8cabe828d0..0a6bb346ba45 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -1559,12 +1559,11 @@ handle_xdp_verdict:
break;
default:
bpf_warn_invalid_xdp_action(pfvf->netdev, prog, act);
- break;
+ fallthrough;
case XDP_ABORTED:
- if (xsk_buff)
- xsk_buff_free(xsk_buff);
- trace_xdp_exception(pfvf->netdev, prog, act);
- break;
+ if (act == XDP_ABORTED)
+ trace_xdp_exception(pfvf->netdev, prog, act);
+ fallthrough;
case XDP_DROP:
cq->pool_ptrs++;
if (xsk_buff) {
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 2bf426cea6dd..72c1967768f4 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1175,7 +1175,7 @@ static int pxa168_eth_stop(struct net_device *dev)
/* Write to ICR to clear interrupts. */
wrl(pep, INT_W_CLEAR, 0);
napi_disable(&pep->napi);
- del_timer_sync(&pep->timeout);
+ timer_delete_sync(&pep->timeout);
netif_carrier_off(dev);
free_irq(dev->irq, dev);
rxq_deinit(dev);
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index a1bada9eaaf6..b2081d6e34f0 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -2662,7 +2662,7 @@ static int skge_down(struct net_device *dev)
netif_tx_disable(dev);
if (is_genesis(hw) && hw->phy_type == SK_PHY_XMAC)
- del_timer_sync(&skge->link_timer);
+ timer_delete_sync(&skge->link_timer);
napi_disable(&skge->napi);
netif_carrier_off(dev);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index d7121c836508..e2a9aae8bc9b 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -5052,7 +5052,7 @@ static int sky2_suspend(struct device *dev)
if (!hw)
return 0;
- del_timer_sync(&hw->watchdog_timer);
+ timer_delete_sync(&hw->watchdog_timer);
cancel_work_sync(&hw->restart_work);
rtnl_lock();
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig
index 825e05fb8607..0b1cb340206f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig
@@ -7,6 +7,7 @@ config MLX4_EN
tristate "Mellanox Technologies 1/10/40Gbit Ethernet support"
depends on PCI && NETDEVICES && ETHERNET && INET
depends on PTP_1588_CLOCK_OPTIONAL
+ select PAGE_POOL
select MLX4_CORE
help
This driver supports Mellanox Technologies ConnectX Ethernet
diff --git a/drivers/net/ethernet/mellanox/mlx4/catas.c b/drivers/net/ethernet/mellanox/mlx4/catas.c
index 0d8a362c2673..33ba0a5c38ac 100644
--- a/drivers/net/ethernet/mellanox/mlx4/catas.c
+++ b/drivers/net/ethernet/mellanox/mlx4/catas.c
@@ -305,7 +305,7 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
- del_timer_sync(&priv->catas_err.timer);
+ timer_delete_sync(&priv->catas_err.timer);
if (priv->catas_err.map) {
iounmap(priv->catas_err.map);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
index aa36670d9a36..58ec5e44aa7a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
@@ -430,7 +430,7 @@ u8 mlx5e_shampo_get_log_pkt_per_rsrv(struct mlx5_core_dev *mdev,
struct mlx5e_params *params)
{
u32 resrv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) *
- PAGE_SIZE;
+ MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE;
return order_base_2(DIV_ROUND_UP(resrv_size, params->sw_mtu));
}
@@ -834,7 +834,8 @@ static u32 mlx5e_shampo_get_log_cq_size(struct mlx5_core_dev *mdev,
struct mlx5e_params *params,
struct mlx5e_xsk_param *xsk)
{
- int rsrv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) * PAGE_SIZE;
+ int rsrv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) *
+ MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE;
u16 num_strides = BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk));
int pkt_per_rsrv = BIT(mlx5e_shampo_get_log_pkt_per_rsrv(mdev, params));
u8 log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
@@ -1043,7 +1044,8 @@ u32 mlx5e_shampo_hd_per_wqe(struct mlx5_core_dev *mdev,
struct mlx5e_params *params,
struct mlx5e_rq_param *rq_param)
{
- int resv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) * PAGE_SIZE;
+ int resv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) *
+ MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE;
u16 num_strides = BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, NULL));
int pkt_per_resv = BIT(mlx5e_shampo_get_log_pkt_per_rsrv(mdev, params));
u8 log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, NULL);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
index 6830a49fe682..5442a02c4097 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
@@ -246,7 +246,7 @@ static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
{
struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
- del_timer_sync(&fw_reset->timer);
+ timer_delete_sync(&fw_reset->timer);
}
static int mlx5_sync_reset_clear_reset_requested(struct mlx5_core_dev *dev, bool poll_health)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index 91613d5a36cd..624452ddebc0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -847,7 +847,7 @@ void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health)
if (disable_health)
set_bit(MLX5_DROP_HEALTH_WORK, &health->flags);
- del_timer_sync(&health->timer);
+ timer_delete_sync(&health->timer);
}
void mlx5_start_health_fw_log_up(struct mlx5_core_dev *dev)
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index dc1d9f774565..1302aa8e0853 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -3951,7 +3951,7 @@ static void ksz_stop_timer(struct ksz_timer_info *info)
{
if (info->max) {
info->max = 0;
- del_timer_sync(&info->timer);
+ timer_delete_sync(&info->timer);
}
}
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 1423df8531f7..2bac6be8f6a0 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -661,30 +661,16 @@ int mana_pre_alloc_rxbufs(struct mana_port_context *mpc, int new_mtu, int num_qu
mpc->rxbpre_total = 0;
for (i = 0; i < num_rxb; i++) {
- if (mpc->rxbpre_alloc_size > PAGE_SIZE) {
- va = netdev_alloc_frag(mpc->rxbpre_alloc_size);
- if (!va)
- goto error;
-
- page = virt_to_head_page(va);
- /* Check if the frag falls back to single page */
- if (compound_order(page) <
- get_order(mpc->rxbpre_alloc_size)) {
- put_page(page);
- goto error;
- }
- } else {
- page = dev_alloc_page();
- if (!page)
- goto error;
+ page = dev_alloc_pages(get_order(mpc->rxbpre_alloc_size));
+ if (!page)
+ goto error;
- va = page_to_virt(page);
- }
+ va = page_to_virt(page);
da = dma_map_single(dev, va + mpc->rxbpre_headroom,
mpc->rxbpre_datasize, DMA_FROM_DEVICE);
if (dma_mapping_error(dev, da)) {
- put_page(virt_to_head_page(va));
+ put_page(page);
goto error;
}
@@ -1676,7 +1662,7 @@ drop:
}
static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
- dma_addr_t *da, bool *from_pool, bool is_napi)
+ dma_addr_t *da, bool *from_pool)
{
struct page *page;
void *va;
@@ -1687,21 +1673,6 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
if (rxq->xdp_save_va) {
va = rxq->xdp_save_va;
rxq->xdp_save_va = NULL;
- } else if (rxq->alloc_size > PAGE_SIZE) {
- if (is_napi)
- va = napi_alloc_frag(rxq->alloc_size);
- else
- va = netdev_alloc_frag(rxq->alloc_size);
-
- if (!va)
- return NULL;
-
- page = virt_to_head_page(va);
- /* Check if the frag falls back to single page */
- if (compound_order(page) < get_order(rxq->alloc_size)) {
- put_page(page);
- return NULL;
- }
} else {
page = page_pool_dev_alloc_pages(rxq->page_pool);
if (!page)
@@ -1734,7 +1705,7 @@ static void mana_refill_rx_oob(struct device *dev, struct mana_rxq *rxq,
dma_addr_t da;
void *va;
- va = mana_get_rxfrag(rxq, dev, &da, &from_pool, true);
+ va = mana_get_rxfrag(rxq, dev, &da, &from_pool);
if (!va)
return;
@@ -2176,7 +2147,7 @@ static int mana_fill_rx_oob(struct mana_recv_buf_oob *rx_oob, u32 mem_key,
if (mpc->rxbufs_pre)
va = mana_get_rxbuf_pre(rxq, &da);
else
- va = mana_get_rxfrag(rxq, dev, &da, &from_pool, false);
+ va = mana_get_rxfrag(rxq, dev, &da, &from_pool);
if (!va)
return -ENOMEM;
@@ -2262,6 +2233,7 @@ static int mana_create_page_pool(struct mana_rxq *rxq, struct gdma_context *gc)
pprm.nid = gc->numa_node;
pprm.napi = &rxq->rx_cq.napi;
pprm.netdev = rxq->ndev;
+ pprm.order = get_order(rxq->alloc_size);
rxq->page_pool = page_pool_create(&pprm);
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index b7d9657a7af3..7c501a758325 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -2482,7 +2482,7 @@ static int myri10ge_close(struct net_device *dev)
if (mgp->ss[0].tx.req_bytes == NULL)
return 0;
- del_timer_sync(&mgp->watchdog_timer);
+ timer_delete_sync(&mgp->watchdog_timer);
mgp->running = MYRI10GE_ETH_STOPPING;
for (i = 0; i < mgp->num_slices; i++)
napi_disable(&mgp->ss[i].napi);
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index ad0c14849115..05606692e631 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -3179,7 +3179,7 @@ static int netdev_close(struct net_device *dev)
* the final WOL settings?
*/
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
disable_irq(irq);
spin_lock_irq(&np->lock);
natsemi_irq_disable(dev);
@@ -3278,7 +3278,7 @@ static int __maybe_unused natsemi_suspend(struct device *dev_d)
if (netif_running (dev)) {
const int irq = np->pci_dev->irq;
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
disable_irq(irq);
spin_lock_irq(&np->lock);
diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c
index bea969dfa536..bf0347715a05 100644
--- a/drivers/net/ethernet/natsemi/ns83820.c
+++ b/drivers/net/ethernet/natsemi/ns83820.c
@@ -1527,7 +1527,7 @@ static int ns83820_stop(struct net_device *ndev)
struct ns83820 *dev = PRIV(ndev);
/* FIXME: protect against interrupt handler? */
- del_timer_sync(&dev->tx_watchdog);
+ timer_delete_sync(&dev->tx_watchdog);
ns83820_disable_interrupts(dev);
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index f8016dc25e0a..3e55e8dc664c 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -7019,7 +7019,7 @@ static void do_s2io_card_down(struct s2io_nic *sp, int do_io)
if (!is_s2io_card_up(sp))
return;
- del_timer_sync(&sp->alarm_timer);
+ timer_delete_sync(&sp->alarm_timer);
/* If s2io_set_link task is executing, wait till it completes. */
while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state)))
msleep(50);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index abba165738a3..95514fabadf2 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -227,7 +227,7 @@ static void nfp_net_reconfig_sync_enter(struct nfp_net *nn)
spin_unlock_bh(&nn->reconfig_lock);
if (cancelled_timer) {
- del_timer_sync(&nn->reconfig_timer);
+ timer_delete_sync(&nn->reconfig_timer);
nfp_net_reconfig_wait(nn, nn->reconfig_timer.expires);
}
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 499e5e39d513..29cb74ccb25a 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -5623,9 +5623,9 @@ static int nv_close(struct net_device *dev)
napi_disable(&np->napi);
synchronize_irq(np->pci_dev->irq);
- del_timer_sync(&np->oom_kick);
- del_timer_sync(&np->nic_poll);
- del_timer_sync(&np->stats_poll);
+ timer_delete_sync(&np->oom_kick);
+ timer_delete_sync(&np->nic_poll);
+ timer_delete_sync(&np->stats_poll);
netif_stop_queue(dev);
spin_lock_irq(&np->lock);
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 4ac29cd59f2b..1651df8a7c21 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1916,7 +1916,7 @@ void pch_gbe_down(struct pch_gbe_adapter *adapter)
pch_gbe_irq_disable(adapter);
pch_gbe_free_irq(adapter);
- del_timer_sync(&adapter->watchdog_timer);
+ timer_delete_sync(&adapter->watchdog_timer);
netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
index a36d422b5173..26bc8b3b1ec8 100644
--- a/drivers/net/ethernet/packetengines/hamachi.c
+++ b/drivers/net/ethernet/packetengines/hamachi.c
@@ -1712,7 +1712,7 @@ static int hamachi_close(struct net_device *dev)
free_irq(hmp->pci_dev->irq, dev);
- del_timer_sync(&hmp->timer);
+ timer_delete_sync(&hmp->timer);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
index c0515dc63246..21b760e65d73 100644
--- a/drivers/net/ethernet/packetengines/yellowfin.c
+++ b/drivers/net/ethernet/packetengines/yellowfin.c
@@ -1222,7 +1222,7 @@ static int yellowfin_close(struct net_device *dev)
iowrite32(0x80000000, ioaddr + RxCtrl);
iowrite32(0x80000000, ioaddr + TxCtrl);
- del_timer(&yp->timer);
+ timer_delete(&yp->timer);
#if defined(__i386__)
if (yellowfin_debug > 2) {
diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c
index cb4e12df7719..801380729046 100644
--- a/drivers/net/ethernet/pasemi/pasemi_mac.c
+++ b/drivers/net/ethernet/pasemi/pasemi_mac.c
@@ -1288,7 +1288,7 @@ static int pasemi_mac_close(struct net_device *dev)
phy_disconnect(dev->phydev);
}
- del_timer_sync(&mac->tx->clean_timer);
+ timer_delete_sync(&mac->tx->clean_timer);
netif_stop_queue(dev);
napi_disable(&mac->napi);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
index f5dc876eb500..4c377bdc62c8 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
@@ -441,7 +441,7 @@ static void ionic_reset_prepare(struct pci_dev *pdev)
set_bit(IONIC_LIF_F_FW_RESET, lif->state);
- del_timer_sync(&ionic->watchdog_timer);
+ timer_delete_sync(&ionic->watchdog_timer);
cancel_work_sync(&lif->deferred.work);
mutex_lock(&lif->queue_lock);
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index fc78bc959ded..bf5bf8c95c85 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -3420,7 +3420,7 @@ static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset)
pci_disable_msi(qdev->pdev);
}
- del_timer_sync(&qdev->adapter_timer);
+ timer_delete_sync(&qdev->adapter_timer);
napi_disable(&qdev->napi);
diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c
index 6cbcb3164367..c73a57e4a144 100644
--- a/drivers/net/ethernet/realtek/atp.c
+++ b/drivers/net/ethernet/realtek/atp.c
@@ -832,7 +832,7 @@ net_close(struct net_device *dev)
netif_stop_queue(dev);
- del_timer_sync(&lp->timer);
+ timer_delete_sync(&lp->timer);
/* Flush the Tx and disable Rx here. */
lp->addr_mode = CMR2h_OFF;
diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
index 826990459fa4..d5db26103d82 100644
--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
+++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
@@ -2386,7 +2386,7 @@ static void ofdpa_fini(struct rocker *rocker)
struct hlist_node *tmp;
int bkt;
- del_timer_sync(&ofdpa->fdb_cleanup_timer);
+ timer_delete_sync(&ofdpa->fdb_cleanup_timer);
flush_workqueue(rocker->rocker_owq);
spin_lock_irqsave(&ofdpa->flow_tbl_lock, flags);
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 12c8396b6942..36b63bf343a9 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -91,7 +91,7 @@ void sxgbe_disable_eee_mode(struct sxgbe_priv_data * const priv)
{
/* Exit and disable EEE in case of we are in LPI state. */
priv->hw->mac->reset_eee_mode(priv->ioaddr);
- del_timer_sync(&priv->eee_ctrl_timer);
+ timer_delete_sync(&priv->eee_ctrl_timer);
priv->tx_path_in_lpi_mode = false;
}
@@ -1044,7 +1044,7 @@ static void sxgbe_tx_del_timer(struct sxgbe_priv_data *priv)
SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) {
struct sxgbe_tx_queue *p = priv->txq[queue_num];
- del_timer_sync(&p->txtimer);
+ timer_delete_sync(&p->txtimer);
}
}
@@ -1208,7 +1208,7 @@ static int sxgbe_release(struct net_device *dev)
struct sxgbe_priv_data *priv = netdev_priv(dev);
if (priv->eee_enabled)
- del_timer_sync(&priv->eee_ctrl_timer);
+ timer_delete_sync(&priv->eee_ctrl_timer);
/* Stop and disconnect the PHY */
if (dev->phydev) {
diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c
index 9319a2675e7b..1d65113fab76 100644
--- a/drivers/net/ethernet/seeq/ether3.c
+++ b/drivers/net/ethernet/seeq/ether3.c
@@ -181,7 +181,7 @@ static void ether3_ledoff(struct timer_list *t)
*/
static inline void ether3_ledon(struct net_device *dev)
{
- del_timer(&priv(dev)->timer);
+ timer_delete(&priv(dev)->timer);
priv(dev)->timer.expires = jiffies + HZ / 50; /* leave on for 1/50th second */
add_timer(&priv(dev)->timer);
if (priv(dev)->regs.config2 & CFG2_CTRLO)
@@ -454,7 +454,7 @@ static void ether3_timeout(struct net_device *dev, unsigned int txqueue)
{
unsigned long flags;
- del_timer(&priv(dev)->timer);
+ timer_delete(&priv(dev)->timer);
local_irq_save(flags);
printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name);
@@ -851,7 +851,7 @@ static void ether3_remove(struct expansion_card *ec)
ecard_set_drvdata(ec, NULL);
unregister_netdev(dev);
- del_timer_sync(&priv(dev)->timer);
+ timer_delete_sync(&priv(dev)->timer);
free_netdev(dev);
ecard_release_resources(ec);
}
diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
index d941f073f1eb..3a06e3b1bd6b 100644
--- a/drivers/net/ethernet/sfc/ef100_netdev.c
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -450,8 +450,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
net_dev->hw_enc_features |= efx->type->offload_features;
net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
- netif_set_tso_max_segs(net_dev,
- ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT);
+ nic_data = efx->nic_data;
+ netif_set_tso_max_size(efx->net_dev, nic_data->tso_max_payload_len);
+ netif_set_tso_max_segs(efx->net_dev, nic_data->tso_max_payload_num_segs);
rc = efx_ef100_init_datapath_caps(efx);
if (rc < 0)
@@ -477,7 +478,6 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
/* Don't fail init if RSS setup doesn't work. */
efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels);
- nic_data = efx->nic_data;
rc = ef100_get_mac_address(efx, net_dev->perm_addr, CLIENT_HANDLE_SELF,
efx->type->is_vf);
if (rc)
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 62e674d6ff60..3ad95a4c8af2 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -887,8 +887,7 @@ static int ef100_process_design_param(struct efx_nic *efx,
case ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS:
/* We always put HDR_NUM_SEGS=1 in our TSO descriptors */
if (!reader->value) {
- netif_err(efx, probe, efx->net_dev,
- "TSO_MAX_HDR_NUM_SEGS < 1\n");
+ pci_err(efx->pci_dev, "TSO_MAX_HDR_NUM_SEGS < 1\n");
return -EOPNOTSUPP;
}
return 0;
@@ -901,32 +900,28 @@ static int ef100_process_design_param(struct efx_nic *efx,
*/
if (!reader->value || reader->value > EFX_MIN_DMAQ_SIZE ||
EFX_MIN_DMAQ_SIZE % (u32)reader->value) {
- netif_err(efx, probe, efx->net_dev,
- "%s size granularity is %llu, can't guarantee safety\n",
- reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
- reader->value);
+ pci_err(efx->pci_dev,
+ "%s size granularity is %llu, can't guarantee safety\n",
+ reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
+ reader->value);
return -EOPNOTSUPP;
}
return 0;
case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN:
nic_data->tso_max_payload_len = min_t(u64, reader->value,
GSO_LEGACY_MAX_SIZE);
- netif_set_tso_max_size(efx->net_dev,
- nic_data->tso_max_payload_len);
return 0;
case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS:
nic_data->tso_max_payload_num_segs = min_t(u64, reader->value, 0xffff);
- netif_set_tso_max_segs(efx->net_dev,
- nic_data->tso_max_payload_num_segs);
return 0;
case ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES:
nic_data->tso_max_frames = min_t(u64, reader->value, 0xffff);
return 0;
case ESE_EF100_DP_GZ_COMPAT:
if (reader->value) {
- netif_err(efx, probe, efx->net_dev,
- "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
- reader->value);
+ pci_err(efx->pci_dev,
+ "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
+ reader->value);
return -EOPNOTSUPP;
}
return 0;
@@ -946,10 +941,10 @@ static int ef100_process_design_param(struct efx_nic *efx,
* So the value of this shouldn't matter.
*/
if (reader->value != ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT)
- netif_dbg(efx, probe, efx->net_dev,
- "NIC has other than default VI_STRIDES (mask "
- "%#llx), early probing might use wrong one\n",
- reader->value);
+ pci_dbg(efx->pci_dev,
+ "NIC has other than default VI_STRIDES (mask "
+ "%#llx), early probing might use wrong one\n",
+ reader->value);
return 0;
case ESE_EF100_DP_GZ_RX_MAX_RUNT:
/* Driver doesn't look at L2_STATUS:LEN_ERR bit, so we don't
@@ -961,9 +956,9 @@ static int ef100_process_design_param(struct efx_nic *efx,
/* Host interface says "Drivers should ignore design parameters
* that they do not recognise."
*/
- netif_dbg(efx, probe, efx->net_dev,
- "Ignoring unrecognised design parameter %u\n",
- reader->type);
+ pci_dbg(efx->pci_dev,
+ "Ignoring unrecognised design parameter %u\n",
+ reader->type);
return 0;
}
}
@@ -999,13 +994,13 @@ static int ef100_check_design_params(struct efx_nic *efx)
*/
if (reader.state != EF100_TLV_TYPE) {
if (reader.state == EF100_TLV_TYPE_CONT)
- netif_err(efx, probe, efx->net_dev,
- "truncated design parameter (incomplete type %u)\n",
- reader.type);
+ pci_err(efx->pci_dev,
+ "truncated design parameter (incomplete type %u)\n",
+ reader.type);
else
- netif_err(efx, probe, efx->net_dev,
- "truncated design parameter %u\n",
- reader.type);
+ pci_err(efx->pci_dev,
+ "truncated design parameter %u\n",
+ reader.type);
rc = -EIO;
}
out:
diff --git a/drivers/net/ethernet/sfc/falcon/falcon.c b/drivers/net/ethernet/sfc/falcon/falcon.c
index 4af56333ea49..b865275beb66 100644
--- a/drivers/net/ethernet/sfc/falcon/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon/falcon.c
@@ -2657,7 +2657,7 @@ void falcon_stop_nic_stats(struct ef4_nic *efx)
++nic_data->stats_disable_count;
spin_unlock_bh(&efx->stats_lock);
- del_timer_sync(&nic_data->stats_timer);
+ timer_delete_sync(&nic_data->stats_timer);
/* Wait enough time for the most recent transfer to
* complete. */
diff --git a/drivers/net/ethernet/sfc/falcon/rx.c b/drivers/net/ethernet/sfc/falcon/rx.c
index 6bbdb5d2eebf..38ad7ac07726 100644
--- a/drivers/net/ethernet/sfc/falcon/rx.c
+++ b/drivers/net/ethernet/sfc/falcon/rx.c
@@ -791,7 +791,7 @@ void ef4_fini_rx_queue(struct ef4_rx_queue *rx_queue)
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
"shutting down RX queue %d\n", ef4_rx_queue_index(rx_queue));
- del_timer_sync(&rx_queue->slow_fill);
+ timer_delete_sync(&rx_queue->slow_fill);
/* Release RX buffers from the current read ptr to the write ptr */
if (rx_queue->buffer) {
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index dbd2ee915838..dcef0588be96 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -530,7 +530,7 @@ static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout)
* of it aborting the next request.
*/
if (!timeout)
- del_timer_sync(&mcdi->async_timer);
+ timer_delete_sync(&mcdi->async_timer);
spin_lock(&mcdi->async_lock);
async = list_first_entry(&mcdi->async_list,
@@ -1122,7 +1122,7 @@ void efx_mcdi_flush_async(struct efx_nic *efx)
/* We must be in poll or fail mode so no more requests can be queued */
BUG_ON(mcdi->mode == MCDI_MODE_EVENTS);
- del_timer_sync(&mcdi->async_timer);
+ timer_delete_sync(&mcdi->async_timer);
/* If a request is still running, make sure we give the MC
* time to complete it so that the response won't overwrite our
diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
index 4cc83203e188..8eb272ba674b 100644
--- a/drivers/net/ethernet/sfc/rx_common.c
+++ b/drivers/net/ethernet/sfc/rx_common.c
@@ -285,7 +285,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
"shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
- del_timer_sync(&rx_queue->slow_fill);
+ timer_delete_sync(&rx_queue->slow_fill);
if (rx_queue->grant_credits)
flush_work(&rx_queue->grant_work);
diff --git a/drivers/net/ethernet/sfc/siena/mcdi.c b/drivers/net/ethernet/sfc/siena/mcdi.c
index 3f7899daa86a..99ab5f294691 100644
--- a/drivers/net/ethernet/sfc/siena/mcdi.c
+++ b/drivers/net/ethernet/sfc/siena/mcdi.c
@@ -534,7 +534,7 @@ static bool efx_mcdi_complete_async(struct efx_mcdi_iface *mcdi, bool timeout)
* of it aborting the next request.
*/
if (!timeout)
- del_timer_sync(&mcdi->async_timer);
+ timer_delete_sync(&mcdi->async_timer);
spin_lock(&mcdi->async_lock);
async = list_first_entry(&mcdi->async_list,
@@ -1145,7 +1145,7 @@ void efx_siena_mcdi_flush_async(struct efx_nic *efx)
/* We must be in poll or fail mode so no more requests can be queued */
BUG_ON(mcdi->mode == MCDI_MODE_EVENTS);
- del_timer_sync(&mcdi->async_timer);
+ timer_delete_sync(&mcdi->async_timer);
/* If a request is still running, make sure we give the MC
* time to complete it so that the response won't overwrite our
diff --git a/drivers/net/ethernet/sfc/siena/rx_common.c b/drivers/net/ethernet/sfc/siena/rx_common.c
index 2839d0e0a9c1..ab493e529d5c 100644
--- a/drivers/net/ethernet/sfc/siena/rx_common.c
+++ b/drivers/net/ethernet/sfc/siena/rx_common.c
@@ -284,7 +284,7 @@ void efx_siena_fini_rx_queue(struct efx_rx_queue *rx_queue)
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
"shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
- del_timer_sync(&rx_queue->slow_fill);
+ timer_delete_sync(&rx_queue->slow_fill);
/* Release RX buffers from the current read ptr to the write ptr */
if (rx_queue->buffer) {
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
index 4535579018c9..7196e1c607f3 100644
--- a/drivers/net/ethernet/sgi/ioc3-eth.c
+++ b/drivers/net/ethernet/sgi/ioc3-eth.c
@@ -718,7 +718,7 @@ static void ioc3_init(struct net_device *dev)
struct ioc3_private *ip = netdev_priv(dev);
struct ioc3_ethregs *regs = ip->regs;
- del_timer_sync(&ip->ioc3_timer); /* Kill if running */
+ timer_delete_sync(&ip->ioc3_timer); /* Kill if running */
writel(EMCR_RST, &regs->emcr); /* Reset */
readl(&regs->emcr); /* Flush WB */
@@ -801,7 +801,7 @@ static int ioc3_close(struct net_device *dev)
{
struct ioc3_private *ip = netdev_priv(dev);
- del_timer_sync(&ip->ioc3_timer);
+ timer_delete_sync(&ip->ioc3_timer);
netif_stop_queue(dev);
@@ -950,7 +950,7 @@ static int ioc3eth_probe(struct platform_device *pdev)
return 0;
out_stop:
- del_timer_sync(&ip->ioc3_timer);
+ timer_delete_sync(&ip->ioc3_timer);
if (ip->rxr)
dma_free_coherent(ip->dma_dev, RX_RING_SIZE, ip->rxr,
ip->rxr_dma);
@@ -971,7 +971,7 @@ static void ioc3eth_remove(struct platform_device *pdev)
dma_free_coherent(ip->dma_dev, TX_RING_SIZE + SZ_16K - 1, ip->tx_ring, ip->txr_dma);
unregister_netdev(dev);
- del_timer_sync(&ip->ioc3_timer);
+ timer_delete_sync(&ip->ioc3_timer);
free_netdev(dev);
}
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index dda4e488c77a..d10b14787607 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -758,7 +758,7 @@ static irqreturn_t sis190_irq(int irq, void *__dev)
if (status & LinkChange) {
netif_info(tp, intr, dev, "link change\n");
- del_timer(&tp->timer);
+ timer_delete(&tp->timer);
schedule_work(&tp->phy_task);
}
@@ -1034,7 +1034,7 @@ static inline void sis190_delete_timer(struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
}
static inline void sis190_request_timer(struct net_device *dev)
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 85b850372efe..332cbd725900 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -1983,7 +1983,7 @@ static int sis900_close(struct net_device *net_dev)
/* Stop the chip's Tx and Rx Status Machine */
sw32(cr, RxDIS | TxDIS | sr32(cr));
- del_timer(&sis_priv->timer);
+ timer_delete(&sis_priv->timer);
free_irq(pdev->irq, net_dev);
diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c
index 013e90d69182..ca0ab3a35b73 100644
--- a/drivers/net/ethernet/smsc/epic100.c
+++ b/drivers/net/ethernet/smsc/epic100.c
@@ -1292,7 +1292,7 @@ static int epic_close(struct net_device *dev)
netdev_dbg(dev, "Shutting down ethercard, status was %2.2x.\n",
er32(INTSTAT));
- del_timer_sync(&ep->timer);
+ timer_delete_sync(&ep->timer);
epic_disable_int(dev, ep);
diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c
index 86e3ec25df07..6fa957fb523b 100644
--- a/drivers/net/ethernet/smsc/smc91c92_cs.c
+++ b/drivers/net/ethernet/smsc/smc91c92_cs.c
@@ -1105,7 +1105,7 @@ static int smc_close(struct net_device *dev)
outw(CTL_POWERDOWN, ioaddr + CONTROL );
link->open--;
- del_timer_sync(&smc->media);
+ timer_delete_sync(&smc->media);
return 0;
} /* smc_close */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 279532609707..59d07d0d3369 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -467,7 +467,7 @@ static void stmmac_try_to_start_sw_lpi(struct stmmac_priv *priv)
*/
static void stmmac_stop_sw_lpi(struct stmmac_priv *priv)
{
- del_timer_sync(&priv->eee_ctrl_timer);
+ timer_delete_sync(&priv->eee_ctrl_timer);
stmmac_set_lpi_mode(priv, priv->hw, STMMAC_LPI_DISABLE, false, 0);
priv->tx_path_in_lpi_mode = false;
}
@@ -1082,7 +1082,7 @@ static void stmmac_mac_disable_tx_lpi(struct phylink_config *config)
netdev_dbg(priv->dev, "disable EEE\n");
priv->eee_sw_timer_en = false;
- del_timer_sync(&priv->eee_ctrl_timer);
+ timer_delete_sync(&priv->eee_ctrl_timer);
stmmac_set_lpi_mode(priv, priv->hw, STMMAC_LPI_DISABLE, false, 0);
priv->tx_path_in_lpi_mode = false;
@@ -7842,7 +7842,7 @@ int stmmac_suspend(struct device *dev)
if (priv->eee_sw_timer_en) {
priv->tx_path_in_lpi_mode = false;
- del_timer_sync(&priv->eee_ctrl_timer);
+ timer_delete_sync(&priv->eee_ctrl_timer);
}
/* Stop TX/RX DMA */
diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c
index b8948d5b779a..b777e5a099eb 100644
--- a/drivers/net/ethernet/sun/cassini.c
+++ b/drivers/net/ethernet/sun/cassini.c
@@ -3779,7 +3779,7 @@ static void cas_shutdown(struct cas *cp)
/* Make us not-running to avoid timers respawning */
cp->hw_running = 0;
- del_timer_sync(&cp->link_timer);
+ timer_delete_sync(&cp->link_timer);
/* Stop the reset task */
#if 0
diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
index a9a6670b5ff1..6fc37ab27f7b 100644
--- a/drivers/net/ethernet/sun/ldmvsw.c
+++ b/drivers/net/ethernet/sun/ldmvsw.c
@@ -390,7 +390,7 @@ static int vsw_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
return 0;
err_out_del_timer:
- del_timer_sync(&port->clean_timer);
+ timer_delete_sync(&port->clean_timer);
list_del_rcu(&port->list);
synchronize_rcu();
netif_napi_del(&port->napi);
@@ -408,8 +408,8 @@ static void vsw_port_remove(struct vio_dev *vdev)
unsigned long flags;
if (port) {
- del_timer_sync(&port->vio.timer);
- del_timer_sync(&port->clean_timer);
+ timer_delete_sync(&port->vio.timer);
+ timer_delete_sync(&port->clean_timer);
napi_disable(&port->napi);
unregister_netdev(port->dev);
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 72177fea1cfb..73c07f10f053 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -6165,7 +6165,7 @@ static void niu_full_shutdown(struct niu *np, struct net_device *dev)
niu_disable_napi(np);
netif_tx_stop_all_queues(dev);
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
spin_lock_irq(&np->lock);
@@ -6511,7 +6511,7 @@ static void niu_reset_task(struct work_struct *work)
spin_unlock_irqrestore(&np->lock, flags);
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
niu_netif_stop(np);
@@ -9914,7 +9914,7 @@ static int __maybe_unused niu_suspend(struct device *dev_d)
flush_work(&np->reset_task);
niu_netif_stop(np);
- del_timer_sync(&np->timer);
+ timer_delete_sync(&np->timer);
spin_lock_irqsave(&np->lock, flags);
niu_enable_interrupts(np, 0);
diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
index bbb3a6ca19ed..d2c82102133c 100644
--- a/drivers/net/ethernet/sun/sunbmac.c
+++ b/drivers/net/ethernet/sun/sunbmac.c
@@ -931,7 +931,7 @@ static int bigmac_close(struct net_device *dev)
{
struct bigmac *bp = netdev_priv(dev);
- del_timer(&bp->bigmac_timer);
+ timer_delete(&bp->bigmac_timer);
bp->timer_state = asleep;
bp->timer_ticks = 0;
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 3e5f9b17c777..06579d7b5220 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2180,7 +2180,7 @@ static void gem_do_stop(struct net_device *dev, int wol)
gem_disable_ints(gp);
/* Stop the link timer */
- del_timer_sync(&gp->link_timer);
+ timer_delete_sync(&gp->link_timer);
/* We cannot cancel the reset task while holding the
* rtnl lock, we'd get an A->B / B->A deadlock stituation
@@ -2230,7 +2230,7 @@ static void gem_reset_task(struct work_struct *work)
}
/* Stop the link timer */
- del_timer_sync(&gp->link_timer);
+ timer_delete_sync(&gp->link_timer);
/* Stop NAPI and tx */
gem_netif_stop(gp);
@@ -2610,7 +2610,7 @@ static int gem_set_link_ksettings(struct net_device *dev,
/* Apply settings and restart link process. */
if (netif_device_present(gp->dev)) {
- del_timer_sync(&gp->link_timer);
+ timer_delete_sync(&gp->link_timer);
gem_begin_auto_negotiation(gp, cmd);
}
@@ -2626,7 +2626,7 @@ static int gem_nway_reset(struct net_device *dev)
/* Restart link process */
if (netif_device_present(gp->dev)) {
- del_timer_sync(&gp->link_timer);
+ timer_delete_sync(&gp->link_timer);
gem_begin_auto_negotiation(gp, NULL);
}
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 50ace461a1af..9a7586623318 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -1265,7 +1265,7 @@ static int happy_meal_init(struct happy_meal *hp)
u32 regtmp, rxcfg;
/* If auto-negotiation timer is running, kill it. */
- del_timer(&hp->happy_timer);
+ timer_delete(&hp->happy_timer);
HMD("happy_flags[%08x]\n", hp->happy_flags);
if (!(hp->happy_flags & HFLAG_INIT)) {
@@ -1922,7 +1922,7 @@ static int happy_meal_close(struct net_device *dev)
happy_meal_clean_rings(hp);
/* If auto-negotiation timer is running, kill it. */
- del_timer(&hp->happy_timer);
+ timer_delete(&hp->happy_timer);
spin_unlock_irq(&hp->happy_lock);
@@ -2184,7 +2184,7 @@ static int hme_set_link_ksettings(struct net_device *dev,
/* Ok, do it to it. */
spin_lock_irq(&hp->happy_lock);
- del_timer(&hp->happy_timer);
+ timer_delete(&hp->happy_timer);
happy_meal_begin_auto_negotiation(hp, hp->tcvregs, cmd);
spin_unlock_irq(&hp->happy_lock);
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 1e887d951a04..a2a3e94da4b8 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -505,7 +505,7 @@ static void vnet_port_remove(struct vio_dev *vdev)
struct vnet_port *port = dev_get_drvdata(&vdev->dev);
if (port) {
- del_timer_sync(&port->vio.timer);
+ timer_delete_sync(&port->vio.timer);
napi_disable(&port->napi);
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index 1cacb2a0ee03..ddc6d46a7a86 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -1058,7 +1058,7 @@ void sunvnet_clean_timer_expire_common(struct timer_list *t)
(void)mod_timer(&port->clean_timer,
jiffies + VNET_CLEAN_TIMEOUT);
else
- del_timer(&port->clean_timer);
+ timer_delete(&port->clean_timer);
}
EXPORT_SYMBOL_GPL(sunvnet_clean_timer_expire_common);
@@ -1513,7 +1513,7 @@ out_dropped:
(void)mod_timer(&port->clean_timer,
jiffies + VNET_CLEAN_TIMEOUT);
else if (port)
- del_timer(&port->clean_timer);
+ timer_delete(&port->clean_timer);
rcu_read_unlock();
dev_kfree_skb(skb);
vnet_free_skbs(freeskbs);
@@ -1707,7 +1707,7 @@ EXPORT_SYMBOL_GPL(sunvnet_port_free_tx_bufs_common);
void vnet_port_reset(struct vnet_port *port)
{
- del_timer(&port->clean_timer);
+ timer_delete(&port->clean_timer);
sunvnet_port_free_tx_bufs_common(port);
port->rmtu = 0;
port->tso = (port->vsw == 0); /* no tso in vsw, misbehaves in bridge */
diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c b/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
index d1793b6154c7..24e4b246f25f 100644
--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
+++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-net.c
@@ -405,7 +405,7 @@ static void xlgmac_stop_timers(struct xlgmac_pdata *pdata)
if (!channel->tx_ring)
break;
- del_timer_sync(&channel->tx_timer);
+ timer_delete_sync(&channel->tx_timer);
}
}
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index b3118bf0757e..c9fd34787c99 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -516,7 +516,7 @@ static void am65_cpsw_destroy_rxq(struct am65_cpsw_common *common, int id)
napi_disable(&flow->napi_rx);
hrtimer_cancel(&flow->rx_hrtimer);
k3_udma_glue_reset_rx_chn(rx_chn->rx_chn, id, rx_chn,
- am65_cpsw_nuss_rx_cleanup, !!id);
+ am65_cpsw_nuss_rx_cleanup);
for (port = 0; port < common->port_num; port++) {
if (!common->ports[port].ndev)
@@ -3332,7 +3332,7 @@ static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common)
for (i = 0; i < common->rx_ch_num_flows; i++)
k3_udma_glue_reset_rx_chn(rx_chan->rx_chn, i,
rx_chan,
- am65_cpsw_nuss_rx_cleanup, !!i);
+ am65_cpsw_nuss_rx_cleanup);
k3_udma_glue_disable_rx_chn(rx_chan->rx_chn);
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 5cc72a91f220..7f77694ecfba 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -1287,7 +1287,7 @@ static void cpsw_ale_aging_stop(struct cpsw_ale *ale)
return;
}
- del_timer_sync(&ale->timer);
+ timer_delete_sync(&ale->timer);
}
void cpsw_ale_start(struct cpsw_ale *ale)
diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index 46f500b90b17..14002b026452 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -1212,7 +1212,7 @@ void prueth_reset_rx_chan(struct prueth_rx_chn *chn,
for (i = 0; i < num_flows; i++)
k3_udma_glue_reset_rx_chn(chn->rx_chn, i, chn,
- prueth_rx_cleanup, !!i);
+ prueth_rx_cleanup);
if (disable)
k3_udma_glue_disable_rx_chn(chn->rx_chn);
diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
index 63e686f0b119..fd2b74508980 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -3796,7 +3796,7 @@ static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv)
{
struct gbe_priv *gbe_dev = inst_priv;
- del_timer_sync(&gbe_dev->timer);
+ timer_delete_sync(&gbe_dev->timer);
cpts_release(gbe_dev->cpts);
cpsw_ale_stop(gbe_dev->ale);
netcp_txpipe_close(&gbe_dev->tx_pipe);
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index b3da76efa8f5..d9240fb91747 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -332,13 +332,13 @@ static void tlan_stop(struct net_device *dev)
{
struct tlan_priv *priv = netdev_priv(dev);
- del_timer_sync(&priv->media_timer);
+ timer_delete_sync(&priv->media_timer);
tlan_read_and_clear_stats(dev, TLAN_RECORD);
outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
/* Reset and power down phy */
tlan_reset_adapter(dev);
if (priv->timer.function != NULL) {
- del_timer_sync(&priv->timer);
+ timer_delete_sync(&priv->timer);
priv->timer.function = NULL;
}
}
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index c6957e3b7f0f..7ec0e3c13d54 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -1379,7 +1379,7 @@ static int tsi108_close(struct net_device *dev)
netif_stop_queue(dev);
napi_disable(&data->napi);
- del_timer_sync(&data->timer);
+ timer_delete_sync(&data->timer);
tsi108_stop_ethernet(dev);
tsi108_kill_phy(dev);
diff --git a/drivers/net/fddi/defza.c b/drivers/net/fddi/defza.c
index f5c25acaa577..54b7f24f3810 100644
--- a/drivers/net/fddi/defza.c
+++ b/drivers/net/fddi/defza.c
@@ -983,7 +983,7 @@ static irqreturn_t fza_interrupt(int irq, void *dev_id)
case FZA_STATE_UNINITIALIZED:
netif_carrier_off(dev);
- del_timer_sync(&fp->reset_timer);
+ timer_delete_sync(&fp->reset_timer);
fp->ring_cmd_index = 0;
fp->ring_uns_index = 0;
fp->ring_rmc_tx_index = 0;
@@ -1017,7 +1017,7 @@ static irqreturn_t fza_interrupt(int irq, void *dev_id)
fp->queue_active = 0;
netif_stop_queue(dev);
pr_debug("%s: queue stopped\n", fp->name);
- del_timer_sync(&fp->reset_timer);
+ timer_delete_sync(&fp->reset_timer);
pr_warn("%s: halted, reason: %x\n", fp->name,
FZA_STATUS_GET_HALT(status));
fza_regs_dump(fp);
@@ -1227,7 +1227,7 @@ static int fza_close(struct net_device *dev)
netif_stop_queue(dev);
pr_debug("%s: queue stopped\n", fp->name);
- del_timer_sync(&fp->reset_timer);
+ timer_delete_sync(&fp->reset_timer);
spin_lock_irqsave(&fp->lock, flags);
fp->state = FZA_STATE_UNINITIALIZED;
fp->state_chg_flag = 0;
@@ -1493,7 +1493,7 @@ static int fza_probe(struct device *bdev)
return 0;
err_out_irq:
- del_timer_sync(&fp->reset_timer);
+ timer_delete_sync(&fp->reset_timer);
fza_do_shutdown(fp);
free_irq(dev->irq, dev);
@@ -1520,7 +1520,7 @@ static int fza_remove(struct device *bdev)
unregister_netdev(dev);
- del_timer_sync(&fp->reset_timer);
+ timer_delete_sync(&fp->reset_timer);
fza_do_shutdown(fp);
free_irq(dev->irq, dev);
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 3bf6785f9057..b33d84ed5bbf 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -660,8 +660,8 @@ static void sixpack_close(struct tty_struct *tty)
unregister_netdev(sp->dev);
- del_timer_sync(&sp->tx_t);
- del_timer_sync(&sp->resync_t);
+ timer_delete_sync(&sp->tx_t);
+ timer_delete_sync(&sp->resync_t);
/* Free all 6pack frame buffers after unreg. */
kfree(sp->xbuff);
@@ -937,7 +937,7 @@ sixpack_decode(struct sixpack *sp, const u8 *pre_rbuff, size_t count)
inbyte = pre_rbuff[count1];
if (inbyte == SIXP_FOUND_TNC) {
tnc_set_sync_state(sp, TNC_IN_SYNC);
- del_timer(&sp->resync_t);
+ timer_delete(&sp->resync_t);
}
if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
decode_prio_command(sp, inbyte);
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index c71e52249289..f88721dec681 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -794,8 +794,8 @@ static inline void init_brg(struct scc_channel *scc)
static void init_channel(struct scc_channel *scc)
{
- del_timer(&scc->tx_t);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_t);
+ timer_delete(&scc->tx_wdog);
disable_irq(scc->irq);
@@ -999,7 +999,7 @@ static void __scc_start_tx_timer(struct scc_channel *scc,
void (*handler)(struct timer_list *t),
unsigned long when)
{
- del_timer(&scc->tx_t);
+ timer_delete(&scc->tx_t);
if (when == 0)
{
@@ -1029,7 +1029,7 @@ static void scc_start_defer(struct scc_channel *scc)
unsigned long flags;
spin_lock_irqsave(&scc->lock, flags);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_wdog);
if (scc->kiss.maxdefer != 0 && scc->kiss.maxdefer != TIMER_OFF)
{
@@ -1045,7 +1045,7 @@ static void scc_start_maxkeyup(struct scc_channel *scc)
unsigned long flags;
spin_lock_irqsave(&scc->lock, flags);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_wdog);
if (scc->kiss.maxkeyup != 0 && scc->kiss.maxkeyup != TIMER_OFF)
{
@@ -1194,7 +1194,7 @@ static void t_tail(struct timer_list *t)
unsigned long flags;
spin_lock_irqsave(&scc->lock, flags);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_wdog);
scc_key_trx(scc, TX_OFF);
spin_unlock_irqrestore(&scc->lock, flags);
@@ -1219,7 +1219,7 @@ static void t_busy(struct timer_list *t)
{
struct scc_channel *scc = from_timer(scc, t, tx_wdog);
- del_timer(&scc->tx_t);
+ timer_delete(&scc->tx_t);
netif_stop_queue(scc->dev); /* don't pile on the wabbit! */
scc_discard_buffers(scc);
@@ -1248,7 +1248,7 @@ static void t_maxkeyup(struct timer_list *t)
netif_stop_queue(scc->dev);
scc_discard_buffers(scc);
- del_timer(&scc->tx_t);
+ timer_delete(&scc->tx_t);
cl(scc, R1, TxINT_ENAB); /* force an ABORT, but don't */
cl(scc, R15, TxUIE); /* count it. */
@@ -1272,7 +1272,7 @@ static void t_idle(struct timer_list *t)
{
struct scc_channel *scc = from_timer(scc, t, tx_t);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_wdog);
scc_key_trx(scc, TX_OFF);
if(scc->kiss.mintime)
@@ -1407,7 +1407,7 @@ static void scc_stop_calibrate(struct timer_list *t)
unsigned long flags;
spin_lock_irqsave(&scc->lock, flags);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_wdog);
scc_key_trx(scc, TX_OFF);
wr(scc, R6, 0);
wr(scc, R7, FLAG);
@@ -1428,7 +1428,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
netif_stop_queue(scc->dev);
scc_discard_buffers(scc);
- del_timer(&scc->tx_wdog);
+ timer_delete(&scc->tx_wdog);
scc->tx_wdog.function = scc_stop_calibrate;
scc->tx_wdog.expires = jiffies + HZ*duration;
@@ -1609,8 +1609,8 @@ static int scc_net_close(struct net_device *dev)
wr(scc,R3,0);
spin_unlock_irqrestore(&scc->lock, flags);
- del_timer_sync(&scc->tx_t);
- del_timer_sync(&scc->tx_wdog);
+ timer_delete_sync(&scc->tx_t);
+ timer_delete_sync(&scc->tx_wdog);
scc_discard_buffers(scc);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 2ed2f836f09a..f29997b20fd7 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -1158,7 +1158,7 @@ static void __exit yam_cleanup_driver(void)
struct yam_mcs *p;
int i;
- del_timer_sync(&yam_timer);
+ timer_delete_sync(&yam_timer);
for (i = 0; i < NR_PORTS; i++) {
struct net_device *dev = yam_devs[i];
if (dev) {
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index aa8f828a0ae7..6342c319c0e4 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -1357,7 +1357,7 @@ static int rr_close(struct net_device *dev)
rrpriv->fw_running = 0;
spin_unlock_irqrestore(&rrpriv->lock, flags);
- del_timer_sync(&rrpriv->timer);
+ timer_delete_sync(&rrpriv->timer);
spin_lock_irqsave(&rrpriv->lock, flags);
writel(0, &regs->TxPi);
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index b67af4651185..0e0321a7ddd7 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -441,8 +441,8 @@ static enum hrtimer_restart nsim_napi_schedule(struct hrtimer *timer)
static void nsim_rq_timer_init(struct nsim_rq *rq)
{
- hrtimer_init(&rq->napi_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- rq->napi_timer.function = nsim_napi_schedule;
+ hrtimer_setup(&rq->napi_timer, nsim_napi_schedule, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
}
static void nsim_enable_napi(struct netdevsim *ns)
@@ -939,6 +939,7 @@ static int nsim_init_netdevsim(struct netdevsim *ns)
ns->netdev->netdev_ops = &nsim_netdev_ops;
ns->netdev->stat_ops = &nsim_stat_ops;
ns->netdev->queue_mgmt_ops = &nsim_queue_mgmt_ops;
+ netdev_lockdep_set_classes(ns->netdev);
err = nsim_udp_tunnels_info_create(ns->nsim_dev, ns->netdev);
if (err)
@@ -960,6 +961,14 @@ static int nsim_init_netdevsim(struct netdevsim *ns)
if (err)
goto err_ipsec_teardown;
rtnl_unlock();
+
+ if (IS_ENABLED(CONFIG_DEBUG_NET)) {
+ ns->nb.notifier_call = netdev_debug_event;
+ if (register_netdevice_notifier_dev_net(ns->netdev, &ns->nb,
+ &ns->nn))
+ ns->nb.notifier_call = NULL;
+ }
+
return 0;
err_ipsec_teardown:
@@ -1043,6 +1052,10 @@ void nsim_destroy(struct netdevsim *ns)
debugfs_remove(ns->qr_dfs);
debugfs_remove(ns->pp_dfs);
+ if (ns->nb.notifier_call)
+ unregister_netdevice_notifier_dev_net(ns->netdev, &ns->nb,
+ &ns->nn);
+
rtnl_lock();
peer = rtnl_dereference(ns->peer);
if (peer)
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 665020d18f29..d04401f0bdf7 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -144,6 +144,9 @@ struct netdevsim {
struct nsim_ethtool ethtool;
struct netdevsim __rcu *peer;
+
+ struct notifier_block nb;
+ struct netdev_net_notifier nn;
};
struct netdevsim *
diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
index ef6df0e37bea..ef4204638392 100644
--- a/drivers/net/ntb_netdev.c
+++ b/drivers/net/ntb_netdev.c
@@ -291,7 +291,7 @@ static int ntb_netdev_close(struct net_device *ndev)
while ((skb = ntb_transport_rx_remove(dev->qp, &len)))
dev_kfree_skb(skb);
- del_timer_sync(&dev->tx_timer);
+ timer_delete_sync(&dev->tx_timer);
return 0;
}
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 13e43fee1906..9b1de54fd483 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -859,7 +859,7 @@ static int brcm_fet_config_init(struct phy_device *phydev)
return reg;
/* Unmask events we are interested in and mask interrupts globally. */
- if (phydev->phy_id == PHY_ID_BCM5221)
+ if (phydev->drv->phy_id == PHY_ID_BCM5221)
reg = MII_BRCM_FET_IR_ENABLE |
MII_BRCM_FET_IR_MASK;
else
@@ -888,7 +888,7 @@ static int brcm_fet_config_init(struct phy_device *phydev)
return err;
}
- if (phydev->phy_id != PHY_ID_BCM5221) {
+ if (phydev->drv->phy_id != PHY_ID_BCM5221) {
/* Set the LED mode */
reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
if (reg < 0) {
@@ -1009,7 +1009,7 @@ static int brcm_fet_suspend(struct phy_device *phydev)
return err;
}
- if (phydev->phy_id == PHY_ID_BCM5221)
+ if (phydev->drv->phy_id == PHY_ID_BCM5221)
/* Force Low Power Mode with clock enabled */
reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
else
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 69ca765485db..b68369e2342b 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -952,7 +952,7 @@ static unsigned int phylink_inband_caps(struct phylink *pl,
static void phylink_pcs_poll_stop(struct phylink *pl)
{
if (pl->cfg_link_an_mode == MLO_AN_INBAND)
- del_timer(&pl->link_poll);
+ timer_delete(&pl->link_poll);
}
static void phylink_pcs_poll_start(struct phylink *pl)
@@ -2448,7 +2448,7 @@ void phylink_stop(struct phylink *pl)
sfp_upstream_stop(pl->sfp_bus);
if (pl->phydev)
phy_stop(pl->phydev);
- del_timer_sync(&pl->link_poll);
+ timer_delete_sync(&pl->link_poll);
if (pl->link_irq) {
free_irq(pl->link_irq, pl);
pl->link_irq = 0;
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index fb362ee248ff..3cfa17cd5073 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -899,8 +899,8 @@ static void slip_close(struct tty_struct *tty)
/* VSV = very important to remove timers */
#ifdef CONFIG_SLIP_SMART
- del_timer_sync(&sl->keepalive_timer);
- del_timer_sync(&sl->outfill_timer);
+ timer_delete_sync(&sl->keepalive_timer);
+ timer_delete_sync(&sl->outfill_timer);
#endif
/* Flush network side */
unregister_netdev(sl->dev);
@@ -1137,7 +1137,7 @@ static int slip_ioctl(struct tty_struct *tty, unsigned int cmd,
jiffies + sl->keepalive * HZ);
set_bit(SLF_KEEPTEST, &sl->flags);
} else
- del_timer(&sl->keepalive_timer);
+ timer_delete(&sl->keepalive_timer);
spin_unlock_bh(&sl->lock);
return 0;
@@ -1162,7 +1162,7 @@ static int slip_ioctl(struct tty_struct *tty, unsigned int cmd,
jiffies + sl->outfill * HZ);
set_bit(SLF_OUTWAIT, &sl->flags);
} else
- del_timer(&sl->outfill_timer);
+ timer_delete(&sl->outfill_timer);
spin_unlock_bh(&sl->lock);
return 0;
@@ -1217,7 +1217,7 @@ static int sl_siocdevprivate(struct net_device *dev, struct ifreq *rq,
jiffies + sl->keepalive * HZ);
set_bit(SLF_KEEPTEST, &sl->flags);
} else
- del_timer(&sl->keepalive_timer);
+ timer_delete(&sl->keepalive_timer);
break;
case SIOCGKEEPALIVE:
@@ -1235,7 +1235,7 @@ static int sl_siocdevprivate(struct net_device *dev, struct ifreq *rq,
jiffies + sl->outfill * HZ);
set_bit(SLF_OUTWAIT, &sl->flags);
} else
- del_timer(&sl->outfill_timer);
+ timer_delete(&sl->outfill_timer);
break;
case SIOCGOUTFILL:
@@ -1421,7 +1421,7 @@ static void sl_keepalive(struct timer_list *t)
/* keepalive still high :(, we must hangup */
if (sl->outfill)
/* outfill timer must be deleted too */
- (void)del_timer(&sl->outfill_timer);
+ (void) timer_delete(&sl->outfill_timer);
printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
/* this must hangup tty & close slip */
tty_hangup(sl->tty);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index f75f912a0225..7babd1e9a378 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1295,7 +1295,7 @@ static void tun_flow_init(struct tun_struct *tun)
static void tun_flow_uninit(struct tun_struct *tun)
{
- del_timer_sync(&tun->flow_gc_timer);
+ timer_delete_sync(&tun->flow_gc_timer);
tun_flow_flush(tun);
}
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index ff439ef535ac..fc5e441aa7c3 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -738,7 +738,7 @@ static int catc_stop(struct net_device *netdev)
netif_stop_queue(netdev);
if (!catc->is_f5u011)
- del_timer_sync(&catc->timer);
+ timer_delete_sync(&catc->timer);
usb_kill_urb(catc->rx_urb);
usb_kill_urb(catc->tx_urb);
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 137adf6d5b08..e4f1663b6204 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1661,7 +1661,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
if (ret < 0)
return ret;
- del_timer(&dev->stat_monitor);
+ timer_delete(&dev->stat_monitor);
} else if (link && !dev->link_on) {
dev->link_on = true;
@@ -3304,7 +3304,7 @@ static int lan78xx_stop(struct net_device *net)
mutex_lock(&dev->dev_mutex);
if (timer_pending(&dev->stat_monitor))
- del_timer_sync(&dev->stat_monitor);
+ timer_delete_sync(&dev->stat_monitor);
clear_bit(EVENT_DEV_OPEN, &dev->flags);
netif_stop_queue(net);
@@ -4938,7 +4938,7 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
/* reattach */
netif_device_attach(dev->net);
- del_timer(&dev->stat_monitor);
+ timer_delete(&dev->stat_monitor);
if (PMSG_IS_AUTO(message)) {
ret = lan78xx_set_auto_suspend(dev);
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 7b3739b29c8f..bb0bf1415872 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -630,6 +630,16 @@ static const struct driver_info zte_rndis_info = {
.tx_fixup = rndis_tx_fixup,
};
+static const struct driver_info wwan_rndis_info = {
+ .description = "Mobile Broadband RNDIS device",
+ .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+ .bind = rndis_bind,
+ .unbind = rndis_unbind,
+ .status = rndis_status,
+ .rx_fixup = rndis_rx_fixup,
+ .tx_fixup = rndis_tx_fixup,
+};
+
/*-------------------------------------------------------------------------*/
static const struct usb_device_id products [] = {
@@ -666,9 +676,11 @@ static const struct usb_device_id products [] = {
USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
.driver_info = (unsigned long) &rndis_info,
}, {
- /* Novatel Verizon USB730L */
+ /* Mobile Broadband Modem, seen in Novatel Verizon USB730L and
+ * Telit FN990A (RNDIS)
+ */
USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
- .driver_info = (unsigned long) &rndis_info,
+ .driver_info = (unsigned long)&wwan_rndis_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index 3d239b8d1a1b..dec6e82eb0e0 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -522,7 +522,7 @@ static void sierra_net_kevent(struct work_struct *work)
" stopping sync timer",
hh.msgspecific.byte);
/* Got sync resp - stop timer & clear mask */
- del_timer_sync(&priv->sync_timer);
+ timer_delete_sync(&priv->sync_timer);
clear_bit(SIERRA_NET_TIMER_EXPIRY,
&priv->kevent_flags);
break;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 44179f4e807f..c39dfa17813a 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -178,6 +178,17 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
}
EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
+static bool usbnet_needs_usb_name_format(struct usbnet *dev, struct net_device *net)
+{
+ /* Point to point devices which don't have a real MAC address
+ * (or report a fake local one) have historically used the usb%d
+ * naming. Preserve this..
+ */
+ return (dev->driver_info->flags & FLAG_POINTTOPOINT) != 0 &&
+ (is_zero_ether_addr(net->dev_addr) ||
+ is_local_ether_addr(net->dev_addr));
+}
+
static void intr_complete (struct urb *urb)
{
struct usbnet *dev = urb->context;
@@ -519,7 +530,8 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
netif_device_present (dev->net) &&
test_bit(EVENT_DEV_OPEN, &dev->flags) &&
!test_bit (EVENT_RX_HALT, &dev->flags) &&
- !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
+ !test_bit (EVENT_DEV_ASLEEP, &dev->flags) &&
+ !usbnet_going_away(dev)) {
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
case -EPIPE:
usbnet_defer_kevent (dev, EVENT_RX_HALT);
@@ -540,8 +552,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
tasklet_schedule (&dev->bh);
break;
case 0:
- if (!usbnet_going_away(dev))
- __usbnet_queue_skb(&dev->rxq, skb, rx_start);
+ __usbnet_queue_skb(&dev->rxq, skb, rx_start);
}
} else {
netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
@@ -849,7 +860,7 @@ int usbnet_stop (struct net_device *net)
/* deferred work (timer, softirq, task) must also stop */
dev->flags = 0;
- del_timer_sync(&dev->delay);
+ timer_delete_sync(&dev->delay);
tasklet_kill(&dev->bh);
cancel_work_sync(&dev->kevent);
@@ -858,7 +869,7 @@ int usbnet_stop (struct net_device *net)
* we have a flag
*/
tasklet_kill(&dev->bh);
- del_timer_sync(&dev->delay);
+ timer_delete_sync(&dev->delay);
cancel_work_sync(&dev->kevent);
if (!pm)
@@ -1762,13 +1773,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if (status < 0)
goto out1;
- // heuristic: "usb%d" for links we know are two-host,
- // else "eth%d" when there's reasonable doubt. userspace
- // can rename the link if it knows better.
+ /* heuristic: rename to "eth%d" if we are not sure this link
+ * is two-host (these links keep "usb%d")
+ */
if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
- ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
- /* somebody touched it*/
- !is_zero_ether_addr(net->dev_addr)))
+ !usbnet_needs_usb_name_format(dev, net))
strscpy(net->name, "eth%d", sizeof(net->name));
/* WLAN devices should always be named "wlan%d" */
if ((dev->driver_info->flags & FLAG_WLAN) != 0)
@@ -1873,7 +1882,7 @@ out1:
*/
usbnet_mark_going_away(dev);
cancel_work_sync(&dev->kevent);
- del_timer_sync(&dev->delay);
+ timer_delete_sync(&dev->delay);
free_netdev(net);
out:
return status;
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 8c49e903cb3a..9ccc3f09f71b 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -3193,7 +3193,7 @@ static int vxlan_stop(struct net_device *dev)
vxlan_multicast_leave(vxlan);
- del_timer_sync(&vxlan->age_timer);
+ timer_delete_sync(&vxlan->age_timer);
vxlan_flush(vxlan, &desc);
vxlan_sock_release(vxlan);
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index cdebe65a7e2d..7e653432c139 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -285,7 +285,7 @@ static void cisco_stop(struct net_device *dev)
struct cisco_state *st = state(hdlc);
unsigned long flags;
- del_timer_sync(&st->timer);
+ timer_delete_sync(&st->timer);
spin_lock_irqsave(&st->lock, flags);
netif_dormant_on(dev);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 81e72bc1891f..34014f427060 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1025,7 +1025,7 @@ static void fr_stop(struct net_device *dev)
printk(KERN_DEBUG "fr_stop\n");
#endif
if (state(hdlc)->settings.lmi != LMI_NONE)
- del_timer_sync(&state(hdlc)->timer);
+ timer_delete_sync(&state(hdlc)->timer);
fr_set_link_state(0, dev);
}
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 37a3c989cba1..19921b02846d 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -358,7 +358,7 @@ static void ppp_cp_event(struct net_device *dev, u16 pid, u16 event, u8 code,
}
}
if (old_state != CLOSED && proto->state == CLOSED)
- del_timer(&proto->timer);
+ timer_delete(&proto->timer);
#if DEBUG_STATE
printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) ... %s\n", dev->name,
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 56326f38fe8a..995a7207bdf8 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -39,6 +39,7 @@
#include <linux/lapb.h>
#include <linux/init.h>
+#include <net/netdev_lock.h>
#include <net/x25device.h>
static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -366,6 +367,7 @@ static const struct net_device_ops lapbeth_netdev_ops = {
static void lapbeth_setup(struct net_device *dev)
{
+ netdev_lockdep_set_classes(dev);
dev->netdev_ops = &lapbeth_netdev_ops;
dev->needs_free_netdev = true;
dev->type = ARPHRD_X25;
diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
index c496d35b266d..3ffeeba5dccf 100644
--- a/drivers/net/wireguard/device.c
+++ b/drivers/net/wireguard/device.c
@@ -81,7 +81,7 @@ static int wg_pm_notification(struct notifier_block *nb, unsigned long action, v
list_for_each_entry(wg, &device_list, device_list) {
mutex_lock(&wg->device_update_lock);
list_for_each_entry(peer, &wg->peer_list, peer_list) {
- del_timer(&peer->timer_zero_key_material);
+ timer_delete(&peer->timer_zero_key_material);
wg_noise_handshake_clear(&peer->handshake);
wg_noise_keypairs_clear(&peer->keypairs);
}
diff --git a/drivers/net/wireguard/timers.c b/drivers/net/wireguard/timers.c
index 968bdb4df0b3..a9e0890c2f77 100644
--- a/drivers/net/wireguard/timers.c
+++ b/drivers/net/wireguard/timers.c
@@ -48,7 +48,7 @@ static void wg_expired_retransmit_handshake(struct timer_list *timer)
peer->device->dev->name, peer->internal_id,
&peer->endpoint.addr, (int)MAX_TIMER_HANDSHAKES + 2);
- del_timer(&peer->timer_send_keepalive);
+ timer_delete(&peer->timer_send_keepalive);
/* We drop all packets without a keypair and don't try again,
* if we try unsuccessfully for too long to make a handshake.
*/
@@ -167,7 +167,7 @@ void wg_timers_data_received(struct wg_peer *peer)
*/
void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer)
{
- del_timer(&peer->timer_send_keepalive);
+ timer_delete(&peer->timer_send_keepalive);
}
/* Should be called after any type of authenticated packet is received, whether
@@ -175,7 +175,7 @@ void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer)
*/
void wg_timers_any_authenticated_packet_received(struct wg_peer *peer)
{
- del_timer(&peer->timer_new_handshake);
+ timer_delete(&peer->timer_new_handshake);
}
/* Should be called after a handshake initiation message is sent. */
@@ -191,7 +191,7 @@ void wg_timers_handshake_initiated(struct wg_peer *peer)
*/
void wg_timers_handshake_complete(struct wg_peer *peer)
{
- del_timer(&peer->timer_retransmit_handshake);
+ timer_delete(&peer->timer_retransmit_handshake);
peer->timer_handshake_attempts = 0;
peer->sent_lastminute_handshake = false;
ktime_get_real_ts64(&peer->walltime_last_handshake);
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index 156f3650c006..96dc2778022a 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -733,7 +733,7 @@ static void ar5523_data_tx_pkt_put(struct ar5523 *ar)
{
atomic_dec(&ar->tx_nr_total);
if (!atomic_dec_return(&ar->tx_nr_pending)) {
- del_timer(&ar->tx_wd_timer);
+ timer_delete(&ar->tx_wd_timer);
wake_up(&ar->tx_flush_waitq);
}
@@ -1076,7 +1076,7 @@ static void ar5523_stop(struct ieee80211_hw *hw, bool suspend)
ar5523_cmd_write(ar, WDCMSG_TARGET_STOP, NULL, 0, 0);
- del_timer_sync(&ar->tx_wd_timer);
+ timer_delete_sync(&ar->tx_wd_timer);
cancel_work_sync(&ar->tx_wd_work);
cancel_work_sync(&ar->rx_refill_work);
ar5523_cancel_rx_bufs(ar);
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 35bfe7232e95..a0c1afeda4dd 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -1751,7 +1751,7 @@ void ath10k_debug_stop(struct ath10k *ar)
/* Must not use _sync to avoid deadlock, we do that in
* ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
- * warning from del_timer().
+ * warning from timer_delete().
*/
if (ar->debug.htt_stats_mask != 0)
cancel_delayed_work(&ar->debug.htt_stats_dwork);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 7d28ae5453cf..83eab7479f06 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -287,7 +287,7 @@ void ath10k_htt_rx_free(struct ath10k_htt *htt)
if (htt->ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
return;
- del_timer_sync(&htt->rx_ring.refill_retry_timer);
+ timer_delete_sync(&htt->rx_ring.refill_retry_timer);
skb_queue_purge(&htt->rx_msdus_q);
skb_queue_purge(&htt->rx_in_ord_compl_q);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index c52a16f8078f..fb2c60ee433c 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -619,7 +619,7 @@ static void ath10k_pci_sleep_sync(struct ath10k *ar)
return;
}
- del_timer_sync(&ar_pci->ps_timer);
+ timer_delete_sync(&ar_pci->ps_timer);
spin_lock_irqsave(&ar_pci->ps_lock, flags);
WARN_ON(ar_pci->ps_wake_refcount > 0);
@@ -1817,7 +1817,7 @@ static void ath10k_pci_rx_retry_sync(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- del_timer_sync(&ar_pci->rx_post_retry);
+ timer_delete_sync(&ar_pci->rx_post_retry);
}
int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id,
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
index 6805357ee29e..7ce74b4ef201 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.c
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -1621,7 +1621,7 @@ static void ath10k_sdio_hif_power_down(struct ath10k *ar)
ath10k_dbg(ar, ATH10K_DBG_BOOT, "sdio power off\n");
- del_timer_sync(&ar_sdio->sleep_timer);
+ timer_delete_sync(&ar_sdio->sleep_timer);
ath10k_sdio_set_mbox_sleep(ar, true);
/* Disable the card */
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
index d436a874cd5a..866bad2db334 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -911,7 +911,7 @@ static void ath10k_snoc_buffer_cleanup(struct ath10k *ar)
struct ath10k_snoc_pipe *pipe_info;
int pipe_num;
- del_timer_sync(&ar_snoc->rx_post_retry);
+ timer_delete_sync(&ar_snoc->rx_post_retry);
for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
pipe_info = &ar_snoc->pipe_info[pipe_num];
ath10k_snoc_rx_pipe_cleanup(pipe_info);
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index eedba3766ba2..2f862f8f10ca 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -397,7 +397,7 @@ static void ath11k_ahb_stop(struct ath11k_base *ab)
ath11k_ahb_ce_irqs_disable(ab);
ath11k_ahb_sync_ce_irqs(ab);
ath11k_ahb_kill_tasklets(ab);
- del_timer_sync(&ab->rx_replenish_retry);
+ timer_delete_sync(&ab->rx_replenish_retry);
ath11k_ce_cleanup_pipes(ab);
}
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index f124b7329e1a..3a544e5fefca 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -875,7 +875,7 @@ void ath11k_dp_pdev_free(struct ath11k_base *ab)
struct ath11k *ar;
int i;
- del_timer_sync(&ab->mon_reap_timer);
+ timer_delete_sync(&ab->mon_reap_timer);
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
@@ -1170,7 +1170,7 @@ void ath11k_dp_shadow_stop_timer(struct ath11k_base *ab,
if (!update_timer->init)
return;
- del_timer_sync(&update_timer->timer);
+ timer_delete_sync(&update_timer->timer);
}
void ath11k_dp_shadow_init_timer(struct ath11k_base *ab,
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index f2bdbac2a0b7..218ab41c0f3c 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -906,7 +906,7 @@ void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer)
rx_tid = &peer->rx_tid[i];
spin_unlock_bh(&ar->ab->base_lock);
- del_timer_sync(&rx_tid->frag_timer);
+ timer_delete_sync(&rx_tid->frag_timer);
spin_lock_bh(&ar->ab->base_lock);
ath11k_dp_rx_frags_cleanup(rx_tid, true);
@@ -927,7 +927,7 @@ void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer)
ath11k_dp_rx_frags_cleanup(rx_tid, true);
spin_unlock_bh(&ar->ab->base_lock);
- del_timer_sync(&rx_tid->frag_timer);
+ timer_delete_sync(&rx_tid->frag_timer);
spin_lock_bh(&ar->ab->base_lock);
}
}
@@ -3710,7 +3710,7 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
}
spin_unlock_bh(&ab->base_lock);
- del_timer_sync(&rx_tid->frag_timer);
+ timer_delete_sync(&rx_tid->frag_timer);
spin_lock_bh(&ab->base_lock);
peer = ath11k_peer_find_by_id(ab, peer_id);
@@ -5781,7 +5781,7 @@ int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer)
int ret;
if (stop_timer)
- del_timer_sync(&ab->mon_reap_timer);
+ timer_delete_sync(&ab->mon_reap_timer);
/* reap all the monitor related rings */
ret = ath11k_dp_purge_mon_ring(ab);
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index b1f27c3ac723..50c36e6ea102 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -985,7 +985,7 @@ void ath12k_dp_pdev_free(struct ath12k_base *ab)
if (!ab->mon_reap_timer.function)
return;
- del_timer_sync(&ab->mon_reap_timer);
+ timer_delete_sync(&ab->mon_reap_timer);
for (i = 0; i < ab->num_radios; i++)
ath12k_dp_rx_pdev_free(ab, i);
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index ff6a709b5042..75bf4211ad42 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -895,7 +895,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer)
ath12k_dp_rx_frags_cleanup(rx_tid, true);
spin_unlock_bh(&ar->ab->base_lock);
- del_timer_sync(&rx_tid->frag_timer);
+ timer_delete_sync(&rx_tid->frag_timer);
spin_lock_bh(&ar->ab->base_lock);
}
}
@@ -3451,7 +3451,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
}
spin_unlock_bh(&ab->base_lock);
- del_timer_sync(&rx_tid->frag_timer);
+ timer_delete_sync(&rx_tid->frag_timer);
spin_lock_bh(&ab->base_lock);
peer = ath12k_peer_find_by_id(ab, peer_id);
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 72ce321f2a77..8c2e8081112e 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -149,7 +149,7 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
return false;
- del_timer_sync(&vif->sched_scan_timer);
+ timer_delete_sync(&vif->sched_scan_timer);
if (ar->state == ATH6KL_STATE_RECOVERY)
return true;
@@ -1200,7 +1200,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
if (((vif->auth_mode == WPA_PSK_AUTH) ||
(vif->auth_mode == WPA2_PSK_AUTH)) &&
(key_usage & GROUP_USAGE))
- del_timer(&vif->disconnect_timer);
+ timer_delete(&vif->disconnect_timer);
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
@@ -3612,7 +3612,7 @@ void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
discon_issued = test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags);
ath6kl_disconnect(vif);
- del_timer(&vif->disconnect_timer);
+ timer_delete(&vif->disconnect_timer);
if (discon_issued)
ath6kl_disconnect_event(vif, DISCONNECT_CMD,
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 15f455adb860..9b100ee2ebc3 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1915,7 +1915,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
clear_bit(WMI_READY, &ar->flag);
if (ar->fw_recovery.enable)
- del_timer_sync(&ar->fw_recovery.hb_timer);
+ timer_delete_sync(&ar->fw_recovery.hb_timer);
/*
* After wmi_shudown all WMI events will be dropped. We
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 8f9fe23e9755..867089a3c096 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1027,7 +1027,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
aggr_reset_state(vif->aggr_cntxt->aggr_conn);
- del_timer(&vif->disconnect_timer);
+ timer_delete(&vif->disconnect_timer);
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "disconnect reason is %d\n", reason);
diff --git a/drivers/net/wireless/ath/ath6kl/recovery.c b/drivers/net/wireless/ath/ath6kl/recovery.c
index c09e40c9010f..fd2dceb8b63d 100644
--- a/drivers/net/wireless/ath/ath6kl/recovery.c
+++ b/drivers/net/wireless/ath/ath6kl/recovery.c
@@ -25,7 +25,7 @@ static void ath6kl_recovery_work(struct work_struct *work)
ar->state = ATH6KL_STATE_RECOVERY;
- del_timer_sync(&ar->fw_recovery.hb_timer);
+ timer_delete_sync(&ar->fw_recovery.hb_timer);
ath6kl_init_hw_restart(ar);
@@ -119,7 +119,7 @@ void ath6kl_recovery_cleanup(struct ath6kl *ar)
set_bit(RECOVERY_CLEANUP, &ar->flag);
- del_timer_sync(&ar->fw_recovery.hb_timer);
+ timer_delete_sync(&ar->fw_recovery.hb_timer);
cancel_work_sync(&ar->fw_recovery.recovery_work);
}
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 80e66acc5cf6..3a6f0b647e17 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1827,7 +1827,7 @@ void aggr_reset_state(struct aggr_info_conn *aggr_conn)
return;
if (aggr_conn->timer_scheduled) {
- del_timer(&aggr_conn->timer);
+ timer_delete(&aggr_conn->timer);
aggr_conn->timer_scheduled = false;
}
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index bae24e3d3168..799be0be24f4 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1556,7 +1556,7 @@ void ath9k_p2p_ps_timer(void *priv)
struct ath_node *an;
u32 tsf;
- del_timer_sync(&sc->sched.timer);
+ timer_delete_sync(&sc->sched.timer);
ath9k_hw_gen_timer_stop(sc->sc_ah, sc->p2p_ps_timer);
ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index b457e52dd365..5a26f1d05f04 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -305,7 +305,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
/* make sure duty cycle timer is also stopped when resuming */
- del_timer_sync(&btcoex->no_stomp_timer);
+ timer_delete_sync(&btcoex->no_stomp_timer);
btcoex->bt_priority_cnt = 0;
btcoex->bt_priority_time = jiffies;
@@ -329,15 +329,15 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
ath_dbg(ath9k_hw_common(ah), BTCOEX, "Stopping btcoex timers\n");
- del_timer_sync(&btcoex->period_timer);
- del_timer_sync(&btcoex->no_stomp_timer);
+ timer_delete_sync(&btcoex->period_timer);
+ timer_delete_sync(&btcoex->no_stomp_timer);
}
void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
{
struct ath_btcoex *btcoex = &sc->btcoex;
- del_timer_sync(&btcoex->no_stomp_timer);
+ timer_delete_sync(&btcoex->no_stomp_timer);
}
u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 57094bd45d98..19600018e562 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -198,7 +198,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
ath9k_htc_stop_ani(priv);
ieee80211_stop_queues(priv->hw);
- del_timer_sync(&priv->tx.cleanup_timer);
+ timer_delete_sync(&priv->tx.cleanup_timer);
ath9k_htc_tx_drain(priv);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -260,7 +260,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
ath9k_htc_ps_wakeup(priv);
ath9k_htc_stop_ani(priv);
- del_timer_sync(&priv->tx.cleanup_timer);
+ timer_delete_sync(&priv->tx.cleanup_timer);
ath9k_htc_tx_drain(priv);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -997,7 +997,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw, bool suspend)
tasklet_kill(&priv->rx_tasklet);
- del_timer_sync(&priv->tx.cleanup_timer);
+ timer_delete_sync(&priv->tx.cleanup_timer);
ath9k_htc_tx_drain(priv);
ath9k_wmi_event_drain(priv);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 01e0dffbf57e..ee951493e993 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1099,7 +1099,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
- del_timer_sync(&sc->sleep_timer);
+ timer_delete_sync(&sc->sleep_timer);
ath9k_hw_deinit(sc->sc_ah);
if (sc->dfs_detector != NULL)
sc->dfs_detector->exit(sc->dfs_detector);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index d078a59d7d3c..7f890997bb53 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -472,7 +472,7 @@ void ath_stop_ani(struct ath_softc *sc)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
ath_dbg(common, ANI, "Stopping ANI\n");
- del_timer_sync(&common->ani.timer);
+ timer_delete_sync(&common->ani.timer);
}
void ath_check_ani(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a70c94564814..92fc5e3d756e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -123,7 +123,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
if (++sc->ps_usecount != 1)
goto unlock;
- del_timer_sync(&sc->sleep_timer);
+ timer_delete_sync(&sc->sleep_timer);
power_mode = sc->sc_ah->power_mode;
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
@@ -2418,7 +2418,7 @@ static void ath9k_cancel_pending_offchannel(struct ath_softc *sc)
ath_dbg(common, CHAN_CTX,
"%s: Aborting RoC\n", __func__);
- del_timer_sync(&sc->offchannel.timer);
+ timer_delete_sync(&sc->offchannel.timer);
if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
ath_roc_complete(sc, ATH_ROC_COMPLETE_ABORT);
}
@@ -2427,7 +2427,7 @@ static void ath9k_cancel_pending_offchannel(struct ath_softc *sc)
ath_dbg(common, CHAN_CTX,
"%s: Aborting HW scan\n", __func__);
- del_timer_sync(&sc->offchannel.timer);
+ timer_delete_sync(&sc->offchannel.timer);
ath_scan_complete(sc, true);
}
}
@@ -2476,7 +2476,7 @@ static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw,
ath_dbg(common, CHAN_CTX, "Cancel HW scan on vif: %pM\n", vif->addr);
mutex_lock(&sc->mutex);
- del_timer_sync(&sc->offchannel.timer);
+ timer_delete_sync(&sc->offchannel.timer);
ath_scan_complete(sc, true);
mutex_unlock(&sc->mutex);
}
@@ -2526,7 +2526,7 @@ static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
ath_dbg(common, CHAN_CTX, "Cancel RoC\n");
- del_timer_sync(&sc->offchannel.timer);
+ timer_delete_sync(&sc->offchannel.timer);
if (sc->offchannel.roc_vif) {
if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 1ff53520f0a3..27d4034c814e 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -1029,7 +1029,7 @@ static int ath_pci_suspend(struct device *device)
*/
ath9k_stop_btcoex(sc);
ath9k_hw_disable(sc->sc_ah);
- del_timer_sync(&sc->sleep_timer);
+ timer_delete_sync(&sc->sleep_timer);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
return 0;
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index d405a4c34059..cc2a033e87f5 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -350,7 +350,7 @@ void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status)
spin_lock_irqsave(&wcn->dxe_lock, flags);
skb = wcn->tx_ack_skb;
wcn->tx_ack_skb = NULL;
- del_timer(&wcn->tx_ack_timer);
+ timer_delete(&wcn->tx_ack_timer);
spin_unlock_irqrestore(&wcn->dxe_lock, flags);
if (!skb) {
@@ -1055,7 +1055,7 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn)
free_irq(wcn->tx_irq, wcn);
free_irq(wcn->rx_irq, wcn);
- del_timer(&wcn->tx_ack_timer);
+ timer_delete(&wcn->tx_ack_timer);
if (wcn->tx_ack_skb) {
ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb);
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index a1a0a9223e74..5473c01cbe66 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1017,7 +1017,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
out_restore:
if (rc) {
- del_timer_sync(&vif->scan_timer);
+ timer_delete_sync(&vif->scan_timer);
if (vif->mid == 0)
wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
vif->scan_request = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 94e61dbe94f8..44c24c6c8360 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -798,7 +798,7 @@ void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
wil_dbg_misc(wil, "disconnecting\n");
- del_timer_sync(&vif->connect_timer);
+ timer_delete_sync(&vif->connect_timer);
_wil6210_disconnect(vif, bssid, reason_code);
}
@@ -818,7 +818,7 @@ void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid,
wil_dbg_misc(wil, "got disconnect\n");
- del_timer_sync(&vif->connect_timer);
+ timer_delete_sync(&vif->connect_timer);
_wil6210_disconnect_complete(vif, bssid, reason_code);
}
@@ -1465,7 +1465,7 @@ void wil_abort_scan(struct wil6210_vif *vif, bool sync)
return;
wil_dbg_misc(wil, "Abort scan_request 0x%p\n", vif->scan_request);
- del_timer_sync(&vif->scan_timer);
+ timer_delete_sync(&vif->scan_timer);
mutex_unlock(&wil->vif_mutex);
rc = wmi_abort_scan(vif);
if (!rc && sync)
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index d5d364683c0e..59884e8e3765 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -200,8 +200,8 @@ static void wil_dev_setup(struct net_device *dev)
static void wil_vif_deinit(struct wil6210_vif *vif)
{
- del_timer_sync(&vif->scan_timer);
- del_timer_sync(&vif->p2p.discovery_timer);
+ timer_delete_sync(&vif->scan_timer);
+ timer_delete_sync(&vif->p2p.discovery_timer);
cancel_work_sync(&vif->disconnect_worker);
cancel_work_sync(&vif->p2p.discovery_expired_work);
cancel_work_sync(&vif->p2p.delayed_listen_work);
@@ -533,7 +533,7 @@ void wil_vif_remove(struct wil6210_priv *wil, u8 mid)
mutex_unlock(&wil->vif_mutex);
flush_work(&wil->wmi_event_worker);
- del_timer_sync(&vif->connect_timer);
+ timer_delete_sync(&vif->connect_timer);
cancel_work_sync(&vif->disconnect_worker);
wil_probe_client_flush(vif);
cancel_work_sync(&vif->probe_client_worker);
diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c
index f26bf046d889..f20caf1a3905 100644
--- a/drivers/net/wireless/ath/wil6210/p2p.c
+++ b/drivers/net/wireless/ath/wil6210/p2p.c
@@ -184,7 +184,7 @@ u8 wil_p2p_stop_discovery(struct wil6210_vif *vif)
/* discovery not really started, only pending */
p2p->pending_listen_wdev = NULL;
} else {
- del_timer_sync(&p2p->discovery_timer);
+ timer_delete_sync(&p2p->discovery_timer);
wmi_stop_discovery(vif);
}
p2p->discovery_started = 0;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 8ff69dc72fb9..74edd007cd8d 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -933,7 +933,7 @@ static void wmi_evt_scan_complete(struct wil6210_vif *vif, int id,
wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status);
wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
vif->scan_request, info.aborted);
- del_timer_sync(&vif->scan_timer);
+ timer_delete_sync(&vif->scan_timer);
cfg80211_scan_done(vif->scan_request, &info);
if (vif->mid == 0)
wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
@@ -1023,7 +1023,7 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len)
mutex_unlock(&wil->mutex);
return;
}
- del_timer_sync(&vif->connect_timer);
+ timer_delete_sync(&vif->connect_timer);
} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
(wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
if (wil->sta[evt->cid].status != wil_sta_unused) {
@@ -1814,7 +1814,7 @@ wmi_evt_reassoc_status(struct wil6210_vif *vif, int id, void *d, int len)
wil->sta[cid].stats.ft_roams++;
ether_addr_copy(wil->sta[cid].addr, vif->bss->bssid);
mutex_unlock(&wil->mutex);
- del_timer_sync(&vif->connect_timer);
+ timer_delete_sync(&vif->connect_timer);
cfg80211_ref_bss(wiphy, vif->bss);
freq = ieee80211_channel_to_frequency(ch, NL80211_BAND_60GHZ);
diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c
index 504e05ea30f2..4f01189b7c4b 100644
--- a/drivers/net/wireless/atmel/at76c50x-usb.c
+++ b/drivers/net/wireless/atmel/at76c50x-usb.c
@@ -2417,7 +2417,7 @@ static void at76_delete_device(struct at76_priv *priv)
kfree(priv->bulk_out_buffer);
- del_timer_sync(&ledtrig_tx_timer);
+ timer_delete_sync(&ledtrig_tx_timer);
kfree_skb(priv->rx_skb);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
index 1e8495f50c16..e0de34a3e43a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
@@ -289,7 +289,7 @@ static void brcmf_btcoex_handler(struct work_struct *work)
btci = container_of(work, struct brcmf_btcoex_info, work);
if (btci->timer_on) {
btci->timer_on = false;
- del_timer_sync(&btci->timer);
+ timer_delete_sync(&btci->timer);
}
switch (btci->bt_state) {
@@ -428,7 +428,7 @@ static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci)
if (btci->timer_on) {
brcmf_dbg(INFO, "disable BT DHCP Timer\n");
btci->timer_on = false;
- del_timer_sync(&btci->timer);
+ timer_delete_sync(&btci->timer);
/* schedule worker if transition to IDLE is needed */
if (btci->bt_state != BRCMF_BT_DHCP_IDLE) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index d2caa80e9412..9f1854b3d1a5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2304,7 +2304,7 @@ brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
{
if (!active) {
if (devinfo->console_active) {
- del_timer_sync(&devinfo->timer);
+ timer_delete_sync(&devinfo->timer);
devinfo->console_active = false;
}
return;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b1727f35217b..93727b9a5f0d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4611,7 +4611,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, bool active)
{
/* Totally stop the timer */
if (!active && bus->wd_active) {
- del_timer_sync(&bus->timer);
+ timer_delete_sync(&bus->timer);
bus->wd_active = false;
return;
}
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
index 32639e0e8430..dfcc12aa8620 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c
@@ -59,7 +59,7 @@ void libipw_crypt_info_free(struct libipw_crypt_info *info)
int i;
libipw_crypt_quiescing(info);
- del_timer_sync(&info->crypt_deinit_timer);
+ timer_delete_sync(&info->crypt_deinit_timer);
libipw_crypt_deinit_entries(info, 1);
for (i = 0; i < NUM_WEP_KEYS; i++) {
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index 4013443698a2..104748fcdc33 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -2188,7 +2188,7 @@ __il3945_down(struct il_priv *il)
/* Stop TX queues watchdog. We need to have S_EXIT_PENDING bit set
* to prevent rearm timer */
- del_timer_sync(&il->watchdog);
+ timer_delete_sync(&il->watchdog);
/* Station information will now be cleared in device */
il_clear_ucode_stations(il);
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-rs.c b/drivers/net/wireless/intel/iwlegacy/3945-rs.c
index 0eaad980c85c..df1b8ec86651 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-rs.c
@@ -413,7 +413,7 @@ il3945_rs_free_sta(void *il_priv, struct ieee80211_sta *sta, void *il_sta)
* to use il_priv to print out debugging) since it may not be fully
* initialized at this point.
*/
- del_timer_sync(&rs_sta->rate_scale_flush);
+ timer_delete_sync(&rs_sta->rate_scale_flush);
}
/*
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index 05c4af41bdb9..dc8c408902e6 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -5350,7 +5350,7 @@ __il4965_down(struct il_priv *il)
/* Stop TX queues watchdog. We need to have S_EXIT_PENDING bit set
* to prevent rearm timer */
- del_timer_sync(&il->watchdog);
+ timer_delete_sync(&il->watchdog);
il_clear_ucode_stations(il);
@@ -6243,7 +6243,7 @@ il4965_cancel_deferred_work(struct il_priv *il)
il_cancel_scan_deferred_work(il);
- del_timer_sync(&il->stats_periodic);
+ timer_delete_sync(&il->stats_periodic);
}
static void
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index af4f42534ea0..09fb4b758704 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -4842,7 +4842,7 @@ il_setup_watchdog(struct il_priv *il)
mod_timer(&il->watchdog,
jiffies + msecs_to_jiffies(IL_WD_TICK(timeout)));
else
- del_timer(&il->watchdog);
+ timer_delete(&il->watchdog);
}
EXPORT_SYMBOL(il_setup_watchdog);
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
index b246dbd371b3..2ed4b6e798ab 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
@@ -1870,7 +1870,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
}
} else {
priv->event_log.ucode_trace = false;
- del_timer_sync(&priv->ucode_trace);
+ timer_delete_sync(&priv->ucode_trace);
}
return count;
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index 30789ba06d9d..a27a72cc017a 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1082,8 +1082,8 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv)
cancel_work_sync(&priv->bt_full_concurrency);
cancel_work_sync(&priv->bt_runtime_config);
- del_timer_sync(&priv->statistics_periodic);
- del_timer_sync(&priv->ucode_trace);
+ timer_delete_sync(&priv->statistics_periodic);
+ timer_delete_sync(&priv->ucode_trace);
}
static int iwl_init_drv(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
index e1d78550e443..98f0949b3683 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
@@ -257,7 +257,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
tt->tt_previous_temp = temp;
#endif
/* stop ct_kill_waiting_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ timer_delete_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
if (tt->state != old_state) {
switch (tt->state) {
case IWL_TI_0:
@@ -378,7 +378,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
}
}
/* stop ct_kill_waiting_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ timer_delete_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
if (changed) {
if (tt->state >= IWL_TI_1) {
/* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
@@ -506,7 +506,7 @@ static void iwl_bg_ct_exit(struct work_struct *work)
return;
/* stop ct_kill_exit_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+ timer_delete_sync(&priv->thermal_throttle.ct_kill_exit_tm);
if (tt->state == IWL_TI_CT_KILL) {
IWL_ERR(priv,
@@ -640,9 +640,9 @@ void iwl_tt_exit(struct iwl_priv *priv)
struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
/* stop ct_kill_exit_tm timer if activated */
- del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+ timer_delete_sync(&priv->thermal_throttle.ct_kill_exit_tm);
/* stop ct_kill_waiting_tm timer if activated */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ timer_delete_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
cancel_work_sync(&priv->tt_work);
cancel_work_sync(&priv->ct_enter);
cancel_work_sync(&priv->ct_exit);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 4a442d03d8d2..4a4f8de4efe2 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1697,7 +1697,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
if (!trans_pcie->txqs.txq[i])
continue;
- del_timer(&trans_pcie->txqs.txq[i]->stuck_timer);
+ timer_delete(&trans_pcie->txqs.txq[i]->stuck_timer);
}
/* The STATUS_FW_ERROR bit is set in this function. This must happen
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 401919f9fe88..71227fd3dac0 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -911,7 +911,7 @@ static void iwl_txq_gen2_free(struct iwl_trans *trans, int txq_id)
kfree_sensitive(txq->entries[i].cmd);
kfree_sensitive(txq->entries[i].free_buf);
}
- del_timer_sync(&txq->stuck_timer);
+ timer_delete_sync(&txq->stuck_timer);
iwl_txq_gen2_free_memory(trans, txq);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 7c1dd5cc084a..bb90bcfc6763 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -469,7 +469,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
kfree(txq->entries);
txq->entries = NULL;
- del_timer_sync(&txq->stuck_timer);
+ timer_delete_sync(&txq->stuck_timer);
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
@@ -1054,7 +1054,7 @@ static void iwl_txq_progress(struct iwl_txq *txq)
* since we're making progress on this queue
*/
if (txq->read_ptr == txq->write_ptr)
- del_timer(&txq->stuck_timer);
+ timer_delete(&txq->stuck_timer);
else
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
}
@@ -2529,7 +2529,7 @@ void iwl_pcie_freeze_txq_timer(struct iwl_trans *trans,
/* remember how long until the timer fires */
txq->frozen_expiry_remainder =
txq->stuck_timer.expires - now;
- del_timer(&txq->stuck_timer);
+ timer_delete(&txq->stuck_timer);
goto next_queue;
}
diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/marvell/libertas/cmdresp.c
index 8393f396eebe..9742d3dba31c 100644
--- a/drivers/net/wireless/marvell/libertas/cmdresp.c
+++ b/drivers/net/wireless/marvell/libertas/cmdresp.c
@@ -119,7 +119,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
}
/* Now we got response from FW, cancel the command timer */
- del_timer(&priv->command_timer);
+ timer_delete(&priv->command_timer);
priv->cmd_timed_out = 0;
if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c
index 2240b4db8c03..ea3cc2eaec36 100644
--- a/drivers/net/wireless/marvell/libertas/if_usb.c
+++ b/drivers/net/wireless/marvell/libertas/if_usb.c
@@ -897,7 +897,7 @@ restart:
/* ... and wait for the process to complete */
wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
- del_timer_sync(&cardp->fw_timeout);
+ timer_delete_sync(&cardp->fw_timeout);
usb_kill_urb(cardp->rx_urb);
if (!cardp->fwdnldover) {
diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c
index 017e5c6bbade..26d13e9b3c95 100644
--- a/drivers/net/wireless/marvell/libertas/main.c
+++ b/drivers/net/wireless/marvell/libertas/main.c
@@ -202,7 +202,7 @@ int lbs_stop_iface(struct lbs_private *priv)
spin_unlock_irqrestore(&priv->driver_lock, flags);
cancel_work_sync(&priv->mcast_work);
- del_timer_sync(&priv->tx_lockup_timer);
+ timer_delete_sync(&priv->tx_lockup_timer);
/* Disable command processing, and wait for all commands to complete */
lbs_deb_main("waiting for commands to complete\n");
@@ -250,7 +250,7 @@ void lbs_host_to_card_done(struct lbs_private *priv)
unsigned long flags;
spin_lock_irqsave(&priv->driver_lock, flags);
- del_timer(&priv->tx_lockup_timer);
+ timer_delete(&priv->tx_lockup_timer);
priv->dnld_sent = DNLD_RES_RECEIVED;
@@ -594,8 +594,8 @@ static int lbs_thread(void *data)
spin_unlock_irq(&priv->driver_lock);
}
- del_timer(&priv->command_timer);
- del_timer(&priv->tx_lockup_timer);
+ timer_delete(&priv->command_timer);
+ timer_delete(&priv->tx_lockup_timer);
return 0;
}
@@ -798,8 +798,8 @@ static void lbs_free_adapter(struct lbs_private *priv)
{
lbs_free_cmd_buffer(priv);
kfifo_free(&priv->event_fifo);
- del_timer(&priv->command_timer);
- del_timer(&priv->tx_lockup_timer);
+ timer_delete(&priv->command_timer);
+ timer_delete(&priv->tx_lockup_timer);
}
static const struct net_device_ops lbs_netdev_ops = {
diff --git a/drivers/net/wireless/marvell/libertas_tf/cmd.c b/drivers/net/wireless/marvell/libertas_tf/cmd.c
index efb98304555a..7fc1bdb6c458 100644
--- a/drivers/net/wireless/marvell/libertas_tf/cmd.c
+++ b/drivers/net/wireless/marvell/libertas_tf/cmd.c
@@ -757,7 +757,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
}
/* Now we got response from FW, cancel the command timer */
- del_timer(&priv->command_timer);
+ timer_delete(&priv->command_timer);
priv->cmd_timed_out = 0;
if (priv->nr_retries)
priv->nr_retries = 0;
diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
index 1750f5e93de2..7c413dc81f9a 100644
--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
@@ -875,7 +875,7 @@ restart:
wait_event_interruptible(cardp->fw_wq, cardp->priv->surpriseremoved ||
cardp->fwdnldover);
- del_timer_sync(&cardp->fw_timeout);
+ timer_delete_sync(&cardp->fw_timeout);
usb_kill_urb(cardp->rx_urb);
if (!cardp->fwdnldover) {
diff --git a/drivers/net/wireless/marvell/libertas_tf/main.c b/drivers/net/wireless/marvell/libertas_tf/main.c
index b47a832b9ae2..a57a11be57d8 100644
--- a/drivers/net/wireless/marvell/libertas_tf/main.c
+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
@@ -174,7 +174,7 @@ static void lbtf_free_adapter(struct lbtf_private *priv)
{
lbtf_deb_enter(LBTF_DEB_MAIN);
lbtf_free_cmd_buffer(priv);
- del_timer(&priv->command_timer);
+ timer_delete(&priv->command_timer);
lbtf_deb_leave(LBTF_DEB_MAIN);
}
@@ -642,7 +642,7 @@ int lbtf_remove_card(struct lbtf_private *priv)
lbtf_deb_enter(LBTF_DEB_MAIN);
priv->surpriseremoved = 1;
- del_timer(&priv->command_timer);
+ timer_delete(&priv->command_timer);
lbtf_free_adapter(priv);
priv->hw = NULL;
ieee80211_unregister_hw(hw);
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index cb948ca34373..8aff1df09b40 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -206,7 +206,7 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1);
mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);
- del_timer_sync(&tbl->timer_context.timer);
+ timer_delete_sync(&tbl->timer_context.timer);
tbl->timer_context.timer_is_set = false;
spin_lock_bh(&priv->rx_reorder_tbl_lock);
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index b30ed321c625..5573e2ded72f 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -836,7 +836,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
return -1;
}
/* Now we got response from FW, cancel the command timer */
- del_timer_sync(&adapter->cmd_timer);
+ timer_delete_sync(&adapter->cmd_timer);
clear_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags);
if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
index 8b61e45cd667..ce0d42e72e94 100644
--- a/drivers/net/wireless/marvell/mwifiex/init.c
+++ b/drivers/net/wireless/marvell/mwifiex/init.c
@@ -390,7 +390,7 @@ static void mwifiex_invalidate_lists(struct mwifiex_adapter *adapter)
static void
mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
{
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
cancel_delayed_work_sync(&adapter->devdump_work);
mwifiex_cancel_all_pending_cmd(adapter);
wake_up_interruptible(&adapter->cmd_wait_q.wait);
@@ -613,7 +613,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
if (adapter->curr_cmd) {
mwifiex_dbg(adapter, WARN,
"curr_cmd is still in processing\n");
- del_timer_sync(&adapter->cmd_timer);
+ timer_delete_sync(&adapter->cmd_timer);
mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
adapter->curr_cmd = NULL;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index b07cb302a00c..0e1f53940401 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -307,7 +307,7 @@ process_start:
if (IS_CARD_RX_RCVD(adapter)) {
adapter->data_received = false;
adapter->pm_wakeup_fw_try = false;
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
if (adapter->ps_state == PS_STATE_SLEEP)
adapter->ps_state = PS_STATE_AWAKE;
} else {
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index e11458fd4d50..dd2a42e732f2 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2437,7 +2437,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter,
*/
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_fw_try = false;
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
}
spin_lock_irqsave(&adapter->int_lock, flags);
@@ -2527,7 +2527,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
adapter->ps_state == PS_STATE_SLEEP) {
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_fw_try = false;
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
}
}
}
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index 400348abeee5..fecd88967ceb 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -789,7 +789,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
break;
}
if (!mwifiex_send_null_packet
@@ -804,7 +804,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
break;
diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
index 0a5f340876c3..18e8c04d14c4 100644
--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -1490,7 +1490,7 @@ void mwifiex_clean_auto_tdls(struct mwifiex_private *priv)
priv->adapter->auto_tdls &&
priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
priv->auto_tdls_timer_active = false;
- del_timer(&priv->auto_tdls_timer);
+ timer_delete(&priv->auto_tdls_timer);
mwifiex_flush_auto_tdls_list(priv);
}
}
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c
index 3034c4405cb5..2f565397cf36 100644
--- a/drivers/net/wireless/marvell/mwifiex/usb.c
+++ b/drivers/net/wireless/marvell/mwifiex/usb.c
@@ -877,7 +877,7 @@ static int mwifiex_usb_prepare_tx_aggr_skb(struct mwifiex_adapter *adapter,
* write complete, delete the tx_aggr timer
*/
if (port->tx_aggr.timer_cnxt.is_hold_timer_set) {
- del_timer(&port->tx_aggr.timer_cnxt.hold_timer);
+ timer_delete(&port->tx_aggr.timer_cnxt.hold_timer);
port->tx_aggr.timer_cnxt.is_hold_timer_set = false;
port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;
}
@@ -1354,7 +1354,7 @@ static void mwifiex_usb_cleanup_tx_aggr(struct mwifiex_adapter *adapter)
mwifiex_write_data_complete(adapter, skb_tmp,
0, -1);
if (port->tx_aggr.timer_cnxt.hold_timer.function)
- del_timer_sync(&port->tx_aggr.timer_cnxt.hold_timer);
+ timer_delete_sync(&port->tx_aggr.timer_cnxt.hold_timer);
port->tx_aggr.timer_cnxt.is_hold_timer_set = false;
port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;
}
@@ -1557,7 +1557,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
{
/* Simulation of HS_AWAKE event */
adapter->pm_wakeup_fw_try = false;
- del_timer(&adapter->wakeup_timer);
+ timer_delete(&adapter->wakeup_timer);
adapter->pm_wakeup_card_req = false;
adapter->ps_state = PS_STATE_AWAKE;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 2e7b05eeef7a..c54005df08ca 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -97,7 +97,7 @@ static void mt7615_stop(struct ieee80211_hw *hw, bool suspend)
struct mt7615_phy *phy = mt7615_hw_phy(hw);
cancel_delayed_work_sync(&phy->mt76->mac_work);
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
cancel_delayed_work_sync(&dev->pm.ps_work);
@@ -1194,7 +1194,7 @@ static int mt7615_cancel_remain_on_channel(struct ieee80211_hw *hw,
if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
return 0;
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
mt7615_mutex_acquire(phy->dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
index c2e4e6aabd9f..b795d11d943d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
@@ -220,12 +220,12 @@ void mt7615_mac_reset_work(struct work_struct *work)
set_bit(MT76_MCU_RESET, &dev->mphy.state);
wake_up(&dev->mt76.mcu.wait);
cancel_delayed_work_sync(&dev->mphy.mac_work);
- del_timer_sync(&dev->phy.roc_timer);
+ timer_delete_sync(&dev->phy.roc_timer);
cancel_work_sync(&dev->phy.roc_work);
if (phy2) {
set_bit(MT76_RESET, &phy2->mt76->state);
cancel_delayed_work_sync(&phy2->mt76->mac_work);
- del_timer_sync(&phy2->roc_timer);
+ timer_delete_sync(&phy2->roc_timer);
cancel_work_sync(&phy2->roc_work);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
index 4aa9fa1c4a23..d96e06b4fee1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c
@@ -85,7 +85,7 @@ static void mt7663u_stop(struct ieee80211_hw *hw, bool suspend)
struct mt7615_dev *dev = hw->priv;
clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
cancel_delayed_work_sync(&phy->scan_work);
cancel_delayed_work_sync(&phy->mt76->mac_work);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 78b77a54d195..826c48a2ee69 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -364,7 +364,7 @@ void mt7921_roc_abort_sync(struct mt792x_dev *dev)
{
struct mt792x_phy *phy = &dev->phy;
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
ieee80211_iterate_interfaces(mt76_hw(dev),
@@ -395,7 +395,7 @@ static int mt7921_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif)
{
int err = 0;
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
mt792x_mutex_acquire(phy->dev);
@@ -1476,7 +1476,7 @@ static void mt7921_abort_channel_switch(struct ieee80211_hw *hw,
{
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
- del_timer_sync(&mvif->csa_timer);
+ timer_delete_sync(&mvif->csa_timer);
cancel_work_sync(&mvif->csa_work);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index e79364ac129e..66f327781947 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -453,7 +453,7 @@ void mt7925_roc_abort_sync(struct mt792x_dev *dev)
{
struct mt792x_phy *phy = &dev->phy;
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
ieee80211_iterate_interfaces(mt76_hw(dev),
@@ -485,7 +485,7 @@ static int mt7925_abort_roc(struct mt792x_phy *phy,
{
int err = 0;
- del_timer_sync(&phy->roc_timer);
+ timer_delete_sync(&phy->roc_timer);
cancel_work_sync(&phy->roc_work);
mt792x_mutex_acquire(phy->dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
index 0f7806f6338d..38dd58f6e493 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
@@ -340,7 +340,7 @@ void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw,
mutex_unlock(&dev->mt76.mutex);
if (vif->bss_conf.csa_active) {
- del_timer_sync(&mvif->csa_timer);
+ timer_delete_sync(&mvif->csa_timer);
cancel_work_sync(&mvif->csa_work);
}
}
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
index bba53307b960..cb46a39ef757 100644
--- a/drivers/net/wireless/microchip/wilc1000/hif.c
+++ b/drivers/net/wireless/microchip/wilc1000/hif.c
@@ -643,7 +643,7 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
}
}
- del_timer(&hif_drv->connect_timer);
+ timer_delete(&hif_drv->connect_timer);
conn_info->conn_result(CONN_DISCONN_EVENT_CONN_RESP, mac_status,
hif_drv->conn_info.priv);
@@ -669,7 +669,7 @@ void wilc_handle_disconnect(struct wilc_vif *vif)
struct host_if_drv *hif_drv = vif->hif_drv;
if (hif_drv->usr_scan_req.scan_result) {
- del_timer(&hif_drv->scan_timer);
+ timer_delete(&hif_drv->scan_timer);
handle_scan_done(vif, SCAN_EVENT_ABORTED);
}
@@ -713,7 +713,7 @@ static void handle_rcvd_gnrl_async_info(struct work_struct *work)
if (hif_drv->hif_state == HOST_IF_CONNECTED) {
wilc_handle_disconnect(vif);
} else if (hif_drv->usr_scan_req.scan_result) {
- del_timer(&hif_drv->scan_timer);
+ timer_delete(&hif_drv->scan_timer);
handle_scan_done(vif, SCAN_EVENT_ABORTED);
}
}
@@ -746,7 +746,7 @@ int wilc_disconnect(struct wilc_vif *vif)
conn_info = &hif_drv->conn_info;
if (scan_req->scan_result) {
- del_timer(&hif_drv->scan_timer);
+ timer_delete(&hif_drv->scan_timer);
scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->priv);
scan_req->scan_result = NULL;
}
@@ -754,7 +754,7 @@ int wilc_disconnect(struct wilc_vif *vif)
if (conn_info->conn_result) {
if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
hif_drv->hif_state == HOST_IF_EXTERNAL_AUTH)
- del_timer(&hif_drv->connect_timer);
+ timer_delete(&hif_drv->connect_timer);
conn_info->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0,
conn_info->priv);
@@ -959,7 +959,7 @@ static void listen_timer_cb(struct timer_list *t)
int result;
struct host_if_msg *msg;
- del_timer(&vif->hif_drv->remain_on_ch_timer);
+ timer_delete(&vif->hif_drv->remain_on_ch_timer);
msg = wilc_alloc_work(vif, wilc_handle_listen_state_expired, false);
if (IS_ERR(msg))
@@ -1066,7 +1066,7 @@ static void handle_scan_complete(struct work_struct *work)
{
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
- del_timer(&msg->vif->hif_drv->scan_timer);
+ timer_delete(&msg->vif->hif_drv->scan_timer);
handle_scan_done(msg->vif, SCAN_EVENT_DONE);
@@ -1551,7 +1551,7 @@ int wilc_deinit(struct wilc_vif *vif)
timer_shutdown_sync(&hif_drv->scan_timer);
timer_shutdown_sync(&hif_drv->connect_timer);
- del_timer_sync(&vif->periodic_rssi);
+ timer_delete_sync(&vif->periodic_rssi);
timer_shutdown_sync(&hif_drv->remain_on_ch_timer);
if (hif_drv->usr_scan_req.scan_result) {
@@ -1718,7 +1718,7 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
return -EFAULT;
}
- del_timer(&vif->hif_drv->remain_on_ch_timer);
+ timer_delete(&vif->hif_drv->remain_on_ch_timer);
return wilc_handle_roc_expired(vif, cookie);
}
diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c
index 56d1139ba8bc..10d2e2124ff8 100644
--- a/drivers/net/wireless/purelifi/plfxlc/usb.c
+++ b/drivers/net/wireless/purelifi/plfxlc/usb.c
@@ -714,8 +714,8 @@ static void disconnect(struct usb_interface *intf)
mac = plfxlc_hw_mac(hw);
usb = &mac->chip.usb;
- del_timer_sync(&usb->tx.tx_retry_timer);
- del_timer_sync(&usb->sta_queue_cleanup);
+ timer_delete_sync(&usb->tx.tx_retry_timer);
+ timer_delete_sync(&usb->sta_queue_cleanup);
ieee80211_unregister_hw(hw);
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index ff61867d142f..6189edc1d8d7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -473,7 +473,7 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw, bool ips_wq)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
- del_timer_sync(&rtlpriv->works.watchdog_timer);
+ timer_delete_sync(&rtlpriv->works.watchdog_timer);
cancel_delayed_work_sync(&rtlpriv->works.watchdog_wq);
if (ips_wq)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
index 35875cda30fc..2ad4523d1bef 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
@@ -179,9 +179,9 @@ static void rtl88e_deinit_sw_vars(struct ieee80211_hw *hw)
}
if (rtlpriv->psc.low_power_enable)
- del_timer_sync(&rtlpriv->works.fw_clockoff_timer);
+ timer_delete_sync(&rtlpriv->works.fw_clockoff_timer);
- del_timer_sync(&rtlpriv->works.fast_antenna_training_timer);
+ timer_delete_sync(&rtlpriv->works.fast_antenna_training_timer);
}
/* get bt coexist status */
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 2cebe562a1f4..53827657abb2 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -493,7 +493,7 @@ static void bl_cmd_timeout(struct timer_list *t)
struct rsi_hw *adapter = from_timer(adapter, t, bl_cmd_timer);
adapter->blcmd_timer_expired = true;
- del_timer(&adapter->bl_cmd_timer);
+ timer_delete(&adapter->bl_cmd_timer);
}
static int bl_start_cmd_timer(struct rsi_hw *adapter, u32 timeout)
@@ -511,7 +511,7 @@ static int bl_stop_cmd_timer(struct rsi_hw *adapter)
{
adapter->blcmd_timer_expired = false;
if (timer_pending(&adapter->bl_cmd_timer))
- del_timer(&adapter->bl_cmd_timer);
+ timer_delete(&adapter->bl_cmd_timer);
return 0;
}
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 3425a473b9a1..9db08200f4fa 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1754,7 +1754,7 @@ void rsi_roc_timeout(struct timer_list *t)
ieee80211_remain_on_channel_expired(common->priv->hw);
if (timer_pending(&common->roc_timer))
- del_timer(&common->roc_timer);
+ timer_delete(&common->roc_timer);
rsi_resume_conn_channel(common);
mutex_unlock(&common->mutex);
@@ -1776,7 +1776,7 @@ static int rsi_mac80211_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (timer_pending(&common->roc_timer)) {
rsi_dbg(INFO_ZONE, "Stop on-going ROC\n");
- del_timer(&common->roc_timer);
+ timer_delete(&common->roc_timer);
}
common->roc_timer.expires = msecs_to_jiffies(duration) + jiffies;
add_timer(&common->roc_timer);
@@ -1820,7 +1820,7 @@ static int rsi_mac80211_cancel_roc(struct ieee80211_hw *hw,
return 0;
}
- del_timer(&common->roc_timer);
+ timer_delete(&common->roc_timer);
rsi_resume_conn_channel(common);
mutex_unlock(&common->mutex);
diff --git a/drivers/net/wireless/st/cw1200/main.c b/drivers/net/wireless/st/cw1200/main.c
index a54a7b86864f..5d569eeb353f 100644
--- a/drivers/net/wireless/st/cw1200/main.c
+++ b/drivers/net/wireless/st/cw1200/main.c
@@ -458,7 +458,7 @@ static void cw1200_unregister_common(struct ieee80211_hw *dev)
ieee80211_unregister_hw(dev);
- del_timer_sync(&priv->mcast_timeout);
+ timer_delete_sync(&priv->mcast_timeout);
cw1200_unregister_bh(priv);
cw1200_debug_release(priv);
diff --git a/drivers/net/wireless/st/cw1200/pm.c b/drivers/net/wireless/st/cw1200/pm.c
index a20ab577a364..2002e3f9fe45 100644
--- a/drivers/net/wireless/st/cw1200/pm.c
+++ b/drivers/net/wireless/st/cw1200/pm.c
@@ -105,7 +105,7 @@ int cw1200_pm_init(struct cw1200_pm_state *pm,
void cw1200_pm_deinit(struct cw1200_pm_state *pm)
{
- del_timer_sync(&pm->stay_awake);
+ timer_delete_sync(&pm->stay_awake);
}
void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c
index 259739e53fc1..4fd76183c368 100644
--- a/drivers/net/wireless/st/cw1200/queue.c
+++ b/drivers/net/wireless/st/cw1200/queue.c
@@ -244,7 +244,7 @@ void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats)
void cw1200_queue_deinit(struct cw1200_queue *queue)
{
cw1200_queue_clear(queue);
- del_timer_sync(&queue->gc);
+ timer_delete_sync(&queue->gc);
INIT_LIST_HEAD(&queue->free_pool);
kfree(queue->pool);
kfree(queue->link_map_cache);
diff --git a/drivers/net/wireless/st/cw1200/sta.c b/drivers/net/wireless/st/cw1200/sta.c
index c259da8161e4..444272caf124 100644
--- a/drivers/net/wireless/st/cw1200/sta.c
+++ b/drivers/net/wireless/st/cw1200/sta.c
@@ -113,7 +113,7 @@ void cw1200_stop(struct ieee80211_hw *dev, bool suspend)
cancel_work_sync(&priv->unjoin_work);
cancel_delayed_work_sync(&priv->link_id_gc_work);
flush_workqueue(priv->workqueue);
- del_timer_sync(&priv->mcast_timeout);
+ timer_delete_sync(&priv->mcast_timeout);
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
priv->listening = false;
@@ -2102,7 +2102,7 @@ void cw1200_multicast_stop_work(struct work_struct *work)
container_of(work, struct cw1200_common, multicast_stop_work);
if (priv->aid0_bit_set) {
- del_timer_sync(&priv->mcast_timeout);
+ timer_delete_sync(&priv->mcast_timeout);
wsm_lock_tx(priv);
priv->aid0_bit_set = false;
cw1200_set_tim_impl(priv, false);
@@ -2170,7 +2170,7 @@ void cw1200_suspend_resume(struct cw1200_common *priv,
}
spin_unlock_bh(&priv->ps_state_lock);
if (cancel_tmo)
- del_timer_sync(&priv->mcast_timeout);
+ timer_delete_sync(&priv->mcast_timeout);
} else {
spin_lock_bh(&priv->ps_state_lock);
cw1200_ps_notify(priv, arg->link_id, arg->stop);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 8fb58a5d911c..ea9bc4717a85 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -117,7 +117,7 @@ int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif)
else {
ret = wl1271_set_rx_streaming(wl, wlvif, false);
/* don't cancel_work_sync since we might deadlock */
- del_timer_sync(&wlvif->rx_streaming_timer);
+ timer_delete_sync(&wlvif->rx_streaming_timer);
}
out:
return ret;
@@ -2841,7 +2841,7 @@ deinit:
unlock:
mutex_unlock(&wl->mutex);
- del_timer_sync(&wlvif->rx_streaming_timer);
+ timer_delete_sync(&wlvif->rx_streaming_timer);
cancel_work_sync(&wlvif->rx_streaming_enable_work);
cancel_work_sync(&wlvif->rx_streaming_disable_work);
cancel_work_sync(&wlvif->rc_update_work);
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 325fcb3d1075..a0a438881388 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -329,7 +329,7 @@ static void xenvif_down(struct xenvif *vif)
if (queue->tx_irq != queue->rx_irq)
disable_irq(queue->rx_irq);
napi_disable(&queue->napi);
- del_timer_sync(&queue->credit_timeout);
+ timer_delete_sync(&queue->credit_timeout);
}
}
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 63fe51d0e64d..fc52d5c4c69b 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1819,7 +1819,7 @@ static void xennet_disconnect_backend(struct netfront_info *info)
for (i = 0; i < num_queues && info->queues; ++i) {
struct netfront_queue *queue = &info->queues[i];
- del_timer_sync(&queue->rx_refill_timer);
+ timer_delete_sync(&queue->rx_refill_timer);
if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
unbind_from_irqhandler(queue->tx_irq, queue);
diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c
index 93094418fd24..43ce0c9b2355 100644
--- a/drivers/nfc/nfcmrvl/fw_dnld.c
+++ b/drivers/nfc/nfcmrvl/fw_dnld.c
@@ -102,10 +102,10 @@ static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error)
atomic_set(&priv->ndev->cmd_cnt, 0);
if (timer_pending(&priv->ndev->cmd_timer))
- del_timer_sync(&priv->ndev->cmd_timer);
+ timer_delete_sync(&priv->ndev->cmd_timer);
if (timer_pending(&priv->fw_dnld.timer))
- del_timer_sync(&priv->fw_dnld.timer);
+ timer_delete_sync(&priv->fw_dnld.timer);
nfc_info(priv->dev, "FW loading over (%d)]\n", error);
@@ -464,7 +464,7 @@ void nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv,
{
/* Discard command timer */
if (timer_pending(&priv->ndev->cmd_timer))
- del_timer_sync(&priv->ndev->cmd_timer);
+ timer_delete_sync(&priv->ndev->cmd_timer);
/* Allow next command */
atomic_set(&priv->ndev->cmd_cnt, 1);
diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
index e2bc67300a91..34c40d10e260 100644
--- a/drivers/nfc/pn533/pn533.c
+++ b/drivers/nfc/pn533/pn533.c
@@ -1515,7 +1515,7 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg,
cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
if (cur_mod->len == 0) { /* Target mode */
- del_timer(&dev->listen_timer);
+ timer_delete(&dev->listen_timer);
rc = pn533_init_target_complete(dev, resp);
goto done;
}
@@ -1749,7 +1749,7 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev)
{
struct pn533 *dev = nfc_get_drvdata(nfc_dev);
- del_timer(&dev->listen_timer);
+ timer_delete(&dev->listen_timer);
if (!dev->poll_mod_count) {
dev_dbg(dev->dev,
diff --git a/drivers/nfc/pn533/uart.c b/drivers/nfc/pn533/uart.c
index cfbbe0713317..580c9193e4a7 100644
--- a/drivers/nfc/pn533/uart.c
+++ b/drivers/nfc/pn533/uart.c
@@ -209,7 +209,7 @@ static size_t pn532_receive_buf(struct serdev_device *serdev,
struct pn532_uart_phy *dev = serdev_device_get_drvdata(serdev);
size_t i;
- del_timer(&dev->cmd_timeout);
+ timer_delete(&dev->cmd_timeout);
for (i = 0; i < count; i++) {
skb_put_u8(dev->recv_skb, *data++);
if (!pn532_uart_rx_is_frame(dev->recv_skb))
diff --git a/drivers/nfc/st-nci/ndlc.c b/drivers/nfc/st-nci/ndlc.c
index d2aa9f766738..8feac119a4bc 100644
--- a/drivers/nfc/st-nci/ndlc.c
+++ b/drivers/nfc/st-nci/ndlc.c
@@ -161,8 +161,8 @@ static void llt_ndlc_rcv_queue(struct llt_ndlc *ndlc)
case PCB_SYNC_ACK:
skb = skb_dequeue(&ndlc->ack_pending_q);
kfree_skb(skb);
- del_timer_sync(&ndlc->t1_timer);
- del_timer_sync(&ndlc->t2_timer);
+ timer_delete_sync(&ndlc->t1_timer);
+ timer_delete_sync(&ndlc->t2_timer);
ndlc->t2_active = false;
ndlc->t1_active = false;
break;
@@ -213,8 +213,8 @@ static void llt_ndlc_sm_work(struct work_struct *work)
pr_debug("Handle T2(recv DATA) elapsed (T2 now inactive)\n");
ndlc->t2_active = false;
ndlc->t1_active = false;
- del_timer_sync(&ndlc->t1_timer);
- del_timer_sync(&ndlc->t2_timer);
+ timer_delete_sync(&ndlc->t1_timer);
+ timer_delete_sync(&ndlc->t2_timer);
ndlc_close(ndlc);
ndlc->hard_fault = -EREMOTEIO;
}
@@ -283,8 +283,8 @@ EXPORT_SYMBOL(ndlc_probe);
void ndlc_remove(struct llt_ndlc *ndlc)
{
/* cancel timers */
- del_timer_sync(&ndlc->t1_timer);
- del_timer_sync(&ndlc->t2_timer);
+ timer_delete_sync(&ndlc->t1_timer);
+ timer_delete_sync(&ndlc->t2_timer);
ndlc->t2_active = false;
ndlc->t1_active = false;
/* cancel work */
diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
index b2f1ced8e6dd..8cfe5405bae6 100644
--- a/drivers/nfc/st-nci/se.c
+++ b/drivers/nfc/st-nci/se.c
@@ -257,7 +257,7 @@ static void st_nci_hci_admin_event_received(struct nci_dev *ndev,
case ST_NCI_EVT_HOT_PLUG:
if (info->se_info.se_active) {
if (!ST_NCI_EVT_HOT_PLUG_IS_INHIBITED(skb)) {
- del_timer_sync(&info->se_info.se_active_timer);
+ timer_delete_sync(&info->se_info.se_active_timer);
info->se_info.se_active = false;
complete(&info->se_info.req_completion);
} else {
@@ -282,7 +282,7 @@ static int st_nci_hci_apdu_reader_event_received(struct nci_dev *ndev,
switch (event) {
case ST_NCI_EVT_TRANSMIT_DATA:
- del_timer_sync(&info->se_info.bwi_timer);
+ timer_delete_sync(&info->se_info.bwi_timer);
info->se_info.bwi_active = false;
info->se_info.cb(info->se_info.cb_context,
skb->data, skb->len, 0);
@@ -415,7 +415,7 @@ void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd,
if (ndev->hci_dev->count_pipes ==
ndev->hci_dev->expected_pipes) {
- del_timer_sync(&info->se_info.se_active_timer);
+ timer_delete_sync(&info->se_info.se_active_timer);
info->se_info.se_active = false;
ndev->hci_dev->count_pipes = 0;
complete(&info->se_info.req_completion);
@@ -751,9 +751,9 @@ void st_nci_se_deinit(struct nci_dev *ndev)
struct st_nci_info *info = nci_get_drvdata(ndev);
if (info->se_info.bwi_active)
- del_timer_sync(&info->se_info.bwi_timer);
+ timer_delete_sync(&info->se_info.bwi_timer);
if (info->se_info.se_active)
- del_timer_sync(&info->se_info.se_active_timer);
+ timer_delete_sync(&info->se_info.se_active_timer);
info->se_info.se_active = false;
info->se_info.bwi_active = false;
diff --git a/drivers/nfc/st21nfca/core.c b/drivers/nfc/st21nfca/core.c
index 161caf2675cf..bec6f607c32c 100644
--- a/drivers/nfc/st21nfca/core.c
+++ b/drivers/nfc/st21nfca/core.c
@@ -844,7 +844,7 @@ static void st21nfca_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
info->se_info.count_pipes++;
if (info->se_info.count_pipes == info->se_info.expected_pipes) {
- del_timer_sync(&info->se_info.se_active_timer);
+ timer_delete_sync(&info->se_info.se_active_timer);
info->se_info.se_active = false;
info->se_info.count_pipes = 0;
complete(&info->se_info.req_completion);
@@ -864,7 +864,7 @@ static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event,
case ST21NFCA_EVT_HOT_PLUG:
if (info->se_info.se_active) {
if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) {
- del_timer_sync(&info->se_info.se_active_timer);
+ timer_delete_sync(&info->se_info.se_active_timer);
info->se_info.se_active = false;
complete(&info->se_info.req_completion);
} else {
diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c
index dae288bebcb5..9a50f3c03bd4 100644
--- a/drivers/nfc/st21nfca/se.c
+++ b/drivers/nfc/st21nfca/se.c
@@ -380,7 +380,7 @@ int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev,
switch (event) {
case ST21NFCA_EVT_TRANSMIT_DATA:
- del_timer_sync(&info->se_info.bwi_timer);
+ timer_delete_sync(&info->se_info.bwi_timer);
cancel_work_sync(&info->se_info.timeout_work);
info->se_info.bwi_active = false;
r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE,
@@ -435,9 +435,9 @@ void st21nfca_se_deinit(struct nfc_hci_dev *hdev)
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
if (info->se_info.bwi_active)
- del_timer_sync(&info->se_info.bwi_timer);
+ timer_delete_sync(&info->se_info.bwi_timer);
if (info->se_info.se_active)
- del_timer_sync(&info->se_info.se_active_timer);
+ timer_delete_sync(&info->se_info.se_active_timer);
cancel_work_sync(&info->se_info.timeout_work);
info->se_info.bwi_active = false;
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c
index d687e8c2cc78..63ceed89b62e 100644
--- a/drivers/ntb/hw/amd/ntb_hw_amd.c
+++ b/drivers/ntb/hw/amd/ntb_hw_amd.c
@@ -1318,6 +1318,7 @@ static const struct pci_device_id amd_ntb_pci_tbl[] = {
{ PCI_VDEVICE(AMD, 0x148b), (kernel_ulong_t)&dev_data[1] },
{ PCI_VDEVICE(AMD, 0x14c0), (kernel_ulong_t)&dev_data[1] },
{ PCI_VDEVICE(AMD, 0x14c3), (kernel_ulong_t)&dev_data[1] },
+ { PCI_VDEVICE(AMD, 0x155a), (kernel_ulong_t)&dev_data[1] },
{ PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] },
{ 0, }
};
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c
index 544d8a4d2af5..f27df8d7f3b9 100644
--- a/drivers/ntb/hw/idt/ntb_hw_idt.c
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.c
@@ -1041,7 +1041,7 @@ static inline char *idt_get_mw_name(enum idt_mw_type mw_type)
static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
unsigned char *mw_cnt)
{
- struct idt_mw_cfg mws[IDT_MAX_NR_MWS], *ret_mws;
+ struct idt_mw_cfg *mws;
const struct idt_ntb_bar *bars;
enum idt_mw_type mw_type;
unsigned char widx, bidx, en_cnt;
@@ -1049,6 +1049,11 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
int aprt_size;
u32 data;
+ mws = devm_kcalloc(&ndev->ntb.pdev->dev, IDT_MAX_NR_MWS,
+ sizeof(*mws), GFP_KERNEL);
+ if (!mws)
+ return ERR_PTR(-ENOMEM);
+
/* Retrieve the array of the BARs registers */
bars = portdata_tbl[port].bars;
@@ -1103,16 +1108,7 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
}
}
- /* Allocate memory for memory window descriptors */
- ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, sizeof(*ret_mws),
- GFP_KERNEL);
- if (!ret_mws)
- return ERR_PTR(-ENOMEM);
-
- /* Copy the info of detected memory windows */
- memcpy(ret_mws, mws, (*mw_cnt)*sizeof(*ret_mws));
-
- return ret_mws;
+ return mws;
}
/*
diff --git a/drivers/ntb/hw/intel/ntb_hw_gen3.c b/drivers/ntb/hw/intel/ntb_hw_gen3.c
index ffcfc3e02c35..a5aa96a31f4a 100644
--- a/drivers/ntb/hw/intel/ntb_hw_gen3.c
+++ b/drivers/ntb/hw/intel/ntb_hw_gen3.c
@@ -215,6 +215,9 @@ static int gen3_init_ntb(struct intel_ntb_dev *ndev)
}
ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
+ /* Make sure we are not using DB's used for link status */
+ if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD)
+ ndev->db_valid_mask &= ~ndev->db_link_mask;
ndev->reg->db_iowrite(ndev->db_valid_mask,
ndev->self_mmio +
diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
index ad1786be2554..f851397b65d6 100644
--- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
+++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
@@ -288,7 +288,7 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx,
if (size != 0 && xlate_pos < 12)
return -EINVAL;
- if (!IS_ALIGNED(addr, BIT_ULL(xlate_pos))) {
+ if (xlate_pos >= 0 && !IS_ALIGNED(addr, BIT_ULL(xlate_pos))) {
/*
* In certain circumstances we can get a buffer that is
* not aligned to its size. (Most of the time
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index a22ea4a4b202..4f775c3e218f 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -1353,7 +1353,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
qp_count = ilog2(qp_bitmap);
if (nt->use_msi) {
qp_count -= 1;
- nt->msi_db_mask = 1 << qp_count;
+ nt->msi_db_mask = BIT_ULL(qp_count);
ntb_db_clear_mask(ndev, nt->msi_db_mask);
}
diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
index 72bc1d017a46..dfd175f79e8f 100644
--- a/drivers/ntb/test/ntb_perf.c
+++ b/drivers/ntb/test/ntb_perf.c
@@ -839,10 +839,8 @@ static int perf_copy_chunk(struct perf_thread *pthr,
dma_set_unmap(tx, unmap);
ret = dma_submit_error(dmaengine_submit(tx));
- if (ret) {
- dmaengine_unmap_put(unmap);
+ if (ret)
goto err_free_resource;
- }
dmaengine_unmap_put(unmap);
diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c
index 9e84ab411564..51614651d2e7 100644
--- a/drivers/nvdimm/claim.c
+++ b/drivers/nvdimm/claim.c
@@ -56,17 +56,6 @@ bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
return true;
}
-bool nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
- struct nd_namespace_common **_ndns)
-{
- bool claimed;
-
- nvdimm_bus_lock(&attach->dev);
- claimed = __nd_attach_ndns(dev, attach, _ndns);
- nvdimm_bus_unlock(&attach->dev);
- return claimed;
-}
-
static bool is_idle(struct device *dev, struct nd_namespace_common *ndns)
{
struct nd_region *nd_region = to_nd_region(dev->parent);
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 082253a3a956..04f4a049599a 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -442,7 +442,8 @@ int nd_label_data_init(struct nvdimm_drvdata *ndd)
if (ndd->data)
return 0;
- if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0) {
+ if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0 ||
+ ndd->nsarea.config_size == 0) {
dev_dbg(ndd->dev, "failed to init config data area: (%u:%u)\n",
ndd->nsarea.max_xfer, ndd->nsarea.config_size);
return -ENXIO;
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index 86976a9e8a15..bfc6bfeb6e24 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -127,8 +127,6 @@ resource_size_t nd_region_allocatable_dpa(struct nd_region *nd_region);
resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
struct nd_mapping *nd_mapping);
resource_size_t nd_region_available_dpa(struct nd_region *nd_region);
-int nd_region_conflict(struct nd_region *nd_region, resource_size_t start,
- resource_size_t size);
resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd,
struct nd_label_id *label_id);
int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd);
@@ -136,8 +134,6 @@ void get_ndd(struct nvdimm_drvdata *ndd);
resource_size_t __nvdimm_namespace_capacity(struct nd_namespace_common *ndns);
void nd_detach_ndns(struct device *dev, struct nd_namespace_common **_ndns);
void __nd_detach_ndns(struct device *dev, struct nd_namespace_common **_ndns);
-bool nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
- struct nd_namespace_common **_ndns);
bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
struct nd_namespace_common **_ndns);
ssize_t nd_namespace_store(struct device *dev,
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index 37417ce5ec7b..de1ee5ebc851 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -1229,45 +1229,4 @@ bool is_nvdimm_sync(struct nd_region *nd_region)
}
EXPORT_SYMBOL_GPL(is_nvdimm_sync);
-struct conflict_context {
- struct nd_region *nd_region;
- resource_size_t start, size;
-};
-
-static int region_conflict(struct device *dev, void *data)
-{
- struct nd_region *nd_region;
- struct conflict_context *ctx = data;
- resource_size_t res_end, region_end, region_start;
-
- if (!is_memory(dev))
- return 0;
-
- nd_region = to_nd_region(dev);
- if (nd_region == ctx->nd_region)
- return 0;
-
- res_end = ctx->start + ctx->size;
- region_start = nd_region->ndr_start;
- region_end = region_start + nd_region->ndr_size;
- if (ctx->start >= region_start && ctx->start < region_end)
- return -EBUSY;
- if (res_end > region_start && res_end <= region_end)
- return -EBUSY;
- return 0;
-}
-
-int nd_region_conflict(struct nd_region *nd_region, resource_size_t start,
- resource_size_t size)
-{
- struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
- struct conflict_context ctx = {
- .nd_region = nd_region,
- .start = start,
- .size = size,
- };
-
- return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict);
-}
-
MODULE_IMPORT_NS("DEVMEM");
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index 10e453b2436e..d47dfa80fb95 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -18,10 +18,15 @@ config NVME_MULTIPATH
bool "NVMe multipath support"
depends on NVME_CORE
help
- This option enables support for multipath access to NVMe
- subsystems. If this option is enabled only a single
- /dev/nvmeXnY device will show up for each NVMe namespace,
- even if it is accessible through multiple controllers.
+ This option controls support for multipath access to NVMe
+ subsystems. If this option is enabled support for NVMe multipath
+ access is included in the kernel. If this option is disabled support
+ for NVMe multipath access is excluded from the kernel. When this
+ option is disabled each controller/namespace receives its
+ own /dev/nvmeXnY device entry and NVMe multipath access is
+ not supported.
+
+ If unsure, say Y.
config NVME_VERBOSE_ERRORS
bool "NVMe verbose error reporting"
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index c2d89fac86c5..cc23035148b4 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3822,7 +3822,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
"Found shared namespace %d, but multipathing not supported.\n",
info->nsid);
dev_warn_once(ctrl->device,
- "Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0.\n");
+ "Shared namespace support requires core_nvme.multipath=Y.\n");
}
}
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index ecf136489044..ca86d3bf7ea4 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -114,8 +114,7 @@ static struct request *nvme_alloc_user_request(struct request_queue *q,
static int nvme_map_user_request(struct request *req, u64 ubuffer,
unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
- struct io_uring_cmd *ioucmd, unsigned int flags,
- unsigned int iou_issue_flags)
+ struct iov_iter *iter, unsigned int flags)
{
struct request_queue *q = req->q;
struct nvme_ns *ns = q->queuedata;
@@ -129,37 +128,23 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
if (!nvme_ctrl_sgl_supported(ctrl))
dev_warn_once(ctrl->device, "using unchecked data buffer\n");
if (has_metadata) {
- if (!supports_metadata) {
- ret = -EINVAL;
- goto out;
- }
+ if (!supports_metadata)
+ return -EINVAL;
+
if (!nvme_ctrl_meta_sgl_supported(ctrl))
dev_warn_once(ctrl->device,
"using unchecked metadata buffer\n");
}
- if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
- struct iov_iter iter;
-
- /* fixedbufs is only for non-vectored io */
- if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC)) {
- ret = -EINVAL;
- goto out;
- }
- ret = io_uring_cmd_import_fixed(ubuffer, bufflen,
- rq_data_dir(req), &iter, ioucmd,
- iou_issue_flags);
- if (ret < 0)
- goto out;
- ret = blk_rq_map_user_iov(q, req, NULL, &iter, GFP_KERNEL);
- } else {
+ if (iter)
+ ret = blk_rq_map_user_iov(q, req, NULL, iter, GFP_KERNEL);
+ else
ret = blk_rq_map_user_io(req, NULL, nvme_to_user_ptr(ubuffer),
bufflen, GFP_KERNEL, flags & NVME_IOCTL_VEC, 0,
0, rq_data_dir(req));
- }
if (ret)
- goto out;
+ return ret;
bio = req->bio;
if (bdev)
@@ -176,8 +161,6 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
out_unmap:
if (bio)
blk_rq_unmap_user(bio);
-out:
- blk_mq_free_request(req);
return ret;
}
@@ -200,9 +183,9 @@ static int nvme_submit_user_cmd(struct request_queue *q,
req->timeout = timeout;
if (ubuffer && bufflen) {
ret = nvme_map_user_request(req, ubuffer, bufflen, meta_buffer,
- meta_len, NULL, flags, 0);
+ meta_len, NULL, flags);
if (ret)
- return ret;
+ goto out_free_req;
}
bio = req->bio;
@@ -218,7 +201,10 @@ static int nvme_submit_user_cmd(struct request_queue *q,
if (effects)
nvme_passthru_end(ctrl, ns, effects, cmd, ret);
+ return ret;
+out_free_req:
+ blk_mq_free_request(req);
return ret;
}
@@ -469,6 +455,8 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
struct request_queue *q = ns ? ns->queue : ctrl->admin_q;
struct nvme_uring_data d;
struct nvme_command c;
+ struct iov_iter iter;
+ struct iov_iter *map_iter = NULL;
struct request *req;
blk_opf_t rq_flags = REQ_ALLOC_CACHE;
blk_mq_req_flags_t blk_flags = 0;
@@ -504,6 +492,20 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
d.metadata_len = READ_ONCE(cmd->metadata_len);
d.timeout_ms = READ_ONCE(cmd->timeout_ms);
+ if (d.data_len && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
+ /* fixedbufs is only for non-vectored io */
+ if (vec)
+ return -EINVAL;
+
+ ret = io_uring_cmd_import_fixed(d.addr, d.data_len,
+ nvme_is_write(&c) ? WRITE : READ, &iter, ioucmd,
+ issue_flags);
+ if (ret < 0)
+ return ret;
+
+ map_iter = &iter;
+ }
+
if (issue_flags & IO_URING_F_NONBLOCK) {
rq_flags |= REQ_NOWAIT;
blk_flags = BLK_MQ_REQ_NOWAIT;
@@ -517,11 +519,11 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
req->timeout = d.timeout_ms ? msecs_to_jiffies(d.timeout_ms) : 0;
if (d.data_len) {
- ret = nvme_map_user_request(req, d.addr,
- d.data_len, nvme_to_user_ptr(d.metadata),
- d.metadata_len, ioucmd, vec, issue_flags);
+ ret = nvme_map_user_request(req, d.addr, d.data_len,
+ nvme_to_user_ptr(d.metadata), d.metadata_len,
+ map_iter, vec);
if (ret)
- return ret;
+ goto out_free_req;
}
/* to free bio on completion, as req->bio will be null at that time */
@@ -531,6 +533,10 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
req->end_io = nvme_uring_cmd_end_io;
blk_execute_rq_nowait(req, false);
return -EIOCBQUEUED;
+
+out_free_req:
+ blk_mq_free_request(req);
+ return ret;
}
static bool is_ctrl_ioctl(unsigned int cmd)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 6b12ca80aa27..89be5911b25d 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -860,7 +860,7 @@ static int nvme_read_ana_log(struct nvme_ctrl *ctrl)
if (nr_change_groups)
mod_timer(&ctrl->anatt_timer, ctrl->anatt * HZ * 2 + jiffies);
else
- del_timer_sync(&ctrl->anatt_timer);
+ timer_delete_sync(&ctrl->anatt_timer);
out_unlock:
mutex_unlock(&ctrl->ana_lock);
return error;
@@ -900,7 +900,7 @@ void nvme_mpath_stop(struct nvme_ctrl *ctrl)
{
if (!nvme_ctrl_use_ana(ctrl))
return;
- del_timer_sync(&ctrl->anatt_timer);
+ timer_delete_sync(&ctrl->anatt_timer);
cancel_work_sync(&ctrl->ana_work);
}
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 2883d17ee1eb..b178d52eac1b 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -986,6 +986,9 @@ static void nvme_submit_cmds(struct nvme_queue *nvmeq, struct rq_list *rqlist)
{
struct request *req;
+ if (rq_list_empty(rqlist))
+ return;
+
spin_lock(&nvmeq->sq_lock);
while ((req = rq_list_pop(rqlist))) {
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index e4300eb95101..5dcbd5aa86e1 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
bool sep = false;
int i;
- for (i = 0; i < 7; i++) {
+ for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
int state = BIT(i);
if (!(ctrl->csts & state))
diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c
index b54b3fdbe389..51c27b32248d 100644
--- a/drivers/nvme/target/pci-epf.c
+++ b/drivers/nvme/target/pci-epf.c
@@ -1264,6 +1264,7 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
struct nvmet_pci_epf_ctrl *ctrl = tctrl->drvdata;
struct nvmet_pci_epf_queue *cq = &ctrl->cq[cqid];
u16 status;
+ int ret;
if (test_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags))
return NVME_SC_QID_INVALID | NVME_STATUS_DNR;
@@ -1298,6 +1299,24 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
if (status != NVME_SC_SUCCESS)
goto err;
+ /*
+ * Map the CQ PCI address space and since PCI endpoint controllers may
+ * return a partial mapping, check that the mapping is large enough.
+ */
+ ret = nvmet_pci_epf_mem_map(ctrl->nvme_epf, cq->pci_addr, cq->pci_size,
+ &cq->pci_map);
+ if (ret) {
+ dev_err(ctrl->dev, "Failed to map CQ %u (err=%d)\n",
+ cq->qid, ret);
+ goto err_internal;
+ }
+
+ if (cq->pci_map.pci_size < cq->pci_size) {
+ dev_err(ctrl->dev, "Invalid partial mapping of queue %u\n",
+ cq->qid);
+ goto err_unmap_queue;
+ }
+
set_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags);
dev_dbg(ctrl->dev, "CQ[%u]: %u entries of %zu B, IRQ vector %u\n",
@@ -1305,6 +1324,10 @@ static u16 nvmet_pci_epf_create_cq(struct nvmet_ctrl *tctrl,
return NVME_SC_SUCCESS;
+err_unmap_queue:
+ nvmet_pci_epf_mem_unmap(ctrl->nvme_epf, &cq->pci_map);
+err_internal:
+ status = NVME_SC_INTERNAL | NVME_STATUS_DNR;
err:
if (test_and_clear_bit(NVMET_PCI_EPF_Q_IRQ_ENABLED, &cq->flags))
nvmet_pci_epf_remove_irq_vector(ctrl, cq->vector);
@@ -1322,6 +1345,7 @@ static u16 nvmet_pci_epf_delete_cq(struct nvmet_ctrl *tctrl, u16 cqid)
cancel_delayed_work_sync(&cq->work);
nvmet_pci_epf_drain_queue(cq);
nvmet_pci_epf_remove_irq_vector(ctrl, cq->vector);
+ nvmet_pci_epf_mem_unmap(ctrl->nvme_epf, &cq->pci_map);
return NVME_SC_SUCCESS;
}
@@ -1553,36 +1577,6 @@ static void nvmet_pci_epf_free_queues(struct nvmet_pci_epf_ctrl *ctrl)
ctrl->cq = NULL;
}
-static int nvmet_pci_epf_map_queue(struct nvmet_pci_epf_ctrl *ctrl,
- struct nvmet_pci_epf_queue *queue)
-{
- struct nvmet_pci_epf *nvme_epf = ctrl->nvme_epf;
- int ret;
-
- ret = nvmet_pci_epf_mem_map(nvme_epf, queue->pci_addr,
- queue->pci_size, &queue->pci_map);
- if (ret) {
- dev_err(ctrl->dev, "Failed to map queue %u (err=%d)\n",
- queue->qid, ret);
- return ret;
- }
-
- if (queue->pci_map.pci_size < queue->pci_size) {
- dev_err(ctrl->dev, "Invalid partial mapping of queue %u\n",
- queue->qid);
- nvmet_pci_epf_mem_unmap(nvme_epf, &queue->pci_map);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static inline void nvmet_pci_epf_unmap_queue(struct nvmet_pci_epf_ctrl *ctrl,
- struct nvmet_pci_epf_queue *queue)
-{
- nvmet_pci_epf_mem_unmap(ctrl->nvme_epf, &queue->pci_map);
-}
-
static void nvmet_pci_epf_exec_iod_work(struct work_struct *work)
{
struct nvmet_pci_epf_iod *iod =
@@ -1746,11 +1740,7 @@ static void nvmet_pci_epf_cq_work(struct work_struct *work)
struct nvme_completion *cqe;
struct nvmet_pci_epf_iod *iod;
unsigned long flags;
- int ret, n = 0;
-
- ret = nvmet_pci_epf_map_queue(ctrl, cq);
- if (ret)
- goto again;
+ int ret = 0, n = 0;
while (test_bit(NVMET_PCI_EPF_Q_LIVE, &cq->flags) && ctrl->link_up) {
@@ -1797,8 +1787,6 @@ static void nvmet_pci_epf_cq_work(struct work_struct *work)
n++;
}
- nvmet_pci_epf_unmap_queue(ctrl, cq);
-
/*
* We do not support precise IRQ coalescing time (100ns units as per
* NVMe specifications). So if we have posted completion entries without
@@ -1807,7 +1795,6 @@ static void nvmet_pci_epf_cq_work(struct work_struct *work)
if (n)
nvmet_pci_epf_raise_irq(ctrl, cq, true);
-again:
if (ret < 0)
queue_delayed_work(system_highpri_wq, &cq->work,
NVMET_PCI_EPF_CQ_RETRY_INTERVAL);
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index 4547ac44c8d4..474515d27e9c 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -73,7 +73,7 @@ int parport_wait_event (struct parport *port, signed long timeout)
timer_setup(&port->timer, timeout_waiting_on_port, 0);
mod_timer(&port->timer, jiffies + timeout);
ret = down_interruptible (&port->physport->ieee1284.irq);
- if (!del_timer_sync(&port->timer) && !ret)
+ if (!timer_delete_sync(&port->timer) && !ret)
/* Timed out. */
ret = 1;
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index c6b266c772c8..ec6c8dbdc5e9 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -538,4 +538,37 @@ int pci_max_pasids(struct pci_dev *pdev)
return (1 << FIELD_GET(PCI_PASID_CAP_WIDTH, supported));
}
EXPORT_SYMBOL_GPL(pci_max_pasids);
+
+/**
+ * pci_pasid_status - Check the PASID status
+ * @pdev: PCI device structure
+ *
+ * Returns a negative value when no PASID capability is present.
+ * Otherwise the value of the control register is returned.
+ * Status reported are:
+ *
+ * PCI_PASID_CTRL_ENABLE - PASID enabled
+ * PCI_PASID_CTRL_EXEC - Execute permission enabled
+ * PCI_PASID_CTRL_PRIV - Privileged mode enabled
+ */
+int pci_pasid_status(struct pci_dev *pdev)
+{
+ int pasid;
+ u16 ctrl;
+
+ if (pdev->is_virtfn)
+ pdev = pci_physfn(pdev);
+
+ pasid = pdev->pasid_cap;
+ if (!pasid)
+ return -EINVAL;
+
+ pci_read_config_word(pdev, pasid + PCI_PASID_CTRL, &ctrl);
+
+ ctrl &= PCI_PASID_CTRL_ENABLE | PCI_PASID_CTRL_EXEC |
+ PCI_PASID_CTRL_PRIV;
+
+ return ctrl;
+}
+EXPORT_SYMBOL_GPL(pci_pasid_status);
#endif /* CONFIG_PCI_PASID */
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index c01968ef0bd7..20529d1a3c44 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1794,7 +1794,7 @@ static void interrupt_event_handler(struct controller *ctrl)
} else if (ctrl->event_queue[loop].event_type ==
INT_BUTTON_CANCEL) {
dbg("button cancel\n");
- del_timer(&p_slot->task_event);
+ timer_delete(&p_slot->task_event);
mutex_lock(&ctrl->crit_sect);
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index bfbec7c1a6b1..387b85585263 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -564,7 +564,7 @@ void shpchp_release_ctlr(struct controller *ctrl)
shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
if (shpchp_poll_mode)
- del_timer(&ctrl->poll_timer);
+ timer_delete(&ctrl->poll_timer);
else {
free_irq(ctrl->pci_dev->irq, ctrl);
pci_disable_msi(ctrl->pci_dev);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 86a357837a7b..1e464b951ed2 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1324,7 +1324,7 @@ static void __exit exit_i82365(void)
}
platform_device_unregister(i82365_device);
if (poll_interval != 0)
- del_timer_sync(&poll_timer);
+ timer_delete_sync(&poll_timer);
if (grab_irq != 0)
free_irq(cs_irq, pcic_interrupt);
for (i = 0; i < sockets; i++) {
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 1deb9960db34..d361124db993 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -766,7 +766,7 @@ EXPORT_SYMBOL(soc_pcmcia_init_one);
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
{
- del_timer_sync(&skt->poll_timer);
+ timer_delete_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
@@ -865,7 +865,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
return ret;
out_err_8:
- del_timer_sync(&skt->poll_timer);
+ timer_delete_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
out_err_7:
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 5ef888688e23..060aed0edc65 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -509,7 +509,7 @@ static void __exit exit_tcic(void)
{
int i;
- del_timer_sync(&poll_timer);
+ timer_delete_sync(&poll_timer);
if (cs_irq != 0) {
tcic_aux_setw(TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY|0x0a00);
free_irq(cs_irq, tcic_interrupt);
diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
index 300cdaa75a17..aae99adb29eb 100644
--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -1320,7 +1320,7 @@ static void mlxbf_tmfifo_cleanup(struct mlxbf_tmfifo *fifo)
int i;
fifo->is_ready = false;
- del_timer_sync(&fifo->timer);
+ timer_delete_sync(&fifo->timer);
mlxbf_tmfifo_disable_irqs(fifo);
cancel_work_sync(&fifo->work);
for (i = 0; i < MLXBF_TMFIFO_VDEV_MAX; i++)
diff --git a/drivers/platform/x86/gigabyte-wmi.c b/drivers/platform/x86/gigabyte-wmi.c
index f6ba88baee4d..f42c85607a6b 100644
--- a/drivers/platform/x86/gigabyte-wmi.c
+++ b/drivers/platform/x86/gigabyte-wmi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (C) 2021 Thomas Weißschuh <thomas@weissschuh.net>
+ * Copyright (C) 2021 Thomas Weißschuh <linux@weissschuh.net>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -159,6 +159,6 @@ static struct wmi_driver gigabyte_wmi_driver = {
module_wmi_driver(gigabyte_wmi_driver);
MODULE_DEVICE_TABLE(wmi, gigabyte_wmi_id_table);
-MODULE_AUTHOR("Thomas Weißschuh <thomas@weissschuh.net>");
+MODULE_AUTHOR("Thomas Weißschuh <linux@weissschuh.net>");
MODULE_DESCRIPTION("Gigabyte WMI temperature driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c
index dbcd3087aaa4..31239a93dd71 100644
--- a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c
+++ b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c
@@ -84,7 +84,7 @@ static DECLARE_HASHTABLE(isst_hash, 8);
static DEFINE_MUTEX(isst_hash_lock);
static int isst_store_new_cmd(int cmd, u32 cpu, int mbox_cmd_type, u32 param,
- u32 data)
+ u64 data)
{
struct isst_cmd *sst_cmd;
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 79a7b68c7373..5d717b1c23cf 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -1108,7 +1108,7 @@ static int ips_monitor(void *data)
last_sample_period = 1;
} while (!kthread_should_stop());
- del_timer_sync(&ips->timer);
+ timer_delete_sync(&ips->timer);
dev_dbg(ips->dev, "ips-monitor thread stopped\n");
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 3197aaa69da7..b52390fbd743 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -538,7 +538,7 @@ static void sony_laptop_remove_input(void)
if (!atomic_dec_and_test(&sony_laptop_input.users))
return;
- del_timer_sync(&sony_laptop_input.release_key_timer);
+ timer_delete_sync(&sony_laptop_input.release_key_timer);
/*
* Generate key-up events for remaining keys. Note that we don't
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 0384cf311878..5790095c175e 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -367,6 +367,7 @@ static struct {
u32 beep_needs_two_args:1;
u32 mixer_no_level_control:1;
u32 battery_force_primary:1;
+ u32 platform_drv_registered:1;
u32 hotkey_poll_active:1;
u32 has_adaptive_kbd:1;
u32 kbd_lang:1;
@@ -8793,6 +8794,7 @@ static const struct attribute_group fan_driver_attr_group = {
#define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */
#define TPACPI_FAN_DECRPM 0x0020 /* For ECFW's with RPM in register as decimal */
#define TPACPI_FAN_TPR 0x0040 /* Fan speed is in Ticks Per Revolution */
+#define TPACPI_FAN_NOACPI 0x0080 /* Don't use ACPI methods even if detected */
static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1),
@@ -8823,6 +8825,9 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */
TPACPI_Q_LNV3('R', '0', 'Q', TPACPI_FAN_DECRPM),/* L480 */
TPACPI_Q_LNV('8', 'F', TPACPI_FAN_TPR), /* ThinkPad x120e */
+ TPACPI_Q_LNV3('R', '0', '0', TPACPI_FAN_NOACPI),/* E560 */
+ TPACPI_Q_LNV3('R', '1', '2', TPACPI_FAN_NOACPI),/* T495 */
+ TPACPI_Q_LNV3('R', '1', '3', TPACPI_FAN_NOACPI),/* T495s */
};
static int __init fan_init(struct ibm_init_struct *iibm)
@@ -8874,6 +8879,13 @@ static int __init fan_init(struct ibm_init_struct *iibm)
tp_features.fan_ctrl_status_undef = 1;
}
+ if (quirks & TPACPI_FAN_NOACPI) {
+ /* E560, T495, T495s */
+ pr_info("Ignoring buggy ACPI fan access method\n");
+ fang_handle = NULL;
+ fanw_handle = NULL;
+ }
+
if (gfan_handle) {
/* 570, 600e/x, 770e, 770x */
fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
@@ -11820,10 +11832,10 @@ static void thinkpad_acpi_module_exit(void)
platform_device_unregister(tpacpi_sensors_pdev);
}
- if (tpacpi_pdev) {
+ if (tp_features.platform_drv_registered)
platform_driver_unregister(&tpacpi_pdriver);
+ if (tpacpi_pdev)
platform_device_unregister(tpacpi_pdev);
- }
if (proc_dir)
remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
@@ -11893,9 +11905,8 @@ static int __init tpacpi_pdriver_probe(struct platform_device *pdev)
static int __init tpacpi_hwmon_pdriver_probe(struct platform_device *pdev)
{
- tpacpi_hwmon = devm_hwmon_device_register_with_groups(
- &tpacpi_sensors_pdev->dev, TPACPI_NAME, NULL, tpacpi_hwmon_groups);
-
+ tpacpi_hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, TPACPI_NAME,
+ NULL, tpacpi_hwmon_groups);
if (IS_ERR(tpacpi_hwmon))
pr_err("unable to register hwmon device\n");
@@ -11965,15 +11976,23 @@ static int __init thinkpad_acpi_module_init(void)
tp_features.quirks = dmi_id->driver_data;
/* Device initialization */
- tpacpi_pdev = platform_create_bundle(&tpacpi_pdriver, tpacpi_pdriver_probe,
- NULL, 0, NULL, 0);
+ tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, PLATFORM_DEVID_NONE,
+ NULL, 0);
if (IS_ERR(tpacpi_pdev)) {
ret = PTR_ERR(tpacpi_pdev);
tpacpi_pdev = NULL;
- pr_err("unable to register platform device/driver bundle\n");
+ pr_err("unable to register platform device\n");
+ thinkpad_acpi_module_exit();
+ return ret;
+ }
+
+ ret = platform_driver_probe(&tpacpi_pdriver, tpacpi_pdriver_probe);
+ if (ret) {
+ pr_err("unable to register main platform driver\n");
thinkpad_acpi_module_exit();
return ret;
}
+ tp_features.platform_drv_registered = 1;
tpacpi_sensors_pdev = platform_create_bundle(&tpacpi_hwmon_pdriver,
tpacpi_hwmon_pdriver_probe,
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index c43d8ad02529..d2ff76e74a05 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -843,6 +843,7 @@ EXPORT_SYMBOL(isapnp_protocol);
EXPORT_SYMBOL(isapnp_present);
EXPORT_SYMBOL(isapnp_cfg_begin);
EXPORT_SYMBOL(isapnp_cfg_end);
+EXPORT_SYMBOL(isapnp_read_byte);
EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_get_resources(struct pnp_dev *dev)
diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c
index a031eadb49dd..24eea7a91b30 100644
--- a/drivers/power/supply/ip5xxx_power.c
+++ b/drivers/power/supply/ip5xxx_power.c
@@ -828,10 +828,9 @@ static void ip5xxx_setup_regs(struct device *dev, struct ip5xxx *ip5xxx,
static int ip5xxx_power_probe(struct i2c_client *client)
{
- const struct ip5xxx_regfield_config *fields = &ip51xx_fields;
+ const struct ip5xxx_regfield_config *fields;
struct power_supply_config psy_cfg = {};
struct device *dev = &client->dev;
- const struct of_device_id *of_id;
struct power_supply *psy;
struct ip5xxx *ip5xxx;
@@ -843,9 +842,7 @@ static int ip5xxx_power_probe(struct i2c_client *client)
if (IS_ERR(ip5xxx->regmap))
return PTR_ERR(ip5xxx->regmap);
- of_id = i2c_of_match_device(dev->driver->of_match_table, client);
- if (of_id)
- fields = (const struct ip5xxx_regfield_config *)of_id->data;
+ fields = i2c_get_match_data(client) ?: &ip51xx_fields;
ip5xxx_setup_regs(dev, ip5xxx, fields);
psy_cfg.fwnode = dev_fwnode(dev);
diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
index 75c1bae30a7c..374ceefd6f2a 100644
--- a/drivers/pps/clients/pps-gpio.c
+++ b/drivers/pps/clients/pps-gpio.c
@@ -229,7 +229,7 @@ static void pps_gpio_remove(struct platform_device *pdev)
struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
pps_unregister_source(data->pps);
- del_timer_sync(&data->echo_timer);
+ timer_delete_sync(&data->echo_timer);
/* reset echo pin in any case */
gpiod_set_value(data->echo_pin, 0);
dev_info(&pdev->dev, "removed IRQ %d as PPS source\n", data->irq);
diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c
index 2f465549b843..121bd29d863d 100644
--- a/drivers/pps/clients/pps-ktimer.c
+++ b/drivers/pps/clients/pps-ktimer.c
@@ -58,7 +58,7 @@ static void __exit pps_ktimer_exit(void)
{
dev_dbg(&pps->dev, "ktimer PPS source unregistered\n");
- del_timer_sync(&ktimer);
+ timer_delete_sync(&ktimer);
pps_unregister_source(pps);
}
diff --git a/drivers/pps/generators/pps_gen-dummy.c b/drivers/pps/generators/pps_gen-dummy.c
index 55de4aecf35e..547fa7fe29f4 100644
--- a/drivers/pps/generators/pps_gen-dummy.c
+++ b/drivers/pps/generators/pps_gen-dummy.c
@@ -52,7 +52,7 @@ static int pps_gen_dummy_enable(struct pps_gen_device *pps_gen, bool enable)
if (enable)
mod_timer(&ktimer, jiffies + get_random_delay());
else
- del_timer_sync(&ktimer);
+ timer_delete_sync(&ktimer);
return 0;
}
@@ -73,7 +73,7 @@ static const struct pps_gen_source_info pps_gen_dummy_info = {
static void __exit pps_gen_dummy_exit(void)
{
- del_timer_sync(&ktimer);
+ timer_delete_sync(&ktimer);
pps_gen_unregister_source(pps_gen);
}
diff --git a/drivers/pps/generators/pps_gen_tio.c b/drivers/pps/generators/pps_gen_tio.c
index 6c46b46c66cd..1d5ffe055463 100644
--- a/drivers/pps/generators/pps_gen_tio.c
+++ b/drivers/pps/generators/pps_gen_tio.c
@@ -227,8 +227,8 @@ static int pps_gen_tio_probe(struct platform_device *pdev)
return PTR_ERR(tio->base);
pps_tio_disable(tio);
- hrtimer_init(&tio->timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
- tio->timer.function = hrtimer_callback;
+ hrtimer_setup(&tio->timer, hrtimer_callback, CLOCK_REALTIME,
+ HRTIMER_MODE_ABS);
spin_lock_init(&tio->lock);
platform_set_drvdata(pdev, &tio);
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index b25635c5c745..7945c6be1f7c 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -4499,7 +4499,7 @@ ptp_ocp_detach(struct ptp_ocp *bp)
ptp_ocp_detach_sysfs(bp);
ptp_ocp_attr_group_del(bp);
if (timer_pending(&bp->watchdog))
- del_timer_sync(&bp->watchdog);
+ timer_delete_sync(&bp->watchdog);
if (bp->ts0)
ptp_ocp_unregister_ext(bp->ts0);
if (bp->ts1)
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 7d82bd1b36df..1e8142479656 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
{
- int rid = rdev_get_id(rdev);
- int ctr_bit, reg;
+ unsigned int rid = rdev_get_id(rdev);
+ unsigned int ctr_bit, reg;
reg = RK806_POWER_FPWM_EN0 + rid / 8;
ctr_bit = rid % 8;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0bbbf778ecfa..838bdc138ffe 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1321,13 +1321,6 @@ config RTC_DRV_SPEAR
If you say Y here you will get support for the RTC found on
spear
-config RTC_DRV_PCF50633
- depends on MFD_PCF50633
- tristate "NXP PCF50633 RTC"
- help
- If you say yes here you get support for the RTC subsystem of the
- NXP PCF50633 used in embedded systems.
-
config RTC_DRV_AB8500
tristate "ST-Ericsson AB8500 RTC"
depends on AB8500_CORE
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 489b4ab07068..31473b3276d9 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -126,7 +126,6 @@ obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o
obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o
-obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o
diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c
index c4a3ab53dcd4..0eeae5bcc3aa 100644
--- a/drivers/rtc/dev.c
+++ b/drivers/rtc/dev.c
@@ -90,7 +90,7 @@ static int clear_uie(struct rtc_device *rtc)
rtc->stop_uie_polling = 1;
if (rtc->uie_timer_active) {
spin_unlock_irq(&rtc->irq_lock);
- del_timer_sync(&rtc->uie_timer);
+ timer_delete_sync(&rtc->uie_timer);
spin_lock_irq(&rtc->irq_lock);
rtc->uie_timer_active = 0;
}
diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index d2b60487d462..de002f7a39bf 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -426,29 +426,9 @@ static umode_t abeoz9_is_visible(const void *data,
}
}
-static const u32 abeoz9_chip_config[] = {
- HWMON_C_REGISTER_TZ,
- 0
-};
-
-static const struct hwmon_channel_info abeoz9_chip = {
- .type = hwmon_chip,
- .config = abeoz9_chip_config,
-};
-
-static const u32 abeoz9_temp_config[] = {
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN,
- 0
-};
-
-static const struct hwmon_channel_info abeoz9_temp = {
- .type = hwmon_temp,
- .config = abeoz9_temp_config,
-};
-
static const struct hwmon_channel_info * const abeoz9_info[] = {
- &abeoz9_chip,
- &abeoz9_temp,
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN),
NULL
};
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index 2dcda96f4a8e..ed2b6b8bb3bf 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -361,7 +361,7 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
return -ENODEV;
}
- device_init_wakeup(&pdev->dev, true);
+ devm_device_init_wakeup(&pdev->dev);
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
@@ -375,7 +375,7 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
if (err < 0)
return err;
- dev_pm_set_wake_irq(&pdev->dev, irq);
+ devm_pm_set_wake_irq(&pdev->dev, irq);
platform_set_drvdata(pdev, rtc);
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features);
@@ -392,18 +392,11 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
return devm_rtc_register_device(rtc);
}
-static void ab8500_rtc_remove(struct platform_device *pdev)
-{
- dev_pm_clear_wake_irq(&pdev->dev);
- device_init_wakeup(&pdev->dev, false);
-}
-
static struct platform_driver ab8500_rtc_driver = {
.driver = {
.name = "ab8500-rtc",
},
.probe = ab8500_rtc_probe,
- .remove = ab8500_rtc_remove,
.id_table = ab85xx_rtc_ids,
};
diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c
index 880b015eebaf..0d0053b52f9b 100644
--- a/drivers/rtc/rtc-aspeed.c
+++ b/drivers/rtc/rtc-aspeed.c
@@ -8,7 +8,6 @@
#include <linux/io.h>
struct aspeed_rtc {
- struct rtc_device *rtc_dev;
void __iomem *base;
};
@@ -85,6 +84,7 @@ static const struct rtc_class_ops aspeed_rtc_ops = {
static int aspeed_rtc_probe(struct platform_device *pdev)
{
struct aspeed_rtc *rtc;
+ struct rtc_device *rtc_dev;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
@@ -94,17 +94,17 @@ static int aspeed_rtc_probe(struct platform_device *pdev)
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
- rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(rtc->rtc_dev))
- return PTR_ERR(rtc->rtc_dev);
+ rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc_dev))
+ return PTR_ERR(rtc_dev);
platform_set_drvdata(pdev, rtc);
- rtc->rtc_dev->ops = &aspeed_rtc_ops;
- rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900;
- rtc->rtc_dev->range_max = 38814989399LL; /* 3199-12-31 23:59:59 */
+ rtc_dev->ops = &aspeed_rtc_ops;
+ rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900;
+ rtc_dev->range_max = 38814989399LL; /* 3199-12-31 23:59:59 */
- return devm_rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc_dev);
}
static const struct of_device_id aspeed_rtc_match[] = {
diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c
index 865c2e82c7a5..e956505a06fb 100644
--- a/drivers/rtc/rtc-cros-ec.c
+++ b/drivers/rtc/rtc-cros-ec.c
@@ -35,21 +35,18 @@ struct cros_ec_rtc {
static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command,
u32 *response)
{
+ DEFINE_RAW_FLEX(struct cros_ec_command, msg, data,
+ sizeof(struct ec_response_rtc));
int ret;
- struct {
- struct cros_ec_command msg;
- struct ec_response_rtc data;
- } __packed msg;
- memset(&msg, 0, sizeof(msg));
- msg.msg.command = command;
- msg.msg.insize = sizeof(msg.data);
+ msg->command = command;
+ msg->insize = sizeof(struct ec_response_rtc);
- ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
+ ret = cros_ec_cmd_xfer_status(cros_ec, msg);
if (ret < 0)
return ret;
- *response = msg.data.time;
+ *response = ((struct ec_response_rtc *)msg->data)->time;
return 0;
}
@@ -57,18 +54,15 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command,
static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command,
u32 param)
{
+ DEFINE_RAW_FLEX(struct cros_ec_command, msg, data,
+ sizeof(struct ec_response_rtc));
int ret;
- struct {
- struct cros_ec_command msg;
- struct ec_response_rtc data;
- } __packed msg;
- memset(&msg, 0, sizeof(msg));
- msg.msg.command = command;
- msg.msg.outsize = sizeof(msg.data);
- msg.data.time = param;
+ msg->command = command;
+ msg->outsize = sizeof(struct ec_response_rtc);
+ ((struct ec_response_rtc *)msg->data)->time = param;
- ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
+ ret = cros_ec_cmd_xfer_status(cros_ec, msg);
if (ret < 0)
return ret;
return 0;
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 872e0b679be4..5efbe69bf5ca 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1807,10 +1807,8 @@ static int ds1307_probe(struct i2c_client *client)
* For some variants, be sure alarms can trigger when we're
* running on Vbackup (BBSQI/BBSQW)
*/
- if (want_irq || ds1307_can_wakeup_device) {
+ if (want_irq || ds1307_can_wakeup_device)
regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit;
- regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
- }
regmap_write(ds1307->regmap, DS1337_REG_CONTROL,
regs[0]);
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index ed5a6ba89a3e..aa9500791b7e 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -427,18 +427,13 @@ static int ds1343_probe(struct spi_device *spi)
"unable to request irq for rtc ds1343\n");
} else {
device_init_wakeup(&spi->dev, true);
- dev_pm_set_wake_irq(&spi->dev, spi->irq);
+ devm_pm_set_wake_irq(&spi->dev, spi->irq);
}
}
return 0;
}
-static void ds1343_remove(struct spi_device *spi)
-{
- dev_pm_clear_wake_irq(&spi->dev);
-}
-
#ifdef CONFIG_PM_SLEEP
static int ds1343_suspend(struct device *dev)
@@ -471,7 +466,6 @@ static struct spi_driver ds1343_driver = {
.pm = &ds1343_pm,
},
.probe = ds1343_probe,
- .remove = ds1343_remove,
.id_table = ds1343_id,
};
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c
index 3231fd9f61da..217694eca36c 100644
--- a/drivers/rtc/rtc-ds2404.c
+++ b/drivers/rtc/rtc-ds2404.c
@@ -31,7 +31,6 @@ struct ds2404 {
struct gpio_desc *rst_gpiod;
struct gpio_desc *clk_gpiod;
struct gpio_desc *dq_gpiod;
- struct rtc_device *rtc;
};
static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev)
@@ -182,6 +181,7 @@ static const struct rtc_class_ops ds2404_rtc_ops = {
static int rtc_probe(struct platform_device *pdev)
{
struct ds2404 *chip;
+ struct rtc_device *rtc;
int retval = -EBUSY;
chip = devm_kzalloc(&pdev->dev, sizeof(struct ds2404), GFP_KERNEL);
@@ -190,9 +190,9 @@ static int rtc_probe(struct platform_device *pdev)
chip->dev = &pdev->dev;
- chip->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(chip->rtc))
- return PTR_ERR(chip->rtc);
+ rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
retval = ds2404_gpio_map(chip, pdev);
if (retval)
@@ -200,10 +200,10 @@ static int rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chip);
- chip->rtc->ops = &ds2404_rtc_ops;
- chip->rtc->range_max = U32_MAX;
+ rtc->ops = &ds2404_rtc_ops;
+ rtc->range_max = U32_MAX;
- retval = devm_rtc_register_device(chip->rtc);
+ retval = devm_rtc_register_device(rtc);
if (retval)
return retval;
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 19c09c418746..18f35823b4b5 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -339,29 +339,9 @@ static int ds3232_hwmon_read(struct device *dev,
return err;
}
-static u32 ds3232_hwmon_chip_config[] = {
- HWMON_C_REGISTER_TZ,
- 0
-};
-
-static const struct hwmon_channel_info ds3232_hwmon_chip = {
- .type = hwmon_chip,
- .config = ds3232_hwmon_chip_config,
-};
-
-static u32 ds3232_hwmon_temp_config[] = {
- HWMON_T_INPUT,
- 0
-};
-
-static const struct hwmon_channel_info ds3232_hwmon_temp = {
- .type = hwmon_temp,
- .config = ds3232_hwmon_temp_config,
-};
-
static const struct hwmon_channel_info * const ds3232_hwmon_info[] = {
- &ds3232_hwmon_chip,
- &ds3232_hwmon_temp,
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
NULL
};
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 1fdd20d01560..dcdcdd06f30d 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -28,7 +28,6 @@
struct ep93xx_rtc {
void __iomem *mmio_base;
- struct rtc_device *rtc;
};
static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
@@ -123,6 +122,7 @@ static const struct attribute_group ep93xx_rtc_sysfs_files = {
static int ep93xx_rtc_probe(struct platform_device *pdev)
{
struct ep93xx_rtc *ep93xx_rtc;
+ struct rtc_device *rtc;
int err;
ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
@@ -135,18 +135,18 @@ static int ep93xx_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ep93xx_rtc);
- ep93xx_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(ep93xx_rtc->rtc))
- return PTR_ERR(ep93xx_rtc->rtc);
+ rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- ep93xx_rtc->rtc->ops = &ep93xx_rtc_ops;
- ep93xx_rtc->rtc->range_max = U32_MAX;
+ rtc->ops = &ep93xx_rtc_ops;
+ rtc->range_max = U32_MAX;
- err = rtc_add_group(ep93xx_rtc->rtc, &ep93xx_rtc_sysfs_files);
+ err = rtc_add_group(rtc, &ep93xx_rtc_sysfs_files);
if (err)
return err;
- return devm_rtc_register_device(ep93xx_rtc->rtc);
+ return devm_rtc_register_device(rtc);
}
static const struct of_device_id ep93xx_rtc_of_ids[] = {
diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c
index a72c4ad0cec6..c8015f04c71f 100644
--- a/drivers/rtc/rtc-fsl-ftm-alarm.c
+++ b/drivers/rtc/rtc-fsl-ftm-alarm.c
@@ -309,7 +309,7 @@ static const struct of_device_id ftm_rtc_match[] = {
};
MODULE_DEVICE_TABLE(of, ftm_rtc_match);
-static const struct acpi_device_id ftm_imx_acpi_ids[] = {
+static const struct acpi_device_id ftm_imx_acpi_ids[] __maybe_unused = {
{"NXP0014",},
{ }
};
diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
index cb4a5d101f53..02608d378495 100644
--- a/drivers/rtc/rtc-ftrtc010.c
+++ b/drivers/rtc/rtc-ftrtc010.c
@@ -28,7 +28,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
struct ftrtc010_rtc {
- struct rtc_device *rtc_dev;
void __iomem *rtc_base;
int rtc_irq;
struct clk *pclk;
@@ -113,6 +112,7 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
struct ftrtc010_rtc *rtc;
struct device *dev = &pdev->dev;
struct resource *res;
+ struct rtc_device *rtc_dev;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
@@ -160,29 +160,28 @@ static int ftrtc010_rtc_probe(struct platform_device *pdev)
goto err_disable_extclk;
}
- rtc->rtc_dev = devm_rtc_allocate_device(dev);
- if (IS_ERR(rtc->rtc_dev)) {
- ret = PTR_ERR(rtc->rtc_dev);
+ rtc_dev = devm_rtc_allocate_device(dev);
+ if (IS_ERR(rtc_dev)) {
+ ret = PTR_ERR(rtc_dev);
goto err_disable_extclk;
}
- rtc->rtc_dev->ops = &ftrtc010_rtc_ops;
+ rtc_dev->ops = &ftrtc010_rtc_ops;
sec = readl(rtc->rtc_base + FTRTC010_RTC_SECOND);
min = readl(rtc->rtc_base + FTRTC010_RTC_MINUTE);
hour = readl(rtc->rtc_base + FTRTC010_RTC_HOUR);
days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
- rtc->rtc_dev->range_min = (u64)days * 86400 + hour * 3600 +
- min * 60 + sec;
- rtc->rtc_dev->range_max = U32_MAX + rtc->rtc_dev->range_min;
+ rtc_dev->range_min = (u64)days * 86400 + hour * 3600 + min * 60 + sec;
+ rtc_dev->range_max = U32_MAX + rtc_dev->range_min;
ret = devm_request_irq(dev, rtc->rtc_irq, ftrtc010_rtc_interrupt,
IRQF_SHARED, pdev->name, dev);
if (unlikely(ret))
goto err_disable_extclk;
- return devm_rtc_register_device(rtc->rtc_dev);
+ return devm_rtc_register_device(rtc_dev);
err_disable_extclk:
clk_disable_unprepare(rtc->extclk);
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index dd4a62e2d39c..10cd054fe86f 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -41,7 +41,6 @@
struct m48t86_rtc_info {
void __iomem *index_reg;
void __iomem *data_reg;
- struct rtc_device *rtc;
};
static unsigned char m48t86_readb(struct device *dev, unsigned long addr)
@@ -219,6 +218,7 @@ static bool m48t86_verify_chip(struct platform_device *pdev)
static int m48t86_rtc_probe(struct platform_device *pdev)
{
struct m48t86_rtc_info *info;
+ struct rtc_device *rtc;
unsigned char reg;
int err;
struct nvmem_config m48t86_nvmem_cfg = {
@@ -250,17 +250,17 @@ static int m48t86_rtc_probe(struct platform_device *pdev)
return -ENODEV;
}
- info->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(info->rtc))
- return PTR_ERR(info->rtc);
+ rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- info->rtc->ops = &m48t86_rtc_ops;
+ rtc->ops = &m48t86_rtc_ops;
- err = devm_rtc_register_device(info->rtc);
+ err = devm_rtc_register_device(rtc);
if (err)
return err;
- devm_rtc_nvmem_register(info->rtc, &m48t86_nvmem_cfg);
+ devm_rtc_nvmem_register(rtc, &m48t86_nvmem_cfg);
/* read battery status */
reg = m48t86_readb(&pdev->dev, M48T86_D);
diff --git a/drivers/rtc/rtc-max31335.c b/drivers/rtc/rtc-max31335.c
index 3fbcf5f6b92f..a7bb37aaab9e 100644
--- a/drivers/rtc/rtc-max31335.c
+++ b/drivers/rtc/rtc-max31335.c
@@ -184,31 +184,91 @@
#define MAX31335_RAM_SIZE 32
#define MAX31335_TIME_SIZE 0x07
+/* MAX31331 Register Map */
+#define MAX31331_RTC_CONFIG2 0x04
+
#define clk_hw_to_max31335(_hw) container_of(_hw, struct max31335_data, clkout)
+/* Supported Maxim RTC */
+enum max_rtc_ids {
+ ID_MAX31331,
+ ID_MAX31335,
+ MAX_RTC_ID_NR
+};
+
+struct chip_desc {
+ u8 sec_reg;
+ u8 alarm1_sec_reg;
+
+ u8 int_en_reg;
+ u8 int_status_reg;
+
+ u8 ram_reg;
+ u8 ram_size;
+
+ u8 temp_reg;
+
+ u8 trickle_reg;
+
+ u8 clkout_reg;
+
+ enum max_rtc_ids id;
+};
+
struct max31335_data {
struct regmap *regmap;
struct rtc_device *rtc;
struct clk_hw clkout;
+ struct clk *clkin;
+ const struct chip_desc *chip;
+ int irq;
};
static const int max31335_clkout_freq[] = { 1, 64, 1024, 32768 };
+static const struct chip_desc chip[MAX_RTC_ID_NR] = {
+ [ID_MAX31331] = {
+ .id = ID_MAX31331,
+ .int_en_reg = 0x01,
+ .int_status_reg = 0x00,
+ .sec_reg = 0x08,
+ .alarm1_sec_reg = 0x0F,
+ .ram_reg = 0x20,
+ .ram_size = 32,
+ .trickle_reg = 0x1B,
+ .clkout_reg = 0x04,
+ },
+ [ID_MAX31335] = {
+ .id = ID_MAX31335,
+ .int_en_reg = 0x01,
+ .int_status_reg = 0x00,
+ .sec_reg = 0x0A,
+ .alarm1_sec_reg = 0x11,
+ .ram_reg = 0x40,
+ .ram_size = 32,
+ .temp_reg = 0x35,
+ .trickle_reg = 0x1D,
+ .clkout_reg = 0x06,
+ },
+};
+
static const u16 max31335_trickle_resistors[] = {3000, 6000, 11000};
static bool max31335_volatile_reg(struct device *dev, unsigned int reg)
{
+ struct max31335_data *max31335 = dev_get_drvdata(dev);
+ const struct chip_desc *chip = max31335->chip;
+
/* time keeping registers */
- if (reg >= MAX31335_SECONDS &&
- reg < MAX31335_SECONDS + MAX31335_TIME_SIZE)
+ if (reg >= chip->sec_reg && reg < chip->sec_reg + MAX31335_TIME_SIZE)
return true;
/* interrupt status register */
- if (reg == MAX31335_STATUS1)
+ if (reg == chip->int_status_reg)
return true;
- /* temperature registers */
- if (reg == MAX31335_TEMP_DATA_MSB || reg == MAX31335_TEMP_DATA_LSB)
+ /* temperature registers if valid */
+ if (chip->temp_reg && (reg == chip->temp_reg || reg == chip->temp_reg + 1))
return true;
return false;
@@ -227,7 +287,7 @@ static int max31335_read_time(struct device *dev, struct rtc_time *tm)
u8 date[7];
int ret;
- ret = regmap_bulk_read(max31335->regmap, MAX31335_SECONDS, date,
+ ret = regmap_bulk_read(max31335->regmap, max31335->chip->sec_reg, date,
sizeof(date));
if (ret)
return ret;
@@ -262,7 +322,7 @@ static int max31335_set_time(struct device *dev, struct rtc_time *tm)
if (tm->tm_year >= 200)
date[5] |= FIELD_PREP(MAX31335_MONTH_CENTURY, 1);
- return regmap_bulk_write(max31335->regmap, MAX31335_SECONDS, date,
+ return regmap_bulk_write(max31335->regmap, max31335->chip->sec_reg, date,
sizeof(date));
}
@@ -273,7 +333,7 @@ static int max31335_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time time;
u8 regs[6];
- ret = regmap_bulk_read(max31335->regmap, MAX31335_ALM1_SEC, regs,
+ ret = regmap_bulk_read(max31335->regmap, max31335->chip->alarm1_sec_reg, regs,
sizeof(regs));
if (ret)
return ret;
@@ -292,11 +352,11 @@ static int max31335_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (time.tm_year >= 200)
alrm->time.tm_year += 100;
- ret = regmap_read(max31335->regmap, MAX31335_INT_EN1, &ctrl);
+ ret = regmap_read(max31335->regmap, max31335->chip->int_en_reg, &ctrl);
if (ret)
return ret;
- ret = regmap_read(max31335->regmap, MAX31335_STATUS1, &status);
+ ret = regmap_read(max31335->regmap, max31335->chip->int_status_reg, &status);
if (ret)
return ret;
@@ -320,18 +380,18 @@ static int max31335_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
regs[4] = bin2bcd(alrm->time.tm_mon + 1);
regs[5] = bin2bcd(alrm->time.tm_year % 100);
- ret = regmap_bulk_write(max31335->regmap, MAX31335_ALM1_SEC,
+ ret = regmap_bulk_write(max31335->regmap, max31335->chip->alarm1_sec_reg,
regs, sizeof(regs));
if (ret)
return ret;
reg = FIELD_PREP(MAX31335_INT_EN1_A1IE, alrm->enabled);
- ret = regmap_update_bits(max31335->regmap, MAX31335_INT_EN1,
+ ret = regmap_update_bits(max31335->regmap, max31335->chip->int_en_reg,
MAX31335_INT_EN1_A1IE, reg);
if (ret)
return ret;
- ret = regmap_update_bits(max31335->regmap, MAX31335_STATUS1,
+ ret = regmap_update_bits(max31335->regmap, max31335->chip->int_status_reg,
MAX31335_STATUS1_A1F, 0);
return 0;
@@ -341,23 +401,33 @@ static int max31335_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct max31335_data *max31335 = dev_get_drvdata(dev);
- return regmap_update_bits(max31335->regmap, MAX31335_INT_EN1,
+ return regmap_update_bits(max31335->regmap, max31335->chip->int_en_reg,
MAX31335_INT_EN1_A1IE, enabled);
}
static irqreturn_t max31335_handle_irq(int irq, void *dev_id)
{
struct max31335_data *max31335 = dev_id;
- bool status;
- int ret;
+ struct mutex *lock = &max31335->rtc->ops_lock;
+ int ret, status;
- ret = regmap_update_bits_check(max31335->regmap, MAX31335_STATUS1,
- MAX31335_STATUS1_A1F, 0, &status);
+ mutex_lock(lock);
+
+ ret = regmap_read(max31335->regmap, max31335->chip->int_status_reg, &status);
if (ret)
- return IRQ_HANDLED;
+ goto exit;
+
+ if (FIELD_GET(MAX31335_STATUS1_A1F, status)) {
+ ret = regmap_update_bits(max31335->regmap, max31335->chip->int_status_reg,
+ MAX31335_STATUS1_A1F, 0);
+ if (ret)
+ goto exit;
- if (status)
rtc_update_irq(max31335->rtc, 1, RTC_AF | RTC_IRQF);
+ }
+
+exit:
+ mutex_unlock(lock);
return IRQ_HANDLED;
}
@@ -404,7 +474,7 @@ static int max31335_trickle_charger_setup(struct device *dev,
i = i + trickle_cfg;
- return regmap_write(max31335->regmap, MAX31335_TRICKLE_REG,
+ return regmap_write(max31335->regmap, max31335->chip->trickle_reg,
FIELD_PREP(MAX31335_TRICKLE_REG_TRICKLE, i) |
FIELD_PREP(MAX31335_TRICKLE_REG_EN_TRICKLE,
chargeable));
@@ -418,7 +488,7 @@ static unsigned long max31335_clkout_recalc_rate(struct clk_hw *hw,
unsigned int reg;
int ret;
- ret = regmap_read(max31335->regmap, MAX31335_RTC_CONFIG2, &reg);
+ ret = regmap_read(max31335->regmap, max31335->chip->clkout_reg, &reg);
if (ret)
return 0;
@@ -449,23 +519,23 @@ static int max31335_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
ARRAY_SIZE(max31335_clkout_freq));
freq_mask = __roundup_pow_of_two(ARRAY_SIZE(max31335_clkout_freq)) - 1;
- return regmap_update_bits(max31335->regmap, MAX31335_RTC_CONFIG2,
- freq_mask, index);
+ return regmap_update_bits(max31335->regmap, max31335->chip->clkout_reg,
+ freq_mask, index);
}
static int max31335_clkout_enable(struct clk_hw *hw)
{
struct max31335_data *max31335 = clk_hw_to_max31335(hw);
- return regmap_set_bits(max31335->regmap, MAX31335_RTC_CONFIG2,
- MAX31335_RTC_CONFIG2_ENCLKO);
+ return regmap_set_bits(max31335->regmap, max31335->chip->clkout_reg,
+ MAX31335_RTC_CONFIG2_ENCLKO);
}
static void max31335_clkout_disable(struct clk_hw *hw)
{
struct max31335_data *max31335 = clk_hw_to_max31335(hw);
- regmap_clear_bits(max31335->regmap, MAX31335_RTC_CONFIG2,
+ regmap_clear_bits(max31335->regmap, max31335->chip->clkout_reg,
MAX31335_RTC_CONFIG2_ENCLKO);
}
@@ -475,7 +545,7 @@ static int max31335_clkout_is_enabled(struct clk_hw *hw)
unsigned int reg;
int ret;
- ret = regmap_read(max31335->regmap, MAX31335_RTC_CONFIG2, &reg);
+ ret = regmap_read(max31335->regmap, max31335->chip->clkout_reg, &reg);
if (ret)
return ret;
@@ -500,7 +570,7 @@ static int max31335_nvmem_reg_read(void *priv, unsigned int offset,
void *val, size_t bytes)
{
struct max31335_data *max31335 = priv;
- unsigned int reg = MAX31335_TS0_SEC_1_128 + offset;
+ unsigned int reg = max31335->chip->ram_reg + offset;
return regmap_bulk_read(max31335->regmap, reg, val, bytes);
}
@@ -509,7 +579,7 @@ static int max31335_nvmem_reg_write(void *priv, unsigned int offset,
void *val, size_t bytes)
{
struct max31335_data *max31335 = priv;
- unsigned int reg = MAX31335_TS0_SEC_1_128 + offset;
+ unsigned int reg = max31335->chip->ram_reg + offset;
return regmap_bulk_write(max31335->regmap, reg, val, bytes);
}
@@ -533,7 +603,7 @@ static int max31335_read_temp(struct device *dev, enum hwmon_sensor_types type,
if (type != hwmon_temp || attr != hwmon_temp_input)
return -EOPNOTSUPP;
- ret = regmap_bulk_read(max31335->regmap, MAX31335_TEMP_DATA_MSB,
+ ret = regmap_bulk_read(max31335->regmap, max31335->chip->temp_reg,
reg, 2);
if (ret)
return ret;
@@ -577,8 +647,8 @@ static int max31335_clkout_register(struct device *dev)
int ret;
if (!device_property_present(dev, "#clock-cells"))
- return regmap_clear_bits(max31335->regmap, MAX31335_RTC_CONFIG2,
- MAX31335_RTC_CONFIG2_ENCLKO);
+ return regmap_clear_bits(max31335->regmap, max31335->chip->clkout_reg,
+ MAX31335_RTC_CONFIG2_ENCLKO);
max31335->clkout.init = &max31335_clk_init;
@@ -605,6 +675,7 @@ static int max31335_probe(struct i2c_client *client)
#if IS_REACHABLE(HWMON)
struct device *hwmon;
#endif
+ const struct chip_desc *match;
int ret;
max31335 = devm_kzalloc(&client->dev, sizeof(*max31335), GFP_KERNEL);
@@ -616,7 +687,10 @@ static int max31335_probe(struct i2c_client *client)
return PTR_ERR(max31335->regmap);
i2c_set_clientdata(client, max31335);
-
+ match = i2c_get_match_data(client);
+ if (!match)
+ return -ENODEV;
+ max31335->chip = match;
max31335->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(max31335->rtc))
return PTR_ERR(max31335->rtc);
@@ -639,6 +713,8 @@ static int max31335_probe(struct i2c_client *client)
dev_warn(&client->dev,
"unable to request IRQ, alarm max31335 disabled\n");
client->irq = 0;
+ } else {
+ max31335->irq = client->irq;
}
}
@@ -652,13 +728,13 @@ static int max31335_probe(struct i2c_client *client)
"cannot register rtc nvmem\n");
#if IS_REACHABLE(HWMON)
- hwmon = devm_hwmon_device_register_with_info(&client->dev, client->name,
- max31335,
- &max31335_chip_info,
- NULL);
- if (IS_ERR(hwmon))
- return dev_err_probe(&client->dev, PTR_ERR(hwmon),
- "cannot register hwmon device\n");
+ if (max31335->chip->temp_reg) {
+ hwmon = devm_hwmon_device_register_with_info(&client->dev, client->name, max31335,
+ &max31335_chip_info, NULL);
+ if (IS_ERR(hwmon))
+ return dev_err_probe(&client->dev, PTR_ERR(hwmon),
+ "cannot register hwmon device\n");
+ }
#endif
ret = max31335_trickle_charger_setup(&client->dev, max31335);
@@ -669,14 +745,16 @@ static int max31335_probe(struct i2c_client *client)
}
static const struct i2c_device_id max31335_id[] = {
- { "max31335" },
+ { "max31331", (kernel_ulong_t)&chip[ID_MAX31331] },
+ { "max31335", (kernel_ulong_t)&chip[ID_MAX31335] },
{ }
};
MODULE_DEVICE_TABLE(i2c, max31335_id);
static const struct of_device_id max31335_of_match[] = {
- { .compatible = "adi,max31335" },
+ { .compatible = "adi,max31331", .data = &chip[ID_MAX31331] },
+ { .compatible = "adi,max31335", .data = &chip[ID_MAX31335] },
{ }
};
@@ -693,5 +771,6 @@ static struct i2c_driver max31335_driver = {
module_i2c_driver(max31335_driver);
MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
+MODULE_AUTHOR("Saket Kumar Purwar <Saket.Kumarpurwar@analog.com>");
MODULE_DESCRIPTION("MAX31335 RTC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 7bb044d2ac25..69ea3ce75b5a 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -85,7 +85,6 @@ struct max77686_rtc_driver_data {
struct max77686_rtc_info {
struct device *dev;
- struct i2c_client *rtc;
struct rtc_device *rtc_dev;
struct mutex lock;
@@ -691,6 +690,7 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
{
struct device *parent = info->dev->parent;
struct i2c_client *parent_i2c = to_i2c_client(parent);
+ struct i2c_client *client;
int ret;
if (info->drv_data->rtc_irq_from_platform) {
@@ -704,40 +704,35 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
}
info->regmap = dev_get_regmap(parent, NULL);
- if (!info->regmap) {
- dev_err(info->dev, "Failed to get rtc regmap\n");
- return -ENODEV;
- }
+ if (!info->regmap)
+ return dev_err_probe(info->dev, -ENODEV,
+ "Failed to get rtc regmap\n");
if (info->drv_data->rtc_i2c_addr == MAX77686_INVALID_I2C_ADDR) {
info->rtc_regmap = info->regmap;
goto add_rtc_irq;
}
- info->rtc = devm_i2c_new_dummy_device(info->dev, parent_i2c->adapter,
- info->drv_data->rtc_i2c_addr);
- if (IS_ERR(info->rtc)) {
- dev_err(info->dev, "Failed to allocate I2C device for RTC\n");
- return PTR_ERR(info->rtc);
- }
+ client = devm_i2c_new_dummy_device(info->dev, parent_i2c->adapter,
+ info->drv_data->rtc_i2c_addr);
+ if (IS_ERR(client))
+ return dev_err_probe(info->dev, PTR_ERR(client),
+ "Failed to allocate I2C device for RTC\n");
- info->rtc_regmap = devm_regmap_init_i2c(info->rtc,
+ info->rtc_regmap = devm_regmap_init_i2c(client,
info->drv_data->regmap_config);
- if (IS_ERR(info->rtc_regmap)) {
- ret = PTR_ERR(info->rtc_regmap);
- dev_err(info->dev, "Failed to allocate RTC regmap: %d\n", ret);
- return ret;
- }
+ if (IS_ERR(info->rtc_regmap))
+ return dev_err_probe(info->dev, PTR_ERR(info->rtc_regmap),
+ "Failed to allocate RTC regmap\n");
add_rtc_irq:
ret = regmap_add_irq_chip(info->rtc_regmap, info->rtc_irq,
IRQF_ONESHOT | IRQF_SHARED,
0, info->drv_data->rtc_irq_chip,
&info->rtc_irq_data);
- if (ret < 0) {
- dev_err(info->dev, "Failed to add RTC irq chip: %d\n", ret);
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(info->dev, ret,
+ "Failed to add RTC irq chip\n");
return 0;
}
diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c
index 5849729f7d01..7d38258cbe37 100644
--- a/drivers/rtc/rtc-meson-vrtc.c
+++ b/drivers/rtc/rtc-meson-vrtc.c
@@ -13,7 +13,6 @@
struct meson_vrtc_data {
void __iomem *io_alarm;
- struct rtc_device *rtc;
unsigned long alarm_time;
bool enabled;
};
@@ -65,6 +64,7 @@ static const struct rtc_class_ops meson_vrtc_ops = {
static int meson_vrtc_probe(struct platform_device *pdev)
{
struct meson_vrtc_data *vrtc;
+ struct rtc_device *rtc;
vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
if (!vrtc)
@@ -78,12 +78,12 @@ static int meson_vrtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, vrtc);
- vrtc->rtc = devm_rtc_allocate_device(&pdev->dev);
- if (IS_ERR(vrtc->rtc))
- return PTR_ERR(vrtc->rtc);
+ rtc = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- vrtc->rtc->ops = &meson_vrtc_ops;
- return devm_rtc_register_device(vrtc->rtc);
+ rtc->ops = &meson_vrtc_ops;
+ return devm_rtc_register_device(rtc);
}
static int __maybe_unused meson_vrtc_suspend(struct device *dev)
diff --git a/drivers/rtc/rtc-meson.c b/drivers/rtc/rtc-meson.c
index db1d626edca5..47e9ebf58ffc 100644
--- a/drivers/rtc/rtc-meson.c
+++ b/drivers/rtc/rtc-meson.c
@@ -59,7 +59,6 @@
#define MESON_STATIC_DEFAULT (MESON_STATIC_BIAS_CUR | MESON_STATIC_VOLTAGE)
struct meson_rtc {
- struct rtc_device *rtc; /* rtc device we created */
struct device *dev; /* device we bound from */
struct reset_control *reset; /* reset source */
struct regulator *vdd; /* voltage input */
@@ -292,6 +291,7 @@ static int meson_rtc_probe(struct platform_device *pdev)
};
struct device *dev = &pdev->dev;
struct meson_rtc *rtc;
+ struct rtc_device *rtc_dev;
void __iomem *base;
int ret;
u32 tm;
@@ -300,16 +300,16 @@ static int meson_rtc_probe(struct platform_device *pdev)
if (!rtc)
return -ENOMEM;
- rtc->rtc = devm_rtc_allocate_device(dev);
- if (IS_ERR(rtc->rtc))
- return PTR_ERR(rtc->rtc);
+ rtc_dev = devm_rtc_allocate_device(dev);
+ if (IS_ERR(rtc_dev))
+ return PTR_ERR(rtc_dev);
platform_set_drvdata(pdev, rtc);
rtc->dev = dev;
- rtc->rtc->ops = &meson_rtc_ops;
- rtc->rtc->range_max = U32_MAX;
+ rtc_dev->ops = &meson_rtc_ops;
+ rtc_dev->range_max = U32_MAX;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
@@ -365,11 +365,11 @@ static int meson_rtc_probe(struct platform_device *pdev)
}
meson_rtc_nvmem_config.priv = rtc;
- ret = devm_rtc_nvmem_register(rtc->rtc, &meson_rtc_nvmem_config);
+ ret = devm_rtc_nvmem_register(rtc_dev, &meson_rtc_nvmem_config);
if (ret)
goto out_disable_vdd;
- ret = devm_rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc_dev);
if (ret)
goto out_disable_vdd;
diff --git a/drivers/rtc/rtc-mpfs.c b/drivers/rtc/rtc-mpfs.c
index 3892b0f9917f..6aa3eae575d2 100644
--- a/drivers/rtc/rtc-mpfs.c
+++ b/drivers/rtc/rtc-mpfs.c
@@ -266,19 +266,14 @@ static int mpfs_rtc_probe(struct platform_device *pdev)
writel(prescaler, rtcdev->base + PRESCALER_REG);
dev_info(&pdev->dev, "prescaler set to: %lu\n", prescaler);
- device_init_wakeup(&pdev->dev, true);
- ret = dev_pm_set_wake_irq(&pdev->dev, wakeup_irq);
+ devm_device_init_wakeup(&pdev->dev);
+ ret = devm_pm_set_wake_irq(&pdev->dev, wakeup_irq);
if (ret)
dev_err(&pdev->dev, "failed to enable irq wake\n");
return devm_rtc_register_device(rtcdev->rtc);
}
-static void mpfs_rtc_remove(struct platform_device *pdev)
-{
- dev_pm_clear_wake_irq(&pdev->dev);
-}
-
static const struct of_device_id mpfs_rtc_of_match[] = {
{ .compatible = "microchip,mpfs-rtc" },
{ }
@@ -288,7 +283,6 @@ MODULE_DEVICE_TABLE(of, mpfs_rtc_of_match);
static struct platform_driver mpfs_rtc_driver = {
.probe = mpfs_rtc_probe,
- .remove = mpfs_rtc_remove,
.driver = {
.name = "mpfs_rtc",
.of_match_table = mpfs_rtc_of_match,
diff --git a/drivers/rtc/rtc-nxp-bbnsm.c b/drivers/rtc/rtc-nxp-bbnsm.c
index fa3b0328c7a2..d4fc9dc583d3 100644
--- a/drivers/rtc/rtc-nxp-bbnsm.c
+++ b/drivers/rtc/rtc-nxp-bbnsm.c
@@ -189,36 +189,26 @@ static int bbnsm_rtc_probe(struct platform_device *pdev)
/* clear all the pending events */
regmap_write(bbnsm->regmap, BBNSM_EVENTS, 0x7A);
- device_init_wakeup(&pdev->dev, true);
- dev_pm_set_wake_irq(&pdev->dev, bbnsm->irq);
+ ret = devm_device_init_wakeup(&pdev->dev);
+ if (ret)
+ dev_err(&pdev->dev, "failed to init wakeup, %d\n", ret);
+
+ ret = devm_pm_set_wake_irq(&pdev->dev, bbnsm->irq);
+ if (ret)
+ dev_err(&pdev->dev, "failed to set wake irq, %d\n", ret);
ret = devm_request_irq(&pdev->dev, bbnsm->irq, bbnsm_rtc_irq_handler,
IRQF_SHARED, "rtc alarm", &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "failed to request irq %d: %d\n",
bbnsm->irq, ret);
- goto err;
+ return ret;
}
bbnsm->rtc->ops = &bbnsm_rtc_ops;
bbnsm->rtc->range_max = U32_MAX;
- ret = devm_rtc_register_device(bbnsm->rtc);
- if (ret)
- goto err;
-
- return 0;
-
-err:
- dev_pm_clear_wake_irq(&pdev->dev);
- device_init_wakeup(&pdev->dev, false);
- return ret;
-}
-
-static void bbnsm_rtc_remove(struct platform_device *pdev)
-{
- dev_pm_clear_wake_irq(&pdev->dev);
- device_init_wakeup(&pdev->dev, false);
+ return devm_rtc_register_device(bbnsm->rtc);
}
static const struct of_device_id bbnsm_dt_ids[] = {
@@ -233,7 +223,6 @@ static struct platform_driver bbnsm_rtc_driver = {
.of_match_table = bbnsm_dt_ids,
},
.probe = bbnsm_rtc_probe,
- .remove = bbnsm_rtc_remove,
};
module_platform_driver(bbnsm_rtc_driver);
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
deleted file mode 100644
index c019c4d91c7d..000000000000
--- a/drivers/rtc/rtc-pcf50633.c
+++ /dev/null
@@ -1,284 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* NXP PCF50633 RTC Driver
- *
- * (C) 2006-2008 by Openmoko, Inc.
- * Author: Balaji Rao <balajirrao@openmoko.org>
- * All rights reserved.
- *
- * Broken down from monstrous PCF50633 driver mainly by
- * Harald Welte, Andy Green and Werner Almesberger
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/err.h>
-
-#include <linux/mfd/pcf50633/core.h>
-
-#define PCF50633_REG_RTCSC 0x59 /* Second */
-#define PCF50633_REG_RTCMN 0x5a /* Minute */
-#define PCF50633_REG_RTCHR 0x5b /* Hour */
-#define PCF50633_REG_RTCWD 0x5c /* Weekday */
-#define PCF50633_REG_RTCDT 0x5d /* Day */
-#define PCF50633_REG_RTCMT 0x5e /* Month */
-#define PCF50633_REG_RTCYR 0x5f /* Year */
-#define PCF50633_REG_RTCSCA 0x60 /* Alarm Second */
-#define PCF50633_REG_RTCMNA 0x61 /* Alarm Minute */
-#define PCF50633_REG_RTCHRA 0x62 /* Alarm Hour */
-#define PCF50633_REG_RTCWDA 0x63 /* Alarm Weekday */
-#define PCF50633_REG_RTCDTA 0x64 /* Alarm Day */
-#define PCF50633_REG_RTCMTA 0x65 /* Alarm Month */
-#define PCF50633_REG_RTCYRA 0x66 /* Alarm Year */
-
-enum pcf50633_time_indexes {
- PCF50633_TI_SEC,
- PCF50633_TI_MIN,
- PCF50633_TI_HOUR,
- PCF50633_TI_WKDAY,
- PCF50633_TI_DAY,
- PCF50633_TI_MONTH,
- PCF50633_TI_YEAR,
- PCF50633_TI_EXTENT /* always last */
-};
-
-struct pcf50633_time {
- u_int8_t time[PCF50633_TI_EXTENT];
-};
-
-struct pcf50633_rtc {
- int alarm_enabled;
- int alarm_pending;
-
- struct pcf50633 *pcf;
- struct rtc_device *rtc_dev;
-};
-
-static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf)
-{
- rtc->tm_sec = bcd2bin(pcf->time[PCF50633_TI_SEC]);
- rtc->tm_min = bcd2bin(pcf->time[PCF50633_TI_MIN]);
- rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]);
- rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]);
- rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]);
- rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]) - 1;
- rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100;
-}
-
-static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc)
-{
- pcf->time[PCF50633_TI_SEC] = bin2bcd(rtc->tm_sec);
- pcf->time[PCF50633_TI_MIN] = bin2bcd(rtc->tm_min);
- pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour);
- pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday);
- pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday);
- pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon + 1);
- pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100);
-}
-
-static int
-pcf50633_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct pcf50633_rtc *rtc = dev_get_drvdata(dev);
- int err;
-
- if (enabled)
- err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
- else
- err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
-
- if (err < 0)
- return err;
-
- rtc->alarm_enabled = enabled;
-
- return 0;
-}
-
-static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- struct pcf50633_rtc *rtc;
- struct pcf50633_time pcf_tm;
- int ret;
-
- rtc = dev_get_drvdata(dev);
-
- ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSC,
- PCF50633_TI_EXTENT,
- &pcf_tm.time[0]);
- if (ret != PCF50633_TI_EXTENT) {
- dev_err(dev, "Failed to read time\n");
- return -EIO;
- }
-
- dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
- pcf_tm.time[PCF50633_TI_DAY],
- pcf_tm.time[PCF50633_TI_MONTH],
- pcf_tm.time[PCF50633_TI_YEAR],
- pcf_tm.time[PCF50633_TI_HOUR],
- pcf_tm.time[PCF50633_TI_MIN],
- pcf_tm.time[PCF50633_TI_SEC]);
-
- pcf2rtc_time(tm, &pcf_tm);
-
- dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
-
- return 0;
-}
-
-static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct pcf50633_rtc *rtc;
- struct pcf50633_time pcf_tm;
- int alarm_masked, ret = 0;
-
- rtc = dev_get_drvdata(dev);
-
- dev_dbg(dev, "RTC_TIME: %ptRr\n", tm);
-
- rtc2pcf_time(&pcf_tm, tm);
-
- dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
- pcf_tm.time[PCF50633_TI_DAY],
- pcf_tm.time[PCF50633_TI_MONTH],
- pcf_tm.time[PCF50633_TI_YEAR],
- pcf_tm.time[PCF50633_TI_HOUR],
- pcf_tm.time[PCF50633_TI_MIN],
- pcf_tm.time[PCF50633_TI_SEC]);
-
-
- alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);
-
- if (!alarm_masked)
- pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
-
- /* Returns 0 on success */
- ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSC,
- PCF50633_TI_EXTENT,
- &pcf_tm.time[0]);
-
- if (!alarm_masked)
- pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
-
- return ret;
-}
-
-static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct pcf50633_rtc *rtc;
- struct pcf50633_time pcf_tm;
- int ret = 0;
-
- rtc = dev_get_drvdata(dev);
-
- alrm->enabled = rtc->alarm_enabled;
- alrm->pending = rtc->alarm_pending;
-
- ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA,
- PCF50633_TI_EXTENT, &pcf_tm.time[0]);
- if (ret != PCF50633_TI_EXTENT) {
- dev_err(dev, "Failed to read time\n");
- return -EIO;
- }
-
- pcf2rtc_time(&alrm->time, &pcf_tm);
-
- return rtc_valid_tm(&alrm->time);
-}
-
-static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
- struct pcf50633_rtc *rtc;
- struct pcf50633_time pcf_tm;
- int alarm_masked, ret = 0;
-
- rtc = dev_get_drvdata(dev);
-
- rtc2pcf_time(&pcf_tm, &alrm->time);
-
- /* do like mktime does and ignore tm_wday */
- pcf_tm.time[PCF50633_TI_WKDAY] = 7;
-
- alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);
-
- /* disable alarm interrupt */
- if (!alarm_masked)
- pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
-
- /* Returns 0 on success */
- ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
- PCF50633_TI_EXTENT, &pcf_tm.time[0]);
- if (!alrm->enabled)
- rtc->alarm_pending = 0;
-
- if (!alarm_masked || alrm->enabled)
- pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
- rtc->alarm_enabled = alrm->enabled;
-
- return ret;
-}
-
-static const struct rtc_class_ops pcf50633_rtc_ops = {
- .read_time = pcf50633_rtc_read_time,
- .set_time = pcf50633_rtc_set_time,
- .read_alarm = pcf50633_rtc_read_alarm,
- .set_alarm = pcf50633_rtc_set_alarm,
- .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable,
-};
-
-static void pcf50633_rtc_irq(int irq, void *data)
-{
- struct pcf50633_rtc *rtc = data;
-
- rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
- rtc->alarm_pending = 1;
-}
-
-static int pcf50633_rtc_probe(struct platform_device *pdev)
-{
- struct pcf50633_rtc *rtc;
-
- rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
- if (!rtc)
- return -ENOMEM;
-
- rtc->pcf = dev_to_pcf50633(pdev->dev.parent);
- platform_set_drvdata(pdev, rtc);
- rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "pcf50633-rtc",
- &pcf50633_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(rtc->rtc_dev))
- return PTR_ERR(rtc->rtc_dev);
-
- pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM,
- pcf50633_rtc_irq, rtc);
- return 0;
-}
-
-static void pcf50633_rtc_remove(struct platform_device *pdev)
-{
- struct pcf50633_rtc *rtc;
-
- rtc = platform_get_drvdata(pdev);
- pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM);
-}
-
-static struct platform_driver pcf50633_rtc_driver = {
- .driver = {
- .name = "pcf50633-rtc",
- },
- .probe = pcf50633_rtc_probe,
- .remove = pcf50633_rtc_remove,
-};
-
-module_platform_driver(pcf50633_rtc_driver);
-
-MODULE_DESCRIPTION("PCF50633 RTC driver");
-MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 905986c61655..4fa5c4ecdd5a 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -35,6 +35,7 @@
#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
#define PCF85063_REG_CTRL1_STOP BIT(5)
#define PCF85063_REG_CTRL1_EXT_TEST BIT(7)
+#define PCF85063_REG_CTRL1_SWR 0x58
#define PCF85063_REG_CTRL2 0x01
#define PCF85063_CTRL2_AF BIT(6)
@@ -589,16 +590,30 @@ static int pcf85063_probe(struct i2c_client *client)
i2c_set_clientdata(client, pcf85063);
- err = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL1, &tmp);
- if (err) {
- dev_err(&client->dev, "RTC chip is not present\n");
- return err;
- }
+ err = regmap_read(pcf85063->regmap, PCF85063_REG_SC, &tmp);
+ if (err)
+ return dev_err_probe(&client->dev, err, "RTC chip is not present\n");
pcf85063->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(pcf85063->rtc))
return PTR_ERR(pcf85063->rtc);
+ /*
+ * If a Power loss is detected, SW reset the device.
+ * From PCF85063A datasheet:
+ * There is a low probability that some devices will have corruption
+ * of the registers after the automatic power-on reset...
+ */
+ if (tmp & PCF85063_REG_SC_OS) {
+ dev_warn(&client->dev,
+ "POR issue detected, sending a SW reset\n");
+ err = regmap_write(pcf85063->regmap, PCF85063_REG_CTRL1,
+ PCF85063_REG_CTRL1_SWR);
+ if (err < 0)
+ dev_warn(&client->dev,
+ "SW reset failed, trying to continue\n");
+ }
+
err = pcf85063_load_capacitance(pcf85063, client->dev.of_node,
config->force_cap_7000 ? 7000 : 0);
if (err < 0)
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index 39038c0754ee..5caaa714f448 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -21,7 +21,6 @@
#define RTC_CR_MIE (1 << 0)
struct pl030_rtc {
- struct rtc_device *rtc;
void __iomem *base;
};
@@ -86,6 +85,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl030_rtc *rtc;
int ret;
+ struct rtc_device *rtc_dev;
ret = amba_request_regions(dev, NULL);
if (ret)
@@ -97,14 +97,14 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
goto err_rtc;
}
- rtc->rtc = devm_rtc_allocate_device(&dev->dev);
- if (IS_ERR(rtc->rtc)) {
- ret = PTR_ERR(rtc->rtc);
+ rtc_dev = devm_rtc_allocate_device(&dev->dev);
+ if (IS_ERR(rtc_dev)) {
+ ret = PTR_ERR(rtc_dev);
goto err_rtc;
}
- rtc->rtc->ops = &pl030_ops;
- rtc->rtc->range_max = U32_MAX;
+ rtc_dev->ops = &pl030_ops;
+ rtc_dev->range_max = U32_MAX;
rtc->base = ioremap(dev->res.start, resource_size(&dev->res));
if (!rtc->base) {
ret = -ENOMEM;
@@ -121,7 +121,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
goto err_irq;
- ret = devm_rtc_register_device(rtc->rtc);
+ ret = devm_rtc_register_device(rtc_dev);
if (ret)
goto err_reg;
@@ -148,7 +148,7 @@ static void pl030_remove(struct amba_device *dev)
amba_release_regions(dev);
}
-static struct amba_id pl030_ids[] = {
+static const struct amba_id pl030_ids[] = {
{
.id = 0x00041030,
.mask = 0x000fffff,
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index bad6a5d9c683..eab39dfa4e5f 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -74,6 +74,8 @@
* @st_weekday: if this is an ST Microelectronics silicon version that need
* the weekday fix
* @irqflags: special IRQ flags per variant
+ * @range_min: minimum date/time supported by the RTC
+ * @range_max: maximum date/time supported by the RTC
*/
struct pl031_vendor_data {
struct rtc_class_ops ops;
@@ -284,8 +286,6 @@ static void pl031_remove(struct amba_device *adev)
{
struct pl031_local *ldata = dev_get_drvdata(&adev->dev);
- dev_pm_clear_wake_irq(&adev->dev);
- device_init_wakeup(&adev->dev, false);
if (adev->irq[0])
free_irq(adev->irq[0], ldata);
amba_release_regions(adev);
@@ -350,7 +350,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
}
}
- device_init_wakeup(&adev->dev, true);
+ devm_device_init_wakeup(&adev->dev);
ldata->rtc = devm_rtc_allocate_device(&adev->dev);
if (IS_ERR(ldata->rtc)) {
ret = PTR_ERR(ldata->rtc);
@@ -373,7 +373,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
vendor->irqflags, "rtc-pl031", ldata);
if (ret)
goto out;
- dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
+ devm_pm_set_wake_irq(&adev->dev, adev->irq[0]);
}
return 0;
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index b2518aea4218..3c1dddcc81df 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -5,6 +5,7 @@
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2023, Linaro Limited
*/
+#include <linux/efi.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
@@ -16,9 +17,10 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-
#include <linux/unaligned.h>
+#include <asm/byteorder.h>
+
/* RTC_CTRL register bit fields */
#define PM8xxx_RTC_ENABLE BIT(7)
#define PM8xxx_RTC_ALARM_CLEAR BIT(0)
@@ -46,28 +48,125 @@ struct pm8xxx_rtc_regs {
unsigned int alarm_en;
};
+struct qcom_uefi_rtc_info {
+ __le32 offset_gps;
+ u8 reserved[8];
+} __packed;
+
/**
* struct pm8xxx_rtc - RTC driver internal structure
* @rtc: RTC device
* @regmap: regmap used to access registers
* @allow_set_time: whether the time can be set
+ * @use_uefi: use UEFI variable as fallback for offset
* @alarm_irq: alarm irq number
* @regs: register description
* @dev: device structure
+ * @rtc_info: qcom uefi rtc-info structure
* @nvmem_cell: nvmem cell for offset
* @offset: offset from epoch in seconds
+ * @offset_dirty: offset needs to be stored on shutdown
*/
struct pm8xxx_rtc {
struct rtc_device *rtc;
struct regmap *regmap;
bool allow_set_time;
+ bool use_uefi;
int alarm_irq;
const struct pm8xxx_rtc_regs *regs;
struct device *dev;
+ struct qcom_uefi_rtc_info rtc_info;
struct nvmem_cell *nvmem_cell;
u32 offset;
+ bool offset_dirty;
};
+#ifdef CONFIG_EFI
+
+MODULE_IMPORT_NS("EFIVAR");
+
+#define QCOM_UEFI_NAME L"RTCInfo"
+#define QCOM_UEFI_GUID EFI_GUID(0x882f8c2b, 0x9646, 0x435f, \
+ 0x8d, 0xe5, 0xf2, 0x08, 0xff, 0x80, 0xc1, 0xbd)
+#define QCOM_UEFI_ATTRS (EFI_VARIABLE_NON_VOLATILE | \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+ EFI_VARIABLE_RUNTIME_ACCESS)
+
+static int pm8xxx_rtc_read_uefi_offset(struct pm8xxx_rtc *rtc_dd)
+{
+ struct qcom_uefi_rtc_info *rtc_info = &rtc_dd->rtc_info;
+ unsigned long size = sizeof(*rtc_info);
+ struct device *dev = rtc_dd->dev;
+ efi_status_t status;
+ u32 offset_gps;
+ int rc;
+
+ rc = efivar_lock();
+ if (rc)
+ return rc;
+
+ status = efivar_get_variable(QCOM_UEFI_NAME, &QCOM_UEFI_GUID, NULL,
+ &size, rtc_info);
+ efivar_unlock();
+
+ if (status != EFI_SUCCESS) {
+ dev_dbg(dev, "failed to read UEFI offset: %lu\n", status);
+ return efi_status_to_err(status);
+ }
+
+ if (size != sizeof(*rtc_info)) {
+ dev_dbg(dev, "unexpected UEFI structure size %lu\n", size);
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "uefi_rtc_info = %*ph\n", (int)size, rtc_info);
+
+ /* Convert from GPS to Unix time offset */
+ offset_gps = le32_to_cpu(rtc_info->offset_gps);
+ rtc_dd->offset = offset_gps + (u32)RTC_TIMESTAMP_EPOCH_GPS;
+
+ return 0;
+}
+
+static int pm8xxx_rtc_write_uefi_offset(struct pm8xxx_rtc *rtc_dd, u32 offset)
+{
+ struct qcom_uefi_rtc_info *rtc_info = &rtc_dd->rtc_info;
+ unsigned long size = sizeof(*rtc_info);
+ struct device *dev = rtc_dd->dev;
+ efi_status_t status;
+ u32 offset_gps;
+
+ /* Convert from Unix to GPS time offset */
+ offset_gps = offset - (u32)RTC_TIMESTAMP_EPOCH_GPS;
+
+ rtc_info->offset_gps = cpu_to_le32(offset_gps);
+
+ dev_dbg(dev, "efi_rtc_info = %*ph\n", (int)size, rtc_info);
+
+ status = efivar_set_variable(QCOM_UEFI_NAME, &QCOM_UEFI_GUID,
+ QCOM_UEFI_ATTRS, size, rtc_info);
+ if (status != EFI_SUCCESS) {
+ dev_dbg(dev, "failed to write UEFI offset: %lx\n", status);
+ return efi_status_to_err(status);
+ }
+
+ return 0;
+}
+
+#else /* CONFIG_EFI */
+
+static int pm8xxx_rtc_read_uefi_offset(struct pm8xxx_rtc *rtc_dd)
+{
+ return -ENODEV;
+}
+
+static int pm8xxx_rtc_write_uefi_offset(struct pm8xxx_rtc *rtc_dd, u32 offset)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_EFI */
+
static int pm8xxx_rtc_read_nvmem_offset(struct pm8xxx_rtc *rtc_dd)
{
size_t len;
@@ -110,14 +209,6 @@ static int pm8xxx_rtc_write_nvmem_offset(struct pm8xxx_rtc *rtc_dd, u32 offset)
return 0;
}
-static int pm8xxx_rtc_read_offset(struct pm8xxx_rtc *rtc_dd)
-{
- if (!rtc_dd->nvmem_cell)
- return 0;
-
- return pm8xxx_rtc_read_nvmem_offset(rtc_dd);
-}
-
static int pm8xxx_rtc_read_raw(struct pm8xxx_rtc *rtc_dd, u32 *secs)
{
const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
@@ -155,7 +246,7 @@ static int pm8xxx_rtc_update_offset(struct pm8xxx_rtc *rtc_dd, u32 secs)
u32 offset;
int rc;
- if (!rtc_dd->nvmem_cell)
+ if (!rtc_dd->nvmem_cell && !rtc_dd->use_uefi)
return -ENODEV;
rc = pm8xxx_rtc_read_raw(rtc_dd, &raw_secs);
@@ -167,10 +258,25 @@ static int pm8xxx_rtc_update_offset(struct pm8xxx_rtc *rtc_dd, u32 secs)
if (offset == rtc_dd->offset)
return 0;
- rc = pm8xxx_rtc_write_nvmem_offset(rtc_dd, offset);
+ /*
+ * Reduce flash wear by deferring updates due to clock drift until
+ * shutdown.
+ */
+ if (abs_diff(offset, rtc_dd->offset) < 30) {
+ rtc_dd->offset_dirty = true;
+ goto out;
+ }
+
+ if (rtc_dd->nvmem_cell)
+ rc = pm8xxx_rtc_write_nvmem_offset(rtc_dd, offset);
+ else
+ rc = pm8xxx_rtc_write_uefi_offset(rtc_dd, offset);
+
if (rc)
return rc;
+ rtc_dd->offset_dirty = false;
+out:
rtc_dd->offset = offset;
return 0;
@@ -455,6 +561,30 @@ static const struct of_device_id pm8xxx_id_table[] = {
};
MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
+static int pm8xxx_rtc_probe_offset(struct pm8xxx_rtc *rtc_dd)
+{
+ int rc;
+
+ rtc_dd->nvmem_cell = devm_nvmem_cell_get(rtc_dd->dev, "offset");
+ if (IS_ERR(rtc_dd->nvmem_cell)) {
+ rc = PTR_ERR(rtc_dd->nvmem_cell);
+ if (rc != -ENOENT)
+ return rc;
+ rtc_dd->nvmem_cell = NULL;
+ } else {
+ return pm8xxx_rtc_read_nvmem_offset(rtc_dd);
+ }
+
+ /* Use UEFI storage as fallback if available */
+ if (efivar_is_available()) {
+ rc = pm8xxx_rtc_read_uefi_offset(rtc_dd);
+ if (rc == 0)
+ rtc_dd->use_uefi = true;
+ }
+
+ return 0;
+}
+
static int pm8xxx_rtc_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@@ -469,30 +599,23 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
if (rtc_dd == NULL)
return -ENOMEM;
+ rtc_dd->regs = match->data;
+ rtc_dd->dev = &pdev->dev;
+
rtc_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!rtc_dd->regmap)
return -ENXIO;
- rtc_dd->alarm_irq = platform_get_irq(pdev, 0);
- if (rtc_dd->alarm_irq < 0)
- return -ENXIO;
+ if (!of_property_read_bool(pdev->dev.of_node, "qcom,no-alarm")) {
+ rtc_dd->alarm_irq = platform_get_irq(pdev, 0);
+ if (rtc_dd->alarm_irq < 0)
+ return -ENXIO;
+ }
rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node,
"allow-set-time");
-
- rtc_dd->nvmem_cell = devm_nvmem_cell_get(&pdev->dev, "offset");
- if (IS_ERR(rtc_dd->nvmem_cell)) {
- rc = PTR_ERR(rtc_dd->nvmem_cell);
- if (rc != -ENOENT)
- return rc;
- rtc_dd->nvmem_cell = NULL;
- }
-
- rtc_dd->regs = match->data;
- rtc_dd->dev = &pdev->dev;
-
if (!rtc_dd->allow_set_time) {
- rc = pm8xxx_rtc_read_offset(rtc_dd);
+ rc = pm8xxx_rtc_probe_offset(rtc_dd);
if (rc)
return rc;
}
@@ -503,8 +626,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc_dd);
- device_init_wakeup(&pdev->dev, true);
-
rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc_dd->rtc))
return PTR_ERR(rtc_dd->rtc);
@@ -512,32 +633,41 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
rtc_dd->rtc->ops = &pm8xxx_rtc_ops;
rtc_dd->rtc->range_max = U32_MAX;
- rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq,
- pm8xxx_alarm_trigger,
- IRQF_TRIGGER_RISING,
- "pm8xxx_rtc_alarm", rtc_dd);
- if (rc < 0)
- return rc;
+ if (rtc_dd->alarm_irq) {
+ rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq,
+ pm8xxx_alarm_trigger,
+ IRQF_TRIGGER_RISING,
+ "pm8xxx_rtc_alarm", rtc_dd);
+ if (rc < 0)
+ return rc;
- rc = devm_rtc_register_device(rtc_dd->rtc);
- if (rc)
- return rc;
+ rc = devm_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
+ if (rc)
+ return rc;
- rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq);
- if (rc)
- return rc;
+ devm_device_init_wakeup(&pdev->dev);
+ } else {
+ clear_bit(RTC_FEATURE_ALARM, rtc_dd->rtc->features);
+ }
- return 0;
+ return devm_rtc_register_device(rtc_dd->rtc);
}
-static void pm8xxx_remove(struct platform_device *pdev)
+static void pm8xxx_shutdown(struct platform_device *pdev)
{
- dev_pm_clear_wake_irq(&pdev->dev);
+ struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev);
+
+ if (rtc_dd->offset_dirty) {
+ if (rtc_dd->nvmem_cell)
+ pm8xxx_rtc_write_nvmem_offset(rtc_dd, rtc_dd->offset);
+ else
+ pm8xxx_rtc_write_uefi_offset(rtc_dd, rtc_dd->offset);
+ }
}
static struct platform_driver pm8xxx_rtc_driver = {
.probe = pm8xxx_rtc_probe,
- .remove = pm8xxx_remove,
+ .shutdown = pm8xxx_shutdown,
.driver = {
.name = "rtc-pm8xxx",
.of_match_table = pm8xxx_id_table,
diff --git a/drivers/rtc/rtc-renesas-rtca3.c b/drivers/rtc/rtc-renesas-rtca3.c
index a056291d3887..ab816bdf0d77 100644
--- a/drivers/rtc/rtc-renesas-rtca3.c
+++ b/drivers/rtc/rtc-renesas-rtca3.c
@@ -586,17 +586,14 @@ static int rtca3_initial_setup(struct clk *clk, struct rtca3_priv *priv)
*/
usleep_range(sleep_us, sleep_us + 10);
- /* Disable all interrupts. */
- mask = RTCA3_RCR1_AIE | RTCA3_RCR1_CIE | RTCA3_RCR1_PIE;
- ret = rtca3_alarm_irq_set_helper(priv, mask, 0);
- if (ret)
- return ret;
-
mask = RTCA3_RCR2_START | RTCA3_RCR2_HR24;
val = readb(priv->base + RTCA3_RCR2);
- /* Nothing to do if already started in 24 hours and calendar count mode. */
- if ((val & mask) == mask)
- return 0;
+ /* Only disable the interrupts if already started in 24 hours and calendar count mode. */
+ if ((val & mask) == mask) {
+ /* Disable all interrupts. */
+ mask = RTCA3_RCR1_AIE | RTCA3_RCR1_CIE | RTCA3_RCR1_PIE;
+ return rtca3_alarm_irq_set_helper(priv, mask, 0);
+ }
/* Reconfigure the RTC in 24 hours and calendar count mode. */
mask = RTCA3_RCR2_START | RTCA3_RCR2_CNTMD;
diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c
index 35b2e36b426a..2c6a8918acba 100644
--- a/drivers/rtc/rtc-rv3032.c
+++ b/drivers/rtc/rtc-rv3032.c
@@ -69,8 +69,7 @@
#define RV3032_CLKOUT2_FD_MSK GENMASK(6, 5)
#define RV3032_CLKOUT2_OS BIT(7)
-#define RV3032_CTRL1_EERD BIT(3)
-#define RV3032_CTRL1_WADA BIT(5)
+#define RV3032_CTRL1_EERD BIT(2)
#define RV3032_CTRL2_STOP BIT(0)
#define RV3032_CTRL2_EIE BIT(2)
@@ -947,11 +946,6 @@ static int rv3032_probe(struct i2c_client *client)
if (!client->irq)
clear_bit(RTC_FEATURE_ALARM, rv3032->rtc->features);
- ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
- RV3032_CTRL1_WADA, RV3032_CTRL1_WADA);
- if (ret)
- return ret;
-
rv3032_trickle_charger_setup(&client->dev, rv3032);
set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3032->rtc->features);
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c
index b18c12887bdc..20c2dff01bae 100644
--- a/drivers/rtc/rtc-rx8581.c
+++ b/drivers/rtc/rtc-rx8581.c
@@ -52,11 +52,6 @@
#define RX8571_USER_RAM 0x10
#define RX8571_NVRAM_SIZE 0x10
-struct rx8581 {
- struct regmap *regmap;
- struct rtc_device *rtc;
-};
-
struct rx85x1_config {
struct regmap_config regmap;
unsigned int num_nvram;
@@ -72,14 +67,14 @@ static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm)
unsigned char date[7];
unsigned int data;
int err;
- struct rx8581 *rx8581 = i2c_get_clientdata(client);
+ struct regmap *regmap = i2c_get_clientdata(client);
/* First we ensure that the "update flag" is not set, we read the
* time and date then re-read the "update flag". If the update flag
* has been set, we know that the time has changed during the read so
* we repeat the whole process again.
*/
- err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
+ err = regmap_read(regmap, RX8581_REG_FLAG, &data);
if (err < 0)
return err;
@@ -92,20 +87,20 @@ static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm)
do {
/* If update flag set, clear it */
if (data & RX8581_FLAG_UF) {
- err = regmap_write(rx8581->regmap, RX8581_REG_FLAG,
- data & ~RX8581_FLAG_UF);
+ err = regmap_write(regmap, RX8581_REG_FLAG,
+ data & ~RX8581_FLAG_UF);
if (err < 0)
return err;
}
/* Now read time and date */
- err = regmap_bulk_read(rx8581->regmap, RX8581_REG_SC, date,
+ err = regmap_bulk_read(regmap, RX8581_REG_SC, date,
sizeof(date));
if (err < 0)
return err;
/* Check flag register */
- err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
+ err = regmap_read(regmap, RX8581_REG_FLAG, &data);
if (err < 0)
return err;
} while (data & RX8581_FLAG_UF);
@@ -137,7 +132,7 @@ static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct i2c_client *client = to_i2c_client(dev);
int err;
unsigned char buf[7];
- struct rx8581 *rx8581 = i2c_get_clientdata(client);
+ struct regmap *regmap = i2c_get_clientdata(client);
dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -160,25 +155,23 @@ static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[RX8581_REG_DW] = (0x1 << tm->tm_wday);
/* Stop the clock */
- err = regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
+ err = regmap_update_bits(regmap, RX8581_REG_CTRL,
RX8581_CTRL_STOP, RX8581_CTRL_STOP);
if (err < 0)
return err;
/* write register's data */
- err = regmap_bulk_write(rx8581->regmap, RX8581_REG_SC,
- buf, sizeof(buf));
+ err = regmap_bulk_write(regmap, RX8581_REG_SC, buf, sizeof(buf));
if (err < 0)
return err;
/* get VLF and clear it */
- err = regmap_update_bits(rx8581->regmap, RX8581_REG_FLAG,
- RX8581_FLAG_VLF, 0);
+ err = regmap_update_bits(regmap, RX8581_REG_FLAG, RX8581_FLAG_VLF, 0);
if (err < 0)
return err;
/* Restart the clock */
- return regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
+ return regmap_update_bits(regmap, RX8581_REG_CTRL,
RX8581_CTRL_STOP, 0);
}
@@ -190,29 +183,27 @@ static const struct rtc_class_ops rx8581_rtc_ops = {
static int rx8571_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- struct rx8581 *rx8581 = priv;
+ struct regmap *regmap = priv;
- return regmap_bulk_read(rx8581->regmap, RX8571_USER_RAM + offset,
- val, bytes);
+ return regmap_bulk_read(regmap, RX8571_USER_RAM + offset, val, bytes);
}
static int rx8571_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- struct rx8581 *rx8581 = priv;
+ struct regmap *regmap = priv;
- return regmap_bulk_write(rx8581->regmap, RX8571_USER_RAM + offset,
- val, bytes);
+ return regmap_bulk_write(regmap, RX8571_USER_RAM + offset, val, bytes);
}
static int rx85x1_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- struct rx8581 *rx8581 = priv;
+ struct regmap *regmap = priv;
unsigned int tmp_val;
int ret;
- ret = regmap_read(rx8581->regmap, RX8581_REG_RAM, &tmp_val);
+ ret = regmap_read(regmap, RX8581_REG_RAM, &tmp_val);
(*(unsigned char *)val) = (unsigned char) tmp_val;
return ret;
@@ -221,12 +212,11 @@ static int rx85x1_nvram_read(void *priv, unsigned int offset, void *val,
static int rx85x1_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{
- struct rx8581 *rx8581 = priv;
+ struct regmap *regmap = priv;
unsigned char tmp_val;
tmp_val = *((unsigned char *)val);
- return regmap_write(rx8581->regmap, RX8581_REG_RAM,
- (unsigned int)tmp_val);
+ return regmap_write(regmap, RX8581_REG_RAM, (unsigned int)tmp_val);
}
static const struct rx85x1_config rx8581_config = {
@@ -249,9 +239,10 @@ static const struct rx85x1_config rx8571_config = {
static int rx8581_probe(struct i2c_client *client)
{
- struct rx8581 *rx8581;
+ struct regmap *regmap;
const struct rx85x1_config *config = &rx8581_config;
const void *data = of_device_get_match_data(&client->dev);
+ struct rtc_device *rtc;
static struct nvmem_config nvmem_cfg[] = {
{
.name = "rx85x1-",
@@ -276,31 +267,27 @@ static int rx8581_probe(struct i2c_client *client)
if (data)
config = data;
- rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL);
- if (!rx8581)
- return -ENOMEM;
-
- i2c_set_clientdata(client, rx8581);
+ regmap = devm_regmap_init_i2c(client, &config->regmap);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
- rx8581->regmap = devm_regmap_init_i2c(client, &config->regmap);
- if (IS_ERR(rx8581->regmap))
- return PTR_ERR(rx8581->regmap);
+ i2c_set_clientdata(client, regmap);
- rx8581->rtc = devm_rtc_allocate_device(&client->dev);
- if (IS_ERR(rx8581->rtc))
- return PTR_ERR(rx8581->rtc);
+ rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- rx8581->rtc->ops = &rx8581_rtc_ops;
- rx8581->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
- rx8581->rtc->range_max = RTC_TIMESTAMP_END_2099;
- rx8581->rtc->start_secs = 0;
- rx8581->rtc->set_start_time = true;
+ rtc->ops = &rx8581_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
+ rtc->start_secs = 0;
+ rtc->set_start_time = true;
- ret = devm_rtc_register_device(rx8581->rtc);
+ ret = devm_rtc_register_device(rtc);
for (i = 0; i < config->num_nvram; i++) {
- nvmem_cfg[i].priv = rx8581;
- devm_rtc_nvmem_register(rx8581->rtc, &nvmem_cfg[i]);
+ nvmem_cfg[i].priv = regmap;
+ devm_rtc_nvmem_register(rtc, &nvmem_cfg[i]);
}
return ret;
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index cb220807d925..eeb9612a666f 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
+#include <linux/spinlock.h>
#define RZN1_RTC_CTL0 0x00
#define RZN1_RTC_CTL0_SLSB_SUBU 0
@@ -27,6 +28,7 @@
#define RZN1_RTC_CTL0_CE BIT(7)
#define RZN1_RTC_CTL1 0x04
+#define RZN1_RTC_CTL1_1SE BIT(3)
#define RZN1_RTC_CTL1_ALME BIT(4)
#define RZN1_RTC_CTL2 0x08
@@ -58,6 +60,13 @@
struct rzn1_rtc {
struct rtc_device *rtcdev;
void __iomem *base;
+ /*
+ * Protects access to RZN1_RTC_CTL1 reg. rtc_lock with threaded_irqs
+ * would introduce race conditions when switching interrupts because
+ * of potential sleeps
+ */
+ spinlock_t ctl1_access_lock;
+ struct rtc_time tm_alarm;
};
static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm)
@@ -135,8 +144,38 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
static irqreturn_t rzn1_rtc_alarm_irq(int irq, void *dev_id)
{
struct rzn1_rtc *rtc = dev_id;
+ u32 ctl1, set_irq_bits = 0;
+
+ if (rtc->tm_alarm.tm_sec == 0)
+ rtc_update_irq(rtc->rtcdev, 1, RTC_AF | RTC_IRQF);
+ else
+ /* Switch to 1s interrupts */
+ set_irq_bits = RZN1_RTC_CTL1_1SE;
- rtc_update_irq(rtc->rtcdev, 1, RTC_AF | RTC_IRQF);
+ guard(spinlock)(&rtc->ctl1_access_lock);
+
+ ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+ ctl1 &= ~RZN1_RTC_CTL1_ALME;
+ ctl1 |= set_irq_bits;
+ writel(ctl1, rtc->base + RZN1_RTC_CTL1);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rzn1_rtc_1s_irq(int irq, void *dev_id)
+{
+ struct rzn1_rtc *rtc = dev_id;
+ u32 ctl1;
+
+ if (readl(rtc->base + RZN1_RTC_SECC) == bin2bcd(rtc->tm_alarm.tm_sec)) {
+ guard(spinlock)(&rtc->ctl1_access_lock);
+
+ ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+ ctl1 &= ~RZN1_RTC_CTL1_1SE;
+ writel(ctl1, rtc->base + RZN1_RTC_CTL1);
+
+ rtc_update_irq(rtc->rtcdev, 1, RTC_AF | RTC_IRQF);
+ }
return IRQ_HANDLED;
}
@@ -144,14 +183,38 @@ static irqreturn_t rzn1_rtc_alarm_irq(int irq, void *dev_id)
static int rzn1_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
{
struct rzn1_rtc *rtc = dev_get_drvdata(dev);
- u32 ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+ struct rtc_time *tm = &rtc->tm_alarm, tm_now;
+ u32 ctl1;
+ int ret;
- if (enable)
- ctl1 |= RZN1_RTC_CTL1_ALME;
- else
- ctl1 &= ~RZN1_RTC_CTL1_ALME;
+ guard(spinlock_irqsave)(&rtc->ctl1_access_lock);
- writel(ctl1, rtc->base + RZN1_RTC_CTL1);
+ ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+
+ if (enable) {
+ /*
+ * Use alarm interrupt if alarm time is at least a minute away
+ * or less than a minute but in the next minute. Otherwise use
+ * 1 second interrupt to wait for the proper second
+ */
+ do {
+ ctl1 &= ~(RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE);
+
+ ret = rzn1_rtc_read_time(dev, &tm_now);
+ if (ret)
+ return ret;
+
+ if (rtc_tm_sub(tm, &tm_now) > 59 || tm->tm_min != tm_now.tm_min)
+ ctl1 |= RZN1_RTC_CTL1_ALME;
+ else
+ ctl1 |= RZN1_RTC_CTL1_1SE;
+
+ writel(ctl1, rtc->base + RZN1_RTC_CTL1);
+ } while (readl(rtc->base + RZN1_RTC_SECC) != bin2bcd(tm_now.tm_sec));
+ } else {
+ ctl1 &= ~(RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE);
+ writel(ctl1, rtc->base + RZN1_RTC_CTL1);
+ }
return 0;
}
@@ -185,7 +248,7 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
}
ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
- alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME);
+ alrm->enabled = !!(ctl1 & (RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE));
return 0;
}
@@ -216,6 +279,8 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH);
writel(BIT(wday), rtc->base + RZN1_RTC_ALW);
+ rtc->tm_alarm = alrm->time;
+
rzn1_rtc_alarm_irq_enable(dev, alrm->enabled);
return 0;
@@ -304,7 +369,7 @@ static const struct rtc_class_ops rzn1_rtc_ops = {
static int rzn1_rtc_probe(struct platform_device *pdev)
{
struct rzn1_rtc *rtc;
- int alarm_irq;
+ int irq;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
@@ -317,9 +382,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
if (IS_ERR(rtc->base))
return dev_err_probe(&pdev->dev, PTR_ERR(rtc->base), "Missing reg\n");
- alarm_irq = platform_get_irq(pdev, 0);
- if (alarm_irq < 0)
- return alarm_irq;
+ irq = platform_get_irq_byname(pdev, "alarm");
+ if (irq < 0)
+ return irq;
rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtcdev))
@@ -329,8 +394,6 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099;
rtc->rtcdev->alarm_offset_max = 7 * 86400;
rtc->rtcdev->ops = &rzn1_rtc_ops;
- set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
- clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
ret = devm_pm_runtime_enable(&pdev->dev);
if (ret < 0)
@@ -349,13 +412,24 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
/* Disable all interrupts */
writel(0, rtc->base + RZN1_RTC_CTL1);
- ret = devm_request_irq(&pdev->dev, alarm_irq, rzn1_rtc_alarm_irq, 0,
- dev_name(&pdev->dev), rtc);
+ spin_lock_init(&rtc->ctl1_access_lock);
+
+ ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
if (ret) {
- dev_err(&pdev->dev, "RTC timer interrupt not available\n");
+ dev_err(&pdev->dev, "RTC alarm interrupt not available\n");
goto dis_runtime_pm;
}
+ irq = platform_get_irq_byname_optional(pdev, "pps");
+ if (irq >= 0)
+ ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
+
+ if (irq < 0 || ret) {
+ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
+ dev_warn(&pdev->dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
+ }
+
ret = devm_rtc_register_device(rtc->rtcdev);
if (ret)
goto dis_runtime_pm;
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index e3dc18882f41..3408d2ab2741 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -63,7 +63,6 @@ MODULE_DEVICE_TABLE(of, s35390a_of_match);
struct s35390a {
struct i2c_client *client[8];
- struct rtc_device *rtc;
int twentyfourhour;
};
@@ -422,6 +421,7 @@ static int s35390a_probe(struct i2c_client *client)
int err, err_read;
unsigned int i;
struct s35390a *s35390a;
+ struct rtc_device *rtc;
char buf, status1;
struct device *dev = &client->dev;
@@ -447,9 +447,9 @@ static int s35390a_probe(struct i2c_client *client)
}
}
- s35390a->rtc = devm_rtc_allocate_device(dev);
- if (IS_ERR(s35390a->rtc))
- return PTR_ERR(s35390a->rtc);
+ rtc = devm_rtc_allocate_device(dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
err_read = s35390a_read_status(s35390a, &status1);
if (err_read < 0) {
@@ -480,17 +480,17 @@ static int s35390a_probe(struct i2c_client *client)
device_set_wakeup_capable(dev, 1);
- s35390a->rtc->ops = &s35390a_rtc_ops;
- s35390a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
- s35390a->rtc->range_max = RTC_TIMESTAMP_END_2099;
+ rtc->ops = &s35390a_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
- set_bit(RTC_FEATURE_ALARM_RES_MINUTE, s35390a->rtc->features);
- clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, s35390a->rtc->features );
+ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features);
+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
if (status1 & S35390A_FLAG_INT2)
- rtc_update_irq(s35390a->rtc, 1, RTC_AF);
+ rtc_update_irq(rtc, 1, RTC_AF);
- return devm_rtc_register_device(s35390a->rtc);
+ return devm_rtc_register_device(rtc);
}
static struct i2c_driver s35390a_driver = {
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index 36acca5b2639..db5c9b641277 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -146,7 +146,6 @@ static const struct s5m_rtc_reg_config s2mps15_rtc_regs = {
struct s5m_rtc_info {
struct device *dev;
- struct i2c_client *i2c;
struct sec_pmic_dev *s5m87xx;
struct regmap *regmap;
struct rtc_device *rtc_dev;
@@ -627,11 +626,10 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
}
info->rtc_24hr_mode = 1;
- if (ret < 0) {
- dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
- __func__, ret);
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(info->dev, ret,
+ "%s: fail to write controlm reg\n",
+ __func__);
return ret;
}
@@ -640,6 +638,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
{
struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
struct s5m_rtc_info *info;
+ struct i2c_client *i2c;
const struct regmap_config *regmap_cfg;
int ret, alarm_irq;
@@ -669,26 +668,21 @@ static int s5m_rtc_probe(struct platform_device *pdev)
alarm_irq = S5M8767_IRQ_RTCA1;
break;
default:
- dev_err(&pdev->dev,
- "Device type %lu is not supported by RTC driver\n",
- platform_get_device_id(pdev)->driver_data);
- return -ENODEV;
+ return dev_err_probe(&pdev->dev, -ENODEV,
+ "Device type %lu is not supported by RTC driver\n",
+ platform_get_device_id(pdev)->driver_data);
}
- info->i2c = devm_i2c_new_dummy_device(&pdev->dev, s5m87xx->i2c->adapter,
- RTC_I2C_ADDR);
- if (IS_ERR(info->i2c)) {
- dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
- return PTR_ERR(info->i2c);
- }
+ i2c = devm_i2c_new_dummy_device(&pdev->dev, s5m87xx->i2c->adapter,
+ RTC_I2C_ADDR);
+ if (IS_ERR(i2c))
+ return dev_err_probe(&pdev->dev, PTR_ERR(i2c),
+ "Failed to allocate I2C for RTC\n");
- info->regmap = devm_regmap_init_i2c(info->i2c, regmap_cfg);
- if (IS_ERR(info->regmap)) {
- ret = PTR_ERR(info->regmap);
- dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
- ret);
- return ret;
- }
+ info->regmap = devm_regmap_init_i2c(i2c, regmap_cfg);
+ if (IS_ERR(info->regmap))
+ return dev_err_probe(&pdev->dev, PTR_ERR(info->regmap),
+ "Failed to allocate RTC register map\n");
info->dev = &pdev->dev;
info->s5m87xx = s5m87xx;
@@ -696,11 +690,10 @@ static int s5m_rtc_probe(struct platform_device *pdev)
if (s5m87xx->irq_data) {
info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
- if (info->irq <= 0) {
- dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n",
- alarm_irq);
- return -EINVAL;
- }
+ if (info->irq <= 0)
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "Failed to get virtual IRQ %d\n",
+ alarm_irq);
}
platform_set_drvdata(pdev, info);
@@ -724,11 +717,10 @@ static int s5m_rtc_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
s5m_rtc_alarm_irq, 0, "rtc-alarm0",
info);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
- info->irq, ret);
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "Failed to request alarm IRQ %d\n",
+ info->irq);
device_init_wakeup(&pdev->dev, true);
}
diff --git a/drivers/rtc/rtc-sd2405al.c b/drivers/rtc/rtc-sd2405al.c
index d2568c3e3876..00c3033e8079 100644
--- a/drivers/rtc/rtc-sd2405al.c
+++ b/drivers/rtc/rtc-sd2405al.c
@@ -42,7 +42,6 @@
struct sd2405al {
struct device *dev;
- struct rtc_device *rtc;
struct regmap *regmap;
};
@@ -167,6 +166,7 @@ static const struct regmap_config sd2405al_regmap_conf = {
static int sd2405al_probe(struct i2c_client *client)
{
struct sd2405al *sd2405al;
+ struct rtc_device *rtc;
int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
@@ -182,17 +182,17 @@ static int sd2405al_probe(struct i2c_client *client)
if (IS_ERR(sd2405al->regmap))
return PTR_ERR(sd2405al->regmap);
- sd2405al->rtc = devm_rtc_allocate_device(&client->dev);
- if (IS_ERR(sd2405al->rtc))
- return PTR_ERR(sd2405al->rtc);
+ rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- sd2405al->rtc->ops = &sd2405al_rtc_ops;
- sd2405al->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
- sd2405al->rtc->range_max = RTC_TIMESTAMP_END_2099;
+ rtc->ops = &sd2405al_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
dev_set_drvdata(&client->dev, sd2405al);
- ret = devm_rtc_register_device(sd2405al->rtc);
+ ret = devm_rtc_register_device(rtc);
if (ret < 0)
return ret;
diff --git a/drivers/rtc/rtc-sd3078.c b/drivers/rtc/rtc-sd3078.c
index fe27b54beaad..10cc1dcfc774 100644
--- a/drivers/rtc/rtc-sd3078.c
+++ b/drivers/rtc/rtc-sd3078.c
@@ -36,11 +36,6 @@
*/
#define WRITE_PROTECT_EN 0
-struct sd3078 {
- struct rtc_device *rtc;
- struct regmap *regmap;
-};
-
/*
* In order to prevent arbitrary modification of the time register,
* when modification of the register,
@@ -49,14 +44,11 @@ struct sd3078 {
* 2. set WRITE2 bit
* 3. set WRITE3 bit
*/
-static void sd3078_enable_reg_write(struct sd3078 *sd3078)
+static void sd3078_enable_reg_write(struct regmap *regmap)
{
- regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL2,
- KEY_WRITE1, KEY_WRITE1);
- regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
- KEY_WRITE2, KEY_WRITE2);
- regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
- KEY_WRITE3, KEY_WRITE3);
+ regmap_update_bits(regmap, SD3078_REG_CTRL2, KEY_WRITE1, KEY_WRITE1);
+ regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE2, KEY_WRITE2);
+ regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE3, KEY_WRITE3);
}
#if WRITE_PROTECT_EN
@@ -69,14 +61,11 @@ static void sd3078_enable_reg_write(struct sd3078 *sd3078)
* 2. clear WRITE3 bit
* 3. clear WRITE1 bit
*/
-static void sd3078_disable_reg_write(struct sd3078 *sd3078)
+static void sd3078_disable_reg_write(struct regmap *regmap)
{
- regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
- KEY_WRITE2, 0);
- regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
- KEY_WRITE3, 0);
- regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL2,
- KEY_WRITE1, 0);
+ regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE2, 0);
+ regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE3, 0);
+ regmap_update_bits(regmap, SD3078_REG_CTRL2, KEY_WRITE1, 0);
}
#endif
@@ -85,11 +74,10 @@ static int sd3078_rtc_read_time(struct device *dev, struct rtc_time *tm)
unsigned char hour;
unsigned char rtc_data[NUM_TIME_REGS] = {0};
struct i2c_client *client = to_i2c_client(dev);
- struct sd3078 *sd3078 = i2c_get_clientdata(client);
+ struct regmap *regmap = i2c_get_clientdata(client);
int ret;
- ret = regmap_bulk_read(sd3078->regmap, SD3078_REG_SC, rtc_data,
- NUM_TIME_REGS);
+ ret = regmap_bulk_read(regmap, SD3078_REG_SC, rtc_data, NUM_TIME_REGS);
if (ret < 0) {
dev_err(dev, "reading from RTC failed with err:%d\n", ret);
return ret;
@@ -123,7 +111,7 @@ static int sd3078_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
unsigned char rtc_data[NUM_TIME_REGS];
struct i2c_client *client = to_i2c_client(dev);
- struct sd3078 *sd3078 = i2c_get_clientdata(client);
+ struct regmap *regmap = i2c_get_clientdata(client);
int ret;
rtc_data[SD3078_REG_SC] = bin2bcd(tm->tm_sec);
@@ -135,10 +123,10 @@ static int sd3078_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_data[SD3078_REG_YR] = bin2bcd(tm->tm_year - 100);
#if WRITE_PROTECT_EN
- sd3078_enable_reg_write(sd3078);
+ sd3078_enable_reg_write(regmap);
#endif
- ret = regmap_bulk_write(sd3078->regmap, SD3078_REG_SC, rtc_data,
+ ret = regmap_bulk_write(regmap, SD3078_REG_SC, rtc_data,
NUM_TIME_REGS);
if (ret < 0) {
dev_err(dev, "writing to RTC failed with err:%d\n", ret);
@@ -146,7 +134,7 @@ static int sd3078_rtc_set_time(struct device *dev, struct rtc_time *tm)
}
#if WRITE_PROTECT_EN
- sd3078_disable_reg_write(sd3078);
+ sd3078_disable_reg_write(regmap);
#endif
return 0;
@@ -166,36 +154,33 @@ static const struct regmap_config regmap_config = {
static int sd3078_probe(struct i2c_client *client)
{
int ret;
- struct sd3078 *sd3078;
+ struct regmap *regmap;
+ struct rtc_device *rtc;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
- sd3078 = devm_kzalloc(&client->dev, sizeof(*sd3078), GFP_KERNEL);
- if (!sd3078)
- return -ENOMEM;
-
- sd3078->regmap = devm_regmap_init_i2c(client, &regmap_config);
- if (IS_ERR(sd3078->regmap)) {
+ regmap = devm_regmap_init_i2c(client, &regmap_config);
+ if (IS_ERR(regmap)) {
dev_err(&client->dev, "regmap allocation failed\n");
- return PTR_ERR(sd3078->regmap);
+ return PTR_ERR(regmap);
}
- i2c_set_clientdata(client, sd3078);
+ i2c_set_clientdata(client, regmap);
- sd3078->rtc = devm_rtc_allocate_device(&client->dev);
- if (IS_ERR(sd3078->rtc))
- return PTR_ERR(sd3078->rtc);
+ rtc = devm_rtc_allocate_device(&client->dev);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
- sd3078->rtc->ops = &sd3078_rtc_ops;
- sd3078->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
- sd3078->rtc->range_max = RTC_TIMESTAMP_END_2099;
+ rtc->ops = &sd3078_rtc_ops;
+ rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ rtc->range_max = RTC_TIMESTAMP_END_2099;
- ret = devm_rtc_register_device(sd3078->rtc);
+ ret = devm_rtc_register_device(rtc);
if (ret)
return ret;
- sd3078_enable_reg_write(sd3078);
+ sd3078_enable_reg_write(regmap);
return 0;
}
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index a0564d443569..1b715db47160 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -1143,11 +1143,11 @@ static int stm32_rtc_probe(struct platform_device *pdev)
goto err;
}
- ret = device_init_wakeup(&pdev->dev, true);
+ ret = devm_device_init_wakeup(&pdev->dev);
if (ret)
goto err;
- ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm);
+ ret = devm_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm);
if (ret)
goto err;
@@ -1208,9 +1208,6 @@ err_no_rtc_ck:
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
- dev_pm_clear_wake_irq(&pdev->dev);
- device_init_wakeup(&pdev->dev, false);
-
return ret;
}
@@ -1237,9 +1234,6 @@ static void stm32_rtc_remove(struct platform_device *pdev)
/* Enable backup domain write protection if needed */
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
-
- dev_pm_clear_wake_irq(&pdev->dev);
- device_init_wakeup(&pdev->dev, false);
}
static int stm32_rtc_suspend(struct device *dev)
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index a68b8c884102..a9f5b9466fb5 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -44,7 +44,7 @@ static int test_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
timeout = rtc_tm_to_time64(&alrm->time) - ktime_get_real_seconds();
timeout -= rtd->offset;
- del_timer(&rtd->alarm);
+ timer_delete(&rtd->alarm);
expires = jiffies + timeout * HZ;
if (expires > U32_MAX)
@@ -86,7 +86,7 @@ static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
if (enable)
add_timer(&rtd->alarm);
else
- del_timer(&rtd->alarm);
+ timer_delete(&rtd->alarm);
return 0;
}
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 31bfb49588c2..cf36d3bafeca 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1507,7 +1507,7 @@ static void dasd_device_timeout(struct timer_list *t)
void dasd_device_set_timer(struct dasd_device *device, int expires)
{
if (expires == 0)
- del_timer(&device->timer);
+ timer_delete(&device->timer);
else
mod_timer(&device->timer, jiffies + expires);
}
@@ -1518,7 +1518,7 @@ EXPORT_SYMBOL(dasd_device_set_timer);
*/
void dasd_device_clear_timer(struct dasd_device *device)
{
- del_timer(&device->timer);
+ timer_delete(&device->timer);
}
EXPORT_SYMBOL(dasd_device_clear_timer);
@@ -2692,7 +2692,7 @@ static void dasd_block_timeout(struct timer_list *t)
void dasd_block_set_timer(struct dasd_block *block, int expires)
{
if (expires == 0)
- del_timer(&block->timer);
+ timer_delete(&block->timer);
else
mod_timer(&block->timer, jiffies + expires);
}
@@ -2703,7 +2703,7 @@ EXPORT_SYMBOL(dasd_block_set_timer);
*/
void dasd_block_clear_timer(struct dasd_block *block)
{
- del_timer(&block->timer);
+ timer_delete(&block->timer);
}
EXPORT_SYMBOL(dasd_block_clear_timer);
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 1a3190848670..34f3820d7f74 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -793,7 +793,7 @@ static void tty3270_deactivate(struct raw3270_view *view)
{
struct tty3270 *tp = container_of(view, struct tty3270, view);
- del_timer(&tp->timer);
+ timer_delete(&tp->timer);
}
static void tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb)
@@ -1060,7 +1060,7 @@ static void tty3270_free(struct raw3270_view *view)
{
struct tty3270 *tp = container_of(view, struct tty3270, view);
- del_timer_sync(&tp->timer);
+ timer_delete_sync(&tp->timer);
tty3270_free_screen(tp->screen, tp->allocated_lines);
free_page((unsigned long)tp->converted_line);
kfree(tp->input);
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 45bd001206a2..840be75e75d4 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -261,7 +261,7 @@ __sclp_queue_read_req(void)
static inline void
__sclp_set_request_timer(unsigned long time, void (*cb)(struct timer_list *))
{
- del_timer(&sclp_request_timer);
+ timer_delete(&sclp_request_timer);
sclp_request_timer.function = cb;
sclp_request_timer.expires = jiffies + time;
add_timer(&sclp_request_timer);
@@ -407,7 +407,7 @@ __sclp_start_request(struct sclp_req *req)
if (sclp_running_state != sclp_running_state_idle)
return 0;
- del_timer(&sclp_request_timer);
+ timer_delete(&sclp_request_timer);
rc = sclp_service_call_trace(req->command, req->sccb);
req->start_count++;
@@ -442,7 +442,7 @@ sclp_process_queue(void)
spin_unlock_irqrestore(&sclp_lock, flags);
return;
}
- del_timer(&sclp_request_timer);
+ timer_delete(&sclp_request_timer);
while (!list_empty(&sclp_req_queue)) {
req = list_entry(sclp_req_queue.next, struct sclp_req, list);
rc = __sclp_start_request(req);
@@ -662,7 +662,7 @@ static void sclp_interrupt_handler(struct ext_code ext_code,
!ok_response(finished_sccb, active_cmd));
if (finished_sccb) {
- del_timer(&sclp_request_timer);
+ timer_delete(&sclp_request_timer);
sclp_running_state = sclp_running_state_reset_pending;
req = __sclp_find_req(finished_sccb);
if (req) {
@@ -739,7 +739,7 @@ sclp_sync_wait(void)
/* Loop until driver state indicates finished request */
while (sclp_running_state != sclp_running_state_idle) {
/* Check for expired request timer */
- if (get_tod_clock_fast() > timeout && del_timer(&sclp_request_timer))
+ if (get_tod_clock_fast() > timeout && timer_delete(&sclp_request_timer))
sclp_request_timer.function(&sclp_request_timer);
cpu_relax();
}
@@ -1165,7 +1165,7 @@ sclp_check_interface(void)
* with IRQs enabled. */
irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
spin_lock_irqsave(&sclp_lock, flags);
- del_timer(&sclp_request_timer);
+ timer_delete(&sclp_request_timer);
rc = -EBUSY;
if (sclp_init_req.status == SCLP_REQ_DONE) {
if (sccb->header.response_code == 0x20) {
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index 6a030ba38bf3..d8544c485808 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -109,7 +109,7 @@ static void sclp_console_sync_queue(void)
unsigned long flags;
spin_lock_irqsave(&sclp_con_lock, flags);
- del_timer(&sclp_con_timer);
+ timer_delete(&sclp_con_timer);
while (sclp_con_queue_running) {
spin_unlock_irqrestore(&sclp_con_lock, flags);
sclp_sync_wait();
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 33b9c968dbcb..62979adcb381 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -231,7 +231,7 @@ sclp_vt220_emit_current(void)
list_add_tail(&sclp_vt220_current_request->list,
&sclp_vt220_outqueue);
sclp_vt220_current_request = NULL;
- del_timer(&sclp_vt220_timer);
+ timer_delete(&sclp_vt220_timer);
}
sclp_vt220_flush_later = 0;
}
@@ -798,7 +798,7 @@ sclp_vt220_notify(struct notifier_block *self,
sclp_vt220_emit_current();
spin_lock_irqsave(&sclp_vt220_lock, flags);
- del_timer(&sclp_vt220_timer);
+ timer_delete(&sclp_vt220_timer);
while (sclp_vt220_queue_running) {
spin_unlock_irqrestore(&sclp_vt220_lock, flags);
sclp_sync_wait();
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index ce8a440598a8..48e8417a5cff 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -1108,7 +1108,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
struct tape_request, list);
if (req->status == TAPE_REQUEST_LONG_BUSY) {
DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
- if (del_timer(&device->lb_timeout)) {
+ if (timer_delete(&device->lb_timeout)) {
tape_put_device(device);
__tape_start_next_request(device);
}
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index f7e75d9fedf6..b76038632883 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -73,7 +73,7 @@ tape_std_assign(struct tape_device *device)
rc = tape_do_io_interruptible(device, request);
- del_timer_sync(&request->timer);
+ timer_delete_sync(&request->timer);
if (rc != 0) {
DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 42791fa0b80e..e1b1fbdabb1b 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -115,7 +115,7 @@ void
ccw_device_set_timeout(struct ccw_device *cdev, int expires)
{
if (expires == 0)
- del_timer(&cdev->private->timer);
+ timer_delete(&cdev->private->timer);
else
mod_timer(&cdev->private->timer, jiffies + expires);
}
diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c
index 165de1552301..ac382355dc04 100644
--- a/drivers/s390/cio/eadm_sch.c
+++ b/drivers/s390/cio/eadm_sch.c
@@ -114,7 +114,7 @@ static void eadm_subchannel_set_timeout(struct subchannel *sch, int expires)
struct eadm_private *private = get_eadm_private(sch);
if (expires == 0)
- del_timer(&private->timer);
+ timer_delete(&private->timer);
else
mod_timer(&private->timer, jiffies + expires);
}
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index 9a0e6e4d8a5e..4088fda07197 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -1289,7 +1289,7 @@ void ap_queue_prepare_remove(struct ap_queue *aq)
/* move queue device state to SHUTDOWN in progress */
aq->dev_state = AP_DEV_STATE_SHUTDOWN;
spin_unlock_bh(&aq->lock);
- del_timer_sync(&aq->timeout);
+ timer_delete_sync(&aq->timeout);
}
void ap_queue_remove(struct ap_queue *aq)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index bc8669b5c304..766557547f83 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -873,48 +873,66 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
vfio_put_device(&matrix_mdev->vdev);
}
-#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
- "already assigned to %s"
+#define MDEV_SHARING_ERR "Userspace may not assign queue %02lx.%04lx to mdev: already assigned to %s"
-static void vfio_ap_mdev_log_sharing_err(struct ap_matrix_mdev *matrix_mdev,
- unsigned long *apm,
- unsigned long *aqm)
+#define MDEV_IN_USE_ERR "Can not reserve queue %02lx.%04lx for host driver: in use by mdev"
+
+static void vfio_ap_mdev_log_sharing_err(struct ap_matrix_mdev *assignee,
+ struct ap_matrix_mdev *assigned_to,
+ unsigned long *apm, unsigned long *aqm)
{
unsigned long apid, apqi;
- const struct device *dev = mdev_dev(matrix_mdev->mdev);
- const char *mdev_name = dev_name(dev);
- for_each_set_bit_inv(apid, apm, AP_DEVICES)
+ for_each_set_bit_inv(apid, apm, AP_DEVICES) {
+ for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) {
+ dev_warn(mdev_dev(assignee->mdev), MDEV_SHARING_ERR,
+ apid, apqi, dev_name(mdev_dev(assigned_to->mdev)));
+ }
+ }
+}
+
+static void vfio_ap_mdev_log_in_use_err(struct ap_matrix_mdev *assignee,
+ unsigned long *apm, unsigned long *aqm)
+{
+ unsigned long apid, apqi;
+
+ for_each_set_bit_inv(apid, apm, AP_DEVICES) {
for_each_set_bit_inv(apqi, aqm, AP_DOMAINS)
- dev_warn(dev, MDEV_SHARING_ERR, apid, apqi, mdev_name);
+ dev_warn(mdev_dev(assignee->mdev), MDEV_IN_USE_ERR, apid, apqi);
+ }
}
/**
* vfio_ap_mdev_verify_no_sharing - verify APQNs are not shared by matrix mdevs
*
+ * @assignee: the matrix mdev to which @mdev_apm and @mdev_aqm are being
+ * assigned; or, NULL if this function was called by the AP bus
+ * driver in_use callback to verify none of the APQNs being reserved
+ * for the host device driver are in use by a vfio_ap mediated device
* @mdev_apm: mask indicating the APIDs of the APQNs to be verified
* @mdev_aqm: mask indicating the APQIs of the APQNs to be verified
*
- * Verifies that each APQN derived from the Cartesian product of a bitmap of
- * AP adapter IDs and AP queue indexes is not configured for any matrix
- * mediated device. AP queue sharing is not allowed.
+ * Verifies that each APQN derived from the Cartesian product of APIDs
+ * represented by the bits set in @mdev_apm and the APQIs of the bits set in
+ * @mdev_aqm is not assigned to a mediated device other than the mdev to which
+ * the APQN is being assigned (@assignee). AP queue sharing is not allowed.
*
* Return: 0 if the APQNs are not shared; otherwise return -EADDRINUSE.
*/
-static int vfio_ap_mdev_verify_no_sharing(unsigned long *mdev_apm,
+static int vfio_ap_mdev_verify_no_sharing(struct ap_matrix_mdev *assignee,
+ unsigned long *mdev_apm,
unsigned long *mdev_aqm)
{
- struct ap_matrix_mdev *matrix_mdev;
+ struct ap_matrix_mdev *assigned_to;
DECLARE_BITMAP(apm, AP_DEVICES);
DECLARE_BITMAP(aqm, AP_DOMAINS);
- list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
+ list_for_each_entry(assigned_to, &matrix_dev->mdev_list, node) {
/*
- * If the input apm and aqm are fields of the matrix_mdev
- * object, then move on to the next matrix_mdev.
+ * If the mdev to which the mdev_apm and mdev_aqm is being
+ * assigned is the same as the mdev being verified
*/
- if (mdev_apm == matrix_mdev->matrix.apm &&
- mdev_aqm == matrix_mdev->matrix.aqm)
+ if (assignee == assigned_to)
continue;
memset(apm, 0, sizeof(apm));
@@ -924,15 +942,16 @@ static int vfio_ap_mdev_verify_no_sharing(unsigned long *mdev_apm,
* We work on full longs, as we can only exclude the leftover
* bits in non-inverse order. The leftover is all zeros.
*/
- if (!bitmap_and(apm, mdev_apm, matrix_mdev->matrix.apm,
- AP_DEVICES))
+ if (!bitmap_and(apm, mdev_apm, assigned_to->matrix.apm, AP_DEVICES))
continue;
- if (!bitmap_and(aqm, mdev_aqm, matrix_mdev->matrix.aqm,
- AP_DOMAINS))
+ if (!bitmap_and(aqm, mdev_aqm, assigned_to->matrix.aqm, AP_DOMAINS))
continue;
- vfio_ap_mdev_log_sharing_err(matrix_mdev, apm, aqm);
+ if (assignee)
+ vfio_ap_mdev_log_sharing_err(assignee, assigned_to, apm, aqm);
+ else
+ vfio_ap_mdev_log_in_use_err(assigned_to, apm, aqm);
return -EADDRINUSE;
}
@@ -961,7 +980,8 @@ static int vfio_ap_mdev_validate_masks(struct ap_matrix_mdev *matrix_mdev)
matrix_mdev->matrix.aqm))
return -EADDRNOTAVAIL;
- return vfio_ap_mdev_verify_no_sharing(matrix_mdev->matrix.apm,
+ return vfio_ap_mdev_verify_no_sharing(matrix_mdev,
+ matrix_mdev->matrix.apm,
matrix_mdev->matrix.aqm);
}
@@ -2516,7 +2536,7 @@ int vfio_ap_mdev_resource_in_use(unsigned long *apm, unsigned long *aqm)
mutex_lock(&matrix_dev->guests_lock);
mutex_lock(&matrix_dev->mdevs_lock);
- ret = vfio_ap_mdev_verify_no_sharing(apm, aqm);
+ ret = vfio_ap_mdev_verify_no_sharing(NULL, apm, aqm);
mutex_unlock(&matrix_dev->mdevs_lock);
mutex_unlock(&matrix_dev->guests_lock);
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index 8672d225ba77..5fcdce116862 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -158,7 +158,7 @@ fsm_deltimer(fsm_timer *this)
printk(KERN_DEBUG "fsm(%s): Delete timer %p\n", this->fi->name,
this);
#endif
- del_timer(&this->tl);
+ timer_delete(&this->tl);
}
int
@@ -188,7 +188,7 @@ fsm_modtimer(fsm_timer *this, int millisec, int event, void *arg)
this->fi->name, this, millisec);
#endif
- del_timer(&this->tl);
+ timer_delete(&this->tl);
timer_setup(&this->tl, fsm_expire_timer, 0);
this->expire_event = event;
this->event_arg = arg;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 20328d695ef9..f5cfaebfb7c9 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -7088,7 +7088,7 @@ int qeth_stop(struct net_device *dev)
netif_tx_disable(dev);
qeth_for_each_output_queue(card, queue, i) {
- del_timer_sync(&queue->timer);
+ timer_delete_sync(&queue->timer);
/* Queues may get re-allocated, so remove the NAPIs. */
netif_napi_del(&queue->napi);
}
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 99d6b3f8692b..d5f5f563881e 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -458,7 +458,7 @@ static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
return;
}
- del_timer_sync(&req->timer);
+ timer_delete_sync(&req->timer);
zfcp_fsf_protstatus_eval(req);
zfcp_fsf_fsfstatus_eval(req);
req->handler(req);
@@ -891,7 +891,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q_free);
req->issued = get_tod_clock();
if (zfcp_qdio_send(qdio, &req->qdio_req)) {
- del_timer_sync(&req->timer);
+ timer_delete_sync(&req->timer);
/* lookup request again, list might have changed */
if (zfcp_reqlist_find_rm(adapter->req_list, req_id) == NULL)
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 8cbc5e1711af..0957e3f8b46e 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -408,7 +408,7 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
tasklet_disable(&qdio->irq_tasklet);
tasklet_disable(&qdio->request_tasklet);
- del_timer_sync(&qdio->request_timer);
+ timer_delete_sync(&qdio->request_timer);
qdio_stop_irq(adapter->ccw_device);
qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 3e3100dbfda3..f9372a81cd4e 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -6181,7 +6181,7 @@ ahd_shutdown(void *arg)
/*
* Stop periodic timer callbacks.
*/
- del_timer_sync(&ahd->stat_timer);
+ timer_delete_sync(&ahd->stat_timer);
/* This will reset most registers to 0, but not all */
ahd_reset(ahd, /*reinit*/FALSE);
@@ -6975,7 +6975,7 @@ static const char *termstat_strings[] = {
static void
ahd_timer_reset(struct timer_list *timer, int usec)
{
- del_timer(timer);
+ timer_delete(timer);
timer->expires = jiffies + (usec * HZ)/1000000;
add_timer(timer);
}
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index 9dda296c0152..e74393357025 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -731,7 +731,7 @@ static void asd_dl_tasklet_handler(unsigned long data)
goto next_1;
} else if (ascb->scb->header.opcode == EMPTY_SCB) {
goto out;
- } else if (!ascb->uldd_timer && !del_timer(&ascb->timer)) {
+ } else if (!ascb->uldd_timer && !timer_delete(&ascb->timer)) {
goto next_1;
}
spin_lock_irqsave(&seq->pend_q_lock, flags);
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 538a5867e8ab..adf3d9145606 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -851,7 +851,7 @@ static void asd_free_queues(struct asd_ha_struct *asd_ha)
* times out. Apparently we don't wait for the CONTROL PHY
* to complete, so it doesn't matter if we kill the timer.
*/
- del_timer_sync(&ascb->timer);
+ timer_delete_sync(&ascb->timer);
WARN_ON(ascb->scb->header.opcode != CONTROL_PHY);
list_del_init(pos);
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 27d32b8c2987..d45dbf98f25e 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -31,7 +31,7 @@ static int asd_enqueue_internal(struct asd_ascb *ascb,
res = asd_post_ascb_list(ascb->ha, ascb, 1);
if (unlikely(res))
- del_timer(&ascb->timer);
+ timer_delete(&ascb->timer);
return res;
}
@@ -58,7 +58,7 @@ static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb,
{
struct tasklet_completion_status *tcs = ascb->uldd_task;
ASD_DPRINTK("%s: here\n", __func__);
- if (!del_timer(&ascb->timer)) {
+ if (!timer_delete(&ascb->timer)) {
ASD_DPRINTK("%s: couldn't delete timer\n", __func__);
return;
}
@@ -303,7 +303,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
{
struct tasklet_completion_status *tcs;
- if (!del_timer(&ascb->timer))
+ if (!timer_delete(&ascb->timer))
return;
tcs = ascb->uldd_task;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 221a520e8a9b..b450b1fc6bbb 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1161,8 +1161,8 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
out_free_sysfs:
if (set_date_time)
- del_timer_sync(&acb->refresh_timer);
- del_timer_sync(&acb->eternal_timer);
+ timer_delete_sync(&acb->refresh_timer);
+ timer_delete_sync(&acb->eternal_timer);
flush_work(&acb->arcmsr_do_message_isr_bh);
arcmsr_stop_adapter_bgrb(acb);
arcmsr_flush_adapter_cache(acb);
@@ -1204,9 +1204,9 @@ static int __maybe_unused arcmsr_suspend(struct device *dev)
arcmsr_disable_outbound_ints(acb);
arcmsr_free_irq(pdev, acb);
- del_timer_sync(&acb->eternal_timer);
+ timer_delete_sync(&acb->eternal_timer);
if (set_date_time)
- del_timer_sync(&acb->refresh_timer);
+ timer_delete_sync(&acb->refresh_timer);
flush_work(&acb->arcmsr_do_message_isr_bh);
arcmsr_stop_adapter_bgrb(acb);
arcmsr_flush_adapter_cache(acb);
@@ -1685,9 +1685,9 @@ static void arcmsr_free_pcidev(struct AdapterControlBlock *acb)
arcmsr_free_sysfs_attr(acb);
scsi_remove_host(host);
flush_work(&acb->arcmsr_do_message_isr_bh);
- del_timer_sync(&acb->eternal_timer);
+ timer_delete_sync(&acb->eternal_timer);
if (set_date_time)
- del_timer_sync(&acb->refresh_timer);
+ timer_delete_sync(&acb->refresh_timer);
pdev = acb->pdev;
arcmsr_free_irq(pdev, acb);
arcmsr_free_ccb_pool(acb);
@@ -1718,9 +1718,9 @@ static void arcmsr_remove(struct pci_dev *pdev)
arcmsr_free_sysfs_attr(acb);
scsi_remove_host(host);
flush_work(&acb->arcmsr_do_message_isr_bh);
- del_timer_sync(&acb->eternal_timer);
+ timer_delete_sync(&acb->eternal_timer);
if (set_date_time)
- del_timer_sync(&acb->refresh_timer);
+ timer_delete_sync(&acb->refresh_timer);
arcmsr_disable_outbound_ints(acb);
arcmsr_stop_adapter_bgrb(acb);
arcmsr_flush_adapter_cache(acb);
@@ -1765,9 +1765,9 @@ static void arcmsr_shutdown(struct pci_dev *pdev)
(struct AdapterControlBlock *)host->hostdata;
if (acb->acb_flags & ACB_F_ADAPTER_REMOVED)
return;
- del_timer_sync(&acb->eternal_timer);
+ timer_delete_sync(&acb->eternal_timer);
if (set_date_time)
- del_timer_sync(&acb->refresh_timer);
+ timer_delete_sync(&acb->refresh_timer);
arcmsr_disable_outbound_ints(acb);
arcmsr_free_irq(pdev, acb);
flush_work(&acb->arcmsr_do_message_isr_bh);
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 4ce0b2d73614..e0b55d869a35 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2331,7 +2331,7 @@ static void fas216_eh_timer(struct timer_list *t)
fas216_log(info, LOG_ERROR, "error handling timed out\n");
- del_timer(&info->eh_timer);
+ timer_delete(&info->eh_timer);
if (info->rst_bus_status == 0)
info->rst_bus_status = -1;
@@ -2532,7 +2532,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
*/
wait_event(info->eh_wait, info->rst_dev_status);
- del_timer_sync(&info->eh_timer);
+ timer_delete_sync(&info->eh_timer);
spin_lock_irqsave(&info->host_lock, flags);
info->rstSCpnt = NULL;
@@ -2622,7 +2622,7 @@ int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
* Wait one second for the interrupt.
*/
wait_event(info->eh_wait, info->rst_bus_status);
- del_timer_sync(&info->eh_timer);
+ timer_delete_sync(&info->eh_timer);
fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
info->rst_bus_status == 1 ? "success" : "failed");
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index a8b399ed98fc..7d1b767d87fb 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5448,7 +5448,7 @@ static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev,
"BM_%d : EEH error detected\n");
/* first stop UE detection when PCI error detected */
- del_timer_sync(&phba->hw_check);
+ timer_delete_sync(&phba->hw_check);
cancel_delayed_work_sync(&phba->recover_port);
/* sessions are no longer valid, so first fail the sessions */
@@ -5746,7 +5746,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
}
/* first stop UE detection before unloading */
- del_timer_sync(&phba->hw_check);
+ timer_delete_sync(&phba->hw_check);
cancel_delayed_work_sync(&phba->recover_port);
cancel_work_sync(&phba->sess_work);
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index f015c53de0d4..598f2fc93ef2 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -327,7 +327,7 @@ bfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event)
case BFAD_E_EXIT_COMP:
bfa_sm_set_state(bfad, bfad_sm_uninit);
bfad_remove_intr(bfad);
- del_timer_sync(&bfad->hal_tmo);
+ timer_delete_sync(&bfad->hal_tmo);
break;
default:
@@ -376,7 +376,7 @@ bfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event)
case BFAD_E_EXIT_COMP:
bfa_sm_set_state(bfad, bfad_sm_uninit);
bfad_remove_intr(bfad);
- del_timer_sync(&bfad->hal_tmo);
+ timer_delete_sync(&bfad->hal_tmo);
bfad_im_probe_undo(bfad);
bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
bfad_uncfg_pport(bfad);
@@ -1421,7 +1421,7 @@ bfad_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
/* Suspend/fail all bfa operations */
bfa_ioc_suspend(&bfad->bfa.ioc);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- del_timer_sync(&bfad->hal_tmo);
+ timer_delete_sync(&bfad->hal_tmo);
ret = PCI_ERS_RESULT_CAN_RECOVER;
break;
case pci_channel_io_frozen: /* fatal error */
@@ -1435,7 +1435,7 @@ bfad_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
wait_for_completion(&bfad->comp);
bfad_remove_intr(bfad);
- del_timer_sync(&bfad->hal_tmo);
+ timer_delete_sync(&bfad->hal_tmo);
pci_disable_device(pdev);
ret = PCI_ERS_RESULT_NEED_RESET;
break;
@@ -1566,7 +1566,7 @@ bfad_pci_mmio_enabled(struct pci_dev *pdev)
wait_for_completion(&bfad->comp);
bfad_remove_intr(bfad);
- del_timer_sync(&bfad->hal_tmo);
+ timer_delete_sync(&bfad->hal_tmo);
pci_disable_device(pdev);
return PCI_ERS_RESULT_NEED_RESET;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 5ac20c93637c..de6574cccf58 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -1599,7 +1599,7 @@ static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
struct bnx2fc_hba *hba = interface->hba;
/* Stop the transmit retry timer */
- del_timer_sync(&port->timer);
+ timer_delete_sync(&port->timer);
/* Free existing transmit skbs */
fcoe_clean_pending_queue(lport);
@@ -1938,7 +1938,7 @@ static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba)
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&hba->destroy_timer);
+ timer_delete_sync(&hba->destroy_timer);
}
bnx2fc_unbind_adapter_devices(hba);
}
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
index eb3209103312..b8227cfef64f 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
@@ -74,7 +74,7 @@ static void bnx2fc_ofld_wait(struct bnx2fc_rport *tgt)
&tgt->flags)));
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&tgt->ofld_timer);
+ timer_delete_sync(&tgt->ofld_timer);
}
static void bnx2fc_offload_session(struct fcoe_port *port,
@@ -283,7 +283,7 @@ static void bnx2fc_upld_wait(struct bnx2fc_rport *tgt)
&tgt->flags)));
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&tgt->upld_timer);
+ timer_delete_sync(&tgt->upld_timer);
}
static void bnx2fc_upload_session(struct fcoe_port *port,
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 9971f32a663c..6c80e5b514fd 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1626,7 +1626,7 @@ static int bnx2i_conn_start(struct iscsi_cls_conn *cls_conn)
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&bnx2i_conn->ep->ofld_timer);
+ timer_delete_sync(&bnx2i_conn->ep->ofld_timer);
iscsi_conn_start(cls_conn);
return 0;
@@ -1749,7 +1749,7 @@ static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&ep->ofld_timer);
+ timer_delete_sync(&ep->ofld_timer);
bnx2i_ep_destroy_list_del(hba, ep);
@@ -1861,7 +1861,7 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&bnx2i_ep->ofld_timer);
+ timer_delete_sync(&bnx2i_ep->ofld_timer);
bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
@@ -2100,7 +2100,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&bnx2i_ep->ofld_timer);
+ timer_delete_sync(&bnx2i_ep->ofld_timer);
destroy_conn:
bnx2i_ep_active_list_del(hba, bnx2i_ep);
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index e43c5413ce29..beded091dff1 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -3701,7 +3701,7 @@ csio_mberr_worker(void *data)
struct csio_mb *mbp_next;
int rv;
- del_timer_sync(&mbm->timer);
+ timer_delete_sync(&mbm->timer);
spin_lock_irq(&hw->lock);
if (list_empty(&mbm->cbfn_q)) {
@@ -4210,7 +4210,7 @@ csio_mgmtm_init(struct csio_mgmtm *mgmtm, struct csio_hw *hw)
static void
csio_mgmtm_exit(struct csio_mgmtm *mgmtm)
{
- del_timer_sync(&mgmtm->mgmt_timer);
+ timer_delete_sync(&mgmtm->mgmt_timer);
}
diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c
index 94810b19e747..c7b4c464f6b8 100644
--- a/drivers/scsi/csiostor/csio_mb.c
+++ b/drivers/scsi/csiostor/csio_mb.c
@@ -1619,7 +1619,7 @@ csio_mb_cancel_all(struct csio_hw *hw, struct list_head *cbfn_q)
mbp = mbm->mcurrent;
/* Stop mailbox completion timer */
- del_timer_sync(&mbm->timer);
+ timer_delete_sync(&mbm->timer);
/* Add completion to tail of cbfn queue */
list_add_tail(&mbp->list, cbfn_q);
@@ -1682,7 +1682,7 @@ csio_mbm_init(struct csio_mbm *mbm, struct csio_hw *hw,
void
csio_mbm_exit(struct csio_mbm *mbm)
{
- del_timer_sync(&mbm->timer);
+ timer_delete_sync(&mbm->timer);
CSIO_DB_ASSERT(mbm->mcurrent == NULL);
CSIO_DB_ASSERT(list_empty(&mbm->req_q));
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index ec6530240707..461d38e2fb19 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -495,7 +495,7 @@ static int do_act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
spin_lock_bh(&csk->lock);
if (csk->retry_timer.function) {
- del_timer(&csk->retry_timer);
+ timer_delete(&csk->retry_timer);
csk->retry_timer.function = NULL;
}
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index c07d2e3b4bcf..aaba294ecb58 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -930,7 +930,7 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
csk, csk->state, csk->flags, csk->tid);
if (csk->retry_timer.function) {
- del_timer(&csk->retry_timer);
+ timer_delete(&csk->retry_timer);
csk->retry_timer.function = NULL;
}
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index e71de2419758..8dc6be9a00c1 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -765,7 +765,7 @@ static void waiting_process_next(struct AdapterCtlBlk *acb)
return;
if (timer_pending(&acb->waiting_timer))
- del_timer(&acb->waiting_timer);
+ timer_delete(&acb->waiting_timer);
if (list_empty(dcb_list_head))
return;
@@ -1153,7 +1153,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
cmd, cmd->device->id, (u8)cmd->device->lun, cmd);
if (timer_pending(&acb->waiting_timer))
- del_timer(&acb->waiting_timer);
+ timer_delete(&acb->waiting_timer);
/*
* disable interrupt
@@ -1561,7 +1561,7 @@ static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb,
/*dprintkl(KERN_DEBUG, "handle_interrupt: intstatus = 0x%02x ", scsi_intstatus); */
if (timer_pending(&acb->selto_timer))
- del_timer(&acb->selto_timer);
+ timer_delete(&acb->selto_timer);
if (scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) {
disconnect(acb); /* bus free interrupt */
@@ -3454,7 +3454,7 @@ static void scsi_reset_detect(struct AdapterCtlBlk *acb)
dprintkl(KERN_INFO, "scsi_reset_detect: acb=%p\n", acb);
/* delay half a second */
if (timer_pending(&acb->waiting_timer))
- del_timer(&acb->waiting_timer);
+ timer_delete(&acb->waiting_timer);
DC395x_write8(acb, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE);
DC395x_write8(acb, TRM_S1040_DMA_CONTROL, DMARESETMODULE);
@@ -4415,9 +4415,9 @@ static void adapter_uninit(struct AdapterCtlBlk *acb)
/* remove timers */
if (timer_pending(&acb->waiting_timer))
- del_timer(&acb->waiting_timer);
+ timer_delete(&acb->waiting_timer);
if (timer_pending(&acb->selto_timer))
- del_timer(&acb->selto_timer);
+ timer_delete(&acb->selto_timer);
adapter_uninit_chip(acb);
adapter_remove_and_free_all_devices(acb);
diff --git a/drivers/scsi/elx/efct/efct_driver.c b/drivers/scsi/elx/efct/efct_driver.c
index 59f277593785..1bd42f7db177 100644
--- a/drivers/scsi/elx/efct/efct_driver.c
+++ b/drivers/scsi/elx/efct/efct_driver.c
@@ -310,7 +310,7 @@ efct_fw_reset(struct efct *efct)
* during attach.
*/
if (timer_pending(&efct->xport->stats_timer))
- del_timer(&efct->xport->stats_timer);
+ timer_delete(&efct->xport->stats_timer);
if (efct_hw_reset(&efct->hw, EFCT_HW_RESET_FIRMWARE)) {
efc_log_info(efct, "failed to reset firmware\n");
diff --git a/drivers/scsi/elx/efct/efct_xport.c b/drivers/scsi/elx/efct/efct_xport.c
index cf4dced20b8b..2aca60f6428e 100644
--- a/drivers/scsi/elx/efct/efct_xport.c
+++ b/drivers/scsi/elx/efct/efct_xport.c
@@ -508,7 +508,7 @@ efct_xport_detach(struct efct_xport *xport)
/*Shutdown FC Statistics timer*/
if (timer_pending(&xport->stats_timer))
- del_timer(&xport->stats_timer);
+ timer_delete(&xport->stats_timer);
efct_hw_teardown(&efct->hw);
diff --git a/drivers/scsi/elx/libefc/efc_fabric.c b/drivers/scsi/elx/libefc/efc_fabric.c
index 9661eea93aa1..cf7e738c4edc 100644
--- a/drivers/scsi/elx/libefc/efc_fabric.c
+++ b/drivers/scsi/elx/libefc/efc_fabric.c
@@ -888,7 +888,7 @@ gidpt_delay_timer_cb(struct timer_list *t)
{
struct efc_node *node = from_timer(node, t, gidpt_delay_timer);
- del_timer(&node->gidpt_delay_timer);
+ timer_delete(&node->gidpt_delay_timer);
efc_node_post_event(node, EFC_EVT_GIDPT_DELAY_EXPIRED, NULL);
}
diff --git a/drivers/scsi/elx/libefc/efc_node.c b/drivers/scsi/elx/libefc/efc_node.c
index a1b4ce6a27b4..f17e052fe537 100644
--- a/drivers/scsi/elx/libefc/efc_node.c
+++ b/drivers/scsi/elx/libefc/efc_node.c
@@ -149,7 +149,7 @@ efc_node_free(struct efc_node *node)
/* if the gidpt_delay_timer is still running, then delete it */
if (timer_pending(&node->gidpt_delay_timer))
- del_timer(&node->gidpt_delay_timer);
+ timer_delete(&node->gidpt_delay_timer);
xa_erase(&nport->lookup, node->rnode.fc_id);
diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c
index 0cea5f3d1a08..04a07fe57be2 100644
--- a/drivers/scsi/esas2r/esas2r_init.c
+++ b/drivers/scsi/esas2r/esas2r_init.c
@@ -439,7 +439,7 @@ static void esas2r_adapter_power_down(struct esas2r_adapter *a,
if ((test_bit(AF2_INIT_DONE, &a->flags2))
&& (!test_bit(AF_DEGRADED_MODE, &a->flags))) {
if (!power_management) {
- del_timer_sync(&a->timer);
+ timer_delete_sync(&a->timer);
tasklet_kill(&a->tasklet);
}
esas2r_power_down(a);
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 038e38578676..b911fdb387f3 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1013,7 +1013,7 @@ static void fcoe_if_destroy(struct fc_lport *lport)
fc_lport_destroy(lport);
/* Stop the transmit retry timer */
- del_timer_sync(&port->timer);
+ timer_delete_sync(&port->timer);
/* Free existing transmit skbs */
fcoe_clean_pending_queue(lport);
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 5c8d1ba3f8f3..56d270526c9c 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -302,7 +302,7 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
fcoe_ctlr_set_state(fip, FIP_ST_DISABLED);
fcoe_ctlr_reset_fcfs(fip);
mutex_unlock(&fip->ctlr_mutex);
- del_timer_sync(&fip->timer);
+ timer_delete_sync(&fip->timer);
cancel_work_sync(&fip->timer_work);
}
EXPORT_SYMBOL(fcoe_ctlr_destroy);
@@ -478,7 +478,7 @@ EXPORT_SYMBOL(fcoe_ctlr_link_up);
static void fcoe_ctlr_reset(struct fcoe_ctlr *fip)
{
fcoe_ctlr_reset_fcfs(fip);
- del_timer(&fip->timer);
+ timer_delete(&fip->timer);
fip->ctlr_ka_time = 0;
fip->port_ka_time = 0;
fip->sol_time = 0;
diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c
index 4c6bbf417a9a..c2b6f4eb338e 100644
--- a/drivers/scsi/fnic/fdls_disc.c
+++ b/drivers/scsi/fnic/fdls_disc.c
@@ -394,7 +394,7 @@ void fnic_del_fabric_timer_sync(struct fnic *fnic)
{
fnic->iport.fabric.del_timer_inprogress = 1;
spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
- del_timer_sync(&fnic->iport.fabric.retry_timer);
+ timer_delete_sync(&fnic->iport.fabric.retry_timer);
spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
fnic->iport.fabric.del_timer_inprogress = 0;
}
@@ -404,7 +404,7 @@ void fnic_del_tport_timer_sync(struct fnic *fnic,
{
tport->del_timer_inprogress = 1;
spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
- del_timer_sync(&tport->retry_timer);
+ timer_delete_sync(&tport->retry_timer);
spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
tport->del_timer_inprogress = 0;
}
@@ -3617,7 +3617,7 @@ static void fdls_process_fdmi_plogi_rsp(struct fnic_iport_s *iport,
fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_plogi);
if (ntoh24(fchdr->fh_s_id) == FC_FID_MGMT_SERV) {
- del_timer_sync(&iport->fabric.fdmi_timer);
+ timer_delete_sync(&iport->fabric.fdmi_timer);
iport->fabric.fdmi_pending = 0;
switch (plogi_rsp->els.fl_cmd) {
case ELS_LS_ACC:
@@ -3686,7 +3686,7 @@ static void fdls_process_fdmi_reg_ack(struct fnic_iport_s *iport,
iport->fcid);
if (!iport->fabric.fdmi_pending) {
- del_timer_sync(&iport->fabric.fdmi_timer);
+ timer_delete_sync(&iport->fabric.fdmi_timer);
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
"iport fcid: 0x%x: Canceling FDMI timer\n",
iport->fcid);
@@ -3728,7 +3728,7 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
break;
}
- del_timer_sync(&iport->fabric.fdmi_timer);
+ timer_delete_sync(&iport->fabric.fdmi_timer);
iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING;
fdls_send_fdmi_plogi(iport);
@@ -4971,7 +4971,7 @@ void fnic_fdls_link_down(struct fnic_iport_s *iport)
}
if ((fnic_fdmi_support == 1) && (iport->fabric.fdmi_pending > 0)) {
- del_timer_sync(&iport->fabric.fdmi_timer);
+ timer_delete_sync(&iport->fabric.fdmi_timer);
iport->fabric.fdmi_pending = 0;
}
diff --git a/drivers/scsi/fnic/fip.c b/drivers/scsi/fnic/fip.c
index 7bb85949033f..6e7c0b00eb41 100644
--- a/drivers/scsi/fnic/fip.c
+++ b/drivers/scsi/fnic/fip.c
@@ -319,7 +319,7 @@ void fnic_fcoe_fip_discovery_resp(struct fnic *fnic, struct fip_header *fiph)
round_jiffies(fcs_ka_tov));
} else {
if (timer_pending(&fnic->fcs_ka_timer))
- del_timer_sync(&fnic->fcs_ka_timer);
+ timer_delete_sync(&fnic->fcs_ka_timer);
}
if (fka_has_changed) {
@@ -497,7 +497,7 @@ void fnic_fcoe_process_flogi_resp(struct fnic *fnic, struct fip_header *fiph)
oxid = FNIC_STD_GET_OX_ID(fchdr);
fdls_free_oxid(iport, oxid, &iport->active_oxid_fabric_req);
- del_timer_sync(&fnic->retry_fip_timer);
+ timer_delete_sync(&fnic->retry_fip_timer);
if ((be16_to_cpu(flogi_rsp->fip.fip_dl_len) == FIP_FLOGI_LEN)
&& (flogi_rsp->rsp_desc.flogi.els.fl_cmd == ELS_LS_ACC)) {
@@ -580,10 +580,10 @@ void fnic_common_fip_cleanup(struct fnic *fnic)
iport->fip.state = FDLS_FIP_INIT;
- del_timer_sync(&fnic->retry_fip_timer);
- del_timer_sync(&fnic->fcs_ka_timer);
- del_timer_sync(&fnic->enode_ka_timer);
- del_timer_sync(&fnic->vn_ka_timer);
+ timer_delete_sync(&fnic->retry_fip_timer);
+ timer_delete_sync(&fnic->fcs_ka_timer);
+ timer_delete_sync(&fnic->enode_ka_timer);
+ timer_delete_sync(&fnic->vn_ka_timer);
if (!is_zero_ether_addr(iport->fpma))
vnic_dev_del_addr(fnic->vdev, iport->fpma);
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 3dd06376e97b..9a357ff42085 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -1149,20 +1149,20 @@ static void fnic_remove(struct pci_dev *pdev)
fnic_scsi_unload(fnic);
if (vnic_dev_get_intr_mode(fnic->vdev) == VNIC_DEV_INTR_MODE_MSI)
- del_timer_sync(&fnic->notify_timer);
+ timer_delete_sync(&fnic->notify_timer);
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
- del_timer_sync(&fnic->retry_fip_timer);
- del_timer_sync(&fnic->fcs_ka_timer);
- del_timer_sync(&fnic->enode_ka_timer);
- del_timer_sync(&fnic->vn_ka_timer);
+ timer_delete_sync(&fnic->retry_fip_timer);
+ timer_delete_sync(&fnic->fcs_ka_timer);
+ timer_delete_sync(&fnic->enode_ka_timer);
+ timer_delete_sync(&fnic->vn_ka_timer);
fnic_free_txq(&fnic->fip_frame_queue);
fnic_fcoe_reset_vlans(fnic);
}
if ((fnic_fdmi_support == 1) && (fnic->iport.fabric.fdmi_pending > 0))
- del_timer_sync(&fnic->iport.fabric.fdmi_timer);
+ timer_delete_sync(&fnic->iport.fabric.fdmi_timer);
fnic_stats_debugfs_remove(fnic);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 3596414d970b..5cb1d3db4907 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1548,7 +1548,7 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba)
* which is also only used for v1/v2 hw to skip it for v3 hw
*/
if (hisi_hba->hw->sht)
- del_timer_sync(&hisi_hba->timer);
+ timer_delete_sync(&hisi_hba->timer);
set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
}
@@ -2363,7 +2363,7 @@ void hisi_sas_free(struct hisi_hba *hisi_hba)
for (i = 0; i < hisi_hba->n_phy; i++) {
struct hisi_sas_phy *phy = &hisi_hba->phy[i];
- del_timer_sync(&phy->timer);
+ timer_delete_sync(&phy->timer);
}
if (hisi_hba->wq)
@@ -2625,7 +2625,7 @@ void hisi_sas_remove(struct platform_device *pdev)
struct hisi_hba *hisi_hba = sha->lldd_ha;
struct Scsi_Host *shost = sha->shost;
- del_timer_sync(&hisi_hba->timer);
+ timer_delete_sync(&hisi_hba->timer);
sas_unregister_ha(sha);
sas_remove_host(shost);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 04ee02797ca3..a1fc400ab4c3 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -2372,18 +2372,18 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
case STAT_IO_COMPLETE:
/* internal abort command complete */
ts->stat = TMF_RESP_FUNC_SUCC;
- del_timer_sync(&slot->internal_abort_timer);
+ timer_delete_sync(&slot->internal_abort_timer);
goto out;
case STAT_IO_NO_DEVICE:
ts->stat = TMF_RESP_FUNC_COMPLETE;
- del_timer_sync(&slot->internal_abort_timer);
+ timer_delete_sync(&slot->internal_abort_timer);
goto out;
case STAT_IO_NOT_VALID:
/* abort single io, controller don't find
* the io need to abort
*/
ts->stat = TMF_RESP_FUNC_FAILED;
- del_timer_sync(&slot->internal_abort_timer);
+ timer_delete_sync(&slot->internal_abort_timer);
goto out;
default:
break;
@@ -2654,7 +2654,7 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
if (is_sata_phy_v2_hw(hisi_hba, phy_no))
goto end;
- del_timer(&phy->timer);
+ timer_delete(&phy->timer);
if (phy_no == 8) {
u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);
@@ -2730,7 +2730,7 @@ static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
struct hisi_sas_port *port = phy->port;
struct device *dev = hisi_hba->dev;
- del_timer(&phy->timer);
+ timer_delete(&phy->timer);
hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1);
phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
@@ -2744,7 +2744,7 @@ static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
if (port && !get_wideport_bitmap_v2_hw(hisi_hba, port->id))
if (!check_any_wideports_v2_hw(hisi_hba) &&
timer_pending(&hisi_hba->timer))
- del_timer(&hisi_hba->timer);
+ timer_delete(&hisi_hba->timer);
txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO);
hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,
@@ -3204,7 +3204,7 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
int phy_no, offset;
- del_timer(&phy->timer);
+ timer_delete(&phy->timer);
phy_no = sas_phy->id;
initial_fis = &hisi_hba->initial_fis[phy_no];
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 095bbf80c34e..2684d6482067 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -1609,7 +1609,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
phy->port_id = port_id;
spin_lock(&phy->lock);
/* Delete timer and set phy_attached atomically */
- del_timer(&phy->timer);
+ timer_delete(&phy->timer);
phy->phy_attached = 1;
spin_unlock(&phy->lock);
@@ -1643,7 +1643,7 @@ static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
atomic_inc(&phy->down_cnt);
- del_timer(&phy->timer);
+ timer_delete(&phy->timer);
hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1);
phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 773ec2f31bc4..4c493b06062a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1110,7 +1110,7 @@ static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code)
} else
evt->xfer_iu->mad_common.status = cpu_to_be16(IBMVFC_MAD_DRIVER_FAILED);
- del_timer(&evt->timer);
+ timer_delete(&evt->timer);
}
/**
@@ -1754,7 +1754,7 @@ static int ibmvfc_send_event(struct ibmvfc_event *evt,
atomic_set(&evt->active, 0);
list_del(&evt->queue_list);
spin_unlock_irqrestore(&evt->queue->l_lock, flags);
- del_timer(&evt->timer);
+ timer_delete(&evt->timer);
/* If send_crq returns H_CLOSED, return SCSI_MLQUEUE_HOST_BUSY.
* Firmware will send a CRQ with a transport event (0xFF) to
@@ -3832,7 +3832,7 @@ static void ibmvfc_tasklet(void *data)
spin_unlock_irqrestore(vhost->host->host_lock, flags);
list_for_each_entry_safe(evt, temp, &evt_doneq, queue_list) {
- del_timer(&evt->timer);
+ timer_delete(&evt->timer);
list_del(&evt->queue_list);
ibmvfc_trc_end(evt);
evt->done(evt);
@@ -3938,7 +3938,7 @@ static void ibmvfc_drain_sub_crq(struct ibmvfc_queue *scrq)
spin_unlock_irqrestore(scrq->q_lock, flags);
list_for_each_entry_safe(evt, temp, &evt_doneq, queue_list) {
- del_timer(&evt->timer);
+ timer_delete(&evt->timer);
list_del(&evt->queue_list);
ibmvfc_trc_end(evt);
evt->done(evt);
@@ -4542,7 +4542,7 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
vhost->discovery_threads--;
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
- del_timer(&tgt->timer);
+ timer_delete(&tgt->timer);
switch (status) {
case IBMVFC_MAD_SUCCESS:
@@ -4741,7 +4741,7 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
if (ibmvfc_send_event(evt, vhost, IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT)) {
vhost->discovery_threads--;
- del_timer(&tgt->timer);
+ timer_delete(&tgt->timer);
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
kref_put(&tgt->kref, ibmvfc_release_tgt);
} else
@@ -5519,7 +5519,7 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
fc_remote_port_delete(rport);
- del_timer_sync(&tgt->timer);
+ timer_delete_sync(&tgt->timer);
kref_put(&tgt->kref, ibmvfc_release_tgt);
return;
} else if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
@@ -5672,7 +5672,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
spin_unlock_irqrestore(vhost->host->host_lock, flags);
if (rport)
fc_remote_port_delete(rport);
- del_timer_sync(&tgt->timer);
+ timer_delete_sync(&tgt->timer);
kref_put(&tgt->kref, ibmvfc_release_tgt);
return;
} else if (tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 16a1aac11911..d65a45860b33 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -789,7 +789,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code)
while (!list_empty(&hostdata->sent)) {
evt = list_first_entry(&hostdata->sent, struct srp_event_struct, list);
list_del(&evt->list);
- del_timer(&evt->timer);
+ timer_delete(&evt->timer);
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
if (evt->cmnd) {
@@ -944,7 +944,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
be64_to_cpu(crq_as_u64[1]));
if (rc != 0) {
list_del(&evt_struct->list);
- del_timer(&evt_struct->timer);
+ timer_delete(&evt_struct->timer);
/* If send_crq returns H_CLOSED, return SCSI_MLQUEUE_HOST_BUSY.
* Firmware will send a CRQ with a transport event (0xFF) to
@@ -1840,7 +1840,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
atomic_add(be32_to_cpu(evt_struct->xfer_iu->srp.rsp.req_lim_delta),
&hostdata->request_limit);
- del_timer(&evt_struct->timer);
+ timer_delete(&evt_struct->timer);
if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd)
evt_struct->cmnd->result = DID_ERROR << 16;
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 3bfafd43e42a..d89135fb8faa 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -873,7 +873,7 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH,
IPR_IOASC_IOA_WAS_RESET);
- del_timer(&ipr_cmd->timer);
+ timer_delete(&ipr_cmd->timer);
ipr_cmd->done(ipr_cmd);
}
spin_unlock(&hrrq->_lock);
@@ -5347,7 +5347,7 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
list_del(&ioa_cfg->reset_cmd->queue);
- del_timer(&ioa_cfg->reset_cmd->timer);
+ timer_delete(&ioa_cfg->reset_cmd->timer);
ipr_reset_ioa_job(ioa_cfg->reset_cmd);
return IRQ_HANDLED;
}
@@ -5362,7 +5362,7 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
list_del(&ioa_cfg->reset_cmd->queue);
- del_timer(&ioa_cfg->reset_cmd->timer);
+ timer_delete(&ioa_cfg->reset_cmd->timer);
ipr_reset_ioa_job(ioa_cfg->reset_cmd);
} else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) {
if (ioa_cfg->clear_isr) {
@@ -5481,7 +5481,7 @@ static int ipr_iopoll(struct irq_poll *iop, int budget)
list_for_each_entry_safe(ipr_cmd, temp, &doneq, queue) {
list_del(&ipr_cmd->queue);
- del_timer(&ipr_cmd->timer);
+ timer_delete(&ipr_cmd->timer);
ipr_cmd->fast_done(ipr_cmd);
}
@@ -5550,7 +5550,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
spin_unlock_irqrestore(hrrq->lock, hrrq_flags);
list_for_each_entry_safe(ipr_cmd, temp, &doneq, queue) {
list_del(&ipr_cmd->queue);
- del_timer(&ipr_cmd->timer);
+ timer_delete(&ipr_cmd->timer);
ipr_cmd->fast_done(ipr_cmd);
}
return rc;
@@ -5600,7 +5600,7 @@ static irqreturn_t ipr_isr_mhrrq(int irq, void *devp)
list_for_each_entry_safe(ipr_cmd, temp, &doneq, queue) {
list_del(&ipr_cmd->queue);
- del_timer(&ipr_cmd->timer);
+ timer_delete(&ipr_cmd->timer);
ipr_cmd->fast_done(ipr_cmd);
}
return rc;
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 35589b6af90d..c108b5b940c3 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1271,22 +1271,22 @@ void isci_host_deinit(struct isci_host *ihost)
/* Cancel any/all outstanding port timers */
for (i = 0; i < ihost->logical_port_entries; i++) {
struct isci_port *iport = &ihost->ports[i];
- del_timer_sync(&iport->timer.timer);
+ timer_delete_sync(&iport->timer.timer);
}
/* Cancel any/all outstanding phy timers */
for (i = 0; i < SCI_MAX_PHYS; i++) {
struct isci_phy *iphy = &ihost->phys[i];
- del_timer_sync(&iphy->sata_timer.timer);
+ timer_delete_sync(&iphy->sata_timer.timer);
}
- del_timer_sync(&ihost->port_agent.timer.timer);
+ timer_delete_sync(&ihost->port_agent.timer.timer);
- del_timer_sync(&ihost->power_control.timer.timer);
+ timer_delete_sync(&ihost->power_control.timer.timer);
- del_timer_sync(&ihost->timer.timer);
+ timer_delete_sync(&ihost->timer.timer);
- del_timer_sync(&ihost->phy_timer.timer);
+ timer_delete_sync(&ihost->phy_timer.timer);
}
static void __iomem *scu_base(struct isci_host *isci_host)
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h
index f6a8fe206415..d827e49c1d55 100644
--- a/drivers/scsi/isci/isci.h
+++ b/drivers/scsi/isci/isci.h
@@ -481,9 +481,9 @@ irqreturn_t isci_error_isr(int vec, void *data);
/*
* Each timer is associated with a cancellation flag that is set when
- * del_timer() is called and checked in the timer callback function. This
- * is needed since del_timer_sync() cannot be called with sci_lock held.
- * For deinit however, del_timer_sync() is used without holding the lock.
+ * timer_delete() is called and checked in the timer callback function. This
+ * is needed since timer_delete_sync() cannot be called with sci_lock held.
+ * For deinit however, timer_delete_sync() is used without holding the lock.
*/
struct sci_timer {
struct timer_list timer;
@@ -506,7 +506,7 @@ static inline void sci_mod_timer(struct sci_timer *tmr, unsigned long msec)
static inline void sci_del_timer(struct sci_timer *tmr)
{
tmr->cancel = true;
- del_timer(&tmr->timer);
+ timer_delete(&tmr->timer);
}
struct sci_base_state_machine {
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index fd1ef06655cb..e705c30b4e1b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1329,7 +1329,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
fsp->state |= FC_SRB_COMPL;
spin_unlock_bh(&fsp->scsi_pkt_lock);
- del_timer_sync(&fsp->timer);
+ timer_delete_sync(&fsp->timer);
spin_lock_bh(&fsp->scsi_pkt_lock);
if (fsp->seq_ptr) {
@@ -1961,7 +1961,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
fsp->state |= FC_SRB_COMPL;
if (!(fsp->state & FC_SRB_FCP_PROCESSING_TMO)) {
spin_unlock_bh(&fsp->scsi_pkt_lock);
- del_timer_sync(&fsp->timer);
+ timer_delete_sync(&fsp->timer);
spin_lock_bh(&fsp->scsi_pkt_lock);
}
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 2b1bf990a9dc..1ddaf7228340 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1945,7 +1945,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
session->tmf_state != TMF_QUEUED);
if (signal_pending(current))
flush_signals(current);
- del_timer_sync(&session->tmf_timer);
+ timer_delete_sync(&session->tmf_timer);
mutex_lock(&session->eh_mutex);
spin_lock_bh(&session->frwd_lock);
@@ -3247,7 +3247,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
iscsi_remove_conn(cls_conn);
- del_timer_sync(&conn->transport_timer);
+ timer_delete_sync(&conn->transport_timer);
mutex_lock(&session->eh_mutex);
spin_lock_bh(&session->frwd_lock);
@@ -3411,7 +3411,7 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
conn->stop_stage = flag;
spin_unlock_bh(&session->frwd_lock);
- del_timer_sync(&conn->transport_timer);
+ timer_delete_sync(&conn->transport_timer);
iscsi_suspend_tx(conn);
spin_lock_bh(&session->frwd_lock);
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 2b8004eb6f1b..869b5d4db44c 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -89,7 +89,7 @@ static int smp_execute_task_sg(struct domain_device *dev,
res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) {
- del_timer_sync(&task->slow_task->timer);
+ timer_delete_sync(&task->slow_task->timer);
pr_notice("executing SMP task failed:%d\n", res);
break;
}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 55ce7892f217..feb2461b90e8 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -859,7 +859,7 @@ EXPORT_SYMBOL_GPL(sas_bios_param);
void sas_task_internal_done(struct sas_task *task)
{
- del_timer(&task->slow_task->timer);
+ timer_delete(&task->slow_task->timer);
complete(&task->slow_task->completion);
}
@@ -911,7 +911,7 @@ static int sas_execute_internal_abort(struct domain_device *device,
res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) {
- del_timer_sync(&task->slow_task->timer);
+ timer_delete_sync(&task->slow_task->timer);
pr_err("Executing internal abort failed %016llx (%d)\n",
SAS_ADDR(device->sas_addr), res);
break;
@@ -1010,7 +1010,7 @@ int sas_execute_tmf(struct domain_device *device, void *parameter,
res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) {
- del_timer_sync(&task->slow_task->timer);
+ timer_delete_sync(&task->slow_task->timer);
pr_err("executing TMF task failed %016llx (%d)\n",
SAS_ADDR(device->sas_addr), res);
break;
@@ -1180,7 +1180,7 @@ void sas_task_abort(struct sas_task *task)
if (!slow)
return;
- if (!del_timer(&slow->timer))
+ if (!timer_delete(&slow->timer))
return;
slow->timer.function(&slow->timer);
return;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 0d0213bba35d..397216ff2c7e 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -2578,7 +2578,7 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr,
(old_val & DISABLE_FCP_RING_INT))
{
spin_unlock_irq(&phba->hbalock);
- del_timer(&phba->fcp_poll_timer);
+ timer_delete(&phba->fcp_poll_timer);
spin_lock_irq(&phba->hbalock);
if (lpfc_readl(phba->HCregaddr, &creg_val)) {
spin_unlock_irq(&phba->hbalock);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index e08b48b1b655..375a879c31f1 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -4333,7 +4333,7 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
if (!test_and_clear_bit(NLP_DELAY_TMO, &nlp->nlp_flag))
return;
- del_timer_sync(&nlp->nlp_delayfunc);
+ timer_delete_sync(&nlp->nlp_delayfunc);
nlp->nlp_last_elscmd = 0;
if (!list_empty(&nlp->els_retry_evt.evt_listp)) {
list_del_init(&nlp->els_retry_evt.evt_listp);
@@ -4431,7 +4431,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
* firing and before processing the timer, cancel the
* nlp_delayfunc.
*/
- del_timer_sync(&ndlp->nlp_delayfunc);
+ timer_delete_sync(&ndlp->nlp_delayfunc);
retry = ndlp->nlp_retry;
ndlp->nlp_retry = 0;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 8ca590e8469b..179be6c5a43e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1228,7 +1228,7 @@ lpfc_linkdown_port(struct lpfc_vport *vport)
/* Stop delayed Nport discovery */
clear_bit(FC_DISC_DELAYED, &vport->fc_flag);
- del_timer_sync(&vport->delayed_disc_tmo);
+ timer_delete_sync(&vport->delayed_disc_tmo);
if (phba->sli_rev == LPFC_SLI_REV4 &&
vport->port_type == LPFC_PHYSICAL_PORT &&
@@ -1418,7 +1418,7 @@ lpfc_linkup(struct lpfc_hba *phba)
/* Unblock fabric iocbs if they are blocked */
clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
- del_timer_sync(&phba->fabric_block_timer);
+ timer_delete_sync(&phba->fabric_block_timer);
vports = lpfc_create_vport_work_array(phba);
if (vports != NULL)
@@ -5010,7 +5010,7 @@ lpfc_can_disctmo(struct lpfc_vport *vport)
if (test_bit(FC_DISC_TMO, &vport->fc_flag) ||
timer_pending(&vport->fc_disctmo)) {
clear_bit(FC_DISC_TMO, &vport->fc_flag);
- del_timer_sync(&vport->fc_disctmo);
+ timer_delete_sync(&vport->fc_disctmo);
spin_lock_irqsave(&vport->work_port_lock, iflags);
vport->work_port_events &= ~WORKER_DISC_TMO;
spin_unlock_irqrestore(&vport->work_port_lock, iflags);
@@ -5501,7 +5501,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
clear_bit(NLP_DELAY_TMO, &ndlp->nlp_flag);
ndlp->nlp_last_elscmd = 0;
- del_timer_sync(&ndlp->nlp_delayfunc);
+ timer_delete_sync(&ndlp->nlp_delayfunc);
list_del_init(&ndlp->els_retry_evt.evt_listp);
list_del_init(&ndlp->dev_loss_evt.evt_listp);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 7238608ca49f..90021653e59e 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3120,8 +3120,8 @@ lpfc_cleanup(struct lpfc_vport *vport)
void
lpfc_stop_vport_timers(struct lpfc_vport *vport)
{
- del_timer_sync(&vport->els_tmofunc);
- del_timer_sync(&vport->delayed_disc_tmo);
+ timer_delete_sync(&vport->els_tmofunc);
+ timer_delete_sync(&vport->delayed_disc_tmo);
lpfc_can_disctmo(vport);
return;
}
@@ -3140,7 +3140,7 @@ __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
/* Now, try to stop the timer */
- del_timer(&phba->fcf.redisc_wait);
+ timer_delete(&phba->fcf.redisc_wait);
}
/**
@@ -3302,12 +3302,12 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba)
lpfc_stop_vport_timers(phba->pport);
cancel_delayed_work_sync(&phba->eq_delay_work);
cancel_delayed_work_sync(&phba->idle_stat_delay_work);
- del_timer_sync(&phba->sli.mbox_tmo);
- del_timer_sync(&phba->fabric_block_timer);
- del_timer_sync(&phba->eratt_poll);
- del_timer_sync(&phba->hb_tmofunc);
+ timer_delete_sync(&phba->sli.mbox_tmo);
+ timer_delete_sync(&phba->fabric_block_timer);
+ timer_delete_sync(&phba->eratt_poll);
+ timer_delete_sync(&phba->hb_tmofunc);
if (phba->sli_rev == LPFC_SLI_REV4) {
- del_timer_sync(&phba->rrq_tmr);
+ timer_delete_sync(&phba->rrq_tmr);
clear_bit(HBA_RRQ_ACTIVE, &phba->hba_flag);
}
clear_bit(HBA_HBEAT_INP, &phba->hba_flag);
@@ -3316,7 +3316,7 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba)
switch (phba->pci_dev_grp) {
case LPFC_PCI_DEV_LP:
/* Stop any LightPulse device specific driver timers */
- del_timer_sync(&phba->fcp_poll_timer);
+ timer_delete_sync(&phba->fcp_poll_timer);
break;
case LPFC_PCI_DEV_OC:
/* Stop any OneConnect device specific driver timers */
@@ -12761,7 +12761,7 @@ static void __lpfc_cpuhp_remove(struct lpfc_hba *phba)
* timer. Wait for the poll timer to retire.
*/
synchronize_rcu();
- del_timer_sync(&phba->cpuhp_poll_timer);
+ timer_delete_sync(&phba->cpuhp_poll_timer);
}
static void lpfc_cpuhp_remove(struct lpfc_hba *phba)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index f0158fc00f78..9edf80b14b1a 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5488,7 +5488,7 @@ void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport)
struct lpfc_vmid *cur;
if (vport->port_type == LPFC_PHYSICAL_PORT)
- del_timer_sync(&vport->phba->inactive_vmid_poll);
+ timer_delete_sync(&vport->phba->inactive_vmid_poll);
kfree(vport->qfpa_res);
kfree(vport->vmid_priority.vmid_range);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 4e0d48fcb204..6574f9e74476 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -5041,7 +5041,7 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
return 1;
}
- del_timer_sync(&psli->mbox_tmo);
+ timer_delete_sync(&psli->mbox_tmo);
if (ha_copy & HA_ERATT) {
writel(HA_ERATT, phba->HAregaddr);
phba->pport->stopped = 1;
@@ -12076,7 +12076,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
local_bh_enable();
/* Return any active mbox cmds */
- del_timer_sync(&psli->mbox_tmo);
+ timer_delete_sync(&psli->mbox_tmo);
spin_lock_irqsave(&phba->pport->work_port_lock, flags);
phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
@@ -13802,7 +13802,7 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
phba->sli.mbox_active = NULL;
spin_unlock_irqrestore(&phba->hbalock, iflag);
phba->last_completion_time = jiffies;
- del_timer(&phba->sli.mbox_tmo);
+ timer_delete(&phba->sli.mbox_tmo);
if (pmb->mbox_cmpl) {
lpfc_sli_pcimem_bcopy(mbox, pmbox,
MAILBOX_CMD_SIZE);
@@ -14302,7 +14302,7 @@ lpfc_sli4_sp_handle_mbox_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe)
/* Reset heartbeat timer */
phba->last_completion_time = jiffies;
- del_timer(&phba->sli.mbox_tmo);
+ timer_delete(&phba->sli.mbox_tmo);
/* Move mbox data to caller's mailbox region, do endian swapping */
if (pmb->mbox_cmpl && mbox)
@@ -15689,7 +15689,7 @@ static inline void lpfc_sli4_remove_from_poll_list(struct lpfc_queue *eq)
synchronize_rcu();
if (list_empty(&phba->poll_list))
- del_timer_sync(&phba->cpuhp_poll_timer);
+ timer_delete_sync(&phba->cpuhp_poll_timer);
}
void lpfc_sli4_cleanup_poll_list(struct lpfc_hba *phba)
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 3ba837b3093f..d533a8aa72cc 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -3951,7 +3951,7 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter)
}
- del_timer_sync(&timeout.timer);
+ timer_delete_sync(&timeout.timer);
destroy_timer_on_stack(&timeout.timer);
mutex_unlock(&raid_dev->sysfs_mtx);
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index c509440bd161..1f2cd15e3361 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -703,7 +703,7 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
*/
wait_event(wait_q, (kioc->status != -ENODATA));
if (timeout.timer.function) {
- del_timer_sync(&timeout.timer);
+ timer_delete_sync(&timeout.timer);
destroy_timer_on_stack(&timeout.timer);
}
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 28c75865967a..c20447b39cb9 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -6521,7 +6521,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
fail_start_watchdog:
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
- del_timer_sync(&instance->sriov_heartbeat_timer);
+ timer_delete_sync(&instance->sriov_heartbeat_timer);
fail_get_ld_pd_list:
instance->instancet->disable_intr(instance);
megasas_destroy_irqs(instance);
@@ -7603,7 +7603,7 @@ fail_io_attach:
megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
- del_timer_sync(&instance->sriov_heartbeat_timer);
+ timer_delete_sync(&instance->sriov_heartbeat_timer);
instance->instancet->disable_intr(instance);
megasas_destroy_irqs(instance);
@@ -7743,7 +7743,7 @@ megasas_suspend(struct device *dev)
/* Shutdown SR-IOV heartbeat timer */
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
- del_timer_sync(&instance->sriov_heartbeat_timer);
+ timer_delete_sync(&instance->sriov_heartbeat_timer);
/* Stop the FW fault detection watchdog */
if (instance->adapter_type != MFI_SERIES)
@@ -7907,7 +7907,7 @@ megasas_resume(struct device *dev)
fail_start_watchdog:
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
- del_timer_sync(&instance->sriov_heartbeat_timer);
+ timer_delete_sync(&instance->sriov_heartbeat_timer);
fail_init_mfi:
megasas_free_ctrl_dma_buffers(instance);
megasas_free_ctrl_mem(instance);
@@ -7971,7 +7971,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
/* Shutdown SR-IOV heartbeat timer */
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
- del_timer_sync(&instance->sriov_heartbeat_timer);
+ timer_delete_sync(&instance->sriov_heartbeat_timer);
/* Stop the FW fault detection watchdog */
if (instance->adapter_type != MFI_SERIES)
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 1eec23da28e2..721860cb1ef6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -4969,7 +4969,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
}
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
- del_timer_sync(&instance->sriov_heartbeat_timer);
+ timer_delete_sync(&instance->sriov_heartbeat_timer);
set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
set_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING);
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index c4592de4fefc..52ac10226cb0 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -976,7 +976,7 @@ static u32 mvs_is_sig_fis_received(u32 irq_status)
static void mvs_sig_remove_timer(struct mvs_phy *phy)
{
if (phy->timer.function)
- del_timer(&phy->timer);
+ timer_delete(&phy->timer);
phy->timer.function = NULL;
}
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 3ba53916fd86..e0aeb206df8d 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -495,7 +495,7 @@ static void pmcraid_clr_trans_op(
}
if (pinstance->reset_cmd != NULL) {
- del_timer(&pinstance->reset_cmd->timer);
+ timer_delete(&pinstance->reset_cmd->timer);
spin_lock_irqsave(
pinstance->host->host_lock, lock_flags);
pinstance->reset_cmd->cmd_done(pinstance->reset_cmd);
@@ -1999,7 +1999,7 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance)
cpu_to_le32(PMCRAID_DRIVER_ILID);
/* In case the command timer is still running */
- del_timer(&cmd->timer);
+ timer_delete(&cmd->timer);
/* If this is an IO command, complete it by invoking scsi_done
* function. If this is one of the internal commands other
@@ -3982,7 +3982,7 @@ static void pmcraid_tasklet_function(unsigned long instance)
list_del(&cmd->free_list);
spin_unlock_irqrestore(&pinstance->pending_pool_lock,
pending_lock_flags);
- del_timer(&cmd->timer);
+ timer_delete(&cmd->timer);
atomic_dec(&pinstance->outstanding_cmds);
if (cmd->cmd_done == pmcraid_ioa_reset) {
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 47d74f881948..078a9c80bce2 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -2454,7 +2454,7 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
qla1280_debounce_register(&reg->istatus);
wait_for_completion(&wait);
- del_timer_sync(&ha->mailbox_timer);
+ timer_delete_sync(&ha->mailbox_timer);
spin_lock_irq(ha->host->host_lock);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 79cdfec2bca3..0c2dd782b675 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -67,7 +67,7 @@ void qla2x00_sp_free(srb_t *sp)
{
struct srb_iocb *iocb = &sp->u.iocb_cmd;
- del_timer(&iocb->timer);
+ timer_delete(&iocb->timer);
qla2x00_rel_sp(sp);
}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 0b41e8a06602..3224044f1775 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2572,7 +2572,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
static void
qla2x00_async_done(struct srb *sp, int res)
{
- if (del_timer(&sp->u.iocb_cmd.timer)) {
+ if (timer_delete(&sp->u.iocb_cmd.timer)) {
/*
* Successfully cancelled the timeout handler
* ref: TMR
@@ -2645,7 +2645,7 @@ static void qla2x00_els_dcmd_sp_free(srb_t *sp)
elsio->u.els_logo.els_logo_pyld,
elsio->u.els_logo.els_logo_pyld_dma);
- del_timer(&elsio->timer);
+ timer_delete(&elsio->timer);
qla2x00_rel_sp(sp);
}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 79879c4743e6..8b71ac0b1d99 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -20,7 +20,7 @@ void
qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
{
if (vha->vp_idx && vha->timer_active) {
- del_timer_sync(&vha->timer);
+ timer_delete_sync(&vha->timer);
vha->timer_active = 0;
}
}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 6b9b8218b512..b44d134e7105 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -401,7 +401,7 @@ qla2x00_restart_timer(scsi_qla_host_t *vha, unsigned long interval)
static __inline__ void
qla2x00_stop_timer(scsi_qla_host_t *vha)
{
- del_timer_sync(&vha->timer);
+ timer_delete_sync(&vha->timer);
vha->timer_active = 0;
}
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 6b0e6b4cd8af..d540d66e6ffc 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -4021,7 +4021,7 @@ static void qla4xxx_start_timer(struct scsi_qla_host *ha,
static void qla4xxx_stop_timer(struct scsi_qla_host *ha)
{
- del_timer_sync(&ha->timer);
+ timer_delete_sync(&ha->timer);
ha->timer_active = 0;
}
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 0da7be40c925..88135fdb8bd1 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -3853,7 +3853,7 @@ static void pqi_start_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
{
- del_timer_sync(&ctrl_info->heartbeat_timer);
+ timer_delete_sync(&ctrl_info->heartbeat_timer);
}
static void pqi_ofa_capture_event_payload(struct pqi_ctrl_info *ctrl_info,
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 212d89d0d23e..1a6eb72ca281 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1657,7 +1657,7 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev)
struct sym_hcb *np = sym_get_hcb(shost);
printk("%s: detaching ...\n", sym_name(np));
- del_timer_sync(&np->s.timer);
+ timer_delete_sync(&np->s.timer);
/*
* Reset NCR chip.
diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
index bbae3d39c7be..77bf0e83ffcc 100644
--- a/drivers/soc/fsl/qe/qe_ic.c
+++ b/drivers/soc/fsl/qe/qe_ic.c
@@ -344,7 +344,7 @@ static unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
if (irq == 0)
return 0;
- return irq_linear_revmap(qe_ic->irqhost, irq);
+ return irq_find_mapping(qe_ic->irqhost, irq);
}
/* Return an interrupt vector or 0 if no interrupt is pending. */
@@ -360,7 +360,7 @@ static unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
if (irq == 0)
return 0;
- return irq_linear_revmap(qe_ic->irqhost, irq);
+ return irq_find_mapping(qe_ic->irqhost, irq);
}
static void qe_ic_cascade_low(struct irq_desc *desc)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f40c282d4d63..ed38f6d41f47 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -937,9 +937,9 @@ config SPI_QCOM_QSPI
QSPI(Quad SPI) driver for Qualcomm QSPI controller.
config SPI_QPIC_SNAND
- bool "QPIC SNAND controller"
+ tristate "QPIC SNAND controller"
depends on ARCH_QCOM || COMPILE_TEST
- select MTD
+ depends on MTD
help
QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller.
QPIC controller supports both parallel nand and serial nand.
diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c
index c85997478b81..17fc0b17e756 100644
--- a/drivers/spi/spi-amd.c
+++ b/drivers/spi/spi-amd.c
@@ -302,7 +302,7 @@ static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
{
unsigned int i, spd7_val, alt_spd;
- for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
+ for (i = 0; i < ARRAY_SIZE(amd_spi_freq)-1; i++)
if (speed_hz >= amd_spi_freq[i].speed_hz)
break;
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index 0d1aa6592484..77de5a07639a 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -1162,7 +1162,8 @@ static void bcm2835_spi_cleanup(struct spi_device *spi)
sizeof(u32),
DMA_TO_DEVICE);
- gpiod_put(bs->cs_gpio);
+ if (!IS_ERR(bs->cs_gpio))
+ gpiod_put(bs->cs_gpio);
spi_set_csgpiod(spi, 0, NULL);
kfree(target);
@@ -1225,7 +1226,12 @@ static int bcm2835_spi_setup(struct spi_device *spi)
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *target = spi_get_ctldata(spi);
struct gpiod_lookup_table *lookup __free(kfree) = NULL;
- int ret;
+ const char *pinctrl_compats[] = {
+ "brcm,bcm2835-gpio",
+ "brcm,bcm2711-gpio",
+ "brcm,bcm7211-gpio",
+ };
+ int ret, i;
u32 cs;
if (!target) {
@@ -1290,6 +1296,14 @@ static int bcm2835_spi_setup(struct spi_device *spi)
goto err_cleanup;
}
+ for (i = 0; i < ARRAY_SIZE(pinctrl_compats); i++) {
+ if (of_find_compatible_node(NULL, NULL, pinctrl_compats[i]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(pinctrl_compats))
+ return 0;
+
/*
* TODO: The code below is a slightly better alternative to the utter
* abuse of the GPIO API that I found here before. It creates a
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 559fbdfbd9f7..c90462783b3f 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -2073,7 +2073,7 @@ static const struct cqspi_driver_platdata k2g_qspi = {
static const struct cqspi_driver_platdata am654_ospi = {
.hwcaps_mask = CQSPI_SUPPORTS_OCTAL | CQSPI_SUPPORTS_QUAD,
- .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NEEDS_WR_DELAY,
+ .quirks = CQSPI_NEEDS_WR_DELAY,
};
static const struct cqspi_driver_platdata intel_lgm_qspi = {
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index aed98ab14334..6dcba0e0ddaa 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -432,7 +432,7 @@ static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi,
u32 clk_reg;
bool update_clk = false;
- while (i < ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list)) {
+ while (i < (ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list) - 1)) {
clk_val = MRVL_XSPI_CLOCK_DIVIDED(
cdns_mrvl_xspi_clk_div_list[i]);
if (clk_val <= requested_clk)
diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index 355e6a39fb41..5c59fddb32c1 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -844,6 +844,19 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = {
.per_op_freq = true,
};
+static void fsl_qspi_cleanup(void *data)
+{
+ struct fsl_qspi *q = data;
+
+ /* disable the hardware */
+ qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+ qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
+
+ fsl_qspi_clk_disable_unprep(q);
+
+ mutex_destroy(&q->lock);
+}
+
static int fsl_qspi_probe(struct platform_device *pdev)
{
struct spi_controller *ctlr;
@@ -934,6 +947,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
ctlr->dev.of_node = np;
+ ret = devm_add_action_or_reset(dev, fsl_qspi_cleanup, q);
+ if (ret)
+ goto err_destroy_mutex;
+
ret = devm_spi_register_controller(dev, ctlr);
if (ret)
goto err_destroy_mutex;
@@ -953,19 +970,6 @@ err_put_ctrl:
return ret;
}
-static void fsl_qspi_remove(struct platform_device *pdev)
-{
- struct fsl_qspi *q = platform_get_drvdata(pdev);
-
- /* disable the hardware */
- qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
- qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
-
- fsl_qspi_clk_disable_unprep(q);
-
- mutex_destroy(&q->lock);
-}
-
static int fsl_qspi_suspend(struct device *dev)
{
return 0;
@@ -1003,7 +1007,6 @@ static struct platform_driver fsl_qspi_driver = {
.pm = &fsl_qspi_pm_ops,
},
.probe = fsl_qspi_probe,
- .remove = fsl_qspi_remove,
};
module_platform_driver(fsl_qspi_driver);
diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
index fbba7741a9bf..17eb67e19132 100644
--- a/drivers/spi/spi-qpic-snand.c
+++ b/drivers/spi/spi-qpic-snand.c
@@ -1614,7 +1614,7 @@ static const struct of_device_id qcom_snandc_of_match[] = {
.data = &ipq9574_snandc_props,
},
{}
-}
+};
MODULE_DEVICE_TABLE(of, qcom_snandc_of_match);
static struct platform_driver qcom_spi_driver = {
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 1bc012fce7cb..1a6381de6f33 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -547,7 +547,7 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
if (spi->mode & SPI_LSB_FIRST)
cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET;
- if (spi->mode & SPI_CS_HIGH)
+ if ((spi->mode & SPI_CS_HIGH) && !(spi_get_csgpiod(spi, 0)))
cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET;
if (xfer->rx_buf && xfer->tx_buf)
diff --git a/drivers/staging/gpib/Kconfig b/drivers/staging/gpib/Kconfig
index 81510db3072e..aa01538d5beb 100644
--- a/drivers/staging/gpib/Kconfig
+++ b/drivers/staging/gpib/Kconfig
@@ -50,7 +50,6 @@ config GPIB_CEC_PCI
tristate "CEC PCI board"
depends on PCI
depends on HAS_IOPORT
- depends on !X86_PAE
select GPIB_COMMON
select GPIB_NEC7210
help
@@ -64,7 +63,6 @@ config GPIB_NI_PCI_ISA
tristate "NI PCI/ISA compatible boards"
depends on ISA_BUS || PCI || PCMCIA
depends on HAS_IOPORT
- depends on !X86_PAE
depends on PCMCIA || !PCMCIA
depends on HAS_IOPORT_MAP
select GPIB_COMMON
@@ -90,7 +88,6 @@ config GPIB_CB7210
tristate "Measurement Computing compatible boards"
depends on HAS_IOPORT
depends on ISA_BUS || PCI || PCMCIA
- depends on !X86_PAE
depends on PCMCIA || !PCMCIA
select GPIB_COMMON
select GPIB_NEC7210
@@ -169,7 +166,6 @@ config GPIB_HP82341
tristate "HP82341x"
select GPIB_COMMON
select GPIB_TMS9914
- depends on BROKEN
depends on ISA_BUS || EISA
help
GPIB driver for HP82341 A/B/C/D boards
@@ -182,7 +178,6 @@ config GPIB_INES
depends on PCI || ISA_BUS || PCMCIA
depends on PCMCIA || !PCMCIA
depends on HAS_IOPORT
- depends on !X86_PAE
select GPIB_COMMON
select GPIB_NEC7210
help
diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
index 3f4f95b7fe34..445b9380ff98 100644
--- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
+++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
@@ -4,6 +4,10 @@
* copyright : (C) 2002, 2004 by Frank Mori Hess *
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "agilent_82350b.h"
#include <linux/delay.h>
#include <linux/ioport.h>
@@ -20,8 +24,14 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver for Agilent 82350b");
-int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read)
+static int read_transfer_counter(struct agilent_82350b_priv *a_priv);
+static unsigned short read_and_clear_event_status(struct gpib_board *board);
+static void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count);
+static int agilent_82350b_write(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int send_eoi, size_t *bytes_written);
+
+static int agilent_82350b_accel_read(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int *end, size_t *bytes_read)
{
struct agilent_82350b_priv *a_priv = board->private_data;
@@ -48,9 +58,6 @@ int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t lengt
retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes);
*bytes_read += num_bytes;
- if (retval < 0)
- dev_err(board->gpib_dev, "%s: tms9914_read failed retval=%i\n",
- driver_name, retval);
if (retval < 0 || *end)
return retval;
++buffer;
@@ -66,10 +73,7 @@ int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t lengt
int j;
int count;
- if (num_fifo_bytes - i < agilent_82350b_fifo_size)
- block_size = num_fifo_bytes - i;
- else
- block_size = agilent_82350b_fifo_size;
+ block_size = min(num_fifo_bytes - i, agilent_82350b_fifo_size);
set_transfer_counter(a_priv, block_size);
writeb(ENABLE_TI_TO_SRAM | DIRECTION_GPIB_TO_HOST,
a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
@@ -86,7 +90,6 @@ int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t lengt
test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
test_bit(TIMO_NUM, &board->status));
if (retval) {
- dev_dbg(board->gpib_dev, "%s: read wait interrupted\n", driver_name);
retval = -ERESTARTSYS;
break;
}
@@ -100,13 +103,10 @@ int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t lengt
*end = 1;
}
if (test_bit(TIMO_NUM, &board->status)) {
- dev_err(board->gpib_dev, "%s: read timed out\n", driver_name);
retval = -ETIMEDOUT;
break;
}
if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- dev_err(board->gpib_dev, "%s: device clear interrupted read\n",
- driver_name);
retval = -EINTR;
break;
}
@@ -130,30 +130,24 @@ int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t lengt
return 0;
}
-static int translate_wait_return_value(gpib_board_t *board, int retval)
+static int translate_wait_return_value(struct gpib_board *board, int retval)
{
struct agilent_82350b_priv *a_priv = board->private_data;
struct tms9914_priv *tms_priv = &a_priv->tms9914_priv;
- if (retval) {
- dev_err(board->gpib_dev, "%s: write wait interrupted\n", driver_name);
+ if (retval)
return -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- dev_err(board->gpib_dev, "%s: write timed out\n", driver_name);
+ if (test_bit(TIMO_NUM, &board->status))
return -ETIMEDOUT;
- }
- if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- dev_err(board->gpib_dev, "%s: device clear interrupted write\n", driver_name);
+ if (test_bit(DEV_CLEAR_BN, &tms_priv->state))
return -EINTR;
- }
return 0;
}
-int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-
+static int agilent_82350b_accel_write(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int send_eoi,
+ size_t *bytes_written)
{
struct agilent_82350b_priv *a_priv = board->private_data;
struct tms9914_priv *tms_priv = &a_priv->tms9914_priv;
@@ -174,10 +168,8 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng
event_status = read_and_clear_event_status(board);
- //pr_info("ag_ac_wr: event status 0x%x tms state 0x%lx\n", event_status, tms_priv->state);
-
#ifdef EXPERIMENTAL
- pr_info("ag_ac_wr: wait for previous BO to complete if any\n");
+ // wait for previous BO to complete if any
retval = wait_event_interruptible(board->wait,
test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
test_bit(WRITE_READY_BN, &tms_priv->state) ||
@@ -188,22 +180,16 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng
return retval;
#endif
- //pr_info("ag_ac_wr: sending first byte\n");
retval = agilent_82350b_write(board, buffer, 1, 0, &num_bytes);
*bytes_written += num_bytes;
if (retval < 0)
return retval;
- //pr_info("ag_ac_wr: %ld bytes eoi %d tms state 0x%lx\n",length, send_eoi, tms_priv->state);
-
write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BOIE, IMR0);
for (i = 1; i < fifotransferlength;) {
clear_bit(WRITE_READY_BN, &tms_priv->state);
- if (fifotransferlength - i < agilent_82350b_fifo_size)
- block_size = fifotransferlength - i;
- else
- block_size = agilent_82350b_fifo_size;
+ block_size = min(fifotransferlength - i, agilent_82350b_fifo_size);
set_transfer_counter(a_priv, block_size);
for (j = 0; j < block_size; ++j, ++i) {
// load data into board's sram
@@ -211,13 +197,8 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng
}
writeb(ENABLE_TI_TO_SRAM, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
- //pr_info("ag_ac_wr: send block: %d bytes tms 0x%lx\n", block_size,
- // tms_priv->state);
-
- if (agilent_82350b_fifo_is_halted(a_priv)) {
+ if (agilent_82350b_fifo_is_halted(a_priv))
writeb(RESTART_STREAM_BIT, a_priv->gpib_base + STREAM_STATUS_REG);
- // pr_info("ag_ac_wr: needed restart\n");
- }
retval = wait_event_interruptible(board->wait,
((event_status =
@@ -227,7 +208,6 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng
test_bit(TIMO_NUM, &board->status));
writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
num_bytes = block_size - read_transfer_counter(a_priv);
- //pr_info("ag_ac_wr: sent %ld bytes tms 0x%lx\n", num_bytes, tms_priv->state);
*bytes_written += num_bytes;
retval = translate_wait_return_value(board, retval);
@@ -239,9 +219,6 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng
return retval;
if (send_eoi) {
- //pr_info("ag_ac_wr: sending last byte with eoi byte no: %d\n",
- // fifotransferlength+1);
-
retval = agilent_82350b_write(board, buffer + fifotransferlength, 1, send_eoi,
&num_bytes);
*bytes_written += num_bytes;
@@ -251,8 +228,7 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng
return 0;
}
-unsigned short read_and_clear_event_status(gpib_board_t *board)
-
+static unsigned short read_and_clear_event_status(struct gpib_board *board)
{
struct agilent_82350b_priv *a_priv = board->private_data;
unsigned long flags;
@@ -265,12 +241,12 @@ unsigned short read_and_clear_event_status(gpib_board_t *board)
return status;
}
-irqreturn_t agilent_82350b_interrupt(int irq, void *arg)
+static irqreturn_t agilent_82350b_interrupt(int irq, void *arg)
{
int tms9914_status1 = 0, tms9914_status2 = 0;
int event_status;
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct agilent_82350b_priv *a_priv = board->private_data;
unsigned long flags;
irqreturn_t retval = IRQ_NONE;
@@ -286,7 +262,6 @@ irqreturn_t agilent_82350b_interrupt(int irq, void *arg)
tms9914_interrupt_have_status(board, &a_priv->tms9914_priv, tms9914_status1,
tms9914_status2);
}
-//pr_info("event_status=0x%x s1 %x s2 %x\n", event_status,tms9914_status1,tms9914_status2);
//write-clear status bits
if (event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT)) {
writeb(event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT),
@@ -298,12 +273,9 @@ irqreturn_t agilent_82350b_interrupt(int irq, void *arg)
return retval;
}
-void agilent_82350b_detach(gpib_board_t *board);
-
-const char *driver_name = "agilent_82350b";
-
-int read_transfer_counter(struct agilent_82350b_priv *a_priv)
+static void agilent_82350b_detach(struct gpib_board *board);
+static int read_transfer_counter(struct agilent_82350b_priv *a_priv)
{
int lo, mid, value;
@@ -314,8 +286,7 @@ int read_transfer_counter(struct agilent_82350b_priv *a_priv)
return value;
}
-void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count)
-
+static void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count)
{
int complement = -count;
@@ -326,17 +297,16 @@ void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count)
}
// wrappers for interface functions
-int agilent_82350b_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read)
-
+static int agilent_82350b_read(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int *end, size_t *bytes_read)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
}
-int agilent_82350b_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int agilent_82350b_write(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int send_eoi, size_t *bytes_written)
{
struct agilent_82350b_priv *priv = board->private_data;
@@ -344,8 +314,8 @@ int agilent_82350b_write(gpib_board_t *board, uint8_t *buffer, size_t length, in
return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
}
-int agilent_82350b_command(gpib_board_t *board, uint8_t *buffer, size_t length,
- size_t *bytes_written)
+static int agilent_82350b_command(struct gpib_board *board, uint8_t *buffer,
+ size_t length, size_t *bytes_written)
{
struct agilent_82350b_priv *priv = board->private_data;
@@ -353,7 +323,7 @@ int agilent_82350b_command(gpib_board_t *board, uint8_t *buffer, size_t length,
return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
}
-int agilent_82350b_take_control(gpib_board_t *board, int synchronous)
+static int agilent_82350b_take_control(struct gpib_board *board, int synchronous)
{
struct agilent_82350b_priv *priv = board->private_data;
@@ -361,7 +331,7 @@ int agilent_82350b_take_control(gpib_board_t *board, int synchronous)
return tms9914_take_control_workaround(board, &priv->tms9914_priv, synchronous);
}
-int agilent_82350b_go_to_standby(gpib_board_t *board)
+static int agilent_82350b_go_to_standby(struct gpib_board *board)
{
struct agilent_82350b_priv *priv = board->private_data;
@@ -369,7 +339,8 @@ int agilent_82350b_go_to_standby(gpib_board_t *board)
return tms9914_go_to_standby(board, &priv->tms9914_priv);
}
-void agilent_82350b_request_system_control(gpib_board_t *board, int request_control)
+static void agilent_82350b_request_system_control(struct gpib_board *board,
+ int request_control)
{
struct agilent_82350b_priv *a_priv = board->private_data;
@@ -387,7 +358,7 @@ void agilent_82350b_request_system_control(gpib_board_t *board, int request_cont
tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control);
}
-void agilent_82350b_interface_clear(gpib_board_t *board, int assert)
+static void agilent_82350b_interface_clear(struct gpib_board *board, int assert)
{
struct agilent_82350b_priv *priv = board->private_data;
@@ -395,104 +366,96 @@ void agilent_82350b_interface_clear(gpib_board_t *board, int assert)
tms9914_interface_clear(board, &priv->tms9914_priv, assert);
}
-void agilent_82350b_remote_enable(gpib_board_t *board, int enable)
-
+static void agilent_82350b_remote_enable(struct gpib_board *board, int enable)
{
struct agilent_82350b_priv *priv = board->private_data;
tms9914_remote_enable(board, &priv->tms9914_priv, enable);
}
-int agilent_82350b_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
-
+static int agilent_82350b_enable_eos(struct gpib_board *board, uint8_t eos_byte,
+ int compare_8_bits)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
}
-void agilent_82350b_disable_eos(gpib_board_t *board)
-
+static void agilent_82350b_disable_eos(struct gpib_board *board)
{
struct agilent_82350b_priv *priv = board->private_data;
tms9914_disable_eos(board, &priv->tms9914_priv);
}
-unsigned int agilent_82350b_update_status(gpib_board_t *board, unsigned int clear_mask)
-
+static unsigned int agilent_82350b_update_status(struct gpib_board *board,
+ unsigned int clear_mask)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
}
-int agilent_82350b_primary_address(gpib_board_t *board, unsigned int address)
-
+static int agilent_82350b_primary_address(struct gpib_board *board,
+ unsigned int address)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_primary_address(board, &priv->tms9914_priv, address);
}
-int agilent_82350b_secondary_address(gpib_board_t *board, unsigned int address, int enable)
-
+static int agilent_82350b_secondary_address(struct gpib_board *board,
+ unsigned int address, int enable)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
}
-int agilent_82350b_parallel_poll(gpib_board_t *board, uint8_t *result)
-
+static int agilent_82350b_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
}
-void agilent_82350b_parallel_poll_configure(gpib_board_t *board, uint8_t config)
-
+static void agilent_82350b_parallel_poll_configure(struct gpib_board *board,
+ uint8_t config)
{
struct agilent_82350b_priv *priv = board->private_data;
tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
}
-void agilent_82350b_parallel_poll_response(gpib_board_t *board, int ist)
-
+static void agilent_82350b_parallel_poll_response(struct gpib_board *board, int ist)
{
struct agilent_82350b_priv *priv = board->private_data;
tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
}
-void agilent_82350b_serial_poll_response(gpib_board_t *board, uint8_t status)
-
+static void agilent_82350b_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct agilent_82350b_priv *priv = board->private_data;
tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
}
-uint8_t agilent_82350b_serial_poll_status(gpib_board_t *board)
-
+static uint8_t agilent_82350b_serial_poll_status(struct gpib_board *board)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_serial_poll_status(board, &priv->tms9914_priv);
}
-int agilent_82350b_line_status(const gpib_board_t *board)
-
+static int agilent_82350b_line_status(const struct gpib_board *board)
{
struct agilent_82350b_priv *priv = board->private_data;
return tms9914_line_status(board, &priv->tms9914_priv);
}
-unsigned int agilent_82350b_t1_delay(gpib_board_t *board, unsigned int nanosec)
-
+static int agilent_82350b_t1_delay(struct gpib_board *board, unsigned int nanosec)
{
struct agilent_82350b_priv *a_priv = board->private_data;
static const int nanosec_per_clock = 30;
@@ -507,16 +470,14 @@ unsigned int agilent_82350b_t1_delay(gpib_board_t *board, unsigned int nanosec)
return value * nanosec_per_clock;
}
-void agilent_82350b_return_to_local(gpib_board_t *board)
-
+static void agilent_82350b_return_to_local(struct gpib_board *board)
{
struct agilent_82350b_priv *priv = board->private_data;
tms9914_return_to_local(board, &priv->tms9914_priv);
}
-int agilent_82350b_allocate_private(gpib_board_t *board)
-
+static int agilent_82350b_allocate_private(struct gpib_board *board)
{
board->private_data = kzalloc(sizeof(struct agilent_82350b_priv), GFP_KERNEL);
if (!board->private_data)
@@ -524,15 +485,14 @@ int agilent_82350b_allocate_private(gpib_board_t *board)
return 0;
}
-void agilent_82350b_free_private(gpib_board_t *board)
-
+static void agilent_82350b_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
-static int init_82350a_hardware(gpib_board_t *board, const gpib_board_config_t *config)
-
+static int init_82350a_hardware(struct gpib_board *board,
+ const gpib_board_config_t *config)
{
struct agilent_82350b_priv *a_priv = board->private_data;
static const unsigned int firmware_length = 5302;
@@ -557,11 +517,10 @@ static int init_82350a_hardware(gpib_board_t *board, const gpib_board_config_t *
return 0;
// need to programme borg
if (!config->init_data || config->init_data_length != firmware_length) {
- dev_err(board->gpib_dev, "%s: the 82350A board requires firmware after powering on.\n",
- driver_name);
+ dev_err(board->gpib_dev, "the 82350A board requires firmware after powering on.\n");
return -EIO;
}
- dev_info(board->gpib_dev, "%s: Loading firmware...\n", driver_name);
+ dev_dbg(board->gpib_dev, "Loading firmware...\n");
// tickle the borg
writel(plx_cntrl_static_bits | PLX9050_USER3_DATA_BIT,
@@ -580,7 +539,7 @@ static int init_82350a_hardware(gpib_board_t *board, const gpib_board_config_t *
usleep_range(10, 20);
}
if (j == timeout) {
- dev_err(board->gpib_dev, "%s: timed out loading firmware.\n", driver_name);
+ dev_err(board->gpib_dev, "timed out loading firmware.\n");
return -ETIMEDOUT;
}
writeb(firmware_data[i], a_priv->gpib_base + CONFIG_DATA_REG);
@@ -591,15 +550,14 @@ static int init_82350a_hardware(gpib_board_t *board, const gpib_board_config_t *
usleep_range(10, 20);
}
if (j == timeout) {
- dev_err(board->gpib_dev, "%s: timed out waiting for firmware load to complete.\n",
- driver_name);
+ dev_err(board->gpib_dev, "timed out waiting for firmware load to complete.\n");
return -ETIMEDOUT;
}
- dev_info(board->gpib_dev, "%s: ...done.\n", driver_name);
+ dev_dbg(board->gpib_dev, " ...done.\n");
return 0;
}
-static int test_sram(gpib_board_t *board)
+static int test_sram(struct gpib_board *board)
{
struct agilent_82350b_priv *a_priv = board->private_data;
@@ -617,19 +575,19 @@ static int test_sram(gpib_board_t *board)
unsigned int read_value = readb(a_priv->sram_base + i);
if ((i & byte_mask) != read_value) {
- dev_err(board->gpib_dev, "%s: SRAM test failed at %d wanted %d got %d\n",
- driver_name, i, (i & byte_mask), read_value);
+ dev_err(board->gpib_dev, "SRAM test failed at %d wanted %d got %d\n",
+ i, (i & byte_mask), read_value);
return -EIO;
}
if (need_resched())
schedule();
}
- dev_info(board->gpib_dev, "%s: SRAM test passed 0x%x bytes checked\n",
- driver_name, sram_length);
+ dev_dbg(board->gpib_dev, "SRAM test passed 0x%x bytes checked\n", sram_length);
return 0;
}
-static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_config_t *config,
+static int agilent_82350b_generic_attach(struct gpib_board *board,
+ const gpib_board_config_t *config,
int use_fifos)
{
@@ -653,14 +611,14 @@ static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_c
PCI_DEVICE_ID_82350B, NULL);
if (a_priv->pci_device) {
a_priv->model = MODEL_82350B;
- dev_info(board->gpib_dev, "%s: Agilent 82350B board found\n", driver_name);
+ dev_dbg(board->gpib_dev, "Agilent 82350B board found\n");
} else {
a_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_AGILENT,
PCI_DEVICE_ID_82351A, NULL);
if (a_priv->pci_device) {
a_priv->model = MODEL_82351A;
- dev_info(board->gpib_dev, "%s: Agilent 82351B board found\n", driver_name);
+ dev_dbg(board->gpib_dev, "Agilent 82351B board found\n");
} else {
a_priv->pci_device = gpib_pci_get_subsys(config, PCI_VENDOR_ID_PLX,
@@ -670,46 +628,40 @@ static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_c
a_priv->pci_device);
if (a_priv->pci_device) {
a_priv->model = MODEL_82350A;
- dev_info(board->gpib_dev, "%s: HP/Agilent 82350A board found\n",
- driver_name);
+ dev_dbg(board->gpib_dev, "HP/Agilent 82350A board found\n");
} else {
- dev_err(board->gpib_dev, "%s: no 82350/82351 board found\n",
- driver_name);
+ dev_err(board->gpib_dev, "no 82350/82351 board found\n");
return -ENODEV;
}
}
}
if (pci_enable_device(a_priv->pci_device)) {
- dev_err(board->gpib_dev, "%s: error enabling pci device\n", driver_name);
+ dev_err(board->gpib_dev, "error enabling pci device\n");
return -EIO;
}
- if (pci_request_regions(a_priv->pci_device, driver_name))
- return -EIO;
+ if (pci_request_regions(a_priv->pci_device, DRV_NAME))
+ return -ENOMEM;
switch (a_priv->model) {
case MODEL_82350A:
a_priv->plx_base = ioremap(pci_resource_start(a_priv->pci_device, PLX_MEM_REGION),
pci_resource_len(a_priv->pci_device, PLX_MEM_REGION));
- dev_dbg(board->gpib_dev, "%s: plx base address remapped to 0x%p\n",
- driver_name, a_priv->plx_base);
+ dev_dbg(board->gpib_dev, "plx base address remapped to 0x%p\n", a_priv->plx_base);
a_priv->gpib_base = ioremap(pci_resource_start(a_priv->pci_device,
GPIB_82350A_REGION),
pci_resource_len(a_priv->pci_device,
GPIB_82350A_REGION));
- dev_dbg(board->gpib_dev, "%s: gpib base address remapped to 0x%p\n",
- driver_name, a_priv->gpib_base);
+ dev_dbg(board->gpib_dev, "chip base address remapped to 0x%p\n", a_priv->gpib_base);
tms_priv->mmiobase = a_priv->gpib_base + TMS9914_BASE_REG;
a_priv->sram_base = ioremap(pci_resource_start(a_priv->pci_device,
SRAM_82350A_REGION),
pci_resource_len(a_priv->pci_device,
SRAM_82350A_REGION));
- dev_dbg(board->gpib_dev, "%s: sram base address remapped to 0x%p\n",
- driver_name, a_priv->sram_base);
+ dev_dbg(board->gpib_dev, "sram base address remapped to 0x%p\n", a_priv->sram_base);
a_priv->borg_base = ioremap(pci_resource_start(a_priv->pci_device,
BORG_82350A_REGION),
pci_resource_len(a_priv->pci_device,
BORG_82350A_REGION));
- dev_dbg(board->gpib_dev, "%s: borg base address remapped to 0x%p\n",
- driver_name, a_priv->borg_base);
+ dev_dbg(board->gpib_dev, "borg base address remapped to 0x%p\n", a_priv->borg_base);
retval = init_82350a_hardware(board, config);
if (retval < 0)
@@ -719,21 +671,18 @@ static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_c
case MODEL_82351A:
a_priv->gpib_base = ioremap(pci_resource_start(a_priv->pci_device, GPIB_REGION),
pci_resource_len(a_priv->pci_device, GPIB_REGION));
- dev_dbg(board->gpib_dev, "%s: gpib base address remapped to 0x%p\n",
- driver_name, a_priv->gpib_base);
+ dev_dbg(board->gpib_dev, "chip base address remapped to 0x%p\n", a_priv->gpib_base);
tms_priv->mmiobase = a_priv->gpib_base + TMS9914_BASE_REG;
a_priv->sram_base = ioremap(pci_resource_start(a_priv->pci_device, SRAM_REGION),
pci_resource_len(a_priv->pci_device, SRAM_REGION));
- dev_dbg(board->gpib_dev, "%s: sram base address remapped to 0x%p\n",
- driver_name, a_priv->sram_base);
+ dev_dbg(board->gpib_dev, "sram base address remapped to 0x%p\n", a_priv->sram_base);
a_priv->misc_base = ioremap(pci_resource_start(a_priv->pci_device, MISC_REGION),
pci_resource_len(a_priv->pci_device, MISC_REGION));
- dev_dbg(board->gpib_dev, "%s: misc base address remapped to 0x%p\n",
- driver_name, a_priv->misc_base);
+ dev_dbg(board->gpib_dev, "misc base address remapped to 0x%p\n", a_priv->misc_base);
break;
default:
- pr_err("%s: invalid board\n", driver_name);
- return -1;
+ dev_err(board->gpib_dev, "invalid board\n");
+ return -ENODEV;
}
retval = test_sram(board);
@@ -741,12 +690,12 @@ static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_c
return retval;
if (request_irq(a_priv->pci_device->irq, agilent_82350b_interrupt,
- IRQF_SHARED, driver_name, board)) {
- pr_err("%s: can't request IRQ %d\n", driver_name, a_priv->pci_device->irq);
+ IRQF_SHARED, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "failed to obtain irq %d\n", a_priv->pci_device->irq);
return -EIO;
}
a_priv->irq = a_priv->pci_device->irq;
- dev_dbg(board->gpib_dev, "%s: IRQ %d\n", driver_name, a_priv->irq);
+ dev_dbg(board->gpib_dev, " IRQ %d\n", a_priv->irq);
writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
a_priv->card_mode_bits = ENABLE_PCI_IRQ_BIT;
@@ -780,20 +729,19 @@ static int agilent_82350b_generic_attach(gpib_board_t *board, const gpib_board_c
return 0;
}
-int agilent_82350b_unaccel_attach(gpib_board_t *board, const gpib_board_config_t *config)
-
+static int agilent_82350b_unaccel_attach(struct gpib_board *board,
+ const gpib_board_config_t *config)
{
return agilent_82350b_generic_attach(board, config, 0);
}
-int agilent_82350b_accel_attach(gpib_board_t *board, const gpib_board_config_t *config)
-
+static int agilent_82350b_accel_attach(struct gpib_board *board,
+ const gpib_board_config_t *config)
{
return agilent_82350b_generic_attach(board, config, 1);
}
-void agilent_82350b_detach(gpib_board_t *board)
-
+static void agilent_82350b_detach(struct gpib_board *board)
{
struct agilent_82350b_priv *a_priv = board->private_data;
struct tms9914_priv *tms_priv;
@@ -848,6 +796,7 @@ static gpib_interface_t agilent_82350b_unaccel_interface = {
.primary_address = agilent_82350b_primary_address,
.secondary_address = agilent_82350b_secondary_address,
.serial_poll_response = agilent_82350b_serial_poll_response,
+ .serial_poll_status = agilent_82350b_serial_poll_status,
.t1_delay = agilent_82350b_t1_delay,
.return_to_local = agilent_82350b_return_to_local,
};
@@ -875,6 +824,7 @@ static gpib_interface_t agilent_82350b_interface = {
.primary_address = agilent_82350b_primary_address,
.secondary_address = agilent_82350b_secondary_address,
.serial_poll_response = agilent_82350b_serial_poll_response,
+ .serial_poll_status = agilent_82350b_serial_poll_status,
.t1_delay = agilent_82350b_t1_delay,
.return_to_local = agilent_82350b_return_to_local,
};
@@ -895,31 +845,30 @@ static const struct pci_device_id agilent_82350b_pci_table[] = {
MODULE_DEVICE_TABLE(pci, agilent_82350b_pci_table);
static struct pci_driver agilent_82350b_pci_driver = {
- .name = "agilent_82350b",
+ .name = DRV_NAME,
.id_table = agilent_82350b_pci_table,
.probe = &agilent_82350b_pci_probe
};
static int __init agilent_82350b_init_module(void)
-
{
int result;
result = pci_register_driver(&agilent_82350b_pci_driver);
if (result) {
- pr_err("agilent_82350b: pci_register_driver failed: error = %d\n", result);
+ pr_err("pci_register_driver failed: error = %d\n", result);
return result;
}
result = gpib_register_driver(&agilent_82350b_unaccel_interface, THIS_MODULE);
if (result) {
- pr_err("agilent_82350b: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_unaccel;
}
result = gpib_register_driver(&agilent_82350b_interface, THIS_MODULE);
if (result) {
- pr_err("agilent_82350b: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_interface;
}
@@ -934,7 +883,6 @@ err_unaccel:
}
static void __exit agilent_82350b_exit_module(void)
-
{
gpib_unregister_driver(&agilent_82350b_interface);
gpib_unregister_driver(&agilent_82350b_unaccel_interface);
diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h
index 32b322113c10..1573230c619d 100644
--- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h
+++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h
@@ -57,56 +57,6 @@ struct agilent_82350b_priv {
bool using_fifos;
};
-// driver name
-extern const char *driver_name;
-
-// init functions
-
-int agilent_82350b_unaccel_attach(gpib_board_t *board, const gpib_board_config_t *config);
-int agilent_82350b_accel_attach(gpib_board_t *board, const gpib_board_config_t *config);
-
-// interface functions
-int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read);
-int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
-int agilent_82350b_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read);
-int agilent_82350b_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
-int agilent_82350b_command(gpib_board_t *board, uint8_t *buffer, size_t length,
- size_t *bytes_written);
-int agilent_82350b_take_control(gpib_board_t *board, int synchronous);
-int agilent_82350b_go_to_standby(gpib_board_t *board);
-void agilent_82350b_request_system_control(gpib_board_t *board, int request_control);
-void agilent_82350b_interface_clear(gpib_board_t *board, int assert);
-void agilent_82350b_remote_enable(gpib_board_t *board, int enable);
-int agilent_82350b_enable_eos(gpib_board_t *board, uint8_t eos_byte, int
- compare_8_bits);
-void agilent_82350b_disable_eos(gpib_board_t *board);
-unsigned int agilent_82350b_update_status(gpib_board_t *board, unsigned int clear_mask);
-int agilent_82350b_primary_address(gpib_board_t *board, unsigned int address);
-int agilent_82350b_secondary_address(gpib_board_t *board, unsigned int address, int
- enable);
-int agilent_82350b_parallel_poll(gpib_board_t *board, uint8_t *result);
-void agilent_82350b_parallel_poll_configure(gpib_board_t *board, uint8_t config);
-void agilent_82350b_parallel_poll_response(gpib_board_t *board, int ist);
-void agilent_82350b_serial_poll_response(gpib_board_t *board, uint8_t status);
-void agilent_82350b_return_to_local(gpib_board_t *board);
-uint8_t agilent_82350b_serial_poll_status(gpib_board_t *board);
-int agilent_82350b_line_status(const gpib_board_t *board);
-unsigned int agilent_82350b_t1_delay(gpib_board_t *board, unsigned int nanosec);
-
-// interrupt service routines
-irqreturn_t agilent_82350b_interrupt(int irq, void *arg);
-
-// utility functions
-int agilent_82350b_allocate_private(gpib_board_t *board);
-void agilent_82350b_free_private(gpib_board_t *board);
-unsigned short read_and_clear_event_status(gpib_board_t *board);
-int read_transfer_counter(struct agilent_82350b_priv *a_priv);
-void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count);
-
//registers
enum agilent_82350b_gpib_registers
diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c
index 69f0e490d401..da229965d98e 100644
--- a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c
+++ b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c
@@ -7,6 +7,10 @@
#define _GNU_SOURCE
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -21,9 +25,10 @@ MODULE_DESCRIPTION("GPIB driver for Agilent 82357A/B usb adapters");
static struct usb_interface *agilent_82357a_driver_interfaces[MAX_NUM_82357A_INTERFACES];
static DEFINE_MUTEX(agilent_82357a_hotplug_lock); // protect board insertion and removal
-static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned int clear_mask);
+static unsigned int agilent_82357a_update_status(struct gpib_board *board,
+ unsigned int clear_mask);
-static int agilent_82357a_take_control_internal(gpib_board_t *board, int synchronous);
+static int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous);
static void agilent_82357a_bulk_complete(struct urb *urb)
{
@@ -79,14 +84,12 @@ static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void
retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);
if (retval) {
- dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to submit bulk out urb, retval=%i\n", retval);
mutex_unlock(&a_priv->bulk_alloc_lock);
goto cleanup;
}
mutex_unlock(&a_priv->bulk_alloc_lock);
if (down_interruptible(&context->complete)) {
- dev_err(&usb_dev->dev, "%s: interrupted\n", __func__);
retval = -ERESTARTSYS;
goto cleanup;
}
@@ -99,7 +102,7 @@ static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void
cleanup:
if (timeout_msecs) {
if (timer_pending(&a_priv->bulk_timer))
- del_timer_sync(&a_priv->bulk_timer);
+ timer_delete_sync(&a_priv->bulk_timer);
}
mutex_lock(&a_priv->bulk_alloc_lock);
if (a_priv->bulk_urb) {
@@ -149,14 +152,12 @@ static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, v
retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);
if (retval) {
- dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to submit bulk in urb, retval=%i\n", retval);
mutex_unlock(&a_priv->bulk_alloc_lock);
goto cleanup;
}
mutex_unlock(&a_priv->bulk_alloc_lock);
if (down_interruptible(&context->complete)) {
- dev_err(&usb_dev->dev, "%s: interrupted\n", __func__);
retval = -ERESTARTSYS;
goto cleanup;
}
@@ -168,7 +169,7 @@ static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, v
*actual_data_length = a_priv->bulk_urb->actual_length;
cleanup:
if (timeout_msecs)
- del_timer_sync(&a_priv->bulk_timer);
+ timer_delete_sync(&a_priv->bulk_timer);
mutex_lock(&a_priv->bulk_alloc_lock);
if (a_priv->bulk_urb) {
@@ -205,7 +206,6 @@ static int agilent_82357a_receive_control_msg(struct agilent_82357a_priv *a_priv
static void agilent_82357a_dump_raw_block(const u8 *raw_data, int length)
{
- pr_info("hex block dump\n");
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true);
}
@@ -225,7 +225,7 @@ static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,
static const int max_writes = 31;
if (num_writes > max_writes) {
- dev_err(&usb_dev->dev, "%s: bug! num_writes=%i too large\n", __func__, num_writes);
+ dev_err(&usb_dev->dev, "bug! num_writes=%i too large\n", num_writes);
return -EIO;
}
out_data_length = num_writes * bytes_per_write + header_length;
@@ -239,8 +239,7 @@ static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,
out_data[i++] = writes[j].address;
out_data[i++] = writes[j].value;
}
- if (i > out_data_length)
- dev_err(&usb_dev->dev, "%s: bug! buffer overrun\n", __func__);
+
retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
if (retval) {
kfree(out_data);
@@ -249,8 +248,8 @@ static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,
retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);
kfree(out_data);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
mutex_unlock(&a_priv->bulk_transfer_lock);
return retval;
}
@@ -265,20 +264,19 @@ static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,
mutex_unlock(&a_priv->bulk_transfer_lock);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
agilent_82357a_dump_raw_block(in_data, bytes_read);
kfree(in_data);
return -EIO;
}
if (in_data[0] != (0xff & ~DATA_PIPE_CMD_WR_REGS)) {
- dev_err(&usb_dev->dev, "%s: error, bulk command=0x%x != ~DATA_PIPE_CMD_WR_REGS\n",
- __func__, in_data[0]);
+ dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_WR_REGS\n", in_data[0]);
return -EIO;
}
if (in_data[1]) {
- dev_err(&usb_dev->dev, "%s: nonzero error code 0x%x in DATA_PIPE_CMD_WR_REGS response\n",
- __func__, in_data[1]);
+ dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_WR_REGS response\n",
+ in_data[1]);
return -EIO;
}
kfree(in_data);
@@ -299,9 +297,10 @@ static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,
static const int header_length = 2;
static const int max_reads = 62;
- if (num_reads > max_reads)
- dev_err(&usb_dev->dev, "%s: bug! num_reads=%i too large\n", __func__, num_reads);
-
+ if (num_reads > max_reads) {
+ dev_err(&usb_dev->dev, "bug! num_reads=%i too large\n", num_reads);
+ return -EIO;
+ }
out_data_length = num_reads + header_length;
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
@@ -311,8 +310,7 @@ static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,
out_data[i++] = num_reads;
for (j = 0; j < num_reads; j++)
out_data[i++] = reads[j].address;
- if (i > out_data_length)
- dev_err(&usb_dev->dev, "%s: bug! buffer overrun\n", __func__);
+
if (blocking) {
retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
if (retval) {
@@ -329,8 +327,8 @@ static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,
retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);
kfree(out_data);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
mutex_unlock(&a_priv->bulk_transfer_lock);
return retval;
}
@@ -345,21 +343,20 @@ static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,
mutex_unlock(&a_priv->bulk_transfer_lock);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
agilent_82357a_dump_raw_block(in_data, bytes_read);
kfree(in_data);
return -EIO;
}
i = 0;
if (in_data[i++] != (0xff & ~DATA_PIPE_CMD_RD_REGS)) {
- dev_err(&usb_dev->dev, "%s: error, bulk command=0x%x != ~DATA_PIPE_CMD_RD_REGS\n",
- __func__, in_data[0]);
+ dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_RD_REGS\n", in_data[0]);
return -EIO;
}
if (in_data[i++]) {
- dev_err(&usb_dev->dev, "%s: nonzero error code 0x%x in DATA_PIPE_CMD_RD_REGS response\n",
- __func__, in_data[1]);
+ dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_RD_REGS response\n",
+ in_data[1]);
return -EIO;
}
for (j = 0; j < num_reads; j++)
@@ -390,14 +387,13 @@ static int agilent_82357a_abort(struct agilent_82357a_priv *a_priv, int flush)
wIndex, status_data,
status_data_len, 100);
if (receive_control_retval < 0) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_control_msg() returned %i\n",
- __func__, receive_control_retval);
+ dev_err(&usb_dev->dev, "82357a_receive_control_msg() returned %i\n",
+ receive_control_retval);
retval = -EIO;
goto cleanup;
}
if (status_data[0] != (~XFER_ABORT & 0xff)) {
- dev_err(&usb_dev->dev, "%s: error, major code=0x%x != ~XFER_ABORT\n",
- __func__, status_data[0]);
+ dev_err(&usb_dev->dev, "major code=0x%x != ~XFER_ABORT\n", status_data[0]);
retval = -EIO;
goto cleanup;
}
@@ -413,8 +409,7 @@ static int agilent_82357a_abort(struct agilent_82357a_priv *a_priv, int flush)
fallthrough;
case UGP_ERR_FLUSHING_ALREADY:
default:
- dev_err(&usb_dev->dev, "%s: abort returned error code=0x%x\n",
- __func__, status_data[1]);
+ dev_err(&usb_dev->dev, "abort returned error code=0x%x\n", status_data[1]);
retval = -EIO;
break;
}
@@ -425,15 +420,15 @@ cleanup:
}
// interface functions
-int agilent_82357a_command(gpib_board_t *board, uint8_t *buffer, size_t length,
+int agilent_82357a_command(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written);
-static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
+static int agilent_82357a_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
size_t *nbytes)
{
int retval;
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
int out_data_length, in_data_length;
int bytes_written, bytes_read;
@@ -444,6 +439,10 @@ static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t leng
*nbytes = 0;
*end = 0;
+
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
out_data_length = 0x9;
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
@@ -469,8 +468,8 @@ static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t leng
retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, msec_timeout);
kfree(out_data);
if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
mutex_unlock(&a_priv->bulk_transfer_lock);
if (retval < 0)
return retval;
@@ -501,19 +500,19 @@ static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t leng
&extra_bytes_read, 100);
bytes_read += extra_bytes_read;
if (extra_bytes_retval) {
- dev_err(&usb_dev->dev, "%s: extra_bytes_retval=%i, bytes_read=%i\n",
- __func__, extra_bytes_retval, bytes_read);
+ dev_err(&usb_dev->dev, "extra_bytes_retval=%i, bytes_read=%i\n",
+ extra_bytes_retval, bytes_read);
agilent_82357a_abort(a_priv, 0);
}
} else if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
agilent_82357a_abort(a_priv, 0);
}
mutex_unlock(&a_priv->bulk_transfer_lock);
if (bytes_read > length + 1) {
bytes_read = length + 1;
- pr_warn("%s: bytes_read > length? truncating", __func__);
+ dev_warn(&usb_dev->dev, "bytes_read > length? truncating");
}
if (bytes_read >= 1) {
@@ -535,12 +534,14 @@ static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t leng
return retval;
}
-static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_commands, int send_eoi, size_t *bytes_written)
+static ssize_t agilent_82357a_generic_write(struct gpib_board *board,
+ uint8_t *buffer, size_t length,
+ int send_commands, int send_eoi,
+ size_t *bytes_written)
{
int retval;
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data = NULL;
u8 *status_data = NULL;
int out_data_length;
@@ -551,6 +552,10 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
struct agilent_82357a_register_pairlet read_reg;
*bytes_written = 0;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
out_data_length = length + 0x8;
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
@@ -584,8 +589,8 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
kfree(out_data);
if (retval || raw_bytes_written != i) {
agilent_82357a_abort(a_priv, 0);
- dev_err(&usb_dev->dev, "%s: agilent_82357a_send_bulk_msg returned %i, raw_bytes_written=%i, i=%i\n",
- __func__, retval, raw_bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, raw_bytes_written=%i, i=%i\n",
+ retval, raw_bytes_written, i);
mutex_unlock(&a_priv->bulk_transfer_lock);
if (retval < 0)
return retval;
@@ -597,7 +602,7 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
&a_priv->interrupt_flags) ||
test_bit(TIMO_NUM, &board->status));
if (retval) {
- dev_err(&usb_dev->dev, "%s: wait write complete interrupted\n", __func__);
+ dev_dbg(&usb_dev->dev, "wait write complete interrupted\n");
agilent_82357a_abort(a_priv, 0);
mutex_unlock(&a_priv->bulk_transfer_lock);
return -ERESTARTSYS;
@@ -614,8 +619,7 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
read_reg.address = BSR;
retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return -ETIMEDOUT;
}
@@ -632,8 +636,7 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
read_reg.address = ADSR;
retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return -ETIMEDOUT;
}
adsr = read_reg.value;
@@ -659,8 +662,7 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
100);
mutex_unlock(&a_priv->bulk_transfer_lock);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_receive_control_msg() returned %i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "receive_control_msg() returned %i\n", retval);
kfree(status_data);
return -EIO;
}
@@ -673,19 +675,19 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
return 0;
}
-static int agilent_82357a_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
+static int agilent_82357a_write(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int send_eoi, size_t *bytes_written)
{
return agilent_82357a_generic_write(board, buffer, length, 0, send_eoi, bytes_written);
}
-int agilent_82357a_command(gpib_board_t *board, uint8_t *buffer, size_t length,
+int agilent_82357a_command(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written)
{
return agilent_82357a_generic_write(board, buffer, length, 1, 0, bytes_written);
}
-int agilent_82357a_take_control_internal(gpib_board_t *board, int synchronous)
+int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous)
{
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
@@ -699,17 +701,20 @@ int agilent_82357a_take_control_internal(gpib_board_t *board, int synchronous)
write.value = AUX_TCA;
retval = agilent_82357a_write_registers(a_priv, &write, 1);
if (retval)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return retval;
}
-static int agilent_82357a_take_control(gpib_board_t *board, int synchronous)
+static int agilent_82357a_take_control(struct gpib_board *board, int synchronous)
{
+ struct agilent_82357a_priv *a_priv = board->private_data;
const int timeout = 10;
int i;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+
/* It looks like the 9914 does not handle tcs properly.
* See comment above tms9914_take_control_workaround() in
* drivers/gpib/tms9914/tms9914_aux.c
@@ -730,31 +735,39 @@ static int agilent_82357a_take_control(gpib_board_t *board, int synchronous)
return 0;
}
-static int agilent_82357a_go_to_standby(gpib_board_t *board)
+static int agilent_82357a_go_to_standby(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet write;
int retval;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
write.address = AUXCR;
write.value = AUX_GTS;
retval = agilent_82357a_write_registers(a_priv, &write, 1);
if (retval)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return 0;
}
//FIXME should change prototype to return int
-static void agilent_82357a_request_system_control(gpib_board_t *board, int request_control)
+static void agilent_82357a_request_system_control(struct gpib_board *board,
+ int request_control)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet writes[2];
int retval;
int i = 0;
+ if (!a_priv->bus_interface)
+ return; // -ENODEV;
+
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
/* 82357B needs bit to be set in 9914 AUXCR register */
writes[i].address = AUXCR;
if (request_control) {
@@ -771,18 +784,21 @@ static void agilent_82357a_request_system_control(gpib_board_t *board, int reque
++i;
retval = agilent_82357a_write_registers(a_priv, writes, i);
if (retval)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return;// retval;
}
-static void agilent_82357a_interface_clear(gpib_board_t *board, int assert)
+static void agilent_82357a_interface_clear(struct gpib_board *board, int assert)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet write;
int retval;
+ if (!a_priv->bus_interface)
+ return; // -ENODEV;
+
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
write.address = AUXCR;
write.value = AUX_SIC;
if (assert) {
@@ -791,56 +807,64 @@ static void agilent_82357a_interface_clear(gpib_board_t *board, int assert)
}
retval = agilent_82357a_write_registers(a_priv, &write, 1);
if (retval)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
}
-static void agilent_82357a_remote_enable(gpib_board_t *board, int enable)
+static void agilent_82357a_remote_enable(struct gpib_board *board, int enable)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet write;
int retval;
+ if (!a_priv->bus_interface)
+ return; //-ENODEV;
+
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
write.address = AUXCR;
write.value = AUX_SRE;
if (enable)
write.value |= AUX_CS;
retval = agilent_82357a_write_registers(a_priv, &write, 1);
if (retval)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
a_priv->ren_state = enable;
return;// 0;
}
-static int agilent_82357a_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int agilent_82357a_enable_eos(struct gpib_board *board, uint8_t eos_byte,
+ int compare_8_bits)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- if (compare_8_bits == 0) {
- pr_warn("%s: hardware only supports 8-bit EOS compare", __func__);
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ if (compare_8_bits == 0)
return -EOPNOTSUPP;
- }
+
a_priv->eos_char = eos_byte;
a_priv->eos_mode = REOS | BIN;
return 0;
}
-static void agilent_82357a_disable_eos(gpib_board_t *board)
+static void agilent_82357a_disable_eos(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv = board->private_data;
a_priv->eos_mode &= ~REOS;
}
-static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int agilent_82357a_update_status(struct gpib_board *board,
+ unsigned int clear_mask)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet address_status, bus_status;
int retval;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
board->status &= ~clear_mask;
if (a_priv->is_cic)
set_bit(CIC_NUM, &board->status);
@@ -850,8 +874,7 @@ static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned i
retval = agilent_82357a_read_registers(a_priv, &address_status, 1, 0);
if (retval) {
if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return board->status;
}
// check for remote/local
@@ -883,8 +906,7 @@ static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned i
retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
if (retval) {
if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return board->status;
}
if (bus_status.value & BSR_SRQ_BIT)
@@ -895,40 +917,46 @@ static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned i
return board->status;
}
-static int agilent_82357a_primary_address(gpib_board_t *board, unsigned int address)
+static int agilent_82357a_primary_address(struct gpib_board *board, unsigned int address)
{
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
struct agilent_82357a_register_pairlet write;
int retval;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
// put primary address in address0
write.address = ADR;
write.value = address & ADDRESS_MASK;
retval = agilent_82357a_write_registers(a_priv, &write, 1);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return retval;
}
return retval;
}
-static int agilent_82357a_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int agilent_82357a_secondary_address(struct gpib_board *board,
+ unsigned int address, int enable)
{
if (enable)
- pr_warn("%s: warning: assigning a secondary address not supported\n", __func__);
- return -EOPNOTSUPP;
+ return -EOPNOTSUPP;
+ return 0;
}
-static int agilent_82357a_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int agilent_82357a_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet writes[2];
struct agilent_82357a_register_pairlet read;
int retval;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
// execute parallel poll
writes[0].address = AUXCR;
writes[0].value = AUX_CS | AUX_RPP;
@@ -936,16 +964,14 @@ static int agilent_82357a_parallel_poll(gpib_board_t *board, uint8_t *result)
writes[1].value = a_priv->hw_control_bits & ~NOT_PARALLEL_POLL;
retval = agilent_82357a_write_registers(a_priv, writes, 2);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return retval;
}
udelay(2); //silly, since usb write will take way longer
read.address = CPTR;
retval = agilent_82357a_read_registers(a_priv, &read, 1, 1);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return retval;
}
*result = read.value;
@@ -956,75 +982,76 @@ static int agilent_82357a_parallel_poll(gpib_board_t *board, uint8_t *result)
writes[1].value = AUX_RPP;
retval = agilent_82357a_write_registers(a_priv, writes, 2);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return retval;
}
return 0;
}
-static void agilent_82357a_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void agilent_82357a_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
//board can only be system controller
return;// 0;
}
-static void agilent_82357a_parallel_poll_response(gpib_board_t *board, int ist)
+static void agilent_82357a_parallel_poll_response(struct gpib_board *board, int ist)
{
//board can only be system controller
return;// 0;
}
-static void agilent_82357a_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void agilent_82357a_serial_poll_response(struct gpib_board *board, uint8_t status)
{
//board can only be system controller
return;// 0;
}
-static uint8_t agilent_82357a_serial_poll_status(gpib_board_t *board)
+static uint8_t agilent_82357a_serial_poll_status(struct gpib_board *board)
{
//board can only be system controller
return 0;
}
-static void agilent_82357a_return_to_local(gpib_board_t *board)
+static void agilent_82357a_return_to_local(struct gpib_board *board)
{
//board can only be system controller
return;// 0;
}
-static int agilent_82357a_line_status(const gpib_board_t *board)
+static int agilent_82357a_line_status(const struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet bus_status;
int retval;
- int status = ValidALL;
+ int status = VALID_ALL;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
bus_status.address = BSR;
retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
if (retval) {
if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return retval;
}
if (bus_status.value & BSR_REN_BIT)
- status |= BusREN;
+ status |= BUS_REN;
if (bus_status.value & BSR_IFC_BIT)
- status |= BusIFC;
+ status |= BUS_IFC;
if (bus_status.value & BSR_SRQ_BIT)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if (bus_status.value & BSR_EOI_BIT)
- status |= BusEOI;
+ status |= BUS_EOI;
if (bus_status.value & BSR_NRFD_BIT)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if (bus_status.value & BSR_NDAC_BIT)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if (bus_status.value & BSR_DAV_BIT)
- status |= BusDAV;
+ status |= BUS_DAV;
if (bus_status.value & BSR_ATN_BIT)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
@@ -1044,25 +1071,27 @@ static unsigned short nanosec_to_fast_talker_bits(unsigned int *nanosec)
return bits;
}
-static unsigned int agilent_82357a_t1_delay(gpib_board_t *board, unsigned int nanosec)
+static int agilent_82357a_t1_delay(struct gpib_board *board, unsigned int nanosec)
{
struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
+ struct usb_device *usb_dev;
struct agilent_82357a_register_pairlet write;
int retval;
+ if (!a_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(a_priv->bus_interface);
write.address = FAST_TALKER_T1;
write.value = nanosec_to_fast_talker_bits(&nanosec);
retval = agilent_82357a_write_registers(a_priv, &write, 1);
if (retval)
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return nanosec;
}
static void agilent_82357a_interrupt_complete(struct urb *urb)
{
- gpib_board_t *board = urb->context;
+ struct gpib_board *board = urb->context;
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
int retval;
@@ -1081,7 +1110,7 @@ static void agilent_82357a_interrupt_complete(struct urb *urb)
default: /* other error, resubmit */
retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);
if (retval)
- dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__);
+ dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
return;
}
@@ -1097,10 +1126,10 @@ static void agilent_82357a_interrupt_complete(struct urb *urb)
retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);
if (retval)
- dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__);
+ dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
}
-static int agilent_82357a_setup_urbs(gpib_board_t *board)
+static int agilent_82357a_setup_urbs(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev;
@@ -1133,8 +1162,7 @@ static int agilent_82357a_setup_urbs(gpib_board_t *board)
if (retval) {
usb_free_urb(a_priv->interrupt_urb);
a_priv->interrupt_urb = NULL;
- dev_err(&usb_dev->dev, "%s: failed to submit first interrupt urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to submit first interrupt urb, retval=%i\n", retval);
goto setup_exit;
}
mutex_unlock(&a_priv->interrupt_alloc_lock);
@@ -1165,7 +1193,7 @@ static void agilent_82357a_release_urbs(struct agilent_82357a_priv *a_priv)
}
}
-static int agilent_82357a_allocate_private(gpib_board_t *board)
+static int agilent_82357a_allocate_private(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv;
@@ -1180,112 +1208,82 @@ static int agilent_82357a_allocate_private(gpib_board_t *board)
return 0;
}
-static void agilent_82357a_free_private(gpib_board_t *board)
+static void agilent_82357a_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
-
}
-static int agilent_82357a_init(gpib_board_t *board)
+#define INIT_NUM_REG_WRITES 18
+static int agilent_82357a_init(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
struct agilent_82357a_register_pairlet hw_control;
- struct agilent_82357a_register_pairlet writes[0x20];
+ struct agilent_82357a_register_pairlet writes[INIT_NUM_REG_WRITES];
int retval;
- int i;
unsigned int nanosec;
- i = 0;
- writes[i].address = LED_CONTROL;
- writes[i].value = FAIL_LED_ON;
- ++i;
- writes[i].address = RESET_TO_POWERUP;
- writes[i].value = RESET_SPACEBALL;
- ++i;
- retval = agilent_82357a_write_registers(a_priv, writes, i);
+ writes[0].address = LED_CONTROL;
+ writes[0].value = FAIL_LED_ON;
+ writes[1].address = RESET_TO_POWERUP;
+ writes[1].value = RESET_SPACEBALL;
+ retval = agilent_82357a_write_registers(a_priv, writes, 2);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return -EIO;
}
set_current_state(TASK_INTERRUPTIBLE);
if (schedule_timeout(usec_to_jiffies(2000)))
return -ERESTARTSYS;
- i = 0;
- writes[i].address = AUXCR;
- writes[i].value = AUX_NBAF;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_HLDE;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_TON;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_LON;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_RSV2;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_INVAL;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_RPP;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_STDL;
- ++i;
- writes[i].address = AUXCR;
- writes[i].value = AUX_VSTDL;
- ++i;
- writes[i].address = FAST_TALKER_T1;
+ writes[0].address = AUXCR;
+ writes[0].value = AUX_NBAF;
+ writes[1].address = AUXCR;
+ writes[1].value = AUX_HLDE;
+ writes[2].address = AUXCR;
+ writes[2].value = AUX_TON;
+ writes[3].address = AUXCR;
+ writes[3].value = AUX_LON;
+ writes[4].address = AUXCR;
+ writes[4].value = AUX_RSV2;
+ writes[5].address = AUXCR;
+ writes[5].value = AUX_INVAL;
+ writes[6].address = AUXCR;
+ writes[6].value = AUX_RPP;
+ writes[7].address = AUXCR;
+ writes[7].value = AUX_STDL;
+ writes[8].address = AUXCR;
+ writes[8].value = AUX_VSTDL;
+ writes[9].address = FAST_TALKER_T1;
nanosec = board->t1_nano_sec;
- writes[i].value = nanosec_to_fast_talker_bits(&nanosec);
+ writes[9].value = nanosec_to_fast_talker_bits(&nanosec);
board->t1_nano_sec = nanosec;
- ++i;
- writes[i].address = ADR;
- writes[i].value = board->pad & ADDRESS_MASK;
- ++i;
- writes[i].address = PPR;
- writes[i].value = 0;
- ++i;
- writes[i].address = SPMR;
- writes[i].value = 0;
- ++i;
- writes[i].address = PROTOCOL_CONTROL;
- writes[i].value = WRITE_COMPLETE_INTERRUPT_EN;
- ++i;
- writes[i].address = IMR0;
- writes[i].value = HR_BOIE | HR_BIIE;
- ++i;
- writes[i].address = IMR1;
- writes[i].value = HR_SRQIE;
- ++i;
+ writes[10].address = ADR;
+ writes[10].value = board->pad & ADDRESS_MASK;
+ writes[11].address = PPR;
+ writes[11].value = 0;
+ writes[12].address = SPMR;
+ writes[12].value = 0;
+ writes[13].address = PROTOCOL_CONTROL;
+ writes[13].value = WRITE_COMPLETE_INTERRUPT_EN;
+ writes[14].address = IMR0;
+ writes[14].value = HR_BOIE | HR_BIIE;
+ writes[15].address = IMR1;
+ writes[15].value = HR_SRQIE;
// turn off reset state
- writes[i].address = AUXCR;
- writes[i].value = AUX_CHIP_RESET;
- ++i;
- writes[i].address = LED_CONTROL;
- writes[i].value = FIRMWARE_LED_CONTROL;
- ++i;
- if (i > ARRAY_SIZE(writes)) {
- dev_err(&usb_dev->dev, "%s: bug! writes[] overflow\n", __func__);
- return -EFAULT;
- }
- retval = agilent_82357a_write_registers(a_priv, writes, i);
+ writes[16].address = AUXCR;
+ writes[16].value = AUX_CHIP_RESET;
+ writes[17].address = LED_CONTROL;
+ writes[17].value = FIRMWARE_LED_CONTROL;
+ retval = agilent_82357a_write_registers(a_priv, writes, INIT_NUM_REG_WRITES);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return -EIO;
}
hw_control.address = HW_CONTROL;
retval = agilent_82357a_read_registers(a_priv, &hw_control, 1, 1);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_read_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "read_registers() returned error\n");
return -EIO;
}
a_priv->hw_control_bits = (hw_control.value & ~0x7) | NOT_TI_RESET | NOT_PARALLEL_POLL;
@@ -1307,7 +1305,7 @@ static inline int agilent_82357a_device_match(struct usb_interface *interface,
return 1;
}
-static int agilent_82357a_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int agilent_82357a_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
int retval;
int i;
@@ -1336,7 +1334,7 @@ static int agilent_82357a_attach(gpib_board_t *board, const gpib_board_config_t
}
if (i == MAX_NUM_82357A_INTERFACES) {
dev_err(board->gpib_dev,
- "No Agilent 82357 gpib adapters found, have you loaded its firmware?\n");
+ "No supported adapters found, have you loaded its firmware?\n");
retval = -ENODEV;
goto attach_fail;
}
@@ -1372,8 +1370,7 @@ static int agilent_82357a_attach(gpib_board_t *board, const gpib_board_config_t
goto attach_fail;
}
- dev_info(&usb_dev->dev,
- "bus %d dev num %d attached to gpib minor %d, agilent usb interface %i\n",
+ dev_info(&usb_dev->dev, "bus %d dev num %d attached to gpib%d, interface %i\n",
usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
mutex_unlock(&agilent_82357a_hotplug_lock);
return retval;
@@ -1384,49 +1381,36 @@ attach_fail:
return retval;
}
-static int agilent_82357a_go_idle(gpib_board_t *board)
+static int agilent_82357a_go_idle(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
struct agilent_82357a_register_pairlet writes[0x20];
int retval;
- int i;
- i = 0;
// turn on tms9914 reset state
- writes[i].address = AUXCR;
- writes[i].value = AUX_CS | AUX_CHIP_RESET;
- ++i;
+ writes[0].address = AUXCR;
+ writes[0].value = AUX_CS | AUX_CHIP_RESET;
a_priv->hw_control_bits &= ~NOT_TI_RESET;
- writes[i].address = HW_CONTROL;
- writes[i].value = a_priv->hw_control_bits;
- ++i;
- writes[i].address = PROTOCOL_CONTROL;
- writes[i].value = 0;
- ++i;
- writes[i].address = IMR0;
- writes[i].value = 0;
- ++i;
- writes[i].address = IMR1;
- writes[i].value = 0;
- ++i;
- writes[i].address = LED_CONTROL;
- writes[i].value = 0;
- ++i;
- if (i > ARRAY_SIZE(writes)) {
- dev_err(&usb_dev->dev, "%s: bug! writes[] overflow\n", __func__);
- return -EFAULT;
- }
- retval = agilent_82357a_write_registers(a_priv, writes, i);
+ writes[1].address = HW_CONTROL;
+ writes[1].value = a_priv->hw_control_bits;
+ writes[2].address = PROTOCOL_CONTROL;
+ writes[2].value = 0;
+ writes[3].address = IMR0;
+ writes[3].value = 0;
+ writes[4].address = IMR1;
+ writes[4].value = 0;
+ writes[5].address = LED_CONTROL;
+ writes[5].value = 0;
+ retval = agilent_82357a_write_registers(a_priv, writes, 6);
if (retval) {
- dev_err(&usb_dev->dev, "%s: agilent_82357a_write_registers() returned error\n",
- __func__);
+ dev_err(&usb_dev->dev, "write_registers() returned error\n");
return -EIO;
}
return 0;
}
-static void agilent_82357a_detach(gpib_board_t *board)
+static void agilent_82357a_detach(struct gpib_board *board)
{
struct agilent_82357a_priv *a_priv;
@@ -1445,7 +1429,6 @@ static void agilent_82357a_detach(gpib_board_t *board)
agilent_82357a_release_urbs(a_priv);
agilent_82357a_free_private(board);
}
- dev_info(board->gpib_dev, "%s: detached\n", __func__);
mutex_unlock(&agilent_82357a_hotplug_lock);
}
@@ -1510,8 +1493,7 @@ static int agilent_82357a_driver_probe(struct usb_interface *interface,
if (i == MAX_NUM_82357A_INTERFACES) {
usb_put_dev(usb_dev);
mutex_unlock(&agilent_82357a_hotplug_lock);
- dev_err(&usb_dev->dev, "%s: out of space in agilent_82357a_driver_interfaces[]\n",
- __func__);
+ dev_err(&usb_dev->dev, "out of space in agilent_82357a_driver_interfaces[]\n");
return -1;
}
path = kmalloc(path_length, GFP_KERNEL);
@@ -1536,7 +1518,7 @@ static void agilent_82357a_driver_disconnect(struct usb_interface *interface)
for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
if (agilent_82357a_driver_interfaces[i] == interface) {
- gpib_board_t *board = usb_get_intfdata(interface);
+ struct gpib_board *board = usb_get_intfdata(interface);
if (board) {
struct agilent_82357a_priv *a_priv = board->private_data;
@@ -1552,13 +1534,12 @@ static void agilent_82357a_driver_disconnect(struct usb_interface *interface)
mutex_unlock(&a_priv->control_alloc_lock);
}
}
- dev_dbg(&usb_dev->dev, "nulled agilent_82357a_driver_interfaces[%i]\n", i);
agilent_82357a_driver_interfaces[i] = NULL;
break;
}
}
if (i == MAX_NUM_82357A_INTERFACES)
- dev_err(&usb_dev->dev, "unable to find interface in agilent_82357a_driver_interfaces[]? bug?\n");
+ dev_err(&usb_dev->dev, "unable to find interface - bug?\n");
usb_put_dev(usb_dev);
mutex_unlock(&agilent_82357a_hotplug_lock);
@@ -1573,7 +1554,7 @@ static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_mes
for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
if (agilent_82357a_driver_interfaces[i] == interface) {
- gpib_board_t *board = usb_get_intfdata(interface);
+ struct gpib_board *board = usb_get_intfdata(interface);
if (board) {
struct agilent_82357a_priv *a_priv = board->private_data;
@@ -1583,18 +1564,18 @@ static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_mes
agilent_82357a_abort(a_priv, 0);
retval = agilent_82357a_go_idle(board);
if (retval) {
- dev_err(&usb_dev->dev, "%s: failed to go idle, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to go idle, retval=%i\n",
+ retval);
mutex_unlock(&agilent_82357a_hotplug_lock);
return retval;
}
mutex_lock(&a_priv->interrupt_alloc_lock);
agilent_82357a_cleanup_urbs(a_priv);
mutex_unlock(&a_priv->interrupt_alloc_lock);
- dev_info(&usb_dev->dev,
- "bus %d dev num %d gpib minor %d, agilent usb interface %i suspended\n",
- usb_dev->bus->busnum, usb_dev->devnum,
- board->minor, i);
+ dev_dbg(&usb_dev->dev,
+ "bus %d dev num %d gpib %d, interface %i suspended\n",
+ usb_dev->bus->busnum, usb_dev->devnum,
+ board->minor, i);
}
}
break;
@@ -1609,7 +1590,7 @@ static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_mes
static int agilent_82357a_driver_resume(struct usb_interface *interface)
{
struct usb_device *usb_dev = interface_to_usbdev(interface);
- gpib_board_t *board;
+ struct gpib_board *board;
int i, retval;
mutex_lock(&agilent_82357a_hotplug_lock);
@@ -1631,8 +1612,8 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface)
mutex_lock(&a_priv->interrupt_alloc_lock);
retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);
if (retval) {
- dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to resubmit interrupt urb in resume, retval=%i\n",
+ retval);
mutex_unlock(&a_priv->interrupt_alloc_lock);
mutex_unlock(&agilent_82357a_hotplug_lock);
return retval;
@@ -1655,9 +1636,9 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface)
// assert/unassert REN
agilent_82357a_remote_enable(board, a_priv->ren_state);
- dev_info(&usb_dev->dev,
- "bus %d dev num %d gpib minor %d, agilent usb interface %i resumed\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
+ dev_dbg(&usb_dev->dev,
+ "bus %d dev num %d gpib%d, interface %i resumed\n",
+ usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
}
resume_exit:
@@ -1667,7 +1648,7 @@ resume_exit:
}
static struct usb_driver agilent_82357a_bus_driver = {
- .name = "agilent_82357a_gpib",
+ .name = DRV_NAME,
.probe = agilent_82357a_driver_probe,
.disconnect = agilent_82357a_driver_disconnect,
.suspend = agilent_82357a_driver_suspend,
@@ -1680,19 +1661,18 @@ static int __init agilent_82357a_init_module(void)
int i;
int ret;
- pr_info("agilent_82357a_gpib driver loading");
for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i)
agilent_82357a_driver_interfaces[i] = NULL;
ret = usb_register(&agilent_82357a_bus_driver);
if (ret) {
- pr_err("agilent_82357a: usb_register failed: error = %d\n", ret);
+ pr_err("usb_register failed: error = %d\n", ret);
return ret;
}
ret = gpib_register_driver(&agilent_82357a_gpib_interface, THIS_MODULE);
if (ret) {
- pr_err("agilent_82357a: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
usb_deregister(&agilent_82357a_bus_driver);
return ret;
}
@@ -1702,7 +1682,6 @@ static int __init agilent_82357a_init_module(void)
static void __exit agilent_82357a_exit_module(void)
{
- pr_info("agilent_82357a_gpib driver unloading");
gpib_unregister_driver(&agilent_82357a_gpib_interface);
usb_deregister(&agilent_82357a_bus_driver);
}
diff --git a/drivers/staging/gpib/cb7210/Makefile b/drivers/staging/gpib/cb7210/Makefile
index cda0725d6487..d239ae80b415 100644
--- a/drivers/staging/gpib/cb7210/Makefile
+++ b/drivers/staging/gpib/cb7210/Makefile
@@ -1,4 +1,3 @@
-ccflags-$(CONFIG_GPIB_PCMCIA) := -DGPIB_PCMCIA
obj-$(CONFIG_GPIB_CB7210) += cb7210.o
diff --git a/drivers/staging/gpib/cb7210/cb7210.c b/drivers/staging/gpib/cb7210/cb7210.c
index 4d22f647a453..6b22a33a8c4f 100644
--- a/drivers/staging/gpib/cb7210/cb7210.c
+++ b/drivers/staging/gpib/cb7210/cb7210.c
@@ -5,6 +5,10 @@
* copyright : (C) 2001, 2002 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "cb7210.h"
#include <linux/ioport.h>
#include <linux/sched.h>
@@ -23,7 +27,10 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver Measurement Computing boards using cb7210.2 and cbi488.2");
-static inline int have_fifo_word(const struct cb7210_priv *cb_priv)
+static int cb7210_read(struct gpib_board *board, uint8_t *buffer, size_t length,
+ int *end, size_t *bytes_read);
+
+ static inline int have_fifo_word(const struct cb7210_priv *cb_priv)
{
if (((cb7210_read_byte(cb_priv, HS_STATUS)) &
(HS_RX_MSB_NOT_EMPTY | HS_RX_LSB_NOT_EMPTY)) ==
@@ -33,7 +40,7 @@ static inline int have_fifo_word(const struct cb7210_priv *cb_priv)
return 0;
}
-static inline void input_fifo_enable(gpib_board_t *board, int enable)
+static inline void input_fifo_enable(struct gpib_board *board, int enable)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
@@ -69,7 +76,7 @@ static inline void input_fifo_enable(gpib_board_t *board, int enable)
spin_unlock_irqrestore(&board->spinlock, flags);
}
-static int fifo_read(gpib_board_t *board, struct cb7210_priv *cb_priv, uint8_t *buffer,
+static int fifo_read(struct gpib_board *board, struct cb7210_priv *cb_priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
ssize_t retval = 0;
@@ -80,12 +87,12 @@ static int fifo_read(gpib_board_t *board, struct cb7210_priv *cb_priv, uint8_t *
*bytes_read = 0;
if (cb_priv->fifo_iobase == 0) {
- pr_err("cb7210: fifo iobase is zero!\n");
+ dev_err(board->gpib_dev, "fifo iobase is zero!\n");
return -EIO;
}
*end = 0;
if (length <= cb7210_fifo_size) {
- pr_err("cb7210: bug! %s with length < fifo size\n", __func__);
+ dev_err(board->gpib_dev, " bug! fifo read length < fifo size\n");
return -EINVAL;
}
@@ -100,7 +107,6 @@ static int fifo_read(gpib_board_t *board, struct cb7210_priv *cb_priv, uint8_t *
test_bit(RECEIVED_END_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_warn("cb7210: fifo half full wait interrupted\n");
retval = -ERESTARTSYS;
nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
break;
@@ -150,7 +156,6 @@ static int fifo_read(gpib_board_t *board, struct cb7210_priv *cb_priv, uint8_t *
test_bit(RECEIVED_END_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_warn("cb7210: fifo half full wait interrupted\n");
retval = -ERESTARTSYS;
}
if (test_bit(TIMO_NUM, &board->status))
@@ -165,8 +170,8 @@ static int fifo_read(gpib_board_t *board, struct cb7210_priv *cb_priv, uint8_t *
return retval;
}
-int cb7210_accel_read(gpib_board_t *board, uint8_t *buffer,
- size_t length, int *end, size_t *bytes_read)
+static int cb7210_accel_read(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int *end, size_t *bytes_read)
{
ssize_t retval;
struct cb7210_priv *cb_priv = board->private_data;
@@ -185,7 +190,6 @@ int cb7210_accel_read(gpib_board_t *board, uint8_t *buffer,
test_bit(READ_READY_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_warn("cb7210: read ready wait interrupted\n");
return -ERESTARTSYS;
}
if (test_bit(TIMO_NUM, &board->status))
@@ -225,7 +229,7 @@ static int output_fifo_empty(const struct cb7210_priv *cb_priv)
return 0;
}
-static inline void output_fifo_enable(gpib_board_t *board, int enable)
+static inline void output_fifo_enable(struct gpib_board *board, int enable)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
@@ -260,7 +264,8 @@ static inline void output_fifo_enable(gpib_board_t *board, int enable)
spin_unlock_irqrestore(&board->spinlock, flags);
}
-static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int fifo_write(struct gpib_board *board, uint8_t *buffer, size_t length,
+ size_t *bytes_written)
{
size_t count = 0;
ssize_t retval = 0;
@@ -271,7 +276,7 @@ static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_
*bytes_written = 0;
if (cb_priv->fifo_iobase == 0) {
- pr_err("cb7210: fifo iobase is zero!\n");
+ dev_err(board->gpib_dev, "fifo iobase is zero!\n");
return -EINVAL;
}
if (length == 0)
@@ -290,7 +295,6 @@ static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_warn("cb7210: fifo wait interrupted\n");
retval = -ERESTARTSYS;
break;
}
@@ -306,7 +310,7 @@ static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_
if (num_bytes + count > length)
num_bytes = length - count;
if (num_bytes % cb7210_fifo_width) {
- pr_err("cb7210: bug! %s with odd number of bytes\n", __func__);
+ dev_err(board->gpib_dev, " bug! fifo write with odd number of bytes\n");
retval = -EINVAL;
break;
}
@@ -331,7 +335,6 @@ static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_err("cb7210: wait for last byte interrupted\n");
retval = -ERESTARTSYS;
}
if (test_bit(TIMO_NUM, &board->status))
@@ -347,8 +350,8 @@ static int fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length, size_
return retval;
}
-int cb7210_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int cb7210_accel_write(struct gpib_board *board, uint8_t *buffer,
+ size_t length, int send_eoi, size_t *bytes_written)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
@@ -375,39 +378,37 @@ int cb7210_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int
return retval;
}
-int cb7210_line_status(const gpib_board_t *board)
+static int cb7210_line_status(const struct gpib_board *board)
{
- int status = ValidALL;
+ int status = VALID_ALL;
int bsr_bits;
struct cb7210_priv *cb_priv;
- struct nec7210_priv *nec_priv;
cb_priv = board->private_data;
- nec_priv = &cb_priv->nec7210_priv;
bsr_bits = cb7210_paged_read_byte(cb_priv, BUS_STATUS, BUS_STATUS_PAGE);
if ((bsr_bits & BSR_REN_BIT) == 0)
- status |= BusREN;
+ status |= BUS_REN;
if ((bsr_bits & BSR_IFC_BIT) == 0)
- status |= BusIFC;
+ status |= BUS_IFC;
if ((bsr_bits & BSR_SRQ_BIT) == 0)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if ((bsr_bits & BSR_EOI_BIT) == 0)
- status |= BusEOI;
+ status |= BUS_EOI;
if ((bsr_bits & BSR_NRFD_BIT) == 0)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if ((bsr_bits & BSR_NDAC_BIT) == 0)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if ((bsr_bits & BSR_DAV_BIT) == 0)
- status |= BusDAV;
+ status |= BUS_DAV;
if ((bsr_bits & BSR_ATN_BIT) == 0)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
-unsigned int cb7210_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int cb7210_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
@@ -424,16 +425,16 @@ unsigned int cb7210_t1_delay(gpib_board_t *board, unsigned int nano_sec)
return retval;
}
-irqreturn_t cb7210_locked_internal_interrupt(gpib_board_t *board);
+static irqreturn_t cb7210_locked_internal_interrupt(struct gpib_board *board);
/*
* GPIB interrupt service routines
*/
-irqreturn_t cb_pci_interrupt(int irq, void *arg)
+static irqreturn_t cb_pci_interrupt(int irq, void *arg)
{
int bits;
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct cb7210_priv *priv = board->private_data;
// first task check if this is really our interrupt in a shared irq environment
@@ -462,7 +463,7 @@ irqreturn_t cb_pci_interrupt(int irq, void *arg)
return cb7210_locked_internal_interrupt(arg);
}
-irqreturn_t cb7210_internal_interrupt(gpib_board_t *board)
+static irqreturn_t cb7210_internal_interrupt(struct gpib_board *board)
{
int hs_status, status1, status2;
struct cb7210_priv *priv = board->private_data;
@@ -479,7 +480,7 @@ irqreturn_t cb7210_internal_interrupt(gpib_board_t *board)
status2 = read_byte(nec_priv, ISR2);
nec7210_interrupt_have_status(board, nec_priv, status1, status2);
- dev_dbg(board->gpib_dev, "cb7210: status 0x%x, mode 0x%x\n", hs_status, priv->hs_mode_bits);
+ dev_dbg(board->gpib_dev, "status 0x%x, mode 0x%x\n", hs_status, priv->hs_mode_bits);
clear_bits = 0;
@@ -516,7 +517,7 @@ irqreturn_t cb7210_internal_interrupt(gpib_board_t *board)
return IRQ_HANDLED;
}
-irqreturn_t cb7210_locked_internal_interrupt(gpib_board_t *board)
+static irqreturn_t cb7210_locked_internal_interrupt(struct gpib_board *board)
{
unsigned long flags;
irqreturn_t retval;
@@ -527,55 +528,57 @@ irqreturn_t cb7210_locked_internal_interrupt(gpib_board_t *board)
return retval;
}
-irqreturn_t cb7210_interrupt(int irq, void *arg)
+static irqreturn_t cb7210_interrupt(int irq, void *arg)
{
return cb7210_internal_interrupt(arg);
}
-static int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int cb_isa_attach(gpib_board_t *board, const gpib_board_config_t *config);
+static int cb_pci_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static int cb_isa_attach(struct gpib_board *board, const gpib_board_config_t *config);
-static void cb_pci_detach(gpib_board_t *board);
-static void cb_isa_detach(gpib_board_t *board);
+static void cb_pci_detach(struct gpib_board *board);
+static void cb_isa_detach(struct gpib_board *board);
// wrappers for interface functions
-int cb7210_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
+static int cb7210_read(struct gpib_board *board, uint8_t *buffer, size_t length,
+ int *end, size_t *bytes_read)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
}
-int cb7210_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
+static int cb7210_write(struct gpib_board *board, uint8_t *buffer, size_t length,
+ int send_eoi, size_t *bytes_written)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-int cb7210_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int cb7210_command(struct gpib_board *board, uint8_t *buffer, size_t length,
+ size_t *bytes_written)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-int cb7210_take_control(gpib_board_t *board, int synchronous)
+static int cb7210_take_control(struct gpib_board *board, int synchronous)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-int cb7210_go_to_standby(gpib_board_t *board)
+static int cb7210_go_to_standby(struct gpib_board *board)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-void cb7210_request_system_control(gpib_board_t *board, int request_control)
+static void cb7210_request_system_control(struct gpib_board *board, int request_control)
{
struct cb7210_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -589,91 +592,91 @@ void cb7210_request_system_control(gpib_board_t *board, int request_control)
nec7210_request_system_control(board, nec_priv, request_control);
}
-void cb7210_interface_clear(gpib_board_t *board, int assert)
+static void cb7210_interface_clear(struct gpib_board *board, int assert)
{
struct cb7210_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-void cb7210_remote_enable(gpib_board_t *board, int enable)
+static void cb7210_remote_enable(struct gpib_board *board, int enable)
{
struct cb7210_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-int cb7210_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int cb7210_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-void cb7210_disable_eos(gpib_board_t *board)
+static void cb7210_disable_eos(struct gpib_board *board)
{
struct cb7210_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-unsigned int cb7210_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int cb7210_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
}
-int cb7210_primary_address(gpib_board_t *board, unsigned int address)
+static int cb7210_primary_address(struct gpib_board *board, unsigned int address)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-int cb7210_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int cb7210_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-int cb7210_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int cb7210_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
}
-void cb7210_parallel_poll_configure(gpib_board_t *board, uint8_t configuration)
+static void cb7210_parallel_poll_configure(struct gpib_board *board, uint8_t configuration)
{
struct cb7210_priv *priv = board->private_data;
nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration);
}
-void cb7210_parallel_poll_response(gpib_board_t *board, int ist)
+static void cb7210_parallel_poll_response(struct gpib_board *board, int ist)
{
struct cb7210_priv *priv = board->private_data;
nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
}
-void cb7210_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void cb7210_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct cb7210_priv *priv = board->private_data;
nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
}
-uint8_t cb7210_serial_poll_status(gpib_board_t *board)
+static uint8_t cb7210_serial_poll_status(struct gpib_board *board)
{
struct cb7210_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-void cb7210_return_to_local(gpib_board_t *board)
+static void cb7210_return_to_local(struct gpib_board *board)
{
struct cb7210_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -849,27 +852,27 @@ static gpib_interface_t cb_isa_accel_interface = {
.return_to_local = cb7210_return_to_local,
};
-static int cb7210_allocate_private(gpib_board_t *board)
+static int cb7210_allocate_private(struct gpib_board *board)
{
struct cb7210_priv *priv;
board->private_data = kmalloc(sizeof(struct cb7210_priv), GFP_KERNEL);
if (!board->private_data)
- return -1;
+ return -ENOMEM;
priv = board->private_data;
memset(priv, 0, sizeof(struct cb7210_priv));
init_nec7210_private(&priv->nec7210_priv);
return 0;
}
-void cb7210_generic_detach(gpib_board_t *board)
+static void cb7210_generic_detach(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
// generic part of attach functions shared by all cb7210 boards
-int cb7210_generic_attach(gpib_board_t *board)
+static int cb7210_generic_attach(struct gpib_board *board)
{
struct cb7210_priv *cb_priv;
struct nec7210_priv *nec_priv;
@@ -887,7 +890,7 @@ int cb7210_generic_attach(gpib_board_t *board)
return 0;
}
-int cb7210_init(struct cb7210_priv *cb_priv, gpib_board_t *board)
+static int cb7210_init(struct cb7210_priv *cb_priv, struct gpib_board *board)
{
struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
@@ -917,13 +920,13 @@ int cb7210_init(struct cb7210_priv *cb_priv, gpib_board_t *board)
/* poll so we can detect assertion of ATN */
if (gpib_request_pseudo_irq(board, cb_pci_interrupt)) {
- pr_err("pc2_gpib: failed to allocate pseudo_irq\n");
+ pr_err("failed to allocate pseudo_irq\n");
return -1;
}
return 0;
}
-int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int cb_pci_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct cb7210_priv *cb_priv;
struct nec7210_priv *nec_priv;
@@ -957,17 +960,17 @@ int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
}
}
if (!cb_priv->pci_device) {
- pr_warn("cb7210: no supported boards found.\n");
- return -1;
+ dev_err(board->gpib_dev, "no supported boards found.\n");
+ return -ENODEV;
}
if (pci_enable_device(cb_priv->pci_device)) {
- pr_err("cb7210: error enabling pci device\n");
- return -1;
+ dev_err(board->gpib_dev, "error enabling pci device\n");
+ return -EIO;
}
- if (pci_request_regions(cb_priv->pci_device, "cb7210"))
- return -1;
+ if (pci_request_regions(cb_priv->pci_device, DRV_NAME))
+ return -EBUSY;
switch (cb_priv->pci_chip) {
case PCI_CHIP_AMCC_S5933:
cb_priv->amcc_iobase = pci_resource_start(cb_priv->pci_device, 0);
@@ -979,13 +982,14 @@ int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
cb_priv->fifo_iobase = nec_priv->iobase;
break;
default:
- pr_err("cb7210: bug! unhandled pci_chip=%i\n", cb_priv->pci_chip);
+ dev_err(board->gpib_dev, "bug! unhandled pci_chip=%i\n", cb_priv->pci_chip);
return -EIO;
}
isr_flags |= IRQF_SHARED;
- if (request_irq(cb_priv->pci_device->irq, cb_pci_interrupt, isr_flags, "cb7210", board)) {
- pr_err("cb7210: can't request IRQ %d\n", cb_priv->pci_device->irq);
- return -1;
+ if (request_irq(cb_priv->pci_device->irq, cb_pci_interrupt, isr_flags, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "can't request IRQ %d\n",
+ cb_priv->pci_device->irq);
+ return -EBUSY;
}
cb_priv->irq = cb_priv->pci_device->irq;
@@ -1004,7 +1008,7 @@ int cb_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
return cb7210_init(cb_priv, board);
}
-void cb_pci_detach(gpib_board_t *board)
+static void cb_pci_detach(struct gpib_board *board)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1027,7 +1031,7 @@ void cb_pci_detach(gpib_board_t *board)
cb7210_generic_detach(board);
}
-int cb_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int cb_isa_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
int isr_flags = 0;
struct cb7210_priv *cb_priv;
@@ -1040,20 +1044,22 @@ int cb_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
return retval;
cb_priv = board->private_data;
nec_priv = &cb_priv->nec7210_priv;
- if (!request_region(config->ibbase, cb7210_iosize, "cb7210")) {
- pr_err("gpib: ioports starting at 0x%x are already in use\n", config->ibbase);
- return -EIO;
+ if (!request_region(config->ibbase, cb7210_iosize, DRV_NAME)) {
+ dev_err(board->gpib_dev, "ioports starting at 0x%x are already in use\n",
+ config->ibbase);
+ return -EBUSY;
}
nec_priv->iobase = config->ibbase;
cb_priv->fifo_iobase = nec7210_iobase(cb_priv);
bits = irq_bits(config->ibirq);
if (bits == 0)
- pr_err("board incapable of using irq %i, try 2-5, 7, 10, or 11\n", config->ibirq);
+ dev_err(board->gpib_dev, "board incapable of using irq %i, try 2-5, 7, 10, or 11\n",
+ config->ibirq);
// install interrupt handler
- if (request_irq(config->ibirq, cb7210_interrupt, isr_flags, "cb7210", board)) {
- pr_err("gpib: can't request IRQ %d\n", config->ibirq);
+ if (request_irq(config->ibirq, cb7210_interrupt, isr_flags, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "failed to obtain IRQ %d\n", config->ibirq);
return -EBUSY;
}
cb_priv->irq = config->ibirq;
@@ -1061,7 +1067,7 @@ int cb_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
return cb7210_init(cb_priv, board);
}
-void cb_isa_detach(gpib_board_t *board)
+static void cb_isa_detach(struct gpib_board *board)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1093,7 +1099,7 @@ static const struct pci_device_id cb7210_pci_table[] = {
MODULE_DEVICE_TABLE(pci, cb7210_pci_table);
static struct pci_driver cb7210_pci_driver = {
- .name = "cb7210",
+ .name = DRV_NAME,
.id_table = cb7210_pci_table,
.probe = &cb7210_pci_probe
};
@@ -1106,7 +1112,7 @@ static struct pci_driver cb7210_pci_driver = {
* pcmcia skeleton example (presumably David Hinds)
***************************************************************************/
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
#include <linux/kernel.h>
#include <linux/ptrace.h>
@@ -1117,23 +1123,6 @@ static struct pci_driver cb7210_pci_driver = {
#include <pcmcia/ds.h>
/*
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- * you do not define PCMCIA_DEBUG at all, all the debug code will be
- * left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- * be present but disabled -- but it can then be enabled for specific
- * modules at load time with a 'pc_debug=#' option to insmod.
- */
-
-#define PCMCIA_DEBUG 1
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-#define DEBUG(n, args...) do {if (pc_debug > (n)) pr_debug(args); } while (0)
-#else
-#define DEBUG(args...)
-#endif
-
-/*
* The event() function is this driver's Card Services event handler.
* It will be called by Card Services when an appropriate card status
* event is received. The config() and release() entry points are
@@ -1144,8 +1133,8 @@ static int pc_debug = PCMCIA_DEBUG;
static int cb_gpib_config(struct pcmcia_device *link);
static void cb_gpib_release(struct pcmcia_device *link);
-static int cb_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static void cb_pcmcia_detach(gpib_board_t *board);
+static int cb_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static void cb_pcmcia_detach(struct gpib_board *board);
/*
* A linked list of "instances" of the gpib device. Each actual
@@ -1178,7 +1167,7 @@ static struct pcmcia_device *curr_dev;
struct local_info {
struct pcmcia_device *p_dev;
- gpib_board_t *dev;
+ struct gpib_board *dev;
};
/*
@@ -1197,8 +1186,6 @@ static int cb_gpib_probe(struct pcmcia_device *link)
// int ret, i;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
-
/* Allocate space for private device-specific data */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -1236,9 +1223,7 @@ static int cb_gpib_probe(struct pcmcia_device *link)
static void cb_gpib_remove(struct pcmcia_device *link)
{
struct local_info *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
-
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
if (info->dev)
cb_pcmcia_detach(info->dev);
@@ -1267,7 +1252,6 @@ static int cb_gpib_config(struct pcmcia_device *link)
handle = link;
dev = link->priv;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
retval = pcmcia_loop_config(link, &cb_gpib_config_iteration, NULL);
if (retval) {
@@ -1276,8 +1260,6 @@ static int cb_gpib_config(struct pcmcia_device *link)
return -ENODEV;
}
- DEBUG(0, "gpib_cs: manufacturer: 0x%x card: 0x%x\n", link->manf_id, link->card_id);
-
/*
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping.
@@ -1289,7 +1271,6 @@ static int cb_gpib_config(struct pcmcia_device *link)
return -ENODEV;
}
- pr_info("gpib device loaded\n");
return 0;
} /* gpib_config */
@@ -1301,18 +1282,16 @@ static int cb_gpib_config(struct pcmcia_device *link)
static void cb_gpib_release(struct pcmcia_device *link)
{
- DEBUG(0, "%s(0x%p)\n", __func__, link);
pcmcia_disable_device(link);
}
static int cb_gpib_suspend(struct pcmcia_device *link)
{
//struct local_info *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
if (link->open)
- pr_warn("Device still open ???\n");
+ dev_warn(&link->dev, "Device still open\n");
//netif_device_detach(dev);
return 0;
@@ -1321,12 +1300,10 @@ static int cb_gpib_suspend(struct pcmcia_device *link)
static int cb_gpib_resume(struct pcmcia_device *link)
{
//struct local_info *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
/*if (link->open) {
* ni_gpib_probe(dev); / really?
- * printk("Gpib resumed ???\n");
* //netif_device_attach(dev);
*
*/
@@ -1342,8 +1319,8 @@ static struct pcmcia_device_id cb_pcmcia_ids[] = {
MODULE_DEVICE_TABLE(pcmcia, cb_pcmcia_ids);
static struct pcmcia_driver cb_gpib_cs_driver = {
+ .name = "cb_gpib_cs",
.owner = THIS_MODULE,
- .drv = { .name = "cb_gpib_cs", },
.id_table = cb_pcmcia_ids,
.probe = cb_gpib_probe,
.remove = cb_gpib_remove,
@@ -1351,9 +1328,8 @@ static struct pcmcia_driver cb_gpib_cs_driver = {
.resume = cb_gpib_resume,
};
-void cb_pcmcia_cleanup_module(void)
+static void cb_pcmcia_cleanup_module(void)
{
- DEBUG(0, "cb_gpib_cs: unloading\n");
pcmcia_unregister_driver(&cb_gpib_cs_driver);
}
@@ -1441,15 +1417,15 @@ static gpib_interface_t cb_pcmcia_accel_interface = {
.return_to_local = cb7210_return_to_local,
};
-int cb_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int cb_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct cb7210_priv *cb_priv;
struct nec7210_priv *nec_priv;
int retval;
if (!curr_dev) {
- pr_err("no cb pcmcia cards found\n");
- return -1;
+ dev_err(board->gpib_dev, "no cb pcmcia cards found\n");
+ return -ENODEV;
}
retval = cb7210_generic_attach(board);
@@ -1460,25 +1436,24 @@ int cb_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
nec_priv = &cb_priv->nec7210_priv;
if (!request_region(curr_dev->resource[0]->start, resource_size(curr_dev->resource[0]),
- "cb7210")) {
- pr_err("gpib: ioports starting at 0x%lx are already in use\n",
- (unsigned long)curr_dev->resource[0]->start);
- return -EIO;
+ DRV_NAME)) {
+ dev_err(board->gpib_dev, "ioports starting at 0x%lx are already in use\n",
+ (unsigned long)curr_dev->resource[0]->start);
+ return -EBUSY;
}
nec_priv->iobase = curr_dev->resource[0]->start;
cb_priv->fifo_iobase = curr_dev->resource[0]->start;
- if (request_irq(curr_dev->irq, cb7210_interrupt, IRQF_SHARED,
- "cb7210", board)) {
- pr_err("cb7210: failed to request IRQ %d\n", curr_dev->irq);
- return -1;
+ if (request_irq(curr_dev->irq, cb7210_interrupt, IRQF_SHARED, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "failed to request IRQ %d\n", curr_dev->irq);
+ return -EBUSY;
}
cb_priv->irq = curr_dev->irq;
return cb7210_init(cb_priv, board);
}
-void cb_pcmcia_detach(gpib_board_t *board)
+static void cb_pcmcia_detach(struct gpib_board *board)
{
struct cb7210_priv *cb_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1496,7 +1471,7 @@ void cb_pcmcia_detach(gpib_board_t *board)
cb7210_generic_detach(board);
}
-#endif /* GPIB_PCMCIA */
+#endif /* CONFIG_GPIB_PCMCIA */
static int __init cb7210_init_module(void)
{
@@ -1504,75 +1479,75 @@ static int __init cb7210_init_module(void)
ret = pci_register_driver(&cb7210_pci_driver);
if (ret) {
- pr_err("cb7210: pci_register_driver failed: error = %d\n", ret);
+ pr_err("pci_register_driver failed: error = %d\n", ret);
return ret;
}
ret = gpib_register_driver(&cb_pci_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pci;
}
ret = gpib_register_driver(&cb_isa_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_isa;
}
ret = gpib_register_driver(&cb_pci_accel_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pci_accel;
}
ret = gpib_register_driver(&cb_pci_unaccel_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pci_unaccel;
}
ret = gpib_register_driver(&cb_isa_accel_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_isa_accel;
}
ret = gpib_register_driver(&cb_isa_unaccel_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_isa_unaccel;
}
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
ret = gpib_register_driver(&cb_pcmcia_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pcmcia;
}
ret = gpib_register_driver(&cb_pcmcia_accel_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pcmcia_accel;
}
ret = gpib_register_driver(&cb_pcmcia_unaccel_interface, THIS_MODULE);
if (ret) {
- pr_err("cb7210: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pcmcia_unaccel;
}
ret = pcmcia_register_driver(&cb_gpib_cs_driver);
if (ret) {
- pr_err("cb7210: pcmcia_register_driver failed: error = %d\n", ret);
+ pr_err("pcmcia_register_driver failed: error = %d\n", ret);
goto err_pcmcia_driver;
}
#endif
return 0;
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
err_pcmcia_driver:
gpib_unregister_driver(&cb_pcmcia_unaccel_interface);
err_pcmcia_unaccel:
@@ -1606,7 +1581,7 @@ static void __exit cb7210_exit_module(void)
gpib_unregister_driver(&cb_pci_unaccel_interface);
gpib_unregister_driver(&cb_isa_accel_interface);
gpib_unregister_driver(&cb_isa_unaccel_interface);
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
gpib_unregister_driver(&cb_pcmcia_interface);
gpib_unregister_driver(&cb_pcmcia_accel_interface);
gpib_unregister_driver(&cb_pcmcia_unaccel_interface);
diff --git a/drivers/staging/gpib/cb7210/cb7210.h b/drivers/staging/gpib/cb7210/cb7210.h
index d56cd905cc8c..2108fe7a8ce5 100644
--- a/drivers/staging/gpib/cb7210/cb7210.h
+++ b/drivers/staging/gpib/cb7210/cb7210.h
@@ -36,51 +36,6 @@ struct cb7210_priv {
unsigned in_fifo_half_full : 1;
};
-// interrupt service routines
-irqreturn_t cb_pci_interrupt(int irq, void *arg);
-irqreturn_t cb7210_interrupt(int irq, void *arg);
-irqreturn_t cb7210_internal_interrupt(gpib_board_t *board);
-
-// interface functions
-int cb7210_read(gpib_board_t *board, uint8_t *buffer, size_t length,
- int *end, size_t *bytes_read);
-int cb7210_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
- int *end, size_t *bytes_read);
-int cb7210_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written);
-int cb7210_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written);
-int cb7210_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written);
-int cb7210_take_control(gpib_board_t *board, int synchronous);
-int cb7210_go_to_standby(gpib_board_t *board);
-void cb7210_request_system_control(gpib_board_t *board, int request_control);
-void cb7210_interface_clear(gpib_board_t *board, int assert);
-void cb7210_remote_enable(gpib_board_t *board, int enable);
-int cb7210_enable_eos(gpib_board_t *board, uint8_t eos_byte,
- int compare_8_bits);
-void cb7210_disable_eos(gpib_board_t *board);
-unsigned int cb7210_update_status(gpib_board_t *board, unsigned int clear_mask);
-int cb7210_primary_address(gpib_board_t *board, unsigned int address);
-int cb7210_secondary_address(gpib_board_t *board, unsigned int address,
- int enable);
-int cb7210_parallel_poll(gpib_board_t *board, uint8_t *result);
-void cb7210_serial_poll_response(gpib_board_t *board, uint8_t status);
-uint8_t cb7210_serial_poll_status(gpib_board_t *board);
-void cb7210_parallel_poll_configure(gpib_board_t *board, uint8_t configuration);
-void cb7210_parallel_poll_response(gpib_board_t *board, int ist);
-int cb7210_line_status(const gpib_board_t *board);
-unsigned int cb7210_t1_delay(gpib_board_t *board, unsigned int nano_sec);
-void cb7210_return_to_local(gpib_board_t *board);
-
-// utility functions
-void cb7210_generic_detach(gpib_board_t *board);
-int cb7210_generic_attach(gpib_board_t *board);
-int cb7210_init(struct cb7210_priv *priv, gpib_board_t *board);
-
-// pcmcia init/cleanup
-int cb_pcmcia_init_module(void);
-void cb_pcmcia_cleanup_module(void);
-
// pci-gpib register offset
static const int cb7210_reg_offset = 1;
diff --git a/drivers/staging/gpib/cec/cec.h b/drivers/staging/gpib/cec/cec.h
index 040ca70ed708..3ce2869c7429 100644
--- a/drivers/staging/gpib/cec/cec.h
+++ b/drivers/staging/gpib/cec/cec.h
@@ -16,34 +16,5 @@ struct cec_priv {
unsigned int irq;
};
-// interface functions
-int cec_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read);
-int cec_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
-int cec_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written);
-int cec_take_control(gpib_board_t *board, int synchronous);
-int cec_go_to_standby(gpib_board_t *board);
-void cec_request_system_control(gpib_board_t *board, int request_control);
-void cec_interface_clear(gpib_board_t *board, int assert);
-void cec_remote_enable(gpib_board_t *board, int enable);
-int cec_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits);
-void cec_disable_eos(gpib_board_t *board);
-unsigned int cec_update_status(gpib_board_t *board, unsigned int clear_mask);
-int cec_primary_address(gpib_board_t *board, unsigned int address);
-int cec_secondary_address(gpib_board_t *board, unsigned int address, int enable);
-int cec_parallel_poll(gpib_board_t *board, uint8_t *result);
-void cec_parallel_poll_configure(gpib_board_t *board, uint8_t configuration);
-void cec_parallel_poll_response(gpib_board_t *board, int ist);
-void cec_serial_poll_response(gpib_board_t *board, uint8_t status);
-void cec_return_to_local(gpib_board_t *board);
-
-// interrupt service routines
-irqreturn_t cec_interrupt(int irq, void *arg);
-
-// utility functions
-void cec_free_private(gpib_board_t *board);
-int cec_generic_attach(gpib_board_t *board);
-void cec_init(struct cec_priv *priv, const gpib_board_t *board);
-
// offset between consecutive nec7210 registers
static const int cec_reg_offset = 1;
diff --git a/drivers/staging/gpib/cec/cec_gpib.c b/drivers/staging/gpib/cec/cec_gpib.c
index d056cd1d6b3e..a822fa428cd0 100644
--- a/drivers/staging/gpib/cec/cec_gpib.c
+++ b/drivers/staging/gpib/cec/cec_gpib.c
@@ -4,6 +4,10 @@
* copyright : (C) 2002 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "cec.h"
#include <linux/pci.h>
#include <linux/io.h>
@@ -19,9 +23,9 @@ MODULE_DESCRIPTION("GPIB driver for CEC PCI and PCMCIA boards");
* GPIB interrupt service routines
*/
-irqreturn_t cec_interrupt(int irq, void *arg)
+static irqreturn_t cec_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct cec_priv *priv = board->private_data;
unsigned long flags;
irqreturn_t retval;
@@ -36,146 +40,148 @@ irqreturn_t cec_interrupt(int irq, void *arg)
#define CEC_DEV_ID 0x5cec
#define CEC_SUBID 0x9050
-static int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config);
+static int cec_pci_attach(struct gpib_board *board, const gpib_board_config_t *config);
-static void cec_pci_detach(gpib_board_t *board);
+static void cec_pci_detach(struct gpib_board *board);
// wrappers for interface functions
-int cec_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
+static int cec_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
+ size_t *bytes_read)
{
struct cec_priv *priv = board->private_data;
return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
}
-int cec_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int cec_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written)
{
struct cec_priv *priv = board->private_data;
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-int cec_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int cec_command(struct gpib_board *board, uint8_t *buffer,
+ size_t length, size_t *bytes_written)
{
struct cec_priv *priv = board->private_data;
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-int cec_take_control(gpib_board_t *board, int synchronous)
+static int cec_take_control(struct gpib_board *board, int synchronous)
{
struct cec_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-int cec_go_to_standby(gpib_board_t *board)
+static int cec_go_to_standby(struct gpib_board *board)
{
struct cec_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-void cec_request_system_control(gpib_board_t *board, int request_control)
+static void cec_request_system_control(struct gpib_board *board, int request_control)
{
struct cec_priv *priv = board->private_data;
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
}
-void cec_interface_clear(gpib_board_t *board, int assert)
+static void cec_interface_clear(struct gpib_board *board, int assert)
{
struct cec_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-void cec_remote_enable(gpib_board_t *board, int enable)
+static void cec_remote_enable(struct gpib_board *board, int enable)
{
struct cec_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-int cec_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int cec_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct cec_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-void cec_disable_eos(gpib_board_t *board)
+static void cec_disable_eos(struct gpib_board *board)
{
struct cec_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-unsigned int cec_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int cec_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct cec_priv *priv = board->private_data;
return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
}
-int cec_primary_address(gpib_board_t *board, unsigned int address)
+static int cec_primary_address(struct gpib_board *board, unsigned int address)
{
struct cec_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-int cec_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int cec_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct cec_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-int cec_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int cec_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct cec_priv *priv = board->private_data;
return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
}
-void cec_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void cec_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
struct cec_priv *priv = board->private_data;
nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
}
-void cec_parallel_poll_response(gpib_board_t *board, int ist)
+static void cec_parallel_poll_response(struct gpib_board *board, int ist)
{
struct cec_priv *priv = board->private_data;
nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
}
-void cec_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void cec_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct cec_priv *priv = board->private_data;
nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
}
-static uint8_t cec_serial_poll_status(gpib_board_t *board)
+static uint8_t cec_serial_poll_status(struct gpib_board *board)
{
struct cec_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-static unsigned int cec_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int cec_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct cec_priv *priv = board->private_data;
return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec);
}
-void cec_return_to_local(gpib_board_t *board)
+static void cec_return_to_local(struct gpib_board *board)
{
struct cec_priv *priv = board->private_data;
@@ -210,7 +216,7 @@ static gpib_interface_t cec_pci_interface = {
.return_to_local = cec_return_to_local,
};
-static int cec_allocate_private(gpib_board_t *board)
+static int cec_allocate_private(struct gpib_board *board)
{
struct cec_priv *priv;
@@ -223,13 +229,13 @@ static int cec_allocate_private(gpib_board_t *board)
return 0;
}
-void cec_free_private(gpib_board_t *board)
+static void cec_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
-int cec_generic_attach(gpib_board_t *board)
+static int cec_generic_attach(struct gpib_board *board)
{
struct cec_priv *cec_priv;
struct nec7210_priv *nec_priv;
@@ -247,7 +253,7 @@ int cec_generic_attach(gpib_board_t *board)
return 0;
}
-void cec_init(struct cec_priv *cec_priv, const gpib_board_t *board)
+static void cec_init(struct cec_priv *cec_priv, const struct gpib_board *board)
{
struct nec7210_priv *nec_priv = &cec_priv->nec7210_priv;
@@ -259,7 +265,7 @@ void cec_init(struct cec_priv *cec_priv, const gpib_board_t *board)
nec7210_board_online(nec_priv, board);
}
-int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int cec_pci_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct cec_priv *cec_priv;
struct nec7210_priv *nec_priv;
@@ -283,31 +289,29 @@ int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
break;
}
if (!cec_priv->pci_device) {
- pr_err("gpib: no cec PCI board found\n");
- return -1;
+ dev_err(board->gpib_dev, "no cec PCI board found\n");
+ return -ENODEV;
}
if (pci_enable_device(cec_priv->pci_device)) {
- pr_err("error enabling pci device\n");
- return -1;
+ dev_err(board->gpib_dev, "error enabling pci device\n");
+ return -EIO;
}
if (pci_request_regions(cec_priv->pci_device, "cec-gpib"))
- return -1;
+ return -EBUSY;
cec_priv->plx_iobase = pci_resource_start(cec_priv->pci_device, 1);
- pr_info(" plx9050 base address 0x%lx\n", cec_priv->plx_iobase);
- nec_priv->iobase = pci_resource_start(cec_priv->pci_device, 3);
- pr_info(" nec7210 base address 0x%x\n", nec_priv->iobase);
+ nec_priv->iobase = pci_resource_start(cec_priv->pci_device, 3);
isr_flags |= IRQF_SHARED;
- if (request_irq(cec_priv->pci_device->irq, cec_interrupt, isr_flags, "pci-gpib", board)) {
- pr_err("gpib: can't request IRQ %d\n", cec_priv->pci_device->irq);
- return -1;
+ if (request_irq(cec_priv->pci_device->irq, cec_interrupt, isr_flags, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "failed to obtain IRQ %d\n", cec_priv->pci_device->irq);
+ return -EBUSY;
}
cec_priv->irq = cec_priv->pci_device->irq;
if (gpib_request_pseudo_irq(board, cec_interrupt)) {
- pr_err("cec: failed to allocate pseudo irq\n");
+ dev_err(board->gpib_dev, "failed to allocate pseudo irq\n");
return -1;
}
cec_init(cec_priv, board);
@@ -319,7 +323,7 @@ int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-void cec_pci_detach(gpib_board_t *board)
+static void cec_pci_detach(struct gpib_board *board)
{
struct cec_priv *cec_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -354,7 +358,7 @@ static const struct pci_device_id cec_pci_table[] = {
MODULE_DEVICE_TABLE(pci, cec_pci_table);
static struct pci_driver cec_pci_driver = {
- .name = "cec_gpib",
+ .name = DRV_NAME,
.id_table = cec_pci_table,
.probe = &cec_pci_probe
};
@@ -365,13 +369,13 @@ static int __init cec_init_module(void)
result = pci_register_driver(&cec_pci_driver);
if (result) {
- pr_err("cec_gpib: pci_register_driver failed: error = %d\n", result);
+ pr_err("pci_register_driver failed: error = %d\n", result);
return result;
}
result = gpib_register_driver(&cec_pci_interface, THIS_MODULE);
if (result) {
- pr_err("cec_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
return result;
}
diff --git a/drivers/staging/gpib/common/gpib_os.c b/drivers/staging/gpib/common/gpib_os.c
index 4901e660242e..8456b97290b8 100644
--- a/drivers/staging/gpib/common/gpib_os.c
+++ b/drivers/staging/gpib/common/gpib_os.c
@@ -5,6 +5,9 @@
***************************************************************************
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+
#include "ibsys.h"
#include <linux/module.h>
#include <linux/wait.h>
@@ -23,53 +26,53 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB base support");
MODULE_ALIAS_CHARDEV_MAJOR(GPIB_CODE);
-static int board_type_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, unsigned long arg);
-static int read_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
+static int board_type_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, unsigned long arg);
+static int read_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board,
unsigned long arg);
-static int write_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
+static int write_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board,
unsigned long arg);
-static int command_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
+static int command_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board,
unsigned long arg);
-static int open_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg);
-static int close_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg);
-static int serial_poll_ioctl(gpib_board_t *board, unsigned long arg);
-static int wait_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, unsigned long arg);
-static int parallel_poll_ioctl(gpib_board_t *board, unsigned long arg);
-static int online_ioctl(gpib_board_t *board, unsigned long arg);
-static int remote_enable_ioctl(gpib_board_t *board, unsigned long arg);
-static int take_control_ioctl(gpib_board_t *board, unsigned long arg);
-static int line_status_ioctl(gpib_board_t *board, unsigned long arg);
-static int pad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg);
+static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg);
+static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg);
+static int wait_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, unsigned long arg);
+static int parallel_poll_ioctl(struct gpib_board *board, unsigned long arg);
+static int online_ioctl(struct gpib_board *board, unsigned long arg);
+static int remote_enable_ioctl(struct gpib_board *board, unsigned long arg);
+static int take_control_ioctl(struct gpib_board *board, unsigned long arg);
+static int line_status_ioctl(struct gpib_board *board, unsigned long arg);
+static int pad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg);
-static int sad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int sad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg);
-static int eos_ioctl(gpib_board_t *board, unsigned long arg);
-static int request_service_ioctl(gpib_board_t *board, unsigned long arg);
-static int request_service2_ioctl(gpib_board_t *board, unsigned long arg);
+static int eos_ioctl(struct gpib_board *board, unsigned long arg);
+static int request_service_ioctl(struct gpib_board *board, unsigned long arg);
+static int request_service2_ioctl(struct gpib_board *board, unsigned long arg);
static int iobase_ioctl(gpib_board_config_t *config, unsigned long arg);
static int irq_ioctl(gpib_board_config_t *config, unsigned long arg);
static int dma_ioctl(gpib_board_config_t *config, unsigned long arg);
-static int autospoll_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int autospoll_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg);
-static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int mutex_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg);
-static int timeout_ioctl(gpib_board_t *board, unsigned long arg);
-static int status_bytes_ioctl(gpib_board_t *board, unsigned long arg);
-static int board_info_ioctl(const gpib_board_t *board, unsigned long arg);
-static int ppc_ioctl(gpib_board_t *board, unsigned long arg);
-static int set_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg);
-static int get_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg);
-static int query_board_rsv_ioctl(gpib_board_t *board, unsigned long arg);
-static int interface_clear_ioctl(gpib_board_t *board, unsigned long arg);
+static int timeout_ioctl(struct gpib_board *board, unsigned long arg);
+static int status_bytes_ioctl(struct gpib_board *board, unsigned long arg);
+static int board_info_ioctl(const struct gpib_board *board, unsigned long arg);
+static int ppc_ioctl(struct gpib_board *board, unsigned long arg);
+static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg);
+static int get_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg);
+static int query_board_rsv_ioctl(struct gpib_board *board, unsigned long arg);
+static int interface_clear_ioctl(struct gpib_board *board, unsigned long arg);
static int select_pci_ioctl(gpib_board_config_t *config, unsigned long arg);
static int select_device_path_ioctl(gpib_board_config_t *config, unsigned long arg);
-static int event_ioctl(gpib_board_t *board, unsigned long arg);
-static int request_system_control_ioctl(gpib_board_t *board, unsigned long arg);
-static int t1_delay_ioctl(gpib_board_t *board, unsigned long arg);
+static int event_ioctl(struct gpib_board *board, unsigned long arg);
+static int request_system_control_ioctl(struct gpib_board *board, unsigned long arg);
+static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg);
-static int cleanup_open_devices(gpib_file_private_t *file_priv, gpib_board_t *board);
+static int cleanup_open_devices(gpib_file_private_t *file_priv, struct gpib_board *board);
-static int pop_gpib_event_nolock(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type);
+static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type);
/*
* Timer functions
@@ -79,18 +82,18 @@ static int pop_gpib_event_nolock(gpib_board_t *board, gpib_event_queue_t *queue,
static void watchdog_timeout(struct timer_list *t)
{
- gpib_board_t *board = from_timer(board, t, timer);
+ struct gpib_board *board = from_timer(board, t, timer);
set_bit(TIMO_NUM, &board->status);
wake_up_interruptible(&board->wait);
}
/* install timer interrupt handler */
-void os_start_timer(gpib_board_t *board, unsigned int usec_timeout)
+void os_start_timer(struct gpib_board *board, unsigned int usec_timeout)
/* Starts the timeout task */
{
if (timer_pending(&board->timer)) {
- pr_err("gpib: bug! timer already running?\n");
+ dev_err(board->gpib_dev, "bug! timer already running?\n");
return;
}
clear_bit(TIMO_NUM, &board->status);
@@ -102,14 +105,14 @@ void os_start_timer(gpib_board_t *board, unsigned int usec_timeout)
}
}
-void os_remove_timer(gpib_board_t *board)
+void os_remove_timer(struct gpib_board *board)
/* Removes the timeout task */
{
if (timer_pending(&board->timer))
- del_timer_sync(&board->timer);
+ timer_delete_sync(&board->timer);
}
-int io_timed_out(gpib_board_t *board)
+int io_timed_out(struct gpib_board *board)
{
if (test_bit(TIMO_NUM, &board->status))
return 1;
@@ -137,10 +140,10 @@ static void pseudo_irq_handler(struct timer_list *t)
mod_timer(&pseudo_irq->timer, jiffies + pseudo_irq_period());
}
-int gpib_request_pseudo_irq(gpib_board_t *board, irqreturn_t (*handler)(int, void *))
+int gpib_request_pseudo_irq(struct gpib_board *board, irqreturn_t (*handler)(int, void *))
{
if (timer_pending(&board->pseudo_irq.timer) || board->pseudo_irq.handler) {
- pr_err("gpib: only one pseudo interrupt per board allowed\n");
+ dev_err(board->gpib_dev, "only one pseudo interrupt per board allowed\n");
return -1;
}
@@ -156,11 +159,11 @@ int gpib_request_pseudo_irq(gpib_board_t *board, irqreturn_t (*handler)(int, voi
}
EXPORT_SYMBOL(gpib_request_pseudo_irq);
-void gpib_free_pseudo_irq(gpib_board_t *board)
+void gpib_free_pseudo_irq(struct gpib_board *board)
{
atomic_set(&board->pseudo_irq.active, 0);
- del_timer_sync(&board->pseudo_irq.timer);
+ timer_delete_sync(&board->pseudo_irq.timer);
board->pseudo_irq.handler = NULL;
}
EXPORT_SYMBOL(gpib_free_pseudo_irq);
@@ -175,7 +178,7 @@ unsigned int num_status_bytes(const gpib_status_queue_t *dev)
}
// push status byte onto back of status byte fifo
-int push_status_byte(gpib_board_t *board, gpib_status_queue_t *device, u8 poll_byte)
+int push_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 poll_byte)
{
struct list_head *head = &device->status_bytes;
status_byte_t *status;
@@ -209,7 +212,7 @@ int push_status_byte(gpib_board_t *board, gpib_status_queue_t *device, u8 poll_b
}
// pop status byte from front of status byte fifo
-int pop_status_byte(gpib_board_t *board, gpib_status_queue_t *device, u8 *poll_byte)
+int pop_status_byte(struct gpib_board *board, gpib_status_queue_t *device, u8 *poll_byte)
{
struct list_head *head = &device->status_bytes;
struct list_head *front = head->next;
@@ -240,7 +243,7 @@ int pop_status_byte(gpib_board_t *board, gpib_status_queue_t *device, u8 *poll_b
return 0;
}
-gpib_status_queue_t *get_gpib_status_queue(gpib_board_t *board, unsigned int pad, int sad)
+gpib_status_queue_t *get_gpib_status_queue(struct gpib_board *board, unsigned int pad, int sad)
{
gpib_status_queue_t *device;
struct list_head *list_ptr;
@@ -255,13 +258,11 @@ gpib_status_queue_t *get_gpib_status_queue(gpib_board_t *board, unsigned int pad
return NULL;
}
-int get_serial_poll_byte(gpib_board_t *board, unsigned int pad, int sad, unsigned int usec_timeout,
+int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad, unsigned int usec_timeout,
uint8_t *poll_byte)
{
gpib_status_queue_t *device;
- dev_dbg(board->gpib_dev, "%s:()\n", __func__);
-
device = get_gpib_status_queue(board, pad, sad);
if (num_status_bytes(device))
return pop_status_byte(board, device, poll_byte);
@@ -269,11 +270,10 @@ int get_serial_poll_byte(gpib_board_t *board, unsigned int pad, int sad, unsigne
return dvrsp(board, pad, sad, usec_timeout, poll_byte);
}
-int autopoll_all_devices(gpib_board_t *board)
+int autopoll_all_devices(struct gpib_board *board)
{
int retval;
- dev_dbg(board->gpib_dev, "entering %s()\n", __func__);
if (mutex_lock_interruptible(&board->user_mutex))
return -ERESTARTSYS;
if (mutex_lock_interruptible(&board->big_gpib_mutex)) {
@@ -290,7 +290,7 @@ int autopoll_all_devices(gpib_board_t *board)
return retval;
}
- dev_dbg(board->gpib_dev, "%s complete\n", __func__);
+ dev_dbg(board->gpib_dev, "complete\n");
/* need to wake wait queue in case someone is
* waiting on RQS
*/
@@ -301,15 +301,13 @@ int autopoll_all_devices(gpib_board_t *board)
return retval;
}
-static int setup_serial_poll(gpib_board_t *board, unsigned int usec_timeout)
+static int setup_serial_poll(struct gpib_board *board, unsigned int usec_timeout)
{
u8 cmd_string[8];
int i;
size_t bytes_written;
int ret;
- dev_dbg(board->gpib_dev, "entering %s()\n", __func__);
-
os_start_timer(board, usec_timeout);
ret = ibcac(board, 1, 1);
if (ret < 0) {
@@ -326,7 +324,7 @@ static int setup_serial_poll(gpib_board_t *board, unsigned int usec_timeout)
ret = board->interface->command(board, cmd_string, i, &bytes_written);
if (ret < 0 || bytes_written < i) {
- pr_err("gpib: failed to setup serial poll\n");
+ dev_dbg(board->gpib_dev, "failed to setup serial poll\n");
os_remove_timer(board);
return -EIO;
}
@@ -335,7 +333,7 @@ static int setup_serial_poll(gpib_board_t *board, unsigned int usec_timeout)
return 0;
}
-static int read_serial_poll_byte(gpib_board_t *board, unsigned int pad,
+static int read_serial_poll_byte(struct gpib_board *board, unsigned int pad,
int sad, unsigned int usec_timeout, uint8_t *result)
{
u8 cmd_string[8];
@@ -344,7 +342,7 @@ static int read_serial_poll_byte(gpib_board_t *board, unsigned int pad,
int i;
size_t nbytes;
- dev_dbg(board->gpib_dev, "entering %s(), pad=%i sad=%i\n", __func__, pad, sad);
+ dev_dbg(board->gpib_dev, "entering pad=%i sad=%i\n", pad, sad);
os_start_timer(board, usec_timeout);
ret = ibcac(board, 1, 1);
@@ -361,7 +359,7 @@ static int read_serial_poll_byte(gpib_board_t *board, unsigned int pad,
ret = board->interface->command(board, cmd_string, i, &nbytes);
if (ret < 0 || nbytes < i) {
- pr_err("gpib: failed to setup serial poll\n");
+ dev_err(board->gpib_dev, "failed to setup serial poll\n");
os_remove_timer(board);
return -EIO;
}
@@ -371,7 +369,7 @@ static int read_serial_poll_byte(gpib_board_t *board, unsigned int pad,
// read poll result
ret = board->interface->read(board, result, 1, &end_flag, &nbytes);
if (ret < 0 || nbytes < 1) {
- pr_err("gpib: serial poll failed\n");
+ dev_err(board->gpib_dev, "serial poll failed\n");
os_remove_timer(board);
return -EIO;
}
@@ -380,14 +378,12 @@ static int read_serial_poll_byte(gpib_board_t *board, unsigned int pad,
return 0;
}
-static int cleanup_serial_poll(gpib_board_t *board, unsigned int usec_timeout)
+static int cleanup_serial_poll(struct gpib_board *board, unsigned int usec_timeout)
{
u8 cmd_string[8];
int ret;
size_t bytes_written;
- dev_dbg(board->gpib_dev, "entering %s()\n", __func__);
-
os_start_timer(board, usec_timeout);
ret = ibcac(board, 1, 1);
if (ret < 0) {
@@ -399,7 +395,7 @@ static int cleanup_serial_poll(gpib_board_t *board, unsigned int usec_timeout)
cmd_string[1] = UNT;
ret = board->interface->command(board, cmd_string, 2, &bytes_written);
if (ret < 0 || bytes_written < 2) {
- pr_err("gpib: failed to disable serial poll\n");
+ dev_err(board->gpib_dev, "failed to disable serial poll\n");
os_remove_timer(board);
return -EIO;
}
@@ -408,7 +404,7 @@ static int cleanup_serial_poll(gpib_board_t *board, unsigned int usec_timeout)
return 0;
}
-static int serial_poll_single(gpib_board_t *board, unsigned int pad, int sad,
+static int serial_poll_single(struct gpib_board *board, unsigned int pad, int sad,
unsigned int usec_timeout, uint8_t *result)
{
int retval, cleanup_retval;
@@ -426,7 +422,7 @@ static int serial_poll_single(gpib_board_t *board, unsigned int pad, int sad,
return 0;
}
-int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout)
+int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout)
{
int retval = 0;
struct list_head *cur;
@@ -435,8 +431,6 @@ int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout)
u8 result;
unsigned int num_bytes = 0;
- dev_dbg(board->gpib_dev, "entering %s()\n", __func__);
-
head = &board->device_list;
if (head->next == head)
return 0;
@@ -475,19 +469,19 @@ int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout)
* SPD and UNT are sent at the completion of the poll.
*/
-int dvrsp(gpib_board_t *board, unsigned int pad, int sad,
+int dvrsp(struct gpib_board *board, unsigned int pad, int sad,
unsigned int usec_timeout, uint8_t *result)
{
int status = ibstatus(board);
int retval;
if ((status & CIC) == 0) {
- pr_err("gpib: not CIC during serial poll\n");
+ dev_err(board->gpib_dev, "not CIC during serial poll\n");
return -1;
}
if (pad > MAX_GPIB_PRIMARY_ADDRESS || sad > MAX_GPIB_SECONDARY_ADDRESS || sad < -1) {
- pr_err("gpib: bad address for serial poll");
+ dev_err(board->gpib_dev, "bad address for serial poll");
return -1;
}
@@ -527,7 +521,7 @@ static int init_gpib_file_private(gpib_file_private_t *priv)
int ibopen(struct inode *inode, struct file *filep)
{
unsigned int minor = iminor(inode);
- gpib_board_t *board;
+ struct gpib_board *board;
gpib_file_private_t *priv;
if (minor >= GPIB_MAX_NUM_BOARDS) {
@@ -544,20 +538,16 @@ int ibopen(struct inode *inode, struct file *filep)
priv = filep->private_data;
init_gpib_file_private((gpib_file_private_t *)filep->private_data);
- dev_dbg(board->gpib_dev, "pid %i, gpib: opening minor %d\n", current->pid, minor);
-
if (board->use_count == 0) {
int retval;
retval = request_module("gpib%i", minor);
- if (retval) {
- dev_dbg(board->gpib_dev, "pid %i, gpib: request module returned %i\n",
- current->pid, retval);
- }
+ if (retval)
+ dev_dbg(board->gpib_dev, "request module returned %i\n", retval);
}
if (board->interface) {
if (!try_module_get(board->provider_module)) {
- pr_err("gpib: try_module_get() failed\n");
+ dev_err(board->gpib_dev, "try_module_get() failed\n");
return -EIO;
}
board->use_count++;
@@ -569,7 +559,7 @@ int ibopen(struct inode *inode, struct file *filep)
int ibclose(struct inode *inode, struct file *filep)
{
unsigned int minor = iminor(inode);
- gpib_board_t *board;
+ struct gpib_board *board;
gpib_file_private_t *priv = filep->private_data;
gpib_descriptor_t *desc;
@@ -580,21 +570,19 @@ int ibclose(struct inode *inode, struct file *filep)
board = &board_array[minor];
- dev_dbg(board->gpib_dev, "pid %i, closing minor %d\n", current->pid, minor);
-
if (priv) {
desc = handle_to_descriptor(priv, 0);
if (desc) {
if (desc->autopoll_enabled) {
- dev_dbg(board->gpib_dev, "pid %i, decrementing autospollers\n",
- current->pid);
+ dev_dbg(board->gpib_dev, "decrementing autospollers\n");
if (board->autospollers > 0)
board->autospollers--;
else
- pr_err("gpib: Attempt to decrement zero autospollers\n");
+ dev_err(board->gpib_dev,
+ "Attempt to decrement zero autospollers\n");
}
} else {
- pr_err("gpib: Unexpected null gpib_descriptor\n");
+ dev_err(board->gpib_dev, "Unexpected null gpib_descriptor\n");
}
cleanup_open_devices(priv, board);
@@ -617,7 +605,7 @@ int ibclose(struct inode *inode, struct file *filep)
long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
unsigned int minor = iminor(filep->f_path.dentry->d_inode);
- gpib_board_t *board;
+ struct gpib_board *board;
gpib_file_private_t *file_priv = filep->private_data;
long retval = -ENOTTY;
@@ -630,8 +618,8 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg)
if (mutex_lock_interruptible(&board->big_gpib_mutex))
return -ERESTARTSYS;
- dev_dbg(board->gpib_dev, "pid %i, ioctl %d, interface=%s, use=%d, onl=%d\n",
- current->pid, cmd & 0xff,
+ dev_dbg(board->gpib_dev, "ioctl %d, interface=%s, use=%d, onl=%d\n",
+ cmd & 0xff,
board->interface ? board->interface->name : "",
board->use_count,
board->online);
@@ -647,13 +635,13 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg)
break;
}
if (!board->interface) {
- pr_err("gpib: no gpib board configured on /dev/gpib%i\n", minor);
+ dev_err(board->gpib_dev, "no gpib board configured\n");
retval = -ENODEV;
goto done;
}
if (file_priv->got_module == 0) {
if (!try_module_get(board->provider_module)) {
- pr_err("gpib: try_module_get() failed\n");
+ dev_err(board->gpib_dev, "try_module_get() failed\n");
retval = -EIO;
goto done;
}
@@ -699,8 +687,6 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg)
}
if (!board->online) {
- pr_err("gpib: ioctl %i invalid for offline board\n",
- cmd & 0xff);
retval = -EINVAL;
goto done;
}
@@ -737,8 +723,6 @@ long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg)
spin_lock(&board->locking_pid_spinlock);
if (current->pid != board->locking_pid) {
spin_unlock(&board->locking_pid_spinlock);
- pr_err("gpib: need to hold board lock to perform ioctl %i\n",
- cmd & 0xff);
retval = -EPERM;
goto done;
}
@@ -822,7 +806,7 @@ done:
return retval;
}
-static int board_type_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board, unsigned long arg)
+static int board_type_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board, unsigned long arg)
{
struct list_head *list_ptr;
board_type_ioctl_t cmd;
@@ -830,10 +814,8 @@ static int board_type_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (board->online) {
- pr_err("gpib: can't change board type while board is online.\n");
+ if (board->online)
return -EBUSY;
- }
retval = copy_from_user(&cmd, (void __user *)arg, sizeof(board_type_ioctl_t));
if (retval)
@@ -875,7 +857,7 @@ static int board_type_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
return -EINVAL;
}
-static int read_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
+static int read_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board,
unsigned long arg)
{
read_write_ioctl_t read_cmd;
@@ -951,7 +933,7 @@ static int read_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
}
static int command_ioctl(gpib_file_private_t *file_priv,
- gpib_board_t *board, unsigned long arg)
+ struct gpib_board *board, unsigned long arg)
{
read_write_ioctl_t cmd;
u8 __user *userbuf;
@@ -1034,7 +1016,7 @@ static int command_ioctl(gpib_file_private_t *file_priv,
return retval;
}
-static int write_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
+static int write_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board,
unsigned long arg)
{
read_write_ioctl_t write_cmd;
@@ -1105,7 +1087,7 @@ static int write_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
return retval;
}
-static int status_bytes_ioctl(gpib_board_t *board, unsigned long arg)
+static int status_bytes_ioctl(struct gpib_board *board, unsigned long arg)
{
gpib_status_queue_t *device;
spoll_bytes_ioctl_t cmd;
@@ -1128,7 +1110,7 @@ static int status_bytes_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int increment_open_device_count(gpib_board_t *board, struct list_head *head,
+static int increment_open_device_count(struct gpib_board *board, struct list_head *head,
unsigned int pad, int sad)
{
struct list_head *list_ptr;
@@ -1140,8 +1122,8 @@ static int increment_open_device_count(gpib_board_t *board, struct list_head *he
for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) {
device = list_entry(list_ptr, gpib_status_queue_t, list);
if (gpib_address_equal(device->pad, device->sad, pad, sad)) {
- dev_dbg(board->gpib_dev, "pid %i, incrementing open count for pad %i, sad %i\n",
- current->pid, device->pad, device->sad);
+ dev_dbg(board->gpib_dev, "incrementing open count for pad %i, sad %i\n",
+ device->pad, device->sad);
device->reference_count++;
return 0;
}
@@ -1158,13 +1140,12 @@ static int increment_open_device_count(gpib_board_t *board, struct list_head *he
list_add(&device->list, head);
- dev_dbg(board->gpib_dev, "pid %i, opened pad %i, sad %i\n",
- current->pid, device->pad, device->sad);
+ dev_dbg(board->gpib_dev, "opened pad %i, sad %i\n", device->pad, device->sad);
return 0;
}
-static int subtract_open_device_count(gpib_board_t *board, struct list_head *head,
+static int subtract_open_device_count(struct gpib_board *board, struct list_head *head,
unsigned int pad, int sad, unsigned int count)
{
gpib_status_queue_t *device;
@@ -1173,33 +1154,33 @@ static int subtract_open_device_count(gpib_board_t *board, struct list_head *hea
for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) {
device = list_entry(list_ptr, gpib_status_queue_t, list);
if (gpib_address_equal(device->pad, device->sad, pad, sad)) {
- dev_dbg(board->gpib_dev, "pid %i, decrementing open count for pad %i, sad %i\n",
- current->pid, device->pad, device->sad);
+ dev_dbg(board->gpib_dev, "decrementing open count for pad %i, sad %i\n",
+ device->pad, device->sad);
if (count > device->reference_count) {
- pr_err("gpib: bug! in %s()\n", __func__);
+ dev_err(board->gpib_dev, "bug! in %s()\n", __func__);
return -EINVAL;
}
device->reference_count -= count;
if (device->reference_count == 0) {
- dev_dbg(board->gpib_dev, "pid %i, closing pad %i, sad %i\n",
- current->pid, device->pad, device->sad);
+ dev_dbg(board->gpib_dev, "closing pad %i, sad %i\n",
+ device->pad, device->sad);
list_del(list_ptr);
kfree(device);
}
return 0;
}
}
- pr_err("gpib: bug! tried to close address that was never opened!\n");
+ dev_err(board->gpib_dev, "bug! tried to close address that was never opened!\n");
return -EINVAL;
}
-static inline int decrement_open_device_count(gpib_board_t *board, struct list_head *head,
+static inline int decrement_open_device_count(struct gpib_board *board, struct list_head *head,
unsigned int pad, int sad)
{
return subtract_open_device_count(board, head, pad, sad, 1);
}
-static int cleanup_open_devices(gpib_file_private_t *file_priv, gpib_board_t *board)
+static int cleanup_open_devices(gpib_file_private_t *file_priv, struct gpib_board *board)
{
int retval = 0;
int i;
@@ -1224,7 +1205,7 @@ static int cleanup_open_devices(gpib_file_private_t *file_priv, gpib_board_t *bo
return 0;
}
-static int open_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg)
+static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg)
{
open_dev_ioctl_t open_dev_cmd;
int retval;
@@ -1274,7 +1255,7 @@ static int open_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long
return 0;
}
-static int close_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned long arg)
+static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg)
{
close_dev_ioctl_t cmd;
gpib_file_private_t *file_priv = filep->private_data;
@@ -1301,13 +1282,11 @@ static int close_dev_ioctl(struct file *filep, gpib_board_t *board, unsigned lon
return 0;
}
-static int serial_poll_ioctl(gpib_board_t *board, unsigned long arg)
+static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg)
{
serial_poll_ioctl_t serial_cmd;
int retval;
- dev_dbg(board->gpib_dev, "pid %i, entering %s()\n", current->pid, __func__);
-
retval = copy_from_user(&serial_cmd, (void __user *)arg, sizeof(serial_cmd));
if (retval)
return -EFAULT;
@@ -1324,7 +1303,7 @@ static int serial_poll_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int wait_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
+static int wait_ioctl(gpib_file_private_t *file_priv, struct gpib_board *board,
unsigned long arg)
{
wait_ioctl_t wait_cmd;
@@ -1351,7 +1330,7 @@ static int wait_ioctl(gpib_file_private_t *file_priv, gpib_board_t *board,
return 0;
}
-static int parallel_poll_ioctl(gpib_board_t *board, unsigned long arg)
+static int parallel_poll_ioctl(struct gpib_board *board, unsigned long arg)
{
u8 poll_byte;
int retval;
@@ -1367,7 +1346,7 @@ static int parallel_poll_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int online_ioctl(gpib_board_t *board, unsigned long arg)
+static int online_ioctl(struct gpib_board *board, unsigned long arg)
{
online_ioctl_t online_cmd;
int retval;
@@ -1411,7 +1390,7 @@ static int online_ioctl(gpib_board_t *board, unsigned long arg)
return retval;
}
-static int remote_enable_ioctl(gpib_board_t *board, unsigned long arg)
+static int remote_enable_ioctl(struct gpib_board *board, unsigned long arg)
{
int enable;
int retval;
@@ -1423,7 +1402,7 @@ static int remote_enable_ioctl(gpib_board_t *board, unsigned long arg)
return ibsre(board, enable);
}
-static int take_control_ioctl(gpib_board_t *board, unsigned long arg)
+static int take_control_ioctl(struct gpib_board *board, unsigned long arg)
{
int synchronous;
int retval;
@@ -1435,7 +1414,7 @@ static int take_control_ioctl(gpib_board_t *board, unsigned long arg)
return ibcac(board, synchronous, 1);
}
-static int line_status_ioctl(gpib_board_t *board, unsigned long arg)
+static int line_status_ioctl(struct gpib_board *board, unsigned long arg)
{
short lines;
int retval;
@@ -1451,7 +1430,7 @@ static int line_status_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int pad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int pad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg)
{
pad_ioctl_t cmd;
@@ -1487,7 +1466,7 @@ static int pad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
return 0;
}
-static int sad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int sad_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg)
{
sad_ioctl_t cmd;
@@ -1522,7 +1501,7 @@ static int sad_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
return 0;
}
-static int eos_ioctl(gpib_board_t *board, unsigned long arg)
+static int eos_ioctl(struct gpib_board *board, unsigned long arg)
{
eos_ioctl_t eos_cmd;
int retval;
@@ -1534,7 +1513,7 @@ static int eos_ioctl(gpib_board_t *board, unsigned long arg)
return ibeos(board, eos_cmd.eos, eos_cmd.eos_flags);
}
-static int request_service_ioctl(gpib_board_t *board, unsigned long arg)
+static int request_service_ioctl(struct gpib_board *board, unsigned long arg)
{
u8 status_byte;
int retval;
@@ -1546,7 +1525,7 @@ static int request_service_ioctl(gpib_board_t *board, unsigned long arg)
return ibrsv2(board, status_byte, status_byte & request_service_bit);
}
-static int request_service2_ioctl(gpib_board_t *board, unsigned long arg)
+static int request_service2_ioctl(struct gpib_board *board, unsigned long arg)
{
request_service2_t request_service2_cmd;
int retval;
@@ -1613,7 +1592,7 @@ static int dma_ioctl(gpib_board_config_t *config, unsigned long arg)
return 0;
}
-static int autospoll_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int autospoll_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg)
{
autospoll_ioctl_t enable;
@@ -1639,18 +1618,19 @@ static int autospoll_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
board->autospollers--;
retval = 0;
} else {
- pr_err("gpib: tried to set number of autospollers negative\n");
+ dev_err(board->gpib_dev,
+ "tried to set number of autospollers negative\n");
retval = -EINVAL;
}
} else {
- pr_err("gpib: autopoll disable requested before enable\n");
+ dev_err(board->gpib_dev, "autopoll disable requested before enable\n");
retval = -EINVAL;
}
}
return retval;
}
-static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
+static int mutex_ioctl(struct gpib_board *board, gpib_file_private_t *file_priv,
unsigned long arg)
{
int retval, lock_mutex;
@@ -1661,10 +1641,8 @@ static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
if (lock_mutex) {
retval = mutex_lock_interruptible(&board->user_mutex);
- if (retval) {
- pr_warn("gpib: ioctl interrupted while waiting on lock\n");
+ if (retval)
return -ERESTARTSYS;
- }
spin_lock(&board->locking_pid_spinlock);
board->locking_pid = current->pid;
@@ -1672,13 +1650,12 @@ static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
atomic_set(&file_priv->holding_mutex, 1);
- dev_dbg(board->gpib_dev, "pid %i, locked board %d mutex\n",
- current->pid, board->minor);
+ dev_dbg(board->gpib_dev, "locked board mutex\n");
} else {
spin_lock(&board->locking_pid_spinlock);
if (current->pid != board->locking_pid) {
- pr_err("gpib: bug! pid %i tried to release mutex held by pid %i\n",
- current->pid, board->locking_pid);
+ dev_err(board->gpib_dev, "bug! pid %i tried to release mutex held by pid %i\n",
+ current->pid, board->locking_pid);
spin_unlock(&board->locking_pid_spinlock);
return -EPERM;
}
@@ -1688,13 +1665,12 @@ static int mutex_ioctl(gpib_board_t *board, gpib_file_private_t *file_priv,
atomic_set(&file_priv->holding_mutex, 0);
mutex_unlock(&board->user_mutex);
- dev_dbg(board->gpib_dev, "pid %i, unlocked board %i mutex\n",
- current->pid, board->minor);
+ dev_dbg(board->gpib_dev, "unlocked board mutex\n");
}
return 0;
}
-static int timeout_ioctl(gpib_board_t *board, unsigned long arg)
+static int timeout_ioctl(struct gpib_board *board, unsigned long arg)
{
unsigned int timeout;
int retval;
@@ -1704,12 +1680,12 @@ static int timeout_ioctl(gpib_board_t *board, unsigned long arg)
return -EFAULT;
board->usec_timeout = timeout;
- dev_dbg(board->gpib_dev, "pid %i, timeout set to %i usec\n", current->pid, timeout);
+ dev_dbg(board->gpib_dev, "timeout set to %i usec\n", timeout);
return 0;
}
-static int ppc_ioctl(gpib_board_t *board, unsigned long arg)
+static int ppc_ioctl(struct gpib_board *board, unsigned long arg)
{
ppoll_config_ioctl_t cmd;
int retval;
@@ -1735,7 +1711,7 @@ static int ppc_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int set_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg)
+static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg)
{
local_ppoll_mode_ioctl_t cmd;
int retval;
@@ -1744,17 +1720,15 @@ static int set_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg)
if (retval)
return -EFAULT;
- if (!board->interface->local_parallel_poll_mode) {
- pr_warn("gpib: local/remote parallel poll mode not supported by driver.");
- return -EIO;
- }
+ if (!board->interface->local_parallel_poll_mode)
+ return -ENOENT;
board->local_ppoll_mode = cmd != 0;
board->interface->local_parallel_poll_mode(board, board->local_ppoll_mode);
return 0;
}
-static int get_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg)
+static int get_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg)
{
local_ppoll_mode_ioctl_t cmd;
int retval;
@@ -1767,7 +1741,7 @@ static int get_local_ppoll_mode_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int query_board_rsv_ioctl(gpib_board_t *board, unsigned long arg)
+static int query_board_rsv_ioctl(struct gpib_board *board, unsigned long arg)
{
int status;
int retval;
@@ -1781,7 +1755,7 @@ static int query_board_rsv_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int board_info_ioctl(const gpib_board_t *board, unsigned long arg)
+static int board_info_ioctl(const struct gpib_board *board, unsigned long arg)
{
board_info_ioctl_t info;
int retval;
@@ -1804,7 +1778,7 @@ static int board_info_ioctl(const gpib_board_t *board, unsigned long arg)
return 0;
}
-static int interface_clear_ioctl(gpib_board_t *board, unsigned long arg)
+static int interface_clear_ioctl(struct gpib_board *board, unsigned long arg)
{
unsigned int usec_duration;
int retval;
@@ -1867,7 +1841,7 @@ unsigned int num_gpib_events(const gpib_event_queue_t *queue)
return queue->num_events;
}
-static int push_gpib_event_nolock(gpib_board_t *board, short event_type)
+static int push_gpib_event_nolock(struct gpib_board *board, short event_type)
{
gpib_event_queue_t *queue = &board->event_queue;
struct list_head *head = &queue->event_head;
@@ -1887,7 +1861,7 @@ static int push_gpib_event_nolock(gpib_board_t *board, short event_type)
event = kmalloc(sizeof(gpib_event_t), GFP_ATOMIC);
if (!event) {
queue->dropped_event = 1;
- pr_err("gpib: failed to allocate memory for event\n");
+ dev_err(board->gpib_dev, "failed to allocate memory for event\n");
return -ENOMEM;
}
@@ -1905,7 +1879,7 @@ static int push_gpib_event_nolock(gpib_board_t *board, short event_type)
}
// push event onto back of event queue
-int push_gpib_event(gpib_board_t *board, short event_type)
+int push_gpib_event(struct gpib_board *board, short event_type)
{
unsigned long flags;
int retval;
@@ -1923,7 +1897,7 @@ int push_gpib_event(gpib_board_t *board, short event_type)
}
EXPORT_SYMBOL(push_gpib_event);
-static int pop_gpib_event_nolock(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type)
+static int pop_gpib_event_nolock(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type)
{
struct list_head *head = &queue->event_head;
struct list_head *front = head->next;
@@ -1957,7 +1931,7 @@ static int pop_gpib_event_nolock(gpib_board_t *board, gpib_event_queue_t *queue,
}
// pop event from front of event queue
-int pop_gpib_event(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type)
+int pop_gpib_event(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type)
{
unsigned long flags;
int retval;
@@ -1968,7 +1942,7 @@ int pop_gpib_event(gpib_board_t *board, gpib_event_queue_t *queue, short *event_
return retval;
}
-static int event_ioctl(gpib_board_t *board, unsigned long arg)
+static int event_ioctl(struct gpib_board *board, unsigned long arg)
{
event_ioctl_t user_event;
int retval;
@@ -1987,7 +1961,7 @@ static int event_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int request_system_control_ioctl(gpib_board_t *board, unsigned long arg)
+static int request_system_control_ioctl(struct gpib_board *board, unsigned long arg)
{
rsc_ioctl_t request_control;
int retval;
@@ -2001,16 +1975,14 @@ static int request_system_control_ioctl(gpib_board_t *board, unsigned long arg)
return 0;
}
-static int t1_delay_ioctl(gpib_board_t *board, unsigned long arg)
+static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg)
{
t1_delay_ioctl_t cmd;
unsigned int delay;
int retval;
- if (!board->interface->t1_delay) {
- pr_warn("gpib: t1 delay not implemented in driver!\n");
- return -EIO;
- }
+ if (!board->interface->t1_delay)
+ return -ENOENT;
retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
if (retval)
@@ -2018,8 +1990,11 @@ static int t1_delay_ioctl(gpib_board_t *board, unsigned long arg)
delay = cmd;
- board->t1_nano_sec = board->interface->t1_delay(board, delay);
+ retval = board->interface->t1_delay(board, delay);
+ if (retval < 0)
+ return retval;
+ board->t1_nano_sec = retval;
return 0;
}
@@ -2032,7 +2007,7 @@ static const struct file_operations ib_fops = {
.release = &ibclose,
};
-gpib_board_t board_array[GPIB_MAX_NUM_BOARDS];
+struct gpib_board board_array[GPIB_MAX_NUM_BOARDS];
LIST_HEAD(registered_drivers);
@@ -2067,7 +2042,7 @@ void gpib_unregister_driver(gpib_interface_t *interface)
struct list_head *list_ptr;
for (i = 0; i < GPIB_MAX_NUM_BOARDS; i++) {
- gpib_board_t *board = &board_array[i];
+ struct gpib_board *board = &board_array[i];
if (board->interface == interface) {
if (board->use_count > 0)
@@ -2087,7 +2062,6 @@ void gpib_unregister_driver(gpib_interface_t *interface)
kfree(entry);
}
}
- pr_info("gpib: unregistered %s interface\n", interface->name);
}
EXPORT_SYMBOL(gpib_unregister_driver);
@@ -2098,7 +2072,7 @@ static void init_gpib_board_config(gpib_board_config_t *config)
config->pci_slot = -1;
}
-void init_gpib_board(gpib_board_t *board)
+void init_gpib_board(struct gpib_board *board)
{
board->interface = NULL;
board->provider_module = NULL;
@@ -2133,7 +2107,7 @@ void init_gpib_board(gpib_board_t *board)
board->local_ppoll_mode = 0;
}
-int gpib_allocate_board(gpib_board_t *board)
+int gpib_allocate_board(struct gpib_board *board)
{
if (!board->buffer) {
board->buffer_length = 0x4000;
@@ -2146,7 +2120,7 @@ int gpib_allocate_board(gpib_board_t *board)
return 0;
}
-void gpib_deallocate_board(gpib_board_t *board)
+void gpib_deallocate_board(struct gpib_board *board)
{
short dummy;
@@ -2159,7 +2133,7 @@ void gpib_deallocate_board(gpib_board_t *board)
pop_gpib_event(board, &board->event_queue, &dummy);
}
-static void init_board_array(gpib_board_t *board_array, unsigned int length)
+static void init_board_array(struct gpib_board *board_array, unsigned int length)
{
int i;
@@ -2184,7 +2158,7 @@ static int __init gpib_common_init_module(void)
{
int i;
- pr_info("Linux-GPIB core driver\n");
+ pr_info("GPIB core driver\n");
init_board_array(board_array, GPIB_MAX_NUM_BOARDS);
if (register_chrdev(GPIB_CODE, "gpib", &ib_fops)) {
pr_err("gpib: can't get major %d\n", GPIB_CODE);
diff --git a/drivers/staging/gpib/common/iblib.c b/drivers/staging/gpib/common/iblib.c
index 5f6fa135f505..b297261818f2 100644
--- a/drivers/staging/gpib/common/iblib.c
+++ b/drivers/staging/gpib/common/iblib.c
@@ -4,6 +4,8 @@
* copyright : (C) 2001, 2002 by Frank Mori Hess
***************************************************************************/
+#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "ibsys.h"
#include <linux/delay.h>
#include <linux/kthread.h>
@@ -19,15 +21,13 @@
* If fallback_to_async is non-zero, try to take control asynchronously
* if synchronous attempt fails.
*/
-int ibcac(gpib_board_t *board, int sync, int fallback_to_async)
+int ibcac(struct gpib_board *board, int sync, int fallback_to_async)
{
int status = ibstatus(board);
int retval;
- if ((status & CIC) == 0) {
- pr_err("gpib: not CIC during %s()\n", __func__);
- return -1;
- }
+ if ((status & CIC) == 0)
+ return -EINVAL;
if (status & ATN)
return 0;
@@ -61,7 +61,7 @@ int ibcac(gpib_board_t *board, int sync, int fallback_to_async)
* set the skip_check_for_command_acceptors flag in their
* gpib_interface_struct to avoid useless overhead.
*/
-static int check_for_command_acceptors(gpib_board_t *board)
+static int check_for_command_acceptors(struct gpib_board *board)
{
int lines;
@@ -76,15 +76,8 @@ static int check_for_command_acceptors(gpib_board_t *board)
if (lines < 0)
return lines;
- if (lines & ValidATN) {
- if ((lines & BusATN) == 0) {
- pr_err("gpib: ATN not asserted in %s()?", __func__);
- return 0;
- }
- }
-
- if ((lines & ValidNRFD) && (lines & ValidNDAC)) {
- if ((lines & BusNRFD) == 0 && (lines & BusNDAC) == 0)
+ if ((lines & VALID_NRFD) && (lines & VALID_NDAC)) {
+ if ((lines & BUS_NRFD) == 0 && (lines & BUS_NDAC) == 0)
return -ENOTCONN;
}
@@ -103,7 +96,7 @@ static int check_for_command_acceptors(gpib_board_t *board)
* must be called to initialize the GPIB and enable
* the interface to leave the controller idle state.
*/
-int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_written)
+int ibcmd(struct gpib_board *board, uint8_t *buf, size_t length, size_t *bytes_written)
{
ssize_t ret = 0;
int status;
@@ -112,10 +105,8 @@ int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_writte
status = ibstatus(board);
- if ((status & CIC) == 0) {
- pr_err("gpib: cannot send command when not controller-in-charge\n");
- return -EIO;
- }
+ if ((status & CIC) == 0)
+ return -EINVAL;
os_start_timer(board, board->usec_timeout);
@@ -140,26 +131,22 @@ int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_writte
* active state, i.e., turn ATN off.
*/
-int ibgts(gpib_board_t *board)
+int ibgts(struct gpib_board *board)
{
int status = ibstatus(board);
int retval;
- if ((status & CIC) == 0) {
- pr_err("gpib: not CIC during %s()\n", __func__);
- return -1;
- }
+ if ((status & CIC) == 0)
+ return -EINVAL;
retval = board->interface->go_to_standby(board); /* go to standby */
- if (retval < 0)
- pr_err("gpib: error while going to standby\n");
board->interface->update_status(board, 0);
return retval;
}
-static int autospoll_wait_should_wake_up(gpib_board_t *board)
+static int autospoll_wait_should_wake_up(struct gpib_board *board)
{
int retval;
@@ -175,7 +162,7 @@ static int autospoll_wait_should_wake_up(gpib_board_t *board)
static int autospoll_thread(void *board_void)
{
- gpib_board_t *board = board_void;
+ struct gpib_board *board = board_void;
int retval = 0;
dev_dbg(board->gpib_dev, "entering autospoll thread\n");
@@ -200,20 +187,19 @@ static int autospoll_thread(void *board_void)
retval = autopoll_all_devices(board);
module_put(board->provider_module);
} else {
- pr_err("gpib%i: %s: try_module_get() failed!\n", board->minor, __func__);
+ dev_err(board->gpib_dev, "try_module_get() failed!\n");
}
if (retval <= 0) {
- pr_err("gpib%i: %s: stuck SRQ\n", board->minor, __func__);
+ dev_err(board->gpib_dev, "stuck SRQ\n");
atomic_set(&board->stuck_srq, 1); // XXX could be better
set_bit(SRQI_NUM, &board->status);
}
}
- pr_info("gpib%i: exiting autospoll thread\n", board->minor);
return retval;
}
-int ibonline(gpib_board_t *board)
+int ibonline(struct gpib_board *board)
{
int retval;
@@ -230,7 +216,6 @@ int ibonline(gpib_board_t *board)
retval = board->interface->attach(board, &board->config);
if (retval < 0) {
board->interface->detach(board);
- pr_err("gpib: interface attach failed\n");
return retval;
}
/* nios2nommu on 2.6.11 uclinux kernel has weird problems
@@ -241,19 +226,19 @@ int ibonline(gpib_board_t *board)
"gpib%d_autospoll_kthread", board->minor);
retval = IS_ERR(board->autospoll_task);
if (retval) {
- pr_err("gpib: failed to create autospoll thread\n");
+ dev_err(board->gpib_dev, "failed to create autospoll thread\n");
board->interface->detach(board);
return retval;
}
#endif
board->online = 1;
- dev_dbg(board->gpib_dev, "gpib: board online\n");
+ dev_dbg(board->gpib_dev, "board online\n");
return 0;
}
/* XXX need to make sure board is generally not in use (grab board lock?) */
-int iboffline(gpib_board_t *board)
+int iboffline(struct gpib_board *board)
{
int retval;
@@ -265,14 +250,14 @@ int iboffline(gpib_board_t *board)
if (board->autospoll_task && !IS_ERR(board->autospoll_task)) {
retval = kthread_stop(board->autospoll_task);
if (retval)
- pr_err("gpib: kthread_stop returned %i\n", retval);
+ dev_err(board->gpib_dev, "kthread_stop returned %i\n", retval);
board->autospoll_task = NULL;
}
board->interface->detach(board);
gpib_deallocate_board(board);
board->online = 0;
- dev_dbg(board->gpib_dev, "gpib: board offline\n");
+ dev_dbg(board->gpib_dev, "board offline\n");
return 0;
}
@@ -285,7 +270,7 @@ int iboffline(gpib_board_t *board)
* Next LSB (bits 8-15) - STATUS lines mask (lines that are currently set).
*
*/
-int iblines(const gpib_board_t *board, short *lines)
+int iblines(const struct gpib_board *board, short *lines)
{
int retval;
@@ -312,7 +297,7 @@ int iblines(const gpib_board_t *board, short *lines)
* calling ibcmd.
*/
-int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t *nbytes)
+int ibrd(struct gpib_board *board, uint8_t *buf, size_t length, int *end_flag, size_t *nbytes)
{
ssize_t ret = 0;
int retval;
@@ -320,10 +305,8 @@ int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t
*nbytes = 0;
*end_flag = 0;
- if (length == 0) {
- pr_warn("gpib: %s() called with zero length?\n", __func__);
+ if (length == 0)
return 0;
- }
if (board->master) {
retval = ibgts(board);
@@ -338,10 +321,9 @@ int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t
do {
ret = board->interface->read(board, buf, length - *nbytes, end_flag, &bytes_read);
- if (ret < 0) {
- pr_err("gpib read error\n");
+ if (ret < 0)
goto ibrd_out;
- }
+
buf += bytes_read;
*nbytes += bytes_read;
if (need_resched())
@@ -361,7 +343,7 @@ ibrd_out:
* 1. Prior to conducting the poll the interface is placed
* in the controller active state.
*/
-int ibrpp(gpib_board_t *board, uint8_t *result)
+int ibrpp(struct gpib_board *board, uint8_t *result)
{
int retval = 0;
@@ -370,15 +352,13 @@ int ibrpp(gpib_board_t *board, uint8_t *result)
if (retval)
return -1;
- if (board->interface->parallel_poll(board, result)) {
- pr_err("gpib: parallel poll failed\n");
- retval = -1;
- }
+ retval = board->interface->parallel_poll(board, result);
+
os_remove_timer(board);
return retval;
}
-int ibppc(gpib_board_t *board, uint8_t configuration)
+int ibppc(struct gpib_board *board, uint8_t configuration)
{
configuration &= 0x1f;
board->interface->parallel_poll_configure(board, configuration);
@@ -387,15 +367,13 @@ int ibppc(gpib_board_t *board, uint8_t configuration)
return 0;
}
-int ibrsv2(gpib_board_t *board, uint8_t status_byte, int new_reason_for_service)
+int ibrsv2(struct gpib_board *board, uint8_t status_byte, int new_reason_for_service)
{
int board_status = ibstatus(board);
const unsigned int MSS = status_byte & request_service_bit;
- if ((board_status & CIC)) {
- pr_err("gpib: interface requested service while CIC\n");
+ if ((board_status & CIC))
return -EINVAL;
- }
if (MSS == 0 && new_reason_for_service)
return -EINVAL;
@@ -422,21 +400,17 @@ int ibrsv2(gpib_board_t *board, uint8_t status_byte, int new_reason_for_service)
* ibcmd in order to initialize the bus and enable the
* interface to leave the controller idle state.
*/
-int ibsic(gpib_board_t *board, unsigned int usec_duration)
+int ibsic(struct gpib_board *board, unsigned int usec_duration)
{
- if (board->master == 0) {
- pr_err("gpib: tried to assert IFC when not system controller\n");
- return -1;
- }
+ if (board->master == 0)
+ return -EINVAL;
if (usec_duration < 100)
usec_duration = 100;
- if (usec_duration > 1000) {
+ if (usec_duration > 1000)
usec_duration = 1000;
- pr_warn("gpib: warning, shortening long udelay\n");
- }
- dev_dbg(board->gpib_dev, "sending interface clear\n");
+ dev_dbg(board->gpib_dev, "sending interface clear, delay = %ius\n", usec_duration);
board->interface->interface_clear(board, 1);
udelay(usec_duration);
board->interface->interface_clear(board, 0);
@@ -444,26 +418,22 @@ int ibsic(gpib_board_t *board, unsigned int usec_duration)
return 0;
}
-void ibrsc(gpib_board_t *board, int request_control)
+ /* FIXME make int */
+void ibrsc(struct gpib_board *board, int request_control)
{
board->master = request_control != 0;
- if (!board->interface->request_system_control) {
- pr_err("gpib: bug! driver does not implement request_system_control()\n");
- return;
- }
- board->interface->request_system_control(board, request_control);
+ if (board->interface->request_system_control)
+ board->interface->request_system_control(board, request_control);
}
/*
* IBSRE
* Send REN true if v is non-zero or false if v is zero.
*/
-int ibsre(gpib_board_t *board, int enable)
+int ibsre(struct gpib_board *board, int enable)
{
- if (board->master == 0) {
- pr_err("gpib: tried to set REN when not system controller\n");
- return -1;
- }
+ if (board->master == 0)
+ return -EINVAL;
board->interface->remote_enable(board, enable); /* set or clear REN */
if (!enable)
@@ -477,12 +447,11 @@ int ibsre(gpib_board_t *board, int enable)
* change the GPIB address of the interface board. The address
* must be 0 through 30. ibonl resets the address to PAD.
*/
-int ibpad(gpib_board_t *board, unsigned int addr)
+int ibpad(struct gpib_board *board, unsigned int addr)
{
- if (addr > MAX_GPIB_PRIMARY_ADDRESS) {
- pr_err("gpib: invalid primary address %u\n", addr);
- return -1;
- }
+ if (addr > MAX_GPIB_PRIMARY_ADDRESS)
+ return -EINVAL;
+
board->pad = addr;
if (board->online)
board->interface->primary_address(board, board->pad);
@@ -496,12 +465,10 @@ int ibpad(gpib_board_t *board, unsigned int addr)
* The address must be 0 through 30, or negative disables. ibonl resets the
* address to SAD.
*/
-int ibsad(gpib_board_t *board, int addr)
+int ibsad(struct gpib_board *board, int addr)
{
- if (addr > MAX_GPIB_SECONDARY_ADDRESS) {
- pr_err("gpib: invalid secondary address %i\n", addr);
- return -1;
- }
+ if (addr > MAX_GPIB_SECONDARY_ADDRESS)
+ return -EINVAL;
board->sad = addr;
if (board->online) {
if (board->sad >= 0)
@@ -519,14 +486,12 @@ int ibsad(gpib_board_t *board, int addr)
* Set the end-of-string modes for I/O operations to v.
*
*/
-int ibeos(gpib_board_t *board, int eos, int eosflags)
+int ibeos(struct gpib_board *board, int eos, int eosflags)
{
int retval;
- if (eosflags & ~EOS_MASK) {
- pr_err("bad EOS modes\n");
+ if (eosflags & ~EOS_MASK)
return -EINVAL;
- }
if (eosflags & REOS) {
retval = board->interface->enable_eos(board, eos, eosflags & BIN);
} else {
@@ -536,12 +501,12 @@ int ibeos(gpib_board_t *board, int eos, int eosflags)
return retval;
}
-int ibstatus(gpib_board_t *board)
+int ibstatus(struct gpib_board *board)
{
return general_ibstatus(board, NULL, 0, 0, NULL);
}
-int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device,
+int general_ibstatus(struct gpib_board *board, const gpib_status_queue_t *device,
int clear_mask, int set_mask, gpib_descriptor_t *desc)
{
int status = 0;
@@ -555,8 +520,8 @@ int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device,
status &= ~TIMO;
/* get real SRQI status if we can */
if (iblines(board, &line_status) == 0) {
- if ((line_status & ValidSRQ)) {
- if ((line_status & BusSRQ))
+ if ((line_status & VALID_SRQ)) {
+ if ((line_status & BUS_SRQ))
status |= SRQI;
else
status &= ~SRQI;
@@ -587,7 +552,7 @@ int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device,
}
struct wait_info {
- gpib_board_t *board;
+ struct gpib_board *board;
struct timer_list timer;
int timed_out;
unsigned long usec_timeout;
@@ -611,7 +576,7 @@ static void init_wait_info(struct wait_info *winfo)
static int wait_satisfied(struct wait_info *winfo, gpib_status_queue_t *status_queue,
int wait_mask, int *status, gpib_descriptor_t *desc)
{
- gpib_board_t *board = winfo->board;
+ struct gpib_board *board = winfo->board;
int temp_status;
if (mutex_lock_interruptible(&board->big_gpib_mutex))
@@ -645,7 +610,7 @@ static void start_wait_timer(struct wait_info *winfo)
static void remove_wait_timer(struct wait_info *winfo)
{
- del_timer_sync(&winfo->timer);
+ timer_delete_sync(&winfo->timer);
destroy_timer_on_stack(&winfo->timer);
}
@@ -657,7 +622,7 @@ static void remove_wait_timer(struct wait_info *winfo)
* If the mask is 0 then
* no condition is waited for.
*/
-int ibwait(gpib_board_t *board, int wait_mask, int clear_mask, int set_mask,
+int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask,
int *status, unsigned long usec_timeout, gpib_descriptor_t *desc)
{
int retval = 0;
@@ -712,15 +677,13 @@ int ibwait(gpib_board_t *board, int wait_mask, int clear_mask, int set_mask,
* well as the interface board itself must be
* addressed by calling ibcmd.
*/
-int ibwrt(gpib_board_t *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written)
+int ibwrt(struct gpib_board *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written)
{
int ret = 0;
int retval;
- if (cnt == 0) {
- pr_warn("gpib: %s() called with zero length?\n", __func__);
+ if (cnt == 0)
return 0;
- }
if (board->master) {
retval = ibgts(board);
diff --git a/drivers/staging/gpib/common/ibsys.h b/drivers/staging/gpib/common/ibsys.h
index da20971e9c7e..19960af809c2 100644
--- a/drivers/staging/gpib/common/ibsys.h
+++ b/drivers/staging/gpib/common/ibsys.h
@@ -19,13 +19,13 @@
#define MAX_GPIB_PRIMARY_ADDRESS 30
#define MAX_GPIB_SECONDARY_ADDRESS 31
-int gpib_allocate_board(gpib_board_t *board);
-void gpib_deallocate_board(gpib_board_t *board);
+int gpib_allocate_board(struct gpib_board *board);
+void gpib_deallocate_board(struct gpib_board *board);
unsigned int num_status_bytes(const gpib_status_queue_t *dev);
-int push_status_byte(gpib_board_t *board, gpib_status_queue_t *device, uint8_t poll_byte);
-int pop_status_byte(gpib_board_t *board, gpib_status_queue_t *device, uint8_t *poll_byte);
-gpib_status_queue_t *get_gpib_status_queue(gpib_board_t *board, unsigned int pad, int sad);
-int get_serial_poll_byte(gpib_board_t *board, unsigned int pad, int sad,
+int push_status_byte(struct gpib_board *board, gpib_status_queue_t *device, uint8_t poll_byte);
+int pop_status_byte(struct gpib_board *board, gpib_status_queue_t *device, uint8_t *poll_byte);
+gpib_status_queue_t *get_gpib_status_queue(struct gpib_board *board, unsigned int pad, int sad);
+int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad,
unsigned int usec_timeout, uint8_t *poll_byte);
-int autopoll_all_devices(gpib_board_t *board);
+int autopoll_all_devices(struct gpib_board *board);
diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.c b/drivers/staging/gpib/eastwood/fluke_gpib.c
index 0304c5de4ccd..a6b1ac169f94 100644
--- a/drivers/staging/gpib/eastwood/fluke_gpib.c
+++ b/drivers/staging/gpib/eastwood/fluke_gpib.c
@@ -7,6 +7,10 @@
* copyright: (C) 2006, 2010, 2015 Fluke Corporation
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "fluke_gpib.h"
#include "gpibP.h"
@@ -20,11 +24,11 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB Driver for Fluke cda devices");
-static int fluke_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config);
-static int fluke_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config);
-static void fluke_detach(gpib_board_t *board);
-static int fluke_config_dma(gpib_board_t *board, int output);
-static irqreturn_t fluke_gpib_internal_interrupt(gpib_board_t *board);
+static int fluke_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config);
+static int fluke_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config);
+static void fluke_detach(struct gpib_board *board);
+static int fluke_config_dma(struct gpib_board *board, int output);
+static irqreturn_t fluke_gpib_internal_interrupt(struct gpib_board *board);
static struct platform_device *fluke_gpib_pdev;
@@ -50,7 +54,7 @@ static void fluke_locking_write_byte(struct nec7210_priv *nec_priv, uint8_t byte
}
// wrappers for interface functions
-static int fluke_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
+static int fluke_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
size_t *bytes_read)
{
struct fluke_priv *priv = board->private_data;
@@ -58,7 +62,7 @@ static int fluke_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *
return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
}
-static int fluke_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fluke_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
struct fluke_priv *priv = board->private_data;
@@ -66,28 +70,29 @@ static int fluke_write(gpib_board_t *board, uint8_t *buffer, size_t length,
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-static int fluke_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int fluke_command(struct gpib_board *board, uint8_t *buffer,
+ size_t length, size_t *bytes_written)
{
struct fluke_priv *priv = board->private_data;
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-static int fluke_take_control(gpib_board_t *board, int synchronous)
+static int fluke_take_control(struct gpib_board *board, int synchronous)
{
struct fluke_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-static int fluke_go_to_standby(gpib_board_t *board)
+static int fluke_go_to_standby(struct gpib_board *board)
{
struct fluke_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-static void fluke_request_system_control(gpib_board_t *board, int request_control)
+static void fluke_request_system_control(struct gpib_board *board, int request_control)
{
struct fluke_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -95,91 +100,91 @@ static void fluke_request_system_control(gpib_board_t *board, int request_contro
nec7210_request_system_control(board, nec_priv, request_control);
}
-static void fluke_interface_clear(gpib_board_t *board, int assert)
+static void fluke_interface_clear(struct gpib_board *board, int assert)
{
struct fluke_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-static void fluke_remote_enable(gpib_board_t *board, int enable)
+static void fluke_remote_enable(struct gpib_board *board, int enable)
{
struct fluke_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-static int fluke_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int fluke_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct fluke_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-static void fluke_disable_eos(gpib_board_t *board)
+static void fluke_disable_eos(struct gpib_board *board)
{
struct fluke_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-static unsigned int fluke_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int fluke_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct fluke_priv *priv = board->private_data;
return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
}
-static int fluke_primary_address(gpib_board_t *board, unsigned int address)
+static int fluke_primary_address(struct gpib_board *board, unsigned int address)
{
struct fluke_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-static int fluke_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int fluke_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct fluke_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-static int fluke_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int fluke_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct fluke_priv *priv = board->private_data;
return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
}
-static void fluke_parallel_poll_configure(gpib_board_t *board, uint8_t configuration)
+static void fluke_parallel_poll_configure(struct gpib_board *board, uint8_t configuration)
{
struct fluke_priv *priv = board->private_data;
nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration);
}
-static void fluke_parallel_poll_response(gpib_board_t *board, int ist)
+static void fluke_parallel_poll_response(struct gpib_board *board, int ist)
{
struct fluke_priv *priv = board->private_data;
nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
}
-static void fluke_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void fluke_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct fluke_priv *priv = board->private_data;
nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
}
-static uint8_t fluke_serial_poll_status(gpib_board_t *board)
+static uint8_t fluke_serial_poll_status(struct gpib_board *board)
{
struct fluke_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-static void fluke_return_to_local(gpib_board_t *board)
+static void fluke_return_to_local(struct gpib_board *board)
{
struct fluke_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -189,39 +194,37 @@ static void fluke_return_to_local(gpib_board_t *board)
write_byte(nec_priv, AUX_RTL, AUXMR);
}
-static int fluke_line_status(const gpib_board_t *board)
+static int fluke_line_status(const struct gpib_board *board)
{
- int status = ValidALL;
+ int status = VALID_ALL;
int bsr_bits;
struct fluke_priv *e_priv;
- struct nec7210_priv *nec_priv;
e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
bsr_bits = fluke_paged_read_byte(e_priv, BUS_STATUS, BUS_STATUS_PAGE);
if ((bsr_bits & BSR_REN_BIT) == 0)
- status |= BusREN;
+ status |= BUS_REN;
if ((bsr_bits & BSR_IFC_BIT) == 0)
- status |= BusIFC;
+ status |= BUS_IFC;
if ((bsr_bits & BSR_SRQ_BIT) == 0)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if ((bsr_bits & BSR_EOI_BIT) == 0)
- status |= BusEOI;
+ status |= BUS_EOI;
if ((bsr_bits & BSR_NRFD_BIT) == 0)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if ((bsr_bits & BSR_NDAC_BIT) == 0)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if ((bsr_bits & BSR_DAV_BIT) == 0)
- status |= BusDAV;
+ status |= BUS_DAV;
if ((bsr_bits & BSR_ATN_BIT) == 0)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
-static unsigned int fluke_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int fluke_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct fluke_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -238,7 +241,7 @@ static unsigned int fluke_t1_delay(gpib_board_t *board, unsigned int nano_sec)
return retval;
}
-static int lacs_or_read_ready(gpib_board_t *board)
+static int lacs_or_read_ready(struct gpib_board *board)
{
const struct fluke_priv *e_priv = board->private_data;
const struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -254,7 +257,7 @@ static int lacs_or_read_ready(gpib_board_t *board)
/* Wait until it is possible for a read to do something useful. This
* is not essential, it only exists to prevent RFD holdoff from being released pointlessly.
*/
-static int wait_for_read(gpib_board_t *board)
+static int wait_for_read(struct gpib_board *board)
{
struct fluke_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -263,9 +266,9 @@ static int wait_for_read(gpib_board_t *board)
if (wait_event_interruptible(board->wait,
lacs_or_read_ready(board) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
@@ -311,34 +314,30 @@ static int source_handshake_is_sids_or_sgns(struct fluke_priv *e_priv)
* If the chip is SGNS it is probably waiting for a a byte to
* be written to it.
*/
-static int wait_for_data_out_ready(gpib_board_t *board)
+static int wait_for_data_out_ready(struct gpib_board *board)
{
struct fluke_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
int retval = 0;
-// printk("%s: enter\n", __FUNCTION__);
if (wait_event_interruptible(board->wait,
(test_bit(TACS_NUM, &board->status) &&
source_handshake_is_sgns(e_priv)) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
retval = -EINTR;
-// printk("%s: exit, retval=%i\n", __FUNCTION__, retval);
return retval;
}
-static int wait_for_sids_or_sgns(gpib_board_t *board)
+static int wait_for_sids_or_sgns(struct gpib_board *board)
{
struct fluke_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
int retval = 0;
-// printk("%s: enter\n", __FUNCTION__);
if (wait_event_interruptible(board->wait,
source_handshake_is_sids_or_sgns(e_priv) ||
@@ -350,19 +349,17 @@ static int wait_for_sids_or_sgns(gpib_board_t *board)
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
retval = -EINTR;
-// printk("%s: exit, retval=%i\n", __FUNCTION__, retval);
return retval;
}
static void fluke_dma_callback(void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct fluke_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
unsigned long flags;
spin_lock_irqsave(&board->spinlock, flags);
-// printk("%s: enter\n", __FUNCTION__);
nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, HR_DOIE | HR_DIIE);
wake_up_interruptible(&board->wait);
@@ -370,11 +367,11 @@ static void fluke_dma_callback(void *arg)
fluke_gpib_internal_interrupt(board);
clear_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
clear_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
-// printk("%s: exit\n", __FUNCTION__);
+
spin_unlock_irqrestore(&board->spinlock, flags);
}
-static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fluke_dma_write(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written)
{
struct fluke_priv *e_priv = board->private_data;
@@ -385,7 +382,7 @@ static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
struct dma_async_tx_descriptor *tx_desc;
*bytes_written = 0;
-// printk("%s: enter\n", __FUNCTION__);
+
if (WARN_ON_ONCE(length > e_priv->dma_buffer_size))
return -EFAULT;
dmaengine_terminate_all(e_priv->dma_channel);
@@ -403,7 +400,7 @@ static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, address, length, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tx_desc) {
- pr_err("fluke_gpib: failed to allocate dma transmit descriptor\n");
+ dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
retval = -ENOMEM;
goto cleanup;
}
@@ -419,10 +416,8 @@ static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
clear_bit(WRITE_READY_BN, &nec_priv->state);
set_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
- // printk("%s: in spin lock\n", __FUNCTION__);
spin_unlock_irqrestore(&board->spinlock, flags);
-// printk("%s: waiting for write.\n", __FUNCTION__);
// suspend until message is sent
if (wait_event_interruptible(board->wait,
((readl(e_priv->write_transfer_counter) &
@@ -430,7 +425,6 @@ static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted!\n");
retval = -ERESTARTSYS;
}
if (test_bit(TIMO_NUM, &board->status))
@@ -459,11 +453,10 @@ static int fluke_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
cleanup:
dma_unmap_single(board->dev, address, length, DMA_TO_DEVICE);
-// printk("%s: exit, retval=%d\n", __FUNCTION__, retval);
return retval;
}
-static int fluke_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fluke_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
struct fluke_priv *e_priv = board->private_data;
@@ -474,7 +467,7 @@ static int fluke_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length
size_t dma_remainder = remainder;
if (!e_priv->dma_channel) {
- pr_err("fluke_gpib: No dma channel available, cannot do accel write.");
+ dev_err(board->gpib_dev, "No dma channel available, cannot do accel write.");
return -ENXIO;
}
@@ -486,7 +479,6 @@ static int fluke_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length
if (send_eoi)
--dma_remainder;
-// printk("%s: entering while loop\n", __FUNCTION__);
while (dma_remainder > 0) {
size_t num_bytes;
@@ -512,7 +504,7 @@ static int fluke_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length
//handle sending of last byte with eoi
if (send_eoi) {
size_t num_bytes;
- // printk("%s: handling last byte\n", __FUNCTION__);
+
if (WARN_ON_ONCE(remainder != 1))
return -EFAULT;
@@ -533,7 +525,6 @@ static int fluke_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length
return retval;
remainder -= num_bytes;
}
-// printk("%s: bytes send=%i\n", __FUNCTION__, (int)(length - remainder));
return 0;
}
@@ -544,7 +535,7 @@ static int fluke_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie)
result = dmaengine_pause(chan);
if (result < 0) {
- pr_err("fluke_gpib: dma pause failed?\n");
+ pr_err("dma pause failed?\n");
return result;
}
dmaengine_tx_status(chan, cookie, &state);
@@ -553,7 +544,7 @@ static int fluke_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie)
return state.residue;
}
-static int fluke_dma_read(gpib_board_t *board, uint8_t *buffer,
+static int fluke_dma_read(struct gpib_board *board, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
struct fluke_priv *e_priv = board->private_data;
@@ -567,10 +558,6 @@ static int fluke_dma_read(gpib_board_t *board, uint8_t *buffer,
int i;
static const int timeout = 10;
- // printk("%s: enter, bus_address=0x%x, length=%i\n", __FUNCTION__,
- // (unsigned)bus_address,
- // (int)length);
-
*bytes_read = 0;
*end = 0;
if (length == 0)
@@ -589,7 +576,7 @@ static int fluke_dma_read(gpib_board_t *board, uint8_t *buffer,
bus_address, length, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tx_desc) {
- pr_err("fluke_gpib: failed to allocate dma transmit descriptor\n");
+ dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
dma_unmap_single(NULL, bus_address, length, DMA_FROM_DEVICE);
return -EIO;
}
@@ -608,14 +595,12 @@ static int fluke_dma_read(gpib_board_t *board, uint8_t *buffer,
clear_bit(READ_READY_BN, &nec_priv->state);
spin_unlock_irqrestore(&board->spinlock, flags);
-// printk("waiting for data transfer.\n");
// wait for data to transfer
if (wait_event_interruptible(board->wait,
test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state) == 0 ||
test_bit(RECEIVED_END_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_warn("fluke: dma read wait interrupted\n");
retval = -ERESTARTSYS;
}
if (test_bit(TIMO_NUM, &board->status))
@@ -672,7 +657,7 @@ static int fluke_dma_read(gpib_board_t *board, uint8_t *buffer,
return retval;
}
-static int fluke_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fluke_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read)
{
struct fluke_priv *e_priv = board->private_data;
@@ -682,10 +667,6 @@ static int fluke_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
int retval = 0;
size_t dma_nbytes;
-/* printk("%s: enter, buffer=0x%p, length=%i\n", __FUNCTION__,
- * buffer, (int)length);
- * printk("\t dma_buffer=0x%p\n", e_priv->dma_buffer);
- */
*end = 0;
*bytes_read = 0;
@@ -699,7 +680,6 @@ static int fluke_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
nec7210_release_rfd_holdoff(board, nec_priv);
-// printk("%s: entering while loop\n", __FUNCTION__);
while (remain > 0) {
transfer_size = (e_priv->dma_buffer_size < remain) ?
e_priv->dma_buffer_size : remain;
@@ -709,14 +689,12 @@ static int fluke_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
*bytes_read += dma_nbytes;
if (*end)
break;
- if (retval < 0) {
-// printk("%s: early exit, retval=%i\n", __FUNCTION__, (int)retval);
+ if (retval < 0)
return retval;
- }
if (need_resched())
schedule();
}
-// printk("%s: exit, retval=%i\n", __FUNCTION__, (int)retval);
+
return retval;
}
@@ -809,7 +787,7 @@ static gpib_interface_t fluke_interface = {
.return_to_local = fluke_return_to_local,
};
-irqreturn_t fluke_gpib_internal_interrupt(gpib_board_t *board)
+irqreturn_t fluke_gpib_internal_interrupt(struct gpib_board *board)
{
int status0, status1, status2;
struct fluke_priv *priv = board->private_data;
@@ -830,13 +808,6 @@ irqreturn_t fluke_gpib_internal_interrupt(gpib_board_t *board)
if (nec7210_interrupt_have_status(board, nec_priv, status1, status2) == IRQ_HANDLED)
retval = IRQ_HANDLED;
-/*
- * if((status1 & nec_priv->reg_bits[IMR1]) ||
- * (status2 & (nec_priv->reg_bits[IMR2] & IMR2_ENABLE_INTR_MASK)))
- * {
- * printk("fluke: status1 0x%x, status2 0x%x\n", status1, status2);
- * }
- */
if (read_byte(nec_priv, ADR0) & DATA_IN_STATUS) {
if (test_bit(RFD_HOLDOFF_BN, &nec_priv->state))
@@ -853,7 +824,7 @@ irqreturn_t fluke_gpib_internal_interrupt(gpib_board_t *board)
static irqreturn_t fluke_gpib_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
unsigned long flags;
irqreturn_t retval;
@@ -863,7 +834,7 @@ static irqreturn_t fluke_gpib_interrupt(int irq, void *arg)
return retval;
}
-static int fluke_allocate_private(gpib_board_t *board)
+static int fluke_allocate_private(struct gpib_board *board)
{
struct fluke_priv *priv;
@@ -880,7 +851,7 @@ static int fluke_allocate_private(gpib_board_t *board)
return 0;
}
-static void fluke_generic_detach(gpib_board_t *board)
+static void fluke_generic_detach(struct gpib_board *board)
{
if (board->private_data) {
struct fluke_priv *e_priv = board->private_data;
@@ -892,7 +863,7 @@ static void fluke_generic_detach(gpib_board_t *board)
}
// generic part of attach functions shared by all cb7210 boards
-static int fluke_generic_attach(gpib_board_t *board)
+static int fluke_generic_attach(struct gpib_board *board)
{
struct fluke_priv *e_priv;
struct nec7210_priv *nec_priv;
@@ -912,7 +883,7 @@ static int fluke_generic_attach(gpib_board_t *board)
return 0;
}
-static int fluke_config_dma(gpib_board_t *board, int output)
+static int fluke_config_dma(struct gpib_board *board, int output)
{
struct fluke_priv *e_priv = board->private_data;
struct dma_slave_config config;
@@ -937,7 +908,7 @@ static int fluke_config_dma(gpib_board_t *board, int output)
return dmaengine_slave_config(e_priv->dma_channel, &config);
}
-static int fluke_init(struct fluke_priv *e_priv, gpib_board_t *board, int handshake_mode)
+static int fluke_init(struct fluke_priv *e_priv, struct gpib_board *board, int handshake_mode)
{
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -954,7 +925,7 @@ static int fluke_init(struct fluke_priv *e_priv, gpib_board_t *board, int handsh
/* poll so we can detect ATN changes */
if (gpib_request_pseudo_irq(board, fluke_gpib_interrupt)) {
- pr_err("fluke_gpib: failed to allocate pseudo_irq\n");
+ dev_err(board->gpib_dev, "failed to allocate pseudo_irq\n");
return -EINVAL;
}
@@ -972,7 +943,7 @@ static bool gpib_dma_channel_filter(struct dma_chan *chan, void *filter_param)
return chan->chan_id == 0;
}
-static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *config,
+static int fluke_attach_impl(struct gpib_board *board, const gpib_board_config_t *config,
unsigned int handshake_mode)
{
struct fluke_priv *e_priv;
@@ -984,7 +955,7 @@ static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *con
dma_cap_mask_t dma_cap;
if (!fluke_gpib_pdev) {
- pr_err("No gpib platform device was found, attach failed.\n");
+ dev_err(board->gpib_dev, "No fluke device was found, attach failed.\n");
return -ENODEV;
}
@@ -999,7 +970,7 @@ static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *con
res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 0);
if (!res) {
- dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource for cb7210 gpib\n");
+ dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource\n");
return -ENODEV;
}
@@ -1012,10 +983,7 @@ static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *con
e_priv->gpib_iomem_res = res;
nec_priv->mmiobase = ioremap(e_priv->gpib_iomem_res->start,
- resource_size(e_priv->gpib_iomem_res));
- pr_info("gpib: mmiobase %llx remapped to %p, length=%d\n",
- (u64)e_priv->gpib_iomem_res->start,
- nec_priv->mmiobase, (int)resource_size(e_priv->gpib_iomem_res));
+ resource_size(e_priv->gpib_iomem_res));
if (!nec_priv->mmiobase) {
dev_err(&fluke_gpib_pdev->dev, "Could not map I/O memory\n");
return -ENOMEM;
@@ -1050,19 +1018,14 @@ static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *con
e_priv->write_transfer_counter = ioremap(e_priv->write_transfer_counter_res->start,
resource_size(e_priv->write_transfer_counter_res));
- pr_info("gpib: write transfer counter %lx remapped to %p, length=%d\n",
- (unsigned long)e_priv->write_transfer_counter_res->start,
- e_priv->write_transfer_counter,
- (int)resource_size(e_priv->write_transfer_counter_res));
if (!e_priv->write_transfer_counter) {
dev_err(&fluke_gpib_pdev->dev, "Could not map I/O memory\n");
return -ENOMEM;
}
irq = platform_get_irq(fluke_gpib_pdev, 0);
- pr_info("gpib: irq %d\n", irq);
if (irq < 0) {
- dev_err(&fluke_gpib_pdev->dev, "fluke_gpib: request for IRQ failed\n");
+ dev_err(&fluke_gpib_pdev->dev, "failed to obtain IRQ\n");
return -EBUSY;
}
retval = request_irq(irq, fluke_gpib_interrupt, isr_flags, fluke_gpib_pdev->name, board);
@@ -1078,7 +1041,7 @@ static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *con
dma_cap_set(DMA_SLAVE, dma_cap);
e_priv->dma_channel = dma_request_channel(dma_cap, gpib_dma_channel_filter, NULL);
if (!e_priv->dma_channel) {
- pr_err("fluke_gpib: failed to allocate a dma channel.\n");
+ dev_err(board->gpib_dev, "failed to allocate a dma channel.\n");
// we don't error out here because unaccel interface will still
// work without dma
}
@@ -1086,17 +1049,17 @@ static int fluke_attach_impl(gpib_board_t *board, const gpib_board_config_t *con
return fluke_init(e_priv, board, handshake_mode);
}
-int fluke_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config)
+int fluke_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config)
{
return fluke_attach_impl(board, config, HR_HLDA);
}
-int fluke_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config)
+int fluke_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config)
{
return fluke_attach_impl(board, config, HR_HLDE);
}
-void fluke_detach(gpib_board_t *board)
+void fluke_detach(struct gpib_board *board)
{
struct fluke_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1142,8 +1105,7 @@ MODULE_DEVICE_TABLE(of, fluke_gpib_of_match);
static struct platform_driver fluke_gpib_platform_driver = {
.driver = {
- .name = "fluke_gpib",
- .owner = THIS_MODULE,
+ .name = DRV_NAME,
.of_match_table = fluke_gpib_of_match,
},
.probe = &fluke_gpib_probe
@@ -1155,25 +1117,25 @@ static int __init fluke_init_module(void)
result = platform_driver_register(&fluke_gpib_platform_driver);
if (result) {
- pr_err("fluke_gpib: platform_driver_register failed: error = %d\n", result);
+ pr_err("platform_driver_register failed: error = %d\n", result);
return result;
}
result = gpib_register_driver(&fluke_unaccel_interface, THIS_MODULE);
if (result) {
- pr_err("fluke_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_unaccel;
}
result = gpib_register_driver(&fluke_hybrid_interface, THIS_MODULE);
if (result) {
- pr_err("fluke_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_hybrid;
}
result = gpib_register_driver(&fluke_interface, THIS_MODULE);
if (result) {
- pr_err("fluke_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_interface;
}
diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c
index f950e7cdd8f8..53f4b3fccc3c 100644
--- a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c
+++ b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c
@@ -12,6 +12,10 @@
* (C) 2017 Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "fmh_gpib.h"
#include "gpibP.h"
@@ -28,19 +32,21 @@ MODULE_DESCRIPTION("GPIB Driver for fmh_gpib_core");
MODULE_AUTHOR("Frank Mori Hess <fmh6jj@gmail.com>");
static irqreturn_t fmh_gpib_interrupt(int irq, void *arg);
-static int fmh_gpib_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config);
-static int fmh_gpib_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config);
-static void fmh_gpib_detach(gpib_board_t *board);
-static int fmh_gpib_pci_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config);
-static int fmh_gpib_pci_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config);
-static void fmh_gpib_pci_detach(gpib_board_t *board);
-static int fmh_gpib_config_dma(gpib_board_t *board, int output);
-static irqreturn_t fmh_gpib_internal_interrupt(gpib_board_t *board);
+static int fmh_gpib_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config);
+static int fmh_gpib_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config);
+static void fmh_gpib_detach(struct gpib_board *board);
+static int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board,
+ const gpib_board_config_t *config);
+static int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board,
+ const gpib_board_config_t *config);
+static void fmh_gpib_pci_detach(struct gpib_board *board);
+static int fmh_gpib_config_dma(struct gpib_board *board, int output);
+static irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board);
static struct platform_driver fmh_gpib_platform_driver;
static struct pci_driver fmh_gpib_pci_driver;
// wrappers for interface functions
-static int fmh_gpib_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read)
{
struct fmh_priv *priv = board->private_data;
@@ -48,7 +54,7 @@ static int fmh_gpib_read(gpib_board_t *board, uint8_t *buffer, size_t length,
return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
}
-static int fmh_gpib_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
struct fmh_priv *priv = board->private_data;
@@ -56,7 +62,7 @@ static int fmh_gpib_write(gpib_board_t *board, uint8_t *buffer, size_t length,
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-static int fmh_gpib_command(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_command(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written)
{
struct fmh_priv *priv = board->private_data;
@@ -64,21 +70,21 @@ static int fmh_gpib_command(gpib_board_t *board, uint8_t *buffer, size_t length,
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-static int fmh_gpib_take_control(gpib_board_t *board, int synchronous)
+static int fmh_gpib_take_control(struct gpib_board *board, int synchronous)
{
struct fmh_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-static int fmh_gpib_go_to_standby(gpib_board_t *board)
+static int fmh_gpib_go_to_standby(struct gpib_board *board)
{
struct fmh_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-static void fmh_gpib_request_system_control(gpib_board_t *board, int request_control)
+static void fmh_gpib_request_system_control(struct gpib_board *board, int request_control)
{
struct fmh_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -86,77 +92,77 @@ static void fmh_gpib_request_system_control(gpib_board_t *board, int request_con
nec7210_request_system_control(board, nec_priv, request_control);
}
-static void fmh_gpib_interface_clear(gpib_board_t *board, int assert)
+static void fmh_gpib_interface_clear(struct gpib_board *board, int assert)
{
struct fmh_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-static void fmh_gpib_remote_enable(gpib_board_t *board, int enable)
+static void fmh_gpib_remote_enable(struct gpib_board *board, int enable)
{
struct fmh_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-static int fmh_gpib_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int fmh_gpib_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct fmh_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-static void fmh_gpib_disable_eos(gpib_board_t *board)
+static void fmh_gpib_disable_eos(struct gpib_board *board)
{
struct fmh_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-static unsigned int fmh_gpib_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int fmh_gpib_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct fmh_priv *priv = board->private_data;
return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
}
-static int fmh_gpib_primary_address(gpib_board_t *board, unsigned int address)
+static int fmh_gpib_primary_address(struct gpib_board *board, unsigned int address)
{
struct fmh_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-static int fmh_gpib_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int fmh_gpib_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct fmh_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-static int fmh_gpib_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int fmh_gpib_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct fmh_priv *priv = board->private_data;
return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
}
-static void fmh_gpib_parallel_poll_configure(gpib_board_t *board, uint8_t configuration)
+static void fmh_gpib_parallel_poll_configure(struct gpib_board *board, uint8_t configuration)
{
struct fmh_priv *priv = board->private_data;
nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration);
}
-static void fmh_gpib_parallel_poll_response(gpib_board_t *board, int ist)
+static void fmh_gpib_parallel_poll_response(struct gpib_board *board, int ist)
{
struct fmh_priv *priv = board->private_data;
nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
}
-static void fmh_gpib_local_parallel_poll_mode(gpib_board_t *board, int local)
+static void fmh_gpib_local_parallel_poll_mode(struct gpib_board *board, int local)
{
struct fmh_priv *priv = board->private_data;
@@ -171,7 +177,7 @@ static void fmh_gpib_local_parallel_poll_mode(gpib_board_t *board, int local)
}
}
-static void fmh_gpib_serial_poll_response2(gpib_board_t *board, uint8_t status,
+static void fmh_gpib_serial_poll_response2(struct gpib_board *board, uint8_t status,
int new_reason_for_service)
{
struct fmh_priv *priv = board->private_data;
@@ -206,14 +212,14 @@ static void fmh_gpib_serial_poll_response2(gpib_board_t *board, uint8_t status,
spin_unlock_irqrestore(&board->spinlock, flags);
}
-static uint8_t fmh_gpib_serial_poll_status(gpib_board_t *board)
+static uint8_t fmh_gpib_serial_poll_status(struct gpib_board *board)
{
struct fmh_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-static void fmh_gpib_return_to_local(gpib_board_t *board)
+static void fmh_gpib_return_to_local(struct gpib_board *board)
{
struct fmh_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -223,9 +229,9 @@ static void fmh_gpib_return_to_local(gpib_board_t *board)
write_byte(nec_priv, AUX_RTL, AUXMR);
}
-static int fmh_gpib_line_status(const gpib_board_t *board)
+static int fmh_gpib_line_status(const struct gpib_board *board)
{
- int status = ValidALL;
+ int status = VALID_ALL;
int bsr_bits;
struct fmh_priv *e_priv;
struct nec7210_priv *nec_priv;
@@ -236,26 +242,26 @@ static int fmh_gpib_line_status(const gpib_board_t *board)
bsr_bits = read_byte(nec_priv, BUS_STATUS_REG);
if ((bsr_bits & BSR_REN_BIT) == 0)
- status |= BusREN;
+ status |= BUS_REN;
if ((bsr_bits & BSR_IFC_BIT) == 0)
- status |= BusIFC;
+ status |= BUS_IFC;
if ((bsr_bits & BSR_SRQ_BIT) == 0)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if ((bsr_bits & BSR_EOI_BIT) == 0)
- status |= BusEOI;
+ status |= BUS_EOI;
if ((bsr_bits & BSR_NRFD_BIT) == 0)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if ((bsr_bits & BSR_NDAC_BIT) == 0)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if ((bsr_bits & BSR_DAV_BIT) == 0)
- status |= BusDAV;
+ status |= BUS_DAV;
if ((bsr_bits & BSR_ATN_BIT) == 0)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
-static unsigned int fmh_gpib_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int fmh_gpib_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -272,7 +278,7 @@ static unsigned int fmh_gpib_t1_delay(gpib_board_t *board, unsigned int nano_sec
return retval;
}
-static int lacs_or_read_ready(gpib_board_t *board)
+static int lacs_or_read_ready(struct gpib_board *board)
{
const struct fmh_priv *e_priv = board->private_data;
const struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -287,7 +293,7 @@ static int lacs_or_read_ready(gpib_board_t *board)
return retval;
}
-static int wait_for_read(gpib_board_t *board)
+static int wait_for_read(struct gpib_board *board)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -306,7 +312,7 @@ static int wait_for_read(gpib_board_t *board)
return retval;
}
-static int wait_for_rx_fifo_half_full_or_end(gpib_board_t *board)
+static int wait_for_rx_fifo_half_full_or_end(struct gpib_board *board)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
@@ -329,12 +335,11 @@ static int wait_for_rx_fifo_half_full_or_end(gpib_board_t *board)
/* Wait until the gpib chip is ready to accept a data out byte.
*/
-static int wait_for_data_out_ready(gpib_board_t *board)
+static int wait_for_data_out_ready(struct gpib_board *board)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
int retval = 0;
-// printk("%s: enter\n", __FUNCTION__);
if (wait_event_interruptible(board->wait,
(test_bit(TACS_NUM, &board->status) &&
@@ -348,19 +353,18 @@ static int wait_for_data_out_ready(gpib_board_t *board)
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
retval = -EINTR;
-// printk("%s: exit, retval=%i\n", __FUNCTION__, retval);
+
return retval;
}
static void fmh_gpib_dma_callback(void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
unsigned long flags;
spin_lock_irqsave(&board->spinlock, flags);
-// printk("%s: enter\n", __FUNCTION__);
nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, HR_DOIE | HR_DIIE);
wake_up_interruptible(&board->wait);
@@ -370,7 +374,6 @@ static void fmh_gpib_dma_callback(void *arg)
clear_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
clear_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
- // printk("%s: exit\n", __FUNCTION__);
spin_unlock_irqrestore(&board->spinlock, flags);
}
@@ -388,7 +391,7 @@ static int fmh_gpib_all_bytes_are_sent(struct fmh_priv *e_priv)
return 1;
}
-static int fmh_gpib_dma_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_dma_write(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written)
{
struct fmh_priv *e_priv = board->private_data;
@@ -399,14 +402,13 @@ static int fmh_gpib_dma_write(gpib_board_t *board, uint8_t *buffer, size_t lengt
struct dma_async_tx_descriptor *tx_desc;
*bytes_written = 0;
-// printk("%s: enter\n", __FUNCTION__);
if (WARN_ON_ONCE(length > e_priv->dma_buffer_size))
return -EFAULT;
dmaengine_terminate_all(e_priv->dma_channel);
memcpy(e_priv->dma_buffer, buffer, length);
address = dma_map_single(board->dev, e_priv->dma_buffer, length, DMA_TO_DEVICE);
if (dma_mapping_error(board->dev, address))
- pr_err("dma mapping error in dma write!\n");
+ dev_err(board->gpib_dev, "dma mapping error in dma write!\n");
/* program dma controller */
retval = fmh_gpib_config_dma(board, 1);
if (retval)
@@ -415,7 +417,7 @@ static int fmh_gpib_dma_write(gpib_board_t *board, uint8_t *buffer, size_t lengt
tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, address, length, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tx_desc) {
- pr_err("fmh_gpib_gpib: failed to allocate dma transmit descriptor\n");
+ dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
retval = -ENOMEM;
goto cleanup;
}
@@ -432,19 +434,17 @@ static int fmh_gpib_dma_write(gpib_board_t *board, uint8_t *buffer, size_t lengt
dma_async_issue_pending(e_priv->dma_channel);
clear_bit(WRITE_READY_BN, &nec_priv->state);
set_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
-// printk("%s: in spin lock\n", __FUNCTION__);
+
spin_unlock_irqrestore(&board->spinlock, flags);
-// printk("%s: waiting for write.\n", __FUNCTION__);
// suspend until message is sent
if (wait_event_interruptible(board->wait,
fmh_gpib_all_bytes_are_sent(e_priv) ||
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted!\n");
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
@@ -464,16 +464,12 @@ static int fmh_gpib_dma_write(gpib_board_t *board, uint8_t *buffer, size_t lengt
fifo_xfer_counter_mask);
if (WARN_ON_ONCE(*bytes_written > length))
return -EFAULT;
- /* printk("length=%i, *bytes_written=%i, residue=%i, retval=%i\n",
- * length, *bytes_written, get_dma_residue(e_priv->dma_channel), retval);
- */
cleanup:
dma_unmap_single(board->dev, address, length, DMA_TO_DEVICE);
-// printk("%s: exit, retval=%d\n", __FUNCTION__, retval);
return retval;
}
-static int fmh_gpib_accel_write(gpib_board_t *board, uint8_t *buffer,
+static int fmh_gpib_accel_write(struct gpib_board *board, uint8_t *buffer,
size_t length, int send_eoi, size_t *bytes_written)
{
struct fmh_priv *e_priv = board->private_data;
@@ -484,7 +480,7 @@ static int fmh_gpib_accel_write(gpib_board_t *board, uint8_t *buffer,
size_t dma_remainder = remainder;
if (!e_priv->dma_channel) {
- pr_err("fmh_gpib_gpib: No dma channel available, cannot do accel write.");
+ dev_err(board->gpib_dev, "No dma channel available, cannot do accel write.");
return -ENXIO;
}
@@ -498,7 +494,6 @@ static int fmh_gpib_accel_write(gpib_board_t *board, uint8_t *buffer,
if (send_eoi)
--dma_remainder;
-// printk("%s: entering while loop\n", __FUNCTION__);
while (dma_remainder > 0) {
size_t num_bytes;
@@ -524,7 +519,7 @@ static int fmh_gpib_accel_write(gpib_board_t *board, uint8_t *buffer,
//handle sending of last byte with eoi
if (send_eoi) {
size_t num_bytes;
- // printk("%s: handling last byte\n", __FUNCTION__);
+
if (WARN_ON_ONCE(remainder != 1))
return -EFAULT;
@@ -545,7 +540,6 @@ static int fmh_gpib_accel_write(gpib_board_t *board, uint8_t *buffer,
return retval;
remainder -= num_bytes;
}
-// printk("%s: bytes send=%i\n", __FUNCTION__, (int)(length - remainder));
return 0;
}
@@ -556,7 +550,7 @@ static int fmh_gpib_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie)
result = dmaengine_pause(chan);
if (result < 0) {
- pr_err("fmh_gpib_gpib: dma pause failed?\n");
+ pr_err("dma pause failed?\n");
return result;
}
dmaengine_tx_status(chan, cookie, &state);
@@ -565,12 +559,11 @@ static int fmh_gpib_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie)
return state.residue;
}
-static int wait_for_tx_fifo_half_empty(gpib_board_t *board)
+static int wait_for_tx_fifo_half_empty(struct gpib_board *board)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
int retval = 0;
-// printk("%s: enter\n", __FUNCTION__);
if (wait_event_interruptible(board->wait,
(test_bit(TACS_NUM, &board->status) &&
@@ -584,14 +577,14 @@ static int wait_for_tx_fifo_half_empty(gpib_board_t *board)
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
retval = -EINTR;
-// printk("%s: exit, retval=%i\n", __FUNCTION__, retval);
+
return retval;
}
/* supports writing a chunk of data whose length must fit into the hardware'd xfer counter,
* called in a loop by fmh_gpib_fifo_write()
*/
-static int fmh_gpib_fifo_write_countable(gpib_board_t *board, uint8_t *buffer,
+static int fmh_gpib_fifo_write_countable(struct gpib_board *board, uint8_t *buffer,
size_t length, int send_eoi, size_t *bytes_written)
{
struct fmh_priv *e_priv = board->private_data;
@@ -600,7 +593,6 @@ static int fmh_gpib_fifo_write_countable(gpib_board_t *board, uint8_t *buffer,
unsigned int remainder;
*bytes_written = 0;
-// printk("%s: enter\n", __FUNCTION__);
if (WARN_ON_ONCE(length > fifo_xfer_counter_mask))
return -EFAULT;
@@ -635,10 +627,9 @@ static int fmh_gpib_fifo_write_countable(gpib_board_t *board, uint8_t *buffer,
fmh_gpib_all_bytes_are_sent(e_priv) ||
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted!\n");
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
@@ -655,15 +646,11 @@ cleanup:
fifo_xfer_counter_mask);
if (WARN_ON_ONCE(*bytes_written > length))
return -EFAULT;
- /* printk("length=%i, *bytes_written=%i, residue=%i, retval=%i\n",
- * length, *bytes_written, get_dma_residue(e_priv->dma_channel), retval);
- */
-// printk("%s: exit, retval=%d\n", __FUNCTION__, retval);
return retval;
}
-static int fmh_gpib_fifo_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_fifo_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
struct fmh_priv *e_priv = board->private_data;
@@ -678,8 +665,6 @@ static int fmh_gpib_fifo_write(gpib_board_t *board, uint8_t *buffer, size_t leng
clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
-// printk("%s: entering while loop\n", __FUNCTION__);
-
while (remainder > 0) {
size_t num_bytes;
int last_pass;
@@ -708,11 +693,11 @@ static int fmh_gpib_fifo_write(gpib_board_t *board, uint8_t *buffer, size_t leng
if (need_resched())
schedule();
}
-// printk("%s: bytes send=%i\n", __FUNCTION__, (int)(length - remainder));
+
return retval;
}
-static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
+static int fmh_gpib_dma_read(struct gpib_board *board, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
struct fmh_priv *e_priv = board->private_data;
@@ -725,10 +710,6 @@ static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
struct dma_async_tx_descriptor *tx_desc;
dma_cookie_t dma_cookie;
- // printk("%s: enter, bus_address=0x%x, length=%i\n", __FUNCTION__,
- //(unsigned)bus_address,
-// (int)length);
-
*bytes_read = 0;
*end = 0;
if (length == 0)
@@ -737,7 +718,7 @@ static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
bus_address = dma_map_single(board->dev, e_priv->dma_buffer,
length, DMA_FROM_DEVICE);
if (dma_mapping_error(board->dev, bus_address))
- pr_err("dma mapping error in dma read!");
+ dev_err(board->gpib_dev, "dma mapping error in dma read!");
/* program dma controller */
retval = fmh_gpib_config_dma(board, 0);
@@ -749,7 +730,7 @@ static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
length, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tx_desc) {
- pr_err("fmh_gpib_gpib: failed to allocate dma transmit descriptor\n");
+ dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE);
return -EIO;
}
@@ -769,7 +750,7 @@ static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
set_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
spin_unlock_irqrestore(&board->spinlock, flags);
-// printk("waiting for data transfer.\n");
+
// wait for data to transfer
wait_retval = wait_event_interruptible(board->wait,
test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state)
@@ -777,10 +758,9 @@ static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
test_bit(RECEIVED_END_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status));
- if (wait_retval) {
- pr_warn("fmh_gpib: dma read wait interrupted\n");
+ if (wait_retval)
retval = -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
@@ -825,13 +805,11 @@ static int fmh_gpib_dma_read(gpib_board_t *board, uint8_t *buffer,
*end = 1;
}
spin_unlock_irqrestore(&board->spinlock, flags);
-// printk("\tbytes_read=%i, residue=%i, end=%i, retval=%i, wait_retval=%i\n",
-// *bytes_read, residue, *end, retval, wait_retval);
return retval;
}
-static void fmh_gpib_release_rfd_holdoff(gpib_board_t *board, struct fmh_priv *e_priv)
+static void fmh_gpib_release_rfd_holdoff(struct gpib_board *board, struct fmh_priv *e_priv)
{
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
unsigned int ext_status_1;
@@ -868,7 +846,7 @@ static void fmh_gpib_release_rfd_holdoff(gpib_board_t *board, struct fmh_priv *e
spin_unlock_irqrestore(&board->spinlock, flags);
}
-static int fmh_gpib_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read)
{
struct fmh_priv *e_priv = board->private_data;
@@ -918,17 +896,13 @@ static int fmh_gpib_accel_read(gpib_board_t *board, uint8_t *buffer, size_t leng
/* Read a chunk of data whose length is within the limits of the hardware's
* xfer counter. Called in a loop from fmh_gpib_fifo_read().
*/
-static int fmh_gpib_fifo_read_countable(gpib_board_t *board, uint8_t *buffer,
+static int fmh_gpib_fifo_read_countable(struct gpib_board *board, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
int retval = 0;
- // printk("%s: enter, bus_address=0x%x, length=%i\n", __FUNCTION__,
- // (unsigned)bus_address,
-// (int)length);
-
*bytes_read = 0;
*end = 0;
if (length == 0)
@@ -977,13 +951,10 @@ cleanup:
*end = 1;
}
-// printk("\tbytes_read=%i, end=%i, retval=%i, wait_retval=%i\n",
-// *bytes_read, *end, retval, wait_retval);
-
return retval;
}
-static int fmh_gpib_fifo_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int fmh_gpib_fifo_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read)
{
struct fmh_priv *e_priv = board->private_data;
@@ -1152,7 +1123,7 @@ static gpib_interface_t fmh_gpib_pci_unaccel_interface = {
.return_to_local = fmh_gpib_return_to_local,
};
-irqreturn_t fmh_gpib_internal_interrupt(gpib_board_t *board)
+irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board)
{
unsigned int status0, status1, status2, ext_status_1, fifo_status;
struct fmh_priv *priv = board->private_data;
@@ -1242,7 +1213,7 @@ irqreturn_t fmh_gpib_internal_interrupt(gpib_board_t *board)
irqreturn_t fmh_gpib_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
unsigned long flags;
irqreturn_t retval;
@@ -1252,7 +1223,7 @@ irqreturn_t fmh_gpib_interrupt(int irq, void *arg)
return retval;
}
-static int fmh_gpib_allocate_private(gpib_board_t *board)
+static int fmh_gpib_allocate_private(struct gpib_board *board)
{
struct fmh_priv *priv;
@@ -1269,7 +1240,7 @@ static int fmh_gpib_allocate_private(gpib_board_t *board)
return 0;
}
-static void fmh_gpib_generic_detach(gpib_board_t *board)
+static void fmh_gpib_generic_detach(struct gpib_board *board)
{
if (board->private_data) {
struct fmh_priv *e_priv = board->private_data;
@@ -1283,7 +1254,7 @@ static void fmh_gpib_generic_detach(gpib_board_t *board)
}
// generic part of attach functions
-static int fmh_gpib_generic_attach(gpib_board_t *board)
+static int fmh_gpib_generic_attach(struct gpib_board *board)
{
struct fmh_priv *e_priv;
struct nec7210_priv *nec_priv;
@@ -1303,7 +1274,7 @@ static int fmh_gpib_generic_attach(gpib_board_t *board)
return 0;
}
-static int fmh_gpib_config_dma(gpib_board_t *board, int output)
+static int fmh_gpib_config_dma(struct gpib_board *board, int output)
{
struct fmh_priv *e_priv = board->private_data;
struct dma_slave_config config;
@@ -1333,7 +1304,7 @@ static int fmh_gpib_config_dma(gpib_board_t *board, int output)
return dmaengine_slave_config(e_priv->dma_channel, &config);
}
-static int fmh_gpib_init(struct fmh_priv *e_priv, gpib_board_t *board, int handshake_mode)
+static int fmh_gpib_init(struct fmh_priv *e_priv, struct gpib_board *board, int handshake_mode)
{
struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
unsigned long flags;
@@ -1376,11 +1347,11 @@ static int fmh_gpib_device_match(struct device *dev, const void *data)
if (config->serial_number)
return 0;
- dev_notice(dev, "matched: %s\n", of_node_full_name(dev_of_node((dev))));
+ dev_dbg(dev, "matched: %s\n", of_node_full_name(dev_of_node((dev))));
return 1;
}
-static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *config,
+static int fmh_gpib_attach_impl(struct gpib_board *board, const gpib_board_config_t *config,
unsigned int handshake_mode, int acquire_dma)
{
struct fmh_priv *e_priv;
@@ -1393,7 +1364,7 @@ static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *
board->dev = driver_find_device(&fmh_gpib_platform_driver.driver,
NULL, (const void *)config, &fmh_gpib_device_match);
if (!board->dev) {
- pr_err("No matching fmh_gpib_core device was found, attach failed.");
+ dev_err(board->gpib_dev, "No matching fmh_gpib_core device was found, attach failed.");
return -ENODEV;
}
// currently only used to mark the device as already attached
@@ -1409,7 +1380,7 @@ static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpib_control_status");
if (!res) {
- dev_err(board->dev, "Unable to locate mmio resource for cb7210 gpib\n");
+ dev_err(board->dev, "Unable to locate mmio resource\n");
return -ENODEV;
}
@@ -1422,13 +1393,13 @@ static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *
e_priv->gpib_iomem_res = res;
nec_priv->mmiobase = ioremap(e_priv->gpib_iomem_res->start,
- resource_size(e_priv->gpib_iomem_res));
+ resource_size(e_priv->gpib_iomem_res));
if (!nec_priv->mmiobase) {
- dev_err(board->dev, "Could not map I/O memory for gpib\n");
+ dev_err(board->dev, "Could not map I/O memory\n");
return -ENOMEM;
}
- dev_info(board->dev, "iobase %pr remapped to %p\n",
- e_priv->gpib_iomem_res, nec_priv->mmiobase);
+ dev_dbg(board->dev, "iobase %pr remapped to %p\n",
+ e_priv->gpib_iomem_res, nec_priv->mmiobase);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma_fifos");
if (!res) {
@@ -1448,14 +1419,13 @@ static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *
dev_err(board->dev, "Could not map I/O memory for fifos\n");
return -ENOMEM;
}
- dev_info(board->dev, "dma fifos 0x%lx remapped to %p, length=%ld\n",
- (unsigned long)e_priv->dma_port_res->start, e_priv->fifo_base,
- (unsigned long)resource_size(e_priv->dma_port_res));
+ dev_dbg(board->dev, "dma fifos 0x%lx remapped to %p, length=%ld\n",
+ (unsigned long)e_priv->dma_port_res->start, e_priv->fifo_base,
+ (unsigned long)resource_size(e_priv->dma_port_res));
irq = platform_get_irq(pdev, 0);
- pr_info("gpib: irq %d\n", irq);
if (irq < 0) {
- dev_err(board->dev, "fmh_gpib_gpib: request for IRQ failed\n");
+ dev_err(board->dev, "request for IRQ failed\n");
return -EBUSY;
}
retval = request_irq(irq, fmh_gpib_interrupt, IRQF_SHARED, pdev->name, board);
@@ -1484,17 +1454,17 @@ static int fmh_gpib_attach_impl(gpib_board_t *board, const gpib_board_config_t *
return fmh_gpib_init(e_priv, board, handshake_mode);
}
-int fmh_gpib_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config)
+int fmh_gpib_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config)
{
return fmh_gpib_attach_impl(board, config, HR_HLDA, 0);
}
-int fmh_gpib_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config)
+int fmh_gpib_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config)
{
return fmh_gpib_attach_impl(board, config, HR_HLDE, 1);
}
-void fmh_gpib_detach(gpib_board_t *board)
+void fmh_gpib_detach(struct gpib_board *board)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1527,7 +1497,7 @@ void fmh_gpib_detach(gpib_board_t *board)
fmh_gpib_generic_detach(board);
}
-static int fmh_gpib_pci_attach_impl(gpib_board_t *board, const gpib_board_config_t *config,
+static int fmh_gpib_pci_attach_impl(struct gpib_board *board, const gpib_board_config_t *config,
unsigned int handshake_mode)
{
struct fmh_priv *e_priv;
@@ -1546,7 +1516,7 @@ static int fmh_gpib_pci_attach_impl(gpib_board_t *board, const gpib_board_config
pci_device = gpib_pci_get_device(config, BOGUS_PCI_VENDOR_ID_FLUKE,
BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER, NULL);
if (!pci_device) {
- pr_err("No matching fmh_gpib_core pci device was found, attach failed.");
+ dev_err(board->gpib_dev, "No matching fmh_gpib_core pci device was found, attach failed.");
return -ENODEV;
}
board->dev = &pci_device->dev;
@@ -1563,34 +1533,32 @@ static int fmh_gpib_pci_attach_impl(gpib_board_t *board, const gpib_board_config
return -EIO;
}
e_priv->gpib_iomem_res = &pci_device->resource[gpib_control_status_pci_resource_index];
- e_priv->dma_port_res = &pci_device->resource[gpib_fifo_pci_resource_index];
+ e_priv->dma_port_res = &pci_device->resource[gpib_fifo_pci_resource_index];
nec_priv->mmiobase = ioremap(pci_resource_start(pci_device,
- gpib_control_status_pci_resource_index),
- pci_resource_len(pci_device,
- gpib_control_status_pci_resource_index));
- dev_info(board->dev, "base address for gpib control/status registers remapped to 0x%p\n",
- nec_priv->mmiobase);
+ gpib_control_status_pci_resource_index),
+ pci_resource_len(pci_device,
+ gpib_control_status_pci_resource_index));
+ dev_dbg(board->dev, "base address for gpib control/status registers remapped to 0x%p\n",
+ nec_priv->mmiobase);
if (e_priv->dma_port_res->flags & IORESOURCE_MEM) {
e_priv->fifo_base = ioremap(pci_resource_start(pci_device,
gpib_fifo_pci_resource_index),
pci_resource_len(pci_device,
gpib_fifo_pci_resource_index));
- dev_info(board->dev, "base address for gpib fifo registers remapped to 0x%p\n",
- e_priv->fifo_base);
+ dev_dbg(board->dev, "base address for gpib fifo registers remapped to 0x%p\n",
+ e_priv->fifo_base);
} else {
e_priv->fifo_base = NULL;
- dev_info(board->dev, "hardware has no gpib fifo registers.\n");
+ dev_dbg(board->dev, "hardware has no gpib fifo registers.\n");
}
if (pci_device->irq) {
retval = request_irq(pci_device->irq, fmh_gpib_interrupt, IRQF_SHARED,
KBUILD_MODNAME, board);
if (retval) {
- dev_err(board->dev,
- "cannot register interrupt handler err=%d\n",
- retval);
+ dev_err(board->dev, "cannot register interrupt handler err=%d\n", retval);
return retval;
}
}
@@ -1602,12 +1570,12 @@ static int fmh_gpib_pci_attach_impl(gpib_board_t *board, const gpib_board_config
return fmh_gpib_init(e_priv, board, handshake_mode);
}
-int fmh_gpib_pci_attach_holdoff_all(gpib_board_t *board, const gpib_board_config_t *config)
+int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board, const gpib_board_config_t *config)
{
return fmh_gpib_pci_attach_impl(board, config, HR_HLDA);
}
-int fmh_gpib_pci_attach_holdoff_end(gpib_board_t *board, const gpib_board_config_t *config)
+int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board, const gpib_board_config_t *config)
{
int retval;
struct fmh_priv *e_priv;
@@ -1615,13 +1583,13 @@ int fmh_gpib_pci_attach_holdoff_end(gpib_board_t *board, const gpib_board_config
retval = fmh_gpib_pci_attach_impl(board, config, HR_HLDE);
e_priv = board->private_data;
if (retval == 0 && e_priv && e_priv->supports_fifo_interrupts == 0) {
- pr_err("fmh_gpib: your fmh_gpib_core does not appear to support fifo interrupts. Try the fmh_gpib_pci_unaccel board type instead.");
+ dev_err(board->gpib_dev, "your fmh_gpib_core does not appear to support fifo interrupts. Try the fmh_gpib_pci_unaccel board type instead.");
return -EIO;
}
return retval;
}
-void fmh_gpib_pci_detach(gpib_board_t *board)
+void fmh_gpib_pci_detach(struct gpib_board *board)
{
struct fmh_priv *e_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1662,7 +1630,7 @@ MODULE_DEVICE_TABLE(of, fmh_gpib_of_match);
static struct platform_driver fmh_gpib_platform_driver = {
.driver = {
- .name = "fmh_gpib",
+ .name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = fmh_gpib_of_match,
},
@@ -1681,7 +1649,7 @@ static const struct pci_device_id fmh_gpib_pci_match[] = {
MODULE_DEVICE_TABLE(pci, fmh_gpib_pci_match);
static struct pci_driver fmh_gpib_pci_driver = {
- .name = "fmh_gpib",
+ .name = DRV_NAME,
.id_table = fmh_gpib_pci_match,
.probe = &fmh_gpib_pci_probe
};
@@ -1692,37 +1660,37 @@ static int __init fmh_gpib_init_module(void)
result = platform_driver_register(&fmh_gpib_platform_driver);
if (result) {
- pr_err("fmh_gpib: platform_driver_register failed: error = %d\n", result);
+ pr_err("platform_driver_register failed: error = %d\n", result);
return result;
}
result = pci_register_driver(&fmh_gpib_pci_driver);
if (result) {
- pr_err("fmh_gpib: pci_register_driver failed: error = %d\n", result);
+ pr_err("pci_register_driver failed: error = %d\n", result);
goto err_pci_driver;
}
result = gpib_register_driver(&fmh_gpib_unaccel_interface, THIS_MODULE);
if (result) {
- pr_err("fmh_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_unaccel;
}
result = gpib_register_driver(&fmh_gpib_interface, THIS_MODULE);
if (result) {
- pr_err("fmh_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_interface;
}
result = gpib_register_driver(&fmh_gpib_pci_unaccel_interface, THIS_MODULE);
if (result) {
- pr_err("fmh_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_pci_unaccel;
}
result = gpib_register_driver(&fmh_gpib_pci_interface, THIS_MODULE);
if (result) {
- pr_err("fmh_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_pci;
}
diff --git a/drivers/staging/gpib/gpio/gpib_bitbang.c b/drivers/staging/gpib/gpio/gpib_bitbang.c
index 828c99ea613f..86bdd381472a 100644
--- a/drivers/staging/gpib/gpio/gpib_bitbang.c
+++ b/drivers/staging/gpib/gpio/gpib_bitbang.c
@@ -25,6 +25,8 @@
* device support (non master operation)
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
#define NAME KBUILD_MODNAME
#define ENABLE_IRQ(IRQ, TYPE) irq_set_irq_type(IRQ, TYPE)
@@ -41,7 +43,7 @@
*/
#define dbg_printk(level, frm, ...) \
do { if (debug >= (level)) \
- pr_info("%s:%s - " frm, NAME, __func__, ## __VA_ARGS__); } \
+ dev_dbg(board->gpib_dev, frm, ## __VA_ARGS__); } \
while (0)
#define LINVAL gpiod_get_value(DAV), \
@@ -316,13 +318,14 @@ struct bb_priv {
};
static inline long usec_diff(struct timespec64 *a, struct timespec64 *b);
-static void bb_buffer_print(unsigned char *buffer, size_t length, int cmd, int eoi);
+static void bb_buffer_print(struct gpib_board *board, unsigned char *buffer, size_t length,
+ int cmd, int eoi);
static void set_data_lines(u8 byte);
static u8 get_data_lines(void);
static void set_data_lines_input(void);
static void set_data_lines_output(void);
static inline int check_for_eos(struct bb_priv *priv, uint8_t byte);
-static void set_atn(struct bb_priv *priv, int atn_asserted);
+static void set_atn(struct gpib_board *board, int atn_asserted);
static inline void SET_DIR_WRITE(struct bb_priv *priv);
static inline void SET_DIR_READ(struct bb_priv *priv);
@@ -334,11 +337,7 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB helper functions for bitbanging I/O");
/**** global variables ****/
-#ifdef CONFIG_GPIB_DEBUG
-static int debug = 1;
-#else
static int debug;
-#endif
module_param(debug, int, 0644);
static char printable(char x)
@@ -354,7 +353,7 @@ static char printable(char x)
* *
***************************************************************************/
-static int bb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int bb_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read)
{
struct bb_priv *priv = board->private_data;
@@ -426,7 +425,7 @@ read_end:
static irqreturn_t bb_DAV_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct bb_priv *priv = board->private_data;
int val;
unsigned long flags;
@@ -492,7 +491,7 @@ dav_exit:
* *
***************************************************************************/
-static int bb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int bb_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
unsigned long flags;
@@ -508,7 +507,7 @@ static int bb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
board, mutex_is_locked(&board->user_mutex), length);
if (debug > 1)
- bb_buffer_print(buffer, length, priv->cmd, send_eoi);
+ bb_buffer_print(board, buffer, length, priv->cmd, send_eoi);
priv->count = 0;
priv->phase = 300;
@@ -550,7 +549,6 @@ static int bb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
dbg_printk(1, "timeout after %zu/%zu at %d " LINFMT " eoi: %d\n",
priv->w_cnt, length, priv->phase, LINVAL, send_eoi);
} else {
- // dbg_printk(1,"written %zu\n", priv->w_cnt);
retval = priv->w_cnt;
}
} else {
@@ -582,7 +580,7 @@ write_end:
static irqreturn_t bb_NRFD_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct bb_priv *priv = board->private_data;
unsigned long flags;
int nrfd;
@@ -655,7 +653,7 @@ nrfd_exit:
static irqreturn_t bb_NDAC_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct bb_priv *priv = board->private_data;
unsigned long flags;
int ndac;
@@ -716,7 +714,7 @@ ndac_exit:
static irqreturn_t bb_SRQ_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
int val = gpiod_get_value(SRQ);
@@ -730,7 +728,7 @@ static irqreturn_t bb_SRQ_interrupt(int irq, void *arg)
return IRQ_HANDLED;
}
-static int bb_command(gpib_board_t *board, uint8_t *buffer,
+static int bb_command(struct gpib_board *board, uint8_t *buffer,
size_t length, size_t *bytes_written)
{
size_t ret;
@@ -811,7 +809,8 @@ static char *cmd_string[32] = {
"CFE" // 0x1f
};
-static void bb_buffer_print(unsigned char *buffer, size_t length, int cmd, int eoi)
+static void bb_buffer_print(struct gpib_board *board, unsigned char *buffer, size_t length,
+ int cmd, int eoi)
{
int i;
@@ -843,11 +842,13 @@ static void bb_buffer_print(unsigned char *buffer, size_t length, int cmd, int e
* STATUS Management *
* *
***************************************************************************/
-static void set_atn(struct bb_priv *priv, int atn_asserted)
+static void set_atn(struct gpib_board *board, int atn_asserted)
{
+ struct bb_priv *priv = board->private_data;
+
if (priv->listener_state != listener_idle &&
priv->talker_state != talker_idle) {
- dbg_printk(0, "listener/talker state machine conflict\n");
+ dev_err(board->gpib_dev, "listener/talker state machine conflict\n");
}
if (atn_asserted) {
if (priv->listener_state == listener_active)
@@ -866,22 +867,22 @@ static void set_atn(struct bb_priv *priv, int atn_asserted)
priv->atn_asserted = atn_asserted;
}
-static int bb_take_control(gpib_board_t *board, int synchronous)
+static int bb_take_control(struct gpib_board *board, int synchronous)
{
dbg_printk(2, "%d\n", synchronous);
- set_atn(board->private_data, 1);
+ set_atn(board, 1);
set_bit(CIC_NUM, &board->status);
return 0;
}
-static int bb_go_to_standby(gpib_board_t *board)
+static int bb_go_to_standby(struct gpib_board *board)
{
dbg_printk(2, "\n");
- set_atn(board->private_data, 0);
+ set_atn(board, 0);
return 0;
}
-static void bb_request_system_control(gpib_board_t *board, int request_control)
+static void bb_request_system_control(struct gpib_board *board, int request_control)
{
dbg_printk(2, "%d\n", request_control);
if (request_control) {
@@ -893,7 +894,7 @@ static void bb_request_system_control(gpib_board_t *board, int request_control)
}
}
-static void bb_interface_clear(gpib_board_t *board, int assert)
+static void bb_interface_clear(struct gpib_board *board, int assert)
{
struct bb_priv *priv = board->private_data;
@@ -907,7 +908,7 @@ static void bb_interface_clear(gpib_board_t *board, int assert)
}
}
-static void bb_remote_enable(gpib_board_t *board, int enable)
+static void bb_remote_enable(struct gpib_board *board, int enable)
{
dbg_printk(2, "%d\n", enable);
if (enable) {
@@ -919,7 +920,7 @@ static void bb_remote_enable(gpib_board_t *board, int enable)
}
}
-static int bb_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int bb_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct bb_priv *priv = board->private_data;
@@ -932,7 +933,7 @@ static int bb_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bi
return 0;
}
-static void bb_disable_eos(gpib_board_t *board)
+static void bb_disable_eos(struct gpib_board *board)
{
struct bb_priv *priv = board->private_data;
@@ -940,7 +941,7 @@ static void bb_disable_eos(gpib_board_t *board)
priv->eos_flags &= ~REOS;
}
-static unsigned int bb_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int bb_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct bb_priv *priv = board->private_data;
@@ -971,14 +972,14 @@ static unsigned int bb_update_status(gpib_board_t *board, unsigned int clear_mas
return board->status;
}
-static int bb_primary_address(gpib_board_t *board, unsigned int address)
+static int bb_primary_address(struct gpib_board *board, unsigned int address)
{
dbg_printk(2, "%d\n", address);
board->pad = address;
return 0;
}
-static int bb_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int bb_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
dbg_printk(2, "%d %d\n", address, enable);
if (enable)
@@ -986,33 +987,29 @@ static int bb_secondary_address(gpib_board_t *board, unsigned int address, int e
return 0;
}
-static int bb_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int bb_parallel_poll(struct gpib_board *board, uint8_t *result)
{
- dbg_printk(1, "%s\n", "not implemented");
- return -EPERM;
+ return -ENOENT;
}
-static void bb_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void bb_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
- dbg_printk(1, "%s\n", "not implemented");
}
-static void bb_parallel_poll_response(gpib_board_t *board, int ist)
+static void bb_parallel_poll_response(struct gpib_board *board, int ist)
{
}
-static void bb_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void bb_serial_poll_response(struct gpib_board *board, uint8_t status)
{
- dbg_printk(1, "%s\n", "not implemented");
}
-static uint8_t bb_serial_poll_status(gpib_board_t *board)
+static uint8_t bb_serial_poll_status(struct gpib_board *board)
{
- dbg_printk(1, "%s\n", "not implemented");
- return 0; // -ENOSYS;
+ return 0; // -ENOENT;
}
-static unsigned int bb_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int bb_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct bb_priv *priv = board->private_data;
@@ -1028,33 +1025,30 @@ static unsigned int bb_t1_delay(gpib_board_t *board, unsigned int nano_sec)
return priv->t1_delay;
}
-static void bb_return_to_local(gpib_board_t *board)
+static void bb_return_to_local(struct gpib_board *board)
{
- dbg_printk(1, "%s\n", "not implemented");
}
-static int bb_line_status(const gpib_board_t *board)
+static int bb_line_status(const struct gpib_board *board)
{
- int line_status = ValidALL;
-
-// dbg_printk(1,"\n");
+ int line_status = VALID_ALL;
if (gpiod_get_value(REN) == 0)
- line_status |= BusREN;
+ line_status |= BUS_REN;
if (gpiod_get_value(IFC) == 0)
- line_status |= BusIFC;
+ line_status |= BUS_IFC;
if (gpiod_get_value(NDAC) == 0)
- line_status |= BusNDAC;
+ line_status |= BUS_NDAC;
if (gpiod_get_value(NRFD) == 0)
- line_status |= BusNRFD;
+ line_status |= BUS_NRFD;
if (gpiod_get_value(DAV) == 0)
- line_status |= BusDAV;
+ line_status |= BUS_DAV;
if (gpiod_get_value(EOI) == 0)
- line_status |= BusEOI;
+ line_status |= BUS_EOI;
if (gpiod_get_value(_ATN) == 0)
- line_status |= BusATN;
+ line_status |= BUS_ATN;
if (gpiod_get_value(SRQ) == 0)
- line_status |= BusSRQ;
+ line_status |= BUS_SRQ;
dbg_printk(2, "status lines: %4x\n", line_status);
@@ -1067,7 +1061,7 @@ static int bb_line_status(const gpib_board_t *board)
* *
***************************************************************************/
-static int allocate_private(gpib_board_t *board)
+static int allocate_private(struct gpib_board *board)
{
board->private_data = kzalloc(sizeof(struct bb_priv), GFP_KERNEL);
if (!board->private_data)
@@ -1075,13 +1069,13 @@ static int allocate_private(gpib_board_t *board)
return 0;
}
-static void free_private(gpib_board_t *board)
+static void free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
-static int bb_get_irq(gpib_board_t *board, char *name,
+static int bb_get_irq(struct gpib_board *board, char *name,
struct gpio_desc *gpio, int *irq,
irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags)
{
@@ -1091,11 +1085,11 @@ static int bb_get_irq(gpib_board_t *board, char *name,
*irq = gpiod_to_irq(gpio);
dbg_printk(2, "IRQ %s: %d\n", name, *irq);
if (*irq < 0) {
- dbg_printk(0, "gpib: can't get IRQ for %s\n", name);
+ dev_err(board->gpib_dev, "can't get IRQ for %s\n", name);
return -1;
}
if (request_threaded_irq(*irq, handler, thread_fn, flags, name, board)) {
- dbg_printk(0, "gpib: can't request IRQ for %s %d\n", name, *irq);
+ dev_err(board->gpib_dev, "can't request IRQ for %s %d\n", name, *irq);
*irq = 0;
return -1;
}
@@ -1103,7 +1097,7 @@ static int bb_get_irq(gpib_board_t *board, char *name,
return 0;
}
-static void bb_free_irq(gpib_board_t *board, int *irq, char *name)
+static void bb_free_irq(struct gpib_board *board, int *irq, char *name)
{
if (*irq) {
free_irq(*irq, board);
@@ -1124,7 +1118,7 @@ static void release_gpios(void)
}
}
-static int allocate_gpios(gpib_board_t *board)
+static int allocate_gpios(struct gpib_board *board)
{
int j, retval = 0;
bool error = false;
@@ -1163,8 +1157,8 @@ try_again:
gpiod_add_lookup_table(lookup_table);
goto try_again;
}
- dbg_printk(0, "Unable to obtain gpio descriptor for pin %d error %ld\n",
- gpios_vector[j], PTR_ERR(desc));
+ dev_err(board->gpib_dev, "Unable to obtain gpio descriptor for pin %d error %ld\n",
+ gpios_vector[j], PTR_ERR(desc));
error = true;
break;
}
@@ -1182,7 +1176,7 @@ try_again:
return retval;
}
-static void bb_detach(gpib_board_t *board)
+static void bb_detach(struct gpib_board *board)
{
struct bb_priv *priv = board->private_data;
@@ -1212,7 +1206,7 @@ static void bb_detach(gpib_board_t *board)
free_private(board);
}
-static int bb_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int bb_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct bb_priv *priv;
int retval = 0;
@@ -1253,7 +1247,7 @@ static int bb_attach(gpib_board_t *board, const gpib_board_config_t *config)
gpios_vector[&(DC) - &all_descriptors[0]] = -1;
gpios_vector[&(ACT_LED) - &all_descriptors[0]] = -1;
} else {
- dbg_printk(0, "Unrecognized pin mapping.\n");
+ dev_err(board->gpib_dev, "Unrecognized pin map %s\n", pin_map);
goto bb_attach_fail;
}
dbg_printk(0, "Using pin map \"%s\" %s\n", pin_map, (sn7516x) ?
@@ -1344,19 +1338,15 @@ static int __init bb_init_module(void)
int result = gpib_register_driver(&bb_interface, THIS_MODULE);
if (result) {
- pr_err("gpib_bitbang: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
return result;
}
- dbg_printk(0, "module loaded with pin map \"%s\"%s\n",
- pin_map, (sn7516x_used) ? " and SN7516x driver support" : "");
return 0;
}
static void __exit bb_exit_module(void)
{
- dbg_printk(0, "module unloaded!");
-
gpib_unregister_driver(&bb_interface);
}
diff --git a/drivers/staging/gpib/hp_82335/hp82335.c b/drivers/staging/gpib/hp_82335/hp82335.c
index 700d1ba029d2..fd23b1cb80f9 100644
--- a/drivers/staging/gpib/hp_82335/hp82335.c
+++ b/drivers/staging/gpib/hp_82335/hp82335.c
@@ -8,6 +8,10 @@
* implement recovery from bus errors (if necessary)
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "hp82335.h"
#include <linux/io.h>
#include <linux/ioport.h>
@@ -20,153 +24,155 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver for HP 82335 interface cards");
-static int hp82335_attach(gpib_board_t *board, const gpib_board_config_t *config);
-
-static void hp82335_detach(gpib_board_t *board);
+static int hp82335_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static void hp82335_detach(struct gpib_board *board);
+static irqreturn_t hp82335_interrupt(int irq, void *arg);
// wrappers for interface functions
-int hp82335_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
+static int hp82335_read(struct gpib_board *board, uint8_t *buffer, size_t length,
+ int *end, size_t *bytes_read)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
}
-int hp82335_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int hp82335_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
}
-int hp82335_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int hp82335_command(struct gpib_board *board, uint8_t *buffer, size_t length,
+ size_t *bytes_written)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
}
-int hp82335_take_control(gpib_board_t *board, int synchronous)
+static int hp82335_take_control(struct gpib_board *board, int synchronous)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_take_control(board, &priv->tms9914_priv, synchronous);
}
-int hp82335_go_to_standby(gpib_board_t *board)
+static int hp82335_go_to_standby(struct gpib_board *board)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_go_to_standby(board, &priv->tms9914_priv);
}
-void hp82335_request_system_control(gpib_board_t *board, int request_control)
+static void hp82335_request_system_control(struct gpib_board *board, int request_control)
{
struct hp82335_priv *priv = board->private_data;
tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
}
-void hp82335_interface_clear(gpib_board_t *board, int assert)
+static void hp82335_interface_clear(struct gpib_board *board, int assert)
{
struct hp82335_priv *priv = board->private_data;
tms9914_interface_clear(board, &priv->tms9914_priv, assert);
}
-void hp82335_remote_enable(gpib_board_t *board, int enable)
+static void hp82335_remote_enable(struct gpib_board *board, int enable)
{
struct hp82335_priv *priv = board->private_data;
tms9914_remote_enable(board, &priv->tms9914_priv, enable);
}
-int hp82335_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int hp82335_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
}
-void hp82335_disable_eos(gpib_board_t *board)
+static void hp82335_disable_eos(struct gpib_board *board)
{
struct hp82335_priv *priv = board->private_data;
tms9914_disable_eos(board, &priv->tms9914_priv);
}
-unsigned int hp82335_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int hp82335_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
}
-int hp82335_primary_address(gpib_board_t *board, unsigned int address)
+static int hp82335_primary_address(struct gpib_board *board, unsigned int address)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_primary_address(board, &priv->tms9914_priv, address);
}
-int hp82335_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int hp82335_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
}
-int hp82335_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int hp82335_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
}
-void hp82335_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void hp82335_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
struct hp82335_priv *priv = board->private_data;
tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
}
-void hp82335_parallel_poll_response(gpib_board_t *board, int ist)
+static void hp82335_parallel_poll_response(struct gpib_board *board, int ist)
{
struct hp82335_priv *priv = board->private_data;
tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
}
-void hp82335_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void hp82335_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct hp82335_priv *priv = board->private_data;
tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
}
-static uint8_t hp82335_serial_poll_status(gpib_board_t *board)
+static uint8_t hp82335_serial_poll_status(struct gpib_board *board)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_serial_poll_status(board, &priv->tms9914_priv);
}
-static int hp82335_line_status(const gpib_board_t *board)
+static int hp82335_line_status(const struct gpib_board *board)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_line_status(board, &priv->tms9914_priv);
}
-static unsigned int hp82335_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int hp82335_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct hp82335_priv *priv = board->private_data;
return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec);
}
-void hp82335_return_to_local(gpib_board_t *board)
+static void hp82335_return_to_local(struct gpib_board *board)
{
struct hp82335_priv *priv = board->private_data;
@@ -201,7 +207,7 @@ static gpib_interface_t hp82335_interface = {
.return_to_local = hp82335_return_to_local,
};
-int hp82335_allocate_private(gpib_board_t *board)
+static int hp82335_allocate_private(struct gpib_board *board)
{
board->private_data = kzalloc(sizeof(struct hp82335_priv), GFP_KERNEL);
if (!board->private_data)
@@ -209,7 +215,7 @@ int hp82335_allocate_private(gpib_board_t *board)
return 0;
}
-void hp82335_free_private(gpib_board_t *board)
+static void hp82335_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
@@ -237,7 +243,7 @@ static void hp82335_clear_interrupt(struct hp82335_priv *hp_priv)
writeb(0, tms_priv->mmiobase + HPREG_INTR_CLEAR);
}
-int hp82335_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int hp82335_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct hp82335_priv *hp_priv;
struct tms9914_priv *tms_priv;
@@ -272,26 +278,23 @@ int hp82335_attach(gpib_board_t *board, const gpib_board_config_t *config)
case 0xfc000:
break;
default:
- pr_err("hp82335: invalid base io address 0x%u\n", config->ibbase);
+ dev_err(board->gpib_dev, "invalid base io address 0x%x\n", config->ibbase);
return -EINVAL;
}
if (!request_mem_region(upper_iomem_base, hp82335_upper_iomem_size, "hp82335")) {
- pr_err("hp82335: failed to allocate io memory region 0x%lx-0x%lx\n",
- upper_iomem_base, upper_iomem_base + hp82335_upper_iomem_size - 1);
+ dev_err(board->gpib_dev, "failed to allocate io memory region 0x%lx-0x%lx\n",
+ upper_iomem_base, upper_iomem_base + hp82335_upper_iomem_size - 1);
return -EBUSY;
}
hp_priv->raw_iobase = upper_iomem_base;
tms_priv->mmiobase = ioremap(upper_iomem_base, hp82335_upper_iomem_size);
- pr_info("hp82335: upper half of 82335 iomem region 0x%lx remapped to 0x%p\n",
- hp_priv->raw_iobase, tms_priv->mmiobase);
- retval = request_irq(config->ibirq, hp82335_interrupt, 0, "hp82335", board);
+ retval = request_irq(config->ibirq, hp82335_interrupt, 0, DRV_NAME, board);
if (retval) {
- pr_err("hp82335: can't request IRQ %d\n", config->ibirq);
+ dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
return retval;
}
hp_priv->irq = config->ibirq;
- pr_info("hp82335: IRQ %d\n", config->ibirq);
tms9914_board_reset(tms_priv);
@@ -304,7 +307,7 @@ int hp82335_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-void hp82335_detach(gpib_board_t *board)
+static void hp82335_detach(struct gpib_board *board)
{
struct hp82335_priv *hp_priv = board->private_data;
struct tms9914_priv *tms_priv;
@@ -329,7 +332,7 @@ static int __init hp82335_init_module(void)
int result = gpib_register_driver(&hp82335_interface, THIS_MODULE);
if (result) {
- pr_err("hp82335: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
return result;
}
@@ -348,10 +351,10 @@ module_exit(hp82335_exit_module);
* GPIB interrupt service routines
*/
-irqreturn_t hp82335_interrupt(int irq, void *arg)
+static irqreturn_t hp82335_interrupt(int irq, void *arg)
{
int status1, status2;
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct hp82335_priv *priv = board->private_data;
unsigned long flags;
irqreturn_t retval;
diff --git a/drivers/staging/gpib/hp_82335/hp82335.h b/drivers/staging/gpib/hp_82335/hp82335.h
index 4b185d7c5188..0c252a712ec9 100644
--- a/drivers/staging/gpib/hp_82335/hp82335.h
+++ b/drivers/staging/gpib/hp_82335/hp82335.h
@@ -17,36 +17,6 @@ struct hp82335_priv {
unsigned long raw_iobase;
};
-// interface functions
-int hp82335_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read);
-int hp82335_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written);
-int hp82335_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written);
-int hp82335_take_control(gpib_board_t *board, int synchronous);
-int hp82335_go_to_standby(gpib_board_t *board);
-void hp82335_request_system_control(gpib_board_t *board, int request_control);
-void hp82335_interface_clear(gpib_board_t *board, int assert);
-void hp82335_remote_enable(gpib_board_t *board, int enable);
-int hp82335_enable_eos(gpib_board_t *board, uint8_t eos_byte, int
- compare_8_bits);
-void hp82335_disable_eos(gpib_board_t *board);
-unsigned int hp82335_update_status(gpib_board_t *board, unsigned int clear_mask);
-int hp82335_primary_address(gpib_board_t *board, unsigned int address);
-int hp82335_secondary_address(gpib_board_t *board, unsigned int address, int
- enable);
-int hp82335_parallel_poll(gpib_board_t *board, uint8_t *result);
-void hp82335_parallel_poll_configure(gpib_board_t *board, uint8_t config);
-void hp82335_parallel_poll_response(gpib_board_t *board, int ist);
-void hp82335_serial_poll_response(gpib_board_t *board, uint8_t status);
-void hp82335_return_to_local(gpib_board_t *board);
-
-// interrupt service routines
-irqreturn_t hp82335_interrupt(int irq, void *arg);
-
-// utility functions
-int hp82335_allocate_private(gpib_board_t *board);
-void hp82335_free_private(gpib_board_t *board);
-
// size of io memory region used
static const int hp82335_rom_size = 0x2000;
static const int hp82335_upper_iomem_size = 0x2000;
diff --git a/drivers/staging/gpib/hp_82341/hp_82341.c b/drivers/staging/gpib/hp_82341/hp_82341.c
index 0ddae295912f..f52e673dc869 100644
--- a/drivers/staging/gpib/hp_82341/hp_82341.c
+++ b/drivers/staging/gpib/hp_82341/hp_82341.c
@@ -6,6 +6,10 @@
* copyright : (C) 2002, 2005 by Frank Mori Hess *
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "hp_82341.h"
#include <linux/delay.h>
#include <linux/ioport.h>
@@ -16,9 +20,17 @@
#include <linux/isapnp.h>
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("GPIB driver for hp 82341a/b/c/d boards");
+
+static unsigned short read_and_clear_event_status(struct gpib_board *board);
+static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count);
+static int read_transfer_counter(struct hp_82341_priv *hp_priv);
+static int hp_82341_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written);
+static irqreturn_t hp_82341_interrupt(int irq, void *arg);
-int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read)
+static int hp_82341_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
+ size_t *bytes_read)
{
struct hp_82341_priv *hp_priv = board->private_data;
struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
@@ -50,7 +62,7 @@ int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int
retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes);
*bytes_read += num_bytes;
if (retval < 0)
- pr_err("tms9914_read failed retval=%i\n", retval);
+ dev_err(board->gpib_dev, "tms9914_read failed retval=%i\n", retval);
if (retval < 0 || *end)
return retval;
++buffer;
@@ -86,7 +98,6 @@ int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int
test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
test_bit(TIMO_NUM, &board->status));
if (retval) {
- pr_warn("%s: read wait interrupted\n", __func__);
retval = -ERESTARTSYS;
break;
}
@@ -111,12 +122,10 @@ int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int
tms_priv->holdoff_active = 1;
}
if (test_bit(TIMO_NUM, &board->status)) {
- pr_debug("%s: minor %i: read timed out\n", __FILE__, board->minor);
retval = -ETIMEDOUT;
break;
}
if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- pr_warn("%s: device clear interrupted read\n", __FILE__);
retval = -EINTR;
break;
}
@@ -138,7 +147,7 @@ int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int
return 0;
}
-static int restart_write_fifo(gpib_board_t *board, struct hp_82341_priv *hp_priv)
+static int restart_write_fifo(struct gpib_board *board, struct hp_82341_priv *hp_priv)
{
struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
@@ -149,7 +158,7 @@ static int restart_write_fifo(gpib_board_t *board, struct hp_82341_priv *hp_priv
//restart doesn't work if data holdoff is in effect
status = tms9914_line_status(board, tms_priv);
- if ((status & BusNRFD) == 0) {
+ if ((status & BUS_NRFD) == 0) {
outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG);
return 0;
}
@@ -163,8 +172,8 @@ static int restart_write_fifo(gpib_board_t *board, struct hp_82341_priv *hp_priv
return 0;
}
-int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
+static int hp_82341_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length,
+ int send_eoi, size_t *bytes_written)
{
struct hp_82341_priv *hp_priv = board->private_data;
struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
@@ -204,7 +213,7 @@ int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
outb(ENABLE_TI_BUFFER_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
retval = restart_write_fifo(board, hp_priv);
if (retval < 0) {
- pr_err("hp82341: failed to restart write stream\n");
+ dev_err(board->gpib_dev, "failed to restart write stream\n");
break;
}
retval = wait_event_interruptible(board->wait,
@@ -216,17 +225,14 @@ int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
*bytes_written += block_size - read_transfer_counter(hp_priv);
if (retval) {
- pr_warn("%s: write wait interrupted\n", __FILE__);
retval = -ERESTARTSYS;
break;
}
if (test_bit(TIMO_NUM, &board->status)) {
- pr_debug("%s: minor %i: write timed out\n", __FILE__, board->minor);
retval = -ETIMEDOUT;
break;
}
if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- pr_warn("%s: device clear interrupted write\n", __FILE__);
retval = -EINTR;
break;
}
@@ -244,48 +250,50 @@ int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
return 0;
}
-static int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config);
+static int hp_82341_attach(struct gpib_board *board, const gpib_board_config_t *config);
-static void hp_82341_detach(gpib_board_t *board);
+static void hp_82341_detach(struct gpib_board *board);
// wrappers for interface functions
-int hp_82341_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
+static int hp_82341_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
+ size_t *bytes_read)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
}
-int hp_82341_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int hp_82341_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
}
-int hp_82341_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int hp_82341_command(struct gpib_board *board, uint8_t *buffer, size_t length,
+ size_t *bytes_written)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
}
-int hp_82341_take_control(gpib_board_t *board, int synchronous)
+static int hp_82341_take_control(struct gpib_board *board, int synchronous)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_take_control(board, &priv->tms9914_priv, synchronous);
}
-int hp_82341_go_to_standby(gpib_board_t *board)
+static int hp_82341_go_to_standby(struct gpib_board *board)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_go_to_standby(board, &priv->tms9914_priv);
}
-void hp_82341_request_system_control(gpib_board_t *board, int request_control)
+static void hp_82341_request_system_control(struct gpib_board *board, int request_control)
{
struct hp_82341_priv *priv = board->private_data;
@@ -297,105 +305,105 @@ void hp_82341_request_system_control(gpib_board_t *board, int request_control)
tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
}
-void hp_82341_interface_clear(gpib_board_t *board, int assert)
+static void hp_82341_interface_clear(struct gpib_board *board, int assert)
{
struct hp_82341_priv *priv = board->private_data;
tms9914_interface_clear(board, &priv->tms9914_priv, assert);
}
-void hp_82341_remote_enable(gpib_board_t *board, int enable)
+static void hp_82341_remote_enable(struct gpib_board *board, int enable)
{
struct hp_82341_priv *priv = board->private_data;
tms9914_remote_enable(board, &priv->tms9914_priv, enable);
}
-int hp_82341_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int hp_82341_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
}
-void hp_82341_disable_eos(gpib_board_t *board)
+static void hp_82341_disable_eos(struct gpib_board *board)
{
struct hp_82341_priv *priv = board->private_data;
tms9914_disable_eos(board, &priv->tms9914_priv);
}
-unsigned int hp_82341_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int hp_82341_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
}
-int hp_82341_primary_address(gpib_board_t *board, unsigned int address)
+static int hp_82341_primary_address(struct gpib_board *board, unsigned int address)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_primary_address(board, &priv->tms9914_priv, address);
}
-int hp_82341_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int hp_82341_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
}
-int hp_82341_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int hp_82341_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
}
-void hp_82341_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void hp_82341_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
struct hp_82341_priv *priv = board->private_data;
tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
}
-void hp_82341_parallel_poll_response(gpib_board_t *board, int ist)
+static void hp_82341_parallel_poll_response(struct gpib_board *board, int ist)
{
struct hp_82341_priv *priv = board->private_data;
tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
}
-void hp_82341_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void hp_82341_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct hp_82341_priv *priv = board->private_data;
tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
}
-static uint8_t hp_82341_serial_poll_status(gpib_board_t *board)
+static uint8_t hp_82341_serial_poll_status(struct gpib_board *board)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_serial_poll_status(board, &priv->tms9914_priv);
}
-static int hp_82341_line_status(const gpib_board_t *board)
+static int hp_82341_line_status(const struct gpib_board *board)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_line_status(board, &priv->tms9914_priv);
}
-static unsigned int hp_82341_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int hp_82341_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct hp_82341_priv *priv = board->private_data;
return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec);
}
-void hp_82341_return_to_local(gpib_board_t *board)
+static void hp_82341_return_to_local(struct gpib_board *board)
{
struct hp_82341_priv *priv = board->private_data;
@@ -457,7 +465,7 @@ static gpib_interface_t hp_82341_interface = {
.return_to_local = hp_82341_return_to_local,
};
-int hp_82341_allocate_private(gpib_board_t *board)
+static int hp_82341_allocate_private(struct gpib_board *board)
{
board->private_data = kzalloc(sizeof(struct hp_82341_priv), GFP_KERNEL);
if (!board->private_data)
@@ -465,7 +473,7 @@ int hp_82341_allocate_private(gpib_board_t *board)
return 0;
}
-void hp_82341_free_private(gpib_board_t *board)
+static void hp_82341_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
@@ -486,21 +494,21 @@ static int hp_82341_find_isapnp_board(struct pnp_dev **dev)
*dev = pnp_find_dev(NULL, ISAPNP_VENDOR('H', 'W', 'P'),
ISAPNP_FUNCTION(0x1411), NULL);
if (!*dev || !(*dev)->card) {
- pr_err("hp_82341: failed to find isapnp board\n");
+ pr_err("failed to find isapnp board\n");
return -ENODEV;
}
if (pnp_device_attach(*dev) < 0) {
- pr_err("hp_82341: board already active, skipping\n");
+ pr_err("board already active, skipping\n");
return -EBUSY;
}
if (pnp_activate_dev(*dev) < 0) {
pnp_device_detach(*dev);
- pr_err("hp_82341: failed to activate() atgpib/tnt, aborting\n");
+ pr_err("failed to activate(), aborting\n");
return -EAGAIN;
}
if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) {
pnp_device_detach(*dev);
- pr_err("hp_82341: invalid port or irq for atgpib/tnt, aborting\n");
+ pr_err("invalid port or irq, aborting\n");
return -ENOMEM;
}
return 0;
@@ -521,7 +529,7 @@ static int xilinx_ready(struct hp_82341_priv *hp_priv)
else
return 0;
default:
- pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__);
+ pr_err("bug! unknown hw_version\n");
break;
}
return 0;
@@ -541,7 +549,7 @@ static int xilinx_done(struct hp_82341_priv *hp_priv)
else
return 0;
default:
- pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__);
+ pr_err("bug! unknown hw_version\n");
break;
}
return 0;
@@ -562,7 +570,7 @@ static int irq_valid(struct hp_82341_priv *hp_priv, int irq)
case 15:
return 1;
default:
- pr_err("hp_82341: invalid irq=%i for 82341C, irq must be 3, 5, 7, 9, 10, 11, 12, or 15.\n",
+ pr_err("invalid irq=%i for 82341C, irq must be 3, 5, 7, 9, 10, 11, 12, or 15.\n",
irq);
return 0;
}
@@ -570,7 +578,7 @@ static int irq_valid(struct hp_82341_priv *hp_priv, int irq)
case HW_VERSION_82341D:
return 1;
default:
- pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__);
+ pr_err("bug! unknown hw_version\n");
break;
}
return 0;
@@ -592,7 +600,7 @@ static int hp_82341_load_firmware_array(struct hp_82341_priv *hp_priv,
usleep_range(10, 15);
}
if (j == timeout) {
- pr_err("hp_82341: timed out waiting for Xilinx ready.\n");
+ pr_err("timed out waiting for Xilinx ready.\n");
return -ETIMEDOUT;
}
outb(firmware_data[i], hp_priv->iobase[0] + XILINX_DATA_REG);
@@ -605,7 +613,7 @@ static int hp_82341_load_firmware_array(struct hp_82341_priv *hp_priv,
usleep_range(10, 15);
}
if (j == timeout) {
- pr_err("hp_82341: timed out waiting for Xilinx done.\n");
+ pr_err("timed out waiting for Xilinx done.\n");
return -ETIMEDOUT;
}
return 0;
@@ -616,27 +624,27 @@ static int hp_82341_load_firmware(struct hp_82341_priv *hp_priv, const gpib_boar
if (config->init_data_length == 0) {
if (xilinx_done(hp_priv))
return 0;
- pr_err("hp_82341: board needs be initialized with firmware upload.\n"
+ pr_err("board needs be initialized with firmware upload.\n"
"\tUse the --init-data option of gpib_config.\n");
return -EINVAL;
}
switch (hp_priv->hw_version) {
case HW_VERSION_82341C:
if (config->init_data_length != hp_82341c_firmware_length) {
- pr_err("hp_82341: bad firmware length=%i for 82341c (expected %i).\n",
+ pr_err("bad firmware length=%i for 82341c (expected %i).\n",
config->init_data_length, hp_82341c_firmware_length);
return -EINVAL;
}
break;
case HW_VERSION_82341D:
if (config->init_data_length != hp_82341d_firmware_length) {
- pr_err("hp_82341: bad firmware length=%i for 82341d (expected %i).\n",
+ pr_err("bad firmware length=%i for 82341d (expected %i).\n",
config->init_data_length, hp_82341d_firmware_length);
return -EINVAL;
}
break;
default:
- pr_err("hp_82341: %s: bug! unknown hw_version\n", __func__);
+ pr_err("bug! unknown hw_version\n");
break;
}
return hp_82341_load_firmware_array(hp_priv, config->init_data, config->init_data_length);
@@ -678,7 +686,7 @@ static int clear_xilinx(struct hp_82341_priv *hp_priv)
return 0;
}
-int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int hp_82341_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct hp_82341_priv *hp_priv;
struct tms9914_priv *tms_priv;
@@ -714,13 +722,12 @@ int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config)
hp_priv->hw_version = HW_VERSION_82341C;
hp_priv->io_region_offset = 0x400;
}
- pr_info("hp_82341: base io 0x%u\n", iobase);
for (i = 0; i < hp_82341_num_io_regions; ++i) {
start_addr = iobase + i * hp_priv->io_region_offset;
- if (!request_region(start_addr, hp_82341_region_iosize, "hp_82341")) {
- pr_err("hp_82341: failed to allocate io ports 0x%lx-0x%lx\n",
- start_addr,
- start_addr + hp_82341_region_iosize - 1);
+ if (!request_region(start_addr, hp_82341_region_iosize, DRV_NAME)) {
+ dev_err(board->gpib_dev, "failed to allocate io ports 0x%x-0x%x\n",
+ start_addr,
+ start_addr + hp_82341_region_iosize - 1);
return -EIO;
}
hp_priv->iobase[i] = start_addr;
@@ -730,7 +737,7 @@ int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config)
retval = isapnp_cfg_begin(hp_priv->pnp_dev->card->number,
hp_priv->pnp_dev->number);
if (retval < 0) {
- pr_err("hp_82341: isapnp_cfg_begin returned error\n");
+ dev_err(board->gpib_dev, "isapnp_cfg_begin returned error\n");
return retval;
}
isapnp_write_byte(PIO_DIRECTION_REG, HP_82341D_XILINX_READY_BIT |
@@ -746,12 +753,11 @@ int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config)
return retval;
if (irq_valid(hp_priv, irq) == 0)
return -EINVAL;
- if (request_irq(irq, hp_82341_interrupt, 0, "hp_82341", board)) {
- pr_err("hp_82341: failed to allocate IRQ %d\n", irq);
+ if (request_irq(irq, hp_82341_interrupt, 0, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "failed to allocate IRQ %d\n", irq);
return -EIO;
}
hp_priv->irq = irq;
- pr_info("hp_82341: IRQ %d\n", irq);
hp_priv->config_control_bits &= ~IRQ_SELECT_MASK;
hp_priv->config_control_bits |= IRQ_SELECT_BITS(irq);
outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG);
@@ -768,13 +774,11 @@ int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config)
hp_priv->iobase[0] + EVENT_STATUS_REG);
tms9914_online(board, tms_priv);
- pr_info("hp_82341: board id %x %x %x %x\n", inb(hp_priv->iobase[1] + ID0_REG),
- inb(hp_priv->iobase[1] + ID1_REG), inb(hp_priv->iobase[2] + ID2_REG),
- inb(hp_priv->iobase[2] + ID3_REG));
+
return 0;
}
-void hp_82341_detach(gpib_board_t *board)
+static void hp_82341_detach(struct gpib_board *board)
{
struct hp_82341_priv *hp_priv = board->private_data;
struct tms9914_priv *tms_priv;
@@ -799,11 +803,14 @@ void hp_82341_detach(gpib_board_t *board)
hp_82341_free_private(board);
}
+#if 0
+/* unused, will be needed when the driver is turned into a pnp_driver */
static const struct pnp_device_id hp_82341_pnp_table[] = {
{.id = "HWP1411"},
{.id = ""}
};
MODULE_DEVICE_TABLE(pnp, hp_82341_pnp_table);
+#endif
static int __init hp_82341_init_module(void)
{
@@ -811,13 +818,13 @@ static int __init hp_82341_init_module(void)
ret = gpib_register_driver(&hp_82341_unaccel_interface, THIS_MODULE);
if (ret) {
- pr_err("hp_82341: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
return ret;
}
ret = gpib_register_driver(&hp_82341_interface, THIS_MODULE);
if (ret) {
- pr_err("hp_82341: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
gpib_unregister_driver(&hp_82341_unaccel_interface);
return ret;
}
@@ -837,7 +844,7 @@ module_exit(hp_82341_exit_module);
/*
* GPIB interrupt service routines
*/
-unsigned short read_and_clear_event_status(gpib_board_t *board)
+static unsigned short read_and_clear_event_status(struct gpib_board *board)
{
struct hp_82341_priv *hp_priv = board->private_data;
unsigned long flags;
@@ -850,10 +857,10 @@ unsigned short read_and_clear_event_status(gpib_board_t *board)
return status;
}
-irqreturn_t hp_82341_interrupt(int irq, void *arg)
+static irqreturn_t hp_82341_interrupt(int irq, void *arg)
{
int status1, status2;
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct hp_82341_priv *hp_priv = board->private_data;
struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
unsigned long flags;
@@ -862,7 +869,6 @@ irqreturn_t hp_82341_interrupt(int irq, void *arg)
spin_lock_irqsave(&board->spinlock, flags);
event_status = inb(hp_priv->iobase[0] + EVENT_STATUS_REG);
-// printk("hp_82341: interrupt event_status=0x%x\n", event_status);
if (event_status & INTERRUPT_PENDING_EVENT_BIT)
retval = IRQ_HANDLED;
//write-clear status bits
@@ -877,15 +883,12 @@ irqreturn_t hp_82341_interrupt(int irq, void *arg)
status1 = read_byte(tms_priv, ISR0);
status2 = read_byte(tms_priv, ISR1);
tms9914_interrupt_have_status(board, tms_priv, status1, status2);
-/* printk("hp_82341: interrupt status1=0x%x status2=0x%x\n",
- * status1, status2);
- */
}
spin_unlock_irqrestore(&board->spinlock, flags);
return retval;
}
-int read_transfer_counter(struct hp_82341_priv *hp_priv)
+static int read_transfer_counter(struct hp_82341_priv *hp_priv)
{
int lo, mid, value;
@@ -896,7 +899,7 @@ int read_transfer_counter(struct hp_82341_priv *hp_priv)
return value;
}
-void set_transfer_counter(struct hp_82341_priv *hp_priv, int count)
+static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count)
{
int complement = -count;
diff --git a/drivers/staging/gpib/hp_82341/hp_82341.h b/drivers/staging/gpib/hp_82341/hp_82341.h
index 0065ebd9747c..370a3d4576eb 100644
--- a/drivers/staging/gpib/hp_82341/hp_82341.h
+++ b/drivers/staging/gpib/hp_82341/hp_82341.h
@@ -26,42 +26,6 @@ struct hp_82341_priv {
enum hp_82341_hardware_version hw_version;
};
-
-// interface functions
-int hp_82341_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read);
-int hp_82341_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
-int hp_82341_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read);
-int hp_82341_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
-int hp_82341_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written);
-int hp_82341_take_control(gpib_board_t *board, int synchronous);
-int hp_82341_go_to_standby(gpib_board_t *board);
-void hp_82341_request_system_control(gpib_board_t *board, int request_control);
-void hp_82341_interface_clear(gpib_board_t *board, int assert);
-void hp_82341_remote_enable(gpib_board_t *board, int enable);
-int hp_82341_enable_eos(gpib_board_t *board, uint8_t eos_byte, int
- compare_8_bits);
-void hp_82341_disable_eos(gpib_board_t *board);
-unsigned int hp_82341_update_status(gpib_board_t *board, unsigned int clear_mask);
-int hp_82341_primary_address(gpib_board_t *board, unsigned int address);
-int hp_82341_secondary_address(gpib_board_t *board, unsigned int address, int
- enable);
-int hp_82341_parallel_poll(gpib_board_t *board, uint8_t *result);
-void hp_82341_parallel_poll_configure(gpib_board_t *board, uint8_t config);
-void hp_82341_parallel_poll_response(gpib_board_t *board, int ist);
-void hp_82341_serial_poll_response(gpib_board_t *board, uint8_t status);
-void hp_82341_return_to_local(gpib_board_t *board);
-
-// interrupt service routines
-irqreturn_t hp_82341_interrupt(int irq, void *arg);
-
-// utility functions
-int hp_82341_allocate_private(gpib_board_t *board);
-void hp_82341_free_private(gpib_board_t *board);
-
static const int hp_82341_region_iosize = 0x8;
static const int hp_82341_num_io_regions = 4;
static const int hp_82341_fifo_size = 0xffe;
@@ -199,7 +163,3 @@ enum hp_82341d_pnp_pio_bits {
HP_82341D_LEGACY_MODE_BIT = 0x4,
HP_82341D_NOT_PROG_BIT = 0x8, // clear to reinitialize xilinx
};
-
-unsigned short read_and_clear_event_status(gpib_board_t *board);
-int read_transfer_counter(struct hp_82341_priv *hp_priv);
-void set_transfer_counter(struct hp_82341_priv *hp_priv, int count);
diff --git a/drivers/staging/gpib/include/gpibP.h b/drivers/staging/gpib/include/gpibP.h
index d35fdd391f7e..0c71a038e444 100644
--- a/drivers/staging/gpib/include/gpibP.h
+++ b/drivers/staging/gpib/include/gpibP.h
@@ -26,13 +26,13 @@ struct pci_dev *gpib_pci_get_subsys(const gpib_board_config_t *config, unsigned
unsigned int device_id, unsigned int ss_vendor,
unsigned int ss_device, struct pci_dev *from);
unsigned int num_gpib_events(const gpib_event_queue_t *queue);
-int push_gpib_event(gpib_board_t *board, short event_type);
-int pop_gpib_event(gpib_board_t *board, gpib_event_queue_t *queue, short *event_type);
-int gpib_request_pseudo_irq(gpib_board_t *board, irqreturn_t (*handler)(int, void *));
-void gpib_free_pseudo_irq(gpib_board_t *board);
+int push_gpib_event(struct gpib_board *board, short event_type);
+int pop_gpib_event(struct gpib_board *board, gpib_event_queue_t *queue, short *event_type);
+int gpib_request_pseudo_irq(struct gpib_board *board, irqreturn_t (*handler)(int, void *));
+void gpib_free_pseudo_irq(struct gpib_board *board);
int gpib_match_device_path(struct device *dev, const char *device_path_in);
-extern gpib_board_t board_array[GPIB_MAX_NUM_BOARDS];
+extern struct gpib_board board_array[GPIB_MAX_NUM_BOARDS];
extern struct list_head registered_drivers;
diff --git a/drivers/staging/gpib/include/gpib_proto.h b/drivers/staging/gpib/include/gpib_proto.h
index 1499f954210b..2c7dfc02f517 100644
--- a/drivers/staging/gpib/include/gpib_proto.h
+++ b/drivers/staging/gpib/include/gpib_proto.h
@@ -10,11 +10,11 @@ int ibclose(struct inode *inode, struct file *file);
long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg);
int osInit(void);
void osReset(void);
-void os_start_timer(gpib_board_t *board, unsigned int usec_timeout);
-void os_remove_timer(gpib_board_t *board);
+void os_start_timer(struct gpib_board *board, unsigned int usec_timeout);
+void os_remove_timer(struct gpib_board *board);
void osSendEOI(void);
void osSendEOI(void);
-void init_gpib_board(gpib_board_t *board);
+void init_gpib_board(struct gpib_board *board);
static inline unsigned long usec_to_jiffies(unsigned int usec)
{
unsigned long usec_per_jiffy = 1000000 / HZ;
@@ -22,35 +22,35 @@ static inline unsigned long usec_to_jiffies(unsigned int usec)
return 1 + (usec + usec_per_jiffy - 1) / usec_per_jiffy;
};
-int serial_poll_all(gpib_board_t *board, unsigned int usec_timeout);
+int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout);
void init_gpib_descriptor(gpib_descriptor_t *desc);
-int dvrsp(gpib_board_t *board, unsigned int pad, int sad,
+int dvrsp(struct gpib_board *board, unsigned int pad, int sad,
unsigned int usec_timeout, uint8_t *result);
-int ibAPWait(gpib_board_t *board, int pad);
-int ibAPrsp(gpib_board_t *board, int padsad, char *spb);
-void ibAPE(gpib_board_t *board, int pad, int v);
-int ibcac(gpib_board_t *board, int sync, int fallback_to_async);
-int ibcmd(gpib_board_t *board, uint8_t *buf, size_t length, size_t *bytes_written);
-int ibgts(gpib_board_t *board);
-int ibonline(gpib_board_t *board);
-int iboffline(gpib_board_t *board);
-int iblines(const gpib_board_t *board, short *lines);
-int ibrd(gpib_board_t *board, uint8_t *buf, size_t length, int *end_flag, size_t *bytes_read);
-int ibrpp(gpib_board_t *board, uint8_t *buf);
-int ibrsv2(gpib_board_t *board, uint8_t status_byte, int new_reason_for_service);
-void ibrsc(gpib_board_t *board, int request_control);
-int ibsic(gpib_board_t *board, unsigned int usec_duration);
-int ibsre(gpib_board_t *board, int enable);
-int ibpad(gpib_board_t *board, unsigned int addr);
-int ibsad(gpib_board_t *board, int addr);
-int ibeos(gpib_board_t *board, int eos, int eosflags);
-int ibwait(gpib_board_t *board, int wait_mask, int clear_mask, int set_mask,
+int ibAPWait(struct gpib_board *board, int pad);
+int ibAPrsp(struct gpib_board *board, int padsad, char *spb);
+void ibAPE(struct gpib_board *board, int pad, int v);
+int ibcac(struct gpib_board *board, int sync, int fallback_to_async);
+int ibcmd(struct gpib_board *board, uint8_t *buf, size_t length, size_t *bytes_written);
+int ibgts(struct gpib_board *board);
+int ibonline(struct gpib_board *board);
+int iboffline(struct gpib_board *board);
+int iblines(const struct gpib_board *board, short *lines);
+int ibrd(struct gpib_board *board, uint8_t *buf, size_t length, int *end_flag, size_t *bytes_read);
+int ibrpp(struct gpib_board *board, uint8_t *buf);
+int ibrsv2(struct gpib_board *board, uint8_t status_byte, int new_reason_for_service);
+void ibrsc(struct gpib_board *board, int request_control);
+int ibsic(struct gpib_board *board, unsigned int usec_duration);
+int ibsre(struct gpib_board *board, int enable);
+int ibpad(struct gpib_board *board, unsigned int addr);
+int ibsad(struct gpib_board *board, int addr);
+int ibeos(struct gpib_board *board, int eos, int eosflags);
+int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask,
int *status, unsigned long usec_timeout, gpib_descriptor_t *desc);
-int ibwrt(gpib_board_t *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written);
-int ibstatus(gpib_board_t *board);
-int general_ibstatus(gpib_board_t *board, const gpib_status_queue_t *device,
+int ibwrt(struct gpib_board *board, uint8_t *buf, size_t cnt, int send_eoi, size_t *bytes_written);
+int ibstatus(struct gpib_board *board);
+int general_ibstatus(struct gpib_board *board, const gpib_status_queue_t *device,
int clear_mask, int set_mask, gpib_descriptor_t *desc);
-int io_timed_out(gpib_board_t *board);
-int ibppc(gpib_board_t *board, uint8_t configuration);
+int io_timed_out(struct gpib_board *board);
+int ibppc(struct gpib_board *board, uint8_t configuration);
#endif /* GPIB_PROTO_INCLUDED */
diff --git a/drivers/staging/gpib/include/gpib_types.h b/drivers/staging/gpib/include/gpib_types.h
index b41781a55a60..2d9b9be683f8 100644
--- a/drivers/staging/gpib/include/gpib_types.h
+++ b/drivers/staging/gpib/include/gpib_types.h
@@ -23,7 +23,7 @@
#include <linux/interrupt.h>
typedef struct gpib_interface_struct gpib_interface_t;
-typedef struct gpib_board_struct gpib_board_t;
+struct gpib_board;
/* config parameters that are only used by driver attach functions */
typedef struct {
@@ -55,9 +55,9 @@ struct gpib_interface_struct {
/* name of board */
char *name;
/* attach() initializes board and allocates resources */
- int (*attach)(gpib_board_t *board, const gpib_board_config_t *config);
+ int (*attach)(struct gpib_board *board, const gpib_board_config_t *config);
/* detach() shuts down board and frees resources */
- void (*detach)(gpib_board_t *board);
+ void (*detach)(struct gpib_board *board);
/* read() should read at most 'length' bytes from the bus into
* 'buffer'. It should return when it fills the buffer or
* encounters an END (EOI and or EOS if appropriate). It should set 'end'
@@ -68,19 +68,19 @@ struct gpib_interface_struct {
* return indicates error.
* nbytes returns number of bytes read
*/
- int (*read)(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
+ int (*read)(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
size_t *bytes_read);
/* write() should write 'length' bytes from buffer to the bus.
* If the boolean value send_eoi is nonzero, then EOI should
* be sent along with the last byte. Returns number of bytes
* written or negative value on error.
*/
- int (*write)(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
+ int (*write)(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
size_t *bytes_written);
/* command() writes the command bytes in 'buffer' to the bus
* Returns zero on success or negative value on error.
*/
- int (*command)(gpib_board_t *board, uint8_t *buffer, size_t length,
+ int (*command)(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written);
/* Take control (assert ATN). If 'asyncronous' is nonzero, take
* control asyncronously (assert ATN immediately without waiting
@@ -88,54 +88,54 @@ struct gpib_interface_struct {
* until board becomes controller in charge. Returns zero no success,
* nonzero on error.
*/
- int (*take_control)(gpib_board_t *board, int asyncronous);
+ int (*take_control)(struct gpib_board *board, int asyncronous);
/* De-assert ATN. Returns zero on success, nonzer on error.
*/
- int (*go_to_standby)(gpib_board_t *board);
+ int (*go_to_standby)(struct gpib_board *board);
/* request/release control of the IFC and REN lines (system controller) */
- void (*request_system_control)(gpib_board_t *board, int request_control);
+ void (*request_system_control)(struct gpib_board *board, int request_control);
/* Asserts or de-asserts 'interface clear' (IFC) depending on
* boolean value of 'assert'
*/
- void (*interface_clear)(gpib_board_t *board, int assert);
+ void (*interface_clear)(struct gpib_board *board, int assert);
/* Sends remote enable command if 'enable' is nonzero, disables remote mode
* if 'enable' is zero
*/
- void (*remote_enable)(gpib_board_t *board, int enable);
+ void (*remote_enable)(struct gpib_board *board, int enable);
/* enable END for reads, when byte 'eos' is received. If
* 'compare_8_bits' is nonzero, then all 8 bits are compared
* with the eos bytes. Otherwise only the 7 least significant
* bits are compared.
*/
- int (*enable_eos)(gpib_board_t *board, uint8_t eos, int compare_8_bits);
+ int (*enable_eos)(struct gpib_board *board, uint8_t eos, int compare_8_bits);
/* disable END on eos byte (END on EOI only)*/
- void (*disable_eos)(gpib_board_t *board);
+ void (*disable_eos)(struct gpib_board *board);
/* configure parallel poll */
- void (*parallel_poll_configure)(gpib_board_t *board, uint8_t configuration);
+ void (*parallel_poll_configure)(struct gpib_board *board, uint8_t configuration);
/* conduct parallel poll */
- int (*parallel_poll)(gpib_board_t *board, uint8_t *result);
+ int (*parallel_poll)(struct gpib_board *board, uint8_t *result);
/* set/clear ist (individual status bit) */
- void (*parallel_poll_response)(gpib_board_t *board, int ist);
+ void (*parallel_poll_response)(struct gpib_board *board, int ist);
/* select local parallel poll configuration mode PP2 versus remote PP1 */
- void (*local_parallel_poll_mode)(gpib_board_t *board, int local);
+ void (*local_parallel_poll_mode)(struct gpib_board *board, int local);
/* Returns current status of the bus lines. Should be set to
* NULL if your board does not have the ability to query the
* state of the bus lines.
*/
- int (*line_status)(const gpib_board_t *board);
+ int (*line_status)(const struct gpib_board *board);
/* updates and returns the board's current status.
* The meaning of the bits are specified in gpib_user.h
* in the IBSTA section. The driver does not need to
* worry about setting the CMPL, END, TIMO, or ERR bits.
*/
- unsigned int (*update_status)(gpib_board_t *board, unsigned int clear_mask);
+ unsigned int (*update_status)(struct gpib_board *board, unsigned int clear_mask);
/* Sets primary address 0-30 for gpib interface card.
*/
- int (*primary_address)(gpib_board_t *board, unsigned int address);
+ int (*primary_address)(struct gpib_board *board, unsigned int address);
/* Sets and enables, or disables secondary address 0-30
* for gpib interface card.
*/
- int (*secondary_address)(gpib_board_t *board, unsigned int address,
+ int (*secondary_address)(struct gpib_board *board, unsigned int address,
int enable);
/* Sets the byte the board should send in response to a serial poll.
* This function should also start or stop requests for service via
@@ -149,7 +149,7 @@ struct gpib_interface_struct {
* by IEEE 488.2 section 11.3.3.4.3 "Allowed Coupled Control of
* STB, reqt, and reqf".
*/
- void (*serial_poll_response)(gpib_board_t *board, uint8_t status_byte);
+ void (*serial_poll_response)(struct gpib_board *board, uint8_t status_byte);
/* Sets the byte the board should send in response to a serial poll.
* This function should also request service via IEEE 488.2 reqt/reqf
* based on MSS (bit 6 of the status_byte) and new_reason_for_service.
@@ -164,15 +164,15 @@ struct gpib_interface_struct {
* If this method is left NULL by the driver, then the user library
* function ibrsv2 will not work.
*/
- void (*serial_poll_response2)(gpib_board_t *board, uint8_t status_byte,
+ void (*serial_poll_response2)(struct gpib_board *board, uint8_t status_byte,
int new_reason_for_service);
/* returns the byte the board will send in response to a serial poll.
*/
- uint8_t (*serial_poll_status)(gpib_board_t *board);
+ uint8_t (*serial_poll_status)(struct gpib_board *board);
/* adjust T1 delay */
- unsigned int (*t1_delay)(gpib_board_t *board, unsigned int nano_sec);
+ int (*t1_delay)(struct gpib_board *board, unsigned int nano_sec);
/* go to local mode */
- void (*return_to_local)(gpib_board_t *board);
+ void (*return_to_local)(struct gpib_board *board);
/* board does not support 7 bit eos comparisons */
unsigned no_7_bit_eos : 1;
/* skip check for listeners before trying to send command bytes */
@@ -198,7 +198,7 @@ static inline void init_event_queue(gpib_event_queue_t *queue)
struct gpib_pseudo_irq {
struct timer_list timer;
irqreturn_t (*handler)(int irq, void *arg);
- gpib_board_t *board;
+ struct gpib_board *board;
atomic_t active;
};
@@ -216,11 +216,11 @@ typedef struct gpib_interface_list_struct {
struct module *module;
} gpib_interface_list_t;
-/* One gpib_board_t is allocated for each physical board in the computer.
+/* One struct gpib_board is allocated for each physical board in the computer.
* It provides storage for variables local to each board, and interface
* functions for performing operations on the board
*/
-struct gpib_board_struct {
+struct gpib_board {
/* functions used by this board */
gpib_interface_t *interface;
/* Pointer to module whose use count we should increment when
diff --git a/drivers/staging/gpib/include/nec7210.h b/drivers/staging/gpib/include/nec7210.h
index ca998c4a84bf..069896456230 100644
--- a/drivers/staging/gpib/include/nec7210.h
+++ b/drivers/staging/gpib/include/nec7210.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+//* SPDX-License-Identifier: GPL-2.0 */
/***************************************************************************
* copyright : (C) 2002 by Frank Mori Hess
@@ -78,48 +78,48 @@ enum {
};
// interface functions
-int nec7210_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read);
-int nec7210_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length, int send_eoi, size_t *bytes_written);
-int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length, size_t *bytes_written);
-int nec7210_take_control(gpib_board_t *board, struct nec7210_priv *priv, int syncronous);
-int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv);
-void nec7210_request_system_control(gpib_board_t *board,
+int nec7210_take_control(struct gpib_board *board, struct nec7210_priv *priv, int syncronous);
+int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv);
+void nec7210_request_system_control(struct gpib_board *board,
struct nec7210_priv *priv, int request_control);
-void nec7210_interface_clear(gpib_board_t *board, struct nec7210_priv *priv, int assert);
-void nec7210_remote_enable(gpib_board_t *board, struct nec7210_priv *priv, int enable);
-int nec7210_enable_eos(gpib_board_t *board, struct nec7210_priv *priv, uint8_t eos_bytes,
+void nec7210_interface_clear(struct gpib_board *board, struct nec7210_priv *priv, int assert);
+void nec7210_remote_enable(struct gpib_board *board, struct nec7210_priv *priv, int enable);
+int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, uint8_t eos_bytes,
int compare_8_bits);
-void nec7210_disable_eos(gpib_board_t *board, struct nec7210_priv *priv);
-unsigned int nec7210_update_status(gpib_board_t *board, struct nec7210_priv *priv,
+void nec7210_disable_eos(struct gpib_board *board, struct nec7210_priv *priv);
+unsigned int nec7210_update_status(struct gpib_board *board, struct nec7210_priv *priv,
unsigned int clear_mask);
-unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_priv *priv);
-int nec7210_primary_address(const gpib_board_t *board,
+unsigned int nec7210_update_status_nolock(struct gpib_board *board, struct nec7210_priv *priv);
+int nec7210_primary_address(const struct gpib_board *board,
struct nec7210_priv *priv, unsigned int address);
-int nec7210_secondary_address(const gpib_board_t *board, struct nec7210_priv *priv,
+int nec7210_secondary_address(const struct gpib_board *board, struct nec7210_priv *priv,
unsigned int address, int enable);
-int nec7210_parallel_poll(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *result);
-void nec7210_serial_poll_response(gpib_board_t *board, struct nec7210_priv *priv, uint8_t status);
-void nec7210_parallel_poll_configure(gpib_board_t *board,
+int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *result);
+void nec7210_serial_poll_response(struct gpib_board *board, struct nec7210_priv *priv, uint8_t status);
+void nec7210_parallel_poll_configure(struct gpib_board *board,
struct nec7210_priv *priv, unsigned int configuration);
-void nec7210_parallel_poll_response(gpib_board_t *board,
+void nec7210_parallel_poll_response(struct gpib_board *board,
struct nec7210_priv *priv, int ist);
-uint8_t nec7210_serial_poll_status(gpib_board_t *board,
+uint8_t nec7210_serial_poll_status(struct gpib_board *board,
struct nec7210_priv *priv);
-unsigned int nec7210_t1_delay(gpib_board_t *board,
- struct nec7210_priv *priv, unsigned int nano_sec);
-void nec7210_return_to_local(const gpib_board_t *board, struct nec7210_priv *priv);
+int nec7210_t1_delay(struct gpib_board *board,
+ struct nec7210_priv *priv, unsigned int nano_sec);
+void nec7210_return_to_local(const struct gpib_board *board, struct nec7210_priv *priv);
// utility functions
-void nec7210_board_reset(struct nec7210_priv *priv, const gpib_board_t *board);
-void nec7210_board_online(struct nec7210_priv *priv, const gpib_board_t *board);
+void nec7210_board_reset(struct nec7210_priv *priv, const struct gpib_board *board);
+void nec7210_board_online(struct nec7210_priv *priv, const struct gpib_board *board);
unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg,
unsigned int mask, unsigned int bits);
-void nec7210_set_handshake_mode(gpib_board_t *board, struct nec7210_priv *priv, int mode);
-void nec7210_release_rfd_holdoff(gpib_board_t *board, struct nec7210_priv *priv);
-uint8_t nec7210_read_data_in(gpib_board_t *board, struct nec7210_priv *priv, int *end);
+void nec7210_set_handshake_mode(struct gpib_board *board, struct nec7210_priv *priv, int mode);
+void nec7210_release_rfd_holdoff(struct gpib_board *board, struct nec7210_priv *priv);
+uint8_t nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end);
// wrappers for io functions
uint8_t nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num);
@@ -134,8 +134,8 @@ void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, uint8_t data,
unsigned int register_num);
// interrupt service routine
-irqreturn_t nec7210_interrupt(gpib_board_t *board, struct nec7210_priv *priv);
-irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board,
+irqreturn_t nec7210_interrupt(struct gpib_board *board, struct nec7210_priv *priv);
+irqreturn_t nec7210_interrupt_have_status(struct gpib_board *board,
struct nec7210_priv *priv, int status1, int status2);
#endif //_NEC7210_H
diff --git a/drivers/staging/gpib/include/tms9914.h b/drivers/staging/gpib/include/tms9914.h
index d8c8d1c9b131..424c95ad85c6 100644
--- a/drivers/staging/gpib/include/tms9914.h
+++ b/drivers/staging/gpib/include/tms9914.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+//* SPDX-License-Identifier: GPL-2.0 */
/***************************************************************************
* copyright : (C) 2002 by Frank Mori Hess
@@ -79,47 +79,47 @@ enum {
};
// interface functions
-int tms9914_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read);
-int tms9914_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, int send_eoi, size_t *bytes_written);
-int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, size_t *bytes_written);
-int tms9914_take_control(gpib_board_t *board, struct tms9914_priv *priv, int syncronous);
+int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int syncronous);
/* alternate version of tms9914_take_control which works around buggy tcs
* implementation.
*/
-int tms9914_take_control_workaround(gpib_board_t *board, struct tms9914_priv *priv,
+int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv,
int syncronous);
-int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv);
-void tms9914_request_system_control(gpib_board_t *board, struct tms9914_priv *priv,
+int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv);
+void tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
int request_control);
-void tms9914_interface_clear(gpib_board_t *board, struct tms9914_priv *priv, int assert);
-void tms9914_remote_enable(gpib_board_t *board, struct tms9914_priv *priv, int enable);
-int tms9914_enable_eos(gpib_board_t *board, struct tms9914_priv *priv, uint8_t eos_bytes,
+void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert);
+void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable);
+int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, uint8_t eos_bytes,
int compare_8_bits);
-void tms9914_disable_eos(gpib_board_t *board, struct tms9914_priv *priv);
-unsigned int tms9914_update_status(gpib_board_t *board, struct tms9914_priv *priv,
+void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv);
+unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv,
unsigned int clear_mask);
-int tms9914_primary_address(gpib_board_t *board,
+int tms9914_primary_address(struct gpib_board *board,
struct tms9914_priv *priv, unsigned int address);
-int tms9914_secondary_address(gpib_board_t *board, struct tms9914_priv *priv,
+int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv,
unsigned int address, int enable);
-int tms9914_parallel_poll(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *result);
-void tms9914_parallel_poll_configure(gpib_board_t *board,
+int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *result);
+void tms9914_parallel_poll_configure(struct gpib_board *board,
struct tms9914_priv *priv, uint8_t config);
-void tms9914_parallel_poll_response(gpib_board_t *board,
+void tms9914_parallel_poll_response(struct gpib_board *board,
struct tms9914_priv *priv, int ist);
-void tms9914_serial_poll_response(gpib_board_t *board, struct tms9914_priv *priv, uint8_t status);
-uint8_t tms9914_serial_poll_status(gpib_board_t *board, struct tms9914_priv *priv);
-int tms9914_line_status(const gpib_board_t *board, struct tms9914_priv *priv);
-unsigned int tms9914_t1_delay(gpib_board_t *board, struct tms9914_priv *priv,
+void tms9914_serial_poll_response(struct gpib_board *board, struct tms9914_priv *priv, uint8_t status);
+uint8_t tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv);
+int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv);
+unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv,
unsigned int nano_sec);
-void tms9914_return_to_local(const gpib_board_t *board, struct tms9914_priv *priv);
+void tms9914_return_to_local(const struct gpib_board *board, struct tms9914_priv *priv);
// utility functions
void tms9914_board_reset(struct tms9914_priv *priv);
-void tms9914_online(gpib_board_t *board, struct tms9914_priv *priv);
+void tms9914_online(struct gpib_board *board, struct tms9914_priv *priv);
void tms9914_release_holdoff(struct tms9914_priv *priv);
void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode);
@@ -130,8 +130,8 @@ uint8_t tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register
void tms9914_iomem_write_byte(struct tms9914_priv *priv, uint8_t data, unsigned int register_num);
// interrupt service routine
-irqreturn_t tms9914_interrupt(gpib_board_t *board, struct tms9914_priv *priv);
-irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_priv *priv,
+irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv);
+irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms9914_priv *priv,
int status1, int status2);
// tms9914 has 8 registers
diff --git a/drivers/staging/gpib/ines/Makefile b/drivers/staging/gpib/ines/Makefile
index 6b6e480fd811..88241f15ecea 100644
--- a/drivers/staging/gpib/ines/Makefile
+++ b/drivers/staging/gpib/ines/Makefile
@@ -1,4 +1,3 @@
-ccflags-$(CONFIG_GPIB_PCMCIA) := -DGPIB_PCMCIA
obj-$(CONFIG_GPIB_INES) += ines_gpib.o
diff --git a/drivers/staging/gpib/ines/ines.h b/drivers/staging/gpib/ines/ines.h
index 3918737fa21a..ff27f055a0ff 100644
--- a/drivers/staging/gpib/ines/ines.h
+++ b/drivers/staging/gpib/ines/ines.h
@@ -36,41 +36,41 @@ struct ines_priv {
};
// interface functions
-int ines_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read);
-int ines_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+int ines_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read);
+int ines_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written);
-int ines_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+int ines_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read);
-int ines_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+int ines_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written);
-int ines_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written);
-int ines_take_control(gpib_board_t *board, int synchronous);
-int ines_go_to_standby(gpib_board_t *board);
-void ines_request_system_control(gpib_board_t *board, int request_control);
-void ines_interface_clear(gpib_board_t *board, int assert);
-void ines_remote_enable(gpib_board_t *board, int enable);
-int ines_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits);
-void ines_disable_eos(gpib_board_t *board);
-unsigned int ines_update_status(gpib_board_t *board, unsigned int clear_mask);
-int ines_primary_address(gpib_board_t *board, unsigned int address);
-int ines_secondary_address(gpib_board_t *board, unsigned int address, int enable);
-int ines_parallel_poll(gpib_board_t *board, uint8_t *result);
-void ines_parallel_poll_configure(gpib_board_t *board, uint8_t config);
-void ines_parallel_poll_response(gpib_board_t *board, int ist);
-void ines_serial_poll_response(gpib_board_t *board, uint8_t status);
-uint8_t ines_serial_poll_status(gpib_board_t *board);
-int ines_line_status(const gpib_board_t *board);
-unsigned int ines_t1_delay(gpib_board_t *board, unsigned int nano_sec);
-void ines_return_to_local(gpib_board_t *board);
+int ines_command(struct gpib_board *board, uint8_t *buffer, size_t length, size_t *bytes_written);
+int ines_take_control(struct gpib_board *board, int synchronous);
+int ines_go_to_standby(struct gpib_board *board);
+void ines_request_system_control(struct gpib_board *board, int request_control);
+void ines_interface_clear(struct gpib_board *board, int assert);
+void ines_remote_enable(struct gpib_board *board, int enable);
+int ines_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits);
+void ines_disable_eos(struct gpib_board *board);
+unsigned int ines_update_status(struct gpib_board *board, unsigned int clear_mask);
+int ines_primary_address(struct gpib_board *board, unsigned int address);
+int ines_secondary_address(struct gpib_board *board, unsigned int address, int enable);
+int ines_parallel_poll(struct gpib_board *board, uint8_t *result);
+void ines_parallel_poll_configure(struct gpib_board *board, uint8_t config);
+void ines_parallel_poll_response(struct gpib_board *board, int ist);
+void ines_serial_poll_response(struct gpib_board *board, uint8_t status);
+uint8_t ines_serial_poll_status(struct gpib_board *board);
+int ines_line_status(const struct gpib_board *board);
+int ines_t1_delay(struct gpib_board *board, unsigned int nano_sec);
+void ines_return_to_local(struct gpib_board *board);
// interrupt service routines
irqreturn_t ines_pci_interrupt(int irq, void *arg);
-irqreturn_t ines_interrupt(gpib_board_t *board);
+irqreturn_t ines_interrupt(struct gpib_board *board);
// utility functions
-void ines_free_private(gpib_board_t *board);
-int ines_generic_attach(gpib_board_t *board);
-void ines_online(struct ines_priv *priv, const gpib_board_t *board, int use_accel);
+void ines_free_private(struct gpib_board *board);
+int ines_generic_attach(struct gpib_board *board);
+void ines_online(struct ines_priv *priv, const struct gpib_board *board, int use_accel);
void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count);
/* inb/outb wrappers */
diff --git a/drivers/staging/gpib/ines/ines_gpib.c b/drivers/staging/gpib/ines/ines_gpib.c
index 22a05a287bce..d93eb05dab90 100644
--- a/drivers/staging/gpib/ines/ines_gpib.c
+++ b/drivers/staging/gpib/ines/ines_gpib.c
@@ -5,6 +5,10 @@
* (C) 2002 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include "ines.h"
#include <linux/pci.h>
@@ -21,34 +25,32 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver for Ines iGPIB 72010");
-int ines_line_status(const gpib_board_t *board)
+int ines_line_status(const struct gpib_board *board)
{
- int status = ValidALL;
+ int status = VALID_ALL;
int bcm_bits;
struct ines_priv *ines_priv;
- struct nec7210_priv *nec_priv;
ines_priv = board->private_data;
- nec_priv = &ines_priv->nec7210_priv;
bcm_bits = ines_inb(ines_priv, BUS_CONTROL_MONITOR);
if (bcm_bits & BCM_REN_BIT)
- status |= BusREN;
+ status |= BUS_REN;
if (bcm_bits & BCM_IFC_BIT)
- status |= BusIFC;
+ status |= BUS_IFC;
if (bcm_bits & BCM_SRQ_BIT)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if (bcm_bits & BCM_EOI_BIT)
- status |= BusEOI;
+ status |= BUS_EOI;
if (bcm_bits & BCM_NRFD_BIT)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if (bcm_bits & BCM_NDAC_BIT)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if (bcm_bits & BCM_DAV_BIT)
- status |= BusDAV;
+ status |= BUS_DAV;
if (bcm_bits & BCM_ATN_BIT)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
@@ -56,14 +58,14 @@ int ines_line_status(const gpib_board_t *board)
void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count)
{
if (count > 0xffff) {
- pr_err("ines: bug! tried to set xfer counter > 0xffff\n");
+ pr_err("bug! tried to set xfer counter > 0xffff\n");
return;
}
ines_outb(priv, (count >> 8) & 0xff, XFER_COUNT_UPPER);
ines_outb(priv, count & 0xff, XFER_COUNT_LOWER);
}
-unsigned int ines_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+int ines_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct ines_priv *ines_priv = board->private_data;
struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
@@ -93,7 +95,7 @@ static inline unsigned short num_in_fifo_bytes(struct ines_priv *ines_priv)
return ines_inb(ines_priv, IN_FIFO_COUNT);
}
-static ssize_t pio_read(gpib_board_t *board, struct ines_priv *ines_priv, uint8_t *buffer,
+static ssize_t pio_read(struct gpib_board *board, struct ines_priv *ines_priv, uint8_t *buffer,
size_t length, size_t *nbytes)
{
ssize_t retval = 0;
@@ -106,21 +108,18 @@ static ssize_t pio_read(gpib_board_t *board, struct ines_priv *ines_priv, uint8_
num_in_fifo_bytes(ines_priv) ||
test_bit(RECEIVED_END_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- pr_warn("gpib: pio read wait interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
return -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
return -ETIMEDOUT;
if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
return -EINTR;
num_fifo_bytes = num_in_fifo_bytes(ines_priv);
- if (num_fifo_bytes + *nbytes > length) {
- pr_warn("ines: counter allowed %li extra byte(s)\n",
- (long)(num_fifo_bytes - (length - *nbytes)));
+ if (num_fifo_bytes + *nbytes > length)
num_fifo_bytes = length - *nbytes;
- }
+
for (i = 0; i < num_fifo_bytes; i++)
buffer[(*nbytes)++] = read_byte(nec_priv, DIR);
if (test_bit(RECEIVED_END_BN, &nec_priv->state) &&
@@ -134,7 +133,7 @@ static ssize_t pio_read(gpib_board_t *board, struct ines_priv *ines_priv, uint8_
return retval;
}
-int ines_accel_read(gpib_board_t *board, uint8_t *buffer,
+int ines_accel_read(struct gpib_board *board, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
ssize_t retval = 0;
@@ -191,7 +190,7 @@ static inline unsigned short num_out_fifo_bytes(struct ines_priv *ines_priv)
return ines_inb(ines_priv, OUT_FIFO_COUNT);
}
-static int ines_write_wait(gpib_board_t *board, struct ines_priv *ines_priv,
+static int ines_write_wait(struct gpib_board *board, struct ines_priv *ines_priv,
unsigned int fifo_threshold)
{
struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
@@ -201,10 +200,9 @@ static int ines_write_wait(gpib_board_t *board, struct ines_priv *ines_priv,
num_out_fifo_bytes(ines_priv) < fifo_threshold ||
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
return -ERESTARTSYS;
- }
+
if (test_bit(BUS_ERROR_BN, &nec_priv->state))
return -EIO;
if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
@@ -215,7 +213,7 @@ static int ines_write_wait(gpib_board_t *board, struct ines_priv *ines_priv,
return 0;
}
-int ines_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+int ines_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
size_t count = 0;
@@ -268,7 +266,7 @@ int ines_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
irqreturn_t ines_pci_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct ines_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -283,7 +281,7 @@ irqreturn_t ines_pci_interrupt(int irq, void *arg)
return ines_interrupt(board);
}
-irqreturn_t ines_interrupt(gpib_board_t *board)
+irqreturn_t ines_interrupt(struct gpib_board *board)
{
struct ines_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -301,7 +299,7 @@ irqreturn_t ines_interrupt(gpib_board_t *board)
wake++;
}
if (isr3_bits & FIFO_ERROR_BIT)
- pr_err("ines gpib: fifo error\n");
+ dev_err(board->gpib_dev, "fifo error\n");
if (isr3_bits & XFER_COUNT_BIT)
wake++;
@@ -315,12 +313,12 @@ irqreturn_t ines_interrupt(gpib_board_t *board)
return IRQ_HANDLED;
}
-static int ines_pci_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int ines_pci_accel_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int ines_isa_attach(gpib_board_t *board, const gpib_board_config_t *config);
+static int ines_pci_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static int ines_pci_accel_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static int ines_isa_attach(struct gpib_board *board, const gpib_board_config_t *config);
-static void ines_pci_detach(gpib_board_t *board);
-static void ines_isa_detach(gpib_board_t *board);
+static void ines_pci_detach(struct gpib_board *board);
+static void ines_isa_detach(struct gpib_board *board);
enum ines_pci_vendor_ids {
PCI_VENDOR_ID_INES_QUICKLOGIC = 0x16da
@@ -395,7 +393,8 @@ static struct ines_pci_id pci_ids[] = {
static const int num_pci_chips = ARRAY_SIZE(pci_ids);
// wrappers for interface functions
-int ines_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
+int ines_read(struct gpib_board *board, uint8_t *buffer, size_t length,
+ int *end, size_t *bytes_read)
{
struct ines_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -413,7 +412,7 @@ int ines_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, siz
return retval;
}
-int ines_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
+int ines_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
size_t *bytes_written)
{
struct ines_priv *priv = board->private_data;
@@ -421,119 +420,119 @@ int ines_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-int ines_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+int ines_command(struct gpib_board *board, uint8_t *buffer, size_t length, size_t *bytes_written)
{
struct ines_priv *priv = board->private_data;
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-int ines_take_control(gpib_board_t *board, int synchronous)
+int ines_take_control(struct gpib_board *board, int synchronous)
{
struct ines_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-int ines_go_to_standby(gpib_board_t *board)
+int ines_go_to_standby(struct gpib_board *board)
{
struct ines_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-void ines_request_system_control(gpib_board_t *board, int request_control)
+void ines_request_system_control(struct gpib_board *board, int request_control)
{
struct ines_priv *priv = board->private_data;
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
}
-void ines_interface_clear(gpib_board_t *board, int assert)
+void ines_interface_clear(struct gpib_board *board, int assert)
{
struct ines_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-void ines_remote_enable(gpib_board_t *board, int enable)
+void ines_remote_enable(struct gpib_board *board, int enable)
{
struct ines_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-int ines_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+int ines_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct ines_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-void ines_disable_eos(gpib_board_t *board)
+void ines_disable_eos(struct gpib_board *board)
{
struct ines_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-unsigned int ines_update_status(gpib_board_t *board, unsigned int clear_mask)
+unsigned int ines_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct ines_priv *priv = board->private_data;
return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
}
-int ines_primary_address(gpib_board_t *board, unsigned int address)
+int ines_primary_address(struct gpib_board *board, unsigned int address)
{
struct ines_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-int ines_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+int ines_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct ines_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-int ines_parallel_poll(gpib_board_t *board, uint8_t *result)
+int ines_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct ines_priv *priv = board->private_data;
return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
}
-void ines_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+void ines_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
struct ines_priv *priv = board->private_data;
nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
}
-void ines_parallel_poll_response(gpib_board_t *board, int ist)
+void ines_parallel_poll_response(struct gpib_board *board, int ist)
{
struct ines_priv *priv = board->private_data;
nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
}
-void ines_serial_poll_response(gpib_board_t *board, uint8_t status)
+void ines_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct ines_priv *priv = board->private_data;
nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
}
-uint8_t ines_serial_poll_status(gpib_board_t *board)
+uint8_t ines_serial_poll_status(struct gpib_board *board)
{
struct ines_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-void ines_return_to_local(gpib_board_t *board)
+void ines_return_to_local(struct gpib_board *board)
{
struct ines_priv *priv = board->private_data;
@@ -652,7 +651,7 @@ static gpib_interface_t ines_isa_interface = {
.return_to_local = ines_return_to_local,
};
-static int ines_allocate_private(gpib_board_t *board)
+static int ines_allocate_private(struct gpib_board *board)
{
struct ines_priv *priv;
@@ -665,13 +664,13 @@ static int ines_allocate_private(gpib_board_t *board)
return 0;
}
-void ines_free_private(gpib_board_t *board)
+void ines_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
-int ines_generic_attach(gpib_board_t *board)
+int ines_generic_attach(struct gpib_board *board)
{
struct ines_priv *ines_priv;
struct nec7210_priv *nec_priv;
@@ -691,7 +690,7 @@ int ines_generic_attach(gpib_board_t *board)
return 0;
}
-void ines_online(struct ines_priv *ines_priv, const gpib_board_t *board, int use_accel)
+void ines_online(struct ines_priv *ines_priv, const struct gpib_board *board, int use_accel)
{
struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
@@ -725,7 +724,7 @@ void ines_online(struct ines_priv *ines_priv, const gpib_board_t *board, int use
nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, 0);
}
-static int ines_common_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ines_common_pci_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct ines_priv *ines_priv;
struct nec7210_priv *nec_priv;
@@ -769,16 +768,16 @@ static int ines_common_pci_attach(gpib_board_t *board, const gpib_board_config_t
} while (1);
}
if (!ines_priv->pci_device) {
- pr_err("gpib: could not find ines PCI board\n");
+ dev_err(board->gpib_dev, "could not find ines PCI board\n");
return -1;
}
if (pci_enable_device(ines_priv->pci_device)) {
- pr_err("error enabling pci device\n");
+ dev_err(board->gpib_dev, "error enabling pci device\n");
return -1;
}
- if (pci_request_regions(ines_priv->pci_device, "ines-gpib"))
+ if (pci_request_regions(ines_priv->pci_device, DRV_NAME))
return -1;
nec_priv->iobase = pci_resource_start(ines_priv->pci_device,
found_id.gpib_region);
@@ -797,7 +796,7 @@ static int ines_common_pci_attach(gpib_board_t *board, const gpib_board_config_t
case PCI_CHIP_QUICKLOGIC5030:
break;
default:
- pr_err("gpib: unspecified chip type? (bug)\n");
+ dev_err(board->gpib_dev, "unspecified chip type? (bug)\n");
nec_priv->iobase = 0;
pci_release_regions(ines_priv->pci_device);
return -1;
@@ -813,8 +812,8 @@ static int ines_common_pci_attach(gpib_board_t *board, const gpib_board_config_t
#endif
isr_flags |= IRQF_SHARED;
if (request_irq(ines_priv->pci_device->irq, ines_pci_interrupt, isr_flags,
- "pci-gpib", board)) {
- pr_err("gpib: can't request IRQ %d\n", ines_priv->pci_device->irq);
+ DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "can't request IRQ %d\n", ines_priv->pci_device->irq);
return -1;
}
ines_priv->irq = ines_priv->pci_device->irq;
@@ -846,14 +845,14 @@ static int ines_common_pci_attach(gpib_board_t *board, const gpib_board_config_t
case PCI_CHIP_QUICKLOGIC5030:
break;
default:
- pr_err("gpib: unspecified chip type? (bug)\n");
+ dev_err(board->gpib_dev, "unspecified chip type? (bug)\n");
return -1;
}
return 0;
}
-int ines_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
+int ines_pci_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct ines_priv *ines_priv;
int retval;
@@ -868,7 +867,7 @@ int ines_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-int ines_pci_accel_attach(gpib_board_t *board, const gpib_board_config_t *config)
+int ines_pci_accel_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct ines_priv *ines_priv;
int retval;
@@ -885,7 +884,7 @@ int ines_pci_accel_attach(gpib_board_t *board, const gpib_board_config_t *config
static const int ines_isa_iosize = 0x20;
-int ines_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
+int ines_isa_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct ines_priv *ines_priv;
struct nec7210_priv *nec_priv;
@@ -899,15 +898,16 @@ int ines_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
ines_priv = board->private_data;
nec_priv = &ines_priv->nec7210_priv;
- if (!request_region(config->ibbase, ines_isa_iosize, "ines_gpib")) {
- pr_err("ines_gpib: ioports at 0x%x already in use\n", config->ibbase);
- return -1;
+ if (!request_region(config->ibbase, ines_isa_iosize, DRV_NAME)) {
+ dev_err(board->gpib_dev, "ioports at 0x%x already in use\n",
+ config->ibbase);
+ return -EBUSY;
}
nec_priv->iobase = config->ibbase;
nec_priv->offset = 1;
nec7210_board_reset(nec_priv, board);
- if (request_irq(config->ibirq, ines_pci_interrupt, isr_flags, "ines_gpib", board)) {
- pr_err("ines_gpib: failed to allocate IRQ %d\n", config->ibirq);
+ if (request_irq(config->ibirq, ines_pci_interrupt, isr_flags, DRV_NAME, board)) {
+ dev_err(board->gpib_dev, "failed to allocate IRQ %d\n", config->ibirq);
return -1;
}
ines_priv->irq = config->ibirq;
@@ -915,7 +915,7 @@ int ines_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-void ines_pci_detach(gpib_board_t *board)
+void ines_pci_detach(struct gpib_board *board)
{
struct ines_priv *ines_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -949,7 +949,7 @@ void ines_pci_detach(gpib_board_t *board)
ines_free_private(board);
}
-void ines_isa_detach(gpib_board_t *board)
+void ines_isa_detach(struct gpib_board *board)
{
struct ines_priv *ines_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -977,7 +977,7 @@ static struct pci_driver ines_pci_driver = {
.probe = &ines_pci_probe
};
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
#include <linux/kernel.h>
#include <linux/ptrace.h>
@@ -988,13 +988,6 @@ static struct pci_driver ines_pci_driver = {
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-#define DEBUG(n, args...) do {if (pc_debug > (n)) pr_debug(args)} while (0)
-#else
-#define DEBUG(args...)
-#endif
-
static const int ines_pcmcia_iosize = 0x20;
/* The event() function is this driver's Card Services event handler.
@@ -1007,11 +1000,11 @@ static const int ines_pcmcia_iosize = 0x20;
static int ines_gpib_config(struct pcmcia_device *link);
static void ines_gpib_release(struct pcmcia_device *link);
-static int ines_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int ines_pcmcia_accel_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static void ines_pcmcia_detach(gpib_board_t *board);
+static int ines_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static int ines_pcmcia_accel_attach(struct gpib_board *board, const gpib_board_config_t *config);
+static void ines_pcmcia_detach(struct gpib_board *board);
static irqreturn_t ines_pcmcia_interrupt(int irq, void *arg);
-static int ines_common_pcmcia_attach(gpib_board_t *board);
+static int ines_common_pcmcia_attach(struct gpib_board *board);
/*
* A linked list of "instances" of the gpib device. Each actual
* PCMCIA card corresponds to one device instance, and is described
@@ -1043,7 +1036,7 @@ static struct pcmcia_device *curr_dev;
struct local_info {
struct pcmcia_device *p_dev;
- gpib_board_t *dev;
+ struct gpib_board *dev;
u_short manfid;
u_short cardid;
};
@@ -1063,8 +1056,6 @@ static int ines_gpib_probe(struct pcmcia_device *link)
// int ret, i;
- DEBUG(0, "%s(0x%p)\n", __func__ link);
-
/* Allocate space for private device-specific data */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -1096,9 +1087,7 @@ static int ines_gpib_probe(struct pcmcia_device *link)
static void ines_gpib_remove(struct pcmcia_device *link)
{
struct local_info *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
-
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
if (info->dev)
ines_pcmcia_detach(info->dev);
@@ -1125,7 +1114,6 @@ static int ines_gpib_config(struct pcmcia_device *link)
void __iomem *virt;
dev = link->priv;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
retval = pcmcia_loop_config(link, &ines_gpib_config_iteration, NULL);
if (retval) {
@@ -1134,8 +1122,8 @@ static int ines_gpib_config(struct pcmcia_device *link)
return -ENODEV;
}
- pr_debug("ines_cs: manufacturer: 0x%x card: 0x%x\n",
- link->manf_id, link->card_id);
+ dev_dbg(&link->dev, "ines_cs: manufacturer: 0x%x card: 0x%x\n",
+ link->manf_id, link->card_id);
/* for the ines card we have to setup the configuration registers in
* attribute memory here
@@ -1167,7 +1155,6 @@ static int ines_gpib_config(struct pcmcia_device *link)
ines_gpib_release(link);
return -ENODEV;
}
- pr_info("ines gpib device loaded\n");
return 0;
} /* gpib_config */
@@ -1179,18 +1166,16 @@ static int ines_gpib_config(struct pcmcia_device *link)
static void ines_gpib_release(struct pcmcia_device *link)
{
- DEBUG(0, "%s(0x%p)\n", __func__, link);
pcmcia_disable_device(link);
} /* gpib_release */
static int ines_gpib_suspend(struct pcmcia_device *link)
{
//struct local_info *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
if (link->open)
- pr_err("Device still open ???\n");
+ dev_err(&link->dev, "Device still open\n");
//netif_device_detach(dev);
return 0;
@@ -1199,12 +1184,10 @@ static int ines_gpib_suspend(struct pcmcia_device *link)
static int ines_gpib_resume(struct pcmcia_device *link)
{
//struct local_info_t *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
/*if (link->open) {
* ni_gpib_probe(dev); / really?
- * printk("Gpib resumed ???\n");
* //netif_device_attach(dev);
*}
*/
@@ -1229,7 +1212,6 @@ static struct pcmcia_driver ines_gpib_cs_driver = {
void ines_pcmcia_cleanup_module(void)
{
- DEBUG(0, "ines_cs: unloading\n");
pcmcia_unregister_driver(&ines_gpib_cs_driver);
}
@@ -1319,19 +1301,19 @@ static gpib_interface_t ines_pcmcia_interface = {
irqreturn_t ines_pcmcia_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
return ines_interrupt(board);
}
-int ines_common_pcmcia_attach(gpib_board_t *board)
+int ines_common_pcmcia_attach(struct gpib_board *board)
{
struct ines_priv *ines_priv;
struct nec7210_priv *nec_priv;
int retval;
if (!curr_dev) {
- pr_err("no ines pcmcia cards found\n");
+ dev_err(board->gpib_dev, "no ines pcmcia cards found\n");
return -1;
}
@@ -1343,9 +1325,9 @@ int ines_common_pcmcia_attach(gpib_board_t *board)
nec_priv = &ines_priv->nec7210_priv;
if (!request_region(curr_dev->resource[0]->start,
- resource_size(curr_dev->resource[0]), "ines_gpib")) {
- pr_err("ines_gpib: ioports at 0x%lx already in use\n",
- (unsigned long)(curr_dev->resource[0]->start));
+ resource_size(curr_dev->resource[0]), DRV_NAME)) {
+ dev_err(board->gpib_dev, "ioports at 0x%lx already in use\n",
+ (unsigned long)(curr_dev->resource[0]->start));
return -1;
}
@@ -1355,7 +1337,7 @@ int ines_common_pcmcia_attach(gpib_board_t *board)
if (request_irq(curr_dev->irq, ines_pcmcia_interrupt, IRQF_SHARED,
"pcmcia-gpib", board)) {
- pr_err("gpib: can't request IRQ %d\n", curr_dev->irq);
+ dev_err(board->gpib_dev, "can't request IRQ %d\n", curr_dev->irq);
return -1;
}
ines_priv->irq = curr_dev->irq;
@@ -1363,7 +1345,7 @@ int ines_common_pcmcia_attach(gpib_board_t *board)
return 0;
}
-int ines_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
+int ines_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct ines_priv *ines_priv;
int retval;
@@ -1378,7 +1360,7 @@ int ines_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-int ines_pcmcia_accel_attach(gpib_board_t *board, const gpib_board_config_t *config)
+int ines_pcmcia_accel_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct ines_priv *ines_priv;
int retval;
@@ -1393,7 +1375,7 @@ int ines_pcmcia_accel_attach(gpib_board_t *board, const gpib_board_config_t *con
return 0;
}
-void ines_pcmcia_detach(gpib_board_t *board)
+void ines_pcmcia_detach(struct gpib_board *board)
{
struct ines_priv *ines_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1410,7 +1392,7 @@ void ines_pcmcia_detach(gpib_board_t *board)
ines_free_private(board);
}
-#endif /* GPIB_PCMCIA */
+#endif /* CONFIG_GPIB_PCMCIA */
static int __init ines_init_module(void)
{
@@ -1418,63 +1400,63 @@ static int __init ines_init_module(void)
ret = pci_register_driver(&ines_pci_driver);
if (ret) {
- pr_err("ines_gpib: pci_register_driver failed: error = %d\n", ret);
+ pr_err("pci_register_driver failed: error = %d\n", ret);
return ret;
}
ret = gpib_register_driver(&ines_pci_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pci;
}
ret = gpib_register_driver(&ines_pci_unaccel_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pci_unaccel;
}
ret = gpib_register_driver(&ines_pci_accel_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pci_accel;
}
ret = gpib_register_driver(&ines_isa_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_isa;
}
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
ret = gpib_register_driver(&ines_pcmcia_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pcmcia;
}
ret = gpib_register_driver(&ines_pcmcia_unaccel_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pcmcia_unaccel;
}
ret = gpib_register_driver(&ines_pcmcia_accel_interface, THIS_MODULE);
if (ret) {
- pr_err("ines_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pcmcia_accel;
}
ret = pcmcia_register_driver(&ines_gpib_cs_driver);
if (ret) {
- pr_err("ines_gpib: pcmcia_register_driver failed: error = %d\n", ret);
+ pr_err("pcmcia_register_driver failed: error = %d\n", ret);
goto err_pcmcia_driver;
}
#endif
return 0;
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
err_pcmcia_driver:
gpib_unregister_driver(&ines_pcmcia_accel_interface);
err_pcmcia_accel:
diff --git a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c
index 85322af62c23..faf96e9cc4a1 100644
--- a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c
+++ b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c
@@ -8,6 +8,10 @@
* copyright : (C) 2011 Marcello Carla' *
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define NAME KBUILD_MODNAME
+
/* base module includes */
#include <linux/module.h>
@@ -31,8 +35,6 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver for LPVO usb devices");
-#define NAME "lpvo_usb_gpib"
-
/*
* Table of devices that work with this driver.
*
@@ -55,10 +57,11 @@ MODULE_DEVICE_TABLE(usb, skel_table);
/*
* *** Diagnostics and Debug ***
- *
+ * To enable the diagnostic and debug messages either compile with DEBUG set
+ * or control via the dynamic debug mechanisms.
* The module parameter "debug" controls the sending of debug messages to
- * syslog. By default it is set to 0 or 1 according to GPIB_CONFIG_KERNEL_DEBUG.
- * debug = 0: only register/deregister messages are generated
+ * syslog. By default it is set to 0
+ * debug = 0: only attach/detach messages are sent
* 1: every action is logged
* 2: extended logging; each single exchanged byte is documented
* (about twice the log volume of [1])
@@ -70,11 +73,15 @@ MODULE_DEVICE_TABLE(usb, skel_table);
static int debug;
module_param(debug, int, 0644);
-#define DIA_LOG(level, format, ...) \
+#define DIA_LOG(level, format, ...) \
do { if (debug >= (level)) \
- pr_alert("%s:%s - " format, NAME, __func__, ## __VA_ARGS__); } \
+ dev_dbg(board->gpib_dev, format, ## __VA_ARGS__); } \
while (0)
+#define WQT wait_queue_entry_t
+#define WQH head
+#define WQE entry
+
/* standard and extended command sets of the usb-gpib adapter */
#define USB_GPIB_ON "\nIB\n"
@@ -135,7 +142,7 @@ struct char_buf { /* used by one_char() routine */
};
struct usb_gpib_priv { /* private data to the device */
- u8 eos; /* eos character */
+ u8 eos; /* eos character */
short eos_flags; /* eos mode */
int timeout; /* current value for timeout */
void *dev; /* the usb device private data structure */
@@ -143,42 +150,23 @@ struct usb_gpib_priv { /* private data to the device */
#define GPIB_DEV (((struct usb_gpib_priv *)board->private_data)->dev)
-#define SHOW_STATUS(board) { \
- DIA_LOG(2, "# - board %p\n", board); \
- DIA_LOG(2, "# - buffer_length %d\n", board->buffer_length); \
- DIA_LOG(2, "# - status %lx\n", board->status); \
- DIA_LOG(2, "# - use_count %d\n", board->use_count); \
- DIA_LOG(2, "# - pad %x\n", board->pad); \
- DIA_LOG(2, "# - sad %x\n", board->sad); \
- DIA_LOG(2, "# - timeout %d\n", board->usec_timeout); \
- DIA_LOG(2, "# - ppc %d\n", board->parallel_poll_configuration); \
- DIA_LOG(2, "# - t1delay %d\n", board->t1_nano_sec); \
- DIA_LOG(2, "# - online %d\n", board->online); \
- DIA_LOG(2, "# - autopoll %d\n", board->autospollers); \
- DIA_LOG(2, "# - autopoll task %p\n", board->autospoll_task); \
- DIA_LOG(2, "# - minor %d\n", board->minor); \
- DIA_LOG(2, "# - master %d\n", board->master); \
- DIA_LOG(2, "# - list %d\n", board->ist); \
- }
-/*
- * n = 0;
- * list_for_each (l, &board->device_list) n++;
- * TTY_LOG ("%s:%s - devices in list %d\n", a, b, n);
- */
-
-/*
- * TTY_LOG - write a message to the current work terminal (if any)
- */
-
-#define TTY_LOG(format, ...) { \
- char buf[128]; \
- struct tty_struct *tty = get_current_tty(); \
- if (tty) { \
- snprintf(buf, 128, format, __VA_ARGS__); \
- tty->driver->ops->write(tty, buf, strlen(buf)); \
- tty->driver->ops->write(tty, "\r", 1); \
- } \
- }
+static void show_status(struct gpib_board *board)
+{
+ DIA_LOG(2, "# - buffer_length %d\n", board->buffer_length);
+ DIA_LOG(2, "# - status %lx\n", board->status);
+ DIA_LOG(2, "# - use_count %d\n", board->use_count);
+ DIA_LOG(2, "# - pad %x\n", board->pad);
+ DIA_LOG(2, "# - sad %x\n", board->sad);
+ DIA_LOG(2, "# - timeout %d\n", board->usec_timeout);
+ DIA_LOG(2, "# - ppc %d\n", board->parallel_poll_configuration);
+ DIA_LOG(2, "# - t1delay %d\n", board->t1_nano_sec);
+ DIA_LOG(2, "# - online %d\n", board->online);
+ DIA_LOG(2, "# - autopoll %d\n", board->autospollers);
+ DIA_LOG(2, "# - autopoll task %p\n", board->autospoll_task);
+ DIA_LOG(2, "# - minor %d\n", board->minor);
+ DIA_LOG(2, "# - master %d\n", board->master);
+ DIA_LOG(2, "# - list %d\n", board->ist);
+}
/*
* GLOBAL VARIABLES: required for
@@ -200,8 +188,8 @@ static struct mutex minors_lock; /* operations on usb_minors are to be prote
struct usb_skel;
static ssize_t skel_do_write(struct usb_skel *, const char *, size_t);
static ssize_t skel_do_read(struct usb_skel *, char *, size_t);
-static int skel_do_open(gpib_board_t *, int);
-static int skel_do_release(gpib_board_t *);
+static int skel_do_open(struct gpib_board *, int);
+static int skel_do_release(struct gpib_board *);
/*
* usec_diff : take difference in MICROsec between two 'timespec'
@@ -229,27 +217,7 @@ static inline int usec_diff(struct timespec64 *a, struct timespec64 *b)
static int write_loop(void *dev, char *msg, int leng)
{
-// int nchar = 0, val;
-
-// do {
-
return skel_do_write(dev, msg, leng);
-
-// if (val < 1) {
-// printk (KERN_ALERT "%s:%s - write error: %d %d/%d\n",
-// NAME, __func__, val, nchar, leng);
-// return -EIO;
-// }
-// nchar +=val;
-// } while (nchar < leng);
-// return leng;
-}
-
-static char printable(char x)
-{
- if (x < 32 || x > 126)
- return ' ';
- return x;
}
/**
@@ -257,15 +225,15 @@ static char printable(char x)
*
* @board: the gpib_board_struct data area for this gpib interface
* @msg: the byte sequence.
- * @leng the byte sequence length; can be given as zero and is
+ * @leng: the byte sequence length; can be given as zero and is
* computed automatically, but if 'msg' contains a zero byte,
* it has to be given explicitly.
*/
-static int send_command(gpib_board_t *board, char *msg, int leng)
+static int send_command(struct gpib_board *board, char *msg, int leng)
{
char buffer[64];
- int nchar, j;
+ int nchar;
int retval;
struct timespec64 before, after;
@@ -280,17 +248,10 @@ static int send_command(gpib_board_t *board, char *msg, int leng)
nchar = skel_do_read(GPIB_DEV, buffer, 64);
if (nchar < 0) {
- DIA_LOG(0, " return from read: %d\n", nchar);
+ dev_err(board->gpib_dev, " return from read: %d\n", nchar);
return nchar;
} else if (nchar != 1) {
- for (j = 0 ; j < leng ; j++) {
- DIA_LOG(0, " Irregular reply to command: %d %x %c\n",
- j, msg[j], printable(msg[j]));
- }
- for (j = 0 ; j < nchar ; j++) {
- DIA_LOG(0, " Irregular command reply: %d %x %c\n",
- j, buffer[j] & 0xff, printable(buffer[j]));
- }
+ dev_err(board->gpib_dev, " Irregular reply to command: %s\n", msg);
return -EIO;
}
ktime_get_real_ts64 (&after);
@@ -310,7 +271,7 @@ static int send_command(gpib_board_t *board, char *msg, int leng)
*
*/
-static int set_control_line(gpib_board_t *board, int line, int value)
+static int set_control_line(struct gpib_board *board, int line, int value)
{
char msg[] = USB_GPIB_SET_LINES;
int retval;
@@ -337,11 +298,11 @@ static int set_control_line(gpib_board_t *board, int line, int value)
/*
* one_char() - read one single byte from input buffer
*
- * @board: the gpib_board_struct data area for this gpib interface
- * @char_buf: the routine private data structure
+ * @board: the gpib_board_struct data area for this gpib interface
+ * @char_buf: the routine private data structure
*/
-static int one_char(gpib_board_t *board, struct char_buf *b)
+static int one_char(struct gpib_board *board, struct char_buf *b)
{
struct timespec64 before, after;
@@ -360,13 +321,7 @@ static int one_char(gpib_board_t *board, struct char_buf *b)
if (b->nchar > 0) {
DIA_LOG(2, "--> %x\n", b->inbuf[b->last - b->nchar]);
return b->inbuf[b->last - b->nchar--];
- } else if (b->nchar == 0) {
- dev_alert(board->gpib_dev, "%s:%s - read returned EOF\n", NAME, __func__);
- return -EIO;
}
- dev_alert(board->gpib_dev, "%s:%s - read error %d\n", NAME, __func__, b->nchar);
- TTY_LOG("\n *** %s *** Read Error - %s\n", NAME,
- "Reset the adapter with 'gpib_config'\n");
return -EIO;
}
@@ -381,7 +336,7 @@ static int one_char(gpib_board_t *board, struct char_buf *b)
* not supported.
*/
-static void set_timeout(gpib_board_t *board)
+static void set_timeout(struct gpib_board *board)
{
int n, val;
char command[sizeof(USB_GPIB_TTMO) + 6];
@@ -406,12 +361,10 @@ static void set_timeout(gpib_board_t *board)
val = send_command(board, command, 0);
}
- if (val != ACK) {
- dev_alert(board->gpib_dev, "%s:%s - error in timeout set: <%s>\n",
- NAME, __func__, command);
- } else {
+ if (val != ACK)
+ dev_err(board->gpib_dev, "error in timeout set: <%s>\n", command);
+ else
data->timeout = board->usec_timeout;
- }
}
/*
@@ -431,7 +384,7 @@ static void set_timeout(gpib_board_t *board)
* detach() will be called. Always.
*/
-static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int usb_gpib_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
int retval, j;
u32 base = config->ibbase;
@@ -451,8 +404,6 @@ static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *confi
if (config->device_path) {
/* if config->device_path given, try that first */
- dev_alert(board->gpib_dev, "%s:%s - Looking for device_path: %s\n",
- NAME, __func__, config->device_path);
for (j = 0 ; j < MAX_DEV ; j++) {
if ((assigned_usb_minors & 1 << j) == 0)
continue;
@@ -487,8 +438,7 @@ static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *confi
mutex_unlock(&minors_lock);
if (j == MAX_DEV) {
- dev_alert(board->gpib_dev, "%s:%s - Requested device is not registered.\n",
- NAME, __func__);
+ dev_err(board->gpib_dev, "Requested device is not registered.\n");
return -EIO;
}
@@ -501,13 +451,13 @@ static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *confi
DIA_LOG(1, "Skel open: %d\n", retval);
if (retval) {
- TTY_LOG("%s:%s - skel open failed.\n", NAME, __func__);
+ dev_err(board->gpib_dev, "skel open failed.\n");
kfree(board->private_data);
board->private_data = NULL;
return -ENODEV;
}
- SHOW_STATUS(board);
+ show_status(board);
retval = send_command(board, USB_GPIB_ON, 0);
DIA_LOG(1, "USB_GPIB_ON returns %x\n", retval);
@@ -541,8 +491,8 @@ static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *confi
if (retval != ACK)
return -EIO;
- SHOW_STATUS(board);
- TTY_LOG("Module '%s' has been sucesfully configured\n", NAME);
+ show_status(board);
+ DIA_LOG(0, "attached\n");
return 0;
}
@@ -553,13 +503,13 @@ static int usb_gpib_attach(gpib_board_t *board, const gpib_board_config_t *confi
*
*/
-static void usb_gpib_detach(gpib_board_t *board)
+static void usb_gpib_detach(struct gpib_board *board)
{
int retval;
- SHOW_STATUS(board);
+ show_status(board);
- DIA_LOG(0, "detaching %p\n", board);
+ DIA_LOG(0, "detaching\n");
if (board->private_data) {
if (GPIB_DEV) {
@@ -573,15 +523,14 @@ static void usb_gpib_detach(gpib_board_t *board)
board->private_data = NULL;
}
- DIA_LOG(0, "done %p\n", board);
- TTY_LOG("Module '%s' has been detached\n", NAME);
+ DIA_LOG(0, "detached\n");
}
/*
* Other functions follow in alphabetical order
*/
/* command */
-static int usb_gpib_command(gpib_board_t *board,
+static int usb_gpib_command(struct gpib_board *board,
u8 *buffer,
size_t length,
size_t *bytes_written)
@@ -614,7 +563,7 @@ static int usb_gpib_command(gpib_board_t *board,
* Cannot do nothing here, but remember for future use.
*/
-static void usb_gpib_disable_eos(gpib_board_t *board)
+static void usb_gpib_disable_eos(struct gpib_board *board)
{
((struct usb_gpib_priv *)board->private_data)->eos_flags &= ~REOS;
DIA_LOG(1, "done: %x\n",
@@ -630,7 +579,7 @@ static void usb_gpib_disable_eos(gpib_board_t *board)
*
*/
-static int usb_gpib_enable_eos(gpib_board_t *board,
+static int usb_gpib_enable_eos(struct gpib_board *board,
u8 eos_byte,
int compare_8_bits)
{
@@ -650,7 +599,7 @@ static int usb_gpib_enable_eos(gpib_board_t *board,
* @board: the gpib_board data area for this gpib interface
*/
-static int usb_gpib_go_to_standby(gpib_board_t *board)
+static int usb_gpib_go_to_standby(struct gpib_board *board)
{
int retval = set_control_line(board, IB_BUS_ATN, 0);
@@ -665,14 +614,14 @@ static int usb_gpib_go_to_standby(gpib_board_t *board)
* usb_gpib_interface_clear() - Assert or de-assert IFC
*
* @board: the gpib_board data area for this gpib interface
- * assert: 1: assert IFC; 0: de-assert IFC
+ * @assert: 1: assert IFC; 0: de-assert IFC
*
* Currently on the assert request we issue the lpvo IBZ
* command that cycles IFC low for 100 usec, then we ignore
* the de-assert request.
*/
-static void usb_gpib_interface_clear(gpib_board_t *board, int assert)
+static void usb_gpib_interface_clear(struct gpib_board *board, int assert)
{
int retval = 0;
@@ -688,21 +637,16 @@ static void usb_gpib_interface_clear(gpib_board_t *board, int assert)
}
/**
- * line_status() - Read the status of the bus lines.
+ * usb_gpib_line_status() - Read the status of the bus lines.
*
* @board: the gpib_board data area for this gpib interface
*
* We can read all lines.
*/
-
-#define WQT wait_queue_entry_t
-#define WQH head
-#define WQE entry
-
-static int usb_gpib_line_status(const gpib_board_t *board)
+static int usb_gpib_line_status(const struct gpib_board *board)
{
int buffer;
- int line_status = ValidALL; /* all lines will be read */
+ int line_status = VALID_ALL; /* all lines will be read */
struct list_head *p, *q;
WQT *item;
unsigned long flags;
@@ -730,30 +674,29 @@ static int usb_gpib_line_status(const gpib_board_t *board)
msleep(sleep);
}
- buffer = send_command((gpib_board_t *)board, USB_GPIB_STATUS, 0);
+ buffer = send_command((struct gpib_board *)board, USB_GPIB_STATUS, 0);
if (buffer < 0) {
- dev_alert(board->gpib_dev, "%s:%s - line status read failed with %d\n",
- NAME, __func__, buffer);
+ dev_err(board->gpib_dev, "line status read failed with %d\n", buffer);
return -1;
}
if ((buffer & 0x01) == 0)
- line_status |= BusREN;
+ line_status |= BUS_REN;
if ((buffer & 0x02) == 0)
- line_status |= BusIFC;
+ line_status |= BUS_IFC;
if ((buffer & 0x04) == 0)
- line_status |= BusNDAC;
+ line_status |= BUS_NDAC;
if ((buffer & 0x08) == 0)
- line_status |= BusNRFD;
+ line_status |= BUS_NRFD;
if ((buffer & 0x10) == 0)
- line_status |= BusDAV;
+ line_status |= BUS_DAV;
if ((buffer & 0x20) == 0)
- line_status |= BusEOI;
+ line_status |= BUS_EOI;
if ((buffer & 0x40) == 0)
- line_status |= BusATN;
+ line_status |= BUS_ATN;
if ((buffer & 0x80) == 0)
- line_status |= BusSRQ;
+ line_status |= BUS_SRQ;
DIA_LOG(1, "done with %x %x\n", buffer, line_status);
@@ -762,7 +705,7 @@ static int usb_gpib_line_status(const gpib_board_t *board)
/* parallel_poll */
-static int usb_gpib_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int usb_gpib_parallel_poll(struct gpib_board *board, uint8_t *result)
{
/* request parallel poll asserting ATN | EOI;
* we suppose ATN already asserted
@@ -773,27 +716,23 @@ static int usb_gpib_parallel_poll(gpib_board_t *board, uint8_t *result)
DIA_LOG(1, "enter %p\n", board);
retval = set_control_line(board, IB_BUS_EOI, 1);
- if (retval != ACK) {
- dev_alert(board->gpib_dev, "%s:%s - assert EOI failed\n", NAME, __func__);
+ if (retval != ACK)
return -EIO;
- }
*result = send_command(board, USB_GPIB_READ_DATA, 0);
DIA_LOG(1, "done with %x\n", *result);
retval = set_control_line(board, IB_BUS_EOI, 0);
- if (retval != 0x06) {
- dev_alert(board->gpib_dev, "%s:%s - unassert EOI failed\n", NAME, __func__);
+ if (retval != 0x06)
return -EIO;
- }
return 0;
}
/* read */
-static int usb_gpib_read(gpib_board_t *board,
+static int usb_gpib_read(struct gpib_board *board,
u8 *buffer,
size_t length,
int *end,
@@ -866,8 +805,7 @@ static int usb_gpib_read(gpib_board_t *board,
goto read_return;
if (one_char(board, &b) != DLE || one_char(board, &b) != STX) {
- dev_alert(board->gpib_dev, "%s:%s - wrong <DLE><STX> sequence\n",
- NAME, __func__);
+ dev_err(board->gpib_dev, "wrong <DLE><STX> sequence\n");
retval = -EIO;
goto read_return;
}
@@ -907,15 +845,12 @@ static int usb_gpib_read(gpib_board_t *board,
retval = 0;
goto read_return;
} else {
- dev_alert(board->gpib_dev, "%s:%s - %s %x\n",
- NAME, __func__,
- "Wrong end of message", c);
+ dev_err(board->gpib_dev, "wrong end of message %x", c);
retval = -ETIME;
goto read_return;
}
} else {
- dev_alert(board->gpib_dev, "%s:%s - %s\n", NAME, __func__,
- "lone <DLE> in stream");
+ dev_err(board->gpib_dev, "lone <DLE> in stream");
retval = -EIO;
goto read_return;
}
@@ -934,8 +869,7 @@ static int usb_gpib_read(gpib_board_t *board,
c = one_char(board, &b);
if (c == ACK) {
if (MAX_READ_EXCESS - read_count > 1)
- dev_alert(board->gpib_dev, "%s:%s - %s\n", NAME, __func__,
- "small buffer - maybe some data lost");
+ dev_dbg(board->gpib_dev, "small buffer - maybe some data lost");
retval = 0;
goto read_return;
}
@@ -943,15 +877,13 @@ static int usb_gpib_read(gpib_board_t *board,
}
}
- dev_alert(board->gpib_dev, "%s:%s - no input end - GPIB board in odd state\n",
- NAME, __func__);
+ dev_err(board->gpib_dev, "no input end - board in odd state\n");
retval = -EIO;
read_return:
kfree(b.inbuf);
- DIA_LOG(1, "done with byte/status: %d %x %d\n",
- (int)*bytes_read, retval, *end);
+ DIA_LOG(1, "done with byte/status: %d %x %d\n", (int)*bytes_read, retval, *end);
if (retval == 0 || retval == -ETIME) {
if (send_command(board, USB_GPIB_UNTALK, sizeof(USB_GPIB_UNTALK)) == 0x06)
@@ -964,21 +896,20 @@ read_return:
/* remote_enable */
-static void usb_gpib_remote_enable(gpib_board_t *board, int enable)
+static void usb_gpib_remote_enable(struct gpib_board *board, int enable)
{
int retval;
retval = set_control_line(board, IB_BUS_REN, enable ? 1 : 0);
if (retval != ACK)
- dev_alert(board->gpib_dev, "%s:%s - could not set REN line: %x\n",
- NAME, __func__, retval);
+ dev_err(board->gpib_dev, "could not set REN line: %x\n", retval);
DIA_LOG(1, "done with %x\n", retval);
}
/* request_system_control */
-static void usb_gpib_request_system_control(gpib_board_t *board,
+static void usb_gpib_request_system_control(struct gpib_board *board,
int request_control)
{
if (request_control)
@@ -992,7 +923,7 @@ static void usb_gpib_request_system_control(gpib_board_t *board,
/* take_control */
/* beware: the sync flag is ignored; what is its real meaning? */
-static int usb_gpib_take_control(gpib_board_t *board, int sync)
+static int usb_gpib_take_control(struct gpib_board *board, int sync)
{
int retval;
@@ -1007,7 +938,7 @@ static int usb_gpib_take_control(gpib_board_t *board, int sync)
/* update_status */
-static unsigned int usb_gpib_update_status(gpib_board_t *board,
+static unsigned int usb_gpib_update_status(struct gpib_board *board,
unsigned int clear_mask)
{
/* There is nothing we can do here, I guess */
@@ -1022,7 +953,7 @@ static unsigned int usb_gpib_update_status(gpib_board_t *board,
/* write */
/* beware: DLE characters are not escaped - can only send ASCII data */
-static int usb_gpib_write(gpib_board_t *board,
+static int usb_gpib_write(struct gpib_board *board,
u8 *buffer,
size_t length,
int send_eoi,
@@ -1053,9 +984,8 @@ static int usb_gpib_write(gpib_board_t *board,
*bytes_written = length;
- if (send_command(board, USB_GPIB_UNLISTEN, sizeof(USB_GPIB_UNLISTEN))
- != 0x06)
- return -EPIPE;
+ if (send_command(board, USB_GPIB_UNLISTEN, sizeof(USB_GPIB_UNLISTEN)) != 0x06)
+ return -EPIPE;
return length;
}
@@ -1066,64 +996,56 @@ static int usb_gpib_write(gpib_board_t *board,
/* parallel_poll configure */
-static void usb_gpib_parallel_poll_configure(gpib_board_t *board,
+static void usb_gpib_parallel_poll_configure(struct gpib_board *board,
uint8_t configuration)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
}
/* parallel_poll_response */
-static void usb_gpib_parallel_poll_response(gpib_board_t *board, int ist)
+static void usb_gpib_parallel_poll_response(struct gpib_board *board, int ist)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
}
/* primary_address */
-static int usb_gpib_primary_address(gpib_board_t *board, unsigned int address)
+static int usb_gpib_primary_address(struct gpib_board *board, unsigned int address)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
return 0;
}
/* return_to_local */
-static void usb_gpib_return_to_local(gpib_board_t *board)
+static void usb_gpib_return_to_local(struct gpib_board *board)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
}
/* secondary_address */
-static int usb_gpib_secondary_address(gpib_board_t *board,
+static int usb_gpib_secondary_address(struct gpib_board *board,
unsigned int address,
int enable)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
return 0;
}
/* serial_poll_response */
-static void usb_gpib_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void usb_gpib_serial_poll_response(struct gpib_board *board, uint8_t status)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
}
/* serial_poll_status */
-static uint8_t usb_gpib_serial_poll_status(gpib_board_t *board)
+static uint8_t usb_gpib_serial_poll_status(struct gpib_board *board)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
return 0;
}
/* t1_delay */
-static unsigned int usb_gpib_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int usb_gpib_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
- dev_alert(board->gpib_dev, "%s:%s - currently a NOP\n", NAME, __func__);
return 0;
}
@@ -1181,7 +1103,7 @@ static int usb_gpib_init_module(struct usb_interface *interface)
if (!assigned_usb_minors) {
rv = gpib_register_driver(&usb_gpib_interface, THIS_MODULE);
if (rv) {
- pr_err("lpvo_usb_gpib: gpib_register_driver failed: error = %d\n", rv);
+ pr_err("gpib_register_driver failed: error = %d\n", rv);
goto exit;
}
} else {
@@ -1191,8 +1113,8 @@ static int usb_gpib_init_module(struct usb_interface *interface)
for (j = 0 ; j < MAX_DEV ; j++) {
if (usb_minors[j] == interface->minor && assigned_usb_minors & 1 << j) {
- pr_alert("%s:%s - CODE BUG: USB minor %d registered at %d.\n",
- NAME, __func__, interface->minor, j);
+ pr_err("CODE BUG: USB minor %d registered at %d.\n",
+ interface->minor, j);
rv = -1;
goto exit;
}
@@ -1207,13 +1129,11 @@ static int usb_gpib_init_module(struct usb_interface *interface)
usb_minors[j] = interface->minor;
lpvo_usb_interfaces[j] = interface;
assigned_usb_minors |= mask;
- DIA_LOG(0, "usb minor %d registered at %d\n", interface->minor, j);
rv = 0;
goto exit;
}
}
- pr_alert("%s:%s - No slot available for interface %p minor %d\n",
- NAME, __func__, interface, interface->minor);
+ pr_err("No slot available for interface %p minor %d\n", interface, interface->minor);
rv = -1;
exit:
@@ -1235,7 +1155,7 @@ static void usb_gpib_exit_module(int minor)
goto exit;
}
}
- pr_alert("%s:%s - CODE BUG: USB minor %d not found.\n", NAME, __func__, minor);
+ pr_err("CODE BUG: USB minor %d not found.\n", minor);
exit:
mutex_unlock(&minors_lock);
@@ -1267,7 +1187,7 @@ static int write_latency_timer(struct usb_device *udev)
LATENCY_TIMER, LATENCY_CHANNEL,
NULL, 0, WDR_TIMEOUT);
if (rv < 0)
- pr_alert("Unable to write latency timer: %i\n", rv);
+ dev_err(&udev->dev, "Unable to write latency timer: %i\n", rv);
return rv;
}
@@ -1363,18 +1283,15 @@ static void skel_delete(struct kref *kref)
* skel_do_open() - to be called by usb_gpib_attach
*/
-static int skel_do_open(gpib_board_t *board, int subminor)
+static int skel_do_open(struct gpib_board *board, int subminor)
{
struct usb_skel *dev;
struct usb_interface *interface;
int retval = 0;
- DIA_LOG(0, "Required minor: %d\n", subminor);
-
interface = usb_find_interface(&skel_driver, subminor);
if (!interface) {
- pr_err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
+ dev_err(board->gpib_dev, "can't find device for minor %d\n", subminor);
retval = -ENODEV;
goto exit;
}
@@ -1403,7 +1320,7 @@ exit:
* skel_do_release() - to be called by usb_gpib_detach
*/
-static int skel_do_release(gpib_board_t *board)
+static int skel_do_release(struct gpib_board *board)
{
struct usb_skel *dev;
@@ -1439,9 +1356,8 @@ static void skel_read_bulk_callback(struct urb *urb)
if (!(urb->status == -ENOENT ||
urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN))
- dev_err(&dev->interface->dev,
- "%s - nonzero read bulk status received: %d\n",
- __func__, urb->status);
+ dev_err(&dev->interface->dev, "nonzero read bulk status received: %d\n",
+ urb->status);
dev->errors = urb->status;
} else {
@@ -1478,9 +1394,7 @@ static int skel_do_read_io(struct usb_skel *dev, size_t count)
/* do it */
rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
if (rv < 0) {
- dev_err(&dev->interface->dev,
- "%s - failed submitting read urb, error %d\n",
- __func__, rv);
+ dev_err(&dev->interface->dev, "failed submitting read urb, error %d\n", rv);
rv = (rv == -ENOMEM) ? rv : -EIO;
spin_lock_irq(&dev->err_lock);
dev->ongoing_read = 0;
@@ -1504,14 +1418,10 @@ static ssize_t skel_do_read(struct usb_skel *dev, char *buffer, size_t count)
if (!dev->bulk_in_urb || !count)
return 0;
- DIA_LOG(1, "enter for %zu.\n", count);
-
restart: /* added to comply with ftdi timeout technique */
/* no concurrent readers */
- DIA_LOG(2, "restart with %zd %zd.\n", dev->bulk_in_filled, dev->bulk_in_copied);
-
rv = mutex_lock_interruptible(&dev->io_mutex);
if (rv < 0)
return rv;
@@ -1527,8 +1437,6 @@ retry:
ongoing_io = dev->ongoing_read;
spin_unlock_irq(&dev->err_lock);
- DIA_LOG(2, "retry with %d.\n", ongoing_io);
-
if (ongoing_io) {
// /* nonblocking IO shall not wait */
// /* no file, no O_NONBLOCK; maybe provide when from user space */
@@ -1569,8 +1477,6 @@ retry:
// size_t chunk = min(available, count); /* compute chunk later */
size_t chunk;
- DIA_LOG(2, "we have data: %zu %zu.\n", dev->bulk_in_filled, dev->bulk_in_copied);
-
if (!available) {
/*
* all data has been used
@@ -1596,12 +1502,6 @@ retry:
*/
if (dev->bulk_in_copied) {
- int j;
-
- for (j = 0 ; j < dev->bulk_in_filled ; j++) {
- pr_alert("copy -> %x %zu %x\n",
- j, dev->bulk_in_copied, dev->bulk_in_buffer[j]);
- }
chunk = min(available, count);
memcpy(buffer, dev->bulk_in_buffer + dev->bulk_in_copied, chunk);
rv = chunk;
@@ -1613,7 +1513,7 @@ retry:
/* account for two bytes to be discarded */
chunk = min(available, count + 2);
if (chunk < 2) {
- pr_alert("BAD READ - chunk: %zu\n", chunk);
+ dev_err(&dev->udev->dev, "BAD READ - chunk: %zu\n", chunk);
rv = -EIO;
goto exit;
}
@@ -1633,8 +1533,6 @@ retry:
// if (available < count)
// skel_do_read_io(dev, dev->bulk_in_size);
} else {
- DIA_LOG(1, "no data - start read - copied: %zd.\n", dev->bulk_in_copied);
-
/* no data in the buffer */
rv = skel_do_read_io(dev, dev->bulk_in_size);
if (rv < 0)
@@ -1645,10 +1543,10 @@ retry:
exit:
mutex_unlock(&dev->io_mutex);
if (rv == 2)
- goto restart; /* ftdi chip returns two status bytes after a latency anyhow */
- DIA_LOG(1, "exit with %d.\n", rv);
+ goto restart; /* ftdi chip returns two status bytes after a latency anyhow */
+
if (rv > 0)
- return rv - 2; /* account for 2 discarded bytes in a valid buffer */
+ return rv - 2; /* account for 2 discarded bytes in a valid buffer */
return rv;
}
@@ -1669,8 +1567,7 @@ static void skel_write_bulk_callback(struct urb *urb)
urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN))
dev_err(&dev->interface->dev,
- "%s - nonzero write bulk status received: %d\n",
- __func__, urb->status);
+ "nonzero write bulk status received: %d\n", urb->status);
spin_lock_irqsave(&dev->err_lock, flags);
dev->errors = urb->status;
@@ -1763,9 +1660,7 @@ static ssize_t skel_do_write(struct usb_skel *dev, const char *buffer, size_t co
retval = usb_submit_urb(urb, GFP_KERNEL);
mutex_unlock(&dev->io_mutex);
if (retval) {
- dev_err(&dev->interface->dev,
- "%s - failed submitting write urb, error %d\n",
- __func__, retval);
+ dev_err(&dev->interface->dev, "failed submitting write urb, error %d\n", retval);
goto error_unanchor;
}
@@ -1831,8 +1726,7 @@ static int skel_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&skel_driver, subminor);
if (!interface) {
- pr_err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
+ pr_err("can't find device for minor %d\n", subminor);
retval = -ENODEV;
goto exit;
}
@@ -1895,8 +1789,6 @@ static ssize_t skel_read(struct file *file, char __user *buffer, size_t count,
rv = skel_do_read(dev, buf, count);
- pr_alert("%s - return with %zu\n", __func__, rv);
-
if (rv > 0) {
if (copy_to_user(buffer, buf, rv)) {
kfree(buf);
@@ -2015,8 +1907,8 @@ static int skel_probe(struct usb_interface *interface,
/* let the world know */
device_path = kobject_get_path(&dev->udev->dev.kobj, GFP_KERNEL);
- pr_alert("%s:%s - New lpvo_usb_device -> bus: %d dev: %d path: %s\n", NAME, __func__,
- dev->udev->bus->busnum, dev->udev->devnum, device_path);
+ dev_dbg(&interface->dev, "New lpvo_usb_device -> bus: %d dev: %d path: %s\n",
+ dev->udev->bus->busnum, dev->udev->devnum, device_path);
kfree(device_path);
#if USER_DEVICE
@@ -2029,14 +1921,9 @@ static int skel_probe(struct usb_interface *interface,
usb_set_intfdata(interface, NULL);
goto error;
}
-
- /* let the user know what node this device is now attached to */
- dev_info(&interface->dev,
- "lpvo_usb_gpib device now attached to lpvo_raw%d",
- interface->minor);
#endif
- write_latency_timer(dev->udev); /* adjust the latency timer */
+ write_latency_timer(dev->udev); /* adjust the latency timer */
usb_gpib_init_module(interface); /* last, init the lpvo for this minor */
@@ -2073,8 +1960,6 @@ static void skel_disconnect(struct usb_interface *interface)
/* decrement our usage count */
kref_put(&dev->kref, skel_delete);
-
- dev_info(&interface->dev, "USB lpvo_raw #%d now disconnected", minor);
}
static void skel_draw_down(struct usb_skel *dev)
diff --git a/drivers/staging/gpib/nec7210/nec7210.c b/drivers/staging/gpib/nec7210/nec7210.c
index c9a837fad96e..846c0a3fa1dc 100644
--- a/drivers/staging/gpib/nec7210/nec7210.c
+++ b/drivers/staging/gpib/nec7210/nec7210.c
@@ -4,6 +4,8 @@
* copyright : (C) 2001, 2002 by Frank Mori Hess
***************************************************************************/
+#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "board.h"
#include <linux/ioport.h>
#include <linux/sched.h>
@@ -21,7 +23,7 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB library code for NEC uPD7210");
-int nec7210_enable_eos(gpib_board_t *board, struct nec7210_priv *priv, uint8_t eos_byte,
+int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, uint8_t eos_byte,
int compare_8_bits)
{
write_byte(priv, eos_byte, EOSR);
@@ -35,14 +37,14 @@ int nec7210_enable_eos(gpib_board_t *board, struct nec7210_priv *priv, uint8_t e
}
EXPORT_SYMBOL(nec7210_enable_eos);
-void nec7210_disable_eos(gpib_board_t *board, struct nec7210_priv *priv)
+void nec7210_disable_eos(struct gpib_board *board, struct nec7210_priv *priv)
{
priv->auxa_bits &= ~HR_REOS;
write_byte(priv, priv->auxa_bits, AUXMR);
}
EXPORT_SYMBOL(nec7210_disable_eos);
-int nec7210_parallel_poll(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *result)
+int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *result)
{
int ret;
@@ -62,14 +64,14 @@ int nec7210_parallel_poll(gpib_board_t *board, struct nec7210_priv *priv, uint8_
}
EXPORT_SYMBOL(nec7210_parallel_poll);
-void nec7210_parallel_poll_configure(gpib_board_t *board,
+void nec7210_parallel_poll_configure(struct gpib_board *board,
struct nec7210_priv *priv, unsigned int configuration)
{
write_byte(priv, PPR | configuration, AUXMR);
}
EXPORT_SYMBOL(nec7210_parallel_poll_configure);
-void nec7210_parallel_poll_response(gpib_board_t *board, struct nec7210_priv *priv, int ist)
+void nec7210_parallel_poll_response(struct gpib_board *board, struct nec7210_priv *priv, int ist)
{
if (ist)
write_byte(priv, AUX_SPPF, AUXMR);
@@ -83,7 +85,8 @@ EXPORT_SYMBOL(nec7210_parallel_poll_response);
* the 488.2 capability (for example with NI chips), or we need to implement the
* 488.2 set srv state machine in the driver (if that is even viable).
*/
-void nec7210_serial_poll_response(gpib_board_t *board, struct nec7210_priv *priv, uint8_t status)
+void nec7210_serial_poll_response(struct gpib_board *board,
+ struct nec7210_priv *priv, uint8_t status)
{
unsigned long flags;
@@ -100,13 +103,13 @@ void nec7210_serial_poll_response(gpib_board_t *board, struct nec7210_priv *priv
}
EXPORT_SYMBOL(nec7210_serial_poll_response);
-uint8_t nec7210_serial_poll_status(gpib_board_t *board, struct nec7210_priv *priv)
+uint8_t nec7210_serial_poll_status(struct gpib_board *board, struct nec7210_priv *priv)
{
return read_byte(priv, SPSR);
}
EXPORT_SYMBOL(nec7210_serial_poll_status);
-int nec7210_primary_address(const gpib_board_t *board, struct nec7210_priv *priv,
+int nec7210_primary_address(const struct gpib_board *board, struct nec7210_priv *priv,
unsigned int address)
{
// put primary address in address0
@@ -115,7 +118,7 @@ int nec7210_primary_address(const gpib_board_t *board, struct nec7210_priv *priv
}
EXPORT_SYMBOL(nec7210_primary_address);
-int nec7210_secondary_address(const gpib_board_t *board, struct nec7210_priv *priv,
+int nec7210_secondary_address(const struct gpib_board *board, struct nec7210_priv *priv,
unsigned int address, int enable)
{
if (enable) {
@@ -164,7 +167,7 @@ static void update_listener_state(struct nec7210_priv *priv, unsigned int addres
}
}
-unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_priv *priv)
+unsigned int nec7210_update_status_nolock(struct gpib_board *board, struct nec7210_priv *priv)
{
int address_status_bits;
u8 spoll_status;
@@ -198,7 +201,6 @@ unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_pr
priv->srq_pending = 0;
set_bit(SPOLL_NUM, &board->status);
}
-// dev_dbg(board->gpib_dev, "status 0x%x, state 0x%x\n", board->status, priv->state);
/* we rely on the interrupt handler to set the
* rest of the status bits
@@ -208,7 +210,7 @@ unsigned int nec7210_update_status_nolock(gpib_board_t *board, struct nec7210_pr
}
EXPORT_SYMBOL(nec7210_update_status_nolock);
-unsigned int nec7210_update_status(gpib_board_t *board, struct nec7210_priv *priv,
+unsigned int nec7210_update_status(struct gpib_board *board, struct nec7210_priv *priv,
unsigned int clear_mask)
{
unsigned long flags;
@@ -233,7 +235,7 @@ unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg,
}
EXPORT_SYMBOL(nec7210_set_reg_bits);
-void nec7210_set_handshake_mode(gpib_board_t *board, struct nec7210_priv *priv, int mode)
+void nec7210_set_handshake_mode(struct gpib_board *board, struct nec7210_priv *priv, int mode)
{
unsigned long flags;
@@ -249,7 +251,7 @@ void nec7210_set_handshake_mode(gpib_board_t *board, struct nec7210_priv *priv,
}
EXPORT_SYMBOL(nec7210_set_handshake_mode);
-uint8_t nec7210_read_data_in(gpib_board_t *board, struct nec7210_priv *priv, int *end)
+uint8_t nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end)
{
unsigned long flags;
u8 data;
@@ -267,7 +269,7 @@ uint8_t nec7210_read_data_in(gpib_board_t *board, struct nec7210_priv *priv, int
}
EXPORT_SYMBOL(nec7210_read_data_in);
-int nec7210_take_control(gpib_board_t *board, struct nec7210_priv *priv, int syncronous)
+int nec7210_take_control(struct gpib_board *board, struct nec7210_priv *priv, int syncronous)
{
int i;
const int timeout = 100;
@@ -294,7 +296,7 @@ int nec7210_take_control(gpib_board_t *board, struct nec7210_priv *priv, int syn
}
EXPORT_SYMBOL(nec7210_take_control);
-int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv)
+int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv)
{
int i;
const int timeout = 1000;
@@ -319,10 +321,8 @@ int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv)
if (adsr_bits & HR_NATN)
break;
}
- if (i == HZ) {
- pr_err("nec7210: error waiting for NATN\n");
+ if (i == HZ)
return -ETIMEDOUT;
- }
}
clear_bit(COMMAND_READY_BN, &priv->state);
@@ -330,7 +330,7 @@ int nec7210_go_to_standby(gpib_board_t *board, struct nec7210_priv *priv)
}
EXPORT_SYMBOL(nec7210_go_to_standby);
-void nec7210_request_system_control(gpib_board_t *board, struct nec7210_priv *priv,
+void nec7210_request_system_control(struct gpib_board *board, struct nec7210_priv *priv,
int request_control)
{
if (request_control == 0) {
@@ -341,7 +341,7 @@ void nec7210_request_system_control(gpib_board_t *board, struct nec7210_priv *pr
}
EXPORT_SYMBOL(nec7210_request_system_control);
-void nec7210_interface_clear(gpib_board_t *board, struct nec7210_priv *priv, int assert)
+void nec7210_interface_clear(struct gpib_board *board, struct nec7210_priv *priv, int assert)
{
if (assert)
write_byte(priv, AUX_SIFC, AUXMR);
@@ -350,7 +350,7 @@ void nec7210_interface_clear(gpib_board_t *board, struct nec7210_priv *priv, int
}
EXPORT_SYMBOL(nec7210_interface_clear);
-void nec7210_remote_enable(gpib_board_t *board, struct nec7210_priv *priv, int enable)
+void nec7210_remote_enable(struct gpib_board *board, struct nec7210_priv *priv, int enable)
{
if (enable)
write_byte(priv, AUX_SREN, AUXMR);
@@ -359,7 +359,7 @@ void nec7210_remote_enable(gpib_board_t *board, struct nec7210_priv *priv, int e
}
EXPORT_SYMBOL(nec7210_remote_enable);
-void nec7210_release_rfd_holdoff(gpib_board_t *board, struct nec7210_priv *priv)
+void nec7210_release_rfd_holdoff(struct gpib_board *board, struct nec7210_priv *priv)
{
unsigned long flags;
@@ -373,8 +373,8 @@ void nec7210_release_rfd_holdoff(gpib_board_t *board, struct nec7210_priv *priv)
}
EXPORT_SYMBOL(nec7210_release_rfd_holdoff);
-unsigned int nec7210_t1_delay(gpib_board_t *board, struct nec7210_priv *priv,
- unsigned int nano_sec)
+int nec7210_t1_delay(struct gpib_board *board, struct nec7210_priv *priv,
+ unsigned int nano_sec)
{
unsigned int retval;
@@ -391,13 +391,13 @@ unsigned int nec7210_t1_delay(gpib_board_t *board, struct nec7210_priv *priv,
}
EXPORT_SYMBOL(nec7210_t1_delay);
-void nec7210_return_to_local(const gpib_board_t *board, struct nec7210_priv *priv)
+void nec7210_return_to_local(const struct gpib_board *board, struct nec7210_priv *priv)
{
write_byte(priv, AUX_RTL, AUXMR);
}
EXPORT_SYMBOL(nec7210_return_to_local);
-static inline short nec7210_atn_has_changed(gpib_board_t *board, struct nec7210_priv *priv)
+static inline short nec7210_atn_has_changed(struct gpib_board *board, struct nec7210_priv *priv)
{
short address_status_bits = read_byte(priv, ADSR);
@@ -415,7 +415,7 @@ static inline short nec7210_atn_has_changed(gpib_board_t *board, struct nec7210_
return -1;
}
-int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t
+int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, uint8_t
*buffer, size_t length, size_t *bytes_written)
{
int retval = 0;
@@ -430,17 +430,14 @@ int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t
test_bit(COMMAND_READY_BN, &priv->state) ||
test_bit(BUS_ERROR_BN, &priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib command wait interrupted\n");
+ dev_dbg(board->gpib_dev, "command wait interrupted\n");
retval = -ERESTARTSYS;
break;
}
if (test_bit(TIMO_NUM, &board->status))
break;
- if (test_and_clear_bit(BUS_ERROR_BN, &priv->state)) {
- pr_err("nec7210: bus error on command byte\n");
+ if (test_and_clear_bit(BUS_ERROR_BN, &priv->state))
break;
- }
-
spin_lock_irqsave(&board->spinlock, flags);
clear_bit(COMMAND_READY_BN, &priv->state);
write_byte(priv, buffer[*bytes_written], CDOR);
@@ -454,24 +451,20 @@ int nec7210_command(gpib_board_t *board, struct nec7210_priv *priv, uint8_t
// wait for last byte to get sent
if (wait_event_interruptible(board->wait, test_bit(COMMAND_READY_BN, &priv->state) ||
test_bit(BUS_ERROR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib command wait interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- dev_dbg(board->gpib_dev, "gpib command timed out\n");
+
+ if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
- }
- if (test_and_clear_bit(BUS_ERROR_BN, &priv->state)) {
- pr_err("nec7210: bus error on command byte\n");
+
+ if (test_and_clear_bit(BUS_ERROR_BN, &priv->state))
retval = -EIO;
- }
return retval;
}
EXPORT_SYMBOL(nec7210_command);
-static int pio_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+static int pio_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
ssize_t retval = 0;
@@ -484,7 +477,6 @@ static int pio_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buf
test_bit(READ_READY_BN, &priv->state) ||
test_bit(DEV_CLEAR_BN, &priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "nec7210: pio read wait interrupted\n");
retval = -ERESTARTSYS;
break;
}
@@ -503,12 +495,10 @@ static int pio_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buf
break;
}
if (test_bit(TIMO_NUM, &board->status)) {
- dev_dbg(board->gpib_dev, "interrupted by timeout\n");
retval = -ETIMEDOUT;
break;
}
if (test_bit(DEV_CLEAR_BN, &priv->state)) {
- dev_dbg(board->gpib_dev, "interrupted by device clear\n");
retval = -EINTR;
break;
}
@@ -523,7 +513,7 @@ static int pio_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buf
}
#ifdef NEC_DMA
-static ssize_t __dma_read(gpib_board_t *board, struct nec7210_priv *priv, size_t length)
+static ssize_t __dma_read(struct gpib_board *board, struct nec7210_priv *priv, size_t length)
{
ssize_t retval = 0;
size_t count = 0;
@@ -557,10 +547,9 @@ static ssize_t __dma_read(gpib_board_t *board, struct nec7210_priv *priv, size_t
if (wait_event_interruptible(board->wait,
test_bit(DMA_READ_IN_PROGRESS_BN, &priv->state) == 0 ||
test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "nec7210: dma read wait interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_bit(DEV_CLEAR_BN, &priv->state))
@@ -579,7 +568,7 @@ static ssize_t __dma_read(gpib_board_t *board, struct nec7210_priv *priv, size_t
return retval ? retval : count;
}
-static ssize_t dma_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+static ssize_t dma_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length)
{
size_t remain = length;
@@ -606,7 +595,7 @@ static ssize_t dma_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t
}
#endif
-int nec7210_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
ssize_t retval = 0;
@@ -627,7 +616,7 @@ int nec7210_read(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer
}
EXPORT_SYMBOL(nec7210_read);
-static int pio_write_wait(gpib_board_t *board, struct nec7210_priv *priv,
+static int pio_write_wait(struct gpib_board *board, struct nec7210_priv *priv,
short wake_on_lacs, short wake_on_atn, short wake_on_bus_error)
{
// wait until byte is ready to be sent
@@ -638,26 +627,22 @@ static int pio_write_wait(gpib_board_t *board, struct nec7210_priv *priv,
(wake_on_bus_error && test_bit(BUS_ERROR_BN, &priv->state)) ||
(wake_on_lacs && test_bit(LACS_NUM, &board->status)) ||
(wake_on_atn && test_bit(ATN_NUM, &board->status)) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
return -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- dev_dbg(board->gpib_dev, "nec7210: write timed out\n");
+
+ if (test_bit(TIMO_NUM, &board->status))
return -ETIMEDOUT;
- }
- if (test_bit(DEV_CLEAR_BN, &priv->state)) {
- dev_dbg(board->gpib_dev, "nec7210: write interrupted by clear\n");
+
+ if (test_bit(DEV_CLEAR_BN, &priv->state))
return -EINTR;
- }
- if (wake_on_bus_error && test_and_clear_bit(BUS_ERROR_BN, &priv->state)) {
- dev_dbg(board->gpib_dev, "nec7210: bus error on write\n");
+
+ if (wake_on_bus_error && test_and_clear_bit(BUS_ERROR_BN, &priv->state))
return -EIO;
- }
+
return 0;
}
-static int pio_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+static int pio_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length, size_t *bytes_written)
{
size_t last_count = 0;
@@ -677,7 +662,6 @@ static int pio_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *bu
if (retval == -EIO) {
/* resend last byte on bus error */
*bytes_written = last_count;
- dev_dbg(board->gpib_dev, "resending %c\n", buffer[*bytes_written]);
/* we can get unrecoverable bus errors,
* so give up after a while
*/
@@ -701,7 +685,7 @@ static int pio_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *bu
}
#ifdef NEC_DMA
-static ssize_t __dma_write(gpib_board_t *board, struct nec7210_priv *priv, dma_addr_t address,
+static ssize_t __dma_write(struct gpib_board *board, struct nec7210_priv *priv, dma_addr_t address,
size_t length)
{
unsigned long flags, dma_irq_flags;
@@ -733,10 +717,9 @@ static ssize_t __dma_write(gpib_board_t *board, struct nec7210_priv *priv, dma_a
test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state) == 0 ||
test_bit(BUS_ERROR_BN, &priv->state) ||
test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted!\n");
+ test_bit(TIMO_NUM, &board->status)))
retval = -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
retval = -ETIMEDOUT;
if (test_and_clear_bit(DEV_CLEAR_BN, &priv->state))
@@ -759,7 +742,7 @@ static ssize_t __dma_write(gpib_board_t *board, struct nec7210_priv *priv, dma_a
return retval ? retval : length;
}
-static ssize_t dma_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer,
+static ssize_t dma_write(struct gpib_board *board, struct nec7210_priv *priv, uint8_t *buffer,
size_t length)
{
size_t remain = length;
@@ -783,8 +766,9 @@ static ssize_t dma_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t
return length - remain;
}
#endif
-int nec7210_write(gpib_board_t *board, struct nec7210_priv *priv, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
+int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv,
+ uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written)
{
int retval = 0;
@@ -845,7 +829,7 @@ EXPORT_SYMBOL(nec7210_write);
/*
* interrupt service routine
*/
-irqreturn_t nec7210_interrupt(gpib_board_t *board, struct nec7210_priv *priv)
+irqreturn_t nec7210_interrupt(struct gpib_board *board, struct nec7210_priv *priv)
{
int status1, status2;
@@ -857,7 +841,7 @@ irqreturn_t nec7210_interrupt(gpib_board_t *board, struct nec7210_priv *priv)
}
EXPORT_SYMBOL(nec7210_interrupt);
-irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board,
+irqreturn_t nec7210_interrupt_have_status(struct gpib_board *board,
struct nec7210_priv *priv, int status1, int status2)
{
#ifdef NEC_DMA
@@ -937,13 +921,8 @@ irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board,
set_bit(COMMAND_READY_BN, &priv->state);
// command pass through received
- if (status1 & HR_CPT) {
- unsigned int command;
-
- command = read_byte(priv, CPTR) & gpib_command_mask;
+ if (status1 & HR_CPT)
write_byte(priv, AUX_NVAL, AUXMR);
-// printk("gpib: command pass through 0x%x\n", command);
- }
if (status1 & HR_ERR)
set_bit(BUS_ERROR_BN, &priv->state);
@@ -980,7 +959,7 @@ irqreturn_t nec7210_interrupt_have_status(gpib_board_t *board,
}
EXPORT_SYMBOL(nec7210_interrupt_have_status);
-void nec7210_board_reset(struct nec7210_priv *priv, const gpib_board_t *board)
+void nec7210_board_reset(struct nec7210_priv *priv, const struct gpib_board *board)
{
/* 7210 chip reset */
write_byte(priv, AUX_CR, AUXMR);
@@ -1014,7 +993,7 @@ void nec7210_board_reset(struct nec7210_priv *priv, const gpib_board_t *board)
}
EXPORT_SYMBOL(nec7210_board_reset);
-void nec7210_board_online(struct nec7210_priv *priv, const gpib_board_t *board)
+void nec7210_board_online(struct nec7210_priv *priv, const struct gpib_board *board)
{
/* set GPIB address */
nec7210_primary_address(board, priv, board->pad);
diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c
index d0656dc520f5..9f1b9927f025 100644
--- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c
+++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c
@@ -5,6 +5,10 @@
* copyright : (C) 2004 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -20,7 +24,7 @@ MODULE_DESCRIPTION("GPIB driver for National Instruments USB devices");
static struct usb_interface *ni_usb_driver_interfaces[MAX_NUM_NI_USB_INTERFACES];
static int ni_usb_parse_status_block(const u8 *buffer, struct ni_usb_status_block *status);
-static int ni_usb_set_interrupt_monitor(gpib_board_t *board, unsigned int monitored_bits);
+static int ni_usb_set_interrupt_monitor(struct gpib_board *board, unsigned int monitored_bits);
static void ni_usb_stop(struct ni_usb_priv *ni_priv);
static DEFINE_MUTEX(ni_usb_hotplug_lock);
@@ -75,7 +79,7 @@ static unsigned short ni_usb_timeout_code(unsigned int usec)
*/
else if (usec <= 1000000000)
return 0x02;
- pr_err("%s: bug? usec is greater than 1e9\n", __func__);
+ pr_err("bug? usec is greater than 1e9\n");
return 0xf0;
}
@@ -83,8 +87,6 @@ static void ni_usb_bulk_complete(struct urb *urb)
{
struct ni_usb_urb_ctx *context = urb->context;
-// printk("debug: %s: status=0x%x, error_count=%i, actual_length=%i\n", __func__,
-// urb->status, urb->error_count, urb->actual_length);
complete(&context->complete);
}
@@ -134,11 +136,11 @@ static int ni_usb_nonblocking_send_bulk_msg(struct ni_usb_priv *ni_priv, void *d
retval = usb_submit_urb(ni_priv->bulk_urb, GFP_KERNEL);
if (retval) {
- del_timer_sync(&ni_priv->bulk_timer);
+ timer_delete_sync(&ni_priv->bulk_timer);
usb_free_urb(ni_priv->bulk_urb);
ni_priv->bulk_urb = NULL;
- dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to submit bulk out urb, retval=%i\n",
+ retval);
mutex_unlock(&ni_priv->bulk_transfer_lock);
return retval;
}
@@ -146,13 +148,13 @@ static int ni_usb_nonblocking_send_bulk_msg(struct ni_usb_priv *ni_priv, void *d
wait_for_completion(&context->complete); // wait for ni_usb_bulk_complete
if (context->timed_out) {
usb_kill_urb(ni_priv->bulk_urb);
- dev_err(&usb_dev->dev, "%s: killed urb due to timeout\n", __func__);
+ dev_err(&usb_dev->dev, "killed urb due to timeout\n");
retval = -ETIMEDOUT;
} else {
retval = ni_priv->bulk_urb->status;
}
- del_timer_sync(&ni_priv->bulk_timer);
+ timer_delete_sync(&ni_priv->bulk_timer);
*actual_data_length = ni_priv->bulk_urb->actual_length;
mutex_lock(&ni_priv->bulk_transfer_lock);
usb_free_urb(ni_priv->bulk_urb);
@@ -218,14 +220,12 @@ static int ni_usb_nonblocking_receive_bulk_msg(struct ni_usb_priv *ni_priv,
if (timeout_msecs)
mod_timer(&ni_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
- //printk("%s: submitting urb\n", __func__);
retval = usb_submit_urb(ni_priv->bulk_urb, GFP_KERNEL);
if (retval) {
- del_timer_sync(&ni_priv->bulk_timer);
+ timer_delete_sync(&ni_priv->bulk_timer);
usb_free_urb(ni_priv->bulk_urb);
ni_priv->bulk_urb = NULL;
- dev_err(&usb_dev->dev, "%s: failed to submit bulk out urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to submit bulk in urb, retval=%i\n", retval);
mutex_unlock(&ni_priv->bulk_transfer_lock);
return retval;
}
@@ -250,13 +250,13 @@ static int ni_usb_nonblocking_receive_bulk_msg(struct ni_usb_priv *ni_priv,
}
if (context->timed_out) {
usb_kill_urb(ni_priv->bulk_urb);
- dev_err(&usb_dev->dev, "%s: killed urb due to timeout\n", __func__);
+ dev_err(&usb_dev->dev, "killed urb due to timeout\n");
retval = -ETIMEDOUT;
} else {
if (ni_priv->bulk_urb->status)
retval = ni_priv->bulk_urb->status;
}
- del_timer_sync(&ni_priv->bulk_timer);
+ timer_delete_sync(&ni_priv->bulk_timer);
*actual_data_length = ni_priv->bulk_urb->actual_length;
mutex_lock(&ni_priv->bulk_transfer_lock);
usb_free_urb(ni_priv->bulk_urb);
@@ -310,7 +310,7 @@ static int ni_usb_receive_control_msg(struct ni_usb_priv *ni_priv, __u8 request,
return retval;
}
-static void ni_usb_soft_update_status(gpib_board_t *board, unsigned int ni_usb_ibsta,
+static void ni_usb_soft_update_status(struct gpib_board *board, unsigned int ni_usb_ibsta,
unsigned int clear_mask)
{
static const unsigned int ni_usb_ibsta_mask = SRQI | ATN | CIC | REM | LACS | TACS | LOK;
@@ -330,14 +330,14 @@ static void ni_usb_soft_update_status(gpib_board_t *board, unsigned int ni_usb_i
ni_priv->monitored_ibsta_bits &= ~ni_usb_ibsta;
need_monitoring_bits &= ~ni_priv->monitored_ibsta_bits; /* mm - monitored set */
spin_unlock_irqrestore(&board->spinlock, flags);
- dev_dbg(&usb_dev->dev, "%s: need_monitoring_bits=0x%x\n", __func__, need_monitoring_bits);
+ dev_dbg(&usb_dev->dev, "need_monitoring_bits=0x%x\n", need_monitoring_bits);
if (need_monitoring_bits & ~ni_usb_ibsta)
ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask);
else if (need_monitoring_bits & ni_usb_ibsta)
wake_up_interruptible(&board->wait);
- dev_dbg(&usb_dev->dev, "%s: ni_usb_ibsta=0x%x\n", __func__, ni_usb_ibsta);
+ dev_dbg(&usb_dev->dev, "ibsta=0x%x\n", ni_usb_ibsta);
}
static int ni_usb_parse_status_block(const u8 *buffer, struct ni_usb_status_block *status)
@@ -371,7 +371,7 @@ static int ni_usb_parse_register_read_block(const u8 *raw_data, unsigned int *re
int k;
if (raw_data[i++] != NIUSB_REGISTER_READ_DATA_START_ID) {
- pr_err("%s: parse error: wrong start id\n", __func__);
+ pr_err("parse error: wrong start id\n");
unexpected = 1;
}
for (k = 0; k < results_per_chunk && j < num_results; ++k)
@@ -380,18 +380,18 @@ static int ni_usb_parse_register_read_block(const u8 *raw_data, unsigned int *re
while (i % 4)
i++;
if (raw_data[i++] != NIUSB_REGISTER_READ_DATA_END_ID) {
- pr_err("%s: parse error: wrong end id\n", __func__);
+ pr_err("parse error: wrong end id\n");
unexpected = 1;
}
if (raw_data[i++] % results_per_chunk != num_results % results_per_chunk) {
- pr_err("%s: parse error: wrong count=%i for NIUSB_REGISTER_READ_DATA_END\n",
- __func__, (int)raw_data[i - 1]);
+ pr_err("parse error: wrong count=%i for NIUSB_REGISTER_READ_DATA_END\n",
+ (int)raw_data[i - 1]);
unexpected = 1;
}
while (i % 4) {
if (raw_data[i++] != 0) {
- pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n",
- __func__, i - 1, (int)raw_data[i - 1]);
+ pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
+ i - 1, (int)raw_data[i - 1]);
unexpected = 1;
}
}
@@ -408,9 +408,8 @@ static int ni_usb_parse_termination_block(const u8 *buffer)
buffer[i++] != 0x0 ||
buffer[i++] != 0x0 ||
buffer[i++] != 0x0) {
- pr_err("%s: received unexpected termination block\n", __func__);
- pr_err(" expected: 0x%x 0x%x 0x%x 0x%x\n",
- NIUSB_TERM_ID, 0x0, 0x0, 0x0);
+ pr_err("received unexpected termination block\n");
+ pr_err(" expected: 0x%x 0x%x 0x%x 0x%x\n", NIUSB_TERM_ID, 0x0, 0x0, 0x0);
pr_err(" received: 0x%x 0x%x 0x%x 0x%x\n",
buffer[i - 4], buffer[i - 3], buffer[i - 2], buffer[i - 1]);
}
@@ -427,7 +426,6 @@ static int parse_board_ibrd_readback(const u8 *raw_data, struct ni_usb_status_bl
int i = 0;
int j = 0;
int k;
- unsigned int adr1_bits;
int num_data_blocks = 0;
struct ni_usb_status_block register_write_status;
int unexpected = 0;
@@ -438,12 +436,12 @@ static int parse_board_ibrd_readback(const u8 *raw_data, struct ni_usb_status_bl
} else if (raw_data[i] == NIUSB_IBRD_EXTENDED_DATA_ID) {
data_block_length = ibrd_extended_data_block_length;
if (raw_data[++i] != 0) {
- pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n",
- __func__, i, (int)raw_data[i]);
+ pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
+ i, (int)raw_data[i]);
unexpected = 1;
}
} else {
- pr_err("%s: logic bug!\n", __func__);
+ pr_err("Unexpected NIUSB_IBRD ID\n");
return -EINVAL;
}
++i;
@@ -457,10 +455,10 @@ static int parse_board_ibrd_readback(const u8 *raw_data, struct ni_usb_status_bl
}
i += ni_usb_parse_status_block(&raw_data[i], status);
if (status->id != NIUSB_IBRD_STATUS_ID) {
- pr_err("%s: bug: status->id=%i, != ibrd_status_id\n", __func__, status->id);
+ pr_err("bug: status->id=%i, != ibrd_status_id\n", status->id);
return -EIO;
}
- adr1_bits = raw_data[i++];
+ i++;
if (num_data_blocks) {
*actual_bytes_read = (num_data_blocks - 1) * data_block_length + raw_data[i++];
} else {
@@ -468,29 +466,28 @@ static int parse_board_ibrd_readback(const u8 *raw_data, struct ni_usb_status_bl
*actual_bytes_read = 0;
}
if (*actual_bytes_read > j)
- pr_err("%s: bug: discarded data. actual_bytes_read=%i, j=%i\n",
- __func__, *actual_bytes_read, j);
+ pr_err("bug: discarded data. actual_bytes_read=%i, j=%i\n", *actual_bytes_read, j);
for (k = 0; k < 2; k++)
if (raw_data[i++] != 0) {
- pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n",
- __func__, i - 1, (int)raw_data[i - 1]);
+ pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
+ i - 1, (int)raw_data[i - 1]);
unexpected = 1;
}
i += ni_usb_parse_status_block(&raw_data[i], &register_write_status);
if (register_write_status.id != NIUSB_REG_WRITE_ID) {
- pr_err("%s: unexpected data: register write status id=0x%x, expected 0x%x\n",
- __func__, register_write_status.id, NIUSB_REG_WRITE_ID);
+ pr_err("unexpected data: register write status id=0x%x, expected 0x%x\n",
+ register_write_status.id, NIUSB_REG_WRITE_ID);
unexpected = 1;
}
if (raw_data[i++] != 2) {
- pr_err("%s: unexpected data: register write count=%i, expected 2\n",
- __func__, (int)raw_data[i - 1]);
+ pr_err("unexpected data: register write count=%i, expected 2\n",
+ (int)raw_data[i - 1]);
unexpected = 1;
}
for (k = 0; k < 3; k++)
if (raw_data[i++] != 0) {
- pr_err("%s: unexpected data: raw_data[%i]=0x%x, expected 0\n",
- __func__, i - 1, (int)raw_data[i - 1]);
+ pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
+ i - 1, (int)raw_data[i - 1]);
unexpected = 1;
}
i += ni_usb_parse_termination_block(&raw_data[i]);
@@ -530,18 +527,14 @@ static int ni_usb_write_registers(struct ni_usb_priv *ni_priv,
out_data_length = num_writes * bytes_per_write + 0x10;
out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data) {
- dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__);
+ if (!out_data)
return -ENOMEM;
- }
i += ni_usb_bulk_register_write_header(&out_data[i], num_writes);
for (j = 0; j < num_writes; j++)
i += ni_usb_bulk_register_write(&out_data[i], writes[j]);
while (i % 4)
out_data[i++] = 0x00;
i += ni_usb_bulk_termination(&out_data[i]);
- if (i > out_data_length)
- dev_err(&usb_dev->dev, "%s: bug! buffer overrun\n", __func__);
mutex_lock(&ni_priv->addressed_transfer_lock);
@@ -549,22 +542,21 @@ static int ni_usb_write_registers(struct ni_usb_priv *ni_priv,
kfree(out_data);
if (retval) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return retval;
}
in_data = kmalloc(in_data_length, GFP_KERNEL);
if (!in_data) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__);
return -ENOMEM;
}
retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
if (retval || bytes_read != 16) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
ni_usb_dump_raw_block(in_data, bytes_read);
kfree(in_data);
return retval;
@@ -576,18 +568,16 @@ static int ni_usb_write_registers(struct ni_usb_priv *ni_priv,
//FIXME parse extra 09 status bits and termination
kfree(in_data);
if (status.id != NIUSB_REG_WRITE_ID) {
- dev_err(&usb_dev->dev, "%s: parse error, id=0x%x != NIUSB_REG_WRITE_ID\n",
- __func__, status.id);
+ dev_err(&usb_dev->dev, "parse error, id=0x%x != NIUSB_REG_WRITE_ID\n", status.id);
return -EIO;
}
if (status.error_code) {
- dev_err(&usb_dev->dev, "%s: nonzero error code 0x%x\n",
- __func__, status.error_code);
+ dev_err(&usb_dev->dev, "nonzero error code 0x%x\n", status.error_code);
return -EIO;
}
if (reg_writes_completed != num_writes) {
- dev_err(&usb_dev->dev, "%s: reg_writes_completed=%i, num_writes=%i\n",
- __func__, reg_writes_completed, num_writes);
+ dev_err(&usb_dev->dev, "reg_writes_completed=%i, num_writes=%i\n",
+ reg_writes_completed, num_writes);
return -EIO;
}
if (ibsta)
@@ -596,12 +586,12 @@ static int ni_usb_write_registers(struct ni_usb_priv *ni_priv,
}
// interface functions
-static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int ni_usb_read(struct gpib_board *board, uint8_t *buffer, size_t length,
int *end, size_t *bytes_read)
{
int retval, parse_retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
static const int out_data_length = 0x20;
int in_data_length;
@@ -614,10 +604,11 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
struct ni_usb_register reg;
*bytes_read = 0;
- if (length > max_read_length) {
- length = max_read_length;
- dev_err(&usb_dev->dev, "%s: read length too long\n", __func__);
- }
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ if (length > max_read_length)
+ return -EINVAL;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
return -ENOMEM;
@@ -649,8 +640,8 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
if (retval || usb_bytes_written != i) {
if (retval == 0)
retval = -EIO;
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n",
- __func__, retval, usb_bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n",
+ retval, usb_bytes_written, i);
mutex_unlock(&ni_priv->addressed_transfer_lock);
return retval;
}
@@ -668,8 +659,8 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
if (retval == -ERESTARTSYS) {
} else if (retval) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, usb_bytes_read=%i\n",
- __func__, retval, usb_bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, usb_bytes_read=%i\n",
+ retval, usb_bytes_read);
kfree(in_data);
return retval;
}
@@ -677,14 +668,14 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
if (parse_retval != usb_bytes_read) {
if (parse_retval >= 0)
parse_retval = -EIO;
- dev_err(&usb_dev->dev, "%s: retval=%i usb_bytes_read=%i\n",
- __func__, parse_retval, usb_bytes_read);
+ dev_err(&usb_dev->dev, "retval=%i usb_bytes_read=%i\n",
+ parse_retval, usb_bytes_read);
kfree(in_data);
return parse_retval;
}
if (actual_length != length - status.count) {
- dev_err(&usb_dev->dev, "%s: actual_length=%i expected=%li\n",
- __func__, actual_length, (long)(length - status.count));
+ dev_err(&usb_dev->dev, "actual_length=%i expected=%li\n",
+ actual_length, (long)(length - status.count));
ni_usb_dump_raw_block(in_data, usb_bytes_read);
}
kfree(in_data);
@@ -699,7 +690,7 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
break;
case NIUSB_ATN_STATE_ERROR:
retval = -EIO;
- dev_err(&usb_dev->dev, "%s: read when ATN set\n", __func__);
+ dev_err(&usb_dev->dev, "read when ATN set\n");
break;
case NIUSB_ADDRESSING_ERROR:
retval = -EIO;
@@ -708,12 +699,11 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
retval = -ETIMEDOUT;
break;
case NIUSB_EOSMODE_ERROR:
- dev_err(&usb_dev->dev, "%s: driver bug, we should have been able to avoid NIUSB_EOSMODE_ERROR.\n",
- __func__);
+ dev_err(&usb_dev->dev, "driver bug, we should have been able to avoid NIUSB_EOSMODE_ERROR.\n");
retval = -EINVAL;
break;
default:
- dev_err(&usb_dev->dev, "%s: unknown error code=%i\n", __func__, status.error_code);
+ dev_err(&usb_dev->dev, "unknown error code=%i\n", status.error_code);
retval = -EIO;
break;
}
@@ -726,12 +716,12 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,
return retval;
}
-static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int ni_usb_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
int out_data_length;
static const int in_data_length = 0x10;
@@ -741,12 +731,11 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
struct ni_usb_status_block status;
static const int max_write_length = 0xffff;
- *bytes_written = 0;
- if (length > max_write_length) {
- length = max_write_length;
- send_eoi = 0;
- dev_err(&usb_dev->dev, "%s: write length too long\n", __func__);
- }
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ if (length > max_write_length)
+ return -EINVAL;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data_length = length + 0x10;
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
@@ -777,8 +766,8 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
kfree(out_data);
if (retval || usb_bytes_written != i) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n",
- __func__, retval, usb_bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n",
+ retval, usb_bytes_written, i);
return retval;
}
@@ -793,8 +782,8 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
mutex_unlock(&ni_priv->addressed_transfer_lock);
if ((retval && retval != -ERESTARTSYS) || usb_bytes_read != 12) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, usb_bytes_read=%i\n",
- __func__, retval, usb_bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, usb_bytes_read=%i\n",
+ retval, usb_bytes_read);
kfree(in_data);
return retval;
}
@@ -810,8 +799,8 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
*/
break;
case NIUSB_ADDRESSING_ERROR:
- dev_err(&usb_dev->dev, "%s: Addressing error retval %d error code=%i\n",
- __func__, retval, status.error_code);
+ dev_err(&usb_dev->dev, "Addressing error retval %d error code=%i\n",
+ retval, status.error_code);
retval = -ENXIO;
break;
case NIUSB_NO_LISTENER_ERROR:
@@ -821,8 +810,7 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
retval = -ETIMEDOUT;
break;
default:
- dev_err(&usb_dev->dev, "%s: unknown error code=%i\n",
- __func__, status.error_code);
+ dev_err(&usb_dev->dev, "unknown error code=%i\n", status.error_code);
retval = -EPIPE;
break;
}
@@ -831,12 +819,12 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,
return retval;
}
-static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int ni_usb_command_chunk(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *command_bytes_written)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
int out_data_length;
static const int in_data_length = 0x10;
@@ -848,8 +836,11 @@ static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t len
static const int max_command_length = 0x10;
*command_bytes_written = 0;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
if (length > max_command_length)
length = max_command_length;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data_length = length + 0x10;
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
@@ -873,8 +864,8 @@ static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t len
kfree(out_data);
if (retval || bytes_written != i) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return retval;
}
@@ -890,8 +881,8 @@ static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t len
mutex_unlock(&ni_priv->addressed_transfer_lock);
if ((retval && retval != -ERESTARTSYS) || bytes_read != 12) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
kfree(in_data);
return retval;
}
@@ -909,19 +900,19 @@ static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t len
case NIUSB_NO_BUS_ERROR:
return -ENOTCONN;
case NIUSB_EOSMODE_ERROR:
- dev_err(&usb_dev->dev, "%s: got eosmode error. Driver bug?\n", __func__);
+ dev_err(&usb_dev->dev, "got eosmode error. Driver bug?\n");
return -EIO;
case NIUSB_TIMEOUT_ERROR:
return -ETIMEDOUT;
default:
- dev_err(&usb_dev->dev, "%s: unknown error code=%i\n", __func__, status.error_code);
+ dev_err(&usb_dev->dev, "unknown error code=%i\n", status.error_code);
return -EIO;
}
ni_usb_soft_update_status(board, status.ibsta, 0);
return 0;
}
-static int ni_usb_command(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int ni_usb_command(struct gpib_board *board, uint8_t *buffer, size_t length,
size_t *bytes_written)
{
size_t count;
@@ -938,11 +929,11 @@ static int ni_usb_command(gpib_board_t *board, uint8_t *buffer, size_t length,
return 0;
}
-static int ni_usb_take_control(gpib_board_t *board, int synchronous)
+static int ni_usb_take_control(struct gpib_board *board, int synchronous)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
static const int out_data_length = 0x10;
static const int in_data_length = 0x10;
@@ -950,6 +941,9 @@ static int ni_usb_take_control(gpib_board_t *board, int synchronous)
int i = 0;
struct ni_usb_status_block status;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
return -ENOMEM;
@@ -968,15 +962,14 @@ static int ni_usb_take_control(gpib_board_t *board, int synchronous)
kfree(out_data);
if (retval || bytes_written != i) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return retval;
}
in_data = kmalloc(in_data_length, GFP_KERNEL);
if (!in_data) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__);
return -ENOMEM;
}
retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 1);
@@ -986,8 +979,8 @@ static int ni_usb_take_control(gpib_board_t *board, int synchronous)
if ((retval && retval != -ERESTARTSYS) || bytes_read != 12) {
if (retval == 0)
retval = -EIO;
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
kfree(in_data);
return retval;
}
@@ -997,11 +990,11 @@ static int ni_usb_take_control(gpib_board_t *board, int synchronous)
return retval;
}
-static int ni_usb_go_to_standby(gpib_board_t *board)
+static int ni_usb_go_to_standby(struct gpib_board *board)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
static const int out_data_length = 0x10;
static const int in_data_length = 0x20;
@@ -1009,6 +1002,9 @@ static int ni_usb_go_to_standby(gpib_board_t *board)
int i = 0;
struct ni_usb_status_block status;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
return -ENOMEM;
@@ -1025,15 +1021,14 @@ static int ni_usb_go_to_standby(gpib_board_t *board)
kfree(out_data);
if (retval || bytes_written != i) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return retval;
}
in_data = kmalloc(in_data_length, GFP_KERNEL);
if (!in_data) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__);
return -ENOMEM;
}
retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
@@ -1041,29 +1036,31 @@ static int ni_usb_go_to_standby(gpib_board_t *board)
mutex_unlock(&ni_priv->addressed_transfer_lock);
if (retval || bytes_read != 12) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
kfree(in_data);
return retval;
}
ni_usb_parse_status_block(in_data, &status);
kfree(in_data);
if (status.id != NIUSB_IBGTS_ID)
- dev_err(&usb_dev->dev, "%s: bug: status.id 0x%x != INUSB_IBGTS_ID\n",
- __func__, status.id);
+ dev_err(&usb_dev->dev, "bug: status.id 0x%x != INUSB_IBGTS_ID\n", status.id);
ni_usb_soft_update_status(board, status.ibsta, 0);
return 0;
}
-static void ni_usb_request_system_control(gpib_board_t *board, int request_control)
+static void ni_usb_request_system_control(struct gpib_board *board, int request_control)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[4];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
if (request_control) {
writes[i].device = NIUSB_SUBDEV_TNT4882;
writes[i].address = CMDR;
@@ -1093,7 +1090,7 @@ static void ni_usb_request_system_control(gpib_board_t *board, int request_contr
}
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return; // retval;
}
if (!request_control)
@@ -1103,11 +1100,11 @@ static void ni_usb_request_system_control(gpib_board_t *board, int request_contr
}
//FIXME maybe the interface should have a "pulse interface clear" function that can return an error?
-static void ni_usb_interface_clear(gpib_board_t *board, int assert)
+static void ni_usb_interface_clear(struct gpib_board *board, int assert)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
static const int out_data_length = 0x10;
static const int in_data_length = 0x10;
@@ -1115,14 +1112,15 @@ static void ni_usb_interface_clear(gpib_board_t *board, int assert)
int i = 0;
struct ni_usb_status_block status;
- // FIXME: we are going to pulse when assert is true, and ignore otherwise
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+// FIXME: we are going to pulse when assert is true, and ignore otherwise
if (assert == 0)
return;
out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data) {
- dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__);
+ if (!out_data)
return;
- }
out_data[i++] = NIUSB_IBSIC_ID;
out_data[i++] = 0x0;
out_data[i++] = 0x0;
@@ -1131,8 +1129,8 @@ static void ni_usb_interface_clear(gpib_board_t *board, int assert)
retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
kfree(out_data);
if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return;
}
in_data = kmalloc(in_data_length, GFP_KERNEL);
@@ -1141,8 +1139,8 @@ static void ni_usb_interface_clear(gpib_board_t *board, int assert)
retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
if (retval || bytes_read != 12) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
kfree(in_data);
return;
}
@@ -1151,14 +1149,17 @@ static void ni_usb_interface_clear(gpib_board_t *board, int assert)
ni_usb_soft_update_status(board, status.ibsta, 0);
}
-static void ni_usb_remote_enable(gpib_board_t *board, int enable)
+static void ni_usb_remote_enable(struct gpib_board *board, int enable)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
struct ni_usb_register reg;
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
reg.device = NIUSB_SUBDEV_TNT4882;
reg.address = nec7210_to_tnt4882_offset(AUXMR);
if (enable)
@@ -1167,7 +1168,7 @@ static void ni_usb_remote_enable(gpib_board_t *board, int enable)
reg.value = AUX_CREN;
retval = ni_usb_write_registers(ni_priv, &reg, 1, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return; //retval;
}
ni_priv->ren_state = enable;
@@ -1175,7 +1176,7 @@ static void ni_usb_remote_enable(gpib_board_t *board, int enable)
return;// 0;
}
-static int ni_usb_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int ni_usb_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct ni_usb_priv *ni_priv = board->private_data;
@@ -1188,7 +1189,7 @@ static int ni_usb_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_
return 0;
}
-static void ni_usb_disable_eos(gpib_board_t *board)
+static void ni_usb_disable_eos(struct gpib_board *board)
{
struct ni_usb_priv *ni_priv = board->private_data;
/* adapter gets unhappy if you don't zero all the bits
@@ -1198,16 +1199,18 @@ static void ni_usb_disable_eos(gpib_board_t *board)
ni_priv->eos_char = 0;
}
-static unsigned int ni_usb_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int ni_usb_update_status(struct gpib_board *board, unsigned int clear_mask)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
static const int buffer_length = 8;
u8 *buffer;
struct ni_usb_status_block status;
- //printk("%s: receive control pipe is %i\n", __func__, pipe);
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
buffer = kmalloc(buffer_length, GFP_KERNEL);
if (!buffer)
return board->status;
@@ -1216,7 +1219,7 @@ static unsigned int ni_usb_update_status(gpib_board_t *board, unsigned int clear
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x200, 0x0, buffer, buffer_length, 1000);
if (retval != buffer_length) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg returned %i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg returned %i\n", retval);
kfree(buffer);
return board->status;
}
@@ -1235,7 +1238,6 @@ static void ni_usb_stop(struct ni_usb_priv *ni_priv)
u8 *buffer;
struct ni_usb_status_block status;
- //printk("%s: receive control pipe is %i\n", __func__, pipe);
buffer = kmalloc(buffer_length, GFP_KERNEL);
if (!buffer)
return;
@@ -1244,7 +1246,7 @@ static void ni_usb_stop(struct ni_usb_priv *ni_priv)
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0, 0x0, buffer, buffer_length, 1000);
if (retval != buffer_length) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg returned %i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg returned %i\n", retval);
kfree(buffer);
return;
}
@@ -1252,15 +1254,18 @@ static void ni_usb_stop(struct ni_usb_priv *ni_priv)
kfree(buffer);
}
-static int ni_usb_primary_address(gpib_board_t *board, unsigned int address)
+static int ni_usb_primary_address(struct gpib_board *board, unsigned int address)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[2];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
writes[i].device = NIUSB_SUBDEV_TNT4882;
writes[i].address = nec7210_to_tnt4882_offset(ADR);
writes[i].value = address;
@@ -1271,7 +1276,7 @@ static int ni_usb_primary_address(gpib_board_t *board, unsigned int address)
i++;
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
@@ -1307,30 +1312,33 @@ static int ni_usb_write_sad(struct ni_usb_register *writes, int address, int ena
return i;
}
-static int ni_usb_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int ni_usb_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[3];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
i += ni_usb_write_sad(writes, address, enable);
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
return 0;
}
-static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int ni_usb_parallel_poll(struct gpib_board *board, uint8_t *result)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
static const int out_data_length = 0x10;
static const int in_data_length = 0x20;
@@ -1339,6 +1347,9 @@ static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result)
int j = 0;
struct ni_usb_status_block status;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
return -ENOMEM;
@@ -1353,8 +1364,8 @@ static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result)
kfree(out_data);
if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return retval;
}
in_data = kmalloc(in_data_length, GFP_KERNEL);
@@ -1366,8 +1377,8 @@ static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result)
&bytes_read, 1000, 1);
if (retval && retval != -ERESTARTSYS) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
kfree(in_data);
return retval;
}
@@ -1378,37 +1389,43 @@ static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result)
return retval;
}
-static void ni_usb_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void ni_usb_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[1];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
writes[i].device = NIUSB_SUBDEV_TNT4882;
writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
writes[i].value = PPR | config;
i++;
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return;// retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
return;// 0;
}
-static void ni_usb_parallel_poll_response(gpib_board_t *board, int ist)
+static void ni_usb_parallel_poll_response(struct gpib_board *board, int ist)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[1];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
writes[i].device = NIUSB_SUBDEV_TNT4882;
writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
if (ist)
@@ -1418,76 +1435,85 @@ static void ni_usb_parallel_poll_response(gpib_board_t *board, int ist)
i++;
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return;// retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
return;// 0;
}
-static void ni_usb_serial_poll_response(gpib_board_t *board, u8 status)
+static void ni_usb_serial_poll_response(struct gpib_board *board, u8 status)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[1];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
writes[i].device = NIUSB_SUBDEV_TNT4882;
writes[i].address = nec7210_to_tnt4882_offset(SPMR);
writes[i].value = status;
i++;
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return;// retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
return;// 0;
}
-static uint8_t ni_usb_serial_poll_status(gpib_board_t *board)
+static uint8_t ni_usb_serial_poll_status(struct gpib_board *board)
{
return 0;
}
-static void ni_usb_return_to_local(gpib_board_t *board)
+static void ni_usb_return_to_local(struct gpib_board *board)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
int i = 0;
struct ni_usb_register writes[1];
unsigned int ibsta;
+ if (!ni_priv->bus_interface)
+ return; // -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
writes[i].device = NIUSB_SUBDEV_TNT4882;
writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
writes[i].value = AUX_RTL;
i++;
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return;// retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
return;// 0;
}
-static int ni_usb_line_status(const gpib_board_t *board)
+static int ni_usb_line_status(const struct gpib_board *board)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
u8 *out_data, *in_data;
static const int out_data_length = 0x20;
static const int in_data_length = 0x20;
int bytes_written = 0, bytes_read = 0;
int i = 0;
unsigned int bsr_bits;
- int line_status = ValidALL;
+ int line_status = VALID_ALL;
// NI windows driver reads 0xd(HSSEL), 0xc (ARD0), 0x1f (BSR)
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
out_data = kmalloc(out_data_length, GFP_KERNEL);
if (!out_data)
return -ENOMEM;
@@ -1509,15 +1535,14 @@ static int ni_usb_line_status(const gpib_board_t *board)
if (retval || bytes_written != i) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- __func__, retval, bytes_written, i);
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
+ retval, bytes_written, i);
return retval;
}
in_data = kmalloc(in_data_length, GFP_KERNEL);
if (!in_data) {
mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "%s: kmalloc failed\n", __func__);
return -ENOMEM;
}
retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, in_data, in_data_length,
@@ -1527,8 +1552,8 @@ static int ni_usb_line_status(const gpib_board_t *board)
if (retval) {
if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
kfree(in_data);
return retval;
}
@@ -1536,21 +1561,21 @@ static int ni_usb_line_status(const gpib_board_t *board)
ni_usb_parse_register_read_block(in_data, &bsr_bits, 1);
kfree(in_data);
if (bsr_bits & BCSR_REN_BIT)
- line_status |= BusREN;
+ line_status |= BUS_REN;
if (bsr_bits & BCSR_IFC_BIT)
- line_status |= BusIFC;
+ line_status |= BUS_IFC;
if (bsr_bits & BCSR_SRQ_BIT)
- line_status |= BusSRQ;
+ line_status |= BUS_SRQ;
if (bsr_bits & BCSR_EOI_BIT)
- line_status |= BusEOI;
+ line_status |= BUS_EOI;
if (bsr_bits & BCSR_NRFD_BIT)
- line_status |= BusNRFD;
+ line_status |= BUS_NRFD;
if (bsr_bits & BCSR_NDAC_BIT)
- line_status |= BusNDAC;
+ line_status |= BUS_NDAC;
if (bsr_bits & BCSR_DAV_BIT)
- line_status |= BusDAV;
+ line_status |= BUS_DAV;
if (bsr_bits & BCSR_ATN_BIT)
- line_status |= BusATN;
+ line_status |= BUS_ATN;
return line_status;
}
@@ -1591,28 +1616,31 @@ static int ni_usb_setup_t1_delay(struct ni_usb_register *reg, unsigned int nano_
return i;
}
-static unsigned int ni_usb_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int ni_usb_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
+ struct usb_device *usb_dev;
struct ni_usb_register writes[3];
unsigned int ibsta;
unsigned int actual_ns;
int i;
+ if (!ni_priv->bus_interface)
+ return -ENODEV;
+ usb_dev = interface_to_usbdev(ni_priv->bus_interface);
i = ni_usb_setup_t1_delay(writes, nano_sec, &actual_ns);
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
- return -1; //FIXME should change return type to int for error reporting
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
+ return retval;
}
board->t1_nano_sec = actual_ns;
ni_usb_soft_update_status(board, ibsta, 0);
return actual_ns;
}
-static int ni_usb_allocate_private(gpib_board_t *board)
+static int ni_usb_allocate_private(struct gpib_board *board)
{
struct ni_usb_priv *ni_priv;
@@ -1635,7 +1663,7 @@ static void ni_usb_free_private(struct ni_usb_priv *ni_priv)
}
#define NUM_INIT_WRITES 26
-static int ni_usb_setup_init(gpib_board_t *board, struct ni_usb_register *writes)
+static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *writes)
{
struct ni_usb_priv *ni_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
@@ -1736,13 +1764,13 @@ static int ni_usb_setup_init(gpib_board_t *board, struct ni_usb_register *writes
writes[i].value = AUX_CPPF;
i++;
if (i > NUM_INIT_WRITES) {
- dev_err(&usb_dev->dev, "%s: bug!, buffer overrun, i=%i\n", __func__, i);
+ dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i);
return 0;
}
return i;
}
-static int ni_usb_init(gpib_board_t *board)
+static int ni_usb_init(struct gpib_board *board)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
@@ -1762,7 +1790,7 @@ static int ni_usb_init(gpib_board_t *board)
return -EFAULT;
kfree(writes);
if (retval) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return retval;
}
ni_usb_soft_update_status(board, ibsta, 0);
@@ -1771,16 +1799,13 @@ static int ni_usb_init(gpib_board_t *board)
static void ni_usb_interrupt_complete(struct urb *urb)
{
- gpib_board_t *board = urb->context;
+ struct gpib_board *board = urb->context;
struct ni_usb_priv *ni_priv = board->private_data;
struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
int retval;
struct ni_usb_status_block status;
unsigned long flags;
-// printk("debug: %s: status=0x%x, error_count=%i, actual_length=%i\n", __func__,
-// urb->status, urb->error_count, urb->actual_length);
-
switch (urb->status) {
/* success */
case 0:
@@ -1793,26 +1818,24 @@ static void ni_usb_interrupt_complete(struct urb *urb)
default: /* other error, resubmit */
retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_ATOMIC);
if (retval)
- dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__);
+ dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
return;
}
ni_usb_parse_status_block(urb->transfer_buffer, &status);
-// printk("debug: ibsta=0x%x\n", status.ibsta);
spin_lock_irqsave(&board->spinlock, flags);
ni_priv->monitored_ibsta_bits &= ~status.ibsta;
-// printk("debug: monitored_ibsta_bits=0x%x\n", ni_priv->monitored_ibsta_bits);
spin_unlock_irqrestore(&board->spinlock, flags);
wake_up_interruptible(&board->wait);
retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_ATOMIC);
if (retval)
- dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb\n", __func__);
+ dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
}
-static int ni_usb_set_interrupt_monitor(gpib_board_t *board, unsigned int monitored_bits)
+static int ni_usb_set_interrupt_monitor(struct gpib_board *board, unsigned int monitored_bits)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
@@ -1821,22 +1844,20 @@ static int ni_usb_set_interrupt_monitor(gpib_board_t *board, unsigned int monito
u8 *buffer;
struct ni_usb_status_block status;
unsigned long flags;
- //printk("%s: receive control pipe is %i\n", __func__, pipe);
+
buffer = kmalloc(buffer_length, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
spin_lock_irqsave(&board->spinlock, flags);
ni_priv->monitored_ibsta_bits = ni_usb_ibsta_monitor_mask & monitored_bits;
-// dev_err(&usb_dev->dev, "debug: %s: monitored_ibsta_bits=0x%x\n",
-// __func__, ni_priv->monitored_ibsta_bits);
spin_unlock_irqrestore(&board->spinlock, flags);
retval = ni_usb_receive_control_msg(ni_priv, NI_USB_WAIT_REQUEST, USB_DIR_IN |
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x300, ni_usb_ibsta_monitor_mask & monitored_bits,
buffer, buffer_length, 1000);
if (retval != buffer_length) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg returned %i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg returned %i\n", retval);
kfree(buffer);
return -1;
}
@@ -1845,7 +1866,7 @@ static int ni_usb_set_interrupt_monitor(gpib_board_t *board, unsigned int monito
return 0;
}
-static int ni_usb_setup_urbs(gpib_board_t *board)
+static int ni_usb_setup_urbs(struct gpib_board *board)
{
struct ni_usb_priv *ni_priv = board->private_data;
struct usb_device *usb_dev;
@@ -1872,8 +1893,7 @@ static int ni_usb_setup_urbs(gpib_board_t *board)
retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_KERNEL);
mutex_unlock(&ni_priv->interrupt_transfer_lock);
if (retval) {
- dev_err(&usb_dev->dev, "%s: failed to submit first interrupt urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "failed to submit first interrupt urb, retval=%i\n", retval);
return retval;
}
return 0;
@@ -1904,7 +1924,6 @@ static int ni_usb_b_read_serial_number(struct ni_usb_priv *ni_priv)
int j;
unsigned int serial_number;
-// printk("%s: %s\n", __func__);
in_data = kmalloc(in_data_length, GFP_KERNEL);
if (!in_data)
return -ENOMEM;
@@ -1924,20 +1943,19 @@ static int ni_usb_b_read_serial_number(struct ni_usb_priv *ni_priv)
i += ni_usb_bulk_termination(&out_data[i]);
retval = ni_usb_send_bulk_msg(ni_priv, out_data, out_data_length, &bytes_written, 1000);
if (retval) {
- dev_err(&usb_dev->dev, "%s: ni_usb_send_bulk_msg returned %i, bytes_written=%i, i=%li\n",
- __func__,
+ dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%li\n",
retval, bytes_written, (long)out_data_length);
goto serial_out;
}
retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
if (retval) {
- dev_err(&usb_dev->dev, "%s: ni_usb_receive_bulk_msg returned %i, bytes_read=%i\n",
- __func__, retval, bytes_read);
+ dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
+ retval, bytes_read);
ni_usb_dump_raw_block(in_data, bytes_read);
goto serial_out;
}
if (ARRAY_SIZE(results) < num_reads) {
- dev_err(&usb_dev->dev, "Setup bug\n");
+ dev_err(&usb_dev->dev, "serial number eetup bug\n");
retval = -EINVAL;
goto serial_out;
}
@@ -1945,7 +1963,7 @@ static int ni_usb_b_read_serial_number(struct ni_usb_priv *ni_priv)
serial_number = 0;
for (j = 0; j < num_reads; ++j)
serial_number |= (results[j] & 0xff) << (8 * j);
- dev_info(&usb_dev->dev, "%s: board serial number is 0x%x\n", __func__, serial_number);
+ dev_dbg(&usb_dev->dev, "board serial number is 0x%x\n", serial_number);
retval = 0;
serial_out:
kfree(in_data);
@@ -1973,22 +1991,22 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0, 0x0, buffer, buffer_size, 1000);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n",
- __func__, NI_USB_SERIAL_NUMBER_REQUEST, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
+ NI_USB_SERIAL_NUMBER_REQUEST, retval);
goto ready_out;
}
j = 0;
if (buffer[j] != NI_USB_SERIAL_NUMBER_REQUEST) {
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
- __func__, j, (int)buffer[j], NI_USB_SERIAL_NUMBER_REQUEST);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
+ j, (int)buffer[j], NI_USB_SERIAL_NUMBER_REQUEST);
unexpected = 1;
}
if (unexpected)
ni_usb_dump_raw_block(buffer, retval);
// NI-USB-HS+ pads the serial with 0x0 to make 16 bytes
if (retval != 5 && retval != 16) {
- dev_err(&usb_dev->dev, "%s: received unexpected number of bytes = %i, expected 5 or 16\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "received unexpected number of bytes = %i, expected 5 or 16\n",
+ retval);
ni_usb_dump_raw_block(buffer, retval);
}
serial_number = 0;
@@ -1996,7 +2014,7 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
serial_number |= (buffer[++j] << 8);
serial_number |= (buffer[++j] << 16);
serial_number |= (buffer[++j] << 24);
- dev_info(&usb_dev->dev, "%s: board serial number is 0x%x\n", __func__, serial_number);
+ dev_dbg(&usb_dev->dev, "board serial number is 0x%x\n", serial_number);
for (i = 0; i < timeout; ++i) {
int ready = 0;
@@ -2004,26 +2022,26 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0, 0x0, buffer, buffer_size, 100);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n",
- __func__, NI_USB_POLL_READY_REQUEST, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
+ NI_USB_POLL_READY_REQUEST, retval);
goto ready_out;
}
j = 0;
unexpected = 0;
if (buffer[j] != NI_USB_POLL_READY_REQUEST) { // [0]
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
- __func__, j, (int)buffer[j], NI_USB_POLL_READY_REQUEST);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
+ j, (int)buffer[j], NI_USB_POLL_READY_REQUEST);
unexpected = 1;
}
++j;
if (buffer[j] != 0x1 && buffer[j] != 0x0) { // [1] HS+ sends 0x0
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
if (buffer[++j] != 0x0) { // [2]
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
- __func__, j, (int)buffer[j], 0x0);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
+ j, (int)buffer[j], 0x0);
unexpected = 1;
}
++j;
@@ -2031,22 +2049,22 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
// NI-USB-HS+ sends 0x0
if (buffer[j] != 0x1 && buffer[j] != 0x8 && buffer[j] != 0x7 && buffer[j] != 0x0) {
// [3]
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0, 0x1, 0x7 or 0x8\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0, 0x1, 0x7 or 0x8\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
++j;
// NI-USB-HS+ sends 0 here
if (buffer[j] != 0x30 && buffer[j] != 0x0) { // [4]
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x30\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x30\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
++j;
// MC usb-488 (and sometimes NI-USB-HS?) and NI-USB-HS+ sends 0x0 here
if (buffer[j] != 0x1 && buffer[j] != 0x0) { // [5]
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
if (buffer[++j] != 0x0) { // [6]
@@ -2054,8 +2072,8 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
// NI-USB-HS+ sends 0xf here
if (buffer[j] != 0x2 && buffer[j] != 0xe && buffer[j] != 0xf &&
buffer[j] != 0x16) {
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x2, 0xe, 0xf or 0x16\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x2, 0xe, 0xf or 0x16\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
}
@@ -2064,30 +2082,30 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
// MC usb-488 sends 0x5 here; MC usb-488A sends 0x6 here
if (buffer[j] != 0x3 && buffer[j] != 0x5 && buffer[j] != 0x6 &&
buffer[j] != 0x8) {
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x3 or 0x5, 0x6 or 0x08\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x3 or 0x5, 0x6 or 0x08\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
}
++j;
if (buffer[j] != 0x0 && buffer[j] != 0x2) { // [8] MC usb-488 sends 0x2 here
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x2\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, " unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x2\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
++j;
// MC usb-488A and NI-USB-HS sends 0x3 here; NI-USB-HS+ sends 0x30 here
if (buffer[j] != 0x0 && buffer[j] != 0x3 && buffer[j] != 0x30) { // [9]
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x0, 0x3 or 0x30\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0, 0x3 or 0x30\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
if (buffer[++j] != 0x0) {
ready = 1;
if (buffer[j] != 0x96 && buffer[j] != 0x7 && buffer[j] != 0x6e) {
// [10] MC usb-488 sends 0x7 here
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[%i]=0x%x, expected 0x96, 0x07 or 0x6e\n",
- __func__, j, (int)buffer[j]);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x96, 0x07 or 0x6e\n",
+ j, (int)buffer[j]);
unexpected = 1;
}
}
@@ -2097,7 +2115,6 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
break;
retval = msleep_interruptible(msec_sleep_duration);
if (retval) {
- dev_err(&usb_dev->dev, "ni_usb_gpib: msleep interrupted\n");
retval = -ERESTARTSYS;
goto ready_out;
}
@@ -2106,7 +2123,7 @@ static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
ready_out:
kfree(buffer);
- dev_dbg(&usb_dev->dev, "%s: exit retval=%d\n", __func__, retval);
+ dev_dbg(&usb_dev->dev, "exit retval=%d\n", retval);
return retval;
}
@@ -2134,14 +2151,14 @@ static int ni_usb_hs_plus_extra_init(struct ni_usb_priv *ni_priv)
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0, 0x0, buffer, transfer_size, 1000);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n",
- __func__, NI_USB_HS_PLUS_0x48_REQUEST, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
+ NI_USB_HS_PLUS_0x48_REQUEST, retval);
break;
}
// expected response data: 48 f3 30 00 00 00 00 00 00 00 00 00 00 00 00 00
if (buffer[0] != NI_USB_HS_PLUS_0x48_REQUEST)
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[0]=0x%x, expected 0x%x\n",
- __func__, (int)buffer[0], NI_USB_HS_PLUS_0x48_REQUEST);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[0]=0x%x, expected 0x%x\n",
+ (int)buffer[0], NI_USB_HS_PLUS_0x48_REQUEST);
transfer_size = 2;
@@ -2149,14 +2166,14 @@ static int ni_usb_hs_plus_extra_init(struct ni_usb_priv *ni_priv)
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x1, 0x0, buffer, transfer_size, 1000);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n",
- __func__, NI_USB_HS_PLUS_LED_REQUEST, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
+ NI_USB_HS_PLUS_LED_REQUEST, retval);
break;
}
// expected response data: 4b 00
if (buffer[0] != NI_USB_HS_PLUS_LED_REQUEST)
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[0]=0x%x, expected 0x%x\n",
- __func__, (int)buffer[0], NI_USB_HS_PLUS_LED_REQUEST);
+ dev_err(&usb_dev->dev, "unexpected data: buffer[0]=0x%x, expected 0x%x\n",
+ (int)buffer[0], NI_USB_HS_PLUS_LED_REQUEST);
transfer_size = 9;
@@ -2165,15 +2182,14 @@ static int ni_usb_hs_plus_extra_init(struct ni_usb_priv *ni_priv)
USB_RECIP_INTERFACE,
0x0, 0x1, buffer, transfer_size, 1000);
if (retval < 0) {
- dev_err(&usb_dev->dev, "%s: usb_control_msg request 0x%x returned %i\n",
- __func__, NI_USB_HS_PLUS_0xf8_REQUEST, retval);
+ dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
+ NI_USB_HS_PLUS_0xf8_REQUEST, retval);
break;
}
// expected response data: f8 01 00 00 00 01 00 00 00
if (buffer[0] != NI_USB_HS_PLUS_0xf8_REQUEST)
- dev_err(&usb_dev->dev, "%s: unexpected data: buffer[0]=0x%x, expected 0x%x\n",
- __func__, (int)buffer[0], NI_USB_HS_PLUS_0xf8_REQUEST);
-
+ dev_err(&usb_dev->dev, "unexpected data: buffer[0]=0x%x, expected 0x%x\n",
+ (int)buffer[0], NI_USB_HS_PLUS_0xf8_REQUEST);
} while (0);
// cleanup
@@ -2189,10 +2205,10 @@ static inline int ni_usb_device_match(struct usb_interface *interface,
return 1;
}
-static int ni_usb_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ni_usb_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
int retval;
- int i;
+ int i, index;
struct ni_usb_priv *ni_priv;
int product_id;
struct usb_device *usb_dev;
@@ -2211,19 +2227,17 @@ static int ni_usb_attach(gpib_board_t *board, const gpib_board_config_t *config)
ni_priv->bus_interface = ni_usb_driver_interfaces[i];
usb_set_intfdata(ni_usb_driver_interfaces[i], board);
usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- dev_info(&usb_dev->dev,
- "bus %d dev num %d attached to gpib minor %d, NI usb interface %i\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
+ index = i;
break;
}
}
if (i == MAX_NUM_NI_USB_INTERFACES) {
mutex_unlock(&ni_usb_hotplug_lock);
- pr_err("No supported NI usb gpib adapters found, have you loaded its firmware?\n");
+ dev_err(board->gpib_dev, "No supported adapters found, have you loaded its firmware?\n");
return -ENODEV;
}
if (usb_reset_configuration(interface_to_usbdev(ni_priv->bus_interface)))
- dev_err(&usb_dev->dev, "ni_usb_gpib: usb_reset_configuration() failed.\n");
+ dev_err(&usb_dev->dev, "usb_reset_configuration() failed.\n");
product_id = le16_to_cpu(usb_dev->descriptor.idProduct);
ni_priv->product_id = product_id;
@@ -2296,7 +2310,9 @@ static int ni_usb_attach(gpib_board_t *board, const gpib_board_config_t *config)
}
mutex_unlock(&ni_usb_hotplug_lock);
- dev_info(&usb_dev->dev, "%s: attached\n", __func__);
+ dev_info(&usb_dev->dev,
+ "bus %d dev num %d attached to gpib%d, intf %i\n",
+ usb_dev->bus->busnum, usb_dev->devnum, board->minor, index);
return retval;
}
@@ -2304,33 +2320,25 @@ static int ni_usb_shutdown_hardware(struct ni_usb_priv *ni_priv)
{
struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
int retval;
- int i = 0;
struct ni_usb_register writes[2];
static const int writes_length = ARRAY_SIZE(writes);
unsigned int ibsta;
-// printk("%s: %s\n", __func__);
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CR;
- i++;
- writes[i].device = NIUSB_SUBDEV_UNKNOWN3;
- writes[i].address = 0x10;
- writes[i].value = 0x0;
- i++;
- if (i > writes_length) {
- dev_err(&usb_dev->dev, "%s: bug!, buffer overrun, i=%i\n", __func__, i);
- return -EINVAL;
- }
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
+ writes[0].device = NIUSB_SUBDEV_TNT4882;
+ writes[0].address = nec7210_to_tnt4882_offset(AUXMR);
+ writes[0].value = AUX_CR;
+ writes[1].device = NIUSB_SUBDEV_UNKNOWN3;
+ writes[1].address = 0x10;
+ writes[1].value = 0x0;
+ retval = ni_usb_write_registers(ni_priv, writes, writes_length, &ibsta);
if (retval) {
- dev_err(&usb_dev->dev, "%s: register write failed, retval=%i\n", __func__, retval);
+ dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return retval;
}
return 0;
}
-static void ni_usb_detach(gpib_board_t *board)
+static void ni_usb_detach(struct gpib_board *board)
{
struct ni_usb_priv *ni_priv;
@@ -2413,7 +2421,7 @@ static int ni_usb_driver_probe(struct usb_interface *interface, const struct usb
if (i == MAX_NUM_NI_USB_INTERFACES) {
usb_put_dev(usb_dev);
mutex_unlock(&ni_usb_hotplug_lock);
- dev_err(&usb_dev->dev, "%s: ni_usb_driver_interfaces[] full\n", __func__);
+ dev_err(&usb_dev->dev, "ni_usb_driver_interfaces[] full\n");
return -1;
}
path = kmalloc(path_length, GFP_KERNEL);
@@ -2423,7 +2431,7 @@ static int ni_usb_driver_probe(struct usb_interface *interface, const struct usb
return -ENOMEM;
}
usb_make_path(usb_dev, path, path_length);
- dev_info(&usb_dev->dev, "ni_usb_gpib: probe succeeded for path: %s\n", path);
+ dev_info(&usb_dev->dev, "probe succeeded for path: %s\n", path);
kfree(path);
mutex_unlock(&ni_usb_hotplug_lock);
return 0;
@@ -2437,7 +2445,7 @@ static void ni_usb_driver_disconnect(struct usb_interface *interface)
mutex_lock(&ni_usb_hotplug_lock);
for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) {
if (ni_usb_driver_interfaces[i] == interface) {
- gpib_board_t *board = usb_get_intfdata(interface);
+ struct gpib_board *board = usb_get_intfdata(interface);
if (board) {
struct ni_usb_priv *ni_priv = board->private_data;
@@ -2458,8 +2466,7 @@ static void ni_usb_driver_disconnect(struct usb_interface *interface)
}
}
if (i == MAX_NUM_NI_USB_INTERFACES)
- dev_err(&usb_dev->dev, "%s: unable to find interface in ni_usb_driver_interfaces[]? bug?\n",
- __func__);
+ dev_err(&usb_dev->dev, "unable to find interface bug?\n");
usb_put_dev(usb_dev);
mutex_unlock(&ni_usb_hotplug_lock);
}
@@ -2467,7 +2474,7 @@ static void ni_usb_driver_disconnect(struct usb_interface *interface)
static int ni_usb_driver_suspend(struct usb_interface *interface, pm_message_t message)
{
struct usb_device *usb_dev = interface_to_usbdev(interface);
- gpib_board_t *board;
+ struct gpib_board *board;
int i, retval;
mutex_lock(&ni_usb_hotplug_lock);
@@ -2498,9 +2505,9 @@ static int ni_usb_driver_suspend(struct usb_interface *interface, pm_message_t m
ni_usb_cleanup_urbs(ni_priv);
mutex_unlock(&ni_priv->interrupt_transfer_lock);
}
- dev_info(&usb_dev->dev,
- "bus %d dev num %d gpib minor %d, ni usb interface %i suspended\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
+ dev_dbg(&usb_dev->dev,
+ "bus %d dev num %d gpib%d, interface %i suspended\n",
+ usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
}
mutex_unlock(&ni_usb_hotplug_lock);
@@ -2511,7 +2518,7 @@ static int ni_usb_driver_resume(struct usb_interface *interface)
{
struct usb_device *usb_dev = interface_to_usbdev(interface);
- gpib_board_t *board;
+ struct gpib_board *board;
int i, retval;
mutex_lock(&ni_usb_hotplug_lock);
@@ -2535,15 +2542,15 @@ static int ni_usb_driver_resume(struct usb_interface *interface)
mutex_lock(&ni_priv->interrupt_transfer_lock);
retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_KERNEL);
if (retval) {
- dev_err(&usb_dev->dev, "%s: failed to resubmit interrupt urb, retval=%i\n",
- __func__, retval);
+ dev_err(&usb_dev->dev, "resume failed to resubmit interrupt urb, retval=%i\n",
+ retval);
mutex_unlock(&ni_priv->interrupt_transfer_lock);
mutex_unlock(&ni_usb_hotplug_lock);
return retval;
}
mutex_unlock(&ni_priv->interrupt_transfer_lock);
} else {
- dev_err(&usb_dev->dev, "%s: bug! int urb not set up\n", __func__);
+ dev_err(&usb_dev->dev, "bug! resume int urb not set up\n");
mutex_unlock(&ni_usb_hotplug_lock);
return -EINVAL;
}
@@ -2600,9 +2607,9 @@ static int ni_usb_driver_resume(struct usb_interface *interface)
if (ni_priv->ren_state)
ni_usb_remote_enable(board, 1);
- dev_info(&usb_dev->dev,
- "bus %d dev num %d gpib minor %d, ni usb interface %i resumed\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
+ dev_dbg(&usb_dev->dev,
+ "bus %d dev num %d gpib%d, interface %i resumed\n",
+ usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
}
mutex_unlock(&ni_usb_hotplug_lock);
@@ -2610,7 +2617,7 @@ static int ni_usb_driver_resume(struct usb_interface *interface)
}
static struct usb_driver ni_usb_bus_driver = {
- .name = "ni_usb_gpib",
+ .name = DRV_NAME,
.probe = ni_usb_driver_probe,
.disconnect = ni_usb_driver_disconnect,
.suspend = ni_usb_driver_suspend,
@@ -2623,19 +2630,18 @@ static int __init ni_usb_init_module(void)
int i;
int ret;
- pr_info("ni_usb_gpib driver loading\n");
for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++)
ni_usb_driver_interfaces[i] = NULL;
ret = usb_register(&ni_usb_bus_driver);
if (ret) {
- pr_err("ni_usb_gpib: usb_register failed: error = %d\n", ret);
+ pr_err("usb_register failed: error = %d\n", ret);
return ret;
}
ret = gpib_register_driver(&ni_usb_gpib_interface, THIS_MODULE);
if (ret) {
- pr_err("ni_usb_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
return ret;
}
@@ -2644,7 +2650,6 @@ static int __init ni_usb_init_module(void)
static void __exit ni_usb_exit_module(void)
{
- pr_info("ni_usb_gpib driver unloading\n");
gpib_unregister_driver(&ni_usb_gpib_interface);
usb_deregister(&ni_usb_bus_driver);
}
diff --git a/drivers/staging/gpib/pc2/pc2_gpib.c b/drivers/staging/gpib/pc2/pc2_gpib.c
index c0b07cb63d9a..96d3c09f2273 100644
--- a/drivers/staging/gpib/pc2/pc2_gpib.c
+++ b/drivers/staging/gpib/pc2/pc2_gpib.c
@@ -4,6 +4,9 @@
* copyright : (C) 2001, 2002 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/module.h>
@@ -49,22 +52,13 @@ static inline unsigned int CLEAR_INTR_REG(unsigned int irq)
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver for PC2/PC2a and compatible devices");
-static int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int pc2a_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int pc2a_cb7210_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int pc2_2a_attach(gpib_board_t *board, const gpib_board_config_t *config);
-
-static void pc2_detach(gpib_board_t *board);
-static void pc2a_detach(gpib_board_t *board);
-static void pc2_2a_detach(gpib_board_t *board);
-
/*
* GPIB interrupt service routines
*/
irqreturn_t pc2_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct pc2_priv *priv = board->private_data;
unsigned long flags;
irqreturn_t retval;
@@ -77,7 +71,7 @@ irqreturn_t pc2_interrupt(int irq, void *arg)
irqreturn_t pc2a_interrupt(int irq, void *arg)
{
- gpib_board_t *board = arg;
+ struct gpib_board *board = arg;
struct pc2_priv *priv = board->private_data;
int status1, status2;
unsigned long flags;
@@ -96,7 +90,7 @@ irqreturn_t pc2a_interrupt(int irq, void *arg)
}
// wrappers for interface functions
-static int pc2_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
+static int pc2_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
size_t *bytes_read)
{
struct pc2_priv *priv = board->private_data;
@@ -104,7 +98,7 @@ static int pc2_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *en
return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
}
-static int pc2_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
+static int pc2_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
size_t *bytes_written)
{
struct pc2_priv *priv = board->private_data;
@@ -112,245 +106,133 @@ static int pc2_write(gpib_board_t *board, uint8_t *buffer, size_t length, int se
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-static int pc2_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int pc2_command(struct gpib_board *board, uint8_t *buffer, size_t length, size_t *bytes_written)
{
struct pc2_priv *priv = board->private_data;
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-static int pc2_take_control(gpib_board_t *board, int synchronous)
+static int pc2_take_control(struct gpib_board *board, int synchronous)
{
struct pc2_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-static int pc2_go_to_standby(gpib_board_t *board)
+static int pc2_go_to_standby(struct gpib_board *board)
{
struct pc2_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-static void pc2_request_system_control(gpib_board_t *board, int request_control)
+static void pc2_request_system_control(struct gpib_board *board, int request_control)
{
struct pc2_priv *priv = board->private_data;
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
}
-static void pc2_interface_clear(gpib_board_t *board, int assert)
+static void pc2_interface_clear(struct gpib_board *board, int assert)
{
struct pc2_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-static void pc2_remote_enable(gpib_board_t *board, int enable)
+static void pc2_remote_enable(struct gpib_board *board, int enable)
{
struct pc2_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-static int pc2_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int pc2_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct pc2_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-static void pc2_disable_eos(gpib_board_t *board)
+static void pc2_disable_eos(struct gpib_board *board)
{
struct pc2_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-static unsigned int pc2_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int pc2_update_status(struct gpib_board *board, unsigned int clear_mask)
{
struct pc2_priv *priv = board->private_data;
return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
}
-static int pc2_primary_address(gpib_board_t *board, unsigned int address)
+static int pc2_primary_address(struct gpib_board *board, unsigned int address)
{
struct pc2_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-static int pc2_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int pc2_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct pc2_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-static int pc2_parallel_poll(gpib_board_t *board, uint8_t *result)
+static int pc2_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct pc2_priv *priv = board->private_data;
return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
}
-static void pc2_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void pc2_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
struct pc2_priv *priv = board->private_data;
nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
}
-static void pc2_parallel_poll_response(gpib_board_t *board, int ist)
+static void pc2_parallel_poll_response(struct gpib_board *board, int ist)
{
struct pc2_priv *priv = board->private_data;
nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
}
-static void pc2_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void pc2_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct pc2_priv *priv = board->private_data;
nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
}
-static uint8_t pc2_serial_poll_status(gpib_board_t *board)
+static uint8_t pc2_serial_poll_status(struct gpib_board *board)
{
struct pc2_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-static unsigned int pc2_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int pc2_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct pc2_priv *priv = board->private_data;
return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec);
}
-static void pc2_return_to_local(gpib_board_t *board)
+static void pc2_return_to_local(struct gpib_board *board)
{
struct pc2_priv *priv = board->private_data;
nec7210_return_to_local(board, &priv->nec7210_priv);
}
-static gpib_interface_t pc2_interface = {
- .name = "pcII",
- .attach = pc2_attach,
- .detach = pc2_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static gpib_interface_t pc2a_interface = {
- .name = "pcIIa",
- .attach = pc2a_attach,
- .detach = pc2a_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static gpib_interface_t pc2a_cb7210_interface = {
- .name = "pcIIa_cb7210",
- .attach = pc2a_cb7210_attach,
- .detach = pc2a_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL, //XXX
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static gpib_interface_t pc2_2a_interface = {
- .name = "pcII_IIa",
- .attach = pc2_2a_attach,
- .detach = pc2_2a_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static int allocate_private(gpib_board_t *board)
+static int allocate_private(struct gpib_board *board)
{
struct pc2_priv *priv;
@@ -363,13 +245,13 @@ static int allocate_private(gpib_board_t *board)
return 0;
}
-static void free_private(gpib_board_t *board)
+static void free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
-static int pc2_generic_attach(gpib_board_t *board, const gpib_board_config_t *config,
+static int pc2_generic_attach(struct gpib_board *board, const gpib_board_config_t *config,
enum nec7210_chipset chipset)
{
struct pc2_priv *pc2_priv;
@@ -389,7 +271,8 @@ static int pc2_generic_attach(gpib_board_t *board, const gpib_board_config_t *co
* is adapted to use isa_register_driver.
*/
if (config->ibdma)
- pr_err("DMA disabled for pc2 gpib, driver needs to be adapted to use isa_register_driver to get a struct device*");
+ // driver needs to be adapted to use isa_register_driver to get a struct device*
+ dev_err(board->gpib_dev, "DMA disabled for pc2 gpib");
#else
if (config->ibdma) {
nec_priv->dma_buffer_length = 0x1000;
@@ -401,7 +284,7 @@ static int pc2_generic_attach(gpib_board_t *board, const gpib_board_config_t *co
// request isa dma channel
if (request_dma(config->ibdma, "pc2")) {
- pr_err("gpib: can't request DMA %d\n", config->ibdma);
+ dev_err(board->gpib_dev, "can't request DMA %d\n", config->ibdma);
return -1;
}
nec_priv->dma_channel = config->ibdma;
@@ -411,7 +294,7 @@ static int pc2_generic_attach(gpib_board_t *board, const gpib_board_config_t *co
return 0;
}
-int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int pc2_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
int isr_flags = 0;
struct pc2_priv *pc2_priv;
@@ -427,8 +310,8 @@ int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config)
nec_priv->offset = pc2_reg_offset;
if (!request_region(config->ibbase, pc2_iosize, "pc2")) {
- pr_err("gpib: ioports are already in use\n");
- return -1;
+ dev_err(board->gpib_dev, "ioports are already in use\n");
+ return -EBUSY;
}
nec_priv->iobase = config->ibbase;
@@ -437,14 +320,14 @@ int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config)
// install interrupt handler
if (config->ibirq) {
if (request_irq(config->ibirq, pc2_interrupt, isr_flags, "pc2", board)) {
- pr_err("gpib: can't request IRQ %d\n", config->ibirq);
- return -1;
+ dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
+ return -EBUSY;
}
}
pc2_priv->irq = config->ibirq;
/* poll so we can detect assertion of ATN */
if (gpib_request_pseudo_irq(board, pc2_interrupt)) {
- pr_err("pc2_gpib: failed to allocate pseudo_irq\n");
+ dev_err(board->gpib_dev, "failed to allocate pseudo_irq\n");
return -1;
}
/* set internal counter register for 8 MHz input clock */
@@ -455,7 +338,7 @@ int pc2_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-void pc2_detach(gpib_board_t *board)
+static void pc2_detach(struct gpib_board *board)
{
struct pc2_priv *pc2_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -482,7 +365,7 @@ void pc2_detach(gpib_board_t *board)
free_private(board);
}
-static int pc2a_common_attach(gpib_board_t *board, const gpib_board_config_t *config,
+static int pc2a_common_attach(struct gpib_board *board, const gpib_board_config_t *config,
unsigned int num_registers, enum nec7210_chipset chipset)
{
unsigned int i, j;
@@ -505,18 +388,19 @@ static int pc2a_common_attach(gpib_board_t *board, const gpib_board_config_t *co
case 0x62e1:
break;
default:
- pr_err("PCIIa base range invalid, must be one of 0x[0246]2e1, but is 0x%d\n",
- config->ibbase);
+ dev_err(board->gpib_dev, "PCIIa base range invalid, must be one of 0x[0246]2e1, but is 0x%x\n",
+ config->ibbase);
return -1;
}
if (config->ibirq) {
if (config->ibirq < 2 || config->ibirq > 7) {
- pr_err("pc2_gpib: illegal interrupt level %i\n", config->ibirq);
+ dev_err(board->gpib_dev, "illegal interrupt level %i\n",
+ config->ibirq);
return -1;
}
} else {
- pr_err("pc2_gpib: interrupt disabled, using polling mode (slow)\n");
+ dev_err(board->gpib_dev, "interrupt disabled, using polling mode (slow)\n");
}
#ifdef CHECK_IOPORTS
unsigned int err = 0;
@@ -528,36 +412,36 @@ static int pc2a_common_attach(gpib_board_t *board, const gpib_board_config_t *co
if (config->ibirq && check_region(pc2a_clear_intr_iobase + config->ibirq, 1))
err++;
if (err) {
- pr_err("gpib: ioports are already in use");
- return -1;
+ dev_err(board->gpib_dev, "ioports are already in use");
+ return -EBUSY;
}
#endif
for (i = 0; i < num_registers; i++) {
if (!request_region(config->ibbase +
i * pc2a_reg_offset, 1, "pc2a")) {
- pr_err("gpib: ioports are already in use");
+ dev_err(board->gpib_dev, "ioports are already in use");
for (j = 0; j < i; j++)
release_region(config->ibbase +
j * pc2a_reg_offset, 1);
- return -1;
+ return -EBUSY;
}
}
nec_priv->iobase = config->ibbase;
if (config->ibirq) {
if (!request_region(pc2a_clear_intr_iobase + config->ibirq, 1, "pc2a")) {
- pr_err("gpib: ioports are already in use");
+ dev_err(board->gpib_dev, "ioports are already in use");
return -1;
}
pc2_priv->clear_intr_addr = pc2a_clear_intr_iobase + config->ibirq;
if (request_irq(config->ibirq, pc2a_interrupt, 0, "pc2a", board)) {
- pr_err("gpib: can't request IRQ %d\n", config->ibirq);
- return -1;
+ dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
+ return -EBUSY;
}
}
pc2_priv->irq = config->ibirq;
/* poll so we can detect assertion of ATN */
if (gpib_request_pseudo_irq(board, pc2_interrupt)) {
- pr_err("pc2_gpib: failed to allocate pseudo_irq\n");
+ dev_err(board->gpib_dev, "failed to allocate pseudo_irq\n");
return -1;
}
@@ -575,22 +459,22 @@ static int pc2a_common_attach(gpib_board_t *board, const gpib_board_config_t *co
return 0;
}
-int pc2a_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int pc2a_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
return pc2a_common_attach(board, config, pc2a_iosize, NEC7210);
}
-int pc2a_cb7210_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int pc2a_cb7210_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
return pc2a_common_attach(board, config, pc2a_iosize, CB7210);
}
-int pc2_2a_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int pc2_2a_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
return pc2a_common_attach(board, config, pc2_2a_iosize, NAT4882);
}
-static void pc2a_common_detach(gpib_board_t *board, unsigned int num_registers)
+static void pc2a_common_detach(struct gpib_board *board, unsigned int num_registers)
{
int i;
struct pc2_priv *pc2_priv = board->private_data;
@@ -623,41 +507,153 @@ static void pc2a_common_detach(gpib_board_t *board, unsigned int num_registers)
free_private(board);
}
-void pc2a_detach(gpib_board_t *board)
+static void pc2a_detach(struct gpib_board *board)
{
pc2a_common_detach(board, pc2a_iosize);
}
-void pc2_2a_detach(gpib_board_t *board)
+static void pc2_2a_detach(struct gpib_board *board)
{
pc2a_common_detach(board, pc2_2a_iosize);
}
+static gpib_interface_t pc2_interface = {
+ .name = "pcII",
+ .attach = pc2_attach,
+ .detach = pc2_detach,
+ .read = pc2_read,
+ .write = pc2_write,
+ .command = pc2_command,
+ .take_control = pc2_take_control,
+ .go_to_standby = pc2_go_to_standby,
+ .request_system_control = pc2_request_system_control,
+ .interface_clear = pc2_interface_clear,
+ .remote_enable = pc2_remote_enable,
+ .enable_eos = pc2_enable_eos,
+ .disable_eos = pc2_disable_eos,
+ .parallel_poll = pc2_parallel_poll,
+ .parallel_poll_configure = pc2_parallel_poll_configure,
+ .parallel_poll_response = pc2_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = NULL,
+ .update_status = pc2_update_status,
+ .primary_address = pc2_primary_address,
+ .secondary_address = pc2_secondary_address,
+ .serial_poll_response = pc2_serial_poll_response,
+ .serial_poll_status = pc2_serial_poll_status,
+ .t1_delay = pc2_t1_delay,
+ .return_to_local = pc2_return_to_local,
+};
+
+static gpib_interface_t pc2a_interface = {
+ .name = "pcIIa",
+ .attach = pc2a_attach,
+ .detach = pc2a_detach,
+ .read = pc2_read,
+ .write = pc2_write,
+ .command = pc2_command,
+ .take_control = pc2_take_control,
+ .go_to_standby = pc2_go_to_standby,
+ .request_system_control = pc2_request_system_control,
+ .interface_clear = pc2_interface_clear,
+ .remote_enable = pc2_remote_enable,
+ .enable_eos = pc2_enable_eos,
+ .disable_eos = pc2_disable_eos,
+ .parallel_poll = pc2_parallel_poll,
+ .parallel_poll_configure = pc2_parallel_poll_configure,
+ .parallel_poll_response = pc2_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = NULL,
+ .update_status = pc2_update_status,
+ .primary_address = pc2_primary_address,
+ .secondary_address = pc2_secondary_address,
+ .serial_poll_response = pc2_serial_poll_response,
+ .serial_poll_status = pc2_serial_poll_status,
+ .t1_delay = pc2_t1_delay,
+ .return_to_local = pc2_return_to_local,
+};
+
+static gpib_interface_t pc2a_cb7210_interface = {
+ .name = "pcIIa_cb7210",
+ .attach = pc2a_cb7210_attach,
+ .detach = pc2a_detach,
+ .read = pc2_read,
+ .write = pc2_write,
+ .command = pc2_command,
+ .take_control = pc2_take_control,
+ .go_to_standby = pc2_go_to_standby,
+ .request_system_control = pc2_request_system_control,
+ .interface_clear = pc2_interface_clear,
+ .remote_enable = pc2_remote_enable,
+ .enable_eos = pc2_enable_eos,
+ .disable_eos = pc2_disable_eos,
+ .parallel_poll = pc2_parallel_poll,
+ .parallel_poll_configure = pc2_parallel_poll_configure,
+ .parallel_poll_response = pc2_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = NULL, //XXX
+ .update_status = pc2_update_status,
+ .primary_address = pc2_primary_address,
+ .secondary_address = pc2_secondary_address,
+ .serial_poll_response = pc2_serial_poll_response,
+ .serial_poll_status = pc2_serial_poll_status,
+ .t1_delay = pc2_t1_delay,
+ .return_to_local = pc2_return_to_local,
+};
+
+static gpib_interface_t pc2_2a_interface = {
+ .name = "pcII_IIa",
+ .attach = pc2_2a_attach,
+ .detach = pc2_2a_detach,
+ .read = pc2_read,
+ .write = pc2_write,
+ .command = pc2_command,
+ .take_control = pc2_take_control,
+ .go_to_standby = pc2_go_to_standby,
+ .request_system_control = pc2_request_system_control,
+ .interface_clear = pc2_interface_clear,
+ .remote_enable = pc2_remote_enable,
+ .enable_eos = pc2_enable_eos,
+ .disable_eos = pc2_disable_eos,
+ .parallel_poll = pc2_parallel_poll,
+ .parallel_poll_configure = pc2_parallel_poll_configure,
+ .parallel_poll_response = pc2_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = NULL,
+ .update_status = pc2_update_status,
+ .primary_address = pc2_primary_address,
+ .secondary_address = pc2_secondary_address,
+ .serial_poll_response = pc2_serial_poll_response,
+ .serial_poll_status = pc2_serial_poll_status,
+ .t1_delay = pc2_t1_delay,
+ .return_to_local = pc2_return_to_local,
+};
+
static int __init pc2_init_module(void)
{
int ret;
ret = gpib_register_driver(&pc2_interface, THIS_MODULE);
if (ret) {
- pr_err("pc2_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
return ret;
}
ret = gpib_register_driver(&pc2a_interface, THIS_MODULE);
if (ret) {
- pr_err("pc2_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pc2a;
}
ret = gpib_register_driver(&pc2a_cb7210_interface, THIS_MODULE);
if (ret) {
- pr_err("pc2_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_cb7210;
}
ret = gpib_register_driver(&pc2_2a_interface, THIS_MODULE);
if (ret) {
- pr_err("pc2_gpib: gpib_register_driver failed: error = %d\n", ret);
+ pr_err("gpib_register_driver failed: error = %d\n", ret);
goto err_pc2_2a;
}
diff --git a/drivers/staging/gpib/tms9914/tms9914.c b/drivers/staging/gpib/tms9914/tms9914.c
index ec8e1d4d762f..2abda9d7dfcb 100644
--- a/drivers/staging/gpib/tms9914/tms9914.c
+++ b/drivers/staging/gpib/tms9914/tms9914.c
@@ -4,6 +4,9 @@
* copyright : (C) 2001, 2002 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/module.h>
@@ -24,9 +27,9 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB library for tms9914");
-static unsigned int update_status_nolock(gpib_board_t *board, struct tms9914_priv *priv);
+static unsigned int update_status_nolock(struct gpib_board *board, struct tms9914_priv *priv);
-int tms9914_take_control(gpib_board_t *board, struct tms9914_priv *priv, int synchronous)
+int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int synchronous)
{
int i;
const int timeout = 100;
@@ -63,7 +66,7 @@ EXPORT_SYMBOL_GPL(tms9914_take_control);
* The rest of the tms9914 based drivers still use tms9914_take_control
* directly (which does issue tcs).
*/
-int tms9914_take_control_workaround(gpib_board_t *board, struct tms9914_priv *priv, int synchronous)
+int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv, int synchronous)
{
if (synchronous)
return -ETIMEDOUT;
@@ -71,7 +74,7 @@ int tms9914_take_control_workaround(gpib_board_t *board, struct tms9914_priv *pr
}
EXPORT_SYMBOL_GPL(tms9914_take_control_workaround);
-int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv)
+int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv)
{
int i;
const int timeout = 1000;
@@ -83,10 +86,8 @@ int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv)
break;
udelay(1);
}
- if (i == timeout) {
- pr_err("error waiting for NATN\n");
+ if (i == timeout)
return -ETIMEDOUT;
- }
clear_bit(COMMAND_READY_BN, &priv->state);
@@ -94,7 +95,7 @@ int tms9914_go_to_standby(gpib_board_t *board, struct tms9914_priv *priv)
}
EXPORT_SYMBOL_GPL(tms9914_go_to_standby);
-void tms9914_interface_clear(gpib_board_t *board, struct tms9914_priv *priv, int assert)
+void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert)
{
if (assert) {
write_byte(priv, AUX_SIC | AUX_CS, AUXCR);
@@ -106,7 +107,7 @@ void tms9914_interface_clear(gpib_board_t *board, struct tms9914_priv *priv, int
}
EXPORT_SYMBOL_GPL(tms9914_interface_clear);
-void tms9914_remote_enable(gpib_board_t *board, struct tms9914_priv *priv, int enable)
+void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable)
{
if (enable)
write_byte(priv, AUX_SRE | AUX_CS, AUXCR);
@@ -115,7 +116,7 @@ void tms9914_remote_enable(gpib_board_t *board, struct tms9914_priv *priv, int e
}
EXPORT_SYMBOL_GPL(tms9914_remote_enable);
-void tms9914_request_system_control(gpib_board_t *board, struct tms9914_priv *priv,
+void tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
int request_control)
{
if (request_control) {
@@ -127,7 +128,7 @@ void tms9914_request_system_control(gpib_board_t *board, struct tms9914_priv *pr
}
EXPORT_SYMBOL_GPL(tms9914_request_system_control);
-unsigned int tms9914_t1_delay(gpib_board_t *board, struct tms9914_priv *priv,
+unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv,
unsigned int nano_sec)
{
static const int clock_period = 200; // assuming 5Mhz input clock
@@ -153,7 +154,7 @@ unsigned int tms9914_t1_delay(gpib_board_t *board, struct tms9914_priv *priv,
}
EXPORT_SYMBOL_GPL(tms9914_t1_delay);
-void tms9914_return_to_local(const gpib_board_t *board, struct tms9914_priv *priv)
+void tms9914_return_to_local(const struct gpib_board *board, struct tms9914_priv *priv)
{
write_byte(priv, AUX_RTL, AUXCR);
}
@@ -175,7 +176,7 @@ void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mo
write_byte(priv, AUX_HLDA | AUX_CS, AUXCR);
break;
default:
- pr_err("%s: bug! bad holdoff mode %i\n", __func__, mode);
+ pr_err("bug! bad holdoff mode %i\n", mode);
break;
}
priv->holdoff_mode = mode;
@@ -191,7 +192,7 @@ void tms9914_release_holdoff(struct tms9914_priv *priv)
}
EXPORT_SYMBOL_GPL(tms9914_release_holdoff);
-int tms9914_enable_eos(gpib_board_t *board, struct tms9914_priv *priv, uint8_t eos_byte,
+int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, uint8_t eos_byte,
int compare_8_bits)
{
priv->eos = eos_byte;
@@ -202,13 +203,13 @@ int tms9914_enable_eos(gpib_board_t *board, struct tms9914_priv *priv, uint8_t e
}
EXPORT_SYMBOL(tms9914_enable_eos);
-void tms9914_disable_eos(gpib_board_t *board, struct tms9914_priv *priv)
+void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv)
{
priv->eos_flags &= ~REOS;
}
EXPORT_SYMBOL(tms9914_disable_eos);
-int tms9914_parallel_poll(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *result)
+int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *result)
{
// execute parallel poll
write_byte(priv, AUX_CS | AUX_RPP, AUXCR);
@@ -233,7 +234,7 @@ static void set_ppoll_reg(struct tms9914_priv *priv, int enable,
}
}
-void tms9914_parallel_poll_configure(gpib_board_t *board,
+void tms9914_parallel_poll_configure(struct gpib_board *board,
struct tms9914_priv *priv, uint8_t config)
{
priv->ppoll_enable = (config & PPC_DISABLE) == 0;
@@ -243,14 +244,14 @@ void tms9914_parallel_poll_configure(gpib_board_t *board,
}
EXPORT_SYMBOL(tms9914_parallel_poll_configure);
-void tms9914_parallel_poll_response(gpib_board_t *board,
+void tms9914_parallel_poll_response(struct gpib_board *board,
struct tms9914_priv *priv, int ist)
{
set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, ist);
}
EXPORT_SYMBOL(tms9914_parallel_poll_response);
-void tms9914_serial_poll_response(gpib_board_t *board, struct tms9914_priv *priv, uint8_t status)
+void tms9914_serial_poll_response(struct gpib_board *board, struct tms9914_priv *priv, uint8_t status)
{
unsigned long flags;
@@ -265,7 +266,7 @@ void tms9914_serial_poll_response(gpib_board_t *board, struct tms9914_priv *priv
}
EXPORT_SYMBOL(tms9914_serial_poll_response);
-uint8_t tms9914_serial_poll_status(gpib_board_t *board, struct tms9914_priv *priv)
+uint8_t tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv)
{
u8 status;
unsigned long flags;
@@ -278,7 +279,7 @@ uint8_t tms9914_serial_poll_status(gpib_board_t *board, struct tms9914_priv *pri
}
EXPORT_SYMBOL(tms9914_serial_poll_status);
-int tms9914_primary_address(gpib_board_t *board, struct tms9914_priv *priv, unsigned int address)
+int tms9914_primary_address(struct gpib_board *board, struct tms9914_priv *priv, unsigned int address)
{
// put primary address in address0
write_byte(priv, address & ADDRESS_MASK, ADR);
@@ -286,7 +287,7 @@ int tms9914_primary_address(gpib_board_t *board, struct tms9914_priv *priv, unsi
}
EXPORT_SYMBOL(tms9914_primary_address);
-int tms9914_secondary_address(gpib_board_t *board, struct tms9914_priv *priv,
+int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv,
unsigned int address, int enable)
{
if (enable)
@@ -299,7 +300,7 @@ int tms9914_secondary_address(gpib_board_t *board, struct tms9914_priv *priv,
}
EXPORT_SYMBOL(tms9914_secondary_address);
-unsigned int tms9914_update_status(gpib_board_t *board, struct tms9914_priv *priv,
+unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv,
unsigned int clear_mask)
{
unsigned long flags;
@@ -341,7 +342,7 @@ static void update_listener_state(struct tms9914_priv *priv, unsigned int addres
}
}
-static unsigned int update_status_nolock(gpib_board_t *board, struct tms9914_priv *priv)
+static unsigned int update_status_nolock(struct gpib_board *board, struct tms9914_priv *priv)
{
int address_status;
int bsr_bits;
@@ -387,29 +388,29 @@ static unsigned int update_status_nolock(gpib_board_t *board, struct tms9914_pri
return board->status;
}
-int tms9914_line_status(const gpib_board_t *board, struct tms9914_priv *priv)
+int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv)
{
int bsr_bits;
- int status = ValidALL;
+ int status = VALID_ALL;
bsr_bits = read_byte(priv, BSR);
if (bsr_bits & BSR_REN_BIT)
- status |= BusREN;
+ status |= BUS_REN;
if (bsr_bits & BSR_IFC_BIT)
- status |= BusIFC;
+ status |= BUS_IFC;
if (bsr_bits & BSR_SRQ_BIT)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if (bsr_bits & BSR_EOI_BIT)
- status |= BusEOI;
+ status |= BUS_EOI;
if (bsr_bits & BSR_NRFD_BIT)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if (bsr_bits & BSR_NDAC_BIT)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if (bsr_bits & BSR_DAV_BIT)
- status |= BusDAV;
+ status |= BUS_DAV;
if (bsr_bits & BSR_ATN_BIT)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
@@ -432,15 +433,14 @@ static int check_for_eos(struct tms9914_priv *priv, uint8_t byte)
return 0;
}
-static int wait_for_read_byte(gpib_board_t *board, struct tms9914_priv *priv)
+static int wait_for_read_byte(struct gpib_board *board, struct tms9914_priv *priv)
{
if (wait_event_interruptible(board->wait,
test_bit(READ_READY_BN, &priv->state) ||
test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- pr_debug("gpib: pio read wait interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
return -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
return -ETIMEDOUT;
@@ -449,7 +449,7 @@ static int wait_for_read_byte(gpib_board_t *board, struct tms9914_priv *priv)
return 0;
}
-static inline uint8_t tms9914_read_data_in(gpib_board_t *board, struct tms9914_priv *priv, int *end)
+static inline uint8_t tms9914_read_data_in(struct gpib_board *board, struct tms9914_priv *priv, int *end)
{
unsigned long flags;
u8 data;
@@ -472,7 +472,7 @@ static inline uint8_t tms9914_read_data_in(gpib_board_t *board, struct tms9914_p
case TMS9914_HOLDOFF_NONE:
break;
default:
- pr_err("%s: bug! bad holdoff mode %i\n", __func__, priv->holdoff_mode);
+ dev_err(board->gpib_dev, "bug! bad holdoff mode %i\n", priv->holdoff_mode);
break;
}
spin_unlock_irqrestore(&board->spinlock, flags);
@@ -480,7 +480,7 @@ static inline uint8_t tms9914_read_data_in(gpib_board_t *board, struct tms9914_p
return data;
}
-static int pio_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+static int pio_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
ssize_t retval = 0;
@@ -501,7 +501,7 @@ static int pio_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buf
return retval;
}
-int tms9914_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, int *end, size_t *bytes_read)
{
ssize_t retval = 0;
@@ -541,17 +541,16 @@ int tms9914_read(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer
}
EXPORT_SYMBOL(tms9914_read);
-static int pio_write_wait(gpib_board_t *board, struct tms9914_priv *priv)
+static int pio_write_wait(struct gpib_board *board, struct tms9914_priv *priv)
{
// wait until next byte is ready to be sent
if (wait_event_interruptible(board->wait,
test_bit(WRITE_READY_BN, &priv->state) ||
test_bit(BUS_ERROR_BN, &priv->state) ||
test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted!\n");
+ test_bit(TIMO_NUM, &board->status)))
return -ERESTARTSYS;
- }
+
if (test_bit(TIMO_NUM, &board->status))
return -ETIMEDOUT;
if (test_bit(BUS_ERROR_BN, &priv->state))
@@ -562,7 +561,7 @@ static int pio_write_wait(gpib_board_t *board, struct tms9914_priv *priv)
return 0;
}
-static int pio_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+static int pio_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, size_t *bytes_written)
{
ssize_t retval = 0;
@@ -586,7 +585,7 @@ static int pio_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *bu
return length;
}
-int tms9914_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer, size_t length,
+int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer, size_t length,
int send_eoi, size_t *bytes_written)
{
ssize_t retval = 0;
@@ -621,7 +620,7 @@ int tms9914_write(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffe
}
EXPORT_SYMBOL(tms9914_write);
-static void check_my_address_state(gpib_board_t *board, struct tms9914_priv *priv, int cmd_byte)
+static void check_my_address_state(struct gpib_board *board, struct tms9914_priv *priv, int cmd_byte)
{
if (cmd_byte == MLA(board->pad)) {
priv->primary_listen_addressed = 1;
@@ -656,7 +655,7 @@ static void check_my_address_state(gpib_board_t *board, struct tms9914_priv *pri
}
}
-int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *buffer,
+int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, uint8_t *buffer,
size_t length, size_t *bytes_written)
{
int retval = 0;
@@ -667,10 +666,8 @@ int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *bu
if (wait_event_interruptible(board->wait,
test_bit(COMMAND_READY_BN,
&priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- pr_debug("gpib command wait interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
break;
- }
if (test_bit(TIMO_NUM, &board->status))
break;
@@ -695,7 +692,7 @@ int tms9914_command(gpib_board_t *board, struct tms9914_priv *priv, uint8_t *bu
}
EXPORT_SYMBOL(tms9914_command);
-irqreturn_t tms9914_interrupt(gpib_board_t *board, struct tms9914_priv *priv)
+irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv)
{
int status0, status1;
@@ -706,7 +703,7 @@ irqreturn_t tms9914_interrupt(gpib_board_t *board, struct tms9914_priv *priv)
}
EXPORT_SYMBOL(tms9914_interrupt);
-irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_priv *priv,
+irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms9914_priv *priv,
int status0, int status1)
{
// record reception of END
@@ -761,8 +758,6 @@ irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_pr
write_byte(priv, AUX_INVAL, AUXCR);
}
} else {
- // printk("tms9914: unrecognized gpib command pass thru 0x%x\n",
- // command_byte);
// clear dac holdoff
write_byte(priv, AUX_INVAL, AUXCR);
}
@@ -799,7 +794,7 @@ irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_pr
// check for being addressed with secondary addressing
if (status1 & HR_APT) {
if (board->sad < 0)
- pr_err("tms9914: bug, APT interrupt without secondary addressing?\n");
+ dev_err(board->gpib_dev, "bug, APT interrupt without secondary addressing?\n");
if ((read_byte(priv, CPTR) & gpib_command_mask) == MSA(board->sad))
write_byte(priv, AUX_VAL, AUXCR);
else
@@ -807,8 +802,8 @@ irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, struct tms9914_pr
}
if ((status0 & priv->imr0_bits) || (status1 & priv->imr1_bits)) {
-// dev_dbg(board->gpib_dev, "isr0 0x%x, imr0 0x%x, isr1 0x%x, imr1 0x%x\n",
-// status0, priv->imr0_bits, status1, priv->imr1_bits);
+ dev_dbg(board->gpib_dev, "isr0 0x%x, imr0 0x%x, isr1 0x%x, imr1 0x%x\n",
+ status0, priv->imr0_bits, status1, priv->imr1_bits);
update_status_nolock(board, priv);
wake_up_interruptible(&board->wait);
}
@@ -842,7 +837,7 @@ void tms9914_board_reset(struct tms9914_priv *priv)
}
EXPORT_SYMBOL_GPL(tms9914_board_reset);
-void tms9914_online(gpib_board_t *board, struct tms9914_priv *priv)
+void tms9914_online(struct gpib_board *board, struct tms9914_priv *priv)
{
/* set GPIB address */
tms9914_primary_address(board, priv, board->pad);
diff --git a/drivers/staging/gpib/tnt4882/Makefile b/drivers/staging/gpib/tnt4882/Makefile
index a3c3fb96d5ed..fa1687ad0d1b 100644
--- a/drivers/staging/gpib/tnt4882/Makefile
+++ b/drivers/staging/gpib/tnt4882/Makefile
@@ -1,4 +1,3 @@
-ccflags-$(CONFIG_GPIB_PCMCIA) := -DGPIB_PCMCIA
obj-$(CONFIG_GPIB_NI_PCI_ISA) += tnt4882.o
tnt4882-objs := tnt4882_gpib.o mite.o
diff --git a/drivers/staging/gpib/tnt4882/mite.c b/drivers/staging/gpib/tnt4882/mite.c
index ea64dde46bcb..847b96f411bd 100644
--- a/drivers/staging/gpib/tnt4882/mite.c
+++ b/drivers/staging/gpib/tnt4882/mite.c
@@ -88,7 +88,6 @@ int mite_setup(struct mite_struct *mite)
pr_err("mite: failed to remap mite io memory address.\n");
return -ENOMEM;
}
- pr_info("mite: 0x%08lx mapped to %p\n", mite->mite_phys_addr, mite->mite_io_addr);
addr = pci_resource_start(mite->pcidev, 1);
mite->daq_phys_addr = addr;
mite->daq_io_addr = ioremap(mite->daq_phys_addr, pci_resource_len(mite->pcidev, 1));
@@ -96,7 +95,6 @@ int mite_setup(struct mite_struct *mite)
pr_err("mite: failed to remap daq io memory address.\n");
return -ENOMEM;
}
- pr_info("mite: daq: 0x%08lx mapped to %p\n", mite->daq_phys_addr, mite->daq_io_addr);
writel(mite->daq_phys_addr | WENAB, mite->mite_io_addr + MITE_IODWBSR);
mite->used = 1;
return 0;
@@ -133,18 +131,3 @@ void mite_unsetup(struct mite_struct *mite)
}
mite->used = 0;
}
-
-void mite_list_devices(void)
-{
- struct mite_struct *mite, *next;
-
- pr_info("Available NI PCI device IDs:");
- if (mite_devices)
- for (mite = mite_devices; mite; mite = next) {
- next = mite->next;
- pr_info(" 0x%04x", mite_device_id(mite));
- if (mite->used)
- pr_info("(used)");
- }
- pr_info("\n");
-}
diff --git a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c
index b39ab2abe495..c35b084b6fd0 100644
--- a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c
+++ b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c
@@ -5,6 +5,10 @@
* copyright : (C) 2001, 2002 by Frank Mori Hess
***************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
+#define DRV_NAME KBUILD_MODNAME
+
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/module.h>
@@ -47,49 +51,7 @@ struct tnt4882_priv {
unsigned short auxg_bits; // bits written to auxiliary register G
};
-// interface functions
-static int tnt4882_read(gpib_board_t *board, uint8_t *buffer, size_t length,
- int *end, size_t *bytes_read);
-static int tnt4882_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length,
- int *end, size_t *bytes_read);
-static int tnt4882_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written);
-static int tnt4882_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length,
- int send_eoi, size_t *bytes_written);
-static int tnt4882_command(gpib_board_t *board, uint8_t *buffer, size_t length,
- size_t *bytes_written);
-static int tnt4882_command_unaccel(gpib_board_t *board, uint8_t *buffer,
- size_t length, size_t *bytes_written);
-static int tnt4882_take_control(gpib_board_t *board, int synchronous);
-static int tnt4882_go_to_standby(gpib_board_t *board);
-static void tnt4882_request_system_control(gpib_board_t *board, int request_control);
-static void tnt4882_interface_clear(gpib_board_t *board, int assert);
-static void tnt4882_remote_enable(gpib_board_t *board, int enable);
-static int tnt4882_enable_eos(gpib_board_t *board, uint8_t eos_byte, int
- compare_8_bits);
-static void tnt4882_disable_eos(gpib_board_t *board);
-static unsigned int tnt4882_update_status(gpib_board_t *board, unsigned int clear_mask);
-static int tnt4882_primary_address(gpib_board_t *board, unsigned int address);
-static int tnt4882_secondary_address(gpib_board_t *board, unsigned int address,
- int enable);
-static int tnt4882_parallel_poll(gpib_board_t *board, uint8_t *result);
-static void tnt4882_parallel_poll_configure(gpib_board_t *board, uint8_t config);
-static void tnt4882_parallel_poll_response(gpib_board_t *board, int ist);
-static void tnt4882_serial_poll_response(gpib_board_t *board, uint8_t status);
-static uint8_t tnt4882_serial_poll_status(gpib_board_t *board);
-static int tnt4882_line_status(const gpib_board_t *board);
-static unsigned int tnt4882_t1_delay(gpib_board_t *board, unsigned int nano_sec);
-static void tnt4882_return_to_local(gpib_board_t *board);
-
-// interrupt service routines
-static irqreturn_t tnt4882_internal_interrupt(gpib_board_t *board);
-static irqreturn_t tnt4882_interrupt(int irq, void *arg);
-
-// utility functions
-static int tnt4882_allocate_private(gpib_board_t *board);
-static void tnt4882_free_private(gpib_board_t *board);
-static void tnt4882_init(struct tnt4882_priv *tnt_priv, const gpib_board_t *board);
-static void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, gpib_board_t *board);
+static irqreturn_t tnt4882_internal_interrupt(struct gpib_board *board);
// register offset for nec7210 compatible registers
static const int atgpib_reg_offset = 2;
@@ -139,7 +101,6 @@ static inline unsigned short tnt_readb(struct tnt4882_priv *priv, unsigned long
retval = 0;
break;
default:
- pr_err("tnt4882: bug! unsupported ni_chipset\n");
retval = 0;
break;
}
@@ -174,7 +135,6 @@ static inline void tnt_writeb(struct tnt4882_priv *priv, unsigned short value, u
case NEC7210:
break;
default:
- pr_err("tnt4882: bug! unsupported ni_chipset\n");
break;
}
break;
@@ -188,9 +148,9 @@ static inline void tnt_writeb(struct tnt4882_priv *priv, unsigned short value, u
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIB driver for National Instruments boards using tnt4882 or compatible chips");
-int tnt4882_line_status(const gpib_board_t *board)
+static int tnt4882_line_status(const struct gpib_board *board)
{
- int status = ValidALL;
+ int status = VALID_ALL;
int bcsr_bits;
struct tnt4882_priv *tnt_priv;
@@ -199,26 +159,26 @@ int tnt4882_line_status(const gpib_board_t *board)
bcsr_bits = tnt_readb(tnt_priv, BSR);
if (bcsr_bits & BCSR_REN_BIT)
- status |= BusREN;
+ status |= BUS_REN;
if (bcsr_bits & BCSR_IFC_BIT)
- status |= BusIFC;
+ status |= BUS_IFC;
if (bcsr_bits & BCSR_SRQ_BIT)
- status |= BusSRQ;
+ status |= BUS_SRQ;
if (bcsr_bits & BCSR_EOI_BIT)
- status |= BusEOI;
+ status |= BUS_EOI;
if (bcsr_bits & BCSR_NRFD_BIT)
- status |= BusNRFD;
+ status |= BUS_NRFD;
if (bcsr_bits & BCSR_NDAC_BIT)
- status |= BusNDAC;
+ status |= BUS_NDAC;
if (bcsr_bits & BCSR_DAV_BIT)
- status |= BusDAV;
+ status |= BUS_DAV;
if (bcsr_bits & BCSR_ATN_BIT)
- status |= BusATN;
+ status |= BUS_ATN;
return status;
}
-unsigned int tnt4882_t1_delay(gpib_board_t *board, unsigned int nano_sec)
+static int tnt4882_t1_delay(struct gpib_board *board, unsigned int nano_sec)
{
struct tnt4882_priv *tnt_priv = board->private_data;
struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
@@ -291,7 +251,7 @@ static int drain_fifo_words(struct tnt4882_priv *tnt_priv, uint8_t *buffer, int
return count;
}
-static void tnt4882_release_holdoff(gpib_board_t *board, struct tnt4882_priv *tnt_priv)
+static void tnt4882_release_holdoff(struct gpib_board *board, struct tnt4882_priv *tnt_priv)
{
struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
unsigned short sasr_bits;
@@ -314,8 +274,8 @@ static void tnt4882_release_holdoff(gpib_board_t *board, struct tnt4882_priv *tn
}
}
-int tnt4882_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
- size_t *bytes_read)
+static int tnt4882_accel_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
+ size_t *bytes_read)
{
size_t count = 0;
ssize_t retval = 0;
@@ -368,22 +328,18 @@ int tnt4882_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(ADR_CHANGE_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_err("tnt4882: read interrupted\n");
retval = -ERESTARTSYS;
break;
}
if (test_bit(TIMO_NUM, &board->status)) {
- //pr_info("tnt4882: minor %i read timed out\n", board->minor);
retval = -ETIMEDOUT;
break;
}
if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) {
- pr_err("tnt4882: device clear interrupted read\n");
retval = -EINTR;
break;
}
if (test_bit(ADR_CHANGE_BN, &nec_priv->state)) {
- pr_err("tnt4882: address change interrupted read\n");
retval = -EINTR;
break;
}
@@ -410,20 +366,14 @@ int tnt4882_accel_read(gpib_board_t *board, uint8_t *buffer, size_t length, int
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
test_bit(ADR_CHANGE_BN, &nec_priv->state) ||
test_bit(TIMO_NUM, &board->status))) {
- pr_err("tnt4882: read interrupted\n");
retval = -ERESTARTSYS;
}
if (test_bit(TIMO_NUM, &board->status))
- //pr_info("tnt4882: read timed out\n");
retval = -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) {
- pr_err("tnt4882: device clear interrupted read\n");
+ if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
retval = -EINTR;
- }
- if (test_bit(ADR_CHANGE_BN, &nec_priv->state)) {
- pr_err("tnt4882: address change interrupted read\n");
+ if (test_bit(ADR_CHANGE_BN, &nec_priv->state))
retval = -EINTR;
- }
count += drain_fifo_words(tnt_priv, &buffer[count], length - count);
if (fifo_byte_available(tnt_priv) && count < length)
buffer[count++] = tnt_readb(tnt_priv, FIFOB);
@@ -476,7 +426,7 @@ static unsigned int tnt_transfer_count(struct tnt4882_priv *tnt_priv)
return -count;
};
-static int write_wait(gpib_board_t *board, struct tnt4882_priv *tnt_priv,
+static int write_wait(struct gpib_board *board, struct tnt4882_priv *tnt_priv,
int wait_for_done, int send_commands)
{
struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
@@ -486,26 +436,19 @@ static int write_wait(gpib_board_t *board, struct tnt4882_priv *tnt_priv,
fifo_xfer_done(tnt_priv) ||
test_bit(BUS_ERROR_BN, &nec_priv->state) ||
test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "gpib write interrupted\n");
+ test_bit(TIMO_NUM, &board->status)))
return -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- pr_info("tnt4882: write timed out\n");
+
+ if (test_bit(TIMO_NUM, &board->status))
return -ETIMEDOUT;
- }
- if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state)) {
- pr_err("tnt4882: write bus error\n");
+ if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state))
return (send_commands) ? -ENOTCONN : -ECOMM;
- }
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) {
- pr_err("tnt4882: device clear interrupted write\n");
+ if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
return -EINTR;
- }
return 0;
}
-static int generic_write(gpib_board_t *board, uint8_t *buffer, size_t length,
+static int generic_write(struct gpib_board *board, uint8_t *buffer, size_t length,
int send_eoi, int send_commands, size_t *bytes_written)
{
size_t count = 0;
@@ -596,18 +539,19 @@ static int generic_write(gpib_board_t *board, uint8_t *buffer, size_t length,
return retval;
}
-int tnt4882_accel_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int tnt4882_accel_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written)
{
return generic_write(board, buffer, length, send_eoi, 0, bytes_written);
}
-int tnt4882_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written)
+static int tnt4882_command(struct gpib_board *board, uint8_t *buffer, size_t length,
+ size_t *bytes_written)
{
return generic_write(board, buffer, length, 0, 1, bytes_written);
}
-irqreturn_t tnt4882_internal_interrupt(gpib_board_t *board)
+static irqreturn_t tnt4882_internal_interrupt(struct gpib_board *board)
{
struct tnt4882_priv *priv = board->private_data;
int isr0_bits, isr3_bits, imr3_bits;
@@ -633,7 +577,7 @@ irqreturn_t tnt4882_internal_interrupt(gpib_board_t *board)
if (isr3_bits & HR_DONE)
priv->imr3_bits &= ~HR_DONE;
if (isr3_bits & (HR_INTR | HR_TLCI)) {
- dev_dbg(board->gpib_dev, "tnt4882: minor %i isr0 0x%x imr0 0x%x isr3 0x%x imr3 0x%x\n",
+ dev_dbg(board->gpib_dev, "minor %i isr0 0x%x imr0 0x%x isr3 0x%x imr3 0x%x\n",
board->minor, isr0_bits, priv->imr0_bits, isr3_bits, imr3_bits);
tnt_writeb(priv, priv->imr3_bits, IMR3);
wake_up_interruptible(&board->wait);
@@ -642,28 +586,14 @@ irqreturn_t tnt4882_internal_interrupt(gpib_board_t *board)
return IRQ_HANDLED;
}
-irqreturn_t tnt4882_interrupt(int irq, void *arg)
+static irqreturn_t tnt4882_interrupt(int irq, void *arg)
{
return tnt4882_internal_interrupt(arg);
}
-static int ni_tnt_isa_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int ni_nat4882_isa_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int ni_nec_isa_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config);
-
-static void ni_isa_detach(gpib_board_t *board);
-static void ni_pci_detach(gpib_board_t *board);
-
-#ifdef GPIB_PCMCIA
-static int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static void ni_pcmcia_detach(gpib_board_t *board);
-static int init_ni_gpib_cs(void);
-static void __exit exit_ni_gpib_cs(void);
-#endif
-
// wrappers for interface functions
-int tnt4882_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read)
+static int tnt4882_read(struct gpib_board *board, uint8_t *buffer, size_t length, int *end,
+ size_t *bytes_read)
{
struct tnt4882_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -682,37 +612,37 @@ int tnt4882_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end,
return retval;
}
-int tnt4882_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
+static int tnt4882_write(struct gpib_board *board, uint8_t *buffer, size_t length, int send_eoi,
+ size_t *bytes_written)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
}
-int tnt4882_command_unaccel(gpib_board_t *board, uint8_t *buffer,
- size_t length, size_t *bytes_written)
+static int tnt4882_command_unaccel(struct gpib_board *board, uint8_t *buffer,
+ size_t length, size_t *bytes_written)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
}
-int tnt4882_take_control(gpib_board_t *board, int synchronous)
+static int tnt4882_take_control(struct gpib_board *board, int synchronous)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
}
-int tnt4882_go_to_standby(gpib_board_t *board)
+static int tnt4882_go_to_standby(struct gpib_board *board)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
-void tnt4882_request_system_control(gpib_board_t *board, int request_control)
+static void tnt4882_request_system_control(struct gpib_board *board, int request_control)
{
struct tnt4882_priv *priv = board->private_data;
@@ -727,44 +657,43 @@ void tnt4882_request_system_control(gpib_board_t *board, int request_control)
}
}
-void tnt4882_interface_clear(gpib_board_t *board, int assert)
+static void tnt4882_interface_clear(struct gpib_board *board, int assert)
{
struct tnt4882_priv *priv = board->private_data;
nec7210_interface_clear(board, &priv->nec7210_priv, assert);
}
-void tnt4882_remote_enable(gpib_board_t *board, int enable)
+static void tnt4882_remote_enable(struct gpib_board *board, int enable)
{
struct tnt4882_priv *priv = board->private_data;
nec7210_remote_enable(board, &priv->nec7210_priv, enable);
}
-int tnt4882_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits)
+static int tnt4882_enable_eos(struct gpib_board *board, uint8_t eos_byte, int compare_8_bits)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
}
-void tnt4882_disable_eos(gpib_board_t *board)
+static void tnt4882_disable_eos(struct gpib_board *board)
{
struct tnt4882_priv *priv = board->private_data;
nec7210_disable_eos(board, &priv->nec7210_priv);
}
-unsigned int tnt4882_update_status(gpib_board_t *board, unsigned int clear_mask)
+static unsigned int tnt4882_update_status(struct gpib_board *board, unsigned int clear_mask)
{
unsigned long flags;
u8 line_status;
- unsigned int retval;
struct tnt4882_priv *priv = board->private_data;
spin_lock_irqsave(&board->spinlock, flags);
board->status &= ~clear_mask;
- retval = nec7210_update_status_nolock(board, &priv->nec7210_priv);
+ nec7210_update_status_nolock(board, &priv->nec7210_priv);
/* set / clear SRQ state since it is not cleared by interrupt */
line_status = tnt_readb(priv, BSR);
if (line_status & BCSR_SRQ_BIT)
@@ -775,22 +704,21 @@ unsigned int tnt4882_update_status(gpib_board_t *board, unsigned int clear_mask)
return board->status;
}
-int tnt4882_primary_address(gpib_board_t *board, unsigned int address)
+static int tnt4882_primary_address(struct gpib_board *board, unsigned int address)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_primary_address(board, &priv->nec7210_priv, address);
}
-int tnt4882_secondary_address(gpib_board_t *board, unsigned int address, int enable)
+static int tnt4882_secondary_address(struct gpib_board *board, unsigned int address, int enable)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
}
-int tnt4882_parallel_poll(gpib_board_t *board, uint8_t *result)
-
+static int tnt4882_parallel_poll(struct gpib_board *board, uint8_t *result)
{
struct tnt4882_priv *tnt_priv = board->private_data;
@@ -807,7 +735,7 @@ int tnt4882_parallel_poll(gpib_board_t *board, uint8_t *result)
}
}
-void tnt4882_parallel_poll_configure(gpib_board_t *board, uint8_t config)
+static void tnt4882_parallel_poll_configure(struct gpib_board *board, uint8_t config)
{
struct tnt4882_priv *priv = board->private_data;
@@ -825,7 +753,7 @@ void tnt4882_parallel_poll_configure(gpib_board_t *board, uint8_t config)
}
}
-void tnt4882_parallel_poll_response(gpib_board_t *board, int ist)
+static void tnt4882_parallel_poll_response(struct gpib_board *board, int ist)
{
struct tnt4882_priv *priv = board->private_data;
@@ -835,14 +763,14 @@ void tnt4882_parallel_poll_response(gpib_board_t *board, int ist)
/* this is just used by the old nec7210 isa interfaces, the newer
* boards use tnt4882_serial_poll_response2
*/
-void tnt4882_serial_poll_response(gpib_board_t *board, uint8_t status)
+static void tnt4882_serial_poll_response(struct gpib_board *board, uint8_t status)
{
struct tnt4882_priv *priv = board->private_data;
nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
}
-static void tnt4882_serial_poll_response2(gpib_board_t *board, uint8_t status,
+static void tnt4882_serial_poll_response2(struct gpib_board *board, uint8_t status,
int new_reason_for_service)
{
struct tnt4882_priv *priv = board->private_data;
@@ -876,303 +804,21 @@ static void tnt4882_serial_poll_response2(gpib_board_t *board, uint8_t status,
spin_unlock_irqrestore(&board->spinlock, flags);
}
-uint8_t tnt4882_serial_poll_status(gpib_board_t *board)
+static uint8_t tnt4882_serial_poll_status(struct gpib_board *board)
{
struct tnt4882_priv *priv = board->private_data;
return nec7210_serial_poll_status(board, &priv->nec7210_priv);
}
-void tnt4882_return_to_local(gpib_board_t *board)
+static void tnt4882_return_to_local(struct gpib_board *board)
{
struct tnt4882_priv *priv = board->private_data;
nec7210_return_to_local(board, &priv->nec7210_priv);
}
-static gpib_interface_t ni_pci_interface = {
- .name = "ni_pci",
- .attach = ni_pci_attach,
- .detach = ni_pci_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_pci_accel_interface = {
- .name = "ni_pci_accel",
- .attach = ni_pci_attach,
- .detach = ni_pci_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_isa_interface = {
- .name = "ni_isa",
- .attach = ni_tnt_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_nat4882_isa_interface = {
- .name = "ni_nat4882_isa",
- .attach = ni_nat4882_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_read,
- .write = tnt4882_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_nec_isa_interface = {
- .name = "ni_nec_isa",
- .attach = ni_nec_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_read,
- .write = tnt4882_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_isa_accel_interface = {
- .name = "ni_isa_accel",
- .attach = ni_tnt_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_nat4882_isa_accel_interface = {
- .name = "ni_nat4882_isa_accel",
- .attach = ni_nat4882_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_nec_isa_accel_interface = {
- .name = "ni_nec_isa_accel",
- .attach = ni_nec_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-#ifdef GPIB_PCMCIA
-static gpib_interface_t ni_pcmcia_interface = {
- .name = "ni_pcmcia",
- .attach = ni_pcmcia_attach,
- .detach = ni_pcmcia_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static gpib_interface_t ni_pcmcia_accel_interface = {
- .name = "ni_pcmcia_accel",
- .attach = ni_pcmcia_attach,
- .detach = ni_pcmcia_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-#endif
-
-void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, gpib_board_t *board)
+static void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, struct gpib_board *board)
{
struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
@@ -1185,7 +831,7 @@ void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, gpib_board_t *board)
nec7210_board_reset(nec_priv, board);
}
-int tnt4882_allocate_private(gpib_board_t *board)
+static int tnt4882_allocate_private(struct gpib_board *board)
{
struct tnt4882_priv *tnt_priv;
@@ -1198,13 +844,13 @@ int tnt4882_allocate_private(gpib_board_t *board)
return 0;
}
-void tnt4882_free_private(gpib_board_t *board)
+static void tnt4882_free_private(struct gpib_board *board)
{
kfree(board->private_data);
board->private_data = NULL;
}
-void tnt4882_init(struct tnt4882_priv *tnt_priv, const gpib_board_t *board)
+static void tnt4882_init(struct tnt4882_priv *tnt_priv, const struct gpib_board *board)
{
struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
@@ -1252,7 +898,7 @@ void tnt4882_init(struct tnt4882_priv *tnt_priv, const gpib_board_t *board)
tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0);
}
-int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ni_pci_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct tnt4882_priv *tnt_priv;
struct nec7210_priv *nec_priv;
@@ -1271,10 +917,8 @@ int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
nec_priv->write_byte = nec7210_locking_iomem_write_byte;
nec_priv->offset = atgpib_reg_offset;
- if (!mite_devices) {
- pr_err("no National Instruments PCI boards found\n");
- return -1;
- }
+ if (!mite_devices)
+ return -ENODEV;
for (mite = mite_devices; mite; mite = mite->next) {
short found_board;
@@ -1305,37 +949,32 @@ int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
if (found_board)
break;
}
- if (!mite) {
- pr_err("no NI PCI-GPIB boards found\n");
- return -1;
- }
+ if (!mite)
+ return -ENODEV;
+
tnt_priv->mite = mite;
retval = mite_setup(tnt_priv->mite);
- if (retval < 0) {
- pr_err("tnt4882: error setting up mite.\n");
+ if (retval < 0)
return retval;
- }
nec_priv->mmiobase = tnt_priv->mite->daq_io_addr;
// get irq
- if (request_irq(mite_irq(tnt_priv->mite), tnt4882_interrupt, isr_flags,
- "ni-pci-gpib", board)) {
- pr_err("gpib: can't request IRQ %d\n", mite_irq(tnt_priv->mite));
- return -1;
+ retval = request_irq(mite_irq(tnt_priv->mite), tnt4882_interrupt, isr_flags, "ni-pci-gpib",
+ board);
+ if (retval) {
+ dev_err(board->gpib_dev, "failed to obtain pci irq %d\n", mite_irq(tnt_priv->mite));
+ return retval;
}
tnt_priv->irq = mite_irq(tnt_priv->mite);
- pr_info("tnt4882: irq %i\n", tnt_priv->irq);
// TNT5004 detection
switch (tnt_readb(tnt_priv, CSR) & 0xf0) {
case 0x30:
nec_priv->type = TNT4882;
- pr_info("tnt4882: TNT4882 chipset detected\n");
break;
case 0x40:
nec_priv->type = TNT5004;
- pr_info("tnt4882: TNT5004 chipset detected\n");
break;
}
tnt4882_init(tnt_priv, board);
@@ -1343,7 +982,7 @@ int ni_pci_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-void ni_pci_detach(gpib_board_t *board)
+static void ni_pci_detach(struct gpib_board *board)
{
struct tnt4882_priv *tnt_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1365,28 +1004,22 @@ static int ni_isapnp_find(struct pnp_dev **dev)
{
*dev = pnp_find_dev(NULL, ISAPNP_VENDOR_ID_NI,
ISAPNP_FUNCTION(ISAPNP_ID_NI_ATGPIB_TNT), NULL);
- if (!*dev || !(*dev)->card) {
- pr_err("tnt4882: failed to find isapnp board\n");
+ if (!*dev || !(*dev)->card)
return -ENODEV;
- }
- if (pnp_device_attach(*dev) < 0) {
- pr_err("tnt4882: atgpib/tnt board already active, skipping\n");
+ if (pnp_device_attach(*dev) < 0)
return -EBUSY;
- }
if (pnp_activate_dev(*dev) < 0) {
pnp_device_detach(*dev);
- pr_err("tnt4882: failed to activate() atgpib/tnt, aborting\n");
return -EAGAIN;
}
if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) {
pnp_device_detach(*dev);
- pr_err("tnt4882: invalid port or irq for atgpib/tnt, aborting\n");
- return -ENOMEM;
+ return -EINVAL;
}
return 0;
}
-static int ni_isa_attach_common(gpib_board_t *board, const gpib_board_config_t *config,
+static int ni_isa_attach_common(struct gpib_board *board, const gpib_board_config_t *config,
enum nec7210_chipset chipset)
{
struct tnt4882_priv *tnt_priv;
@@ -1394,6 +1027,7 @@ static int ni_isa_attach_common(gpib_board_t *board, const gpib_board_config_t *
int isr_flags = 0;
u32 iobase;
int irq;
+ int retval;
board->status = 0;
@@ -1409,7 +1043,6 @@ static int ni_isa_attach_common(gpib_board_t *board, const gpib_board_config_t *
// look for plug-n-play board
if (config->ibbase == 0) {
struct pnp_dev *dev;
- int retval;
retval = ni_isapnp_find(&dev);
if (retval < 0)
@@ -1422,18 +1055,18 @@ static int ni_isa_attach_common(gpib_board_t *board, const gpib_board_config_t *
irq = config->ibirq;
}
// allocate ioports
- if (!request_region(iobase, atgpib_iosize, "atgpib")) {
- pr_err("tnt4882: failed to allocate ioports\n");
- return -1;
- }
+ if (!request_region(iobase, atgpib_iosize, "atgpib"))
+ return -EBUSY;
+
nec_priv->mmiobase = ioport_map(iobase, atgpib_iosize);
if (!nec_priv->mmiobase)
- return -1;
+ return -EBUSY;
// get irq
- if (request_irq(irq, tnt4882_interrupt, isr_flags, "atgpib", board)) {
- pr_err("gpib: can't request IRQ %d\n", irq);
- return -1;
+ retval = request_irq(irq, tnt4882_interrupt, isr_flags, "atgpib", board);
+ if (retval) {
+ dev_err(board->gpib_dev, "failed to request ISA irq %d\n", irq);
+ return retval;
}
tnt_priv->irq = irq;
@@ -1442,22 +1075,22 @@ static int ni_isa_attach_common(gpib_board_t *board, const gpib_board_config_t *
return 0;
}
-int ni_tnt_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ni_tnt_isa_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
return ni_isa_attach_common(board, config, TNT4882);
}
-int ni_nat4882_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ni_nat4882_isa_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
return ni_isa_attach_common(board, config, NAT4882);
}
-int ni_nec_isa_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ni_nec_isa_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
return ni_isa_attach_common(board, config, NEC7210);
}
-void ni_isa_detach(gpib_board_t *board)
+static void ni_isa_detach(struct gpib_board *board)
{
struct tnt4882_priv *tnt_priv = board->private_data;
struct nec7210_priv *nec_priv;
@@ -1483,6 +1116,230 @@ static int tnt4882_pci_probe(struct pci_dev *dev, const struct pci_device_id *id
return 0;
}
+static gpib_interface_t ni_pci_interface = {
+ .name = "ni_pci",
+ .attach = ni_pci_attach,
+ .detach = ni_pci_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response2 = tnt4882_serial_poll_response2,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_pci_accel_interface = {
+ .name = "ni_pci_accel",
+ .attach = ni_pci_attach,
+ .detach = ni_pci_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response2 = tnt4882_serial_poll_response2,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_isa_interface = {
+ .name = "ni_isa",
+ .attach = ni_tnt_isa_attach,
+ .detach = ni_isa_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response2 = tnt4882_serial_poll_response2,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_nat4882_isa_interface = {
+ .name = "ni_nat4882_isa",
+ .attach = ni_nat4882_isa_attach,
+ .detach = ni_isa_detach,
+ .read = tnt4882_read,
+ .write = tnt4882_write,
+ .command = tnt4882_command_unaccel,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response2 = tnt4882_serial_poll_response2,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_nec_isa_interface = {
+ .name = "ni_nec_isa",
+ .attach = ni_nec_isa_attach,
+ .detach = ni_isa_detach,
+ .read = tnt4882_read,
+ .write = tnt4882_write,
+ .command = tnt4882_command_unaccel,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = NULL,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response = tnt4882_serial_poll_response,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_isa_accel_interface = {
+ .name = "ni_isa_accel",
+ .attach = ni_tnt_isa_attach,
+ .detach = ni_isa_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response2 = tnt4882_serial_poll_response2,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_nat4882_isa_accel_interface = {
+ .name = "ni_nat4882_isa_accel",
+ .attach = ni_nat4882_isa_attach,
+ .detach = ni_isa_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command_unaccel,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response2 = tnt4882_serial_poll_response2,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_nec_isa_accel_interface = {
+ .name = "ni_nec_isa_accel",
+ .attach = ni_nec_isa_attach,
+ .detach = ni_isa_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command_unaccel,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = NULL,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response = tnt4882_serial_poll_response,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
static const struct pci_device_id tnt4882_pci_table[] = {
{PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB)},
{PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB_PLUS)},
@@ -1499,16 +1356,26 @@ static const struct pci_device_id tnt4882_pci_table[] = {
MODULE_DEVICE_TABLE(pci, tnt4882_pci_table);
static struct pci_driver tnt4882_pci_driver = {
- .name = "tnt4882",
+ .name = DRV_NAME,
.id_table = tnt4882_pci_table,
.probe = &tnt4882_pci_probe
};
+#if 0
+/* unused, will be needed when the driver is turned into a pnp_driver */
static const struct pnp_device_id tnt4882_pnp_table[] = {
{.id = "NICC601"},
{.id = ""}
};
MODULE_DEVICE_TABLE(pnp, tnt4882_pnp_table);
+#endif
+
+#ifdef CONFIG_GPIB_PCMCIA
+static gpib_interface_t ni_pcmcia_interface;
+static gpib_interface_t ni_pcmcia_accel_interface;
+static int __init init_ni_gpib_cs(void);
+static void __exit exit_ni_gpib_cs(void);
+#endif
static int __init tnt4882_init_module(void)
{
@@ -1516,84 +1383,83 @@ static int __init tnt4882_init_module(void)
result = pci_register_driver(&tnt4882_pci_driver);
if (result) {
- pr_err("tnt4882_gpib: pci_register_driver failed: error = %d\n", result);
+ pr_err("pci_register_driver failed: error = %d\n", result);
return result;
}
result = gpib_register_driver(&ni_isa_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_isa;
}
result = gpib_register_driver(&ni_isa_accel_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_isa_accel;
}
result = gpib_register_driver(&ni_nat4882_isa_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_nat4882_isa;
}
result = gpib_register_driver(&ni_nat4882_isa_accel_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_nat4882_isa_accel;
}
result = gpib_register_driver(&ni_nec_isa_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_nec_isa;
}
result = gpib_register_driver(&ni_nec_isa_accel_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_nec_isa_accel;
}
result = gpib_register_driver(&ni_pci_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_pci;
}
result = gpib_register_driver(&ni_pci_accel_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_pci_accel;
}
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
result = gpib_register_driver(&ni_pcmcia_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_pcmcia;
}
result = gpib_register_driver(&ni_pcmcia_accel_interface, THIS_MODULE);
if (result) {
- pr_err("tnt4882_gpib: gpib_register_driver failed: error = %d\n", result);
+ pr_err("gpib_register_driver failed: error = %d\n", result);
goto err_pcmcia_accel;
}
result = init_ni_gpib_cs();
if (result) {
- pr_err("tnt4882_gpib: pcmcia_register_driver failed: error = %d\n", result);
+ pr_err("pcmcia_register_driver failed: error = %d\n", result);
goto err_pcmcia_driver;
}
#endif
mite_init();
- mite_list_devices();
return 0;
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
err_pcmcia_driver:
gpib_unregister_driver(&ni_pcmcia_accel_interface);
err_pcmcia_accel:
@@ -1631,7 +1497,7 @@ static void __exit tnt4882_exit_module(void)
gpib_unregister_driver(&ni_nec_isa_accel_interface);
gpib_unregister_driver(&ni_pci_interface);
gpib_unregister_driver(&ni_pci_accel_interface);
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
gpib_unregister_driver(&ni_pcmcia_interface);
gpib_unregister_driver(&ni_pcmcia_accel_interface);
exit_ni_gpib_cs();
@@ -1642,7 +1508,7 @@ static void __exit tnt4882_exit_module(void)
pci_unregister_driver(&tnt4882_pci_driver);
}
-#ifdef GPIB_PCMCIA
+#ifdef CONFIG_GPIB_PCMCIA
#include <linux/kernel.h>
#include <linux/moduleparam.h>
@@ -1655,29 +1521,9 @@ static void __exit tnt4882_exit_module(void)
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-/*
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
- * you do not define PCMCIA_DEBUG at all, all the debug code will be
- * left out. If you compile with PCMCIA_DEBUG=0, the debug code will
- * be present but disabled -- but it can then be enabled for specific
- * modules at load time with a 'pc_debug=#' option to insmod.
- */
-#define PCMCIA_DEBUG 1
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) \
- do {if (pc_debug > (n)) \
- pr_debug(args); } \
- while (0)
-#else
-#define DEBUG(args...)
-#endif
-
static int ni_gpib_config(struct pcmcia_device *link);
static void ni_gpib_release(struct pcmcia_device *link);
-static int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config);
-static void ni_pcmcia_detach(gpib_board_t *board);
+static void ni_pcmcia_detach(struct gpib_board *board);
/*
* A linked list of "instances" of the dummy device. Each actual
@@ -1696,7 +1542,7 @@ static struct pcmcia_device *curr_dev;
struct local_info_t {
struct pcmcia_device *p_dev;
- gpib_board_t *dev;
+ struct gpib_board *dev;
int stop;
struct bus_operations *bus;
};
@@ -1710,9 +1556,7 @@ struct local_info_t {
static int ni_gpib_probe(struct pcmcia_device *link)
{
struct local_info_t *info;
- //struct gpib_board_t *dev;
-
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev;
/* Allocate space for private device-specific data */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -1745,9 +1589,7 @@ static int ni_gpib_probe(struct pcmcia_device *link)
static void ni_gpib_remove(struct pcmcia_device *link)
{
struct local_info_t *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
-
- DEBUG(0, "%s(%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
if (info->dev)
ni_pcmcia_detach(info->dev);
@@ -1776,11 +1618,9 @@ static int ni_gpib_config_iteration(struct pcmcia_device *link, void *priv_data)
static int ni_gpib_config(struct pcmcia_device *link)
{
//struct local_info_t *info = link->priv;
- //gpib_board_t *dev = info->dev;
+ //struct gpib_board *dev = info->dev;
int last_ret;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
-
last_ret = pcmcia_loop_config(link, &ni_gpib_config_iteration, NULL);
if (last_ret) {
dev_warn(&link->dev, "no configuration found\n");
@@ -1803,18 +1643,16 @@ static int ni_gpib_config(struct pcmcia_device *link)
*/
static void ni_gpib_release(struct pcmcia_device *link)
{
- DEBUG(0, "%s(0x%p)\n", __func__, link);
pcmcia_disable_device(link);
} /* ni_gpib_release */
static int ni_gpib_suspend(struct pcmcia_device *link)
{
//struct local_info_t *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
if (link->open)
- pr_err("Device still open ???\n");
+ dev_warn(&link->dev, "Device still open\n");
//netif_device_detach(dev);
return 0;
@@ -1823,12 +1661,10 @@ static int ni_gpib_suspend(struct pcmcia_device *link)
static int ni_gpib_resume(struct pcmcia_device *link)
{
//struct local_info_t *info = link->priv;
- //struct gpib_board_t *dev = info->dev;
- DEBUG(0, "%s(0x%p)\n", __func__, link);
+ //struct struct gpib_board *dev = info->dev;
/*if (link->open) {
* ni_gpib_probe(dev); / really?
- * printk("Gpib resumed ???\n");
* //netif_device_attach(dev);
*}
*/
@@ -1854,32 +1690,28 @@ static struct pcmcia_driver ni_gpib_cs_driver = {
.resume = ni_gpib_resume,
};
-int __init init_ni_gpib_cs(void)
+static int __init init_ni_gpib_cs(void)
{
return pcmcia_register_driver(&ni_gpib_cs_driver);
}
-void __exit exit_ni_gpib_cs(void)
+static void __exit exit_ni_gpib_cs(void)
{
- DEBUG(0, "ni_gpib_cs: unloading\n");
pcmcia_unregister_driver(&ni_gpib_cs_driver);
}
static const int pcmcia_gpib_iosize = 32;
-int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
+static int ni_pcmcia_attach(struct gpib_board *board, const gpib_board_config_t *config)
{
struct local_info_t *info;
struct tnt4882_priv *tnt_priv;
struct nec7210_priv *nec_priv;
int isr_flags = IRQF_SHARED;
+ int retval;
- DEBUG(0, "%s(0x%p)\n", __func__, board);
-
- if (!curr_dev) {
- pr_err("gpib: no NI PCMCIA board found\n");
- return -1;
- }
+ if (!curr_dev)
+ return -ENODEV;
info = curr_dev->priv;
info->dev = board;
@@ -1888,6 +1720,7 @@ int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
if (tnt4882_allocate_private(board))
return -ENOMEM;
+
tnt_priv = board->private_data;
nec_priv = &tnt_priv->nec7210_priv;
nec_priv->type = TNT4882;
@@ -1895,23 +1728,20 @@ int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
nec_priv->write_byte = nec7210_locking_ioport_write_byte;
nec_priv->offset = atgpib_reg_offset;
- DEBUG(0, "ioport1 window attributes: 0x%lx\n", curr_dev->resource[0]->flags);
if (!request_region(curr_dev->resource[0]->start, resource_size(curr_dev->resource[0]),
- "tnt4882")) {
- pr_err("gpib: ioports starting at 0x%lx are already in use\n",
- (unsigned long)curr_dev->resource[0]->start);
- return -EIO;
- }
+ DRV_NAME))
+ return -ENOMEM;
nec_priv->mmiobase = ioport_map(curr_dev->resource[0]->start,
resource_size(curr_dev->resource[0]));
if (!nec_priv->mmiobase)
- return -1;
+ return -ENOMEM;
// get irq
- if (request_irq(curr_dev->irq, tnt4882_interrupt, isr_flags, "tnt4882", board)) {
- pr_err("gpib: can't request IRQ %d\n", curr_dev->irq);
- return -1;
+ retval = request_irq(curr_dev->irq, tnt4882_interrupt, isr_flags, DRV_NAME, board);
+ if (retval) {
+ dev_err(board->gpib_dev, "failed to obtain PCMCIA irq %d\n", curr_dev->irq);
+ return retval;
}
tnt_priv->irq = curr_dev->irq;
@@ -1920,13 +1750,11 @@ int ni_pcmcia_attach(gpib_board_t *board, const gpib_board_config_t *config)
return 0;
}
-void ni_pcmcia_detach(gpib_board_t *board)
+static void ni_pcmcia_detach(struct gpib_board *board)
{
struct tnt4882_priv *tnt_priv = board->private_data;
struct nec7210_priv *nec_priv;
- DEBUG(0, "%s(0x%p)\n", __func__, board);
-
if (tnt_priv) {
nec_priv = &tnt_priv->nec7210_priv;
if (tnt_priv->irq)
@@ -1941,7 +1769,63 @@ void ni_pcmcia_detach(gpib_board_t *board)
tnt4882_free_private(board);
}
-#endif // GPIB_PCMCIA
+static gpib_interface_t ni_pcmcia_interface = {
+ .name = "ni_pcmcia",
+ .attach = ni_pcmcia_attach,
+ .detach = ni_pcmcia_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response = tnt4882_serial_poll_response,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+static gpib_interface_t ni_pcmcia_accel_interface = {
+ .name = "ni_pcmcia_accel",
+ .attach = ni_pcmcia_attach,
+ .detach = ni_pcmcia_detach,
+ .read = tnt4882_accel_read,
+ .write = tnt4882_accel_write,
+ .command = tnt4882_command,
+ .take_control = tnt4882_take_control,
+ .go_to_standby = tnt4882_go_to_standby,
+ .request_system_control = tnt4882_request_system_control,
+ .interface_clear = tnt4882_interface_clear,
+ .remote_enable = tnt4882_remote_enable,
+ .enable_eos = tnt4882_enable_eos,
+ .disable_eos = tnt4882_disable_eos,
+ .parallel_poll = tnt4882_parallel_poll,
+ .parallel_poll_configure = tnt4882_parallel_poll_configure,
+ .parallel_poll_response = tnt4882_parallel_poll_response,
+ .local_parallel_poll_mode = NULL, // XXX
+ .line_status = tnt4882_line_status,
+ .update_status = tnt4882_update_status,
+ .primary_address = tnt4882_primary_address,
+ .secondary_address = tnt4882_secondary_address,
+ .serial_poll_response = tnt4882_serial_poll_response,
+ .serial_poll_status = tnt4882_serial_poll_status,
+ .t1_delay = tnt4882_t1_delay,
+ .return_to_local = tnt4882_return_to_local,
+};
+
+#endif // CONFIG_GPIB_PCMCIA
module_init(tnt4882_init_module);
module_exit(tnt4882_exit_module);
diff --git a/drivers/staging/gpib/uapi/gpib_user.h b/drivers/staging/gpib/uapi/gpib_user.h
index 0896a55a758f..5ff4588686fd 100644
--- a/drivers/staging/gpib/uapi/gpib_user.h
+++ b/drivers/staging/gpib/uapi/gpib_user.h
@@ -106,26 +106,15 @@ enum eos_flags {
/* GPIB Bus Control Lines bit vector */
enum bus_control_line {
- ValidDAV = 0x01,
- ValidNDAC = 0x02,
- ValidNRFD = 0x04,
- ValidIFC = 0x08,
- ValidREN = 0x10,
- ValidSRQ = 0x20,
- ValidATN = 0x40,
- ValidEOI = 0x80,
- ValidALL = 0xff,
- BusDAV = 0x0100, /* DAV line status bit */
- BusNDAC = 0x0200, /* NDAC line status bit */
- BusNRFD = 0x0400, /* NRFD line status bit */
- BusIFC = 0x0800, /* IFC line status bit */
- BusREN = 0x1000, /* REN line status bit */
- BusSRQ = 0x2000, /* SRQ line status bit */
- BusATN = 0x4000, /* ATN line status bit */
- BusEOI = 0x8000 /* EOI line status bit */
-};
-
-enum old_bus_control_line {
+ VALID_DAV = 0x01,
+ VALID_NDAC = 0x02,
+ VALID_NRFD = 0x04,
+ VALID_IFC = 0x08,
+ VALID_REN = 0x10,
+ VALID_SRQ = 0x20,
+ VALID_ATN = 0x40,
+ VALID_EOI = 0x80,
+ VALID_ALL = 0xff,
BUS_DAV = 0x0100, /* DAV line status bit */
BUS_NDAC = 0x0200, /* NDAC line status bit */
BUS_NRFD = 0x0400, /* NRFD line status bit */
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 8eab94cb06fa..308ed1ca9947 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -948,7 +948,8 @@ static int gb_tty_init(void)
{
int retval = 0;
- gb_tty_driver = tty_alloc_driver(GB_NUM_MINORS, 0);
+ gb_tty_driver = tty_alloc_driver(GB_NUM_MINORS, TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_DYNAMIC_DEV);
if (IS_ERR(gb_tty_driver)) {
pr_err("Can not allocate tty driver\n");
retval = -ENOMEM;
@@ -961,7 +962,6 @@ static int gb_tty_init(void)
gb_tty_driver->minor_start = 0;
gb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
gb_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
gb_tty_driver->init_termios = tty_std_termios;
gb_tty_driver->init_termios.c_cflag = B9600 | CS8 |
CREAD | HUPCL | CLOCAL;
diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c
index 17fd980c9d3c..2855ba2296ac 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -781,7 +781,7 @@ static void prp_stop(struct prp_priv *priv)
imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->underrun_buf);
/* cancel the EOF timeout timer */
- del_timer_sync(&priv->eof_timeout_timer);
+ timer_delete_sync(&priv->eof_timeout_timer);
prp_put_ipu_resources(priv);
}
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 3edbc57be2ca..f1d7fce8c020 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -695,7 +695,7 @@ static void csi_idmac_stop(struct csi_priv *priv)
imx_media_free_dma_buf(priv->dev, &priv->underrun_buf);
/* cancel the EOF timeout timer */
- del_timer_sync(&priv->eof_timeout_timer);
+ timer_delete_sync(&priv->eof_timeout_timer);
csi_idmac_put_ipu_resources(priv);
}
diff --git a/drivers/staging/rtl8723bs/Kconfig b/drivers/staging/rtl8723bs/Kconfig
index 8d48c61961a6..353e6ee2c145 100644
--- a/drivers/staging/rtl8723bs/Kconfig
+++ b/drivers/staging/rtl8723bs/Kconfig
@@ -4,6 +4,7 @@ config RTL8723BS
depends on WLAN && MMC && CFG80211
depends on m
select CRYPTO
+ select CRYPTO_LIB_AES
select CRYPTO_LIB_ARC4
help
This option enables support for RTL8723BS SDIO drivers, such as
diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c
index a6dc88dd4ba1..50022bb5911e 100644
--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
+++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
@@ -324,7 +324,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
{
unsigned char sta_band = 0, shortGIrate = false;
unsigned int tx_ra_bitmap = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex
*pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
@@ -372,9 +372,9 @@ void update_bmc_sta(struct adapter *padapter)
unsigned char network_type;
int supportRateNum = 0;
unsigned int tx_ra_bitmap = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex
*pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
@@ -451,9 +451,9 @@ void update_bmc_sta(struct adapter *padapter)
void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
struct ht_priv *phtpriv_sta = &psta->htpriv;
u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0;
@@ -563,10 +563,10 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
static void update_ap_info(struct adapter *padapter, struct sta_info *psta)
{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex
*pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
psta->wireless_mode = pmlmeext->cur_wireless_mode;
@@ -609,7 +609,7 @@ static void update_hw_ht_param(struct adapter *padapter)
unsigned char max_AMPDU_len;
unsigned char min_MPDU_spacing;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
/* handle A-MPDU parameter field
*
@@ -645,13 +645,13 @@ void start_bss_network(struct adapter *padapter)
u32 acparm;
int ie_len;
struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct security_priv *psecuritypriv = &(padapter->securitypriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
struct wlan_bssid_ex
*pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
struct HT_info_element *pht_info = NULL;
u8 cbw40_enable = 0;
@@ -823,7 +823,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
struct registry_priv *pregistrypriv = &padapter->registrypriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex
*pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
u8 *ie = pbss_network->ies;
@@ -845,7 +845,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
pbss_network->rssi = 0;
- memcpy(pbss_network->mac_address, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ memcpy(pbss_network->mac_address, myid(&padapter->eeprompriv), ETH_ALEN);
/* beacon interval */
p = rtw_get_beacon_interval_from_ie(ie);/* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */
@@ -1186,7 +1186,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
if ((NUM_ACL - 1) < pacl_list->num)
return (-1);
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
phead = get_list_head(pacl_node_q);
list_for_each(plist, phead) {
@@ -1200,12 +1200,12 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
if (added)
return ret;
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
for (i = 0; i < NUM_ACL; i++) {
paclnode = &pacl_list->aclnode[i];
@@ -1225,7 +1225,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
return ret;
}
@@ -1238,7 +1238,7 @@ void rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
struct __queue *pacl_node_q = &pacl_list->acl_node_q;
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
phead = get_list_head(pacl_node_q);
list_for_each_safe(plist, tmp, phead) {
@@ -1258,7 +1258,7 @@ void rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
}
@@ -1308,7 +1308,7 @@ static int rtw_ap_set_key(
u8 keylen;
struct cmd_obj *pcmd;
struct setkey_parm *psetkeyparm;
- struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
int res = _SUCCESS;
pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
@@ -1345,7 +1345,7 @@ static int rtw_ap_set_key(
keylen = 16;
}
- memcpy(&(psetkeyparm->key[0]), key, keylen);
+ memcpy(&psetkeyparm->key[0], key, keylen);
pcmd->cmdcode = _SetKey_CMD_;
pcmd->parmbuf = (u8 *)psetkeyparm;
@@ -1397,10 +1397,10 @@ static void update_bcn_fixed_ie(struct adapter *padapter)
static void update_bcn_erpinfo_ie(struct adapter *padapter)
{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
unsigned char *p, *ie = pnetwork->ies;
u32 len = 0;
@@ -1461,10 +1461,10 @@ static void update_bcn_wps_ie(struct adapter *padapter)
u8 *pbackup_remainder_ie = NULL;
uint wps_ielen = 0, wps_offset, remainder_ielen;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
unsigned char *ie = pnetwork->ies;
u32 ielen = pnetwork->ie_length;
@@ -1537,8 +1537,8 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
if (!padapter)
return;
- pmlmepriv = &(padapter->mlmepriv);
- pmlmeext = &(padapter->mlmeextpriv);
+ pmlmepriv = &padapter->mlmepriv;
+ pmlmeext = &padapter->mlmeextpriv;
/* pmlmeinfo = &(pmlmeext->mlmext_info); */
if (!pmlmeext->bstart_bss)
@@ -1619,7 +1619,7 @@ static int rtw_ht_operation_update(struct adapter *padapter)
{
u16 cur_op_mode, new_op_mode;
int op_mode_changes = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
if (pmlmepriv->htpriv.ht_option)
@@ -1703,8 +1703,8 @@ void associated_clients_update(struct adapter *padapter, u8 updated)
void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
{
u8 beacon_updated = false;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
if (!psta->no_short_preamble_set) {
@@ -1823,8 +1823,8 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
{
u8 beacon_updated = false;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!psta)
return beacon_updated;
@@ -1932,7 +1932,7 @@ void rtw_sta_flush(struct adapter *padapter)
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
@@ -1962,7 +1962,7 @@ void rtw_sta_flush(struct adapter *padapter)
void sta_info_update(struct adapter *padapter, struct sta_info *psta)
{
int flags = psta->flags;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
/* update wmm cap. */
if (WLAN_STA_WME & flags)
@@ -1991,7 +1991,7 @@ void sta_info_update(struct adapter *padapter, struct sta_info *psta)
void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
if (psta->state & _FW_LINKED) {
pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
@@ -2006,7 +2006,7 @@ void rtw_ap_restore_network(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *psta;
- struct security_priv *psecuritypriv = &(padapter->securitypriv);
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
struct list_head *phead, *plist;
u8 chk_alive_num = 0;
char chk_alive_list[NUM_STA];
@@ -2072,7 +2072,7 @@ void rtw_ap_restore_network(struct adapter *padapter)
void start_ap_mode(struct adapter *padapter)
{
int i;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct sta_priv *pstapriv = &padapter->stapriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
@@ -2109,7 +2109,7 @@ void start_ap_mode(struct adapter *padapter)
pmlmepriv->p2p_probe_resp_ie = NULL;
/* for ACL */
- INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
+ INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
pacl_list->num = 0;
pacl_list->mode = 0;
for (i = 0; i < NUM_ACL; i++) {
@@ -2124,7 +2124,7 @@ void stop_ap_mode(struct adapter *padapter)
struct rtw_wlan_acl_node *paclnode;
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
struct __queue *pacl_node_q = &pacl_list->acl_node_q;
@@ -2142,7 +2142,7 @@ void stop_ap_mode(struct adapter *padapter)
padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
/* for ACL */
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
phead = get_list_head(pacl_node_q);
list_for_each_safe(plist, tmp, phead) {
paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
@@ -2155,7 +2155,7 @@ void stop_ap_mode(struct adapter *padapter)
pacl_list->num--;
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
rtw_sta_flush(padapter);
diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c
index 64ce33c6fba1..1c9e8b01d9d8 100644
--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
+++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
@@ -1846,7 +1846,7 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
if (pcmd->res != H2C_SUCCESS)
_set_timer(&pmlmepriv->assoc_timer, 1);
- del_timer_sync(&pmlmepriv->assoc_timer);
+ timer_delete_sync(&pmlmepriv->assoc_timer);
spin_lock_bh(&pmlmepriv->lock);
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
index 5ded183aa08c..58de0c2fdd68 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -681,7 +681,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
spin_unlock_bh(&pmlmepriv->lock);
- del_timer_sync(&pmlmepriv->scan_to_timer);
+ timer_delete_sync(&pmlmepriv->scan_to_timer);
spin_lock_bh(&pmlmepriv->lock);
_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
}
@@ -1166,7 +1166,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
spin_unlock_bh(&pmlmepriv->lock);
/* s5. Cancel assoc_timer */
- del_timer_sync(&pmlmepriv->assoc_timer);
+ timer_delete_sync(&pmlmepriv->assoc_timer);
spin_lock_bh(&pmlmepriv->lock);
} else {
spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 952ce6dd5af9..3d36b6f005e0 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -412,9 +412,9 @@ void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
return;
if (padapter->bDriverStopped) {
- del_timer_sync(&pmlmeext->survey_timer);
- del_timer_sync(&pmlmeext->link_timer);
- /* del_timer_sync(&pmlmeext->ADDBA_timer); */
+ timer_delete_sync(&pmlmeext->survey_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
+ /* timer_delete_sync(&pmlmeext->ADDBA_timer); */
}
}
@@ -1390,7 +1390,7 @@ unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame)
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
return _SUCCESS;
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
/* status */
status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
@@ -1862,7 +1862,7 @@ unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv
break;
case 1: /* SA Query rsp */
- del_timer_sync(&pmlmeext->sa_query_timer);
+ timer_delete_sync(&pmlmeext->sa_query_timer);
break;
default:
break;
@@ -4185,7 +4185,7 @@ void start_clnt_auth(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
@@ -4210,7 +4210,7 @@ void start_clnt_assoc(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
@@ -4792,7 +4792,7 @@ static void rtw_mlmeext_disconnect(struct adapter *padapter)
flush_all_cam_entry(padapter);
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
/* pmlmepriv->LinkDetectInfo.TrafficBusyState = false; */
pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
@@ -5268,7 +5268,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
/* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
/* cancel link timer */
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
/* clear CAM */
flush_all_cam_entry(padapter);
@@ -5312,7 +5312,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* clear CAM */
flush_all_cam_entry(padapter);
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
/* set MSR to nolink -> infra. mode */
/* Set_MSR(padapter, _HW_STATE_NOLINK_); */
@@ -5425,7 +5425,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
set_channel_bwmode(padapter, ch, offset, bw);
/* cancel link timer */
- del_timer_sync(&pmlmeext->link_timer);
+ timer_delete_sync(&pmlmeext->link_timer);
start_clnt_join(padapter);
diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c
index a389ba5ecc6f..895116e9f4e7 100644
--- a/drivers/staging/rtl8723bs/core/rtw_recv.c
+++ b/drivers/staging/rtl8723bs/core/rtw_recv.c
@@ -1893,7 +1893,7 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *
spin_unlock_bh(&ppending_recvframe_queue->lock);
} else {
spin_unlock_bh(&ppending_recvframe_queue->lock);
- del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
+ timer_delete_sync(&preorder_ctrl->reordering_ctrl_timer);
}
return _SUCCESS;
diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
index 1b72f2196a1c..1d2b53c76afc 100644
--- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
@@ -158,7 +158,7 @@ u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
for (i = 0; i < 16 ; i++) {
preorder_ctrl = &psta->recvreorder_ctrl[i];
- del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
+ timer_delete_sync(&preorder_ctrl->reordering_ctrl_timer);
}
}
}
@@ -343,7 +343,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
/* _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); */
/* _rtw_init_sta_recv_priv(&psta->sta_recvpriv); */
- del_timer_sync(&psta->addba_retry_timer);
+ timer_delete_sync(&psta->addba_retry_timer);
/* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
for (i = 0; i < 16 ; i++) {
@@ -354,7 +354,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
preorder_ctrl = &psta->recvreorder_ctrl[i];
- del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
+ timer_delete_sync(&preorder_ctrl->reordering_ctrl_timer);
ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c
index b41ec89932af..1213a91cffff 100644
--- a/drivers/staging/rtl8723bs/hal/hal_com.c
+++ b/drivers/staging/rtl8723bs/hal/hal_com.c
@@ -884,6 +884,9 @@ static u32 Array_kfreemap[] = {
0xfc, 0x0,
};
+#define REG_RF_BB_GAIN_OFFSET 0x7f
+//#define RF_GAIN_OFFSET_MASK 0xfffff
+
void rtw_bb_rf_gain_offset(struct adapter *padapter)
{
u8 value = padapter->eeprompriv.EEPROMRFGainOffset;
diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c
index 21e9f1858745..8736c124f857 100644
--- a/drivers/staging/rtl8723bs/hal/sdio_ops.c
+++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c
@@ -871,7 +871,7 @@ void sd_int_dpc(struct adapter *adapter)
}
if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
- del_timer_sync(&(pwrctl->pwr_rpwm_timer));
+ timer_delete_sync(&(pwrctl->pwr_rpwm_timer));
SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);
diff --git a/drivers/staging/rtl8723bs/include/osdep_intf.h b/drivers/staging/rtl8723bs/include/osdep_intf.h
index 73199be78139..83a25598e962 100644
--- a/drivers/staging/rtl8723bs/include/osdep_intf.h
+++ b/drivers/staging/rtl8723bs/include/osdep_intf.h
@@ -8,33 +8,6 @@
#ifndef __OSDEP_INTF_H_
#define __OSDEP_INTF_H_
-
-struct intf_priv {
-
- u8 *intf_dev;
- u32 max_iosz; /* USB2.0: 128, USB1.1: 64, SDIO:64 */
- u32 max_xmitsz; /* USB2.0: unlimited, SDIO:512 */
- u32 max_recvsz; /* USB2.0: unlimited, SDIO:512 */
-
- volatile u8 *io_rwmem;
- volatile u8 *allocated_io_rwmem;
- u32 io_wsz; /* unit: 4bytes */
- u32 io_rsz;/* unit: 4bytes */
- u8 intf_status;
-
- void (*_bus_io)(u8 *priv);
-
-/*
-Under Sync. IRP (SDIO/USB)
-A protection mechanism is necessary for the io_rwmem(read/write protocol)
-
-Under Async. IRP (SDIO/USB)
-The protection mechanism is through the pending queue.
-*/
-
- struct mutex ioctl_mutex;
-};
-
struct dvobj_priv *devobj_init(void);
void devobj_deinit(struct dvobj_priv *pdvobj);
diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h
index e6d6e9de5474..a4a14474c35d 100644
--- a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h
+++ b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h
@@ -15,7 +15,6 @@
#include "rtl8723b_recv.h"
#include "rtl8723b_xmit.h"
#include "rtl8723b_cmd.h"
-#include "rtw_mp.h"
#include "hal_pwr_seq.h"
#include "Hal8192CPhyReg.h"
#include "hal_phy_cfg.h"
diff --git a/drivers/staging/rtl8723bs/include/rtw_io.h b/drivers/staging/rtl8723bs/include/rtw_io.h
index 0ee87be6dc4f..adf1de4d7924 100644
--- a/drivers/staging/rtl8723bs/include/rtw_io.h
+++ b/drivers/staging/rtl8723bs/include/rtw_io.h
@@ -8,16 +8,7 @@
#ifndef _RTW_IO_H_
#define _RTW_IO_H_
-/*
- For prompt mode accessing, caller shall free io_req
- Otherwise, io_handler will free io_req
-*/
-
-/* below is for the intf_option bit definition... */
-
-struct intf_priv;
struct intf_hdl;
-struct io_queue;
struct _io_ops {
u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
@@ -36,8 +27,6 @@ struct _io_ops {
void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
- void (*_sync_irp_protocol_rw)(struct io_queue *pio_q);
-
u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr);
u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
@@ -49,18 +38,6 @@ struct _io_ops {
void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
};
-struct io_req {
- struct list_head list;
- u32 addr;
- volatile u32 val;
- u32 command;
- u32 status;
- u8 *pbuf;
-
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt);
- u8 *cnxt;
-};
-
struct intf_hdl {
struct adapter *padapter;
struct dvobj_priv *pintf_dev;/* pointer to &(padapter->dvobjpriv); */
@@ -74,21 +51,6 @@ struct intf_hdl {
int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj);
void rtw_reset_continual_io_error(struct dvobj_priv *dvobj);
-/*
-Below is the data structure used by _io_handler
-
-*/
-
-struct io_queue {
- spinlock_t lock;
- struct list_head free_ioreqs;
- struct list_head pending; /* The io_req list that will be served in the single protocol read/write. */
- struct list_head processing;
- u8 *free_ioreqs_buf; /* 4-byte aligned */
- u8 *pallocated_free_ioreqs_buf;
- struct intf_hdl intf;
-};
-
struct io_priv {
struct adapter *padapter;
@@ -97,20 +59,6 @@ struct io_priv {
};
-extern uint ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue);
-extern void sync_ioreq_enqueue(struct io_req *preq, struct io_queue *ioqueue);
-extern uint sync_ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue);
-
-
-extern uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue);
-extern struct io_req *alloc_ioreq(struct io_queue *pio_q);
-
-extern uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl);
-extern void unregister_intf_hdl(struct intf_hdl *pintfhdl);
-
-extern void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-extern void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-
extern u8 rtw_read8(struct adapter *adapter, u32 addr);
extern u16 rtw_read16(struct adapter *adapter, u32 addr);
extern u32 rtw_read32(struct adapter *adapter, u32 addr);
@@ -121,46 +69,6 @@ extern int rtw_write32(struct adapter *adapter, u32 addr, u32 val);
extern u32 rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-extern void rtw_write_scsi(struct adapter *adapter, u32 cnt, u8 *pmem);
-
-/* ioreq */
-extern void ioreq_read8(struct adapter *adapter, u32 addr, u8 *pval);
-extern void ioreq_read16(struct adapter *adapter, u32 addr, u16 *pval);
-extern void ioreq_read32(struct adapter *adapter, u32 addr, u32 *pval);
-extern void ioreq_write8(struct adapter *adapter, u32 addr, u8 val);
-extern void ioreq_write16(struct adapter *adapter, u32 addr, u16 val);
-extern void ioreq_write32(struct adapter *adapter, u32 addr, u32 val);
-
-
-extern uint async_read8(struct adapter *adapter, u32 addr, u8 *pbuff,
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt);
-extern uint async_read16(struct adapter *adapter, u32 addr, u8 *pbuff,
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt);
-extern uint async_read32(struct adapter *adapter, u32 addr, u8 *pbuff,
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt);
-
-extern void async_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-extern void async_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-
-extern void async_write8(struct adapter *adapter, u32 addr, u8 val,
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt);
-extern void async_write16(struct adapter *adapter, u32 addr, u16 val,
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt);
-extern void async_write32(struct adapter *adapter, u32 addr, u32 val,
- void (*_async_io_callback)(struct adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt);
-
-extern void async_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-extern void async_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-
-
int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct adapter *padapter, struct _io_ops *pops));
-
-extern uint alloc_io_queue(struct adapter *adapter);
-extern void free_io_queue(struct adapter *adapter);
-extern void async_bus_io(struct io_queue *pio_q);
-extern void bus_sync_io(struct io_queue *pio_q);
-extern u32 _ioreq2rwmem(struct io_queue *pio_q);
-extern void dev_power_down(struct adapter *Adapter, u8 bpwrup);
-
#endif /* _RTL8711_IO_H_ */
diff --git a/drivers/staging/rtl8723bs/include/rtw_mp.h b/drivers/staging/rtl8723bs/include/rtw_mp.h
deleted file mode 100644
index 5a1cbd2ed851..000000000000
--- a/drivers/staging/rtl8723bs/include/rtw_mp.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- ******************************************************************************/
-#ifndef _RTW_MP_H_
-#define _RTW_MP_H_
-
-#define MAX_MP_XMITBUF_SZ 2048
-
-struct mp_xmit_frame {
- struct list_head list;
-
- struct pkt_attrib attrib;
-
- struct sk_buff *pkt;
-
- int frame_tag;
-
- struct adapter *padapter;
-
- uint mem[(MAX_MP_XMITBUF_SZ >> 2)];
-};
-
-struct mp_wiparam {
- u32 bcompleted;
- u32 act_type;
- u32 io_offset;
- u32 io_value;
-};
-
-struct mp_tx {
- u8 stop;
- u32 count, sended;
- u8 payload;
- struct pkt_attrib attrib;
- /* struct tx_desc desc; */
- /* u8 resvdtx[7]; */
- u8 desc[TXDESC_SIZE];
- u8 *pallocated_buf;
- u8 *buf;
- u32 buf_size, write_size;
- void *PktTxThread;
-};
-
-#define MP_MAX_LINES 1000
-#define MP_MAX_LINES_BYTES 256
-
-typedef void (*MPT_WORK_ITEM_HANDLER)(void *Adapter);
-struct mpt_context {
- /* Indicate if we have started Mass Production Test. */
- bool bMassProdTest;
-
- /* Indicate if the driver is unloading or unloaded. */
- bool bMptDrvUnload;
-
- struct timer_list MPh2c_timeout_timer;
-/* Event used to sync H2c for BT control */
-
- bool MptH2cRspEvent;
- bool MptBtC2hEvent;
- bool bMPh2c_timeout;
-
- /* 8190 PCI does not support NDIS_WORK_ITEM. */
- /* Work Item for Mass Production Test. */
- /* NDIS_WORK_ITEM MptWorkItem; */
-/* RT_WORK_ITEM MptWorkItem; */
- /* Event used to sync the case unloading driver and MptWorkItem is still in progress. */
-/* NDIS_EVENT MptWorkItemEvent; */
- /* To protect the following variables. */
-/* NDIS_SPIN_LOCK MptWorkItemSpinLock; */
- /* Indicate a MptWorkItem is scheduled and not yet finished. */
- bool bMptWorkItemInProgress;
- /* An instance which implements function and context of MptWorkItem. */
- MPT_WORK_ITEM_HANDLER CurrMptAct;
-
- /* 1 =Start, 0 =Stop from UI. */
- u32 MptTestStart;
- /* _TEST_MODE, defined in MPT_Req2.h */
- u32 MptTestItem;
- /* Variable needed in each implementation of CurrMptAct. */
- u32 MptActType; /* Type of action performed in CurrMptAct. */
- /* The Offset of IO operation is depend of MptActType. */
- u32 MptIoOffset;
- /* The Value of IO operation is depend of MptActType. */
- u32 MptIoValue;
- /* The RfPath of IO operation is depend of MptActType. */
- u32 MptRfPath;
-
- enum wireless_mode MptWirelessModeToSw; /* Wireless mode to switch. */
- u8 MptChannelToSw; /* Channel to switch. */
- u8 MptInitGainToSet; /* Initial gain to set. */
- u32 MptBandWidth; /* bandwidth to switch. */
- u32 MptRateIndex; /* rate index. */
- /* Register value kept for Single Carrier Tx test. */
- u8 btMpCckTxPower;
- /* Register value kept for Single Carrier Tx test. */
- u8 btMpOfdmTxPower;
- /* For MP Tx Power index */
- u8 TxPwrLevel[2]; /* rf-A, rf-B */
- u32 RegTxPwrLimit;
- /* Content of RCR Register for Mass Production Test. */
- u32 MptRCR;
- /* true if we only receive packets with specific pattern. */
- bool bMptFilterPattern;
- /* Rx OK count, statistics used in Mass Production Test. */
- u32 MptRxOkCnt;
- /* Rx CRC32 error count, statistics used in Mass Production Test. */
- u32 MptRxCrcErrCnt;
-
- bool bCckContTx; /* true if we are in CCK Continuous Tx test. */
- bool bOfdmContTx; /* true if we are in OFDM Continuous Tx test. */
- bool bStartContTx; /* true if we have start Continuous Tx test. */
- /* true if we are in Single Carrier Tx test. */
- bool bSingleCarrier;
- /* true if we are in Carrier Suppression Tx Test. */
- bool bCarrierSuppression;
- /* true if we are in Single Tone Tx test. */
- bool bSingleTone;
-
- /* ACK counter asked by K.Y.. */
- bool bMptEnableAckCounter;
- u32 MptAckCounter;
-
- /* SD3 Willis For 8192S to save 1T/2T RF table for ACUT Only fro ACUT delete later ~~~! */
- /* s8 BufOfLines[2][MAX_LINES_HWCONFIG_TXT][MAX_BYTES_LINE_HWCONFIG_TXT]; */
- /* s8 BufOfLines[2][MP_MAX_LINES][MP_MAX_LINES_BYTES]; */
- /* s32 RfReadLine[2]; */
-
- u8 APK_bound[2]; /* for APK path A/path B */
- bool bMptIndexEven;
-
- u8 backup0xc50;
- u8 backup0xc58;
- u8 backup0xc30;
- u8 backup0x52_RF_A;
- u8 backup0x52_RF_B;
-
- u32 backup0x58_RF_A;
- u32 backup0x58_RF_B;
-
- u8 h2cReqNum;
- u8 c2hBuf[32];
-
- u8 btInBuf[100];
- u32 mptOutLen;
- u8 mptOutBuf[100];
-
-};
-/* endif */
-
-/* define RTPRIV_IOCTL_MP (SIOCIWFIRSTPRIV + 0x17) */
-enum {
- WRITE_REG = 1,
- READ_REG,
- WRITE_RF,
- READ_RF,
- MP_START,
- MP_STOP,
- MP_RATE,
- MP_CHANNEL,
- MP_BANDWIDTH,
- MP_TXPOWER,
- MP_ANT_TX,
- MP_ANT_RX,
- MP_CTX,
- MP_QUERY,
- MP_ARX,
- MP_PSD,
- MP_PWRTRK,
- MP_THER,
- MP_IOCTL,
- EFUSE_GET,
- EFUSE_SET,
- MP_RESET_STATS,
- MP_DUMP,
- MP_PHYPARA,
- MP_SetRFPathSwh,
- MP_QueryDrvStats,
- MP_SetBT,
- CTA_TEST,
- MP_DISABLE_BT_COEXIST,
- MP_PwrCtlDM,
- MP_NULL,
- MP_GET_TXPOWER_INX,
-};
-
-struct mp_priv {
- struct adapter *papdater;
-
- /* Testing Flag */
- u32 mode;/* 0 for normal type packet, 1 for loopback packet (16bytes TXCMD) */
-
- u32 prev_fw_state;
-
- /* OID cmd handler */
- struct mp_wiparam workparam;
-/* u8 act_in_progress; */
-
- /* Tx Section */
- u8 TID;
- u32 tx_pktcount;
- u32 pktInterval;
- struct mp_tx tx;
-
- /* Rx Section */
- u32 rx_bssidpktcount;
- u32 rx_pktcount;
- u32 rx_pktcount_filter_out;
- u32 rx_crcerrpktcount;
- u32 rx_pktloss;
- bool rx_bindicatePkt;
- struct recv_stat rxstat;
-
- /* RF/BB relative */
- u8 channel;
- u8 bandwidth;
- u8 prime_channel_offset;
- u8 txpoweridx;
- u8 txpoweridx_b;
- u8 rateidx;
- u32 preamble;
-/* u8 modem; */
- u32 CrystalCap;
-/* u32 curr_crystalcap; */
-
- u16 antenna_tx;
- u16 antenna_rx;
-/* u8 curr_rfpath; */
-
- u8 check_mp_pkt;
-
- u8 bSetTxPower;
-/* uint ForcedDataRate; */
- u8 mp_dm;
- u8 mac_filter[ETH_ALEN];
- u8 bmac_filter;
-
- struct wlan_network mp_network;
- NDIS_802_11_MAC_ADDRESS network_macaddr;
-
- u8 *pallocated_mp_xmitframe_buf;
- u8 *pmp_xmtframe_buf;
- struct __queue free_mp_xmitqueue;
- u32 free_mp_xmitframe_cnt;
- bool bSetRxBssid;
- bool bTxBufCkFail;
-
- struct mpt_context MptCtx;
-
- u8 *TXradomBuffer;
-};
-
-/* Hardware Registers */
-extern u8 mpdatarate[NumRates];
-
-#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */
-
-#define REG_RF_BB_GAIN_OFFSET 0x7f
-#define RF_GAIN_OFFSET_MASK 0xfffff
-
-/* */
-/* struct mp_xmit_frame *alloc_mp_xmitframe(struct mp_priv *pmp_priv); */
-/* int free_mp_xmitframe(struct xmit_priv *pxmitpriv, struct mp_xmit_frame *pmp_xmitframe); */
-
-s32 init_mp_priv(struct adapter *padapter);
-void free_mp_priv(struct mp_priv *pmp_priv);
-s32 MPT_InitializeAdapter(struct adapter *padapter, u8 Channel);
-void MPT_DeInitAdapter(struct adapter *padapter);
-s32 mp_start_test(struct adapter *padapter);
-void mp_stop_test(struct adapter *padapter);
-
-u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
-void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
-
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
-
-void SetChannel(struct adapter *padapter);
-void SetBandwidth(struct adapter *padapter);
-int SetTxPower(struct adapter *padapter);
-void SetAntennaPathPower(struct adapter *padapter);
-void SetDataRate(struct adapter *padapter);
-
-void SetAntenna(struct adapter *padapter);
-
-s32 SetThermalMeter(struct adapter *padapter, u8 target_ther);
-void GetThermalMeter(struct adapter *padapter, u8 *value);
-
-void SetContinuousTx(struct adapter *padapter, u8 bStart);
-void SetSingleCarrierTx(struct adapter *padapter, u8 bStart);
-void SetSingleToneTx(struct adapter *padapter, u8 bStart);
-void SetCarrierSuppressionTx(struct adapter *padapter, u8 bStart);
-void PhySetTxPowerLevel(struct adapter *padapter);
-
-void fill_txdesc_for_mp(struct adapter *padapter, u8 *ptxdesc);
-void SetPacketTx(struct adapter *padapter);
-void SetPacketRx(struct adapter *padapter, u8 bStartRx);
-
-void ResetPhyRxPktCount(struct adapter *padapter);
-u32 GetPhyRxPktReceived(struct adapter *padapter);
-u32 GetPhyRxPktCRC32Error(struct adapter *padapter);
-
-s32 SetPowerTracking(struct adapter *padapter, u8 enable);
-void GetPowerTracking(struct adapter *padapter, u8 *enable);
-
-u32 mp_query_psd(struct adapter *padapter, u8 *data);
-
-void Hal_SetAntenna(struct adapter *padapter);
-void Hal_SetBandwidth(struct adapter *padapter);
-
-void Hal_SetTxPower(struct adapter *padapter);
-void Hal_SetCarrierSuppressionTx(struct adapter *padapter, u8 bStart);
-void Hal_SetSingleToneTx(struct adapter *padapter, u8 bStart);
-void Hal_SetSingleCarrierTx(struct adapter *padapter, u8 bStart);
-void Hal_SetContinuousTx(struct adapter *padapter, u8 bStart);
-
-void Hal_SetDataRate(struct adapter *padapter);
-void Hal_SetChannel(struct adapter *padapter);
-void Hal_SetAntennaPathPower(struct adapter *padapter);
-s32 Hal_SetThermalMeter(struct adapter *padapter, u8 target_ther);
-s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable);
-void Hal_GetPowerTracking(struct adapter *padapter, u8 *enable);
-void Hal_GetThermalMeter(struct adapter *padapter, u8 *value);
-void Hal_mpt_SwitchRfSetting(struct adapter *padapter);
-void Hal_MPT_CCKTxPowerAdjust(struct adapter *Adapter, bool bInCH14);
-void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *padapter, bool beven);
-void Hal_SetCCKTxPower(struct adapter *padapter, u8 *TxPower);
-void Hal_SetOFDMTxPower(struct adapter *padapter, u8 *TxPower);
-void Hal_TriggerRFThermalMeter(struct adapter *padapter);
-u8 Hal_ReadRFThermalMeter(struct adapter *padapter);
-void Hal_SetCCKContinuousTx(struct adapter *padapter, u8 bStart);
-void Hal_SetOFDMContinuousTx(struct adapter *padapter, u8 bStart);
-void Hal_ProSetCrystalCap(struct adapter *padapter, u32 CrystalCapVal);
-void MP_PHY_SetRFPathSwitch(struct adapter *padapter, bool bMain);
-u32 mpt_ProQueryCalTxPower(struct adapter *padapter, u8 RfPath);
-void MPT_PwrCtlDM(struct adapter *padapter, u32 bstart);
-u8 MptToMgntRate(u32 MptRateIdx);
-
-#endif /* _RTW_MP_H_ */
diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
index 738a601c55bb..0248dff8f2aa 100644
--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
@@ -697,18 +697,18 @@ free_cmd_priv:
void rtw_cancel_all_timer(struct adapter *padapter)
{
- del_timer_sync(&padapter->mlmepriv.assoc_timer);
+ timer_delete_sync(&padapter->mlmepriv.assoc_timer);
- del_timer_sync(&padapter->mlmepriv.scan_to_timer);
+ timer_delete_sync(&padapter->mlmepriv.scan_to_timer);
- del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer);
+ timer_delete_sync(&padapter->mlmepriv.dynamic_chk_timer);
- del_timer_sync(&(adapter_to_pwrctl(padapter)->pwr_state_check_timer));
+ timer_delete_sync(&(adapter_to_pwrctl(padapter)->pwr_state_check_timer));
- del_timer_sync(&padapter->mlmepriv.set_scan_deny_timer);
+ timer_delete_sync(&padapter->mlmepriv.set_scan_deny_timer);
rtw_clear_scan_deny(padapter);
- del_timer_sync(&padapter->recvpriv.signal_stat_timer);
+ timer_delete_sync(&padapter->recvpriv.signal_stat_timer);
/* cancel dm timer */
rtw_hal_dm_deinit(padapter);
@@ -724,8 +724,6 @@ u8 rtw_free_drv_sw(struct adapter *padapter)
rtw_free_mlme_priv(&padapter->mlmepriv);
- /* free_io_queue(padapter); */
-
_rtw_free_xmit_priv(&padapter->xmitpriv);
_rtw_free_sta_priv(&padapter->stapriv); /* will free bcmc_stainfo here */
diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index 02860d3ec365..025dae3756aa 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -228,8 +228,8 @@ int ddk750_init_hw(struct initchip_param *p_init_param)
reg = peek32(VGA_CONFIGURATION);
reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE);
poke32(VGA_CONFIGURATION, reg);
+#ifdef CONFIG_X86
} else {
-#if defined(__i386__) || defined(__x86_64__)
/* set graphic mode via IO method */
outb_p(0x88, 0x3d4);
outb_p(0x06, 0x3d5);
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index deec33f63bcf..b839b50ac26a 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -658,8 +658,6 @@ static const struct vb2_ops bcm2835_mmal_video_qops = {
.buf_queue = buffer_queue,
.start_streaming = start_streaming,
.stop_streaming = stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
/* ------------------------------------------------------------------
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index a4e83e5d619b..5dbf8d53db09 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -97,13 +97,6 @@ struct vchiq_arm_state {
* tracked separately with the state.
*/
int peer_use_count;
-
- /*
- * Flag to indicate that the first vchiq connect has made it through.
- * This means that both sides should be fully ready, and we should
- * be able to suspend after this point.
- */
- int first_connect;
};
static int
@@ -271,7 +264,7 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state
return -ENXIO;
}
- dev_dbg(&pdev->dev, "arm: vchiq_init - done (slots %pK, phys %pad)\n",
+ dev_dbg(&pdev->dev, "arm: vchiq_init - done (slots %p, phys %pad)\n",
vchiq_slot_zero, &slot_phys);
mutex_init(&drv_mgmt->connected_mutex);
@@ -280,32 +273,23 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state
return 0;
}
-int
-vchiq_platform_init_state(struct vchiq_state *state)
+static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *state)
{
- struct vchiq_arm_state *platform_state;
-
- platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL);
- if (!platform_state)
- return -ENOMEM;
-
- rwlock_init(&platform_state->susp_res_lock);
-
- init_completion(&platform_state->ka_evt);
- atomic_set(&platform_state->ka_use_count, 0);
- atomic_set(&platform_state->ka_use_ack_count, 0);
- atomic_set(&platform_state->ka_release_count, 0);
-
- platform_state->state = state;
-
- state->platform_state = (struct opaque_platform_state *)platform_state;
-
- return 0;
+ return (struct vchiq_arm_state *)state->platform_state;
}
-static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *state)
+static void
+vchiq_platform_uninit(struct vchiq_drv_mgmt *mgmt)
{
- return (struct vchiq_arm_state *)state->platform_state;
+ struct vchiq_arm_state *arm_state;
+
+ kthread_stop(mgmt->state.sync_thread);
+ kthread_stop(mgmt->state.recycle_thread);
+ kthread_stop(mgmt->state.slot_handler_thread);
+
+ arm_state = vchiq_platform_get_arm_state(&mgmt->state);
+ if (!IS_ERR_OR_NULL(arm_state->ka_thread))
+ kthread_stop(arm_state->ka_thread);
}
void vchiq_dump_platform_state(struct seq_file *f)
@@ -368,7 +352,7 @@ void free_bulk_waiter(struct vchiq_instance *instance)
&instance->bulk_waiter_list, list) {
list_del(&waiter->list);
dev_dbg(instance->state->dev,
- "arm: bulk_waiter - cleaned up %pK for pid %d\n",
+ "arm: bulk_waiter - cleaned up %p for pid %d\n",
waiter, waiter->pid);
kfree(waiter);
}
@@ -622,7 +606,7 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl
mutex_lock(&instance->bulk_waiter_list_mutex);
list_add(&waiter->list, &instance->bulk_waiter_list);
mutex_unlock(&instance->bulk_waiter_list_mutex);
- dev_dbg(instance->state->dev, "arm: saved bulk_waiter %pK for pid %d\n",
+ dev_dbg(instance->state->dev, "arm: saved bulk_waiter %p for pid %d\n",
waiter, current->pid);
}
@@ -998,6 +982,39 @@ exit:
}
int
+vchiq_platform_init_state(struct vchiq_state *state)
+{
+ struct vchiq_arm_state *platform_state;
+ char threadname[16];
+
+ platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL);
+ if (!platform_state)
+ return -ENOMEM;
+
+ snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
+ state->id);
+ platform_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func,
+ (void *)state, threadname);
+ if (IS_ERR(platform_state->ka_thread)) {
+ dev_err(state->dev, "couldn't create thread %s\n", threadname);
+ return PTR_ERR(platform_state->ka_thread);
+ }
+
+ rwlock_init(&platform_state->susp_res_lock);
+
+ init_completion(&platform_state->ka_evt);
+ atomic_set(&platform_state->ka_use_count, 0);
+ atomic_set(&platform_state->ka_use_ack_count, 0);
+ atomic_set(&platform_state->ka_release_count, 0);
+
+ platform_state->state = state;
+
+ state->platform_state = (struct opaque_platform_state *)platform_state;
+
+ return 0;
+}
+
+int
vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
enum USE_TYPE_E use_type)
{
@@ -1312,37 +1329,19 @@ out:
return ret;
}
+void vchiq_platform_connected(struct vchiq_state *state)
+{
+ struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
+
+ wake_up_process(arm_state->ka_thread);
+}
+
void vchiq_platform_conn_state_changed(struct vchiq_state *state,
enum vchiq_connstate oldstate,
enum vchiq_connstate newstate)
{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
- char threadname[16];
-
dev_dbg(state->dev, "suspend: %d: %s->%s\n",
state->id, get_conn_state_name(oldstate), get_conn_state_name(newstate));
- if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED)
- return;
-
- write_lock_bh(&arm_state->susp_res_lock);
- if (arm_state->first_connect) {
- write_unlock_bh(&arm_state->susp_res_lock);
- return;
- }
-
- arm_state->first_connect = 1;
- write_unlock_bh(&arm_state->susp_res_lock);
- snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
- state->id);
- arm_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func,
- (void *)state,
- threadname);
- if (IS_ERR(arm_state->ka_thread)) {
- dev_err(state->dev, "suspend: Couldn't create thread %s\n",
- threadname);
- } else {
- wake_up_process(arm_state->ka_thread);
- }
}
static const struct of_device_id vchiq_of_match[] = {
@@ -1386,8 +1385,6 @@ static int vchiq_probe(struct platform_device *pdev)
return ret;
}
- vchiq_debugfs_init(&mgmt->state);
-
dev_dbg(&pdev->dev, "arm: platform initialised - version %d (min %d)\n",
VCHIQ_VERSION, VCHIQ_VERSION_MIN);
@@ -1398,9 +1395,12 @@ static int vchiq_probe(struct platform_device *pdev)
ret = vchiq_register_chrdev(&pdev->dev);
if (ret) {
dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
+ vchiq_platform_uninit(mgmt);
return ret;
}
+ vchiq_debugfs_init(&mgmt->state);
+
bcm2835_audio = vchiq_device_register(&pdev->dev, "bcm2835-audio");
bcm2835_camera = vchiq_device_register(&pdev->dev, "bcm2835-camera");
@@ -1410,19 +1410,12 @@ static int vchiq_probe(struct platform_device *pdev)
static void vchiq_remove(struct platform_device *pdev)
{
struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(&pdev->dev);
- struct vchiq_arm_state *arm_state;
vchiq_device_unregister(bcm2835_audio);
vchiq_device_unregister(bcm2835_camera);
vchiq_debugfs_deinit();
vchiq_deregister_chrdev();
-
- kthread_stop(mgmt->state.sync_thread);
- kthread_stop(mgmt->state.recycle_thread);
- kthread_stop(mgmt->state.slot_handler_thread);
-
- arm_state = vchiq_platform_get_arm_state(&mgmt->state);
- kthread_stop(arm_state->ka_thread);
+ vchiq_platform_uninit(mgmt);
}
static struct platform_driver vchiq_driver = {
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 8d5795db4f39..e7b0c800a205 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -470,7 +470,7 @@ make_service_callback(struct vchiq_service *service, enum vchiq_reason reason,
cb_userdata = bulk->cb_userdata;
}
- dev_dbg(service->state->dev, "core: %d: callback:%d (%s, %pK, %pK %pK)\n",
+ dev_dbg(service->state->dev, "core: %d: callback:%d (%s, %p, %p %p)\n",
service->state->id, service->localport, reason_names[reason],
header, cb_data, cb_userdata);
status = service->base.callback(service->instance, reason, header, service->handle,
@@ -778,7 +778,7 @@ process_free_data_message(struct vchiq_state *state, u32 *service_found,
complete(&quota->quota_event);
} else if (count == 0) {
dev_err(state->dev,
- "core: service %d message_use_count=%d (header %pK, msgid %x, header->msgid %x, header->size %x)\n",
+ "core: service %d message_use_count=%d (header %p, msgid %x, header->msgid %x, header->size %x)\n",
port, quota->message_use_count, header, msgid,
header->msgid, header->size);
WARN(1, "invalid message use count\n");
@@ -799,11 +799,11 @@ process_free_data_message(struct vchiq_state *state, u32 *service_found,
* it has dropped below its quota
*/
complete(&quota->quota_event);
- dev_dbg(state->dev, "core: %d: pfq:%d %x@%pK - slot_use->%d\n",
+ dev_dbg(state->dev, "core: %d: pfq:%d %x@%p - slot_use->%d\n",
state->id, port, header->size, header, count - 1);
} else {
dev_err(state->dev,
- "core: service %d slot_use_count=%d (header %pK, msgid %x, header->msgid %x, header->size %x)\n",
+ "core: service %d slot_use_count=%d (header %p, msgid %x, header->msgid %x, header->size %x)\n",
port, count, header, msgid, header->msgid, header->size);
WARN(1, "bad slot use count\n");
}
@@ -845,7 +845,7 @@ process_free_queue(struct vchiq_state *state, u32 *service_found,
*/
rmb();
- dev_dbg(state->dev, "core: %d: pfq %d=%pK %x %x\n",
+ dev_dbg(state->dev, "core: %d: pfq %d=%p %x %x\n",
state->id, slot_index, data, local->slot_queue_recycle,
slot_queue_available);
@@ -868,7 +868,7 @@ process_free_queue(struct vchiq_state *state, u32 *service_found,
pos += calc_stride(header->size);
if (pos > VCHIQ_SLOT_SIZE) {
dev_err(state->dev,
- "core: pfq - pos %x: header %pK, msgid %x, header->msgid %x, header->size %x\n",
+ "core: pfq - pos %x: header %p, msgid %x, header->msgid %x, header->size %x\n",
pos, header, msgid, header->msgid, header->size);
WARN(1, "invalid slot position\n");
}
@@ -1060,7 +1060,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service,
int tx_end_index;
int slot_use_count;
- dev_dbg(state->dev, "core: %d: qm %s@%pK,%zx (%d->%d)\n",
+ dev_dbg(state->dev, "core: %d: qm %s@%p,%zx (%d->%d)\n",
state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size,
VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid));
@@ -1117,7 +1117,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service,
VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
} else {
- dev_dbg(state->dev, "core: %d: qm %s@%pK,%zx (%d->%d)\n",
+ dev_dbg(state->dev, "core: %d: qm %s@%p,%zx (%d->%d)\n",
state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size,
VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid));
if (size != 0) {
@@ -1204,7 +1204,7 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,
state->id, oldmsgid);
}
- dev_dbg(state->dev, "sync: %d: qms %s@%pK,%x (%d->%d)\n",
+ dev_dbg(state->dev, "sync: %d: qms %s@%p,%x (%d->%d)\n",
state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size,
VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid));
@@ -1539,7 +1539,7 @@ create_pagelist(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr,
GFP_KERNEL);
- dev_dbg(instance->state->dev, "arm: %pK\n", pagelist);
+ dev_dbg(instance->state->dev, "arm: %p\n", pagelist);
if (!pagelist)
return NULL;
@@ -1692,7 +1692,7 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel
unsigned int num_pages = pagelistinfo->num_pages;
unsigned int cache_line_size;
- dev_dbg(instance->state->dev, "arm: %pK, %d\n", pagelistinfo->pagelist, actual);
+ dev_dbg(instance->state->dev, "arm: %p, %d\n", pagelistinfo->pagelist, actual);
drv_mgmt = dev_get_drvdata(instance->state->dev);
@@ -1849,7 +1849,7 @@ parse_open(struct vchiq_state *state, struct vchiq_header *header)
payload = (struct vchiq_open_payload *)header->data;
fourcc = payload->fourcc;
- dev_dbg(state->dev, "core: %d: prs OPEN@%pK (%d->'%p4cc')\n",
+ dev_dbg(state->dev, "core: %d: prs OPEN@%p (%d->'%p4cc')\n",
state->id, header, localport, &fourcc);
service = get_listening_service(state, fourcc);
@@ -1976,14 +1976,14 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
service = get_connected_service(state, remoteport);
if (service)
dev_warn(state->dev,
- "core: %d: prs %s@%pK (%d->%d) - found connected service %d\n",
+ "core: %d: prs %s@%p (%d->%d) - found connected service %d\n",
state->id, msg_type_str(type), header,
remoteport, localport, service->localport);
}
if (!service) {
dev_err(state->dev,
- "core: %d: prs %s@%pK (%d->%d) - invalid/closed service %d\n",
+ "core: %d: prs %s@%p (%d->%d) - invalid/closed service %d\n",
state->id, msg_type_str(type), header, remoteport,
localport, localport);
goto skip_message;
@@ -2003,7 +2003,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
if (((unsigned long)header & VCHIQ_SLOT_MASK) +
calc_stride(size) > VCHIQ_SLOT_SIZE) {
- dev_err(state->dev, "core: header %pK (msgid %x) - size %x too big for slot\n",
+ dev_err(state->dev, "core: header %p (msgid %x) - size %x too big for slot\n",
header, (unsigned int)msgid, (unsigned int)size);
WARN(1, "oversized for slot\n");
}
@@ -2022,7 +2022,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
service->peer_version = payload->version;
}
dev_dbg(state->dev,
- "core: %d: prs OPENACK@%pK,%x (%d->%d) v:%d\n",
+ "core: %d: prs OPENACK@%p,%x (%d->%d) v:%d\n",
state->id, header, size, remoteport, localport,
service->peer_version);
if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
@@ -2037,7 +2037,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
case VCHIQ_MSG_CLOSE:
WARN_ON(size); /* There should be no data */
- dev_dbg(state->dev, "core: %d: prs CLOSE@%pK (%d->%d)\n",
+ dev_dbg(state->dev, "core: %d: prs CLOSE@%p (%d->%d)\n",
state->id, header, remoteport, localport);
mark_service_closing_internal(service, 1);
@@ -2049,7 +2049,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
&service->base.fourcc, service->localport, service->remoteport);
break;
case VCHIQ_MSG_DATA:
- dev_dbg(state->dev, "core: %d: prs DATA@%pK,%x (%d->%d)\n",
+ dev_dbg(state->dev, "core: %d: prs DATA@%p,%x (%d->%d)\n",
state->id, header, size, remoteport, localport);
if ((service->remoteport == remoteport) &&
@@ -2069,7 +2069,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
}
break;
case VCHIQ_MSG_CONNECT:
- dev_dbg(state->dev, "core: %d: prs CONNECT@%pK\n",
+ dev_dbg(state->dev, "core: %d: prs CONNECT@%p\n",
state->id, header);
state->version_common = ((struct vchiq_slot_zero *)
state->slot_data)->version;
@@ -2102,7 +2102,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
if ((int)(queue->remote_insert -
queue->local_insert) >= 0) {
dev_err(state->dev,
- "core: %d: prs %s@%pK (%d->%d) unexpected (ri=%d,li=%d)\n",
+ "core: %d: prs %s@%p (%d->%d) unexpected (ri=%d,li=%d)\n",
state->id, msg_type_str(type), header, remoteport,
localport, queue->remote_insert, queue->local_insert);
mutex_unlock(&service->bulk_mutex);
@@ -2120,7 +2120,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
bulk->actual = *(int *)header->data;
queue->remote_insert++;
- dev_dbg(state->dev, "core: %d: prs %s@%pK (%d->%d) %x@%pad\n",
+ dev_dbg(state->dev, "core: %d: prs %s@%p (%d->%d) %x@%pad\n",
state->id, msg_type_str(type), header, remoteport,
localport, bulk->actual, &bulk->dma_addr);
@@ -2140,12 +2140,12 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
}
break;
case VCHIQ_MSG_PADDING:
- dev_dbg(state->dev, "core: %d: prs PADDING@%pK,%x\n",
+ dev_dbg(state->dev, "core: %d: prs PADDING@%p,%x\n",
state->id, header, size);
break;
case VCHIQ_MSG_PAUSE:
/* If initiated, signal the application thread */
- dev_dbg(state->dev, "core: %d: prs PAUSE@%pK,%x\n",
+ dev_dbg(state->dev, "core: %d: prs PAUSE@%p,%x\n",
state->id, header, size);
if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
dev_err(state->dev, "core: %d: PAUSE received in state PAUSED\n",
@@ -2162,7 +2162,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED);
break;
case VCHIQ_MSG_RESUME:
- dev_dbg(state->dev, "core: %d: prs RESUME@%pK,%x\n",
+ dev_dbg(state->dev, "core: %d: prs RESUME@%p,%x\n",
state->id, header, size);
/* Release the slot mutex */
mutex_unlock(&state->slot_mutex);
@@ -2179,7 +2179,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
break;
default:
- dev_err(state->dev, "core: %d: prs invalid msgid %x@%pK,%x\n",
+ dev_err(state->dev, "core: %d: prs invalid msgid %x@%p,%x\n",
state->id, msgid, header, size);
WARN(1, "invalid message\n");
break;
@@ -2400,7 +2400,7 @@ sync_func(void *v)
if (!service) {
dev_err(state->dev,
- "sync: %d: sf %s@%pK (%d->%d) - invalid/closed service %d\n",
+ "sync: %d: sf %s@%p (%d->%d) - invalid/closed service %d\n",
state->id, msg_type_str(type), header, remoteport,
localport, localport);
release_message_sync(state, header);
@@ -2422,7 +2422,7 @@ sync_func(void *v)
header->data;
service->peer_version = payload->version;
}
- dev_err(state->dev, "sync: %d: sf OPENACK@%pK,%x (%d->%d) v:%d\n",
+ dev_err(state->dev, "sync: %d: sf OPENACK@%p,%x (%d->%d) v:%d\n",
state->id, header, size, remoteport, localport,
service->peer_version);
if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
@@ -2435,7 +2435,7 @@ sync_func(void *v)
break;
case VCHIQ_MSG_DATA:
- dev_dbg(state->dev, "sync: %d: sf DATA@%pK,%x (%d->%d)\n",
+ dev_dbg(state->dev, "sync: %d: sf DATA@%p,%x (%d->%d)\n",
state->id, header, size, remoteport, localport);
if ((service->remoteport == remoteport) &&
@@ -2449,7 +2449,7 @@ sync_func(void *v)
break;
default:
- dev_err(state->dev, "sync: error: %d: sf unexpected msgid %x@%pK,%x\n",
+ dev_err(state->dev, "sync: error: %d: sf unexpected msgid %x@%p,%x\n",
state->id, msgid, header, size);
release_message_sync(state, header);
break;
@@ -2926,13 +2926,13 @@ release_service_messages(struct vchiq_service *service)
int port = VCHIQ_MSG_DSTPORT(msgid);
if ((port == service->localport) && (msgid & VCHIQ_MSGID_CLAIMED)) {
- dev_dbg(state->dev, "core: fsi - hdr %pK\n", header);
+ dev_dbg(state->dev, "core: fsi - hdr %p\n", header);
release_slot(state, slot_info, header, NULL);
}
pos += calc_stride(header->size);
if (pos > VCHIQ_SLOT_SIZE) {
dev_err(state->dev,
- "core: fsi - pos %x: header %pK, msgid %x, header->msgid %x, header->size %x\n",
+ "core: fsi - pos %x: header %p, msgid %x, header->msgid %x, header->size %x\n",
pos, header, msgid, header->msgid, header->size);
WARN(1, "invalid slot position\n");
}
@@ -3091,7 +3091,7 @@ vchiq_bulk_xfer_queue_msg_killable(struct vchiq_service *service,
*/
wmb();
- dev_dbg(state->dev, "core: %d: bt (%d->%d) %cx %x@%pad %pK\n",
+ dev_dbg(state->dev, "core: %d: bt (%d->%d) %cx %x@%pad %p\n",
state->id, service->localport, service->remoteport,
dir_char, bulk->size, &bulk->dma_addr, bulk->cb_data);
@@ -3343,6 +3343,7 @@ vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instanc
return -EAGAIN;
vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+ vchiq_platform_connected(state);
complete(&state->connect);
}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
index 9b4e766990a4..3b5c0618e567 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
@@ -575,6 +575,8 @@ int vchiq_send_remote_use(struct vchiq_state *state);
int vchiq_send_remote_use_active(struct vchiq_state *state);
+void vchiq_platform_connected(struct vchiq_state *state);
+
void vchiq_platform_conn_state_changed(struct vchiq_state *state,
enum vchiq_connstate oldstate,
enum vchiq_connstate newstate);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
index 454f43416503..3b20ba5c7362 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
@@ -270,7 +270,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance,
}
} else {
dev_err(service->state->dev,
- "arm: header %pK: bufsize %x < size %x\n",
+ "arm: header %p: bufsize %x < size %x\n",
header, args->bufsize, header->size);
WARN(1, "invalid size\n");
ret = -EMSGSIZE;
@@ -328,7 +328,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
ret = -ESRCH;
goto out;
}
- dev_dbg(service->state->dev, "arm: found bulk_waiter %pK for pid %d\n",
+ dev_dbg(service->state->dev, "arm: found bulk_waiter %p for pid %d\n",
waiter, current->pid);
status = vchiq_bulk_xfer_waiting(instance, args->handle,
@@ -366,7 +366,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
mutex_lock(&instance->bulk_waiter_list_mutex);
list_add(&waiter->list, &instance->bulk_waiter_list);
mutex_unlock(&instance->bulk_waiter_list_mutex);
- dev_dbg(service->state->dev, "arm: saved bulk_waiter %pK for pid %d\n",
+ dev_dbg(service->state->dev, "arm: saved bulk_waiter %p for pid %d\n",
waiter, current->pid);
ret = put_user(mode_waiting, mode);
@@ -512,7 +512,7 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance,
/* This must be a VCHIQ-style service */
if (args->msgbufsize < msglen) {
dev_err(service->state->dev,
- "arm: header %pK: msgbufsize %x < msglen %x\n",
+ "arm: header %p: msgbufsize %x < msglen %x\n",
header, args->msgbufsize, msglen);
WARN(1, "invalid message size\n");
if (ret == 0)
@@ -588,7 +588,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
long ret = 0;
int i, rc;
- dev_dbg(instance->state->dev, "arm: instance %pK, cmd %s, arg %lx\n", instance,
+ dev_dbg(instance->state->dev, "arm: instance %p, cmd %s, arg %lx\n", instance,
((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
@@ -874,12 +874,12 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (!status && (ret < 0) && (ret != -EINTR) && (ret != -EWOULDBLOCK)) {
dev_dbg(instance->state->dev,
- "arm: ioctl instance %pK, cmd %s -> status %d, %ld\n",
+ "arm: ioctl instance %p, cmd %s -> status %d, %ld\n",
instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
ioctl_names[_IOC_NR(cmd)] : "<invalid>", status, ret);
} else {
dev_dbg(instance->state->dev,
- "arm: ioctl instance %pK, cmd %s -> status %d\n, %ld\n",
+ "arm: ioctl instance %p, cmd %s -> status %d\n, %ld\n",
instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
ioctl_names[_IOC_NR(cmd)] : "<invalid>", status, ret);
}
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index 07e9cf431edd..f0d7eebfcad6 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -810,7 +810,7 @@ int iscsit_stop_time2retain_timer(struct iscsit_session *sess)
sess->time2retain_timer_flags |= ISCSI_TF_STOP;
spin_unlock(&se_tpg->session_lock);
- del_timer_sync(&sess->time2retain_timer);
+ timer_delete_sync(&sess->time2retain_timer);
spin_lock(&se_tpg->session_lock);
sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index d9a6242264b7..e7c3c4cdaae4 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -1227,7 +1227,7 @@ void iscsit_stop_dataout_timer(struct iscsit_cmd *cmd)
cmd->dataout_timer_flags |= ISCSI_TF_STOP;
spin_unlock_bh(&cmd->dataout_timeout_lock);
- del_timer_sync(&cmd->dataout_timer);
+ timer_delete_sync(&cmd->dataout_timer);
spin_lock_bh(&cmd->dataout_timeout_lock);
cmd->dataout_timer_flags &= ~ISCSI_TF_RUNNING;
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index ed2dadb21f75..0bd62ab9a1cd 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -922,7 +922,7 @@ void iscsit_stop_nopin_response_timer(struct iscsit_conn *conn)
conn->nopin_response_timer_flags |= ISCSI_TF_STOP;
spin_unlock_bh(&conn->nopin_timer_lock);
- del_timer_sync(&conn->nopin_response_timer);
+ timer_delete_sync(&conn->nopin_response_timer);
spin_lock_bh(&conn->nopin_timer_lock);
conn->nopin_response_timer_flags &= ~ISCSI_TF_RUNNING;
@@ -989,7 +989,7 @@ void iscsit_stop_nopin_timer(struct iscsit_conn *conn)
conn->nopin_timer_flags |= ISCSI_TF_STOP;
spin_unlock_bh(&conn->nopin_timer_lock);
- del_timer_sync(&conn->nopin_timer);
+ timer_delete_sync(&conn->nopin_timer);
spin_lock_bh(&conn->nopin_timer_lock);
conn->nopin_timer_flags &= ~ISCSI_TF_RUNNING;
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 0f5d820af119..43872ccc07cc 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1232,7 +1232,7 @@ static void tcmu_set_next_deadline(struct list_head *queue,
cmd = list_first_entry(queue, struct tcmu_cmd, queue_entry);
mod_timer(timer, cmd->deadline);
} else
- del_timer(timer);
+ timer_delete(timer);
}
static int
@@ -2321,8 +2321,8 @@ static void tcmu_destroy_device(struct se_device *dev)
{
struct tcmu_dev *udev = TCMU_DEV(dev);
- del_timer_sync(&udev->cmd_timer);
- del_timer_sync(&udev->qfull_timer);
+ timer_delete_sync(&udev->cmd_timer);
+ timer_delete_sync(&udev->qfull_timer);
mutex_lock(&root_udev_mutex);
list_del(&udev->node);
@@ -2408,7 +2408,7 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level)
tcmu_flush_dcache_range(mb, sizeof(*mb));
clear_bit(TCMU_DEV_BIT_BROKEN, &udev->flags);
- del_timer(&udev->cmd_timer);
+ timer_delete(&udev->cmd_timer);
/*
* ring is empty and qfull queue never contains aborted commands.
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c
index 270982740fde..f46f2ddc174e 100644
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -286,14 +286,20 @@ static int brcmstb_set_trips(struct thermal_zone_device *tz, int low, int high)
return 0;
}
-static const struct thermal_zone_device_ops brcmstb_16nm_of_ops = {
+static const struct thermal_zone_device_ops brcmstb_of_ops = {
.get_temp = brcmstb_get_temp,
};
+static const struct brcmstb_thermal_params brcmstb_8nm_params = {
+ .offset = 418670,
+ .mult = 509,
+ .of_ops = &brcmstb_of_ops,
+};
+
static const struct brcmstb_thermal_params brcmstb_16nm_params = {
.offset = 457829,
.mult = 557,
- .of_ops = &brcmstb_16nm_of_ops,
+ .of_ops = &brcmstb_of_ops,
};
static const struct thermal_zone_device_ops brcmstb_28nm_of_ops = {
@@ -308,6 +314,7 @@ static const struct brcmstb_thermal_params brcmstb_28nm_params = {
};
static const struct of_device_id brcmstb_thermal_id_table[] = {
+ { .compatible = "brcm,avs-tmon-bcm74110", .data = &brcmstb_8nm_params },
{ .compatible = "brcm,avs-tmon-bcm7216", .data = &brcmstb_16nm_params },
{ .compatible = "brcm,avs-tmon", .data = &brcmstb_28nm_params },
{},
diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index 07f7f3b7a2fb..088481d91e6e 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -65,12 +65,15 @@
#define LVTS_HW_FILTER 0x0
#define LVTS_TSSEL_CONF 0x13121110
#define LVTS_CALSCALE_CONF 0x300
-#define LVTS_MONINT_CONF 0x8300318C
-#define LVTS_MONINT_OFFSET_SENSOR0 0xC
-#define LVTS_MONINT_OFFSET_SENSOR1 0x180
-#define LVTS_MONINT_OFFSET_SENSOR2 0x3000
-#define LVTS_MONINT_OFFSET_SENSOR3 0x3000000
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0 BIT(3)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1 BIT(8)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2 BIT(13)
+#define LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3 BIT(25)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0 BIT(2)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1 BIT(7)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2 BIT(12)
+#define LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3 BIT(24)
#define LVTS_INT_SENSOR0 0x0009001F
#define LVTS_INT_SENSOR1 0x001203E0
@@ -91,8 +94,6 @@
#define LVTS_MSR_READ_TIMEOUT_US 400
#define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)
-#define LVTS_HW_TSHUT_TEMP 105000
-
#define LVTS_MINIMUM_THRESHOLD 20000
static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
@@ -145,7 +146,6 @@ struct lvts_ctrl {
struct lvts_sensor sensors[LVTS_SENSOR_MAX];
const struct lvts_data *lvts_data;
u32 calibration[LVTS_SENSOR_MAX];
- u32 hw_tshut_raw_temp;
u8 valid_sensor_mask;
int mode;
void __iomem *base;
@@ -329,23 +329,41 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
{
- static const u32 masks[] = {
- LVTS_MONINT_OFFSET_SENSOR0,
- LVTS_MONINT_OFFSET_SENSOR1,
- LVTS_MONINT_OFFSET_SENSOR2,
- LVTS_MONINT_OFFSET_SENSOR3,
+ static const u32 high_offset_inten_masks[] = {
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR0,
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR1,
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR2,
+ LVTS_MONINT_OFFSET_HIGH_INTEN_SENSOR3,
+ };
+ static const u32 low_offset_inten_masks[] = {
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR0,
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR1,
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR2,
+ LVTS_MONINT_OFFSET_LOW_INTEN_SENSOR3,
};
u32 value = 0;
int i;
value = readl(LVTS_MONINT(lvts_ctrl->base));
- for (i = 0; i < ARRAY_SIZE(masks); i++) {
+ lvts_for_each_valid_sensor(i, lvts_ctrl) {
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
- && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
- value |= masks[i];
- else
- value &= ~masks[i];
+ && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) {
+ /*
+ * The minimum threshold needs to be configured in the
+ * OFFSETL register to get working interrupts, but we
+ * don't actually want to generate interrupts when
+ * crossing it.
+ */
+ if (lvts_ctrl->low_thresh == -INT_MAX) {
+ value &= ~low_offset_inten_masks[i];
+ value |= high_offset_inten_masks[i];
+ } else {
+ value |= low_offset_inten_masks[i] | high_offset_inten_masks[i];
+ }
+ } else {
+ value &= ~(low_offset_inten_masks[i] | high_offset_inten_masks[i]);
+ }
}
writel(value, LVTS_MONINT(lvts_ctrl->base));
@@ -837,14 +855,6 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
*/
lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
- /*
- * The temperature to raw temperature must be done
- * after initializing the calibration.
- */
- lvts_ctrl[i].hw_tshut_raw_temp =
- lvts_temp_to_raw(LVTS_HW_TSHUT_TEMP,
- lvts_data->temp_factor);
-
lvts_ctrl[i].low_thresh = INT_MIN;
lvts_ctrl[i].high_thresh = INT_MIN;
}
@@ -860,6 +870,32 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
return 0;
}
+static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl, bool enable)
+{
+ /*
+ * Bitmaps to enable each sensor on filtered mode in the MONCTL0
+ * register.
+ */
+ static const u8 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
+ u32 sensor_map = 0;
+ int i;
+
+ if (lvts_ctrl->mode != LVTS_MSR_FILTERED_MODE)
+ return;
+
+ if (enable) {
+ lvts_for_each_valid_sensor(i, lvts_ctrl)
+ sensor_map |= sensor_filt_bitmap[i];
+ }
+
+ /*
+ * Bits:
+ * 9: Single point access flow
+ * 0-3: Enable sensing point 0-3
+ */
+ writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
+}
+
/*
* At this point the configuration register is the only place in the
* driver where we write multiple values. Per hardware constraint,
@@ -893,7 +929,6 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
* 10 : Selected sensor with bits 19-18
* 11 : Reserved
*/
- writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
/*
* LVTS_PROTTA : Stage 1 temperature threshold
@@ -906,8 +941,8 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
*
* writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
* writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
+ * writel(0x0, LVTS_PROTTC(lvts_ctrl->base));
*/
- writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
/*
* LVTS_MONINT : Interrupt configuration register
@@ -915,7 +950,7 @@ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
* The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
* register, except we set the bits to enable the interrupt.
*/
- writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
+ writel(0, LVTS_MONINT(lvts_ctrl->base));
return 0;
}
@@ -1381,8 +1416,11 @@ static int lvts_suspend(struct device *dev)
lvts_td = dev_get_drvdata(dev);
- for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+ lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], false);
+ usleep_range(100, 200);
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
+ }
clk_disable_unprepare(lvts_td->clk);
@@ -1400,8 +1438,11 @@ static int lvts_resume(struct device *dev)
if (ret)
return ret;
- for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
+ usleep_range(100, 200);
+ lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], true);
+ }
return 0;
}
diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
index c2d59cbfaea9..a81e7d6e865f 100644
--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
@@ -360,7 +360,6 @@ static int qpnp_tm_probe(struct platform_device *pdev)
if (!chip)
return -ENOMEM;
- dev_set_drvdata(&pdev->dev, chip);
chip->dev = &pdev->dev;
mutex_init(&chip->lock);
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 0cb7301eca6e..8d9698ea3ec4 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -4,13 +4,32 @@
* Copyright (c) 2018, Linaro Limited
*/
+#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/nvmem-consumer.h>
#include <linux/regmap.h>
#include "tsens.h"
/* ----- SROT ------ */
#define SROT_HW_VER_OFF 0x0000
#define SROT_CTRL_OFF 0x0004
+#define SROT_MEASURE_PERIOD 0x0008
+#define SROT_Sn_CONVERSION 0x0060
+#define V2_SHIFT_DEFAULT 0x0003
+#define V2_SLOPE_DEFAULT 0x0cd0
+#define V2_CZERO_DEFAULT 0x016a
+#define ONE_PT_SLOPE 0x0cd0
+#define TWO_PT_SHIFTED_GAIN 921600
+#define ONE_PT_CZERO_CONST 94
+#define SW_RST_DEASSERT 0x0
+#define SW_RST_ASSERT 0x1
+#define MEASURE_PERIOD_2mSEC 0x1
+#define RESULT_FORMAT_TEMP 0x1
+#define TSENS_ENABLE 0x1
+#define SENSOR_CONVERSION(n) (((n) * 4) + SROT_Sn_CONVERSION)
+#define CONVERSION_SHIFT_MASK GENMASK(24, 23)
+#define CONVERSION_SLOPE_MASK GENMASK(22, 10)
+#define CONVERSION_CZERO_MASK GENMASK(9, 0)
/* ----- TM ------ */
#define TM_INT_EN_OFF 0x0004
@@ -50,6 +69,17 @@ static struct tsens_features ipq8074_feat = {
.trip_max_temp = 204000,
};
+static struct tsens_features ipq5332_feat = {
+ .ver_major = VER_2_X_NO_RPM,
+ .crit_int = 1,
+ .combo_int = 1,
+ .adc = 0,
+ .srot_split = 1,
+ .max_sensors = 16,
+ .trip_min_temp = 0,
+ .trip_max_temp = 204000,
+};
+
static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
/* ----- SROT ------ */
/* VERSION */
@@ -59,6 +89,10 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
/* CTRL_OFF */
[TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
[TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
+ [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 18),
+ [CODE_OR_TEMP] = REG_FIELD(SROT_CTRL_OFF, 21, 21),
+
+ [MAIN_MEASURE_PERIOD] = REG_FIELD(SROT_MEASURE_PERIOD, 0, 7),
/* ----- TM ------ */
/* INTERRUPT ENABLE */
@@ -104,6 +138,128 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
};
+static int tsens_v2_calibrate_sensor(struct device *dev, struct tsens_sensor *sensor,
+ struct regmap *map, u32 mode, u32 base0, u32 base1)
+{
+ u32 shift = V2_SHIFT_DEFAULT;
+ u32 slope = V2_SLOPE_DEFAULT;
+ u32 czero = V2_CZERO_DEFAULT;
+ char name[20];
+ u32 val;
+ int ret;
+
+ /* Read offset value */
+ ret = snprintf(name, sizeof(name), "tsens_sens%d_off", sensor->hw_id);
+ if (ret < 0)
+ return ret;
+
+ ret = nvmem_cell_read_variable_le_u32(dev, name, &sensor->offset);
+ if (ret)
+ return ret;
+
+ /* Based on calib mode, program SHIFT, SLOPE and CZERO */
+ switch (mode) {
+ case TWO_PT_CALIB:
+ slope = (TWO_PT_SHIFTED_GAIN / (base1 - base0));
+
+ czero = (base0 + sensor->offset - ((base1 - base0) / 3));
+
+ break;
+ case ONE_PT_CALIB2:
+ czero = base0 + sensor->offset - ONE_PT_CZERO_CONST;
+
+ slope = ONE_PT_SLOPE;
+
+ break;
+ default:
+ dev_dbg(dev, "calibrationless mode\n");
+ }
+
+ val = FIELD_PREP(CONVERSION_SHIFT_MASK, shift) |
+ FIELD_PREP(CONVERSION_SLOPE_MASK, slope) |
+ FIELD_PREP(CONVERSION_CZERO_MASK, czero);
+
+ regmap_write(map, SENSOR_CONVERSION(sensor->hw_id), val);
+
+ return 0;
+}
+
+static int tsens_v2_calibration(struct tsens_priv *priv)
+{
+ struct device *dev = priv->dev;
+ u32 mode, base0, base1;
+ int i, ret;
+
+ if (priv->num_sensors > MAX_SENSORS)
+ return -EINVAL;
+
+ ret = nvmem_cell_read_variable_le_u32(priv->dev, "mode", &mode);
+ if (ret == -ENOENT)
+ dev_warn(priv->dev, "Calibration data not present in DT\n");
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(priv->dev, "calibration mode is %d\n", mode);
+
+ ret = nvmem_cell_read_variable_le_u32(priv->dev, "base0", &base0);
+ if (ret < 0)
+ return ret;
+
+ ret = nvmem_cell_read_variable_le_u32(priv->dev, "base1", &base1);
+ if (ret < 0)
+ return ret;
+
+ /* Calibrate each sensor */
+ for (i = 0; i < priv->num_sensors; i++) {
+ ret = tsens_v2_calibrate_sensor(dev, &priv->sensor[i], priv->srot_map,
+ mode, base0, base1);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __init init_tsens_v2_no_rpm(struct tsens_priv *priv)
+{
+ struct device *dev = priv->dev;
+ int i, ret;
+ u32 val = 0;
+
+ ret = init_common(priv);
+ if (ret < 0)
+ return ret;
+
+ priv->rf[CODE_OR_TEMP] = devm_regmap_field_alloc(dev, priv->srot_map,
+ priv->fields[CODE_OR_TEMP]);
+ if (IS_ERR(priv->rf[CODE_OR_TEMP]))
+ return PTR_ERR(priv->rf[CODE_OR_TEMP]);
+
+ priv->rf[MAIN_MEASURE_PERIOD] = devm_regmap_field_alloc(dev, priv->srot_map,
+ priv->fields[MAIN_MEASURE_PERIOD]);
+ if (IS_ERR(priv->rf[MAIN_MEASURE_PERIOD]))
+ return PTR_ERR(priv->rf[MAIN_MEASURE_PERIOD]);
+
+ regmap_field_write(priv->rf[TSENS_SW_RST], SW_RST_ASSERT);
+
+ regmap_field_write(priv->rf[MAIN_MEASURE_PERIOD], MEASURE_PERIOD_2mSEC);
+
+ /* Enable available sensors */
+ for (i = 0; i < priv->num_sensors; i++)
+ val |= 1 << priv->sensor[i].hw_id;
+
+ regmap_field_write(priv->rf[SENSOR_EN], val);
+
+ /* Select temperature format, unit is deci-Celsius */
+ regmap_field_write(priv->rf[CODE_OR_TEMP], RESULT_FORMAT_TEMP);
+
+ regmap_field_write(priv->rf[TSENS_SW_RST], SW_RST_DEASSERT);
+
+ regmap_field_write(priv->rf[TSENS_EN], TSENS_ENABLE);
+
+ return 0;
+}
+
static const struct tsens_ops ops_generic_v2 = {
.init = init_common,
.get_temp = get_temp_tsens_valid,
@@ -122,6 +278,28 @@ struct tsens_plat_data data_ipq8074 = {
.fields = tsens_v2_regfields,
};
+static const struct tsens_ops ops_ipq5332 = {
+ .init = init_tsens_v2_no_rpm,
+ .get_temp = get_temp_tsens_valid,
+ .calibrate = tsens_v2_calibration,
+};
+
+const struct tsens_plat_data data_ipq5332 = {
+ .num_sensors = 5,
+ .ops = &ops_ipq5332,
+ .hw_ids = (unsigned int []){11, 12, 13, 14, 15},
+ .feat = &ipq5332_feat,
+ .fields = tsens_v2_regfields,
+};
+
+const struct tsens_plat_data data_ipq5424 = {
+ .num_sensors = 7,
+ .ops = &ops_ipq5332,
+ .hw_ids = (unsigned int []){9, 10, 11, 12, 13, 14, 15},
+ .feat = &ipq5332_feat,
+ .fields = tsens_v2_regfields,
+};
+
/* Kept around for backward compatibility with old msm8996.dtsi */
struct tsens_plat_data data_8996 = {
.num_sensors = 13,
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 3aa3736181aa..1f5d4de017d9 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -975,7 +975,7 @@ int __init init_common(struct tsens_priv *priv)
ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
if (ret)
goto err_put_device;
- if (!enabled) {
+ if (!enabled && (tsens_version(priv) != VER_2_X_NO_RPM)) {
dev_err(dev, "%s: device not enabled\n", __func__);
ret = -ENODEV;
goto err_put_device;
@@ -1102,6 +1102,12 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
static const struct of_device_id tsens_table[] = {
{
+ .compatible = "qcom,ipq5332-tsens",
+ .data = &data_ipq5332,
+ }, {
+ .compatible = "qcom,ipq5424-tsens",
+ .data = &data_ipq5424,
+ }, {
.compatible = "qcom,ipq8064-tsens",
.data = &data_8960,
}, {
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 7b36a0318fa6..336bc868fd7c 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -35,6 +35,7 @@ enum tsens_ver {
VER_0_1,
VER_1_X,
VER_2_X,
+ VER_2_X_NO_RPM,
};
enum tsens_irq_type {
@@ -168,6 +169,7 @@ enum regfield_ids {
TSENS_SW_RST,
SENSOR_EN,
CODE_OR_TEMP,
+ MAIN_MEASURE_PERIOD,
/* ----- TM ------ */
/* TRDY */
@@ -651,5 +653,6 @@ extern struct tsens_plat_data data_tsens_v1, data_8937, data_8976, data_8956;
/* TSENS v2 targets */
extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
+extern const struct tsens_plat_data data_ipq5332, data_ipq5424;
#endif /* __QCOM_TSENS_H__ */
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 52e26be8c53d..01b58be0dcc6 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -18,6 +18,7 @@
#define SITES_MAX 16
#define TMR_DISABLE 0x0
#define TMR_ME 0x80000000
+#define TMR_CMD BIT(29)
#define TMR_ALPF 0x0c000000
#define TMR_ALPF_V2 0x03000000
#define TMTMIR_DEFAULT 0x0000000f
@@ -265,7 +266,6 @@ static void qoriq_tmu_action(void *p)
struct qoriq_tmu_data *data = p;
regmap_write(data->regmap, REGS_TMR, TMR_DISABLE);
- clk_disable_unprepare(data->clk);
}
static int qoriq_tmu_probe(struct platform_device *pdev)
@@ -296,38 +296,27 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
base = devm_platform_ioremap_resource(pdev, 0);
ret = PTR_ERR_OR_ZERO(base);
- if (ret) {
- dev_err(dev, "Failed to get memory region\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get memory region\n");
data->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
ret = PTR_ERR_OR_ZERO(data->regmap);
- if (ret) {
- dev_err(dev, "Failed to init regmap (%d)\n", ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to init regmap\n");
- data->clk = devm_clk_get_optional(dev, NULL);
+ data->clk = devm_clk_get_optional_enabled(dev, NULL);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
- ret = clk_prepare_enable(data->clk);
- if (ret) {
- dev_err(dev, "Failed to enable clock\n");
- return ret;
- }
-
ret = devm_add_action_or_reset(dev, qoriq_tmu_action, data);
if (ret)
return ret;
/* version register offset at: 0xbf8 on both v1 and v2 */
ret = regmap_read(data->regmap, REGS_IPBRR(0), &ver);
- if (ret) {
- dev_err(&pdev->dev, "Failed to read IP block version\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to read IP block version\n");
+
data->ver = (ver >> 8) & 0xff;
qoriq_tmu_init_device(data); /* TMU initialization */
@@ -337,10 +326,8 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
return ret;
ret = qoriq_tmu_register_tmu_zone(dev, data);
- if (ret < 0) {
- dev_err(dev, "Failed to register sensors\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to register sensors\n");
platform_set_drvdata(pdev, data);
@@ -356,6 +343,12 @@ static int qoriq_tmu_suspend(struct device *dev)
if (ret)
return ret;
+ if (data->ver > TMU_VER1) {
+ ret = regmap_set_bits(data->regmap, REGS_TMR, TMR_CMD);
+ if (ret)
+ return ret;
+ }
+
clk_disable_unprepare(data->clk);
return 0;
@@ -370,6 +363,12 @@ static int qoriq_tmu_resume(struct device *dev)
if (ret)
return ret;
+ if (data->ver > TMU_VER1) {
+ ret = regmap_clear_bits(data->regmap, REGS_TMR, TMR_CMD);
+ if (ret)
+ return ret;
+ }
+
/* Enable monitoring */
return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME);
}
diff --git a/drivers/thermal/renesas/rcar_gen3_thermal.c b/drivers/thermal/renesas/rcar_gen3_thermal.c
index 1ec169aeacfc..24a702ee4c1f 100644
--- a/drivers/thermal/renesas/rcar_gen3_thermal.c
+++ b/drivers/thermal/renesas/rcar_gen3_thermal.c
@@ -21,11 +21,11 @@
/* Register offsets */
#define REG_GEN3_IRQSTR 0x04
#define REG_GEN3_IRQMSK 0x08
-#define REG_GEN3_IRQCTL 0x0C
+#define REG_GEN3_IRQCTL 0x0c
#define REG_GEN3_IRQEN 0x10
#define REG_GEN3_IRQTEMP1 0x14
#define REG_GEN3_IRQTEMP2 0x18
-#define REG_GEN3_IRQTEMP3 0x1C
+#define REG_GEN3_IRQTEMP3 0x1c
#define REG_GEN3_THCTR 0x20
#define REG_GEN3_TEMP 0x28
#define REG_GEN3_THCODE1 0x50
@@ -38,9 +38,9 @@
#define REG_GEN4_THSFMON00 0x180
#define REG_GEN4_THSFMON01 0x184
#define REG_GEN4_THSFMON02 0x188
-#define REG_GEN4_THSFMON15 0x1BC
-#define REG_GEN4_THSFMON16 0x1C0
-#define REG_GEN4_THSFMON17 0x1C4
+#define REG_GEN4_THSFMON15 0x1bc
+#define REG_GEN4_THSFMON16 0x1c0
+#define REG_GEN4_THSFMON17 0x1c4
/* IRQ{STR,MSK,EN} bits */
#define IRQ_TEMP1 BIT(0)
@@ -57,21 +57,27 @@
/* THSCP bits */
#define THSCP_COR_PARA_VLD (BIT(15) | BIT(14))
-#define CTEMP_MASK 0xFFF
+#define CTEMP_MASK 0xfff
#define MCELSIUS(temp) ((temp) * 1000)
-#define GEN3_FUSE_MASK 0xFFF
-#define GEN4_FUSE_MASK 0xFFF
+#define GEN3_FUSE_MASK 0xfff
+#define GEN4_FUSE_MASK 0xfff
#define TSC_MAX_NUM 5
struct rcar_gen3_thermal_priv;
+struct rcar_gen3_thermal_fuse_info {
+ u32 ptat[3];
+ u32 thcode[3];
+ u32 mask;
+};
+
struct rcar_thermal_info {
int scale;
int adj_below;
int adj_above;
- void (*read_fuses)(struct rcar_gen3_thermal_priv *priv);
+ const struct rcar_gen3_thermal_fuse_info *fuses;
};
struct equation_set_coef {
@@ -253,59 +259,31 @@ static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static void rcar_gen3_thermal_read_fuses_gen3(struct rcar_gen3_thermal_priv *priv)
+static void rcar_gen3_thermal_fetch_fuses(struct rcar_gen3_thermal_priv *priv)
{
- unsigned int i;
+ const struct rcar_gen3_thermal_fuse_info *fuses = priv->info->fuses;
/*
* Set the pseudo calibration points with fused values.
* PTAT is shared between all TSCs but only fused for the first
* TSC while THCODEs are fused for each TSC.
*/
- priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
- GEN3_FUSE_MASK;
- priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
- GEN3_FUSE_MASK;
- priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
- GEN3_FUSE_MASK;
-
- for (i = 0; i < priv->num_tscs; i++) {
+ priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], fuses->ptat[0])
+ & fuses->mask;
+ priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], fuses->ptat[1])
+ & fuses->mask;
+ priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], fuses->ptat[2])
+ & fuses->mask;
+
+ for (unsigned int i = 0; i < priv->num_tscs; i++) {
struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
- tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
- GEN3_FUSE_MASK;
- tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
- GEN3_FUSE_MASK;
- tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
- GEN3_FUSE_MASK;
- }
-}
-
-static void rcar_gen3_thermal_read_fuses_gen4(struct rcar_gen3_thermal_priv *priv)
-{
- unsigned int i;
-
- /*
- * Set the pseudo calibration points with fused values.
- * PTAT is shared between all TSCs but only fused for the first
- * TSC while THCODEs are fused for each TSC.
- */
- priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON16) &
- GEN4_FUSE_MASK;
- priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON17) &
- GEN4_FUSE_MASK;
- priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON15) &
- GEN4_FUSE_MASK;
-
- for (i = 0; i < priv->num_tscs; i++) {
- struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
-
- tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON01) &
- GEN4_FUSE_MASK;
- tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON02) &
- GEN4_FUSE_MASK;
- tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON00) &
- GEN4_FUSE_MASK;
+ tsc->thcode[0] = rcar_gen3_thermal_read(tsc, fuses->thcode[0])
+ & fuses->mask;
+ tsc->thcode[1] = rcar_gen3_thermal_read(tsc, fuses->thcode[1])
+ & fuses->mask;
+ tsc->thcode[2] = rcar_gen3_thermal_read(tsc, fuses->thcode[2])
+ & fuses->mask;
}
}
@@ -316,7 +294,7 @@ static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
/* If fuses are not set, fallback to pseudo values. */
thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP);
- if (!priv->info->read_fuses ||
+ if (!priv->info->fuses ||
(thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) {
/* Default THCODE values in case FUSEs are not set. */
static const int thcodes[TSC_MAX_NUM][3] = {
@@ -342,7 +320,8 @@ static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
return false;
}
- priv->info->read_fuses(priv);
+ rcar_gen3_thermal_fetch_fuses(priv);
+
return true;
}
@@ -370,25 +349,37 @@ static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv,
usleep_range(1000, 2000);
}
+static const struct rcar_gen3_thermal_fuse_info rcar_gen3_thermal_fuse_info_gen3 = {
+ .ptat = { REG_GEN3_PTAT1, REG_GEN3_PTAT2, REG_GEN3_PTAT3 },
+ .thcode = { REG_GEN3_THCODE1, REG_GEN3_THCODE2, REG_GEN3_THCODE3 },
+ .mask = GEN3_FUSE_MASK,
+};
+
+static const struct rcar_gen3_thermal_fuse_info rcar_gen3_thermal_fuse_info_gen4 = {
+ .ptat = { REG_GEN4_THSFMON16, REG_GEN4_THSFMON17, REG_GEN4_THSFMON15 },
+ .thcode = { REG_GEN4_THSFMON01, REG_GEN4_THSFMON02, REG_GEN4_THSFMON00 },
+ .mask = GEN4_FUSE_MASK,
+};
+
static const struct rcar_thermal_info rcar_m3w_thermal_info = {
.scale = 157,
.adj_below = -41,
.adj_above = 116,
- .read_fuses = rcar_gen3_thermal_read_fuses_gen3,
+ .fuses = &rcar_gen3_thermal_fuse_info_gen3,
};
static const struct rcar_thermal_info rcar_gen3_thermal_info = {
.scale = 167,
.adj_below = -41,
.adj_above = 126,
- .read_fuses = rcar_gen3_thermal_read_fuses_gen3,
+ .fuses = &rcar_gen3_thermal_fuse_info_gen3,
};
static const struct rcar_thermal_info rcar_gen4_thermal_info = {
.scale = 167,
.adj_below = -41,
.adj_above = 126,
- .read_fuses = rcar_gen3_thermal_read_fuses_gen4,
+ .fuses = &rcar_gen3_thermal_fuse_info_gen4,
};
static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index f551df48eef9..a8ad85feb68f 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -386,6 +386,7 @@ static const struct tsadc_table rk3328_code_table[] = {
{296, -40000},
{304, -35000},
{313, -30000},
+ {322, -25000},
{331, -20000},
{340, -15000},
{349, -10000},
diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c
index 1f25529fe05d..361fece3d818 100644
--- a/drivers/thunderbolt/retimer.c
+++ b/drivers/thunderbolt/retimer.c
@@ -93,9 +93,11 @@ static int tb_retimer_nvm_add(struct tb_retimer *rt)
if (ret)
goto err_nvm;
- ret = tb_nvm_add_non_active(nvm, nvm_write);
- if (ret)
- goto err_nvm;
+ if (!rt->no_nvm_upgrade) {
+ ret = tb_nvm_add_non_active(nvm, nvm_write);
+ if (ret)
+ goto err_nvm;
+ }
rt->nvm = nvm;
dev_dbg(&rt->dev, "NVM version %x.%x\n", nvm->major, nvm->minor);
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 390abcfe7188..8c527af98927 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -1305,12 +1305,16 @@ static void tb_scan_port(struct tb_port *port)
goto out_rpm_put;
}
- tb_retimer_scan(port, true);
-
sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
tb_downstream_route(port));
if (IS_ERR(sw)) {
/*
+ * Make the downstream retimers available even if there
+ * is no router connected.
+ */
+ tb_retimer_scan(port, true);
+
+ /*
* If there is an error accessing the connected switch
* it may be connected to another domain. Also we allow
* the other domain to be connected to a max depth switch.
@@ -1360,6 +1364,14 @@ static void tb_scan_port(struct tb_port *port)
tb_configure_link(port, upstream_port, sw);
/*
+ * Scan for downstream retimers. We only scan them after the
+ * router has been enumerated to avoid issues with certain
+ * Pluggable devices that expect the host to enumerate them
+ * within certain timeout.
+ */
+ tb_retimer_scan(port, true);
+
+ /*
* CL0s and CL1 are enabled and supported together.
* Silently ignore CLx enabling in case CLx is not supported.
*/
diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index 717b31d78728..76254ed3f47f 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -2229,19 +2229,15 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up,
path = tb_path_alloc(tb, down, TB_USB3_HOPID, up, TB_USB3_HOPID, 0,
"USB3 Down");
- if (!path) {
- tb_tunnel_put(tunnel);
- return NULL;
- }
+ if (!path)
+ goto err_free;
tb_usb3_init_path(path);
tunnel->paths[TB_USB3_PATH_DOWN] = path;
path = tb_path_alloc(tb, up, TB_USB3_HOPID, down, TB_USB3_HOPID, 0,
"USB3 Up");
- if (!path) {
- tb_tunnel_put(tunnel);
- return NULL;
- }
+ if (!path)
+ goto err_free;
tb_usb3_init_path(path);
tunnel->paths[TB_USB3_PATH_UP] = path;
@@ -2258,6 +2254,10 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up,
}
return tunnel;
+
+err_free:
+ tb_tunnel_put(tunnel);
+ return NULL;
}
/**
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index 7fb81bbaee60..149f3d53b760 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -210,7 +210,7 @@ config SERIAL_NONSTANDARD
config MOXA_INTELLIO
tristate "Moxa Intellio support"
- depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
+ depends on SERIAL_NONSTANDARD && PCI
select FW_LOADER
help
Say Y here if you have a Moxa Intellio multiport serial card.
diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c
index 001ec318a918..c13f52337035 100644
--- a/drivers/tty/ipwireless/hardware.c
+++ b/drivers/tty/ipwireless/hardware.c
@@ -1496,7 +1496,7 @@ exit_nomem:
static void handle_setup_get_version_rsp(struct ipw_hardware *hw,
unsigned char vers_no)
{
- del_timer(&hw->setup_timer);
+ timer_delete(&hw->setup_timer);
hw->initializing = 0;
printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": card is ready.\n");
@@ -1721,7 +1721,7 @@ void ipwireless_stop_interrupts(struct ipw_hardware *hw)
if (!hw->shutting_down) {
/* Tell everyone we are going down. */
hw->shutting_down = 1;
- del_timer(&hw->setup_timer);
+ timer_delete(&hw->setup_timer);
/* Prevent the hardware from sending any more interrupts */
do_close_hardware(hw);
diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c
index 58b28be63c79..fa47bfcf9e86 100644
--- a/drivers/tty/mips_ejtag_fdc.c
+++ b/drivers/tty/mips_ejtag_fdc.c
@@ -1031,7 +1031,7 @@ err_stop_irq:
raw_spin_unlock_irq(&priv->lock);
} else {
priv->removing = true;
- del_timer_sync(&priv->poll_timer);
+ timer_delete_sync(&priv->poll_timer);
}
kthread_stop(priv->thread);
err_destroy_ports:
@@ -1061,7 +1061,7 @@ static int mips_ejtag_fdc_tty_cpu_down(struct mips_cdmm_device *dev)
raw_spin_unlock_irq(&priv->lock);
} else {
priv->removing = true;
- del_timer_sync(&priv->poll_timer);
+ timer_delete_sync(&priv->poll_timer);
}
kthread_stop(priv->thread);
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index ebaada8db929..329b30fac8fc 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -43,15 +43,6 @@
#include <linux/ratelimit.h>
#include <asm/io.h>
-#include <linux/uaccess.h>
-
-#define MOXA 0x400
-#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */
-#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */
-#define MOXA_GETDATACOUNT (MOXA + 23)
-#define MOXA_GET_IOQUEUE (MOXA + 27)
-#define MOXA_FLUSH_QUEUE (MOXA + 28)
-#define MOXA_GETMSTATUS (MOXA + 65)
/*
* System Configuration
@@ -347,8 +338,6 @@
#define MX_PARMARK 0xA0
#define MX_PARSPACE 0x20
-#define MOXA_VERSION "6.0k"
-
#define MOXA_FW_HDRLEN 32
#define MOXAMAJOR 172
@@ -357,33 +346,21 @@
#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */
#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD)
-#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \
- (brd)->boardType == MOXA_BOARD_C320_PCI)
-
-/*
- * Define the Moxa PCI vendor and device IDs.
- */
-#define MOXA_BUS_TYPE_ISA 0
-#define MOXA_BUS_TYPE_PCI 1
+#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_PCI)
enum {
MOXA_BOARD_C218_PCI = 1,
- MOXA_BOARD_C218_ISA,
MOXA_BOARD_C320_PCI,
- MOXA_BOARD_C320_ISA,
MOXA_BOARD_CP204J,
};
static char *moxa_brdname[] =
{
"C218 Turbo PCI series",
- "C218 Turbo ISA series",
"C320 Turbo PCI series",
- "C320 Turbo ISA series",
"CP-204J series",
};
-#ifdef CONFIG_PCI
static const struct pci_device_id moxa_pcibrds[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218),
.driver_data = MOXA_BOARD_C218_PCI },
@@ -394,14 +371,12 @@ static const struct pci_device_id moxa_pcibrds[] = {
{ 0 }
};
MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
-#endif /* CONFIG_PCI */
struct moxa_port;
static struct moxa_board_conf {
int boardType;
int numPorts;
- int busType;
unsigned int ready;
@@ -413,19 +388,6 @@ static struct moxa_board_conf {
void __iomem *intTable;
} moxa_boards[MAX_BOARDS];
-struct mxser_mstatus {
- tcflag_t cflag;
- int cts;
- int dsr;
- int ri;
- int dcd;
-};
-
-struct moxaq_str {
- int inq;
- int outq;
-};
-
struct moxa_port {
struct tty_port port;
struct moxa_board_conf *board;
@@ -440,12 +402,6 @@ struct moxa_port {
u8 lowChkFlag;
};
-struct mon_str {
- int tick;
- int rxcnt[MAX_PORTS];
- int txcnt[MAX_PORTS];
-};
-
/* statusflags */
#define TXSTOPPED 1
#define LOWWAIT 2
@@ -455,17 +411,11 @@ struct mon_str {
#define WAKEUP_CHARS 256
static int ttymajor = MOXAMAJOR;
-static struct mon_str moxaLog;
static unsigned int moxaFuncTout = HZ / 2;
static unsigned int moxaLowWaterChk;
static DEFINE_MUTEX(moxa_openlock);
static DEFINE_SPINLOCK(moxa_lock);
-static unsigned long baseaddr[MAX_BOARDS];
-static unsigned int type[MAX_BOARDS];
-static unsigned int numports[MAX_BOARDS];
-static struct tty_port moxa_service_port;
-
MODULE_AUTHOR("William Chen");
MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
MODULE_LICENSE("GPL");
@@ -473,13 +423,6 @@ MODULE_FIRMWARE("c218tunx.cod");
MODULE_FIRMWARE("cp204unx.cod");
MODULE_FIRMWARE("c320tunx.cod");
-module_param_array(type, uint, NULL, 0);
-MODULE_PARM_DESC(type, "card type: C218=2, C320=4");
-module_param_hw_array(baseaddr, ulong, ioport, NULL, 0);
-MODULE_PARM_DESC(baseaddr, "base address");
-module_param_array(numports, uint, NULL, 0);
-MODULE_PARM_DESC(numports, "numports (ignored for C218)");
-
module_param(ttymajor, int, 0);
/*
@@ -583,104 +526,6 @@ static void moxa_low_water_check(void __iomem *ofsAddr)
* TTY operations
*/
-static int moxa_ioctl(struct tty_struct *tty,
- unsigned int cmd, unsigned long arg)
-{
- struct moxa_port *ch = tty->driver_data;
- void __user *argp = (void __user *)arg;
- int status, ret = 0;
-
- if (tty->index == MAX_PORTS) {
- if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE &&
- cmd != MOXA_GETMSTATUS)
- return -EINVAL;
- } else if (!ch)
- return -ENODEV;
-
- switch (cmd) {
- case MOXA_GETDATACOUNT:
- moxaLog.tick = jiffies;
- if (copy_to_user(argp, &moxaLog, sizeof(moxaLog)))
- ret = -EFAULT;
- break;
- case MOXA_FLUSH_QUEUE:
- MoxaPortFlushData(ch, arg);
- break;
- case MOXA_GET_IOQUEUE: {
- struct moxaq_str __user *argm = argp;
- struct moxaq_str tmp;
- struct moxa_port *p;
- unsigned int i, j;
-
- for (i = 0; i < MAX_BOARDS; i++) {
- p = moxa_boards[i].ports;
- for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
- memset(&tmp, 0, sizeof(tmp));
- spin_lock_bh(&moxa_lock);
- if (moxa_boards[i].ready) {
- tmp.inq = MoxaPortRxQueue(p);
- tmp.outq = MoxaPortTxQueue(p);
- }
- spin_unlock_bh(&moxa_lock);
- if (copy_to_user(argm, &tmp, sizeof(tmp)))
- return -EFAULT;
- }
- }
- break;
- } case MOXA_GET_OQUEUE:
- status = MoxaPortTxQueue(ch);
- ret = put_user(status, (unsigned long __user *)argp);
- break;
- case MOXA_GET_IQUEUE:
- status = MoxaPortRxQueue(ch);
- ret = put_user(status, (unsigned long __user *)argp);
- break;
- case MOXA_GETMSTATUS: {
- struct mxser_mstatus __user *argm = argp;
- struct mxser_mstatus tmp;
- struct moxa_port *p;
- unsigned int i, j;
-
- for (i = 0; i < MAX_BOARDS; i++) {
- p = moxa_boards[i].ports;
- for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
- struct tty_struct *ttyp;
- memset(&tmp, 0, sizeof(tmp));
- spin_lock_bh(&moxa_lock);
- if (!moxa_boards[i].ready) {
- spin_unlock_bh(&moxa_lock);
- goto copy;
- }
-
- status = MoxaPortLineStatus(p);
- spin_unlock_bh(&moxa_lock);
-
- if (status & 1)
- tmp.cts = 1;
- if (status & 2)
- tmp.dsr = 1;
- if (status & 4)
- tmp.dcd = 1;
-
- ttyp = tty_port_tty_get(&p->port);
- if (!ttyp)
- tmp.cflag = p->cflag;
- else
- tmp.cflag = ttyp->termios.c_cflag;
- tty_kref_put(ttyp);
-copy:
- if (copy_to_user(argm, &tmp, sizeof(tmp)))
- return -EFAULT;
- }
- }
- break;
- }
- default:
- ret = -ENOIOCTLCMD;
- }
- return ret;
-}
-
static int moxa_break_ctl(struct tty_struct *tty, int state)
{
struct moxa_port *port = tty->driver_data;
@@ -697,7 +542,6 @@ static const struct tty_operations moxa_ops = {
.write_room = moxa_write_room,
.flush_buffer = moxa_flush_buffer,
.chars_in_buffer = moxa_chars_in_buffer,
- .ioctl = moxa_ioctl,
.set_termios = moxa_set_termios,
.stop = moxa_stop,
.start = moxa_start,
@@ -725,7 +569,6 @@ static DEFINE_TIMER(moxaTimer, moxa_poll);
static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model)
{
switch (brd->boardType) {
- case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
if (model != 1)
goto err;
@@ -769,7 +612,6 @@ static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf,
msleep(2000);
switch (brd->boardType) {
- case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
tmp = readw(baseAddr + C218_key);
if (tmp != C218_KeyCode)
@@ -833,7 +675,6 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
switch (brd->boardType) {
case MOXA_BOARD_CP204J:
- case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
key = C218_key;
loadbuf = C218_LoadBuf;
@@ -898,15 +739,9 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
return -EIO;
if (MOXA_IS_320(brd)) {
- if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */
- writew(0x3800, baseAddr + TMS320_PORT1);
- writew(0x3900, baseAddr + TMS320_PORT2);
- writew(28499, baseAddr + TMS320_CLOCK);
- } else {
- writew(0x3200, baseAddr + TMS320_PORT1);
- writew(0x3400, baseAddr + TMS320_PORT2);
- writew(19999, baseAddr + TMS320_CLOCK);
- }
+ writew(0x3800, baseAddr + TMS320_PORT1);
+ writew(0x3900, baseAddr + TMS320_PORT2);
+ writew(28499, baseAddr + TMS320_CLOCK);
}
writew(1, baseAddr + Disable_IRQ);
writew(0, baseAddr + Magic_no);
@@ -957,7 +792,6 @@ static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr,
return retval;
switch (brd->boardType) {
- case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
case MOXA_BOARD_CP204J:
port = brd->ports;
@@ -1141,7 +975,6 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
}
switch (brd->boardType) {
- case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
file = "c218tunx.cod";
break;
@@ -1227,7 +1060,6 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
kfree(brd->ports);
}
-#ifdef CONFIG_PCI
static int moxa_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1270,7 +1102,6 @@ static int moxa_pci_probe(struct pci_dev *pdev,
board->boardType = board_type;
switch (board_type) {
- case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
board->numPorts = 8;
break;
@@ -1282,7 +1113,6 @@ static int moxa_pci_probe(struct pci_dev *pdev,
board->numPorts = 0;
break;
}
- board->busType = MOXA_BUS_TYPE_PCI;
retval = moxa_init_board(board, &pdev->dev);
if (retval)
@@ -1318,21 +1148,12 @@ static struct pci_driver moxa_pci_driver = {
.probe = moxa_pci_probe,
.remove = moxa_pci_remove
};
-#endif /* CONFIG_PCI */
static int __init moxa_init(void)
{
- unsigned int isabrds = 0;
int retval = 0;
- struct moxa_board_conf *brd = moxa_boards;
- unsigned int i;
-
- printk(KERN_INFO "MOXA Intellio family driver version %s\n",
- MOXA_VERSION);
- tty_port_init(&moxa_service_port);
-
- moxaDriver = tty_alloc_driver(MAX_PORTS + 1,
+ moxaDriver = tty_alloc_driver(MAX_PORTS,
TTY_DRIVER_REAL_RAW |
TTY_DRIVER_DYNAMIC_DEV);
if (IS_ERR(moxaDriver))
@@ -1348,8 +1169,6 @@ static int __init moxa_init(void)
moxaDriver->init_termios.c_ispeed = 9600;
moxaDriver->init_termios.c_ospeed = 9600;
tty_set_operations(moxaDriver, &moxa_ops);
- /* Having one more port only for ioctls is ugly */
- tty_port_link_device(&moxa_service_port, moxaDriver, MAX_PORTS);
if (tty_register_driver(moxaDriver)) {
printk(KERN_ERR "can't register MOXA Smartio tty driver!\n");
@@ -1357,66 +1176,18 @@ static int __init moxa_init(void)
return -1;
}
- /* Find the boards defined from module args. */
-
- for (i = 0; i < MAX_BOARDS; i++) {
- if (!baseaddr[i])
- break;
- if (type[i] == MOXA_BOARD_C218_ISA ||
- type[i] == MOXA_BOARD_C320_ISA) {
- pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
- isabrds + 1, moxa_brdname[type[i] - 1],
- baseaddr[i]);
- brd->boardType = type[i];
- brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 :
- numports[i];
- brd->busType = MOXA_BUS_TYPE_ISA;
- brd->basemem = ioremap(baseaddr[i], 0x4000);
- if (!brd->basemem) {
- printk(KERN_ERR "MOXA: can't remap %lx\n",
- baseaddr[i]);
- continue;
- }
- if (moxa_init_board(brd, NULL)) {
- iounmap(brd->basemem);
- brd->basemem = NULL;
- continue;
- }
-
- printk(KERN_INFO "MOXA isa board found at 0x%.8lx and "
- "ready (%u ports, firmware loaded)\n",
- baseaddr[i], brd->numPorts);
-
- brd++;
- isabrds++;
- }
- }
-
-#ifdef CONFIG_PCI
retval = pci_register_driver(&moxa_pci_driver);
- if (retval) {
+ if (retval)
printk(KERN_ERR "Can't register MOXA pci driver!\n");
- if (isabrds)
- retval = 0;
- }
-#endif
return retval;
}
static void __exit moxa_exit(void)
{
- unsigned int i;
-
-#ifdef CONFIG_PCI
pci_unregister_driver(&moxa_pci_driver);
-#endif
-
- for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */
- if (moxa_boards[i].ready)
- moxa_board_deinit(&moxa_boards[i]);
- del_timer_sync(&moxaTimer);
+ timer_delete_sync(&moxaTimer);
tty_unregister_driver(moxaDriver);
tty_driver_kref_put(moxaDriver);
@@ -1457,9 +1228,6 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
int port;
port = tty->index;
- if (port == MAX_PORTS) {
- return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
- }
if (mutex_lock_interruptible(&moxa_openlock))
return -ERESTARTSYS;
brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];
@@ -2182,7 +1950,6 @@ static ssize_t MoxaPortWriteData(struct tty_struct *tty, const u8 *buffer,
c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);
if (c > len)
c = len;
- moxaLog.txcnt[port->port.tty->index] += c;
total = c;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_txb);
@@ -2224,7 +1991,6 @@ static ssize_t MoxaPortWriteData(struct tty_struct *tty, const u8 *buffer,
static int MoxaPortReadData(struct moxa_port *port)
{
- struct tty_struct *tty = port->port.tty;
void __iomem *baseAddr, *ofsAddr, *ofs;
u8 *dst;
unsigned int count, len, total;
@@ -2243,7 +2009,6 @@ static int MoxaPortReadData(struct moxa_port *port)
return 0;
total = count;
- moxaLog.rxcnt[tty->index] += total;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_rxb);
writew(spage, baseAddr + Control_reg);
@@ -2331,8 +2096,6 @@ static int moxa_get_serial_info(struct tty_struct *tty,
{
struct moxa_port *info = tty->driver_data;
- if (tty->index == MAX_PORTS)
- return -EINVAL;
if (!info)
return -ENODEV;
mutex_lock(&info->port.mutex);
@@ -2352,8 +2115,6 @@ static int moxa_set_serial_info(struct tty_struct *tty,
struct moxa_port *info = tty->driver_data;
unsigned int close_delay;
- if (tty->index == MAX_PORTS)
- return -EINVAL;
if (!info)
return -ENODEV;
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 363afe11974f..40a336ef8c7e 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -1941,7 +1941,7 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command,
/* Does the reply match our command */
if (ctrl != NULL && (command == ctrl->cmd || command == CMD_NSC)) {
/* Our command was replied to, kill the retry timer */
- del_timer(&gsm->t2_timer);
+ timer_delete(&gsm->t2_timer);
gsm->pending_cmd = NULL;
/* Rejected by the other end */
if (command == CMD_NSC)
@@ -2131,7 +2131,7 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
static void gsm_dlci_close(struct gsm_dlci *dlci)
{
- del_timer(&dlci->t1);
+ timer_delete(&dlci->t1);
if (debug & DBG_ERRORS)
pr_debug("DLCI %d goes closed.\n", dlci->addr);
dlci->state = DLCI_CLOSED;
@@ -2144,7 +2144,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
tty_port_set_initialized(&dlci->port, false);
wake_up_interruptible(&dlci->port.open_wait);
} else {
- del_timer(&dlci->gsm->ka_timer);
+ timer_delete(&dlci->gsm->ka_timer);
dlci->gsm->dead = true;
}
/* A DLCI 0 close is a MUX termination so we need to kick that
@@ -2166,7 +2166,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
/* Note that SABM UA .. SABM UA first UA lost can mean that we go
open -> open */
- del_timer(&dlci->t1);
+ timer_delete(&dlci->t1);
/* This will let a tty open continue */
dlci->state = DLCI_OPEN;
dlci->constipated = false;
@@ -3144,9 +3144,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
}
/* Finish outstanding timers, making sure they are done */
- del_timer_sync(&gsm->kick_timer);
- del_timer_sync(&gsm->t2_timer);
- del_timer_sync(&gsm->ka_timer);
+ timer_delete_sync(&gsm->kick_timer);
+ timer_delete_sync(&gsm->t2_timer);
+ timer_delete_sync(&gsm->ka_timer);
/* Finish writing to ldisc */
flush_work(&gsm->tx_work);
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 5e9ca4376d68..6af3f3a0b531 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -56,6 +56,8 @@
*/
#define WAKEUP_CHARS 256
+#define N_TTY_BUF_SIZE 4096
+
/*
* This defines the low- and high-watermarks for throttling and
* unthrottling the TTY driver. These watermarks are used for
@@ -79,14 +81,6 @@
#define ECHO_BLOCK 256
#define ECHO_DISCARD_WATERMARK N_TTY_BUF_SIZE - (ECHO_BLOCK + 32)
-
-#undef N_TTY_TRACE
-#ifdef N_TTY_TRACE
-# define n_tty_trace(f, args...) trace_printk(f, ##args)
-#else
-# define n_tty_trace(f, args...) no_printk(f, ##args)
-#endif
-
struct n_tty_data {
/* producer-published */
size_t read_head;
@@ -486,18 +480,13 @@ static int do_output_char(u8 c, struct tty_struct *tty, int space)
static int process_output(u8 c, struct tty_struct *tty)
{
struct n_tty_data *ldata = tty->disc_data;
- int space, retval;
- mutex_lock(&ldata->output_lock);
-
- space = tty_write_room(tty);
- retval = do_output_char(c, tty, space);
+ guard(mutex)(&ldata->output_lock);
- mutex_unlock(&ldata->output_lock);
- if (retval < 0)
+ if (do_output_char(c, tty, tty_write_room(tty)) < 0)
return -1;
- else
- return 0;
+
+ return 0;
}
/**
@@ -522,17 +511,15 @@ static ssize_t process_output_block(struct tty_struct *tty,
const u8 *buf, unsigned int nr)
{
struct n_tty_data *ldata = tty->disc_data;
- int space;
- int i;
+ unsigned int space, i;
const u8 *cp;
- mutex_lock(&ldata->output_lock);
+ guard(mutex)(&ldata->output_lock);
space = tty_write_room(tty);
- if (space <= 0) {
- mutex_unlock(&ldata->output_lock);
- return space;
- }
+ if (space == 0)
+ return 0;
+
if (nr > space)
nr = space;
@@ -544,18 +531,18 @@ static ssize_t process_output_block(struct tty_struct *tty,
if (O_ONLRET(tty))
ldata->column = 0;
if (O_ONLCR(tty))
- goto break_out;
+ goto do_write;
ldata->canon_column = ldata->column;
break;
case '\r':
if (O_ONOCR(tty) && ldata->column == 0)
- goto break_out;
+ goto do_write;
if (O_OCRNL(tty))
- goto break_out;
+ goto do_write;
ldata->canon_column = ldata->column = 0;
break;
case '\t':
- goto break_out;
+ goto do_write;
case '\b':
if (ldata->column > 0)
ldata->column--;
@@ -563,18 +550,15 @@ static ssize_t process_output_block(struct tty_struct *tty,
default:
if (!iscntrl(c)) {
if (O_OLCUC(tty))
- goto break_out;
+ goto do_write;
if (!is_continuation(c, tty))
ldata->column++;
}
break;
}
}
-break_out:
- i = tty->ops->write(tty, buf, i);
-
- mutex_unlock(&ldata->output_lock);
- return i;
+do_write:
+ return tty->ops->write(tty, buf, i);
}
static int n_tty_process_echo_ops(struct tty_struct *tty, size_t *tail,
@@ -696,7 +680,7 @@ static int n_tty_process_echo_ops(struct tty_struct *tty, size_t *tail,
static size_t __process_echoes(struct tty_struct *tty)
{
struct n_tty_data *ldata = tty->disc_data;
- int space, old_space;
+ unsigned int space, old_space;
size_t tail;
u8 c;
@@ -2034,9 +2018,6 @@ static bool canon_copy_from_read_buf(const struct tty_struct *tty, u8 **kbp,
tail = MASK(ldata->read_tail);
size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
- n_tty_trace("%s: nr:%zu tail:%zu n:%zu size:%zu\n",
- __func__, *nr, tail, n, size);
-
eol = find_next_bit(ldata->read_flags, size, tail);
more = n - (size - tail);
if (eol == N_TTY_BUF_SIZE && more) {
@@ -2054,9 +2035,6 @@ static bool canon_copy_from_read_buf(const struct tty_struct *tty, u8 **kbp,
if (!found || read_buf(ldata, eol) != __DISABLED_CHAR)
n = c;
- n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n",
- __func__, eol, found, n, c, tail, more);
-
tty_copy(tty, *kbp, tail, n);
*kbp += n;
*nr -= n;
@@ -2133,6 +2111,66 @@ static int job_control(struct tty_struct *tty, struct file *file)
return __tty_check_change(tty, SIGTTIN);
}
+/*
+ * We still hold the atomic_read_lock and the termios_rwsem, and can just
+ * continue to copy data.
+ */
+static ssize_t n_tty_continue_cookie(struct tty_struct *tty, u8 *kbuf,
+ size_t nr, void **cookie)
+{
+ struct n_tty_data *ldata = tty->disc_data;
+ u8 *kb = kbuf;
+
+ if (ldata->icanon && !L_EXTPROC(tty)) {
+ /*
+ * If we have filled the user buffer, see if we should skip an
+ * EOF character before releasing the lock and returning done.
+ */
+ if (!nr)
+ canon_skip_eof(ldata);
+ else if (canon_copy_from_read_buf(tty, &kb, &nr))
+ return kb - kbuf;
+ } else {
+ if (copy_from_read_buf(tty, &kb, &nr))
+ return kb - kbuf;
+ }
+
+ /* No more data - release locks and stop retries */
+ n_tty_kick_worker(tty);
+ n_tty_check_unthrottle(tty);
+ up_read(&tty->termios_rwsem);
+ mutex_unlock(&ldata->atomic_read_lock);
+ *cookie = NULL;
+
+ return kb - kbuf;
+}
+
+static int n_tty_wait_for_input(struct tty_struct *tty, struct file *file,
+ struct wait_queue_entry *wait, long *timeout)
+{
+ if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+ return -EIO;
+ if (tty_hung_up_p(file))
+ return 0;
+ /*
+ * Abort readers for ttys which never actually get hung up.
+ * See __tty_hangup().
+ */
+ if (test_bit(TTY_HUPPING, &tty->flags))
+ return 0;
+ if (!*timeout)
+ return 0;
+ if (tty_io_nonblock(tty, file))
+ return -EAGAIN;
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ up_read(&tty->termios_rwsem);
+ *timeout = wait_woken(wait, TASK_INTERRUPTIBLE, *timeout);
+ down_read(&tty->termios_rwsem);
+
+ return 1;
+}
/**
* n_tty_read - read function for tty
@@ -2166,36 +2204,9 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf,
bool packet;
size_t old_tail;
- /*
- * Is this a continuation of a read started earler?
- *
- * If so, we still hold the atomic_read_lock and the
- * termios_rwsem, and can just continue to copy data.
- */
- if (*cookie) {
- if (ldata->icanon && !L_EXTPROC(tty)) {
- /*
- * If we have filled the user buffer, see
- * if we should skip an EOF character before
- * releasing the lock and returning done.
- */
- if (!nr)
- canon_skip_eof(ldata);
- else if (canon_copy_from_read_buf(tty, &kb, &nr))
- return kb - kbuf;
- } else {
- if (copy_from_read_buf(tty, &kb, &nr))
- return kb - kbuf;
- }
-
- /* No more data - release locks and stop retries */
- n_tty_kick_worker(tty);
- n_tty_check_unthrottle(tty);
- up_read(&tty->termios_rwsem);
- mutex_unlock(&ldata->atomic_read_lock);
- *cookie = NULL;
- return kb - kbuf;
- }
+ /* Is this a continuation of a read started earlier? */
+ if (*cookie)
+ return n_tty_continue_cookie(tty, kbuf, nr, cookie);
retval = job_control(tty, file);
if (retval < 0)
@@ -2250,34 +2261,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf,
tty_buffer_flush_work(tty->port);
down_read(&tty->termios_rwsem);
if (!input_available_p(tty, 0)) {
- if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
- retval = -EIO;
+ int ret = n_tty_wait_for_input(tty, file, &wait,
+ &timeout);
+ if (ret <= 0) {
+ retval = ret;
break;
}
- if (tty_hung_up_p(file))
- break;
- /*
- * Abort readers for ttys which never actually
- * get hung up. See __tty_hangup().
- */
- if (test_bit(TTY_HUPPING, &tty->flags))
- break;
- if (!timeout)
- break;
- if (tty_io_nonblock(tty, file)) {
- retval = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- up_read(&tty->termios_rwsem);
-
- timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
- timeout);
-
- down_read(&tty->termios_rwsem);
continue;
}
}
@@ -2292,21 +2281,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf,
nr--;
}
- /*
- * Copy data, and if there is more to be had
- * and we have nothing more to wait for, then
- * let's mark us for retries.
- *
- * NOTE! We return here with both the termios_sem
- * and atomic_read_lock still held, the retries
- * will release them when done.
- */
- if (copy_from_read_buf(tty, &kb, &nr) && kb - kbuf >= minimum) {
-more_to_be_read:
- remove_wait_queue(&tty->read_wait, &wait);
- *cookie = cookie;
- return kb - kbuf;
- }
+ if (copy_from_read_buf(tty, &kb, &nr) && kb - kbuf >= minimum)
+ goto more_to_be_read;
}
n_tty_check_unthrottle(tty);
@@ -2333,6 +2309,18 @@ more_to_be_read:
retval = kb - kbuf;
return retval;
+more_to_be_read:
+ /*
+ * There is more to be had and we have nothing more to wait for, so
+ * let's mark us for retries.
+ *
+ * NOTE! We return here with both the termios_sem and atomic_read_lock
+ * still held, the retries will release them when done.
+ */
+ remove_wait_queue(&tty->read_wait, &wait);
+ *cookie = cookie;
+
+ return kb - kbuf;
}
/**
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index ebf0bbc2cff2..eb2a2e58fe78 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -316,17 +316,6 @@ void serdev_device_write_flush(struct serdev_device *serdev)
}
EXPORT_SYMBOL_GPL(serdev_device_write_flush);
-int serdev_device_write_room(struct serdev_device *serdev)
-{
- struct serdev_controller *ctrl = serdev->ctrl;
-
- if (!ctrl || !ctrl->ops->write_room)
- return 0;
-
- return serdev->ctrl->ops->write_room(ctrl);
-}
-EXPORT_SYMBOL_GPL(serdev_device_write_room);
-
unsigned int serdev_device_set_baudrate(struct serdev_device *serdev, unsigned int speed)
{
struct serdev_controller *ctrl = serdev->ctrl;
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index 3d7ae7fa5018..bab1b143b8a6 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -92,14 +92,6 @@ static void ttyport_write_flush(struct serdev_controller *ctrl)
tty_driver_flush_buffer(tty);
}
-static int ttyport_write_room(struct serdev_controller *ctrl)
-{
- struct serport *serport = serdev_controller_get_drvdata(ctrl);
- struct tty_struct *tty = serport->tty;
-
- return tty_write_room(tty);
-}
-
static int ttyport_open(struct serdev_controller *ctrl)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
@@ -259,7 +251,6 @@ static int ttyport_break_ctl(struct serdev_controller *ctrl, unsigned int break_
static const struct serdev_controller_ops ctrl_ops = {
.write_buf = ttyport_write_buf,
.write_flush = ttyport_write_flush,
- .write_room = ttyport_write_room,
.open = ttyport_open,
.close = ttyport_close,
.set_flow_control = ttyport_set_flow_control,
diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c
index e5da9ce26006..392447038bfb 100644
--- a/drivers/tty/serial/8250/8250_aspeed_vuart.c
+++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c
@@ -550,7 +550,7 @@ static void aspeed_vuart_remove(struct platform_device *pdev)
{
struct aspeed_vuart *vuart = platform_get_drvdata(pdev);
- del_timer_sync(&vuart->unthrottle_timer);
+ timer_delete_sync(&vuart->unthrottle_timer);
aspeed_vuart_set_enabled(vuart, false);
serial8250_unregister_port(vuart->line);
sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 6f676bb37ac3..5a56f853cf6d 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -298,7 +298,7 @@ static void univ8250_release_irq(struct uart_8250_port *up)
{
struct uart_port *port = &up->port;
- del_timer_sync(&up->timer);
+ timer_delete_sync(&up->timer);
up->timer.function = serial8250_timeout;
if (port->irq)
serial_unlink_irq_chain(up);
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
index f245a84f4a50..bdd26c9f34bd 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -162,7 +162,7 @@ void serial8250_tx_dma_flush(struct uart_8250_port *p)
*/
dma->tx_size = 0;
- dmaengine_terminate_async(dma->rxchan);
+ dmaengine_terminate_async(dma->txchan);
}
int serial8250_rx_dma(struct uart_8250_port *p)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 6afcf27db3b8..1902f29444a1 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -107,11 +107,23 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
return value;
}
+/*
+ * This function is being called as part of the uart_port::serial_out()
+ * routine. Hence, it must not call serial_port_out() or serial_out()
+ * against the modified registers here, i.e. LCR.
+ */
static void dw8250_force_idle(struct uart_port *p)
{
struct uart_8250_port *up = up_to_u8250p(p);
unsigned int lsr;
+ /*
+ * The following call currently performs serial_out()
+ * against the FCR register. Because it differs to LCR
+ * there will be no infinite loop, but if it ever gets
+ * modified, we might need a new custom version of it
+ * that avoids infinite recursion.
+ */
serial8250_clear_and_reinit_fifos(up);
/*
@@ -120,14 +132,19 @@ static void dw8250_force_idle(struct uart_port *p)
* enabled.
*/
if (up->fcr & UART_FCR_ENABLE_FIFO) {
- lsr = p->serial_in(p, UART_LSR);
+ lsr = serial_port_in(p, UART_LSR);
if (!(lsr & UART_LSR_DR))
return;
}
- (void)p->serial_in(p, UART_RX);
+ serial_port_in(p, UART_RX);
}
+/*
+ * This function is being called as part of the uart_port::serial_out()
+ * routine. Hence, it must not call serial_port_out() or serial_out()
+ * against the modified registers here, i.e. LCR.
+ */
static void dw8250_check_lcr(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = to_dw8250_data(p->private_data);
@@ -139,7 +156,7 @@ static void dw8250_check_lcr(struct uart_port *p, int offset, int value)
/* Make sure LCR write wasn't ignored */
while (tries--) {
- unsigned int lcr = p->serial_in(p, offset);
+ unsigned int lcr = serial_port_in(p, offset);
if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
return;
@@ -260,7 +277,7 @@ static int dw8250_handle_irq(struct uart_port *p)
{
struct uart_8250_port *up = up_to_u8250p(p);
struct dw8250_data *d = to_dw8250_data(p->private_data);
- unsigned int iir = p->serial_in(p, UART_IIR);
+ unsigned int iir = serial_port_in(p, UART_IIR);
bool rx_timeout = (iir & 0x3f) == UART_IIR_RX_TIMEOUT;
unsigned int quirks = d->pdata->quirks;
unsigned int status;
@@ -281,7 +298,7 @@ static int dw8250_handle_irq(struct uart_port *p)
status = serial_lsr_in(up);
if (!(status & (UART_LSR_DR | UART_LSR_BI)))
- (void) p->serial_in(p, UART_RX);
+ serial_port_in(p, UART_RX);
uart_port_unlock_irqrestore(p, flags);
}
@@ -303,7 +320,7 @@ static int dw8250_handle_irq(struct uart_port *p)
if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
/* Clear the USR */
- (void)p->serial_in(p, d->pdata->usr_reg);
+ serial_port_in(p, d->pdata->usr_reg);
return 1;
}
@@ -390,7 +407,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios)
{
struct uart_8250_port *up = up_to_u8250p(p);
- unsigned int mcr = p->serial_in(p, UART_MCR);
+ unsigned int mcr = serial_port_in(p, UART_MCR);
if (up->capabilities & UART_CAP_IRDA) {
if (termios->c_line == N_IRDA)
@@ -398,7 +415,7 @@ static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios)
else
mcr &= ~DW_UART_MCR_SIRE;
- p->serial_out(p, UART_MCR, mcr);
+ serial_port_out(p, UART_MCR, mcr);
}
serial8250_do_set_ldisc(p, termios);
}
@@ -421,6 +438,18 @@ static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
return param == chan->device->dev;
}
+static void dw8250_setup_dma_filter(struct uart_port *p, struct dw8250_data *data)
+{
+ /* Platforms with iDMA 64-bit */
+ if (platform_get_resource_byname(to_platform_device(p->dev), IORESOURCE_MEM, "lpss_priv")) {
+ data->data.dma.rx_param = p->dev->parent;
+ data->data.dma.tx_param = p->dev->parent;
+ data->data.dma.fn = dw8250_idma_filter;
+ } else {
+ data->data.dma.fn = dw8250_fallback_dma_filter;
+ }
+}
+
static u32 dw8250_rzn1_get_dmacr_burst(int max_burst)
{
if (max_burst >= 8)
@@ -459,8 +488,8 @@ static void dw8250_prepare_rx_dma(struct uart_8250_port *p)
static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
{
- unsigned int quirks = data->pdata ? data->pdata->quirks : 0;
- u32 cpr_value = data->pdata ? data->pdata->cpr_value : 0;
+ unsigned int quirks = data->pdata->quirks;
+ u32 cpr_value = data->pdata->cpr_value;
if (quirks & DW_UART_QUIRK_CPR_VALUE)
data->data.cpr_value = cpr_value;
@@ -491,14 +520,6 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
p->serial_in = dw8250_serial_in32;
data->uart_16550_compatible = true;
}
-
- /* Platforms with iDMA 64-bit */
- if (platform_get_resource_byname(to_platform_device(p->dev),
- IORESOURCE_MEM, "lpss_priv")) {
- data->data.dma.rx_param = p->dev->parent;
- data->data.dma.tx_param = p->dev->parent;
- data->data.dma.fn = dw8250_idma_filter;
- }
}
static void dw8250_reset_control_assert(void *data)
@@ -520,7 +541,6 @@ static int dw8250_probe(struct platform_device *pdev)
return dev_err_probe(dev, -EINVAL, "no registers defined\n");
spin_lock_init(&p->lock);
- p->handle_irq = dw8250_handle_irq;
p->pm = dw8250_do_pm;
p->type = PORT_8250;
p->flags = UPF_FIXED_PORT;
@@ -532,13 +552,8 @@ static int dw8250_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- data->data.dma.fn = dw8250_fallback_dma_filter;
- data->pdata = device_get_match_data(p->dev);
p->private_data = &data->data;
- data->uart_16550_compatible = device_property_read_bool(dev,
- "snps,uart-16550-compatible");
-
p->mapbase = regs->start;
p->mapsize = resource_size(regs);
@@ -626,11 +641,19 @@ static int dw8250_probe(struct platform_device *pdev)
if (err)
return err;
- dw8250_quirks(p, data);
+ data->uart_16550_compatible = device_property_read_bool(dev, "snps,uart-16550-compatible");
+
+ data->pdata = device_get_match_data(p->dev);
+ if (data->pdata)
+ dw8250_quirks(p, data);
/* If the Busy Functionality is not implemented, don't handle it */
if (data->uart_16550_compatible)
p->handle_irq = NULL;
+ else if (data->pdata)
+ p->handle_irq = dw8250_handle_irq;
+
+ dw8250_setup_dma_filter(p, data);
if (!data->skip_autocfg)
dw8250_setup_port(p);
diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
index 1b7bd55619c6..649ae5c8304d 100644
--- a/drivers/tty/serial/8250/8250_fsl.c
+++ b/drivers/tty/serial/8250/8250_fsl.c
@@ -32,7 +32,7 @@ int fsl8250_handle_irq(struct uart_port *port)
uart_port_lock_irqsave(&up->port, &flags);
- iir = port->serial_in(port, UART_IIR);
+ iir = serial_port_in(port, UART_IIR);
if (iir & UART_IIR_NO_INT) {
uart_port_unlock_irqrestore(&up->port, flags);
return 0;
@@ -54,12 +54,12 @@ int fsl8250_handle_irq(struct uart_port *port)
if (unlikely((iir & UART_IIR_ID) == UART_IIR_RLSI &&
(up->lsr_saved_flags & UART_LSR_BI))) {
up->lsr_saved_flags &= ~UART_LSR_BI;
- port->serial_in(port, UART_RX);
+ serial_port_in(port, UART_RX);
uart_port_unlock_irqrestore(&up->port, flags);
return 1;
}
- lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
+ lsr = orig_lsr = serial_port_in(port, UART_LSR);
/* Process incoming characters first */
if ((lsr & (UART_LSR_DR | UART_LSR_BI)) &&
@@ -71,7 +71,7 @@ int fsl8250_handle_irq(struct uart_port *port)
if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) {
unsigned long delay;
- up->ier = port->serial_in(port, UART_IER);
+ up->ier = serial_port_in(port, UART_IER);
if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
port->ops->stop_rx(port);
} else {
diff --git a/drivers/tty/serial/8250/8250_ni.c b/drivers/tty/serial/8250/8250_ni.c
new file mode 100644
index 000000000000..b10a42d2ad63
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_ni.c
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NI 16550 UART Driver
+ *
+ * The National Instruments (NI) 16550 is a UART that is compatible with the
+ * TL16C550C and OX16C950B register interfaces, but has additional functions
+ * for RS-485 transceiver control. This driver implements support for the
+ * additional functionality on top of the standard serial8250 core.
+ *
+ * Copyright 2012-2023 National Instruments Corporation
+ */
+
+#include <linux/acpi.h>
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/clk.h>
+
+#include "8250.h"
+
+/* Extra bits in UART_ACR */
+#define NI16550_ACR_AUTO_DTR_EN BIT(4)
+
+/* TFS - TX FIFO Size */
+#define NI16550_TFS_OFFSET 0x0C
+/* RFS - RX FIFO Size */
+#define NI16550_RFS_OFFSET 0x0D
+
+/* PMR - Port Mode Register */
+#define NI16550_PMR_OFFSET 0x0E
+/* PMR[1:0] - Port Capabilities */
+#define NI16550_PMR_CAP_MASK GENMASK(1, 0)
+#define NI16550_PMR_NOT_IMPL FIELD_PREP(NI16550_PMR_CAP_MASK, 0) /* not implemented */
+#define NI16550_PMR_CAP_RS232 FIELD_PREP(NI16550_PMR_CAP_MASK, 1) /* RS-232 capable */
+#define NI16550_PMR_CAP_RS485 FIELD_PREP(NI16550_PMR_CAP_MASK, 2) /* RS-485 capable */
+#define NI16550_PMR_CAP_DUAL FIELD_PREP(NI16550_PMR_CAP_MASK, 3) /* dual-port */
+/* PMR[4] - Interface Mode */
+#define NI16550_PMR_MODE_MASK GENMASK(4, 4)
+#define NI16550_PMR_MODE_RS232 FIELD_PREP(NI16550_PMR_MODE_MASK, 0) /* currently 232 */
+#define NI16550_PMR_MODE_RS485 FIELD_PREP(NI16550_PMR_MODE_MASK, 1) /* currently 485 */
+
+/* PCR - Port Control Register */
+/*
+ * Wire Mode | Tx enabled? | Rx enabled?
+ * ---------------|----------------------|--------------------------
+ * PCR_RS422 | Always | Always
+ * PCR_ECHO_RS485 | When DTR asserted | Always
+ * PCR_DTR_RS485 | When DTR asserted | Disabled when TX enabled
+ * PCR_AUTO_RS485 | When data in TX FIFO | Disabled when TX enabled
+ */
+#define NI16550_PCR_OFFSET 0x0F
+#define NI16550_PCR_WIRE_MODE_MASK GENMASK(1, 0)
+#define NI16550_PCR_RS422 FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 0)
+#define NI16550_PCR_ECHO_RS485 FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 1)
+#define NI16550_PCR_DTR_RS485 FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 2)
+#define NI16550_PCR_AUTO_RS485 FIELD_PREP(NI16550_PCR_WIRE_MODE_MASK, 3)
+#define NI16550_PCR_TXVR_ENABLE_BIT BIT(3)
+#define NI16550_PCR_RS485_TERMINATION_BIT BIT(6)
+
+/* flags for ni16550_device_info */
+#define NI_HAS_PMR BIT(0)
+
+struct ni16550_device_info {
+ u32 uartclk;
+ u8 prescaler;
+ u8 flags;
+};
+
+struct ni16550_data {
+ int line;
+ struct clk *clk;
+};
+
+static int ni16550_enable_transceivers(struct uart_port *port)
+{
+ u8 pcr;
+
+ pcr = port->serial_in(port, NI16550_PCR_OFFSET);
+ pcr |= NI16550_PCR_TXVR_ENABLE_BIT;
+ dev_dbg(port->dev, "enable transceivers: write pcr: 0x%02x\n", pcr);
+ port->serial_out(port, NI16550_PCR_OFFSET, pcr);
+
+ return 0;
+}
+
+static int ni16550_disable_transceivers(struct uart_port *port)
+{
+ u8 pcr;
+
+ pcr = port->serial_in(port, NI16550_PCR_OFFSET);
+ pcr &= ~NI16550_PCR_TXVR_ENABLE_BIT;
+ dev_dbg(port->dev, "disable transceivers: write pcr: 0x%02x\n", pcr);
+ port->serial_out(port, NI16550_PCR_OFFSET, pcr);
+
+ return 0;
+}
+
+static int ni16550_rs485_config(struct uart_port *port,
+ struct ktermios *termios,
+ struct serial_rs485 *rs485)
+{
+ struct uart_8250_port *up = container_of(port, struct uart_8250_port, port);
+ u8 pcr;
+
+ pcr = serial_in(up, NI16550_PCR_OFFSET);
+ pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
+
+ if ((rs485->flags & SER_RS485_MODE_RS422) ||
+ !(rs485->flags & SER_RS485_ENABLED)) {
+ /* RS-422 */
+ pcr |= NI16550_PCR_RS422;
+ up->acr &= ~NI16550_ACR_AUTO_DTR_EN;
+ } else {
+ /* RS-485 2-wire Auto */
+ pcr |= NI16550_PCR_AUTO_RS485;
+ up->acr |= NI16550_ACR_AUTO_DTR_EN;
+ }
+
+ dev_dbg(port->dev, "config rs485: write pcr: 0x%02x, acr: %02x\n", pcr, up->acr);
+ serial_out(up, NI16550_PCR_OFFSET, pcr);
+ serial_icr_write(up, UART_ACR, up->acr);
+
+ return 0;
+}
+
+static bool is_pmr_rs232_mode(struct uart_8250_port *up)
+{
+ u8 pmr = serial_in(up, NI16550_PMR_OFFSET);
+ u8 pmr_mode = pmr & NI16550_PMR_MODE_MASK;
+ u8 pmr_cap = pmr & NI16550_PMR_CAP_MASK;
+
+ /*
+ * If the PMR is not implemented, then by default NI UARTs are
+ * connected to RS-485 transceivers
+ */
+ if (pmr_cap == NI16550_PMR_NOT_IMPL)
+ return false;
+
+ if (pmr_cap == NI16550_PMR_CAP_DUAL)
+ /*
+ * If the port is dual-mode capable, then read the mode bit
+ * to know the current mode
+ */
+ return pmr_mode == NI16550_PMR_MODE_RS232;
+ /*
+ * If it is not dual-mode capable, then decide based on the
+ * capability
+ */
+ return pmr_cap == NI16550_PMR_CAP_RS232;
+}
+
+static void ni16550_config_prescaler(struct uart_8250_port *up,
+ u8 prescaler)
+{
+ /*
+ * Page in the Enhanced Mode Registers
+ * Sets EFR[4] for Enhanced Mode.
+ */
+ u8 lcr_value;
+ u8 efr_value;
+
+ lcr_value = serial_in(up, UART_LCR);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+ efr_value = serial_in(up, UART_EFR);
+ efr_value |= UART_EFR_ECB;
+
+ serial_out(up, UART_EFR, efr_value);
+
+ /* Page out the Enhanced Mode Registers */
+ serial_out(up, UART_LCR, lcr_value);
+
+ /* Set prescaler to CPR register. */
+ serial_out(up, UART_SCR, UART_CPR);
+ serial_out(up, UART_ICR, prescaler);
+}
+
+static const struct serial_rs485 ni16550_rs485_supported = {
+ .flags = SER_RS485_ENABLED | SER_RS485_MODE_RS422 | SER_RS485_RTS_ON_SEND |
+ SER_RS485_RTS_AFTER_SEND,
+ /*
+ * delay_rts_* and RX_DURING_TX are not supported.
+ *
+ * RTS_{ON,AFTER}_SEND are supported, but ignored; the transceiver
+ * is connected in only one way and we don't need userspace to tell
+ * us, but want to retain compatibility with applications that do.
+ */
+};
+
+static void ni16550_rs485_setup(struct uart_port *port)
+{
+ port->rs485_config = ni16550_rs485_config;
+ port->rs485_supported = ni16550_rs485_supported;
+ /*
+ * The hardware comes up by default in 2-wire auto mode and we
+ * set the flags to represent that
+ */
+ port->rs485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
+}
+
+static int ni16550_port_startup(struct uart_port *port)
+{
+ int ret;
+
+ ret = serial8250_do_startup(port);
+ if (ret)
+ return ret;
+
+ return ni16550_enable_transceivers(port);
+}
+
+static void ni16550_port_shutdown(struct uart_port *port)
+{
+ ni16550_disable_transceivers(port);
+
+ serial8250_do_shutdown(port);
+}
+
+static int ni16550_get_regs(struct platform_device *pdev,
+ struct uart_port *port)
+{
+ struct resource *regs;
+
+ regs = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (regs) {
+ port->iotype = UPIO_PORT;
+ port->iobase = regs->start;
+
+ return 0;
+ }
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (regs) {
+ port->iotype = UPIO_MEM;
+ port->mapbase = regs->start;
+ port->mapsize = resource_size(regs);
+ port->flags |= UPF_IOREMAP;
+
+ port->membase = devm_ioremap(&pdev->dev, port->mapbase,
+ port->mapsize);
+ if (!port->membase)
+ return -ENOMEM;
+
+ return 0;
+ }
+
+ dev_err(&pdev->dev, "no registers defined\n");
+ return -EINVAL;
+}
+
+/*
+ * Very old implementations don't have the TFS or RFS registers
+ * defined, so we may read all-0s or all-1s. For such devices,
+ * assume a FIFO size of 128.
+ */
+static u8 ni16550_read_fifo_size(struct uart_8250_port *uart, int reg)
+{
+ u8 value = serial_in(uart, reg);
+
+ if (value == 0x00 || value == 0xFF)
+ return 128;
+
+ return value;
+}
+
+static void ni16550_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ struct uart_8250_port *up = up_to_u8250p(port);
+
+ up->mcr |= UART_MCR_CLKSEL;
+ serial8250_do_set_mctrl(port, mctrl);
+}
+
+static int ni16550_probe(struct platform_device *pdev)
+{
+ const struct ni16550_device_info *info;
+ struct device *dev = &pdev->dev;
+ struct uart_8250_port uart = {};
+ unsigned int txfifosz, rxfifosz;
+ unsigned int prescaler = 0;
+ struct ni16550_data *data;
+ const char *portmode;
+ bool rs232_property;
+ int ret;
+ int irq;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ spin_lock_init(&uart.port.lock);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ ret = ni16550_get_regs(pdev, &uart.port);
+ if (ret < 0)
+ return ret;
+
+ /* early setup so that serial_in()/serial_out() work */
+ serial8250_set_defaults(&uart);
+
+ info = device_get_match_data(dev);
+
+ uart.port.dev = dev;
+ uart.port.irq = irq;
+ uart.port.irqflags = IRQF_SHARED;
+ uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
+ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+ uart.port.startup = ni16550_port_startup;
+ uart.port.shutdown = ni16550_port_shutdown;
+
+ /*
+ * Hardware instantiation of FIFO sizes are held in registers.
+ */
+ txfifosz = ni16550_read_fifo_size(&uart, NI16550_TFS_OFFSET);
+ rxfifosz = ni16550_read_fifo_size(&uart, NI16550_RFS_OFFSET);
+
+ dev_dbg(dev, "NI 16550 has TX FIFO size %u, RX FIFO size %u\n",
+ txfifosz, rxfifosz);
+
+ uart.port.type = PORT_16550A;
+ uart.port.fifosize = txfifosz;
+ uart.tx_loadsz = txfifosz;
+ uart.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
+ uart.capabilities = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR;
+
+ /*
+ * Declaration of the base clock frequency can come from one of:
+ * - static declaration in this driver (for older ACPI IDs)
+ * - a "clock-frquency" ACPI
+ */
+ if (info->uartclk)
+ uart.port.uartclk = info->uartclk;
+ if (device_property_read_u32(dev, "clock-frequency",
+ &uart.port.uartclk)) {
+ data->clk = devm_clk_get_enabled(dev, NULL);
+ if (!IS_ERR(data->clk))
+ uart.port.uartclk = clk_get_rate(data->clk);
+ }
+
+ if (!uart.port.uartclk) {
+ dev_err(dev, "unable to determine clock frequency!\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ if (info->prescaler)
+ prescaler = info->prescaler;
+ device_property_read_u32(dev, "clock-prescaler", &prescaler);
+
+ if (prescaler != 0) {
+ uart.port.set_mctrl = ni16550_set_mctrl;
+ ni16550_config_prescaler(&uart, (u8)prescaler);
+ }
+
+ /*
+ * The determination of whether or not this is an RS-485 or RS-232 port
+ * can come from the PMR (if present), otherwise we're solely an RS-485
+ * port.
+ *
+ * This is a device-specific property, and there are old devices in the
+ * field using "transceiver" as an ACPI property, so we have to check
+ * for that as well.
+ */
+ if (!device_property_read_string(dev, "transceiver", &portmode)) {
+ rs232_property = strncmp(portmode, "RS-232", 6) == 0;
+
+ dev_dbg(dev, "port is in %s mode (via device property)\n",
+ rs232_property ? "RS-232" : "RS-485");
+ } else if (info->flags & NI_HAS_PMR) {
+ rs232_property = is_pmr_rs232_mode(&uart);
+
+ dev_dbg(dev, "port is in %s mode (via PMR)\n",
+ rs232_property ? "RS-232" : "RS-485");
+ } else {
+ rs232_property = 0;
+
+ dev_dbg(dev, "port is fixed as RS-485\n");
+ }
+
+ if (!rs232_property) {
+ /*
+ * Neither the 'transceiver' property nor the PMR indicate
+ * that this is an RS-232 port, so it must be an RS-485 one.
+ */
+ ni16550_rs485_setup(&uart.port);
+ }
+
+ ret = serial8250_register_8250_port(&uart);
+ if (ret < 0)
+ goto err;
+ data->line = ret;
+
+ platform_set_drvdata(pdev, data);
+ return 0;
+
+err:
+ return ret;
+}
+
+static void ni16550_remove(struct platform_device *pdev)
+{
+ struct ni16550_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+}
+
+#ifdef CONFIG_ACPI
+/* NI 16550 RS-485 Interface */
+static const struct ni16550_device_info nic7750 = {
+ .uartclk = 33333333,
+};
+
+/* NI CVS-145x RS-485 Interface */
+static const struct ni16550_device_info nic7772 = {
+ .uartclk = 1843200,
+ .flags = NI_HAS_PMR,
+};
+
+/* NI cRIO-904x RS-485 Interface */
+static const struct ni16550_device_info nic792b = {
+ /* Sets UART clock rate to 22.222 MHz with 1.125 prescale */
+ .uartclk = 22222222,
+ .prescaler = 0x09,
+};
+
+/* NI sbRIO 96x8 RS-232/485 Interfaces */
+static const struct ni16550_device_info nic7a69 = {
+ /* Set UART clock rate to 29.629 MHz with 1.125 prescale */
+ .uartclk = 29629629,
+ .prescaler = 0x09,
+};
+static const struct acpi_device_id ni16550_acpi_match[] = {
+ { "NIC7750", (kernel_ulong_t)&nic7750 },
+ { "NIC7772", (kernel_ulong_t)&nic7772 },
+ { "NIC792B", (kernel_ulong_t)&nic792b },
+ { "NIC7A69", (kernel_ulong_t)&nic7a69 },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, ni16550_acpi_match);
+#endif
+
+static struct platform_driver ni16550_driver = {
+ .driver = {
+ .name = "ni16550",
+ .acpi_match_table = ACPI_PTR(ni16550_acpi_match),
+ },
+ .probe = ni16550_probe,
+ .remove = ni16550_remove,
+};
+
+module_platform_driver(ni16550_driver);
+
+MODULE_AUTHOR("Emerson Electric Co.");
+MODULE_DESCRIPTION("NI 16550 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index c2b75e3f106d..2a0ce11f405d 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -692,7 +692,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
/* Synchronize UART_IER access against the console. */
uart_port_lock(port);
- up->ier = port->serial_in(port, UART_IER);
+ up->ier = serial_port_in(port, UART_IER);
if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
port->ops->stop_rx(port);
} else {
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index df4d0d832e54..73c200127b08 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -2728,6 +2728,22 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
.setup = pci_oxsemi_tornado_setup,
},
{
+ .vendor = PCI_VENDOR_ID_INTASHIELD,
+ .device = 0x4026,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_oxsemi_tornado_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTASHIELD,
+ .device = 0x4021,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_oxsemi_tornado_setup,
+ },
+ {
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8811,
.subvendor = PCI_ANY_ID,
@@ -5253,6 +5269,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0BA2,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0BA3,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_2_115200 },
/*
* Brainboxes UC-235/246
*/
@@ -5373,6 +5397,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0C42,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0C43,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_4_115200 },
/*
* Brainboxes UC-420
*/
@@ -5599,6 +5631,20 @@ static const struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
pbn_oxsemi_1_15625000 },
+ /*
+ * Brainboxes XC-235
+ */
+ { PCI_VENDOR_ID_INTASHIELD, 0x4026,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_oxsemi_1_15625000 },
+ /*
+ * Brainboxes XC-475
+ */
+ { PCI_VENDOR_ID_INTASHIELD, 0x4021,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_oxsemi_1_15625000 },
/*
* Perle PCI-RAS cards
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index c57f44882abb..8ac452cea36c 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1678,7 +1678,7 @@ static void serial8250_disable_ms(struct uart_port *port)
if (up->bugs & UART_BUG_NOMSR)
return;
- mctrl_gpio_disable_ms(up->gpios);
+ mctrl_gpio_disable_ms_no_sync(up->gpios);
up->ier &= ~UART_IER_MSI;
serial_port_out(port, UART_IER, up->ier);
@@ -2406,28 +2406,26 @@ int serial8250_do_startup(struct uart_port *port)
* test if we receive TX irq. This way, we'll never enable
* UART_BUG_TXEN.
*/
- if (up->port.quirks & UPQ_NO_TXEN_TEST)
- goto dont_test_tx_en;
-
- /*
- * Do a quick test to see if we receive an interrupt when we enable
- * the TX irq.
- */
- serial_port_out(port, UART_IER, UART_IER_THRI);
- lsr = serial_port_in(port, UART_LSR);
- iir = serial_port_in(port, UART_IIR);
- serial_port_out(port, UART_IER, 0);
+ if (!(up->port.quirks & UPQ_NO_TXEN_TEST)) {
+ /*
+ * Do a quick test to see if we receive an interrupt when we
+ * enable the TX irq.
+ */
+ serial_port_out(port, UART_IER, UART_IER_THRI);
+ lsr = serial_port_in(port, UART_LSR);
+ iir = serial_port_in(port, UART_IIR);
+ serial_port_out(port, UART_IER, 0);
- if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
- if (!(up->bugs & UART_BUG_TXEN)) {
- up->bugs |= UART_BUG_TXEN;
- dev_dbg(port->dev, "enabling bad tx status workarounds\n");
+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+ if (!(up->bugs & UART_BUG_TXEN)) {
+ up->bugs |= UART_BUG_TXEN;
+ dev_dbg(port->dev, "enabling bad tx status workarounds\n");
+ }
+ } else {
+ up->bugs &= ~UART_BUG_TXEN;
}
- } else {
- up->bugs &= ~UART_BUG_TXEN;
}
-dont_test_tx_en:
uart_port_unlock_irqrestore(port, flags);
/*
@@ -2968,7 +2966,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
{
unsigned int size = serial8250_port_size(up);
struct uart_port *port = &up->port;
- int ret = 0;
switch (port->iotype) {
case UPIO_AU:
@@ -2977,32 +2974,28 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
case UPIO_MEM32BE:
case UPIO_MEM16:
case UPIO_MEM:
- if (!port->mapbase) {
- ret = -EINVAL;
- break;
- }
+ if (!port->mapbase)
+ return -EINVAL;
- if (!request_mem_region(port->mapbase, size, "serial")) {
- ret = -EBUSY;
- break;
- }
+ if (!request_mem_region(port->mapbase, size, "serial"))
+ return -EBUSY;
if (port->flags & UPF_IOREMAP) {
port->membase = ioremap(port->mapbase, size);
if (!port->membase) {
release_mem_region(port->mapbase, size);
- ret = -ENOMEM;
+ return -ENOMEM;
}
}
- break;
-
+ return 0;
case UPIO_HUB6:
case UPIO_PORT:
if (!request_region(port->iobase, size, "serial"))
- ret = -EBUSY;
- break;
+ return -EBUSY;
+ return 0;
}
- return ret;
+
+ return 0;
}
static void serial8250_release_std_resource(struct uart_8250_port *up)
diff --git a/drivers/tty/serial/8250/8250_rsa.c b/drivers/tty/serial/8250/8250_rsa.c
index dfaa613e452d..82f2593b4c59 100644
--- a/drivers/tty/serial/8250/8250_rsa.c
+++ b/drivers/tty/serial/8250/8250_rsa.c
@@ -16,30 +16,27 @@ static unsigned int probe_rsa_count;
static int rsa8250_request_resource(struct uart_8250_port *up)
{
- unsigned long start = UART_RSA_BASE << up->port.regshift;
- unsigned int size = 8 << up->port.regshift;
struct uart_port *port = &up->port;
- int ret = -EINVAL;
+ unsigned long start = UART_RSA_BASE << port->regshift;
+ unsigned int size = 8 << port->regshift;
switch (port->iotype) {
case UPIO_HUB6:
case UPIO_PORT:
start += port->iobase;
- if (request_region(start, size, "serial-rsa"))
- ret = 0;
- else
- ret = -EBUSY;
- break;
+ if (!request_region(start, size, "serial-rsa"))
+ return -EBUSY;
+ return 0;
+ default:
+ return -EINVAL;
}
-
- return ret;
}
static void rsa8250_release_resource(struct uart_8250_port *up)
{
- unsigned long offset = UART_RSA_BASE << up->port.regshift;
- unsigned int size = 8 << up->port.regshift;
struct uart_port *port = &up->port;
+ unsigned long offset = UART_RSA_BASE << port->regshift;
+ unsigned int size = 8 << port->regshift;
switch (port->iotype) {
case UPIO_HUB6:
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 55d26d16df9b..bd3d636ff962 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -569,6 +569,19 @@ config SERIAL_8250_BCM7271
including DMA support and high accuracy BAUD rates, say
Y to this option. If unsure, say N.
+config SERIAL_8250_NI
+ tristate "NI 16550 based serial port"
+ depends on SERIAL_8250
+ depends on (X86 && ACPI) || COMPILE_TEST
+ help
+ This driver supports the integrated serial ports on National
+ Instruments (NI) controller hardware. This is required for all NI
+ controller models with onboard RS-485 or dual-mode RS-485/RS-232
+ ports.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_ni.
+
config SERIAL_OF_PLATFORM
tristate "Devicetree based probing for 8250 ports"
depends on SERIAL_8250 && OF
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 1516de629b61..b04eeda03b23 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o
obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o
+obj-$(CONFIG_SERIAL_8250_NI) += 8250_ni.o
obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
obj-$(CONFIG_SERIAL_8250_PARISC) += 8250_parisc.o
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 976dae3bb1bb..79a8186d3361 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -179,25 +179,6 @@ config SERIAL_ATMEL_TTYAT
Say Y if you have an external 8250/16C550 UART. If unsure, say N.
-config SERIAL_KGDB_NMI
- bool "Serial console over KGDB NMI debugger port"
- depends on KGDB_SERIAL_CONSOLE
- help
- This special driver allows you to temporary use NMI debugger port
- as a normal console (assuming that the port is attached to KGDB).
-
- Unlike KDB's disable_nmi command, with this driver you are always
- able to go back to the debugger using KGDB escape sequence ($3#33).
- This is because this console driver processes the input in NMI
- context, and thus is able to intercept the magic sequence.
-
- Note that since the console interprets input and uses polling
- communication methods, for things like PPP you still must fully
- detach debugger port from the KGDB NMI (i.e. disable_nmi), and
- use raw console.
-
- If unsure, say N.
-
config SERIAL_MESON
tristate "Meson serial port support"
depends on ARCH_MESON || COMPILE_TEST
@@ -306,6 +287,29 @@ config SERIAL_TEGRA_TCU_CONSOLE
If unsure, say Y.
+config SERIAL_TEGRA_UTC
+ tristate "NVIDIA Tegra UART Trace Controller"
+ depends on ARCH_TEGRA || COMPILE_TEST
+ select SERIAL_CORE
+ help
+ Support for Tegra UTC (UART Trace controller) client serial port.
+
+ UTC is a HW based serial port that allows multiplexing multiple data
+ streams of up to 16 UTC clients into a single hardware serial port.
+
+config SERIAL_TEGRA_UTC_CONSOLE
+ bool "Support for console on a Tegra UTC serial port"
+ depends on SERIAL_TEGRA_UTC
+ select SERIAL_CORE_CONSOLE
+ default SERIAL_TEGRA_UTC
+ help
+ If you say Y here, it will be possible to use a Tegra UTC client as
+ the system console (the system console is the device which receives
+ all kernel messages and warnings and which allows logins in single
+ user mode).
+
+ If unsure, say Y.
+
config SERIAL_MAX3100
tristate "MAX3100/3110/3111/3222 support"
depends on SPI
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 6ff74f0a9530..d58d9f719889 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o
obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o
obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o
obj-$(CONFIG_SERIAL_TEGRA_TCU) += tegra-tcu.o
+obj-$(CONFIG_SERIAL_TEGRA_UTC) += tegra-utc.o
obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
@@ -96,6 +97,5 @@ obj-$(CONFIG_SERIAL_ZS) += zs.o
# GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
-obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o
obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
obj-$(CONFIG_SERIAL_NUVOTON_MA35D1) += ma35d1_serial.o
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
index 1759137121cc..011f38681131 100644
--- a/drivers/tty/serial/altera_uart.c
+++ b/drivers/tty/serial/altera_uart.c
@@ -339,7 +339,7 @@ static void altera_uart_shutdown(struct uart_port *port)
if (port->irq)
free_irq(port->irq, port);
else
- del_timer_sync(&pp->tmr);
+ timer_delete_sync(&pp->tmr);
}
static const char *altera_uart_type(struct uart_port *port)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 98f178bdbcbe..11d65097578c 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -272,6 +272,7 @@ struct uart_amba_port {
enum pl011_rs485_tx_state rs485_tx_state;
struct hrtimer trigger_start_tx;
struct hrtimer trigger_stop_tx;
+ bool console_line_ended;
#ifdef CONFIG_DMA_ENGINE
/* DMA stuff */
unsigned int dmacr; /* dma control reg */
@@ -1083,7 +1084,7 @@ static void pl011_dma_rx_poll(struct timer_list *t)
uap->dmarx.running = false;
dmaengine_terminate_all(rxchan);
- del_timer(&uap->dmarx.timer);
+ timer_delete(&uap->dmarx.timer);
} else {
mod_timer(&uap->dmarx.timer,
jiffies + msecs_to_jiffies(uap->dmarx.poll_rate));
@@ -1198,7 +1199,7 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, DMA_FROM_DEVICE);
pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_b, DMA_FROM_DEVICE);
if (uap->dmarx.poll_rate)
- del_timer_sync(&uap->dmarx.timer);
+ timer_delete_sync(&uap->dmarx.timer);
uap->using_rx_dma = false;
}
}
@@ -2366,50 +2367,7 @@ static void pl011_console_putchar(struct uart_port *port, unsigned char ch)
while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF)
cpu_relax();
pl011_write(ch, uap, REG_DR);
-}
-
-static void
-pl011_console_write(struct console *co, const char *s, unsigned int count)
-{
- struct uart_amba_port *uap = amba_ports[co->index];
- unsigned int old_cr = 0, new_cr;
- unsigned long flags;
- int locked = 1;
-
- clk_enable(uap->clk);
-
- if (oops_in_progress)
- locked = uart_port_trylock_irqsave(&uap->port, &flags);
- else
- uart_port_lock_irqsave(&uap->port, &flags);
-
- /*
- * First save the CR then disable the interrupts
- */
- if (!uap->vendor->always_enabled) {
- old_cr = pl011_read(uap, REG_CR);
- new_cr = old_cr & ~UART011_CR_CTSEN;
- new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
- pl011_write(new_cr, uap, REG_CR);
- }
-
- uart_console_write(&uap->port, s, count, pl011_console_putchar);
-
- /*
- * Finally, wait for transmitter to become empty and restore the
- * TCR. Allow feature register bits to be inverted to work around
- * errata.
- */
- while ((pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr)
- & uap->vendor->fr_busy)
- cpu_relax();
- if (!uap->vendor->always_enabled)
- pl011_write(old_cr, uap, REG_CR);
-
- if (locked)
- uart_port_unlock_irqrestore(&uap->port, flags);
-
- clk_disable(uap->clk);
+ uap->console_line_ended = (ch == '\n');
}
static void pl011_console_get_options(struct uart_amba_port *uap, int *baud,
@@ -2472,6 +2430,8 @@ static int pl011_console_setup(struct console *co, char *options)
if (ret)
return ret;
+ uap->console_line_ended = true;
+
if (dev_get_platdata(uap->port.dev)) {
struct amba_pl011_data *plat;
@@ -2555,14 +2515,105 @@ static int pl011_console_match(struct console *co, char *name, int idx,
return -ENODEV;
}
+static void
+pl011_console_write_atomic(struct console *co, struct nbcon_write_context *wctxt)
+{
+ struct uart_amba_port *uap = amba_ports[co->index];
+ unsigned int old_cr = 0;
+
+ if (!nbcon_enter_unsafe(wctxt))
+ return;
+
+ clk_enable(uap->clk);
+
+ if (!uap->vendor->always_enabled) {
+ old_cr = pl011_read(uap, REG_CR);
+ pl011_write((old_cr & ~UART011_CR_CTSEN) | (UART01x_CR_UARTEN | UART011_CR_TXE),
+ uap, REG_CR);
+ }
+
+ if (!uap->console_line_ended)
+ uart_console_write(&uap->port, "\n", 1, pl011_console_putchar);
+ uart_console_write(&uap->port, wctxt->outbuf, wctxt->len, pl011_console_putchar);
+
+ while ((pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr) & uap->vendor->fr_busy)
+ cpu_relax();
+
+ if (!uap->vendor->always_enabled)
+ pl011_write(old_cr, uap, REG_CR);
+
+ clk_disable(uap->clk);
+
+ nbcon_exit_unsafe(wctxt);
+}
+
+static void
+pl011_console_write_thread(struct console *co, struct nbcon_write_context *wctxt)
+{
+ struct uart_amba_port *uap = amba_ports[co->index];
+ unsigned int old_cr = 0;
+
+ if (!nbcon_enter_unsafe(wctxt))
+ return;
+
+ clk_enable(uap->clk);
+
+ if (!uap->vendor->always_enabled) {
+ old_cr = pl011_read(uap, REG_CR);
+ pl011_write((old_cr & ~UART011_CR_CTSEN) | (UART01x_CR_UARTEN | UART011_CR_TXE),
+ uap, REG_CR);
+ }
+
+ if (nbcon_exit_unsafe(wctxt)) {
+ int i;
+ unsigned int len = READ_ONCE(wctxt->len);
+
+ for (i = 0; i < len; i++) {
+ if (!nbcon_enter_unsafe(wctxt))
+ break;
+ uart_console_write(&uap->port, wctxt->outbuf + i, 1, pl011_console_putchar);
+ if (!nbcon_exit_unsafe(wctxt))
+ break;
+ }
+ }
+
+ while (!nbcon_enter_unsafe(wctxt))
+ nbcon_reacquire_nobuf(wctxt);
+
+ while ((pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr) & uap->vendor->fr_busy)
+ cpu_relax();
+
+ if (!uap->vendor->always_enabled)
+ pl011_write(old_cr, uap, REG_CR);
+
+ clk_disable(uap->clk);
+
+ nbcon_exit_unsafe(wctxt);
+}
+
+static void
+pl011_console_device_lock(struct console *co, unsigned long *flags)
+{
+ __uart_port_lock_irqsave(&amba_ports[co->index]->port, flags);
+}
+
+static void
+pl011_console_device_unlock(struct console *co, unsigned long flags)
+{
+ __uart_port_unlock_irqrestore(&amba_ports[co->index]->port, flags);
+}
+
static struct uart_driver amba_reg;
static struct console amba_console = {
.name = "ttyAMA",
- .write = pl011_console_write,
.device = uart_console_device,
.setup = pl011_console_setup,
.match = pl011_console_match,
- .flags = CON_PRINTBUFFER | CON_ANYTIME,
+ .write_atomic = pl011_console_write_atomic,
+ .write_thread = pl011_console_write_thread,
+ .device_lock = pl011_console_device_lock,
+ .device_unlock = pl011_console_device_unlock,
+ .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
.index = -1,
.data = &amba_reg,
};
@@ -3000,7 +3051,7 @@ static const struct of_device_id sbsa_uart_of_match[] = {
};
MODULE_DEVICE_TABLE(of, sbsa_uart_of_match);
-static const struct acpi_device_id __maybe_unused sbsa_uart_acpi_match[] = {
+static const struct acpi_device_id sbsa_uart_acpi_match[] = {
{ "ARMH0011", 0 },
{ "ARMHB000", 0 },
{},
@@ -3013,8 +3064,8 @@ static struct platform_driver arm_sbsa_uart_platform_driver = {
.driver = {
.name = "sbsa-uart",
.pm = &pl011_dev_pm_ops,
- .of_match_table = of_match_ptr(sbsa_uart_of_match),
- .acpi_match_table = ACPI_PTR(sbsa_uart_acpi_match),
+ .of_match_table = sbsa_uart_of_match,
+ .acpi_match_table = sbsa_uart_acpi_match,
.suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_AMBA_PL011),
},
};
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index f44f9d20a974..18dba502144d 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -700,7 +700,7 @@ static void atmel_disable_ms(struct uart_port *port)
atmel_port->ms_irq_enabled = false;
- mctrl_gpio_disable_ms(atmel_port->gpios);
+ mctrl_gpio_disable_ms_no_sync(atmel_port->gpios);
if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS))
idr |= ATMEL_US_CTSIC;
@@ -2017,7 +2017,7 @@ static void atmel_shutdown(struct uart_port *port)
* Prevent any tasklets being scheduled during
* cleanup
*/
- del_timer_sync(&atmel_port->uart_timer);
+ timer_delete_sync(&atmel_port->uart_timer);
/* Make sure that no interrupt is on the fly */
synchronize_irq(port->irq);
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index c91b9d9818cd..fe5aed99d55a 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -441,36 +441,36 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport)
static void lpuart_stop_tx(struct uart_port *port)
{
- unsigned char temp;
+ u8 cr2;
- temp = readb(port->membase + UARTCR2);
- temp &= ~(UARTCR2_TIE | UARTCR2_TCIE);
- writeb(temp, port->membase + UARTCR2);
+ cr2 = readb(port->membase + UARTCR2);
+ cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE);
+ writeb(cr2, port->membase + UARTCR2);
}
static void lpuart32_stop_tx(struct uart_port *port)
{
- unsigned long temp;
+ u32 ctrl;
- temp = lpuart32_read(port, UARTCTRL);
- temp &= ~(UARTCTRL_TIE | UARTCTRL_TCIE);
- lpuart32_write(port, temp, UARTCTRL);
+ ctrl = lpuart32_read(port, UARTCTRL);
+ ctrl &= ~(UARTCTRL_TIE | UARTCTRL_TCIE);
+ lpuart32_write(port, ctrl, UARTCTRL);
}
static void lpuart_stop_rx(struct uart_port *port)
{
- unsigned char temp;
+ u8 cr2;
- temp = readb(port->membase + UARTCR2);
- writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2);
+ cr2 = readb(port->membase + UARTCR2);
+ writeb(cr2 & ~UARTCR2_RE, port->membase + UARTCR2);
}
static void lpuart32_stop_rx(struct uart_port *port)
{
- unsigned long temp;
+ u32 ctrl;
- temp = lpuart32_read(port, UARTCTRL);
- lpuart32_write(port, temp & ~UARTCTRL_RE, UARTCTRL);
+ ctrl = lpuart32_read(port, UARTCTRL);
+ lpuart32_write(port, ctrl & ~UARTCTRL_RE, UARTCTRL);
}
static void lpuart_dma_tx(struct lpuart_port *sport)
@@ -581,7 +581,7 @@ static int lpuart_dma_tx_request(struct uart_port *port)
ret = dmaengine_slave_config(sport->dma_tx_chan, &dma_tx_sconfig);
if (ret) {
- dev_err(sport->port.dev,
+ dev_err(port->dev,
"DMA slave config failed, err = %d\n", ret);
return ret;
}
@@ -599,7 +599,7 @@ static void lpuart_flush_buffer(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
struct dma_chan *chan = sport->dma_tx_chan;
- u32 val;
+ u32 fifo;
if (sport->lpuart_dma_tx_use) {
if (sport->dma_tx_in_progress) {
@@ -611,13 +611,13 @@ static void lpuart_flush_buffer(struct uart_port *port)
}
if (lpuart_is_32(sport)) {
- val = lpuart32_read(&sport->port, UARTFIFO);
- val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
- lpuart32_write(&sport->port, val, UARTFIFO);
+ fifo = lpuart32_read(port, UARTFIFO);
+ fifo |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
+ lpuart32_write(port, fifo, UARTFIFO);
} else {
- val = readb(sport->port.membase + UARTCFIFO);
- val |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH;
- writeb(val, sport->port.membase + UARTCFIFO);
+ fifo = readb(port->membase + UARTCFIFO);
+ fifo |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH;
+ writeb(fifo, port->membase + UARTCFIFO);
}
}
@@ -639,38 +639,36 @@ static void lpuart32_wait_bit_set(struct uart_port *port, unsigned int offset,
static int lpuart_poll_init(struct uart_port *port)
{
- struct lpuart_port *sport = container_of(port,
- struct lpuart_port, port);
unsigned long flags;
- unsigned char temp;
+ u8 fifo;
- sport->port.fifosize = 0;
+ port->fifosize = 0;
- uart_port_lock_irqsave(&sport->port, &flags);
+ uart_port_lock_irqsave(port, &flags);
/* Disable Rx & Tx */
- writeb(0, sport->port.membase + UARTCR2);
+ writeb(0, port->membase + UARTCR2);
- temp = readb(sport->port.membase + UARTPFIFO);
+ fifo = readb(port->membase + UARTPFIFO);
/* Enable Rx and Tx FIFO */
- writeb(temp | UARTPFIFO_RXFE | UARTPFIFO_TXFE,
- sport->port.membase + UARTPFIFO);
+ writeb(fifo | UARTPFIFO_RXFE | UARTPFIFO_TXFE,
+ port->membase + UARTPFIFO);
/* flush Tx and Rx FIFO */
writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
- sport->port.membase + UARTCFIFO);
+ port->membase + UARTCFIFO);
/* explicitly clear RDRF */
- if (readb(sport->port.membase + UARTSR1) & UARTSR1_RDRF) {
- readb(sport->port.membase + UARTDR);
- writeb(UARTSFIFO_RXUF, sport->port.membase + UARTSFIFO);
+ if (readb(port->membase + UARTSR1) & UARTSR1_RDRF) {
+ readb(port->membase + UARTDR);
+ writeb(UARTSFIFO_RXUF, port->membase + UARTSFIFO);
}
- writeb(0, sport->port.membase + UARTTWFIFO);
- writeb(1, sport->port.membase + UARTRWFIFO);
+ writeb(0, port->membase + UARTTWFIFO);
+ writeb(1, port->membase + UARTRWFIFO);
/* Enable Rx and Tx */
- writeb(UARTCR2_RE | UARTCR2_TE, sport->port.membase + UARTCR2);
- uart_port_unlock_irqrestore(&sport->port, flags);
+ writeb(UARTCR2_RE | UARTCR2_TE, port->membase + UARTCR2);
+ uart_port_unlock_irqrestore(port, flags);
return 0;
}
@@ -693,33 +691,32 @@ static int lpuart_poll_get_char(struct uart_port *port)
static int lpuart32_poll_init(struct uart_port *port)
{
unsigned long flags;
- struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
- u32 temp;
+ u32 fifo;
- sport->port.fifosize = 0;
+ port->fifosize = 0;
- uart_port_lock_irqsave(&sport->port, &flags);
+ uart_port_lock_irqsave(port, &flags);
/* Disable Rx & Tx */
- lpuart32_write(&sport->port, 0, UARTCTRL);
+ lpuart32_write(port, 0, UARTCTRL);
- temp = lpuart32_read(&sport->port, UARTFIFO);
+ fifo = lpuart32_read(port, UARTFIFO);
/* Enable Rx and Tx FIFO */
- lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
+ lpuart32_write(port, fifo | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
/* flush Tx and Rx FIFO */
- lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
+ lpuart32_write(port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
/* explicitly clear RDRF */
- if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) {
- lpuart32_read(&sport->port, UARTDATA);
- lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO);
+ if (lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF) {
+ lpuart32_read(port, UARTDATA);
+ lpuart32_write(port, UARTFIFO_RXUF, UARTFIFO);
}
/* Enable Rx and Tx */
- lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
- uart_port_unlock_irqrestore(&sport->port, flags);
+ lpuart32_write(port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
+ uart_port_unlock_irqrestore(port, flags);
return 0;
}
@@ -752,7 +749,7 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
{
struct tty_port *tport = &sport->port.state->port;
- unsigned long txcnt;
+ u32 txcnt;
unsigned char c;
if (sport->port.x_char) {
@@ -789,10 +786,10 @@ static void lpuart_start_tx(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
- unsigned char temp;
+ u8 cr2;
- temp = readb(port->membase + UARTCR2);
- writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
+ cr2 = readb(port->membase + UARTCR2);
+ writeb(cr2 | UARTCR2_TIE, port->membase + UARTCR2);
if (sport->lpuart_dma_tx_use) {
if (!lpuart_stopped_or_empty(port))
@@ -806,14 +803,14 @@ static void lpuart_start_tx(struct uart_port *port)
static void lpuart32_start_tx(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
- unsigned long temp;
+ u32 ctrl;
if (sport->lpuart_dma_tx_use) {
if (!lpuart_stopped_or_empty(port))
lpuart_dma_tx(sport);
} else {
- temp = lpuart32_read(port, UARTCTRL);
- lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL);
+ ctrl = lpuart32_read(port, UARTCTRL);
+ lpuart32_write(port, ctrl | UARTCTRL_TIE, UARTCTRL);
if (lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE)
lpuart32_transmit_buffer(sport);
@@ -839,8 +836,8 @@ static unsigned int lpuart_tx_empty(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
- unsigned char sr1 = readb(port->membase + UARTSR1);
- unsigned char sfifo = readb(port->membase + UARTSFIFO);
+ u8 sr1 = readb(port->membase + UARTSR1);
+ u8 sfifo = readb(port->membase + UARTSFIFO);
if (sport->dma_tx_in_progress)
return 0;
@@ -855,9 +852,9 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
- unsigned long stat = lpuart32_read(port, UARTSTAT);
- unsigned long sfifo = lpuart32_read(port, UARTFIFO);
- unsigned long ctrl = lpuart32_read(port, UARTCTRL);
+ u32 stat = lpuart32_read(port, UARTSTAT);
+ u32 sfifo = lpuart32_read(port, UARTFIFO);
+ u32 ctrl = lpuart32_read(port, UARTCTRL);
if (sport->dma_tx_in_progress)
return 0;
@@ -884,7 +881,7 @@ static void lpuart_rxint(struct lpuart_port *sport)
{
unsigned int flg, ignored = 0, overrun = 0;
struct tty_port *port = &sport->port.state->port;
- unsigned char rx, sr;
+ u8 rx, sr;
uart_port_lock(&sport->port);
@@ -961,7 +958,7 @@ static void lpuart32_rxint(struct lpuart_port *sport)
{
unsigned int flg, ignored = 0;
struct tty_port *port = &sport->port.state->port;
- unsigned long rx, sr;
+ u32 rx, sr;
bool is_break;
uart_port_lock(&sport->port);
@@ -1039,7 +1036,7 @@ out:
static irqreturn_t lpuart_int(int irq, void *dev_id)
{
struct lpuart_port *sport = dev_id;
- unsigned char sts;
+ u8 sts;
sts = readb(sport->port.membase + UARTSR1);
@@ -1113,7 +1110,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
int count, copied;
if (lpuart_is_32(sport)) {
- unsigned long sr = lpuart32_read(&sport->port, UARTSTAT);
+ u32 sr = lpuart32_read(&sport->port, UARTSTAT);
if (sr & (UARTSTAT_PE | UARTSTAT_FE)) {
/* Clear the error flags */
@@ -1125,10 +1122,10 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
sport->port.icount.frame++;
}
} else {
- unsigned char sr = readb(sport->port.membase + UARTSR1);
+ u8 sr = readb(sport->port.membase + UARTSR1);
if (sr & (UARTSR1_PE | UARTSR1_FE)) {
- unsigned char cr2;
+ u8 cr2;
/* Disable receiver during this operation... */
cr2 = readb(sport->port.membase + UARTCR2);
@@ -1279,7 +1276,7 @@ static void lpuart32_dma_idleint(struct lpuart_port *sport)
static irqreturn_t lpuart32_int(int irq, void *dev_id)
{
struct lpuart_port *sport = dev_id;
- unsigned long sts, rxcount;
+ u32 sts, rxcount;
sts = lpuart32_read(&sport->port, UARTSTAT);
rxcount = lpuart32_read(&sport->port, UARTWATER);
@@ -1411,12 +1408,12 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
dma_async_issue_pending(chan);
if (lpuart_is_32(sport)) {
- unsigned long temp = lpuart32_read(&sport->port, UARTBAUD);
+ u32 baud = lpuart32_read(&sport->port, UARTBAUD);
- lpuart32_write(&sport->port, temp | UARTBAUD_RDMAE, UARTBAUD);
+ lpuart32_write(&sport->port, baud | UARTBAUD_RDMAE, UARTBAUD);
if (sport->dma_idle_int) {
- unsigned long ctrl = lpuart32_read(&sport->port, UARTCTRL);
+ u32 ctrl = lpuart32_read(&sport->port, UARTCTRL);
lpuart32_write(&sport->port, ctrl | UARTCTRL_ILIE, UARTCTRL);
}
@@ -1436,7 +1433,7 @@ static void lpuart_dma_rx_free(struct uart_port *port)
dmaengine_terminate_sync(chan);
if (!sport->dma_idle_int)
- del_timer_sync(&sport->lpuart_timer);
+ timer_delete_sync(&sport->lpuart_timer);
dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
kfree(sport->rx_ring.buf);
@@ -1449,12 +1446,9 @@ static void lpuart_dma_rx_free(struct uart_port *port)
static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios,
struct serial_rs485 *rs485)
{
- struct lpuart_port *sport = container_of(port,
- struct lpuart_port, port);
-
- u8 modem = readb(sport->port.membase + UARTMODEM) &
+ u8 modem = readb(port->membase + UARTMODEM) &
~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE);
- writeb(modem, sport->port.membase + UARTMODEM);
+ writeb(modem, port->membase + UARTMODEM);
if (rs485->flags & SER_RS485_ENABLED) {
/* Enable auto RS-485 RTS mode */
@@ -1472,19 +1466,29 @@ static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios,
modem &= ~UARTMODEM_TXRTSPOL;
}
- writeb(modem, sport->port.membase + UARTMODEM);
+ writeb(modem, port->membase + UARTMODEM);
return 0;
}
static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termios,
struct serial_rs485 *rs485)
{
- struct lpuart_port *sport = container_of(port,
- struct lpuart_port, port);
-
- unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
+ u32 modem = lpuart32_read(port, UARTMODIR)
& ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
- lpuart32_write(&sport->port, modem, UARTMODIR);
+ u32 ctrl;
+
+ /* TXRTSE and TXRTSPOL only can be changed when transmitter is disabled. */
+ ctrl = lpuart32_read(port, UARTCTRL);
+ if (ctrl & UARTCTRL_TE) {
+ /* wait for the transmit engine to complete */
+ lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC);
+ lpuart32_write(port, ctrl & ~UARTCTRL_TE, UARTCTRL);
+
+ while (lpuart32_read(port, UARTCTRL) & UARTCTRL_TE)
+ cpu_relax();
+ }
+
+ lpuart32_write(port, modem, UARTMODIR);
if (rs485->flags & SER_RS485_ENABLED) {
/* Enable auto RS-485 RTS mode */
@@ -1502,17 +1506,21 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
modem &= ~UARTMODIR_TXRTSPOL;
}
- lpuart32_write(&sport->port, modem, UARTMODIR);
+ lpuart32_write(port, modem, UARTMODIR);
+
+ if (ctrl & UARTCTRL_TE)
+ lpuart32_write(port, ctrl, UARTCTRL);
+
return 0;
}
static unsigned int lpuart_get_mctrl(struct uart_port *port)
{
unsigned int mctrl = 0;
- u8 reg;
+ u8 cr1;
- reg = readb(port->membase + UARTCR1);
- if (reg & UARTCR1_LOOPS)
+ cr1 = readb(port->membase + UARTCR1);
+ if (cr1 & UARTCR1_LOOPS)
mctrl |= TIOCM_LOOP;
return mctrl;
@@ -1521,10 +1529,10 @@ static unsigned int lpuart_get_mctrl(struct uart_port *port)
static unsigned int lpuart32_get_mctrl(struct uart_port *port)
{
unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
- u32 reg;
+ u32 ctrl;
- reg = lpuart32_read(port, UARTCTRL);
- if (reg & UARTCTRL_LOOPS)
+ ctrl = lpuart32_read(port, UARTCTRL);
+ if (ctrl & UARTCTRL_LOOPS)
mctrl |= TIOCM_LOOP;
return mctrl;
@@ -1532,49 +1540,49 @@ static unsigned int lpuart32_get_mctrl(struct uart_port *port)
static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- u8 reg;
+ u8 cr1;
- reg = readb(port->membase + UARTCR1);
+ cr1 = readb(port->membase + UARTCR1);
/* for internal loopback we need LOOPS=1 and RSRC=0 */
- reg &= ~(UARTCR1_LOOPS | UARTCR1_RSRC);
+ cr1 &= ~(UARTCR1_LOOPS | UARTCR1_RSRC);
if (mctrl & TIOCM_LOOP)
- reg |= UARTCR1_LOOPS;
+ cr1 |= UARTCR1_LOOPS;
- writeb(reg, port->membase + UARTCR1);
+ writeb(cr1, port->membase + UARTCR1);
}
static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- u32 reg;
+ u32 ctrl;
- reg = lpuart32_read(port, UARTCTRL);
+ ctrl = lpuart32_read(port, UARTCTRL);
/* for internal loopback we need LOOPS=1 and RSRC=0 */
- reg &= ~(UARTCTRL_LOOPS | UARTCTRL_RSRC);
+ ctrl &= ~(UARTCTRL_LOOPS | UARTCTRL_RSRC);
if (mctrl & TIOCM_LOOP)
- reg |= UARTCTRL_LOOPS;
+ ctrl |= UARTCTRL_LOOPS;
- lpuart32_write(port, reg, UARTCTRL);
+ lpuart32_write(port, ctrl, UARTCTRL);
}
static void lpuart_break_ctl(struct uart_port *port, int break_state)
{
- unsigned char temp;
+ u8 cr2;
- temp = readb(port->membase + UARTCR2) & ~UARTCR2_SBK;
+ cr2 = readb(port->membase + UARTCR2) & ~UARTCR2_SBK;
if (break_state != 0)
- temp |= UARTCR2_SBK;
+ cr2 |= UARTCR2_SBK;
- writeb(temp, port->membase + UARTCR2);
+ writeb(cr2, port->membase + UARTCR2);
}
static void lpuart32_break_ctl(struct uart_port *port, int break_state)
{
- unsigned long temp;
+ u32 ctrl;
- temp = lpuart32_read(port, UARTCTRL);
+ ctrl = lpuart32_read(port, UARTCTRL);
/*
* LPUART IP now has two known bugs, one is CTS has higher priority than the
@@ -1591,23 +1599,22 @@ static void lpuart32_break_ctl(struct uart_port *port, int break_state)
* Disable the transmitter to prevent any data from being sent out
* during break, then invert the TX line to send break.
*/
- temp &= ~UARTCTRL_TE;
- lpuart32_write(port, temp, UARTCTRL);
- temp |= UARTCTRL_TXINV;
- lpuart32_write(port, temp, UARTCTRL);
+ ctrl &= ~UARTCTRL_TE;
+ lpuart32_write(port, ctrl, UARTCTRL);
+ ctrl |= UARTCTRL_TXINV;
+ lpuart32_write(port, ctrl, UARTCTRL);
} else {
/* Disable the TXINV to turn off break and re-enable transmitter. */
- temp &= ~UARTCTRL_TXINV;
- lpuart32_write(port, temp, UARTCTRL);
- temp |= UARTCTRL_TE;
- lpuart32_write(port, temp, UARTCTRL);
+ ctrl &= ~UARTCTRL_TXINV;
+ lpuart32_write(port, ctrl, UARTCTRL);
+ ctrl |= UARTCTRL_TE;
+ lpuart32_write(port, ctrl, UARTCTRL);
}
}
static void lpuart_setup_watermark(struct lpuart_port *sport)
{
- unsigned char val, cr2;
- unsigned char cr2_saved;
+ u8 fifo, cr2, cr2_saved;
cr2 = readb(sport->port.membase + UARTCR2);
cr2_saved = cr2;
@@ -1615,8 +1622,8 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
UARTCR2_RIE | UARTCR2_RE);
writeb(cr2, sport->port.membase + UARTCR2);
- val = readb(sport->port.membase + UARTPFIFO);
- writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE,
+ fifo = readb(sport->port.membase + UARTPFIFO);
+ writeb(fifo | UARTPFIFO_TXFE | UARTPFIFO_RXFE,
sport->port.membase + UARTPFIFO);
/* flush Tx and Rx FIFO */
@@ -1640,7 +1647,7 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
static void lpuart_setup_watermark_enable(struct lpuart_port *sport)
{
- unsigned char cr2;
+ u8 cr2;
lpuart_setup_watermark(sport);
@@ -1651,8 +1658,7 @@ static void lpuart_setup_watermark_enable(struct lpuart_port *sport)
static void lpuart32_setup_watermark(struct lpuart_port *sport)
{
- unsigned long val, ctrl;
- unsigned long ctrl_saved;
+ u32 val, ctrl, ctrl_saved;
ctrl = lpuart32_read(&sport->port, UARTCTRL);
ctrl_saved = ctrl;
@@ -1687,14 +1693,14 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
static void lpuart32_setup_watermark_enable(struct lpuart_port *sport)
{
- u32 temp;
+ u32 ctrl;
lpuart32_setup_watermark(sport);
- temp = lpuart32_read(&sport->port, UARTCTRL);
- temp |= UARTCTRL_RE | UARTCTRL_TE;
- temp |= FIELD_PREP(UARTCTRL_IDLECFG, 0x7);
- lpuart32_write(&sport->port, temp, UARTCTRL);
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
+ ctrl |= UARTCTRL_RE | UARTCTRL_TE;
+ ctrl |= FIELD_PREP(UARTCTRL_IDLECFG, 0x7);
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
}
static void rx_dma_timer_init(struct lpuart_port *sport)
@@ -1761,7 +1767,7 @@ err:
static void lpuart_rx_dma_startup(struct lpuart_port *sport)
{
int ret;
- unsigned char cr3;
+ u8 cr3;
if (uart_console(&sport->port))
goto err;
@@ -1811,16 +1817,16 @@ static void lpuart_hw_setup(struct lpuart_port *sport)
static int lpuart_startup(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
- unsigned char temp;
+ u8 fifo;
/* determine FIFO size and enable FIFO mode */
- temp = readb(sport->port.membase + UARTPFIFO);
+ fifo = readb(port->membase + UARTPFIFO);
- sport->txfifo_size = UARTFIFO_DEPTH((temp >> UARTPFIFO_TXSIZE_OFF) &
+ sport->txfifo_size = UARTFIFO_DEPTH((fifo >> UARTPFIFO_TXSIZE_OFF) &
UARTPFIFO_FIFOSIZE_MASK);
- sport->port.fifosize = sport->txfifo_size;
+ port->fifosize = sport->txfifo_size;
- sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTPFIFO_RXSIZE_OFF) &
+ sport->rxfifo_size = UARTFIFO_DEPTH((fifo >> UARTPFIFO_RXSIZE_OFF) &
UARTPFIFO_FIFOSIZE_MASK);
lpuart_request_dma(sport);
@@ -1831,24 +1837,24 @@ static int lpuart_startup(struct uart_port *port)
static void lpuart32_hw_disable(struct lpuart_port *sport)
{
- unsigned long temp;
+ u32 ctrl;
- temp = lpuart32_read(&sport->port, UARTCTRL);
- temp &= ~(UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE |
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
+ ctrl &= ~(UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE |
UARTCTRL_TIE | UARTCTRL_TE);
- lpuart32_write(&sport->port, temp, UARTCTRL);
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
}
static void lpuart32_configure(struct lpuart_port *sport)
{
- unsigned long temp;
+ u32 ctrl;
- temp = lpuart32_read(&sport->port, UARTCTRL);
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
if (!sport->lpuart_dma_rx_use)
- temp |= UARTCTRL_RIE | UARTCTRL_ILIE;
+ ctrl |= UARTCTRL_RIE | UARTCTRL_ILIE;
if (!sport->lpuart_dma_tx_use)
- temp |= UARTCTRL_TIE;
- lpuart32_write(&sport->port, temp, UARTCTRL);
+ ctrl |= UARTCTRL_TIE;
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
}
static void lpuart32_hw_setup(struct lpuart_port *sport)
@@ -1871,16 +1877,16 @@ static void lpuart32_hw_setup(struct lpuart_port *sport)
static int lpuart32_startup(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
- unsigned long temp;
+ u32 fifo;
/* determine FIFO size */
- temp = lpuart32_read(&sport->port, UARTFIFO);
+ fifo = lpuart32_read(port, UARTFIFO);
- sport->txfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_TXSIZE_OFF) &
+ sport->txfifo_size = UARTFIFO_DEPTH((fifo >> UARTFIFO_TXSIZE_OFF) &
UARTFIFO_FIFOSIZE_MASK);
- sport->port.fifosize = sport->txfifo_size;
+ port->fifosize = sport->txfifo_size;
- sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_RXSIZE_OFF) &
+ sport->rxfifo_size = UARTFIFO_DEPTH((fifo >> UARTFIFO_RXSIZE_OFF) &
UARTFIFO_FIFOSIZE_MASK);
/*
@@ -1891,7 +1897,7 @@ static int lpuart32_startup(struct uart_port *port)
if (is_layerscape_lpuart(sport)) {
sport->rxfifo_size = 16;
sport->txfifo_size = 16;
- sport->port.fifosize = sport->txfifo_size;
+ port->fifosize = sport->txfifo_size;
}
lpuart_request_dma(sport);
@@ -1925,16 +1931,16 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
static void lpuart_shutdown(struct uart_port *port)
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
- unsigned char temp;
+ u8 cr2;
unsigned long flags;
uart_port_lock_irqsave(port, &flags);
/* disable Rx/Tx and interrupts */
- temp = readb(port->membase + UARTCR2);
- temp &= ~(UARTCR2_TE | UARTCR2_RE |
+ cr2 = readb(port->membase + UARTCR2);
+ cr2 &= ~(UARTCR2_TE | UARTCR2_RE |
UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE);
- writeb(temp, port->membase + UARTCR2);
+ writeb(cr2, port->membase + UARTCR2);
uart_port_unlock_irqrestore(port, flags);
@@ -1945,14 +1951,14 @@ static void lpuart32_shutdown(struct uart_port *port)
{
struct lpuart_port *sport =
container_of(port, struct lpuart_port, port);
- unsigned long temp;
+ u32 temp;
unsigned long flags;
uart_port_lock_irqsave(port, &flags);
/* clear status */
- temp = lpuart32_read(&sport->port, UARTSTAT);
- lpuart32_write(&sport->port, temp, UARTSTAT);
+ temp = lpuart32_read(port, UARTSTAT);
+ lpuart32_write(port, temp, UARTSTAT);
/* disable Rx/Tx DMA */
temp = lpuart32_read(port, UARTBAUD);
@@ -1981,17 +1987,17 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
unsigned long flags;
- unsigned char cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem;
+ u8 cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem;
unsigned int baud;
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
unsigned int sbr, brfa;
- cr1 = old_cr1 = readb(sport->port.membase + UARTCR1);
- old_cr2 = readb(sport->port.membase + UARTCR2);
- cr3 = readb(sport->port.membase + UARTCR3);
- cr4 = readb(sport->port.membase + UARTCR4);
- bdh = readb(sport->port.membase + UARTBDH);
- modem = readb(sport->port.membase + UARTMODEM);
+ cr1 = old_cr1 = readb(port->membase + UARTCR1);
+ old_cr2 = readb(port->membase + UARTCR2);
+ cr3 = readb(port->membase + UARTCR3);
+ cr4 = readb(port->membase + UARTCR4);
+ bdh = readb(port->membase + UARTBDH);
+ modem = readb(port->membase + UARTMODEM);
/*
* only support CS8 and CS7, and for CS7 must enable PE.
* supported mode:
@@ -2023,7 +2029,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
* When auto RS-485 RTS mode is enabled,
* hardware flow control need to be disabled.
*/
- if (sport->port.rs485.flags & SER_RS485_ENABLED)
+ if (port->rs485.flags & SER_RS485_ENABLED)
termios->c_cflag &= ~CRTSCTS;
if (termios->c_cflag & CRTSCTS)
@@ -2064,59 +2070,59 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
* Need to update the Ring buffer length according to the selected
* baud rate and restart Rx DMA path.
*
- * Since timer function acqures sport->port.lock, need to stop before
- * acquring same lock because otherwise del_timer_sync() can deadlock.
+ * Since timer function acqures port->lock, need to stop before
+ * acquring same lock because otherwise timer_delete_sync() can deadlock.
*/
if (old && sport->lpuart_dma_rx_use)
- lpuart_dma_rx_free(&sport->port);
+ lpuart_dma_rx_free(port);
- uart_port_lock_irqsave(&sport->port, &flags);
+ uart_port_lock_irqsave(port, &flags);
- sport->port.read_status_mask = 0;
+ port->read_status_mask = 0;
if (termios->c_iflag & INPCK)
- sport->port.read_status_mask |= UARTSR1_FE | UARTSR1_PE;
+ port->read_status_mask |= UARTSR1_FE | UARTSR1_PE;
if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
- sport->port.read_status_mask |= UARTSR1_FE;
+ port->read_status_mask |= UARTSR1_FE;
/* characters to ignore */
- sport->port.ignore_status_mask = 0;
+ port->ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
- sport->port.ignore_status_mask |= UARTSR1_PE;
+ port->ignore_status_mask |= UARTSR1_PE;
if (termios->c_iflag & IGNBRK) {
- sport->port.ignore_status_mask |= UARTSR1_FE;
+ port->ignore_status_mask |= UARTSR1_FE;
/*
* if we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
- sport->port.ignore_status_mask |= UARTSR1_OR;
+ port->ignore_status_mask |= UARTSR1_OR;
}
/* update the per-port timeout */
uart_update_timeout(port, termios->c_cflag, baud);
/* wait transmit engin complete */
- lpuart_wait_bit_set(&sport->port, UARTSR1, UARTSR1_TC);
+ lpuart_wait_bit_set(port, UARTSR1, UARTSR1_TC);
/* disable transmit and receive */
writeb(old_cr2 & ~(UARTCR2_TE | UARTCR2_RE),
- sport->port.membase + UARTCR2);
+ port->membase + UARTCR2);
- sbr = sport->port.uartclk / (16 * baud);
- brfa = ((sport->port.uartclk - (16 * sbr * baud)) * 2) / baud;
+ sbr = port->uartclk / (16 * baud);
+ brfa = ((port->uartclk - (16 * sbr * baud)) * 2) / baud;
bdh &= ~UARTBDH_SBR_MASK;
bdh |= (sbr >> 8) & 0x1F;
cr4 &= ~UARTCR4_BRFA_MASK;
brfa &= UARTCR4_BRFA_MASK;
- writeb(cr4 | brfa, sport->port.membase + UARTCR4);
- writeb(bdh, sport->port.membase + UARTBDH);
- writeb(sbr & 0xFF, sport->port.membase + UARTBDL);
- writeb(cr3, sport->port.membase + UARTCR3);
- writeb(cr1, sport->port.membase + UARTCR1);
- writeb(modem, sport->port.membase + UARTMODEM);
+ writeb(cr4 | brfa, port->membase + UARTCR4);
+ writeb(bdh, port->membase + UARTBDH);
+ writeb(sbr & 0xFF, port->membase + UARTBDL);
+ writeb(cr3, port->membase + UARTCR3);
+ writeb(cr1, port->membase + UARTCR1);
+ writeb(modem, port->membase + UARTMODEM);
/* restore control register */
- writeb(old_cr2, sport->port.membase + UARTCR2);
+ writeb(old_cr2, port->membase + UARTCR2);
if (old && sport->lpuart_dma_rx_use) {
if (!lpuart_start_rx_dma(sport))
@@ -2125,14 +2131,14 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
sport->lpuart_dma_rx_use = false;
}
- uart_port_unlock_irqrestore(&sport->port, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static void __lpuart32_serial_setbrg(struct uart_port *port,
unsigned int baudrate, bool use_rx_dma,
bool use_tx_dma)
{
- u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
+ u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, baud;
u32 clk = port->uartclk;
/*
@@ -2161,9 +2167,9 @@ static void __lpuart32_serial_setbrg(struct uart_port *port,
tmp_diff = clk / (tmp_osr * tmp_sbr) - baudrate;
/* select best values between sbr and sbr+1 */
- tmp = clk / (tmp_osr * (tmp_sbr + 1));
- if (tmp_diff > (baudrate - tmp)) {
- tmp_diff = baudrate - tmp;
+ baud = clk / (tmp_osr * (tmp_sbr + 1));
+ if (tmp_diff > (baudrate - baud)) {
+ tmp_diff = baudrate - baud;
tmp_sbr++;
}
@@ -2185,23 +2191,23 @@ static void __lpuart32_serial_setbrg(struct uart_port *port,
dev_warn(port->dev,
"unacceptable baud rate difference of more than 3%%\n");
- tmp = lpuart32_read(port, UARTBAUD);
+ baud = lpuart32_read(port, UARTBAUD);
if ((osr > 3) && (osr < 8))
- tmp |= UARTBAUD_BOTHEDGE;
+ baud |= UARTBAUD_BOTHEDGE;
- tmp &= ~(UARTBAUD_OSR_MASK << UARTBAUD_OSR_SHIFT);
- tmp |= ((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT;
+ baud &= ~(UARTBAUD_OSR_MASK << UARTBAUD_OSR_SHIFT);
+ baud |= ((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT;
- tmp &= ~UARTBAUD_SBR_MASK;
- tmp |= sbr & UARTBAUD_SBR_MASK;
+ baud &= ~UARTBAUD_SBR_MASK;
+ baud |= sbr & UARTBAUD_SBR_MASK;
if (!use_rx_dma)
- tmp &= ~UARTBAUD_RDMAE;
+ baud &= ~UARTBAUD_RDMAE;
if (!use_tx_dma)
- tmp &= ~UARTBAUD_TDMAE;
+ baud &= ~UARTBAUD_TDMAE;
- lpuart32_write(port, tmp, UARTBAUD);
+ lpuart32_write(port, baud, UARTBAUD);
}
static void lpuart32_serial_setbrg(struct lpuart_port *sport,
@@ -2219,13 +2225,13 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
unsigned long flags;
- unsigned long ctrl, old_ctrl, bd, modem;
+ u32 ctrl, old_ctrl, bd, modem;
unsigned int baud;
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
- ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL);
- bd = lpuart32_read(&sport->port, UARTBAUD);
- modem = lpuart32_read(&sport->port, UARTMODIR);
+ ctrl = old_ctrl = lpuart32_read(port, UARTCTRL);
+ bd = lpuart32_read(port, UARTBAUD);
+ modem = lpuart32_read(port, UARTMODIR);
sport->is_cs7 = false;
/*
* only support CS8 and CS7
@@ -2259,7 +2265,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
* When auto RS-485 RTS mode is enabled,
* hardware flow control need to be disabled.
*/
- if (sport->port.rs485.flags & SER_RS485_ENABLED)
+ if (port->rs485.flags & SER_RS485_ENABLED)
termios->c_cflag &= ~CRTSCTS;
if (termios->c_cflag & CRTSCTS)
@@ -2309,59 +2315,61 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
* Need to update the Ring buffer length according to the selected
* baud rate and restart Rx DMA path.
*
- * Since timer function acqures sport->port.lock, need to stop before
- * acquring same lock because otherwise del_timer_sync() can deadlock.
+ * Since timer function acqures port->lock, need to stop before
+ * acquring same lock because otherwise timer_delete_sync() can deadlock.
*/
if (old && sport->lpuart_dma_rx_use)
- lpuart_dma_rx_free(&sport->port);
+ lpuart_dma_rx_free(port);
- uart_port_lock_irqsave(&sport->port, &flags);
+ uart_port_lock_irqsave(port, &flags);
- sport->port.read_status_mask = 0;
+ port->read_status_mask = 0;
if (termios->c_iflag & INPCK)
- sport->port.read_status_mask |= UARTSTAT_FE | UARTSTAT_PE;
+ port->read_status_mask |= UARTSTAT_FE | UARTSTAT_PE;
if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
- sport->port.read_status_mask |= UARTSTAT_FE;
+ port->read_status_mask |= UARTSTAT_FE;
/* characters to ignore */
- sport->port.ignore_status_mask = 0;
+ port->ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
- sport->port.ignore_status_mask |= UARTSTAT_PE;
+ port->ignore_status_mask |= UARTSTAT_PE;
if (termios->c_iflag & IGNBRK) {
- sport->port.ignore_status_mask |= UARTSTAT_FE;
+ port->ignore_status_mask |= UARTSTAT_FE;
/*
* if we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
- sport->port.ignore_status_mask |= UARTSTAT_OR;
+ port->ignore_status_mask |= UARTSTAT_OR;
}
/* update the per-port timeout */
uart_update_timeout(port, termios->c_cflag, baud);
/*
+ * disable CTS to ensure the transmit engine is not blocked by the flow
+ * control when there is dirty data in TX FIFO
+ */
+ lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
+
+ /*
* LPUART Transmission Complete Flag may never be set while queuing a break
* character, so skip waiting for transmission complete when UARTCTRL_SBK is
* asserted.
*/
- if (!(old_ctrl & UARTCTRL_SBK)) {
- lpuart32_write(&sport->port, 0, UARTMODIR);
- lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
- }
+ if (!(old_ctrl & UARTCTRL_SBK))
+ lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC);
/* disable transmit and receive */
- lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
+ lpuart32_write(port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
UARTCTRL);
- lpuart32_write(&sport->port, bd, UARTBAUD);
+ lpuart32_write(port, bd, UARTBAUD);
lpuart32_serial_setbrg(sport, baud);
- /* disable CTS before enabling UARTCTRL_TE to avoid pending idle preamble */
- lpuart32_write(&sport->port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
/* restore control register */
- lpuart32_write(&sport->port, ctrl, UARTCTRL);
+ lpuart32_write(port, ctrl, UARTCTRL);
/* re-enable the CTS if needed */
- lpuart32_write(&sport->port, modem, UARTMODIR);
+ lpuart32_write(port, modem, UARTMODIR);
if ((ctrl & (UARTCTRL_PE | UARTCTRL_M)) == UARTCTRL_PE)
sport->is_cs7 = true;
@@ -2373,7 +2381,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
sport->lpuart_dma_rx_use = false;
}
- uart_port_unlock_irqrestore(&sport->port, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static const char *lpuart_type(struct uart_port *port)
@@ -2486,7 +2494,7 @@ static void
lpuart_console_write(struct console *co, const char *s, unsigned int count)
{
struct lpuart_port *sport = lpuart_ports[co->index];
- unsigned char old_cr2, cr2;
+ u8 old_cr2, cr2;
unsigned long flags;
int locked = 1;
@@ -2516,7 +2524,7 @@ static void
lpuart32_console_write(struct console *co, const char *s, unsigned int count)
{
struct lpuart_port *sport = lpuart_ports[co->index];
- unsigned long old_cr, cr;
+ u32 old_cr, cr;
unsigned long flags;
int locked = 1;
@@ -2550,7 +2558,7 @@ static void __init
lpuart_console_get_options(struct lpuart_port *sport, int *baud,
int *parity, int *bits)
{
- unsigned char cr, bdh, bdl, brfa;
+ u8 cr, bdh, bdl, brfa;
unsigned int sbr, uartclk, baud_raw;
cr = readb(sport->port.membase + UARTCR2);
@@ -2599,7 +2607,7 @@ static void __init
lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
int *parity, int *bits)
{
- unsigned long cr, bd;
+ u32 cr, bd;
unsigned int sbr, uartclk, baud_raw;
cr = lpuart32_read(&sport->port, UARTCTRL);
@@ -2805,13 +2813,13 @@ static int lpuart_global_reset(struct lpuart_port *sport)
{
struct uart_port *port = &sport->port;
void __iomem *global_addr;
- unsigned long ctrl, bd;
+ u32 ctrl, bd;
unsigned int val = 0;
int ret;
ret = clk_prepare_enable(sport->ipg_clk);
if (ret) {
- dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
+ dev_err(port->dev, "failed to enable uart ipg clk: %d\n", ret);
return ret;
}
@@ -2822,10 +2830,10 @@ static int lpuart_global_reset(struct lpuart_port *sport)
*/
ctrl = lpuart32_read(port, UARTCTRL);
if (ctrl & UARTCTRL_TE) {
- bd = lpuart32_read(&sport->port, UARTBAUD);
+ bd = lpuart32_read(port, UARTBAUD);
if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, 100000, false,
port)) {
- dev_warn(sport->port.dev,
+ dev_warn(port->dev,
"timeout waiting for transmit engine to complete\n");
clk_disable_unprepare(sport->ipg_clk);
return 0;
@@ -2954,7 +2962,7 @@ static int lpuart_probe(struct platform_device *pdev)
goto failed_attach_port;
ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
- DRIVER_NAME, sport);
+ dev_name(&pdev->dev), sport);
if (ret)
goto failed_irq_request;
@@ -3011,7 +3019,7 @@ static int lpuart_runtime_resume(struct device *dev)
static void serial_lpuart_enable_wakeup(struct lpuart_port *sport, bool on)
{
- unsigned int val, baud;
+ u32 val, baud;
if (lpuart_is_32(sport)) {
val = lpuart32_read(&sport->port, UARTCTRL);
@@ -3076,7 +3084,7 @@ static int lpuart_suspend_noirq(struct device *dev)
static int lpuart_resume_noirq(struct device *dev)
{
struct lpuart_port *sport = dev_get_drvdata(dev);
- unsigned int val;
+ u32 stat;
pinctrl_pm_select_default_state(dev);
@@ -3085,8 +3093,8 @@ static int lpuart_resume_noirq(struct device *dev)
/* clear the wakeup flags */
if (lpuart_is_32(sport)) {
- val = lpuart32_read(&sport->port, UARTSTAT);
- lpuart32_write(&sport->port, val, UARTSTAT);
+ stat = lpuart32_read(&sport->port, UARTSTAT);
+ lpuart32_write(&sport->port, stat, UARTSTAT);
}
}
@@ -3096,7 +3104,8 @@ static int lpuart_resume_noirq(struct device *dev)
static int lpuart_suspend(struct device *dev)
{
struct lpuart_port *sport = dev_get_drvdata(dev);
- unsigned long temp, flags;
+ u32 temp;
+ unsigned long flags;
uart_suspend_port(&lpuart_reg, &sport->port);
@@ -3176,7 +3185,7 @@ static void lpuart_console_fixup(struct lpuart_port *sport)
* in VLLS mode, or restore console setting here.
*/
if (is_imx7ulp_lpuart(sport) && lpuart_uport_is_active(sport) &&
- console_suspend_enabled && uart_console(&sport->port)) {
+ console_suspend_enabled && uart_console(uport)) {
mutex_lock(&port->mutex);
memset(&termios, 0, sizeof(struct ktermios));
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c
index 29e42831df39..7fb995a8490e 100644
--- a/drivers/tty/serial/icom.c
+++ b/drivers/tty/serial/icom.c
@@ -1764,11 +1764,10 @@ static int icom_probe(struct pci_dev *dev,
goto probe_exit1;
}
- /* save off irq and request irq line */
- retval = request_irq(dev->irq, icom_interrupt, IRQF_SHARED, ICOM_DRIVER_NAME, (void *)icom_adapter);
- if (retval) {
- goto probe_exit2;
- }
+ /* save off irq and request irq line */
+ retval = request_irq(dev->irq, icom_interrupt, IRQF_SHARED, ICOM_DRIVER_NAME, icom_adapter);
+ if (retval)
+ goto probe_exit2;
retval = icom_load_ports(icom_adapter);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 9a1afe409b98..e4b6f1bfdc95 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1608,7 +1608,7 @@ static void imx_uart_shutdown(struct uart_port *port)
imx_uart_dma_exit(sport);
}
- mctrl_gpio_disable_ms(sport->gpios);
+ mctrl_gpio_disable_ms_sync(sport->gpios);
uart_port_lock_irqsave(&sport->port, &flags);
ucr2 = imx_uart_readl(sport, UCR2);
@@ -1619,7 +1619,7 @@ static void imx_uart_shutdown(struct uart_port *port)
/*
* Stop our timer.
*/
- del_timer_sync(&sport->timer);
+ timer_delete_sync(&sport->timer);
/*
* Disable all interrupts, port and break condition.
@@ -1752,7 +1752,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
old_csize = CS8;
}
- del_timer_sync(&sport->timer);
+ timer_delete_sync(&sport->timer);
/*
* Ask the core to calculate the divisor for us.
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c
deleted file mode 100644
index 2833708e369f..000000000000
--- a/drivers/tty/serial/kgdb_nmi.c
+++ /dev/null
@@ -1,280 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * KGDB NMI serial console
- *
- * Copyright 2010 Google, Inc.
- * Arve Hjønnevåg <arve@android.com>
- * Colin Cross <ccross@android.com>
- * Copyright 2012 Linaro Ltd.
- * Anton Vorontsov <anton.vorontsov@linaro.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/compiler.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/atomic.h>
-#include <linux/console.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
-#include <linux/interrupt.h>
-#include <linux/hrtimer.h>
-#include <linux/tick.h>
-#include <linux/kfifo.h>
-#include <linux/kgdb.h>
-#include <linux/kdb.h>
-
-static atomic_t kgdb_nmi_num_readers = ATOMIC_INIT(0);
-
-static int kgdb_nmi_console_setup(struct console *co, char *options)
-{
- arch_kgdb_ops.enable_nmi(1);
-
- /* The NMI console uses the dbg_io_ops to issue console messages. To
- * avoid duplicate messages during kdb sessions we must inform kdb's
- * I/O utilities that messages sent to the console will automatically
- * be displayed on the dbg_io.
- */
- dbg_io_ops->cons = co;
-
- return 0;
-}
-
-static void kgdb_nmi_console_write(struct console *co, const char *s, uint c)
-{
- int i;
-
- for (i = 0; i < c; i++)
- dbg_io_ops->write_char(s[i]);
-}
-
-static struct tty_driver *kgdb_nmi_tty_driver;
-
-static struct tty_driver *kgdb_nmi_console_device(struct console *co, int *idx)
-{
- *idx = co->index;
- return kgdb_nmi_tty_driver;
-}
-
-static struct console kgdb_nmi_console = {
- .name = "ttyNMI",
- .setup = kgdb_nmi_console_setup,
- .write = kgdb_nmi_console_write,
- .device = kgdb_nmi_console_device,
- .flags = CON_PRINTBUFFER | CON_ANYTIME,
- .index = -1,
-};
-
-/*
- * This is usually the maximum rate on debug ports. We make fifo large enough
- * to make copy-pasting to the terminal usable.
- */
-#define KGDB_NMI_BAUD 115200
-#define KGDB_NMI_FIFO_SIZE roundup_pow_of_two(KGDB_NMI_BAUD / 8 / HZ)
-
-struct kgdb_nmi_tty_priv {
- struct tty_port port;
- struct timer_list timer;
- STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE) fifo;
-};
-
-static struct tty_port *kgdb_nmi_port;
-
-/*
- * The tasklet is cheap, it does not cause wakeups when reschedules itself,
- * instead it waits for the next tick.
- */
-static void kgdb_nmi_tty_receiver(struct timer_list *t)
-{
- struct kgdb_nmi_tty_priv *priv = from_timer(priv, t, timer);
- char ch;
-
- priv->timer.expires = jiffies + (HZ/100);
- add_timer(&priv->timer);
-
- if (likely(!atomic_read(&kgdb_nmi_num_readers) ||
- !kfifo_len(&priv->fifo)))
- return;
-
- while (kfifo_out(&priv->fifo, &ch, 1))
- tty_insert_flip_char(&priv->port, ch, TTY_NORMAL);
- tty_flip_buffer_push(&priv->port);
-}
-
-static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty)
-{
- struct kgdb_nmi_tty_priv *priv =
- container_of(port, struct kgdb_nmi_tty_priv, port);
-
- kgdb_nmi_port = port;
- priv->timer.expires = jiffies + (HZ/100);
- add_timer(&priv->timer);
-
- return 0;
-}
-
-static void kgdb_nmi_tty_shutdown(struct tty_port *port)
-{
- struct kgdb_nmi_tty_priv *priv =
- container_of(port, struct kgdb_nmi_tty_priv, port);
-
- del_timer(&priv->timer);
- kgdb_nmi_port = NULL;
-}
-
-static const struct tty_port_operations kgdb_nmi_tty_port_ops = {
- .activate = kgdb_nmi_tty_activate,
- .shutdown = kgdb_nmi_tty_shutdown,
-};
-
-static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty)
-{
- struct kgdb_nmi_tty_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- INIT_KFIFO(priv->fifo);
- timer_setup(&priv->timer, kgdb_nmi_tty_receiver, 0);
- tty_port_init(&priv->port);
- priv->port.ops = &kgdb_nmi_tty_port_ops;
- tty->driver_data = priv;
-
- ret = tty_port_install(&priv->port, drv, tty);
- if (ret) {
- pr_err("%s: can't install tty port: %d\n", __func__, ret);
- goto err;
- }
- return 0;
-err:
- tty_port_destroy(&priv->port);
- kfree(priv);
- return ret;
-}
-
-static void kgdb_nmi_tty_cleanup(struct tty_struct *tty)
-{
- struct kgdb_nmi_tty_priv *priv = tty->driver_data;
-
- tty->driver_data = NULL;
- tty_port_destroy(&priv->port);
- kfree(priv);
-}
-
-static int kgdb_nmi_tty_open(struct tty_struct *tty, struct file *file)
-{
- struct kgdb_nmi_tty_priv *priv = tty->driver_data;
- unsigned int mode = file->f_flags & O_ACCMODE;
- int ret;
-
- ret = tty_port_open(&priv->port, tty, file);
- if (!ret && (mode == O_RDONLY || mode == O_RDWR))
- atomic_inc(&kgdb_nmi_num_readers);
-
- return ret;
-}
-
-static void kgdb_nmi_tty_close(struct tty_struct *tty, struct file *file)
-{
- struct kgdb_nmi_tty_priv *priv = tty->driver_data;
- unsigned int mode = file->f_flags & O_ACCMODE;
-
- if (mode == O_RDONLY || mode == O_RDWR)
- atomic_dec(&kgdb_nmi_num_readers);
-
- tty_port_close(&priv->port, tty, file);
-}
-
-static void kgdb_nmi_tty_hangup(struct tty_struct *tty)
-{
- struct kgdb_nmi_tty_priv *priv = tty->driver_data;
-
- tty_port_hangup(&priv->port);
-}
-
-static unsigned int kgdb_nmi_tty_write_room(struct tty_struct *tty)
-{
- /* Actually, we can handle any amount as we use polled writes. */
- return 2048;
-}
-
-static ssize_t kgdb_nmi_tty_write(struct tty_struct *tty, const u8 *buf,
- size_t c)
-{
- int i;
-
- for (i = 0; i < c; i++)
- dbg_io_ops->write_char(buf[i]);
- return c;
-}
-
-static const struct tty_operations kgdb_nmi_tty_ops = {
- .open = kgdb_nmi_tty_open,
- .close = kgdb_nmi_tty_close,
- .install = kgdb_nmi_tty_install,
- .cleanup = kgdb_nmi_tty_cleanup,
- .hangup = kgdb_nmi_tty_hangup,
- .write_room = kgdb_nmi_tty_write_room,
- .write = kgdb_nmi_tty_write,
-};
-
-int kgdb_register_nmi_console(void)
-{
- int ret;
-
- if (!arch_kgdb_ops.enable_nmi)
- return 0;
-
- kgdb_nmi_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
- if (IS_ERR(kgdb_nmi_tty_driver)) {
- pr_err("%s: cannot allocate tty\n", __func__);
- return PTR_ERR(kgdb_nmi_tty_driver);
- }
- kgdb_nmi_tty_driver->driver_name = "ttyNMI";
- kgdb_nmi_tty_driver->name = "ttyNMI";
- kgdb_nmi_tty_driver->num = 1;
- kgdb_nmi_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
- kgdb_nmi_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- kgdb_nmi_tty_driver->init_termios = tty_std_termios;
- tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios,
- KGDB_NMI_BAUD, KGDB_NMI_BAUD);
- tty_set_operations(kgdb_nmi_tty_driver, &kgdb_nmi_tty_ops);
-
- ret = tty_register_driver(kgdb_nmi_tty_driver);
- if (ret) {
- pr_err("%s: can't register tty driver: %d\n", __func__, ret);
- goto err_drv_reg;
- }
-
- register_console(&kgdb_nmi_console);
-
- return 0;
-err_drv_reg:
- tty_driver_kref_put(kgdb_nmi_tty_driver);
- return ret;
-}
-EXPORT_SYMBOL_GPL(kgdb_register_nmi_console);
-
-int kgdb_unregister_nmi_console(void)
-{
- int ret;
-
- if (!arch_kgdb_ops.enable_nmi)
- return 0;
- arch_kgdb_ops.enable_nmi(0);
-
- ret = unregister_console(&kgdb_nmi_console);
- if (ret)
- return ret;
-
- tty_unregister_driver(kgdb_nmi_tty_driver);
- tty_driver_kref_put(kgdb_nmi_tty_driver);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(kgdb_unregister_nmi_console);
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 58ea1e1391ce..85f6c5a76e0f 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -186,8 +186,6 @@ static void cleanup_kgdboc(void)
if (configured != 1)
return;
- if (kgdb_unregister_nmi_console())
- return;
kgdboc_unregister_kbd();
kgdb_unregister_io_module(&kgdboc_io_ops);
}
@@ -250,16 +248,10 @@ do_register:
if (err)
goto noconfig;
- err = kgdb_register_nmi_console();
- if (err)
- goto nmi_con_failed;
-
configured = 1;
return 0;
-nmi_con_failed:
- kgdb_unregister_io_module(&kgdboc_io_ops);
noconfig:
kgdboc_unregister_kbd();
configured = 0;
diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c
index 6c13cf1ab646..3a0960c97c77 100644
--- a/drivers/tty/serial/liteuart.c
+++ b/drivers/tty/serial/liteuart.c
@@ -96,7 +96,7 @@ static void liteuart_stop_rx(struct uart_port *port)
struct liteuart_port *uart = to_liteuart_port(port);
/* just delete timer */
- del_timer(&uart->timer);
+ timer_delete(&uart->timer);
}
static void liteuart_rx_chars(struct uart_port *port)
@@ -220,7 +220,7 @@ static void liteuart_shutdown(struct uart_port *port)
if (port->irq)
free_irq(port->irq, port);
else
- del_timer_sync(&uart->timer);
+ timer_delete_sync(&uart->timer);
}
static void liteuart_set_termios(struct uart_port *port, struct ktermios *new,
diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c
index 8dcad52eedfd..285b0fe41a86 100644
--- a/drivers/tty/serial/ma35d1_serial.c
+++ b/drivers/tty/serial/ma35d1_serial.c
@@ -799,7 +799,7 @@ static struct platform_driver ma35d1serial_driver = {
.resume = ma35d1serial_resume,
.driver = {
.name = "ma35d1-uart",
- .of_match_table = of_match_ptr(ma35d1_serial_of_match),
+ .of_match_table = ma35d1_serial_of_match,
},
};
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index cde5f1c86353..f2dd83692b2c 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -506,7 +506,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
MAX3100_STATUS_PE | MAX3100_STATUS_FE |
MAX3100_STATUS_OE;
- del_timer_sync(&s->timer);
+ timer_delete_sync(&s->timer);
uart_update_timeout(port, termios->c_cflag, baud);
spin_lock(&s->conf_lock);
@@ -532,7 +532,7 @@ static void max3100_shutdown(struct uart_port *port)
s->force_end_work = 1;
- del_timer_sync(&s->timer);
+ timer_delete_sync(&s->timer);
if (s->workqueue) {
destroy_workqueue(s->workqueue);
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 2204cc3e3b07..37eb701b0b46 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -1351,7 +1351,6 @@ static const struct uart_ops mpc52xx_uart_ops = {
.startup = mpc52xx_uart_startup,
.shutdown = mpc52xx_uart_shutdown,
.set_termios = mpc52xx_uart_set_termios,
-/* .pm = mpc52xx_uart_pm, Not supported yet */
.type = mpc52xx_uart_type,
.release_port = mpc52xx_uart_release_port,
.request_port = mpc52xx_uart_request_port,
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c
index 85ce1e9af44a..b417faead20f 100644
--- a/drivers/tty/serial/mux.c
+++ b/drivers/tty/serial/mux.c
@@ -563,7 +563,7 @@ static void __exit mux_exit(void)
{
/* Delete the Mux timer. */
if(port_cnt > 0) {
- del_timer_sync(&mux_timer);
+ timer_delete_sync(&mux_timer);
#ifdef CONFIG_SERIAL_MUX_CONSOLE
unregister_console(&mux_console);
#endif
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index c7cee5fee603..508e8c6f01d4 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -1515,7 +1515,6 @@ static const struct uart_ops pch_uart_ops = {
.startup = pch_uart_startup,
.shutdown = pch_uart_shutdown,
.set_termios = pch_uart_set_termios,
-/* .pm = pch_uart_pm, Not supported yet */
.type = pch_uart_type,
.release_port = pch_uart_release_port,
.request_port = pch_uart_request_port,
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c
index 3c34027687d2..8587ebbe1073 100644
--- a/drivers/tty/serial/sa1100.c
+++ b/drivers/tty/serial/sa1100.c
@@ -369,7 +369,7 @@ static void sa1100_shutdown(struct uart_port *port)
/*
* Stop our timer.
*/
- del_timer_sync(&sport->timer);
+ timer_delete_sync(&sport->timer);
/*
* Free the interrupt
@@ -421,7 +421,7 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
- del_timer_sync(&sport->timer);
+ timer_delete_sync(&sport->timer);
uart_port_lock_irqsave(&sport->port, &flags);
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c
index 4c851dae6624..553e3c1321ca 100644
--- a/drivers/tty/serial/sccnxp.c
+++ b/drivers/tty/serial/sccnxp.c
@@ -1033,7 +1033,7 @@ static void sccnxp_remove(struct platform_device *pdev)
if (!s->poll)
devm_free_irq(&pdev->dev, s->irq, s);
else
- del_timer_sync(&s->timer);
+ timer_delete_sync(&s->timer);
for (i = 0; i < s->uart.nr; i++)
uart_remove_one_port(&s->uart, &s->port[i]);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index d46650e578e5..88669972d9a0 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -895,8 +895,8 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
{
struct uart_port *uport = uart_port_check(state);
unsigned long new_port;
- unsigned int change_irq, change_port, closing_wait;
- unsigned int old_custom_divisor, close_delay;
+ unsigned int old_custom_divisor, close_delay, closing_wait;
+ bool change_irq, change_port;
upf_t old_flags, new_flags;
int retval;
@@ -2013,9 +2013,8 @@ static const char *uart_type(struct uart_port *port)
#ifdef CONFIG_PROC_FS
-static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
+static void uart_line_info(struct seq_file *m, struct uart_state *state)
{
- struct uart_state *state = drv->state + i;
struct tty_port *port = &state->port;
enum uart_pm_state pm_state;
struct uart_port *uport;
@@ -2100,7 +2099,7 @@ static int uart_proc_show(struct seq_file *m, void *v)
seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", "", "", "");
for (i = 0; i < drv->nr; i++)
- uart_line_info(m, drv, i);
+ uart_line_info(m, drv->state + i);
return 0;
}
#endif
@@ -3156,7 +3155,6 @@ static int serial_core_add_one_port(struct uart_driver *drv, struct uart_port *u
if (uport->cons && uport->dev)
of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
- tty_port_link_device(port, drv->tty_driver, uport->line);
uart_configure_port(drv, state, uport);
port->console = uart_console(uport);
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c
index 8855688a5b6c..7b02c5ca4afd 100644
--- a/drivers/tty/serial/serial_mctrl_gpio.c
+++ b/drivers/tty/serial/serial_mctrl_gpio.c
@@ -217,7 +217,7 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context)
*
* This will get the {cts,rts,...}-gpios from device tree if they are present
* and request them, set direction etc, and return an allocated structure.
- * `devm_*` functions are used, so there's no need to call mctrl_gpio_free().
+ * `devm_*` functions are used, so there's no need to explicitly free.
* As this sets up the irq handling, make sure to not handle changes to the
* gpio input lines in your driver, too.
*/
@@ -268,32 +268,6 @@ struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx)
EXPORT_SYMBOL_GPL(mctrl_gpio_init);
/**
- * mctrl_gpio_free - explicitly free uart gpios
- * @dev: uart port's device
- * @gpios: gpios structure to be freed
- *
- * This will free the requested gpios in mctrl_gpio_init(). As `devm_*`
- * functions are used, there's generally no need to call this function.
- */
-void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios)
-{
- enum mctrl_gpio_idx i;
-
- if (gpios == NULL)
- return;
-
- for (i = 0; i < UART_GPIO_MAX; i++) {
- if (gpios->irq[i])
- devm_free_irq(gpios->port->dev, gpios->irq[i], gpios);
-
- if (gpios->gpio[i])
- devm_gpiod_put(dev, gpios->gpio[i]);
- }
- devm_kfree(dev, gpios);
-}
-EXPORT_SYMBOL_GPL(mctrl_gpio_free);
-
-/**
* mctrl_gpio_enable_ms - enable irqs and handling of changes to the ms lines
* @gpios: gpios to enable
*/
@@ -322,11 +296,7 @@ void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios)
}
EXPORT_SYMBOL_GPL(mctrl_gpio_enable_ms);
-/**
- * mctrl_gpio_disable_ms - disable irqs and handling of changes to the ms lines
- * @gpios: gpios to disable
- */
-void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios)
+static void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios, bool sync)
{
enum mctrl_gpio_idx i;
@@ -342,10 +312,34 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios)
if (!gpios->irq[i])
continue;
- disable_irq(gpios->irq[i]);
+ if (sync)
+ disable_irq(gpios->irq[i]);
+ else
+ disable_irq_nosync(gpios->irq[i]);
}
}
-EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms);
+
+/**
+ * mctrl_gpio_disable_ms_sync - disable irqs and handling of changes to the ms
+ * lines, and wait for any pending IRQ to be processed
+ * @gpios: gpios to disable
+ */
+void mctrl_gpio_disable_ms_sync(struct mctrl_gpios *gpios)
+{
+ mctrl_gpio_disable_ms(gpios, true);
+}
+EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms_sync);
+
+/**
+ * mctrl_gpio_disable_ms_no_sync - disable irqs and handling of changes to the
+ * ms lines, and return immediately
+ * @gpios: gpios to disable
+ */
+void mctrl_gpio_disable_ms_no_sync(struct mctrl_gpios *gpios)
+{
+ mctrl_gpio_disable_ms(gpios, false);
+}
+EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms_no_sync);
void mctrl_gpio_enable_irq_wake(struct mctrl_gpios *gpios)
{
diff --git a/drivers/tty/serial/serial_mctrl_gpio.h b/drivers/tty/serial/serial_mctrl_gpio.h
index fc76910fb105..961e4ba0c6f8 100644
--- a/drivers/tty/serial/serial_mctrl_gpio.h
+++ b/drivers/tty/serial/serial_mctrl_gpio.h
@@ -59,7 +59,7 @@ struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios,
/*
* Request and set direction of modem control line GPIOs and set up irq
* handling.
- * devm_* functions are used, so there's no need to call mctrl_gpio_free().
+ * devm_* functions are used, so there's no need to explicitly free.
* Returns a pointer to the allocated mctrl structure if ok, -ENOMEM on
* allocation error.
*/
@@ -67,7 +67,7 @@ struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx);
/*
* Request and set direction of modem control line GPIOs.
- * devm_* functions are used, so there's no need to call mctrl_gpio_free().
+ * devm_* functions are used, so there's no need to explicitly free.
* Returns a pointer to the allocated mctrl structure if ok, -ENOMEM on
* allocation error.
*/
@@ -75,21 +75,21 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev,
unsigned int idx);
/*
- * Free the mctrl_gpios structure.
- * Normally, this function will not be called, as the GPIOs will
- * be disposed of by the resource management code.
+ * Enable gpio interrupts to report status line changes.
*/
-void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios);
+void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios);
/*
- * Enable gpio interrupts to report status line changes.
+ * Disable gpio interrupts to report status line changes, and block until
+ * any corresponding IRQ is processed
*/
-void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios);
+void mctrl_gpio_disable_ms_sync(struct mctrl_gpios *gpios);
/*
- * Disable gpio interrupts to report status line changes.
+ * Disable gpio interrupts to report status line changes, and return
+ * immediately
*/
-void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios);
+void mctrl_gpio_disable_ms_no_sync(struct mctrl_gpios *gpios);
/*
* Enable gpio wakeup interrupts to enable wake up source.
@@ -139,16 +139,15 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
return NULL;
}
-static inline
-void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios)
+static inline void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios)
{
}
-static inline void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios)
+static inline void mctrl_gpio_disable_ms_sync(struct mctrl_gpios *gpios)
{
}
-static inline void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios)
+static inline void mctrl_gpio_disable_ms_no_sync(struct mctrl_gpios *gpios)
{
}
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index b72c3bc19bfa..7e7813ccda41 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -104,6 +104,20 @@ struct plat_sci_reg {
u8 offset, size;
};
+struct sci_suspend_regs {
+ u16 scdl;
+ u16 sccks;
+ u16 scsmr;
+ u16 scscr;
+ u16 scfcr;
+ u16 scsptr;
+ u16 hssrr;
+ u16 scpcr;
+ u16 scpdr;
+ u8 scbrr;
+ u8 semr;
+};
+
struct sci_port_params {
const struct plat_sci_reg regs[SCIx_NR_REGS];
unsigned int fifosize;
@@ -134,6 +148,8 @@ struct sci_port {
struct dma_chan *chan_tx;
struct dma_chan *chan_rx;
+ struct reset_control *rstc;
+
#ifdef CONFIG_SERIAL_SH_SCI_DMA
struct dma_chan *chan_tx_saved;
struct dma_chan *chan_rx_saved;
@@ -153,6 +169,7 @@ struct sci_port {
int rx_trigger;
struct timer_list rx_fifo_timer;
int rx_fifo_timeout;
+ struct sci_suspend_regs suspend_regs;
u16 hscif_tot;
bool has_rtscts;
@@ -2297,7 +2314,7 @@ static void sci_shutdown(struct uart_port *port)
dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
s->autorts = false;
- mctrl_gpio_disable_ms(to_sci_port(port)->gpios);
+ mctrl_gpio_disable_ms_sync(to_sci_port(port)->gpios);
uart_port_lock_irqsave(port, &flags);
sci_stop_rx(port);
@@ -2320,7 +2337,7 @@ static void sci_shutdown(struct uart_port *port)
#endif
if (s->rx_trigger > 1 && s->rx_fifo_timeout > 0)
- del_timer_sync(&s->rx_fifo_timer);
+ timer_delete_sync(&s->rx_fifo_timer);
sci_free_irq(s);
sci_free_dma(port);
}
@@ -3373,6 +3390,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
}
sp = &sci_ports[id];
+ sp->rstc = rstc;
*dev_id = id;
p->type = SCI_OF_TYPE(data);
@@ -3545,13 +3563,77 @@ static int sci_probe(struct platform_device *dev)
return 0;
}
+static void sci_console_save(struct sci_port *s)
+{
+ struct sci_suspend_regs *regs = &s->suspend_regs;
+ struct uart_port *port = &s->port;
+
+ if (sci_getreg(port, SCDL)->size)
+ regs->scdl = sci_serial_in(port, SCDL);
+ if (sci_getreg(port, SCCKS)->size)
+ regs->sccks = sci_serial_in(port, SCCKS);
+ if (sci_getreg(port, SCSMR)->size)
+ regs->scsmr = sci_serial_in(port, SCSMR);
+ if (sci_getreg(port, SCSCR)->size)
+ regs->scscr = sci_serial_in(port, SCSCR);
+ if (sci_getreg(port, SCFCR)->size)
+ regs->scfcr = sci_serial_in(port, SCFCR);
+ if (sci_getreg(port, SCSPTR)->size)
+ regs->scsptr = sci_serial_in(port, SCSPTR);
+ if (sci_getreg(port, SCBRR)->size)
+ regs->scbrr = sci_serial_in(port, SCBRR);
+ if (sci_getreg(port, HSSRR)->size)
+ regs->hssrr = sci_serial_in(port, HSSRR);
+ if (sci_getreg(port, SCPCR)->size)
+ regs->scpcr = sci_serial_in(port, SCPCR);
+ if (sci_getreg(port, SCPDR)->size)
+ regs->scpdr = sci_serial_in(port, SCPDR);
+ if (sci_getreg(port, SEMR)->size)
+ regs->semr = sci_serial_in(port, SEMR);
+}
+
+static void sci_console_restore(struct sci_port *s)
+{
+ struct sci_suspend_regs *regs = &s->suspend_regs;
+ struct uart_port *port = &s->port;
+
+ if (sci_getreg(port, SCDL)->size)
+ sci_serial_out(port, SCDL, regs->scdl);
+ if (sci_getreg(port, SCCKS)->size)
+ sci_serial_out(port, SCCKS, regs->sccks);
+ if (sci_getreg(port, SCSMR)->size)
+ sci_serial_out(port, SCSMR, regs->scsmr);
+ if (sci_getreg(port, SCSCR)->size)
+ sci_serial_out(port, SCSCR, regs->scscr);
+ if (sci_getreg(port, SCFCR)->size)
+ sci_serial_out(port, SCFCR, regs->scfcr);
+ if (sci_getreg(port, SCSPTR)->size)
+ sci_serial_out(port, SCSPTR, regs->scsptr);
+ if (sci_getreg(port, SCBRR)->size)
+ sci_serial_out(port, SCBRR, regs->scbrr);
+ if (sci_getreg(port, HSSRR)->size)
+ sci_serial_out(port, HSSRR, regs->hssrr);
+ if (sci_getreg(port, SCPCR)->size)
+ sci_serial_out(port, SCPCR, regs->scpcr);
+ if (sci_getreg(port, SCPDR)->size)
+ sci_serial_out(port, SCPDR, regs->scpdr);
+ if (sci_getreg(port, SEMR)->size)
+ sci_serial_out(port, SEMR, regs->semr);
+}
+
static __maybe_unused int sci_suspend(struct device *dev)
{
struct sci_port *sport = dev_get_drvdata(dev);
- if (sport)
+ if (sport) {
uart_suspend_port(&sci_uart_driver, &sport->port);
+ if (!console_suspend_enabled && uart_console(&sport->port))
+ sci_console_save(sport);
+ else
+ return reset_control_assert(sport->rstc);
+ }
+
return 0;
}
@@ -3559,8 +3641,18 @@ static __maybe_unused int sci_resume(struct device *dev)
{
struct sci_port *sport = dev_get_drvdata(dev);
- if (sport)
+ if (sport) {
+ if (!console_suspend_enabled && uart_console(&sport->port)) {
+ sci_console_restore(sport);
+ } else {
+ int ret = reset_control_deassert(sport->rstc);
+
+ if (ret)
+ return ret;
+ }
+
uart_resume_port(&sci_uart_driver, &sport->port);
+ }
return 0;
}
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 1ec5d8c3aef8..ad06b760cfca 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -944,7 +944,7 @@ static void stm32_usart_enable_ms(struct uart_port *port)
static void stm32_usart_disable_ms(struct uart_port *port)
{
- mctrl_gpio_disable_ms(to_stm32_port(port)->gpios);
+ mctrl_gpio_disable_ms_sync(to_stm32_port(port)->gpios);
}
/* Transmit stop */
@@ -965,10 +965,8 @@ static void stm32_usart_start_tx(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
- if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char) {
- stm32_usart_rs485_rts_disable(port);
+ if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char)
return;
- }
stm32_usart_rs485_rts_enable(port);
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c
index 7f0fef07e141..383141fe7ba0 100644
--- a/drivers/tty/serial/sunsu.c
+++ b/drivers/tty/serial/sunsu.c
@@ -151,16 +151,6 @@ static void serial_out(struct uart_sunsu_port *up, int offset, int value)
}
/*
- * We used to support using pause I/O for certain machines. We
- * haven't supported this for a while, but just in case it's badly
- * needed for certain old 386 machines, I've left these #define's
- * in....
- */
-#define serial_inp(up, offset) serial_in(up, offset)
-#define serial_outp(up, offset, value) serial_out(up, offset, value)
-
-
-/*
* For the 16C950
*/
static void serial_icr_write(struct uart_sunsu_port *up, int offset, int value)
@@ -169,20 +159,6 @@ static void serial_icr_write(struct uart_sunsu_port *up, int offset, int value)
serial_out(up, UART_ICR, value);
}
-#if 0 /* Unused currently */
-static unsigned int serial_icr_read(struct uart_sunsu_port *up, int offset)
-{
- unsigned int value;
-
- serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
- serial_out(up, UART_SCR, offset);
- value = serial_in(up, UART_ICR);
- serial_icr_write(up, UART_ACR, up->acr);
-
- return value;
-}
-#endif
-
#ifdef CONFIG_SERIAL_8250_RSA
/*
* Attempts to turn on the RSA FIFO. Returns zero on failure.
@@ -193,12 +169,12 @@ static int __enable_rsa(struct uart_sunsu_port *up)
unsigned char mode;
int result;
- mode = serial_inp(up, UART_RSA_MSR);
+ mode = serial_in(up, UART_RSA_MSR);
result = mode & UART_RSA_MSR_FIFO;
if (!result) {
- serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
- mode = serial_inp(up, UART_RSA_MSR);
+ serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+ mode = serial_in(up, UART_RSA_MSR);
result = mode & UART_RSA_MSR_FIFO;
}
@@ -217,7 +193,7 @@ static void enable_rsa(struct uart_sunsu_port *up)
uart_port_unlock_irq(&up->port);
}
if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
- serial_outp(up, UART_RSA_FRR, 0);
+ serial_out(up, UART_RSA_FRR, 0);
}
}
@@ -236,12 +212,12 @@ static void disable_rsa(struct uart_sunsu_port *up)
up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
uart_port_lock_irq(&up->port);
- mode = serial_inp(up, UART_RSA_MSR);
+ mode = serial_in(up, UART_RSA_MSR);
result = !(mode & UART_RSA_MSR_FIFO);
if (!result) {
- serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
- mode = serial_inp(up, UART_RSA_MSR);
+ serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+ mode = serial_in(up, UART_RSA_MSR);
result = !(mode & UART_RSA_MSR_FIFO);
}
@@ -326,7 +302,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status)
int saw_console_brk = 0;
do {
- ch = serial_inp(up, UART_RX);
+ ch = serial_in(up, UART_RX);
flag = TTY_NORMAL;
up->port.icount.rx++;
@@ -387,7 +363,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status)
*/
tty_insert_flip_char(port, 0, TTY_OVERRUN);
ignore_char:
- *status = serial_inp(up, UART_LSR);
+ *status = serial_in(up, UART_LSR);
} while ((*status & UART_LSR_DR) && (max_count-- > 0));
if (saw_console_brk)
@@ -401,7 +377,7 @@ static void transmit_chars(struct uart_sunsu_port *up)
int count;
if (up->port.x_char) {
- serial_outp(up, UART_TX, up->port.x_char);
+ serial_out(up, UART_TX, up->port.x_char);
up->port.icount.tx++;
up->port.x_char = 0;
return;
@@ -460,7 +436,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id)
uart_port_lock_irqsave(&up->port, &flags);
do {
- status = serial_inp(up, UART_LSR);
+ status = serial_in(up, UART_LSR);
if (status & UART_LSR_DR)
receive_chars(up, &status);
check_modem_status(up);
@@ -498,7 +474,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break)
{
do {
- unsigned char ch = serial_inp(up, UART_RX);
+ unsigned char ch = serial_in(up, UART_RX);
/* Stop-A is handled by drivers/char/keyboard.c now. */
if (up->su_type == SU_PORT_KBD) {
@@ -530,7 +506,7 @@ static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id)
struct uart_sunsu_port *up = dev_id;
if (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)) {
- unsigned char status = serial_inp(up, UART_LSR);
+ unsigned char status = serial_in(up, UART_LSR);
if ((status & UART_LSR_DR) || (status & UART_LSR_BI))
receive_kbd_ms_chars(up, (status & UART_LSR_BI) != 0);
@@ -619,14 +595,14 @@ static int sunsu_startup(struct uart_port *port)
if (up->port.type == PORT_16C950) {
/* Wake up and initialize UART */
up->acr = 0;
- serial_outp(up, UART_LCR, 0xBF);
- serial_outp(up, UART_EFR, UART_EFR_ECB);
- serial_outp(up, UART_IER, 0);
- serial_outp(up, UART_LCR, 0);
+ serial_out(up, UART_LCR, 0xBF);
+ serial_out(up, UART_EFR, UART_EFR_ECB);
+ serial_out(up, UART_IER, 0);
+ serial_out(up, UART_LCR, 0);
serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
- serial_outp(up, UART_LCR, 0xBF);
- serial_outp(up, UART_EFR, UART_EFR_ECB);
- serial_outp(up, UART_LCR, 0);
+ serial_out(up, UART_LCR, 0xBF);
+ serial_out(up, UART_EFR, UART_EFR_ECB);
+ serial_out(up, UART_LCR, 0);
}
#ifdef CONFIG_SERIAL_8250_RSA
@@ -642,19 +618,19 @@ static int sunsu_startup(struct uart_port *port)
* (they will be reenabled in set_termios())
*/
if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) {
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
- serial_outp(up, UART_FCR, 0);
+ serial_out(up, UART_FCR, 0);
}
/*
* Clear the interrupt registers.
*/
- (void) serial_inp(up, UART_LSR);
- (void) serial_inp(up, UART_RX);
- (void) serial_inp(up, UART_IIR);
- (void) serial_inp(up, UART_MSR);
+ (void) serial_in(up, UART_LSR);
+ (void) serial_in(up, UART_RX);
+ (void) serial_in(up, UART_IIR);
+ (void) serial_in(up, UART_MSR);
/*
* At this point, there's no way the LSR could still be 0xff;
@@ -662,7 +638,7 @@ static int sunsu_startup(struct uart_port *port)
* here.
*/
if (!(up->port.flags & UPF_BUGGY_UART) &&
- (serial_inp(up, UART_LSR) == 0xff)) {
+ (serial_in(up, UART_LSR) == 0xff)) {
printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
return -ENODEV;
}
@@ -682,7 +658,7 @@ static int sunsu_startup(struct uart_port *port)
/*
* Now, initialize the UART
*/
- serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+ serial_out(up, UART_LCR, UART_LCR_WLEN8);
uart_port_lock_irqsave(&up->port, &flags);
@@ -697,7 +673,7 @@ static int sunsu_startup(struct uart_port *port)
* anyway, so we don't enable them here.
*/
up->ier = UART_IER_RLSI | UART_IER_RDI;
- serial_outp(up, UART_IER, up->ier);
+ serial_out(up, UART_IER, up->ier);
if (up->port.flags & UPF_FOURPORT) {
unsigned int icp;
@@ -712,10 +688,10 @@ static int sunsu_startup(struct uart_port *port)
/*
* And clear the interrupt registers again for luck.
*/
- (void) serial_inp(up, UART_LSR);
- (void) serial_inp(up, UART_RX);
- (void) serial_inp(up, UART_IIR);
- (void) serial_inp(up, UART_MSR);
+ (void) serial_in(up, UART_LSR);
+ (void) serial_in(up, UART_RX);
+ (void) serial_in(up, UART_IIR);
+ (void) serial_in(up, UART_MSR);
return 0;
}
@@ -730,7 +706,7 @@ static void sunsu_shutdown(struct uart_port *port)
* Disable interrupts from this port
*/
up->ier = 0;
- serial_outp(up, UART_IER, 0);
+ serial_out(up, UART_IER, 0);
uart_port_lock_irqsave(&up->port, &flags);
if (up->port.flags & UPF_FOURPORT) {
@@ -746,11 +722,11 @@ static void sunsu_shutdown(struct uart_port *port)
/*
* Disable break condition and FIFOs
*/
- serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC);
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT);
- serial_outp(up, UART_FCR, 0);
+ serial_out(up, UART_FCR, 0);
#ifdef CONFIG_SERIAL_8250_RSA
/*
@@ -872,22 +848,22 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
serial_out(up, UART_IER, up->ier);
if (uart_config[up->port.type].flags & UART_STARTECH) {
- serial_outp(up, UART_LCR, 0xBF);
- serial_outp(up, UART_EFR, cflag & CRTSCTS ? UART_EFR_CTS :0);
+ serial_out(up, UART_LCR, 0xBF);
+ serial_out(up, UART_EFR, cflag & CRTSCTS ? UART_EFR_CTS :0);
}
- serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
- serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */
- serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */
+ serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+ serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
+ serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
if (up->port.type == PORT_16750)
- serial_outp(up, UART_FCR, fcr); /* set fcr */
- serial_outp(up, UART_LCR, cval); /* reset DLAB */
+ serial_out(up, UART_FCR, fcr); /* set fcr */
+ serial_out(up, UART_LCR, cval); /* reset DLAB */
up->lcr = cval; /* Save LCR */
if (up->port.type != PORT_16750) {
if (fcr & UART_FCR_ENABLE_FIFO) {
/* emulated UARTs (Lucent Venus 167x) need two steps */
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
}
- serial_outp(up, UART_FCR, fcr); /* set fcr */
+ serial_out(up, UART_FCR, fcr); /* set fcr */
}
up->cflag = cflag;
@@ -1051,18 +1027,18 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
* 0x80 is a non-existent port; which should be safe since
* include/asm/io.h also makes this assumption.
*/
- scratch = serial_inp(up, UART_IER);
- serial_outp(up, UART_IER, 0);
+ scratch = serial_in(up, UART_IER);
+ serial_out(up, UART_IER, 0);
#ifdef __i386__
outb(0xff, 0x080);
#endif
- scratch2 = serial_inp(up, UART_IER);
- serial_outp(up, UART_IER, 0x0f);
+ scratch2 = serial_in(up, UART_IER);
+ serial_out(up, UART_IER, 0x0f);
#ifdef __i386__
outb(0, 0x080);
#endif
- scratch3 = serial_inp(up, UART_IER);
- serial_outp(up, UART_IER, scratch);
+ scratch3 = serial_in(up, UART_IER);
+ serial_out(up, UART_IER, scratch);
if (scratch2 != 0 || scratch3 != 0x0F)
goto out; /* We failed; there's nothing here */
}
@@ -1080,16 +1056,16 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
* that conflicts with COM 1-4 --- we hope!
*/
if (!(up->port.flags & UPF_SKIP_TEST)) {
- serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
- status1 = serial_inp(up, UART_MSR) & 0xF0;
- serial_outp(up, UART_MCR, save_mcr);
+ serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+ status1 = serial_in(up, UART_MSR) & 0xF0;
+ serial_out(up, UART_MCR, save_mcr);
if (status1 != 0x90)
goto out; /* We failed loopback test */
}
- serial_outp(up, UART_LCR, 0xBF); /* set up for StarTech test */
- serial_outp(up, UART_EFR, 0); /* EFR is the same as FCR */
- serial_outp(up, UART_LCR, 0);
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_out(up, UART_LCR, 0xBF); /* set up for StarTech test */
+ serial_out(up, UART_EFR, 0); /* EFR is the same as FCR */
+ serial_out(up, UART_LCR, 0);
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
scratch = serial_in(up, UART_IIR) >> 6;
switch (scratch) {
case 0:
@@ -1107,19 +1083,19 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
}
if (up->port.type == PORT_16550A) {
/* Check for Startech UART's */
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ serial_out(up, UART_LCR, UART_LCR_DLAB);
if (serial_in(up, UART_EFR) == 0) {
up->port.type = PORT_16650;
} else {
- serial_outp(up, UART_LCR, 0xBF);
+ serial_out(up, UART_LCR, 0xBF);
if (serial_in(up, UART_EFR) == 0)
up->port.type = PORT_16650V2;
}
}
if (up->port.type == PORT_16550A) {
/* Check for TI 16750 */
- serial_outp(up, UART_LCR, save_lcr | UART_LCR_DLAB);
- serial_outp(up, UART_FCR,
+ serial_out(up, UART_LCR, save_lcr | UART_LCR_DLAB);
+ serial_out(up, UART_FCR,
UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
scratch = serial_in(up, UART_IIR) >> 5;
if (scratch == 7) {
@@ -1129,24 +1105,24 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
* mode if the UART_FCR7_64BYTE bit was set
* while UART_LCR_DLAB was latched.
*/
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
- serial_outp(up, UART_LCR, 0);
- serial_outp(up, UART_FCR,
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_out(up, UART_LCR, 0);
+ serial_out(up, UART_FCR,
UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
scratch = serial_in(up, UART_IIR) >> 5;
if (scratch == 6)
up->port.type = PORT_16750;
}
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
}
- serial_outp(up, UART_LCR, save_lcr);
+ serial_out(up, UART_LCR, save_lcr);
if (up->port.type == PORT_16450) {
scratch = serial_in(up, UART_SCR);
- serial_outp(up, UART_SCR, 0xa5);
+ serial_out(up, UART_SCR, 0xa5);
status1 = serial_in(up, UART_SCR);
- serial_outp(up, UART_SCR, 0x5a);
+ serial_out(up, UART_SCR, 0x5a);
status2 = serial_in(up, UART_SCR);
- serial_outp(up, UART_SCR, scratch);
+ serial_out(up, UART_SCR, scratch);
if ((status1 != 0xa5) || (status2 != 0x5a))
up->port.type = PORT_8250;
@@ -1163,15 +1139,15 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
*/
#ifdef CONFIG_SERIAL_8250_RSA
if (up->port.type == PORT_RSA)
- serial_outp(up, UART_RSA_FRR, 0);
+ serial_out(up, UART_RSA_FRR, 0);
#endif
- serial_outp(up, UART_MCR, save_mcr);
- serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO |
+ serial_out(up, UART_MCR, save_mcr);
+ serial_out(up, UART_FCR, (UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT));
- serial_outp(up, UART_FCR, 0);
+ serial_out(up, UART_FCR, 0);
(void)serial_in(up, UART_RX);
- serial_outp(up, UART_IER, 0);
+ serial_out(up, UART_IER, 0);
out:
uart_port_unlock_irqrestore(&up->port, flags);
diff --git a/drivers/tty/serial/tegra-utc.c b/drivers/tty/serial/tegra-utc.c
new file mode 100644
index 000000000000..39b14fe813c9
--- /dev/null
+++ b/drivers/tty/serial/tegra-utc.c
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+// NVIDIA Tegra UTC (UART Trace Controller) driver.
+
+#include <linux/bits.h>
+#include <linux/console.h>
+#include <linux/container_of.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/kfifo.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/property.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/types.h>
+
+#define TEGRA_UTC_ENABLE 0x000
+#define TEGRA_UTC_ENABLE_CLIENT_ENABLE BIT(0)
+
+#define TEGRA_UTC_FIFO_THRESHOLD 0x008
+
+#define TEGRA_UTC_COMMAND 0x00c
+#define TEGRA_UTC_COMMAND_RESET BIT(0)
+#define TEGRA_UTC_COMMAND_FLUSH BIT(1)
+
+#define TEGRA_UTC_DATA 0x020
+
+#define TEGRA_UTC_FIFO_STATUS 0x100
+#define TEGRA_UTC_FIFO_EMPTY BIT(0)
+#define TEGRA_UTC_FIFO_FULL BIT(1)
+#define TEGRA_UTC_FIFO_REQ BIT(2)
+#define TEGRA_UTC_FIFO_OVERFLOW BIT(3)
+#define TEGRA_UTC_FIFO_TIMEOUT BIT(4)
+
+#define TEGRA_UTC_FIFO_OCCUPANCY 0x104
+
+#define TEGRA_UTC_INTR_STATUS 0x108
+#define TEGRA_UTC_INTR_SET 0x10c
+#define TEGRA_UTC_INTR_MASK 0x110
+#define TEGRA_UTC_INTR_CLEAR 0x114
+#define TEGRA_UTC_INTR_EMPTY BIT(0)
+#define TEGRA_UTC_INTR_FULL BIT(1)
+#define TEGRA_UTC_INTR_REQ BIT(2)
+#define TEGRA_UTC_INTR_OVERFLOW BIT(3)
+#define TEGRA_UTC_INTR_TIMEOUT BIT(4)
+
+#define TEGRA_UTC_UART_NR 16
+
+#define TEGRA_UTC_INTR_COMMON (TEGRA_UTC_INTR_REQ | TEGRA_UTC_INTR_FULL | TEGRA_UTC_INTR_EMPTY)
+
+struct tegra_utc_port {
+#if IS_ENABLED(CONFIG_SERIAL_TEGRA_UTC_CONSOLE)
+ struct console console;
+#endif
+ struct uart_port port;
+
+ void __iomem *rx_base;
+ void __iomem *tx_base;
+
+ u32 tx_irqmask;
+ u32 rx_irqmask;
+
+ unsigned int fifosize;
+ u32 tx_threshold;
+ u32 rx_threshold;
+};
+
+static u32 tegra_utc_rx_readl(struct tegra_utc_port *tup, unsigned int offset)
+{
+ void __iomem *addr = tup->rx_base + offset;
+
+ return readl_relaxed(addr);
+}
+
+static void tegra_utc_rx_writel(struct tegra_utc_port *tup, u32 val, unsigned int offset)
+{
+ void __iomem *addr = tup->rx_base + offset;
+
+ writel_relaxed(val, addr);
+}
+
+static u32 tegra_utc_tx_readl(struct tegra_utc_port *tup, unsigned int offset)
+{
+ void __iomem *addr = tup->tx_base + offset;
+
+ return readl_relaxed(addr);
+}
+
+static void tegra_utc_tx_writel(struct tegra_utc_port *tup, u32 val, unsigned int offset)
+{
+ void __iomem *addr = tup->tx_base + offset;
+
+ writel_relaxed(val, addr);
+}
+
+static void tegra_utc_enable_tx_irq(struct tegra_utc_port *tup)
+{
+ tup->tx_irqmask = TEGRA_UTC_INTR_REQ;
+
+ tegra_utc_tx_writel(tup, tup->tx_irqmask, TEGRA_UTC_INTR_MASK);
+ tegra_utc_tx_writel(tup, tup->tx_irqmask, TEGRA_UTC_INTR_SET);
+}
+
+static void tegra_utc_disable_tx_irq(struct tegra_utc_port *tup)
+{
+ tup->tx_irqmask = 0x0;
+
+ tegra_utc_tx_writel(tup, tup->tx_irqmask, TEGRA_UTC_INTR_MASK);
+ tegra_utc_tx_writel(tup, tup->tx_irqmask, TEGRA_UTC_INTR_SET);
+}
+
+static void tegra_utc_stop_tx(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ tegra_utc_disable_tx_irq(tup);
+}
+
+static void tegra_utc_init_tx(struct tegra_utc_port *tup)
+{
+ /* Disable TX. */
+ tegra_utc_tx_writel(tup, 0x0, TEGRA_UTC_ENABLE);
+
+ /* Update the FIFO Threshold. */
+ tegra_utc_tx_writel(tup, tup->tx_threshold, TEGRA_UTC_FIFO_THRESHOLD);
+
+ /* Clear and mask all the interrupts. */
+ tegra_utc_tx_writel(tup, TEGRA_UTC_INTR_COMMON, TEGRA_UTC_INTR_CLEAR);
+ tegra_utc_disable_tx_irq(tup);
+
+ /* Enable TX. */
+ tegra_utc_tx_writel(tup, TEGRA_UTC_ENABLE_CLIENT_ENABLE, TEGRA_UTC_ENABLE);
+}
+
+static void tegra_utc_init_rx(struct tegra_utc_port *tup)
+{
+ tup->rx_irqmask = TEGRA_UTC_INTR_REQ | TEGRA_UTC_INTR_TIMEOUT;
+
+ tegra_utc_rx_writel(tup, TEGRA_UTC_COMMAND_RESET, TEGRA_UTC_COMMAND);
+ tegra_utc_rx_writel(tup, tup->rx_threshold, TEGRA_UTC_FIFO_THRESHOLD);
+
+ /* Clear all the pending interrupts. */
+ tegra_utc_rx_writel(tup, TEGRA_UTC_INTR_TIMEOUT | TEGRA_UTC_INTR_OVERFLOW |
+ TEGRA_UTC_INTR_COMMON, TEGRA_UTC_INTR_CLEAR);
+ tegra_utc_rx_writel(tup, tup->rx_irqmask, TEGRA_UTC_INTR_MASK);
+ tegra_utc_rx_writel(tup, tup->rx_irqmask, TEGRA_UTC_INTR_SET);
+
+ /* Enable RX. */
+ tegra_utc_rx_writel(tup, TEGRA_UTC_ENABLE_CLIENT_ENABLE, TEGRA_UTC_ENABLE);
+}
+
+static bool tegra_utc_tx_chars(struct tegra_utc_port *tup)
+{
+ struct uart_port *port = &tup->port;
+ unsigned int pending;
+ u8 c;
+
+ pending = uart_port_tx(port, c,
+ !(tegra_utc_tx_readl(tup, TEGRA_UTC_FIFO_STATUS) & TEGRA_UTC_FIFO_FULL),
+ tegra_utc_tx_writel(tup, c, TEGRA_UTC_DATA));
+
+ return pending;
+}
+
+static void tegra_utc_rx_chars(struct tegra_utc_port *tup)
+{
+ struct tty_port *port = &tup->port.state->port;
+ unsigned int max_chars = 256;
+ u32 status;
+ int sysrq;
+ u32 ch;
+
+ while (max_chars--) {
+ status = tegra_utc_rx_readl(tup, TEGRA_UTC_FIFO_STATUS);
+ if (status & TEGRA_UTC_FIFO_EMPTY)
+ break;
+
+ ch = tegra_utc_rx_readl(tup, TEGRA_UTC_DATA);
+ tup->port.icount.rx++;
+
+ if (status & TEGRA_UTC_FIFO_OVERFLOW)
+ tup->port.icount.overrun++;
+
+ uart_port_unlock(&tup->port);
+ sysrq = uart_handle_sysrq_char(&tup->port, ch);
+ uart_port_lock(&tup->port);
+
+ if (!sysrq)
+ tty_insert_flip_char(port, ch, TTY_NORMAL);
+ }
+
+ tty_flip_buffer_push(port);
+}
+
+static irqreturn_t tegra_utc_isr(int irq, void *dev_id)
+{
+ struct tegra_utc_port *tup = dev_id;
+ unsigned int handled = 0;
+ u32 status;
+
+ uart_port_lock(&tup->port);
+
+ /* Process RX_REQ and RX_TIMEOUT interrupts. */
+ do {
+ status = tegra_utc_rx_readl(tup, TEGRA_UTC_INTR_STATUS) & tup->rx_irqmask;
+ if (status) {
+ tegra_utc_rx_writel(tup, tup->rx_irqmask, TEGRA_UTC_INTR_CLEAR);
+ tegra_utc_rx_chars(tup);
+ handled = 1;
+ }
+ } while (status);
+
+ /* Process TX_REQ interrupt. */
+ do {
+ status = tegra_utc_tx_readl(tup, TEGRA_UTC_INTR_STATUS) & tup->tx_irqmask;
+ if (status) {
+ tegra_utc_tx_writel(tup, tup->tx_irqmask, TEGRA_UTC_INTR_CLEAR);
+ tegra_utc_tx_chars(tup);
+ handled = 1;
+ }
+ } while (status);
+
+ uart_port_unlock(&tup->port);
+
+ return IRQ_RETVAL(handled);
+}
+
+static unsigned int tegra_utc_tx_empty(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ return tegra_utc_tx_readl(tup, TEGRA_UTC_FIFO_OCCUPANCY) ? 0 : TIOCSER_TEMT;
+}
+
+static void tegra_utc_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static unsigned int tegra_utc_get_mctrl(struct uart_port *port)
+{
+ return 0;
+}
+
+static void tegra_utc_start_tx(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ if (tegra_utc_tx_chars(tup))
+ tegra_utc_enable_tx_irq(tup);
+}
+
+static void tegra_utc_stop_rx(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ tup->rx_irqmask = 0x0;
+ tegra_utc_rx_writel(tup, tup->rx_irqmask, TEGRA_UTC_INTR_MASK);
+ tegra_utc_rx_writel(tup, tup->rx_irqmask, TEGRA_UTC_INTR_SET);
+}
+
+static void tegra_utc_hw_init(struct tegra_utc_port *tup)
+{
+ tegra_utc_init_tx(tup);
+ tegra_utc_init_rx(tup);
+}
+
+static int tegra_utc_startup(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+ int ret;
+
+ tegra_utc_hw_init(tup);
+
+ /* Interrupt is dedicated to this UTC client. */
+ ret = request_irq(port->irq, tegra_utc_isr, 0, dev_name(port->dev), tup);
+ if (ret < 0)
+ dev_err(port->dev, "failed to register interrupt handler\n");
+
+ return ret;
+}
+
+static void tegra_utc_shutdown(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ tegra_utc_rx_writel(tup, 0x0, TEGRA_UTC_ENABLE);
+ free_irq(port->irq, tup);
+}
+
+static void tegra_utc_set_termios(struct uart_port *port, struct ktermios *termios,
+ const struct ktermios *old)
+{
+ /* The Tegra UTC clients supports only 8-N-1 configuration without HW flow control */
+ termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
+ termios->c_cflag &= ~(CMSPAR | CRTSCTS);
+ termios->c_cflag |= CS8 | CLOCAL;
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+
+static int tegra_utc_poll_init(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ tegra_utc_hw_init(tup);
+ return 0;
+}
+
+static int tegra_utc_get_poll_char(struct uart_port *port)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ if (tegra_utc_rx_readl(tup, TEGRA_UTC_FIFO_STATUS) & TEGRA_UTC_FIFO_EMPTY)
+ return NO_POLL_CHAR;
+
+ return tegra_utc_rx_readl(tup, TEGRA_UTC_DATA);
+}
+
+static void tegra_utc_put_poll_char(struct uart_port *port, unsigned char ch)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+ u32 val;
+
+ read_poll_timeout_atomic(tegra_utc_tx_readl, val, !(val & TEGRA_UTC_FIFO_FULL),
+ 0, USEC_PER_SEC, false, tup, TEGRA_UTC_FIFO_STATUS);
+
+ tegra_utc_tx_writel(tup, ch, TEGRA_UTC_DATA);
+}
+
+#endif
+
+static const struct uart_ops tegra_utc_uart_ops = {
+ .tx_empty = tegra_utc_tx_empty,
+ .set_mctrl = tegra_utc_set_mctrl,
+ .get_mctrl = tegra_utc_get_mctrl,
+ .stop_tx = tegra_utc_stop_tx,
+ .start_tx = tegra_utc_start_tx,
+ .stop_rx = tegra_utc_stop_rx,
+ .startup = tegra_utc_startup,
+ .shutdown = tegra_utc_shutdown,
+ .set_termios = tegra_utc_set_termios,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_init = tegra_utc_poll_init,
+ .poll_get_char = tegra_utc_get_poll_char,
+ .poll_put_char = tegra_utc_put_poll_char,
+#endif
+};
+
+#if IS_ENABLED(CONFIG_SERIAL_TEGRA_UTC_CONSOLE)
+#define TEGRA_UTC_DEFAULT_FIFO_THRESHOLD 4
+#define TEGRA_UTC_EARLYCON_MAX_BURST_SIZE 128
+
+static void tegra_utc_putc(struct uart_port *port, unsigned char c)
+{
+ writel(c, port->membase + TEGRA_UTC_DATA);
+}
+
+static void tegra_utc_early_write(struct console *con, const char *s, unsigned int n)
+{
+ struct earlycon_device *dev = con->data;
+
+ while (n) {
+ u32 burst_size = TEGRA_UTC_EARLYCON_MAX_BURST_SIZE;
+
+ burst_size -= readl(dev->port.membase + TEGRA_UTC_FIFO_OCCUPANCY);
+ if (n < burst_size)
+ burst_size = n;
+
+ uart_console_write(&dev->port, s, burst_size, tegra_utc_putc);
+
+ n -= burst_size;
+ s += burst_size;
+ }
+}
+
+static int __init tegra_utc_early_console_setup(struct earlycon_device *device, const char *opt)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ /* Configure TX */
+ writel(TEGRA_UTC_COMMAND_FLUSH | TEGRA_UTC_COMMAND_RESET,
+ device->port.membase + TEGRA_UTC_COMMAND);
+ writel(TEGRA_UTC_DEFAULT_FIFO_THRESHOLD, device->port.membase + TEGRA_UTC_FIFO_THRESHOLD);
+
+ /* Clear and mask all the interrupts. */
+ writel(TEGRA_UTC_INTR_COMMON, device->port.membase + TEGRA_UTC_INTR_CLEAR);
+
+ writel(0x0, device->port.membase + TEGRA_UTC_INTR_MASK);
+ writel(0x0, device->port.membase + TEGRA_UTC_INTR_SET);
+
+ /* Enable TX. */
+ writel(TEGRA_UTC_ENABLE_CLIENT_ENABLE, device->port.membase + TEGRA_UTC_ENABLE);
+
+ device->con->write = tegra_utc_early_write;
+
+ return 0;
+}
+OF_EARLYCON_DECLARE(tegra_utc, "nvidia,tegra264-utc", tegra_utc_early_console_setup);
+
+static void tegra_utc_console_putchar(struct uart_port *port, unsigned char ch)
+{
+ struct tegra_utc_port *tup = container_of(port, struct tegra_utc_port, port);
+
+ tegra_utc_tx_writel(tup, ch, TEGRA_UTC_DATA);
+}
+
+static void tegra_utc_console_write_atomic(struct console *cons, struct nbcon_write_context *wctxt)
+{
+ struct tegra_utc_port *tup = container_of(cons, struct tegra_utc_port, console);
+ unsigned int len;
+ char *outbuf;
+
+ if (!nbcon_enter_unsafe(wctxt))
+ return;
+
+ outbuf = wctxt->outbuf;
+ len = wctxt->len;
+
+ while (len) {
+ u32 burst_size = tup->fifosize;
+
+ burst_size -= tegra_utc_tx_readl(tup, TEGRA_UTC_FIFO_OCCUPANCY);
+ if (len < burst_size)
+ burst_size = len;
+
+ uart_console_write(&tup->port, outbuf, burst_size, tegra_utc_console_putchar);
+
+ outbuf += burst_size;
+ len -= burst_size;
+ };
+
+ nbcon_exit_unsafe(wctxt);
+}
+
+static void tegra_utc_console_write_thread(struct console *cons, struct nbcon_write_context *wctxt)
+{
+ struct tegra_utc_port *tup = container_of(cons, struct tegra_utc_port, console);
+ unsigned int len = READ_ONCE(wctxt->len);
+ unsigned int i;
+ u32 val;
+
+ for (i = 0; i < len; i++) {
+ if (!nbcon_enter_unsafe(wctxt))
+ break;
+
+ read_poll_timeout_atomic(tegra_utc_tx_readl, val, !(val & TEGRA_UTC_FIFO_FULL),
+ 0, USEC_PER_SEC, false, tup, TEGRA_UTC_FIFO_STATUS);
+ uart_console_write(&tup->port, wctxt->outbuf + i, 1, tegra_utc_console_putchar);
+
+ if (!nbcon_exit_unsafe(wctxt))
+ break;
+ }
+}
+
+static void tegra_utc_console_device_lock(struct console *cons, unsigned long *flags)
+{
+ struct tegra_utc_port *tup = container_of(cons, struct tegra_utc_port, console);
+ struct uart_port *port = &tup->port;
+
+ __uart_port_lock_irqsave(port, flags);
+}
+
+static void tegra_utc_console_device_unlock(struct console *cons, unsigned long flags)
+{
+ struct tegra_utc_port *tup = container_of(cons, struct tegra_utc_port, console);
+ struct uart_port *port = &tup->port;
+
+ __uart_port_unlock_irqrestore(port, flags);
+}
+
+static int tegra_utc_console_setup(struct console *cons, char *options)
+{
+ struct tegra_utc_port *tup = container_of(cons, struct tegra_utc_port, console);
+
+ tegra_utc_init_tx(tup);
+
+ return 0;
+}
+#endif
+
+static struct uart_driver tegra_utc_driver = {
+ .driver_name = "tegra-utc",
+ .dev_name = "ttyUTC",
+ .nr = TEGRA_UTC_UART_NR,
+};
+
+static int tegra_utc_setup_port(struct device *dev, struct tegra_utc_port *tup)
+{
+ tup->port.dev = dev;
+ tup->port.fifosize = tup->fifosize;
+ tup->port.flags = UPF_BOOT_AUTOCONF;
+ tup->port.iotype = UPIO_MEM;
+ tup->port.ops = &tegra_utc_uart_ops;
+ tup->port.type = PORT_TEGRA_TCU;
+ tup->port.private_data = tup;
+
+#if IS_ENABLED(CONFIG_SERIAL_TEGRA_UTC_CONSOLE)
+ strscpy(tup->console.name, "ttyUTC", sizeof(tup->console.name));
+ tup->console.write_atomic = tegra_utc_console_write_atomic;
+ tup->console.write_thread = tegra_utc_console_write_thread;
+ tup->console.device_lock = tegra_utc_console_device_lock;
+ tup->console.device_unlock = tegra_utc_console_device_unlock;
+ tup->console.device = uart_console_device;
+ tup->console.setup = tegra_utc_console_setup;
+ tup->console.flags = CON_PRINTBUFFER | CON_NBCON;
+ tup->console.data = &tegra_utc_driver;
+#endif
+
+ return uart_read_port_properties(&tup->port);
+}
+
+static int tegra_utc_register_port(struct tegra_utc_port *tup)
+{
+ int ret;
+
+ ret = uart_add_one_port(&tegra_utc_driver, &tup->port);
+ if (ret)
+ return ret;
+
+#if IS_ENABLED(CONFIG_SERIAL_TEGRA_UTC_CONSOLE)
+ register_console(&tup->console);
+#endif
+
+ return 0;
+}
+
+static int tegra_utc_probe(struct platform_device *pdev)
+{
+ const unsigned int *soc_fifosize;
+ struct device *dev = &pdev->dev;
+ struct tegra_utc_port *tup;
+ int ret;
+
+ tup = devm_kzalloc(dev, sizeof(*tup), GFP_KERNEL);
+ if (!tup)
+ return -ENOMEM;
+
+ ret = device_property_read_u32(dev, "tx-threshold", &tup->tx_threshold);
+ if (ret)
+ return dev_err_probe(dev, ret, "missing %s property\n", "tx-threshold");
+
+ ret = device_property_read_u32(dev, "rx-threshold", &tup->rx_threshold);
+ if (ret)
+ return dev_err_probe(dev, ret, "missing %s property\n", "rx-threshold");
+
+ soc_fifosize = device_get_match_data(dev);
+ tup->fifosize = *soc_fifosize;
+
+ tup->tx_base = devm_platform_ioremap_resource_byname(pdev, "tx");
+ if (IS_ERR(tup->tx_base))
+ return PTR_ERR(tup->tx_base);
+
+ tup->rx_base = devm_platform_ioremap_resource_byname(pdev, "rx");
+ if (IS_ERR(tup->rx_base))
+ return PTR_ERR(tup->rx_base);
+
+ ret = tegra_utc_setup_port(dev, tup);
+ if (ret)
+ dev_err_probe(dev, ret, "failed to setup uart port\n");
+
+ platform_set_drvdata(pdev, tup);
+
+ return tegra_utc_register_port(tup);
+}
+
+static void tegra_utc_remove(struct platform_device *pdev)
+{
+ struct tegra_utc_port *tup = platform_get_drvdata(pdev);
+
+#if IS_ENABLED(CONFIG_SERIAL_TEGRA_UTC_CONSOLE)
+ unregister_console(&tup->console);
+#endif
+ uart_remove_one_port(&tegra_utc_driver, &tup->port);
+}
+
+static const unsigned int tegra264_utc_soc = 128;
+
+static const struct of_device_id tegra_utc_of_match[] = {
+ { .compatible = "nvidia,tegra264-utc", .data = &tegra264_utc_soc },
+ {}
+};
+MODULE_DEVICE_TABLE(of, tegra_utc_of_match);
+
+static struct platform_driver tegra_utc_platform_driver = {
+ .probe = tegra_utc_probe,
+ .remove = tegra_utc_remove,
+ .driver = {
+ .name = "tegra-utc",
+ .of_match_table = tegra_utc_of_match,
+ },
+};
+
+static int __init tegra_utc_init(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&tegra_utc_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&tegra_utc_platform_driver);
+ if (ret)
+ uart_unregister_driver(&tegra_utc_driver);
+
+ return ret;
+}
+module_init(tegra_utc_init);
+
+static void __exit tegra_utc_exit(void)
+{
+ platform_driver_unregister(&tegra_utc_platform_driver);
+ uart_unregister_driver(&tegra_utc_driver);
+}
+module_exit(tegra_utc_exit);
+
+MODULE_AUTHOR("Kartik Rajput <kkartik@nvidia.com>");
+MODULE_DESCRIPTION("Tegra UART Trace Controller");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index bd8d92ee7c53..4c703f42680d 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -2220,7 +2220,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
}
info->tx_active = false;
- del_timer(&info->tx_timer);
+ timer_delete(&info->tx_timer);
if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done) {
info->signals &= ~SerialSignal_RTS;
@@ -2375,8 +2375,8 @@ static void shutdown(struct slgt_info *info)
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
- del_timer_sync(&info->tx_timer);
- del_timer_sync(&info->rx_timer);
+ timer_delete_sync(&info->tx_timer);
+ timer_delete_sync(&info->rx_timer);
kfree(info->tx_buf);
info->tx_buf = NULL;
@@ -3955,7 +3955,7 @@ static void tx_stop(struct slgt_info *info)
{
unsigned short val;
- del_timer(&info->tx_timer);
+ timer_delete(&info->tx_timer);
tdma_reset(info);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index f85ce02e4725..6853c4660e7c 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -743,7 +743,7 @@ static void sysrq_detect_reset_sequence(struct sysrq_state *state,
*/
if (value && state->reset_seq_cnt) {
state->reset_canceled = true;
- del_timer(&state->keyreset_timer);
+ timer_delete(&state->keyreset_timer);
}
} else if (value == 0) {
/*
@@ -751,7 +751,7 @@ static void sysrq_detect_reset_sequence(struct sysrq_state *state,
* to be pressed and held for the reset timeout
* to hold.
*/
- del_timer(&state->keyreset_timer);
+ timer_delete(&state->keyreset_timer);
if (--state->reset_seq_cnt == 0)
state->reset_canceled = false;
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
index 1d81eeefb068..75542333c54a 100644
--- a/drivers/tty/tty_audit.c
+++ b/drivers/tty/tty_audit.c
@@ -12,12 +12,14 @@
#include <linux/tty.h>
#include "tty.h"
+#define TTY_AUDIT_BUF_SIZE 4096
+
struct tty_audit_buf {
struct mutex mutex; /* Protects all data below */
dev_t dev; /* The TTY which the data is from */
bool icanon;
size_t valid;
- u8 *data; /* Allocated size N_TTY_BUF_SIZE */
+ u8 *data; /* Allocated size TTY_AUDIT_BUF_SIZE */
};
static struct tty_audit_buf *tty_audit_buf_ref(void)
@@ -37,7 +39,7 @@ static struct tty_audit_buf *tty_audit_buf_alloc(void)
if (!buf)
goto err;
- buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+ buf->data = kmalloc(TTY_AUDIT_BUF_SIZE, GFP_KERNEL);
if (!buf->data)
goto err_buf;
@@ -235,14 +237,14 @@ void tty_audit_add_data(const struct tty_struct *tty, const void *data,
do {
size_t run;
- run = N_TTY_BUF_SIZE - buf->valid;
+ run = TTY_AUDIT_BUF_SIZE - buf->valid;
if (run > size)
run = size;
memcpy(buf->data + buf->valid, data, run);
buf->valid += run;
data += run;
size -= run;
- if (buf->valid == N_TTY_BUF_SIZE)
+ if (buf->valid == TTY_AUDIT_BUF_SIZE)
tty_audit_buf_push(buf);
} while (size != 0);
mutex_unlock(&buf->mutex);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 449dbd216460..ca9b7d7bad2b 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3329,10 +3329,12 @@ EXPORT_SYMBOL(tty_unregister_device);
* __tty_alloc_driver - allocate tty driver
* @lines: count of lines this driver can handle at most
* @owner: module which is responsible for this driver
- * @flags: some of %TTY_DRIVER_ flags, will be set in driver->flags
+ * @flags: some of enum tty_driver_flag, will be set in driver->flags
*
- * This should not be called directly, some of the provided macros should be
- * used instead. Use IS_ERR() and friends on @retval.
+ * This should not be called directly, tty_alloc_driver() should be used
+ * instead.
+ *
+ * Returns: struct tty_driver or a PTR-encoded error (use IS_ERR() and friends).
*/
struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner,
unsigned long flags)
diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c
index 3be428c16260..4e18031a5ca3 100644
--- a/drivers/tty/tty_ldsem.c
+++ b/drivers/tty/tty_ldsem.c
@@ -367,23 +367,6 @@ int __sched ldsem_down_write(struct ld_semaphore *sem, long timeout)
}
/*
- * trylock for writing -- returns 1 if successful, 0 if contention
- */
-int ldsem_down_write_trylock(struct ld_semaphore *sem)
-{
- long count = atomic_long_read(&sem->count);
-
- while ((count & LDSEM_ACTIVE_MASK) == 0) {
- if (atomic_long_try_cmpxchg(&sem->count, &count, count + LDSEM_WRITE_BIAS)) {
- rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_);
- lock_acquired(&sem->dep_map, _RET_IP_);
- return 1;
- }
- }
- return 0;
-}
-
-/*
* release a read lock
*/
void ldsem_up_read(struct ld_semaphore *sem)
diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c
index 5b625f20233b..7ac3048377d5 100644
--- a/drivers/tty/vcc.c
+++ b/drivers/tty/vcc.c
@@ -683,8 +683,8 @@ static void vcc_remove(struct vio_dev *vdev)
{
struct vcc_port *port = dev_get_drvdata(&vdev->dev);
- del_timer_sync(&port->rx_timer);
- del_timer_sync(&port->tx_timer);
+ timer_delete_sync(&port->rx_timer);
+ timer_delete_sync(&port->tx_timer);
/* If there's a process with the device open, do a synchronous
* hangup of the TTY. This *may* cause the process to call close
@@ -700,7 +700,7 @@ static void vcc_remove(struct vio_dev *vdev)
tty_unregister_device(vcc_tty_driver, port->index);
- del_timer_sync(&port->vio.timer);
+ timer_delete_sync(&port->vio.timer);
vio_ldc_free(&port->vio);
sysfs_remove_group(&vdev->dev.kobj, &vcc_attribute_group);
dev_set_drvdata(&vdev->dev, NULL);
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 804355da46f5..ae92e6a50a65 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -275,7 +275,7 @@ static DEFINE_TIMER(kd_mksound_timer, kd_nosound);
void kd_mksound(unsigned int hz, unsigned int ticks)
{
- del_timer_sync(&kd_mksound_timer);
+ timer_delete_sync(&kd_mksound_timer);
input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index be5564ed8c01..f5642b3038e4 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4501,7 +4501,7 @@ void do_blank_screen(int entering_gfx)
}
hide_cursor(vc);
- del_timer_sync(&console_timer);
+ timer_delete_sync(&console_timer);
blank_timer_expired = 0;
save_screen(vc);
@@ -4606,7 +4606,7 @@ void poke_blanked_console(void)
/* This isn't perfectly race free, but a race here would be mostly harmless,
* at worst, we'll do a spurious blank and it's unlikely
*/
- del_timer(&console_timer);
+ timer_delete(&console_timer);
blank_timer_expired = 0;
if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 47d06af33747..c6b9ad12e8fe 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -597,7 +597,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
timer_setup_on_stack(&timer.timer, cxacru_timeout_kill, 0);
mod_timer(&timer.timer, jiffies + msecs_to_jiffies(CMD_TIMEOUT));
wait_for_completion(done);
- del_timer_sync(&timer.timer);
+ timer_delete_sync(&timer.timer);
destroy_timer_on_stack(&timer.timer);
if (actual_length)
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 973548b5c15c..27e3d35ee7dd 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -612,7 +612,7 @@ static void speedtch_handle_int(struct urb *int_urb)
}
if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) {
- del_timer(&instance->status_check_timer);
+ timer_delete(&instance->status_check_timer);
atm_info(usbatm, "DSL line goes up\n");
} else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) {
atm_info(usbatm, "DSL line goes down\n");
@@ -688,7 +688,7 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de
atm_dbg(usbatm, "%s entered\n", __func__);
- del_timer_sync(&instance->status_check_timer);
+ timer_delete_sync(&instance->status_check_timer);
/*
* Since resubmit_timer and int_urb can schedule themselves and
@@ -697,14 +697,14 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de
instance->int_urb = NULL; /* signal shutdown */
mb();
usb_kill_urb(int_urb);
- del_timer_sync(&instance->resubmit_timer);
+ timer_delete_sync(&instance->resubmit_timer);
/*
* At this point, speedtch_handle_int and speedtch_resubmit_int
* can run or be running, but instance->int_urb == NULL means that
* they will not reschedule
*/
usb_kill_urb(int_urb);
- del_timer_sync(&instance->resubmit_timer);
+ timer_delete_sync(&instance->resubmit_timer);
usb_free_urb(int_urb);
flush_work(&instance->status_check_work);
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index d1e622bb1406..a6a05e85ef8c 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -1237,8 +1237,8 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++)
usb_kill_urb(instance->urbs[i]);
- del_timer_sync(&instance->rx_channel.delay);
- del_timer_sync(&instance->tx_channel.delay);
+ timer_delete_sync(&instance->rx_channel.delay);
+ timer_delete_sync(&instance->tx_channel.delay);
/* turn usbatm_[rt]x_process into something close to a no-op */
/* no need to take the spinlock */
diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
index fd1beb10bba7..694aa1457739 100644
--- a/drivers/usb/cdns3/cdns3-gadget.c
+++ b/drivers/usb/cdns3/cdns3-gadget.c
@@ -3468,7 +3468,7 @@ __must_hold(&cdns->lock)
return 0;
}
-static int cdns3_gadget_resume(struct cdns *cdns, bool hibernated)
+static int cdns3_gadget_resume(struct cdns *cdns, bool lost_power)
{
struct cdns3_device *priv_dev = cdns->gadget_dev;
@@ -3476,7 +3476,7 @@ static int cdns3_gadget_resume(struct cdns *cdns, bool hibernated)
return 0;
cdns3_gadget_config(priv_dev);
- if (hibernated)
+ if (lost_power)
writel(USB_CONF_DEVEN, &priv_dev->regs->usb_conf);
return 0;
diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
index 040bb91e9c01..302ebf6d8e53 100644
--- a/drivers/usb/cdns3/cdns3-ti.c
+++ b/drivers/usb/cdns3/cdns3-ti.c
@@ -58,6 +58,7 @@ struct cdns_ti {
unsigned vbus_divider:1;
struct clk *usb2_refclk;
struct clk *lpm_clk;
+ int usb2_refclk_rate_code;
};
static const int cdns_ti_rate_table[] = { /* in KHZ */
@@ -98,15 +99,50 @@ static const struct of_dev_auxdata cdns_ti_auxdata[] = {
{},
};
+static void cdns_ti_reset_and_init_hw(struct cdns_ti *data)
+{
+ u32 reg;
+
+ /* assert RESET */
+ reg = cdns_ti_readl(data, USBSS_W1);
+ reg &= ~USBSS_W1_PWRUP_RST;
+ cdns_ti_writel(data, USBSS_W1, reg);
+
+ /* set static config */
+ reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
+ reg &= ~USBSS1_STATIC_PLL_REF_SEL_MASK;
+ reg |= data->usb2_refclk_rate_code << USBSS1_STATIC_PLL_REF_SEL_SHIFT;
+
+ reg &= ~USBSS1_STATIC_VBUS_SEL_MASK;
+ if (data->vbus_divider)
+ reg |= 1 << USBSS1_STATIC_VBUS_SEL_SHIFT;
+
+ cdns_ti_writel(data, USBSS_STATIC_CONFIG, reg);
+ reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
+
+ /* set USB2_ONLY mode if requested */
+ reg = cdns_ti_readl(data, USBSS_W1);
+ if (data->usb2_only)
+ reg |= USBSS_W1_USB2_ONLY;
+
+ /* set default modestrap */
+ reg |= USBSS_W1_MODESTRAP_SEL;
+ reg &= ~USBSS_W1_MODESTRAP_MASK;
+ reg |= USBSS_MODESTRAP_MODE_NONE << USBSS_W1_MODESTRAP_SHIFT;
+ cdns_ti_writel(data, USBSS_W1, reg);
+
+ /* de-assert RESET */
+ reg |= USBSS_W1_PWRUP_RST;
+ cdns_ti_writel(data, USBSS_W1, reg);
+}
+
static int cdns_ti_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = pdev->dev.of_node;
struct cdns_ti *data;
- int error;
- u32 reg;
- int rate_code, i;
unsigned long rate;
+ int error, i;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -146,7 +182,17 @@ static int cdns_ti_probe(struct platform_device *pdev)
return -EINVAL;
}
- rate_code = i;
+ data->usb2_refclk_rate_code = i;
+ data->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
+ data->usb2_only = device_property_read_bool(dev, "ti,usb2-only");
+
+ /*
+ * The call below to pm_runtime_get_sync() MIGHT reset hardware, if it
+ * detects it as uninitialised. We want to enforce a reset at probe,
+ * and so do it manually here. This means the first runtime_resume()
+ * will be a no-op.
+ */
+ cdns_ti_reset_and_init_hw(data);
pm_runtime_enable(dev);
error = pm_runtime_get_sync(dev);
@@ -155,40 +201,6 @@ static int cdns_ti_probe(struct platform_device *pdev)
goto err;
}
- /* assert RESET */
- reg = cdns_ti_readl(data, USBSS_W1);
- reg &= ~USBSS_W1_PWRUP_RST;
- cdns_ti_writel(data, USBSS_W1, reg);
-
- /* set static config */
- reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
- reg &= ~USBSS1_STATIC_PLL_REF_SEL_MASK;
- reg |= rate_code << USBSS1_STATIC_PLL_REF_SEL_SHIFT;
-
- reg &= ~USBSS1_STATIC_VBUS_SEL_MASK;
- data->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
- if (data->vbus_divider)
- reg |= 1 << USBSS1_STATIC_VBUS_SEL_SHIFT;
-
- cdns_ti_writel(data, USBSS_STATIC_CONFIG, reg);
- reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
-
- /* set USB2_ONLY mode if requested */
- reg = cdns_ti_readl(data, USBSS_W1);
- data->usb2_only = device_property_read_bool(dev, "ti,usb2-only");
- if (data->usb2_only)
- reg |= USBSS_W1_USB2_ONLY;
-
- /* set default modestrap */
- reg |= USBSS_W1_MODESTRAP_SEL;
- reg &= ~USBSS_W1_MODESTRAP_MASK;
- reg |= USBSS_MODESTRAP_MODE_NONE << USBSS_W1_MODESTRAP_SHIFT;
- cdns_ti_writel(data, USBSS_W1, reg);
-
- /* de-assert RESET */
- reg |= USBSS_W1_PWRUP_RST;
- cdns_ti_writel(data, USBSS_W1, reg);
-
error = of_platform_populate(node, NULL, cdns_ti_auxdata, dev);
if (error) {
dev_err(dev, "failed to create children: %d\n", error);
@@ -224,6 +236,24 @@ static void cdns_ti_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
}
+static int cdns_ti_runtime_resume(struct device *dev)
+{
+ const u32 mask = USBSS_W1_PWRUP_RST | USBSS_W1_MODESTRAP_SEL;
+ struct cdns_ti *data = dev_get_drvdata(dev);
+ u32 w1;
+
+ w1 = cdns_ti_readl(data, USBSS_W1);
+ if ((w1 & mask) != mask)
+ cdns_ti_reset_and_init_hw(data);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cdns_ti_pm_ops = {
+ RUNTIME_PM_OPS(NULL, cdns_ti_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+
static const struct of_device_id cdns_ti_of_match[] = {
{ .compatible = "ti,j721e-usb", },
{ .compatible = "ti,am64-usb", },
@@ -237,6 +267,7 @@ static struct platform_driver cdns_ti_driver = {
.driver = {
.name = "cdns3-ti",
.of_match_table = cdns_ti_of_match,
+ .pm = pm_ptr(&cdns_ti_pm_ops),
},
};
diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
index 97edf767ecee..87f310841735 100644
--- a/drivers/usb/cdns3/cdnsp-gadget.c
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
@@ -1974,7 +1974,7 @@ static int cdnsp_gadget_suspend(struct cdns *cdns, bool do_wakeup)
return 0;
}
-static int cdnsp_gadget_resume(struct cdns *cdns, bool hibernated)
+static int cdnsp_gadget_resume(struct cdns *cdns, bool lost_power)
{
struct cdnsp_device *pdev = cdns->gadget_dev;
enum usb_device_speed max_speed;
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
index 98980a23e1c2..1243a5cea91b 100644
--- a/drivers/usb/cdns3/core.c
+++ b/drivers/usb/cdns3/core.c
@@ -524,11 +524,12 @@ EXPORT_SYMBOL_GPL(cdns_suspend);
int cdns_resume(struct cdns *cdns)
{
+ bool power_lost = cdns_power_is_lost(cdns);
enum usb_role real_role;
bool role_changed = false;
int ret = 0;
- if (cdns_power_is_lost(cdns)) {
+ if (power_lost) {
if (!cdns->role_sw) {
real_role = cdns_hw_role_state_machine(cdns);
if (real_role != cdns->role) {
@@ -551,7 +552,7 @@ int cdns_resume(struct cdns *cdns)
}
if (cdns->roles[cdns->role]->resume)
- cdns->roles[cdns->role]->resume(cdns, cdns_power_is_lost(cdns));
+ cdns->roles[cdns->role]->resume(cdns, power_lost);
return 0;
}
diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h
index 57d47348dc19..921cccf1ca9d 100644
--- a/drivers/usb/cdns3/core.h
+++ b/drivers/usb/cdns3/core.h
@@ -30,7 +30,7 @@ struct cdns_role_driver {
int (*start)(struct cdns *cdns);
void (*stop)(struct cdns *cdns);
int (*suspend)(struct cdns *cdns, bool do_wakeup);
- int (*resume)(struct cdns *cdns, bool hibernated);
+ int (*resume)(struct cdns *cdns, bool lost_power);
const char *name;
#define CDNS_ROLE_STATE_INACTIVE 0
#define CDNS_ROLE_STATE_ACTIVE 1
diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c
index 7ba760ee62e3..f0df114c2b53 100644
--- a/drivers/usb/cdns3/host.c
+++ b/drivers/usb/cdns3/host.c
@@ -138,6 +138,16 @@ static void cdns_host_exit(struct cdns *cdns)
cdns_drd_host_off(cdns);
}
+static int cdns_host_resume(struct cdns *cdns, bool power_lost)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(cdns->host_dev);
+ struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
+
+ priv->power_lost = power_lost;
+
+ return 0;
+}
+
int cdns_host_init(struct cdns *cdns)
{
struct cdns_role_driver *rdrv;
@@ -148,6 +158,7 @@ int cdns_host_init(struct cdns *cdns)
rdrv->start = __cdns_host_init;
rdrv->stop = cdns_host_exit;
+ rdrv->resume = cdns_host_resume;
rdrv->state = CDNS_ROLE_STATE_INACTIVE;
rdrv->name = "host";
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 1394881fde5f..6243d8005f5d 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -440,7 +440,7 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
else if (data->oc_pol_configured)
reg &= ~MX6_BM_OVER_CUR_POLARITY;
}
- /* If the polarity is not set keep it as setup by the bootlader */
+ /* If the polarity is not set keep it as setup by the bootloader */
if (data->pwr_pol == 1)
reg |= MX6_BM_PWR_POLARITY;
writel(reg, usbmisc->base + data->index * 4);
@@ -645,7 +645,7 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
else if (data->oc_pol_configured)
reg &= ~MX6_BM_OVER_CUR_POLARITY;
}
- /* If the polarity is not set keep it as setup by the bootlader */
+ /* If the polarity is not set keep it as setup by the bootloader */
if (data->pwr_pol == 1)
reg |= MX6_BM_PWR_POLARITY;
writel(reg, usbmisc->base);
@@ -939,7 +939,7 @@ static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data)
else if (data->oc_pol_configured)
reg &= ~MX6_BM_OVER_CUR_POLARITY;
}
- /* If the polarity is not set keep it as setup by the bootlader */
+ /* If the polarity is not set keep it as setup by the bootloader */
if (data->pwr_pol == 1)
reg |= MX6_BM_PWR_POLARITY;
@@ -1185,7 +1185,7 @@ int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup)
if (usbmisc->ops->hsic_set_clk && data->hsic)
ret = usbmisc->ops->hsic_set_clk(data, false);
if (ret) {
- dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
+ dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
return ret;
}
@@ -1224,7 +1224,7 @@ int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup)
if (usbmisc->ops->hsic_set_clk && data->hsic)
ret = usbmisc->ops->hsic_set_clk(data, true);
if (ret) {
- dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
+ dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
goto hsic_set_clk_fail;
}
diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c
index aa710b50791b..1e36be2a28fd 100644
--- a/drivers/usb/common/usb-conn-gpio.c
+++ b/drivers/usb/common/usb-conn-gpio.c
@@ -158,7 +158,7 @@ static int usb_conn_psy_register(struct usb_conn_info *info)
struct device *dev = info->dev;
struct power_supply_desc *desc = &info->desc;
struct power_supply_config cfg = {
- .of_node = dev->of_node,
+ .fwnode = dev_fwnode(dev),
};
desc->name = "usb-charger";
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index f7bf8d1de3ad..13bd4ec4ea5f 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -64,6 +64,37 @@ static void usb_parse_ssp_isoc_endpoint_companion(struct device *ddev,
memcpy(&ep->ssp_isoc_ep_comp, desc, USB_DT_SSP_ISOC_EP_COMP_SIZE);
}
+static void usb_parse_eusb2_isoc_endpoint_companion(struct device *ddev,
+ int cfgno, int inum, int asnum, struct usb_host_endpoint *ep,
+ unsigned char *buffer, int size)
+{
+ struct usb_eusb2_isoc_ep_comp_descriptor *desc;
+ struct usb_descriptor_header *h;
+
+ /*
+ * eUSB2 isochronous endpoint companion descriptor for this endpoint
+ * shall be declared before the next endpoint or interface descriptor
+ */
+ while (size >= USB_DT_EUSB2_ISOC_EP_COMP_SIZE) {
+ h = (struct usb_descriptor_header *)buffer;
+
+ if (h->bDescriptorType == USB_DT_EUSB2_ISOC_ENDPOINT_COMP) {
+ desc = (struct usb_eusb2_isoc_ep_comp_descriptor *)buffer;
+ ep->eusb2_isoc_ep_comp = *desc;
+ return;
+ }
+ if (h->bDescriptorType == USB_DT_ENDPOINT ||
+ h->bDescriptorType == USB_DT_INTERFACE)
+ break;
+
+ buffer += h->bLength;
+ size -= h->bLength;
+ }
+
+ dev_notice(ddev, "No eUSB2 isoc ep %d companion for config %d interface %d altsetting %d\n",
+ ep->desc.bEndpointAddress, cfgno, inum, asnum);
+}
+
static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
int inum, int asnum, struct usb_host_endpoint *ep,
unsigned char *buffer, int size)
@@ -258,8 +289,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
int n, i, j, retval;
unsigned int maxp;
const unsigned short *maxpacket_maxes;
+ u16 bcdUSB;
d = (struct usb_endpoint_descriptor *) buffer;
+ bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB);
buffer += d->bLength;
size -= d->bLength;
@@ -409,15 +442,17 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
/*
* Validate the wMaxPacketSize field.
- * Some devices have isochronous endpoints in altsetting 0;
- * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0
- * (see the end of section 5.6.3), so don't warn about them.
+ * eUSB2 devices (see USB 2.0 Double Isochronous IN ECN 9.6.6 Endpoint)
+ * and devices with isochronous endpoints in altsetting 0 (see USB 2.0
+ * end of section 5.6.3) have wMaxPacketSize = 0.
+ * So don't warn about those.
*/
maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize);
- if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) {
+
+ if (maxp == 0 && bcdUSB != 0x0220 &&
+ !(usb_endpoint_xfer_isoc(d) && asnum == 0))
dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n",
cfgno, inum, asnum, d->bEndpointAddress);
- }
/* Find the highest legal maxpacket size for this endpoint */
i = 0; /* additional transactions per microframe */
@@ -465,6 +500,12 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
maxp);
}
+ /* Parse a possible eUSB2 periodic endpoint companion descriptor */
+ if (bcdUSB == 0x0220 && d->wMaxPacketSize == 0 &&
+ (usb_endpoint_xfer_isoc(d) || usb_endpoint_xfer_int(d)))
+ usb_parse_eusb2_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
+ endpoint, buffer, size);
+
/* Parse a possible SuperSpeed endpoint companion descriptor */
if (udev->speed >= USB_SPEED_SUPER)
usb_parse_ss_endpoint_companion(ddev, cfgno,
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index a75cf1f6d741..a63c793bac21 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -842,7 +842,7 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
} else { /* Status URB */
if (!hcd->uses_new_polling)
- del_timer (&hcd->rh_timer);
+ timer_delete(&hcd->rh_timer);
if (urb == hcd->status_urb) {
hcd->status_urb = NULL;
usb_hcd_unlink_urb_from_ep(hcd, urb);
@@ -1609,7 +1609,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
if (retval == 0)
retval = -EINPROGRESS;
else if (retval != -EIDRM && retval != -EBUSY)
- dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n",
+ dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
urb, retval);
usb_put_dev(udev);
}
@@ -1786,7 +1786,7 @@ rescan:
/* kick hcd */
unlink1(hcd, urb, -ESHUTDOWN);
dev_dbg (hcd->self.controller,
- "shutdown urb %pK ep%d%s-%s\n",
+ "shutdown urb %p ep%d%s-%s\n",
urb, usb_endpoint_num(&ep->desc),
is_in ? "in" : "out",
usb_ep_type_string(usb_endpoint_type(&ep->desc)));
@@ -2768,14 +2768,14 @@ static void usb_stop_hcd(struct usb_hcd *hcd)
{
hcd->rh_pollable = 0;
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
hcd->driver->stop(hcd);
hcd->state = HC_STATE_HALT;
/* In case the HCD restarted the timer, stop it again. */
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
}
/**
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index dcba4281ea48..0e1dd6ef60a7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1385,7 +1385,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
}
/* Stop hub_wq and related activity */
- del_timer_sync(&hub->irq_urb_retry);
+ timer_delete_sync(&hub->irq_urb_retry);
usb_kill_urb(hub->urb);
if (hub->has_indicators)
cancel_delayed_work_sync(&hub->leds);
@@ -4708,8 +4708,6 @@ void usb_ep0_reinit(struct usb_device *udev)
}
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
-#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
-
static int hub_set_address(struct usb_device *udev, int devnum)
{
int retval;
@@ -4733,7 +4731,7 @@ static int hub_set_address(struct usb_device *udev, int devnum)
if (hcd->driver->address_device)
retval = hcd->driver->address_device(hcd, udev, timeout_ms);
else
- retval = usb_control_msg(udev, usb_sndaddr0pipe(),
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_ADDRESS, 0, devnum, 0,
NULL, 0, timeout_ms);
if (retval == 0) {
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 7576920e2d5a..5e52a35486af 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -376,7 +376,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (!urb || !urb->complete)
return -EINVAL;
if (urb->hcpriv) {
- WARN_ONCE(1, "URB %pK submitted while active\n", urb);
+ WARN_ONCE(1, "URB %p submitted while active\n", urb);
return -EBUSY;
}
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 9919ab725d54..c3d24312db0f 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -43,6 +43,7 @@ int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
/* Backup global regs */
gr = &hsotg->gr_backup;
+ gr->gintsts = dwc2_readl(hsotg, GINTSTS);
gr->gotgctl = dwc2_readl(hsotg, GOTGCTL);
gr->gintmsk = dwc2_readl(hsotg, GINTMSK);
gr->gahbcfg = dwc2_readl(hsotg, GAHBCFG);
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 2bd74f3033ed..34127b890b2a 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -667,6 +667,7 @@ struct dwc2_hw_params {
/**
* struct dwc2_gregs_backup - Holds global registers state before
* entering partial power down
+ * @gintsts: Backup of GINTSTS register
* @gotgctl: Backup of GOTGCTL register
* @gintmsk: Backup of GINTMSK register
* @gahbcfg: Backup of GAHBCFG register
@@ -683,6 +684,7 @@ struct dwc2_hw_params {
* @valid: True if registers values backuped.
*/
struct dwc2_gregs_backup {
+ u32 gintsts;
u32 gotgctl;
u32 gintmsk;
u32 gahbcfg;
@@ -1127,6 +1129,9 @@ struct dwc2_hsotg {
#define DWC2_FS_IOT_ID 0x55310000
#define DWC2_HS_IOT_ID 0x55320000
+#define DWC2_RESTORE_DCTL BIT(0)
+#define DWC2_RESTORE_DCFG BIT(1)
+
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
union dwc2_hcd_internal_flags {
u32 d32;
@@ -1420,7 +1425,7 @@ int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
#define dwc2_is_device_connected(hsotg) (hsotg->connected)
#define dwc2_is_device_enabled(hsotg) (hsotg->enabled)
int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
-int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup);
+int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, unsigned int flags);
int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg);
int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
int rem_wakeup, int reset);
@@ -1435,6 +1440,9 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg);
+int dwc2_gadget_backup_critical_registers(struct dwc2_hsotg *hsotg);
+int dwc2_gadget_restore_critical_registers(struct dwc2_hsotg *hsotg,
+ unsigned int flags);
static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg)
{ hsotg->fifo_map = 0; }
#else
@@ -1459,7 +1467,7 @@ static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
{ return 0; }
static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg,
- int remote_wakeup)
+ unsigned int flags)
{ return 0; }
static inline int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
{ return 0; }
@@ -1482,6 +1490,11 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
{ return 0; }
static inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {}
static inline void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg) {}
+static inline int dwc2_gadget_backup_critical_registers(struct dwc2_hsotg *hsotg)
+{ return 0; }
+static inline int dwc2_gadget_restore_critical_registers(struct dwc2_hsotg *hsotg,
+ unsigned int flags)
+{ return 0; }
static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) {}
#endif
@@ -1505,6 +1518,8 @@ int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg);
void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup);
bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2);
+int dwc2_host_backup_critical_registers(struct dwc2_hsotg *hsotg);
+int dwc2_host_restore_critical_registers(struct dwc2_hsotg *hsotg);
static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg)
{ schedule_work(&hsotg->phy_reset_work); }
#else
@@ -1544,6 +1559,10 @@ static inline void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg,
int rem_wakeup) {}
static inline bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2)
{ return false; }
+static inline int dwc2_host_backup_critical_registers(struct dwc2_hsotg *hsotg)
+{ return 0; }
+static inline int dwc2_host_restore_critical_registers(struct dwc2_hsotg *hsotg)
+{ return 0; }
static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) {}
#endif
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index bd4c788f03bc..300ea4969f0c 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -5204,11 +5204,11 @@ int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
* if controller power were disabled.
*
* @hsotg: Programming view of the DWC_otg controller
- * @remote_wakeup: Indicates whether resume is initiated by Device or Host.
+ * @flags: Defines which registers should be restored.
*
* Return: 0 if successful, negative error code otherwise
*/
-int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup)
+int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, unsigned int flags)
{
struct dwc2_dregs_backup *dr;
int i;
@@ -5224,7 +5224,10 @@ int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup)
}
dr->valid = false;
- if (!remote_wakeup)
+ if (flags & DWC2_RESTORE_DCFG)
+ dwc2_writel(hsotg, dr->dcfg, DCFG);
+
+ if (flags & DWC2_RESTORE_DCTL)
dwc2_writel(hsotg, dr->dctl, DCTL);
dwc2_writel(hsotg, dr->daintmsk, DAINTMSK);
@@ -5310,6 +5313,49 @@ void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "GREFCLK=0x%08x\n", dwc2_readl(hsotg, GREFCLK));
}
+int dwc2_gadget_backup_critical_registers(struct dwc2_hsotg *hsotg)
+{
+ int ret;
+
+ /* Backup all registers */
+ ret = dwc2_backup_global_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to backup global registers\n",
+ __func__);
+ return ret;
+ }
+
+ ret = dwc2_backup_device_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to backup device registers\n",
+ __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+int dwc2_gadget_restore_critical_registers(struct dwc2_hsotg *hsotg,
+ unsigned int flags)
+{
+ int ret;
+
+ ret = dwc2_restore_global_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to restore registers\n",
+ __func__);
+ return ret;
+ }
+ ret = dwc2_restore_device_registers(hsotg, flags);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to restore device registers\n",
+ __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* dwc2_gadget_enter_hibernation() - Put controller in Hibernation.
*
@@ -5327,18 +5373,9 @@ int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
/* Change to L2(suspend) state */
hsotg->lx_state = DWC2_L2;
dev_dbg(hsotg->dev, "Start of hibernation completed\n");
- ret = dwc2_backup_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup global registers\n",
- __func__);
- return ret;
- }
- ret = dwc2_backup_device_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup device registers\n",
- __func__);
+ ret = dwc2_gadget_backup_critical_registers(hsotg);
+ if (ret)
return ret;
- }
gpwrdn = GPWRDN_PWRDNRSTN;
udelay(10);
@@ -5415,6 +5452,7 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
u32 gpwrdn;
u32 dctl;
int ret = 0;
+ unsigned int flags = 0;
struct dwc2_gregs_backup *gr;
struct dwc2_dregs_backup *dr;
@@ -5477,6 +5515,7 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
dctl = dwc2_readl(hsotg, DCTL);
dctl |= DCTL_PWRONPRGDONE;
dwc2_writel(hsotg, dctl, DCTL);
+ flags |= DWC2_RESTORE_DCTL;
}
/* Wait for interrupts which must be cleared */
mdelay(2);
@@ -5484,20 +5523,9 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
dwc2_writel(hsotg, 0xffffffff, GINTSTS);
/* Restore global registers */
- ret = dwc2_restore_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore registers\n",
- __func__);
- return ret;
- }
-
- /* Restore device registers */
- ret = dwc2_restore_device_registers(hsotg, rem_wakeup);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore device registers\n",
- __func__);
+ ret = dwc2_gadget_restore_critical_registers(hsotg, flags);
+ if (ret)
return ret;
- }
if (rem_wakeup) {
mdelay(10);
@@ -5531,19 +5559,9 @@ int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "Entering device partial power down started.\n");
/* Backup all registers */
- ret = dwc2_backup_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup global registers\n",
- __func__);
- return ret;
- }
-
- ret = dwc2_backup_device_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup device registers\n",
- __func__);
+ ret = dwc2_gadget_backup_critical_registers(hsotg);
+ if (ret)
return ret;
- }
/*
* Clear any pending interrupts since dwc2 will not be able to
@@ -5590,11 +5608,8 @@ int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
{
u32 pcgcctl;
u32 dctl;
- struct dwc2_dregs_backup *dr;
int ret = 0;
- dr = &hsotg->dr_backup;
-
dev_dbg(hsotg->dev, "Exiting device partial Power Down started.\n");
pcgcctl = dwc2_readl(hsotg, PCGCTL);
@@ -5611,21 +5626,10 @@ int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
udelay(100);
if (restore) {
- ret = dwc2_restore_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore registers\n",
- __func__);
- return ret;
- }
- /* Restore DCFG */
- dwc2_writel(hsotg, dr->dcfg, DCFG);
-
- ret = dwc2_restore_device_registers(hsotg, 0);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore device registers\n",
- __func__);
+ ret = dwc2_gadget_restore_critical_registers(hsotg, DWC2_RESTORE_DCTL |
+ DWC2_RESTORE_DCFG);
+ if (ret)
return ret;
- }
}
/* Set the Power-On Programming done bit */
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 8c3941ecaaf5..60ef8092259a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5081,7 +5081,7 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg)
cancel_work_sync(&hsotg->phy_reset_work);
- del_timer(&hsotg->wkp_timer);
+ timer_delete(&hsotg->wkp_timer);
}
static void dwc2_hcd_release(struct dwc2_hsotg *hsotg)
@@ -5474,6 +5474,49 @@ int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
return 0;
}
+int dwc2_host_backup_critical_registers(struct dwc2_hsotg *hsotg)
+{
+ int ret;
+
+ /* Backup all registers */
+ ret = dwc2_backup_global_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to backup global registers\n",
+ __func__);
+ return ret;
+ }
+
+ ret = dwc2_backup_host_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to backup host registers\n",
+ __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+int dwc2_host_restore_critical_registers(struct dwc2_hsotg *hsotg)
+{
+ int ret;
+
+ ret = dwc2_restore_global_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to restore registers\n",
+ __func__);
+ return ret;
+ }
+
+ ret = dwc2_restore_host_registers(hsotg);
+ if (ret) {
+ dev_err(hsotg->dev, "%s: failed to restore host registers\n",
+ __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* dwc2_host_enter_hibernation() - Put controller in Hibernation.
*
@@ -5489,18 +5532,9 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
u32 gpwrdn;
dev_dbg(hsotg->dev, "Preparing host for hibernation\n");
- ret = dwc2_backup_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup global registers\n",
- __func__);
- return ret;
- }
- ret = dwc2_backup_host_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup host registers\n",
- __func__);
+ ret = dwc2_host_backup_critical_registers(hsotg);
+ if (ret)
return ret;
- }
/* Enter USB Suspend Mode */
hprt0 = dwc2_readl(hsotg, HPRT0);
@@ -5694,20 +5728,9 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
dwc2_writel(hsotg, 0xffffffff, GINTSTS);
/* Restore global registers */
- ret = dwc2_restore_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore registers\n",
- __func__);
+ ret = dwc2_host_restore_critical_registers(hsotg);
+ if (ret)
return ret;
- }
-
- /* Restore host registers */
- ret = dwc2_restore_host_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore host registers\n",
- __func__);
- return ret;
- }
if (rem_wakeup) {
dwc2_hcd_rem_wakeup(hsotg);
@@ -5774,19 +5797,9 @@ int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg)
dev_warn(hsotg->dev, "Suspend wasn't generated\n");
/* Backup all registers */
- ret = dwc2_backup_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup global registers\n",
- __func__);
- return ret;
- }
-
- ret = dwc2_backup_host_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to backup host registers\n",
- __func__);
+ ret = dwc2_host_backup_critical_registers(hsotg);
+ if (ret)
return ret;
- }
/*
* Clear any pending interrupts since dwc2 will not be able to
@@ -5855,19 +5868,9 @@ int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
udelay(100);
if (restore) {
- ret = dwc2_restore_global_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore registers\n",
- __func__);
- return ret;
- }
-
- ret = dwc2_restore_host_registers(hsotg);
- if (ret) {
- dev_err(hsotg->dev, "%s: failed to restore host registers\n",
- __func__);
+ ret = dwc2_host_restore_critical_registers(hsotg);
+ if (ret)
return ret;
- }
}
/* Drive resume signaling and exit suspend mode on the port. */
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 2a542a99ec44..b0098792dd22 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -1302,7 +1302,7 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
}
/* Cancel pending unreserve; if canceled OK, unreserve was pending */
- if (del_timer(&qh->unreserve_timer))
+ if (timer_delete(&qh->unreserve_timer))
WARN_ON(!qh->unreserve_pending);
/*
@@ -1614,7 +1614,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
{
/* Make sure any unreserve work is finished. */
- if (del_timer_sync(&qh->unreserve_timer)) {
+ if (timer_delete_sync(&qh->unreserve_timer)) {
unsigned long flags;
spin_lock_irqsave(&hsotg->lock, flags);
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 91c80a92d9b8..12b4dc07d08a 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -685,6 +685,14 @@ static int __maybe_unused dwc2_suspend(struct device *dev)
regulator_disable(dwc2->usb33d);
}
+ if (is_device_mode)
+ ret = dwc2_gadget_backup_critical_registers(dwc2);
+ else
+ ret = dwc2_host_backup_critical_registers(dwc2);
+
+ if (ret)
+ return ret;
+
if (dwc2->ll_hw_enabled &&
(is_device_mode || dwc2_host_can_poweroff_phy(dwc2))) {
ret = __dwc2_lowlevel_hw_disable(dwc2);
@@ -694,6 +702,24 @@ static int __maybe_unused dwc2_suspend(struct device *dev)
return ret;
}
+static int dwc2_restore_critical_registers(struct dwc2_hsotg *hsotg)
+{
+ struct dwc2_gregs_backup *gr;
+
+ gr = &hsotg->gr_backup;
+
+ if (!gr->valid) {
+ dev_err(hsotg->dev, "No valid register backup, failed to restore\n");
+ return -EINVAL;
+ }
+
+ if (gr->gintsts & GINTSTS_CURMODE_HOST)
+ return dwc2_host_restore_critical_registers(hsotg);
+
+ return dwc2_gadget_restore_critical_registers(hsotg, DWC2_RESTORE_DCTL |
+ DWC2_RESTORE_DCFG);
+}
+
static int __maybe_unused dwc2_resume(struct device *dev)
{
struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
@@ -706,6 +732,18 @@ static int __maybe_unused dwc2_resume(struct device *dev)
}
dwc2->phy_off_for_suspend = false;
+ /*
+ * During suspend it's possible that the power domain for the
+ * DWC2 controller is disabled and all register values get lost.
+ * In case the GUSBCFG register is not initialized, it's clear the
+ * registers must be restored.
+ */
+ if (!(dwc2_readl(dwc2, GUSBCFG) & GUSBCFG_TOUTCAL_MASK)) {
+ ret = dwc2_restore_critical_registers(dwc2);
+ if (ret)
+ return ret;
+ }
+
if (dwc2->params.activate_stm_id_vb_detection) {
unsigned long flags;
u32 ggpio, gotgctl;
diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c
index c158364bc03e..9db8f3ca493d 100644
--- a/drivers/usb/dwc3/dwc3-am62.c
+++ b/drivers/usb/dwc3/dwc3-am62.c
@@ -153,11 +153,11 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62)
{
struct device *dev = am62->dev;
struct device_node *node = dev->of_node;
- struct of_phandle_args args;
struct regmap *syscon;
int ret;
- syscon = syscon_regmap_lookup_by_phandle(node, "ti,syscon-phy-pll-refclk");
+ syscon = syscon_regmap_lookup_by_phandle_args(node, "ti,syscon-phy-pll-refclk",
+ 1, &am62->offset);
if (IS_ERR(syscon)) {
dev_err(dev, "unable to get ti,syscon-phy-pll-refclk regmap\n");
return PTR_ERR(syscon);
@@ -165,14 +165,6 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62)
am62->syscon = syscon;
- ret = of_parse_phandle_with_fixed_args(node, "ti,syscon-phy-pll-refclk", 1,
- 0, &args);
- if (ret)
- return ret;
-
- of_node_put(args.np);
- am62->offset = args.args[0];
-
/* Core voltage. PHY_CORE_VOLTAGE bit Recommended to be 0 always */
ret = regmap_update_bits(am62->syscon, am62->offset, PHY_CORE_VOLTAGE_MASK, 0);
if (ret) {
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index f5d963fae9e0..de686b9e6404 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -163,6 +163,12 @@ static const struct dwc3_exynos_driverdata exynos7_drvdata = {
.suspend_clk_idx = 1,
};
+static const struct dwc3_exynos_driverdata exynos7870_drvdata = {
+ .clk_names = { "bus_early", "ref", "ctrl" },
+ .num_clks = 3,
+ .suspend_clk_idx = -1,
+};
+
static const struct dwc3_exynos_driverdata exynos850_drvdata = {
.clk_names = { "bus_early", "ref" },
.num_clks = 2,
@@ -186,6 +192,9 @@ static const struct of_device_id exynos_dwc3_match[] = {
.compatible = "samsung,exynos7-dwusb3",
.data = &exynos7_drvdata,
}, {
+ .compatible = "samsung,exynos7870-dwusb3",
+ .data = &exynos7870_drvdata,
+ }, {
.compatible = "samsung,exynos850-dwusb3",
.data = &exynos850_drvdata,
}, {
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 052852f80146..54a4ee2b90b7 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -148,11 +148,21 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = {
{}
};
+/*
+ * Intel Merrifield SoC uses these endpoints for tracing and they cannot
+ * be re-allocated if being used because the side band flow control signals
+ * are hard wired to certain endpoints:
+ * - 1 High BW Bulk IN (IN#1) (RTIT)
+ * - 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8)
+ */
+static const u8 dwc3_pci_mrfld_reserved_endpoints[] = { 3, 16, 17 };
+
static const struct property_entry dwc3_pci_mrfld_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_U8_ARRAY("snps,reserved-endpoints", dwc3_pci_mrfld_reserved_endpoints),
PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"),
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
{}
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index ef7c43008946..5d513decaacd 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -225,7 +225,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
dwc3_data->syscfg_reg_off = res->start;
- dev_vdbg(dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n",
+ dev_vdbg(dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n",
dwc3_data->glue_base, dwc3_data->syscfg_reg_off);
struct device_node *child __free(device_node) = of_get_compatible_child(node,
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 89a4dc8ebf94..47e73c4ed62d 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -547,6 +547,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep)
int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
{
struct dwc3_gadget_ep_cmd_params params;
+ struct dwc3_ep *dep;
u32 cmd;
int i;
int ret;
@@ -563,8 +564,13 @@ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
return ret;
/* Reset resource allocation flags */
- for (i = resource_index; i < dwc->num_eps && dwc->eps[i]; i++)
- dwc->eps[i]->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
+ for (i = resource_index; i < dwc->num_eps; i++) {
+ dep = dwc->eps[i];
+ if (!dep)
+ continue;
+
+ dep->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
+ }
return 0;
}
@@ -751,9 +757,11 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
dwc->last_fifo_depth = fifo_depth;
/* Clear existing TXFIFO for all IN eps except ep0 */
- for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM);
- num += 2) {
+ for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); num += 2) {
dep = dwc->eps[num];
+ if (!dep)
+ continue;
+
/* Don't change TXFRAMNUM on usb31 version */
size = DWC3_IP_IS(DWC3) ? 0 :
dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
@@ -1971,12 +1979,12 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
return -ESHUTDOWN;
}
- if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
+ if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
&req->request, req->dep->name))
return -EINVAL;
if (WARN(req->status < DWC3_REQUEST_STATUS_COMPLETED,
- "%s: request %pK already in flight\n",
+ "%s: request %p already in flight\n",
dep->name, &req->request))
return -EINVAL;
@@ -2165,7 +2173,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
}
}
- dev_err(dwc->dev, "request %pK was not queued to %s\n",
+ dev_err(dwc->dev, "request %p was not queued to %s\n",
request, ep->name);
ret = -EINVAL;
out:
@@ -3429,14 +3437,53 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
return 0;
}
+static int dwc3_gadget_get_reserved_endpoints(struct dwc3 *dwc, const char *propname,
+ u8 *eps, u8 num)
+{
+ u8 count;
+ int ret;
+
+ if (!device_property_present(dwc->dev, propname))
+ return 0;
+
+ ret = device_property_count_u8(dwc->dev, propname);
+ if (ret < 0)
+ return ret;
+ count = ret;
+
+ ret = device_property_read_u8_array(dwc->dev, propname, eps, min(num, count));
+ if (ret)
+ return ret;
+
+ return count;
+}
+
static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 total)
{
+ const char *propname = "snps,reserved-endpoints";
u8 epnum;
+ u8 reserved_eps[DWC3_ENDPOINTS_NUM];
+ u8 count;
+ u8 num;
+ int ret;
INIT_LIST_HEAD(&dwc->gadget->ep_list);
+ ret = dwc3_gadget_get_reserved_endpoints(dwc, propname,
+ reserved_eps, ARRAY_SIZE(reserved_eps));
+ if (ret < 0) {
+ dev_err(dwc->dev, "failed to read %s\n", propname);
+ return ret;
+ }
+ count = ret;
+
for (epnum = 0; epnum < total; epnum++) {
- int ret;
+ for (num = 0; num < count; num++) {
+ if (epnum == reserved_eps[num])
+ break;
+ }
+ if (num < count)
+ continue;
ret = dwc3_gadget_init_endpoint(dwc, epnum);
if (ret)
@@ -3703,6 +3750,8 @@ out:
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
dep = dwc->eps[i];
+ if (!dep)
+ continue;
if (!(dep->flags & DWC3_EP_ENABLED))
continue;
@@ -3852,6 +3901,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
u8 epnum = event->endpoint_number;
dep = dwc->eps[epnum];
+ if (!dep) {
+ dev_warn(dwc->dev, "spurious event, endpoint %u is not allocated\n", epnum);
+ return;
+ }
if (!(dep->flags & DWC3_EP_ENABLED)) {
if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED))
diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
index 5eaeae3e2441..9a1bbd79ff5a 100644
--- a/drivers/usb/gadget/function/uvc_queue.c
+++ b/drivers/usb/gadget/function/uvc_queue.c
@@ -122,8 +122,6 @@ static const struct vb2_ops uvc_queue_qops = {
.queue_setup = uvc_queue_setup,
.buf_prepare = uvc_buffer_prepare,
.buf_queue = uvc_buffer_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
int uvcg_queue_init(struct uvc_video_queue *queue, struct device *dev, enum v4l2_buf_type type,
diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c
index e25e0d8dd387..a05785bdeb30 100644
--- a/drivers/usb/gadget/legacy/zero.c
+++ b/drivers/usb/gadget/legacy/zero.c
@@ -194,7 +194,7 @@ static void zero_suspend(struct usb_composite_dev *cdev)
static void zero_resume(struct usb_composite_dev *cdev)
{
DBG(cdev, "%s\n", __func__);
- del_timer(&autoresume_timer);
+ timer_delete(&autoresume_timer);
}
/*-------------------------------------------------------------------------*/
@@ -398,7 +398,7 @@ err_put_func_inst_ss:
static int zero_unbind(struct usb_composite_dev *cdev)
{
- del_timer_sync(&autoresume_timer);
+ timer_delete_sync(&autoresume_timer);
if (!IS_ERR_OR_NULL(func_ss))
usb_put_function(func_ss);
usb_put_function_instance(func_inst_ss);
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
index 573109ca5b79..a09f72772e6e 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
@@ -548,6 +548,9 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
d->vhub = vhub;
d->index = idx;
d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1);
+ if (!d->name)
+ return -ENOMEM;
+
d->regs = vhub->regs + 0x100 + 0x10 * idx;
ast_vhub_init_ep0(vhub, &d->ep0, d);
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
index 8902abe3ca76..c93ea210c17c 100644
--- a/drivers/usb/gadget/udc/omap_udc.c
+++ b/drivers/usb/gadget/udc/omap_udc.c
@@ -252,7 +252,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
ep->has_dma = 0;
omap_writew(UDC_SET_HALT, UDC_CTRL);
list_del_init(&ep->iso);
- del_timer(&ep->timer);
+ timer_delete(&ep->timer);
spin_unlock_irqrestore(&ep->udc->lock, flags);
diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c
index 1e9998024aaa..24eb1ae78e45 100644
--- a/drivers/usb/gadget/udc/pxa25x_udc.c
+++ b/drivers/usb/gadget/udc/pxa25x_udc.c
@@ -1503,7 +1503,7 @@ reset_gadget(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
ep->stopped = 1;
nuke(ep, -ESHUTDOWN);
}
- del_timer_sync(&dev->timer);
+ timer_delete_sync(&dev->timer);
/* report reset; the driver is already quiesced */
if (driver)
@@ -1530,7 +1530,7 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
ep->stopped = 1;
nuke(ep, -ESHUTDOWN);
}
- del_timer_sync(&dev->timer);
+ timer_delete_sync(&dev->timer);
/* report disconnect; the driver is already quiesced */
if (driver)
@@ -1607,14 +1607,14 @@ static void handle_ep0 (struct pxa25x_udc *dev)
if (udccs0 & UDCCS0_SST) {
nuke(ep, -EPIPE);
udc_ep0_set_UDCCS(dev, UDCCS0_SST);
- del_timer(&dev->timer);
+ timer_delete(&dev->timer);
ep0_idle(dev);
}
/* previous request unfinished? non-error iff back-to-back ... */
if ((udccs0 & UDCCS0_SA) != 0 && dev->ep0state != EP0_IDLE) {
nuke(ep, 0);
- del_timer(&dev->timer);
+ timer_delete(&dev->timer);
ep0_idle(dev);
}
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c
index ff6f846b1d41..6c1d15b2250c 100644
--- a/drivers/usb/gadget/udc/r8a66597-udc.c
+++ b/drivers/usb/gadget/udc/r8a66597-udc.c
@@ -1810,7 +1810,7 @@ static void r8a66597_remove(struct platform_device *pdev)
struct r8a66597 *r8a66597 = platform_get_drvdata(pdev);
usb_del_gadget_udc(&r8a66597->gadget);
- del_timer_sync(&r8a66597->timer);
+ timer_delete_sync(&r8a66597->timer);
r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
if (r8a66597->pdata->on_chip) {
diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c
index 1f8a99d2a643..373942ceb076 100644
--- a/drivers/usb/gadget/udc/snps_udc_core.c
+++ b/drivers/usb/gadget/udc/snps_udc_core.c
@@ -3035,12 +3035,12 @@ void udc_remove(struct udc *dev)
stop_timer++;
if (timer_pending(&udc_timer))
wait_for_completion(&on_exit);
- del_timer_sync(&udc_timer);
+ timer_delete_sync(&udc_timer);
/* remove pollstall timer */
stop_pollstall_timer++;
if (timer_pending(&udc_pollstall_timer))
wait_for_completion(&on_pollstall_exit);
- del_timer_sync(&udc_pollstall_timer);
+ timer_delete_sync(&udc_pollstall_timer);
udc = NULL;
}
EXPORT_SYMBOL_GPL(udc_remove);
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index cdf41886e8ca..150d2542cef0 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -224,7 +224,7 @@ static void quirk_poll_init(struct ehci_platform_priv *priv)
static void quirk_poll_end(struct ehci_platform_priv *priv)
{
- del_timer_sync(&priv->poll_timer);
+ timer_delete_sync(&priv->poll_timer);
cancel_delayed_work(&priv->poll_work);
}
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 2d3a082cb52f..954fc5ad565b 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2357,7 +2357,7 @@ static void isp1362_hc_stop(struct usb_hcd *hcd)
pr_debug("%s:\n", __func__);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
spin_lock_irqsave(&isp1362_hcd->lock, flags);
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0881fdd1823e..dcf31a592f5d 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1946,6 +1946,12 @@ max3421_remove(struct spi_device *spi)
usb_put_hcd(hcd);
}
+static const struct spi_device_id max3421_spi_ids[] = {
+ { "max3421" },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, max3421_spi_ids);
+
static const struct of_device_id max3421_of_match_table[] = {
{ .compatible = "maxim,max3421", },
{},
@@ -1955,6 +1961,7 @@ MODULE_DEVICE_TABLE(of, max3421_of_match_table);
static struct spi_driver max3421_driver = {
.probe = max3421_probe,
.remove = max3421_remove,
+ .id_table = max3421_spi_ids,
.driver = {
.name = "max3421-hcd",
.of_match_table = max3421_of_match_table,
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9b24181fee60..c7784bf8101d 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1003,7 +1003,7 @@ static void ohci_stop (struct usb_hcd *hcd)
if (quirk_nec(ohci))
flush_work(&ohci->nec_work);
- del_timer_sync(&ohci->io_watchdog);
+ timer_delete_sync(&ohci->io_watchdog);
ohci->prev_frame_no = IO_WATCHDOG_OFF;
ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 90cee192e96d..b3d734ab6201 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -315,7 +315,7 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
spin_unlock_irq (&ohci->lock);
if (rc == 0) {
- del_timer_sync(&ohci->io_watchdog);
+ timer_delete_sync(&ohci->io_watchdog);
ohci->prev_frame_no = IO_WATCHDOG_OFF;
}
return rc;
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index fce800ba4c61..d75b1b9b4db0 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -1127,7 +1127,7 @@ static void ehci_mem_cleanup(struct oxu_hcd *oxu)
qh_put(oxu->async);
oxu->async = NULL;
- del_timer(&oxu->urb_timer);
+ timer_delete(&oxu->urb_timer);
oxu->periodic = NULL;
@@ -3154,7 +3154,7 @@ static void oxu_stop(struct usb_hcd *hcd)
ehci_port_power(oxu, 0);
/* no more interrupts ... */
- del_timer_sync(&oxu->watchdog);
+ timer_delete_sync(&oxu->watchdog);
spin_lock_irq(&oxu->lock);
if (HC_IS_RUNNING(hcd->state))
@@ -3887,7 +3887,7 @@ static int oxu_bus_suspend(struct usb_hcd *hcd)
spin_unlock_irq(&oxu->lock);
/* turn off now-idle HC */
- del_timer_sync(&oxu->watchdog);
+ timer_delete_sync(&oxu->watchdog);
spin_lock_irq(&oxu->lock);
ehci_halt(oxu);
hcd->state = HC_STATE_SUSPENDED;
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index a44992e2561b..67e472116d11 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2384,7 +2384,7 @@ static void r8a66597_remove(struct platform_device *pdev)
struct r8a66597 *r8a66597 = platform_get_drvdata(pdev);
struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
- del_timer_sync(&r8a66597->rh_timer);
+ timer_delete_sync(&r8a66597->rh_timer);
usb_remove_hcd(hcd);
iounmap(r8a66597->reg);
if (r8a66597->pdata->on_chip)
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index fa2e4badd288..718b1b7fe366 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1515,7 +1515,7 @@ sl811h_stop(struct usb_hcd *hcd)
struct sl811 *sl811 = hcd_to_sl811(hcd);
unsigned long flags;
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
spin_lock_irqsave(&sl811->lock, flags);
port_power(sl811, 0);
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index fd2408b553cf..14e6dfef16c6 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -716,7 +716,7 @@ static void uhci_stop(struct usb_hcd *hcd)
spin_unlock_irq(&uhci->lock);
synchronize_irq(hcd->irq);
- del_timer_sync(&uhci->fsbr_timer);
+ timer_delete_sync(&uhci->fsbr_timer);
release_uhci(uhci);
}
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 35fcb826152c..45a8256a665f 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -84,7 +84,7 @@ static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp)
uhci_fsbr_on(uhci);
else if (uhci->fsbr_expiring) {
uhci->fsbr_expiring = 0;
- del_timer(&uhci->fsbr_timer);
+ timer_delete(&uhci->fsbr_timer);
}
}
}
diff --git a/drivers/usb/host/xen-hcd.c b/drivers/usb/host/xen-hcd.c
index 46fdab940092..05943f2213e4 100644
--- a/drivers/usb/host/xen-hcd.c
+++ b/drivers/usb/host/xen-hcd.c
@@ -327,7 +327,7 @@ static int xenhcd_bus_suspend(struct usb_hcd *hcd)
}
spin_unlock_irq(&info->lock);
- del_timer_sync(&info->watchdog);
+ timer_delete_sync(&info->watchdog);
return ret;
}
@@ -1307,7 +1307,7 @@ static void xenhcd_stop(struct usb_hcd *hcd)
{
struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
- del_timer_sync(&info->watchdog);
+ timer_delete_sync(&info->watchdog);
spin_lock_irq(&info->lock);
/* cancel all urbs */
hcd->state = HC_STATE_HALT;
diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c
index 8a7d46dae62c..02396c8721dc 100644
--- a/drivers/usb/host/xhci-histb.c
+++ b/drivers/usb/host/xhci-histb.c
@@ -355,7 +355,7 @@ static int __maybe_unused xhci_histb_resume(struct device *dev)
if (!device_may_wakeup(dev))
xhci_histb_host_enable(histb);
- return xhci_resume(xhci, PMSG_RESUME);
+ return xhci_resume(xhci, false, false);
}
static const struct dev_pm_ops xhci_histb_pm_ops = {
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 69c278b64084..c0f226584a40 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -926,7 +926,7 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status,
if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) {
xhci->port_status_u0 |= 1 << wIndex;
if (xhci->port_status_u0 == all_ports_seen_u0) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"All USB3 ports have entered U0 already!");
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index fdf0c1008225..d698095fc88d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1953,7 +1953,6 @@ no_bw:
xhci->interrupters = NULL;
xhci->page_size = 0;
- xhci->page_shift = 0;
xhci->usb2_rhub.bus_state.bus_suspended = 0;
xhci->usb3_rhub.bus_state.bus_suspended = 0;
}
@@ -2372,6 +2371,22 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs,
}
EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter);
+static void xhci_hcd_page_size(struct xhci_hcd *xhci)
+{
+ u32 page_size;
+
+ page_size = readl(&xhci->op_regs->page_size) & XHCI_PAGE_SIZE_MASK;
+ if (!is_power_of_2(page_size)) {
+ xhci_warn(xhci, "Invalid page size register = 0x%x\n", page_size);
+ /* Fallback to 4K page size, since that's common */
+ page_size = 1;
+ }
+
+ xhci->page_size = page_size << 12;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "HCD page size set to %iK",
+ xhci->page_size >> 10);
+}
+
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{
struct xhci_interrupter *ir;
@@ -2379,7 +2394,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
dma_addr_t dma;
unsigned int val, val2;
u64 val_64;
- u32 page_size, temp;
+ u32 temp;
int i;
INIT_LIST_HEAD(&xhci->cmd_list);
@@ -2388,20 +2403,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout);
init_completion(&xhci->cmd_ring_stop_completion);
- page_size = readl(&xhci->op_regs->page_size);
- xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "Supported page size register = 0x%x", page_size);
- i = ffs(page_size);
- if (i < 16)
- xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "Supported page size of %iK", (1 << (i+12)) / 1024);
- else
- xhci_warn(xhci, "WARN: no supported page size\n");
- /* Use 4K pages, since that's common and the minimum the HC supports */
- xhci->page_shift = 12;
- xhci->page_size = 1 << xhci->page_shift;
- xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "HCD page size set to %iK", xhci->page_size / 1024);
+ xhci_hcd_page_size(xhci);
/*
* Program the Number of Device Slots Enabled field in the CONFIG
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 904831344440..208558cf822d 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -746,10 +746,10 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev)
xhci_dbg(xhci, "%s: stop port polling\n", __func__);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
if (shared_hcd) {
clear_bit(HCD_FLAG_POLL_RH, &shared_hcd->flags);
- del_timer_sync(&shared_hcd->rh_timer);
+ timer_delete_sync(&shared_hcd->rh_timer);
}
ret = xhci_mtk_host_disable(mtk);
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index 87f1597a0e5a..257e4d79971f 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -73,13 +73,3 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
return 0;
}
-
-int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- /* Without reset on resume, the HC won't work at all */
- xhci->quirks |= XHCI_RESET_ON_RESUME;
-
- return 0;
-}
diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h
index 3be021793cc8..9d26e22c4842 100644
--- a/drivers/usb/host/xhci-mvebu.h
+++ b/drivers/usb/host/xhci-mvebu.h
@@ -12,16 +12,10 @@ struct usb_hcd;
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
-int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
#else
static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
{
return 0;
}
-
-static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
-{
- return 0;
-}
#endif
#endif /* __LINUX_XHCI_MVEBU_H */
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 54460d11f7ee..0c481cbc8f08 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -807,8 +807,10 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
static int xhci_pci_resume(struct usb_hcd *hcd, pm_message_t msg)
{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+ bool power_lost = msg.event == PM_EVENT_RESTORE;
+ bool is_auto_resume = msg.event == PM_EVENT_AUTO_RESUME;
reset_control_reset(xhci->reset);
@@ -839,7 +841,7 @@ static int xhci_pci_resume(struct usb_hcd *hcd, pm_message_t msg)
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
xhci_pme_quirk(hcd);
- return xhci_resume(xhci, msg);
+ return xhci_resume(xhci, power_lost, is_auto_resume);
}
static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup)
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index d85ffa9ffaa7..3155e3a842da 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -106,7 +106,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = {
};
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
- .init_quirk = xhci_mvebu_a3700_init_quirk,
+ .quirks = XHCI_RESET_ON_RESUME,
};
static const struct xhci_plat_priv xhci_plat_brcm = {
@@ -479,9 +479,10 @@ static int xhci_plat_suspend(struct device *dev)
return 0;
}
-static int xhci_plat_resume_common(struct device *dev, struct pm_message pmsg)
+static int xhci_plat_resume_common(struct device *dev, bool power_lost)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ret;
@@ -501,7 +502,7 @@ static int xhci_plat_resume_common(struct device *dev, struct pm_message pmsg)
if (ret)
goto disable_clks;
- ret = xhci_resume(xhci, pmsg);
+ ret = xhci_resume(xhci, power_lost || priv->power_lost, false);
if (ret)
goto disable_clks;
@@ -522,12 +523,12 @@ disable_clks:
static int xhci_plat_resume(struct device *dev)
{
- return xhci_plat_resume_common(dev, PMSG_RESUME);
+ return xhci_plat_resume_common(dev, false);
}
static int xhci_plat_restore(struct device *dev)
{
- return xhci_plat_resume_common(dev, PMSG_RESTORE);
+ return xhci_plat_resume_common(dev, true);
}
static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
@@ -548,7 +549,7 @@ static int __maybe_unused xhci_plat_runtime_resume(struct device *dev)
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- return xhci_resume(xhci, PMSG_AUTO_RESUME);
+ return xhci_resume(xhci, false, true);
}
const struct dev_pm_ops xhci_plat_pm_ops = {
diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h
index 6475130eac4b..fe4f95e690fa 100644
--- a/drivers/usb/host/xhci-plat.h
+++ b/drivers/usb/host/xhci-plat.h
@@ -15,6 +15,7 @@ struct usb_hcd;
struct xhci_plat_priv {
const char *firmware_name;
unsigned long long quirks;
+ bool power_lost;
void (*plat_start)(struct usb_hcd *);
int (*init_quirk)(struct usb_hcd *);
int (*suspend_quirk)(struct usb_hcd *);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 965bffce301e..5d64c297721c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -204,6 +204,50 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
}
/*
+ * If enqueue points at a link TRB, follow links until an ordinary TRB is reached.
+ * Toggle the cycle bit of passed link TRBs and optionally chain them.
+ */
+static void inc_enq_past_link(struct xhci_hcd *xhci, struct xhci_ring *ring, u32 chain)
+{
+ unsigned int link_trb_count = 0;
+
+ while (trb_is_link(ring->enqueue)) {
+
+ /*
+ * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit
+ * set, but other sections talk about dealing with the chain bit set. This was
+ * fixed in the 0.96 specification errata, but we have to assume that all 0.95
+ * xHCI hardware can't handle the chain bit being cleared on a link TRB.
+ *
+ * On 0.95 and some 0.96 HCs the chain bit is set once at segment initalization
+ * and never changed here. On all others, modify it as requested by the caller.
+ */
+ if (!xhci_link_chain_quirk(xhci, ring->type)) {
+ ring->enqueue->link.control &= cpu_to_le32(~TRB_CHAIN);
+ ring->enqueue->link.control |= cpu_to_le32(chain);
+ }
+
+ /* Give this link TRB to the hardware */
+ wmb();
+ ring->enqueue->link.control ^= cpu_to_le32(TRB_CYCLE);
+
+ /* Toggle the cycle bit after the last ring segment. */
+ if (link_trb_toggles_cycle(ring->enqueue))
+ ring->cycle_state ^= 1;
+
+ ring->enq_seg = ring->enq_seg->next;
+ ring->enqueue = ring->enq_seg->trbs;
+
+ trace_xhci_inc_enq(ring);
+
+ if (link_trb_count++ > ring->num_segs) {
+ xhci_warn(xhci, "Link TRB loop at enqueue\n");
+ break;
+ }
+ }
+}
+
+/*
* See Cycle bit rules. SW is the consumer for the event ring only.
*
* If we've just enqueued a TRB that is in the middle of a TD (meaning the
@@ -211,11 +255,6 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
* If we've enqueued the last TRB in a TD, make sure the following link TRBs
* have their chain bit cleared (so that each Link TRB is a separate TD).
*
- * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit
- * set, but other sections talk about dealing with the chain bit set. This was
- * fixed in the 0.96 specification errata, but we have to assume that all 0.95
- * xHCI hardware can't handle the chain bit being cleared on a link TRB.
- *
* @more_trbs_coming: Will you enqueue more TRBs before calling
* prepare_transfer()?
*/
@@ -223,8 +262,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
bool more_trbs_coming)
{
u32 chain;
- union xhci_trb *next;
- unsigned int link_trb_count = 0;
chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN;
@@ -233,48 +270,67 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
return;
}
- next = ++(ring->enqueue);
+ ring->enqueue++;
- /* Update the dequeue pointer further if that was a link TRB */
- while (trb_is_link(next)) {
+ /*
+ * If we are in the middle of a TD or the caller plans to enqueue more
+ * TDs as one transfer (eg. control), traverse any link TRBs right now.
+ * Otherwise, enqueue can stay on a link until the next prepare_ring().
+ * This avoids enqueue entering deq_seg and simplifies ring expansion.
+ */
+ if (trb_is_link(ring->enqueue) && (chain || more_trbs_coming))
+ inc_enq_past_link(xhci, ring, chain);
+}
- /*
- * If the caller doesn't plan on enqueueing more TDs before
- * ringing the doorbell, then we don't want to give the link TRB
- * to the hardware just yet. We'll give the link TRB back in
- * prepare_ring() just before we enqueue the TD at the top of
- * the ring.
- */
- if (!chain && !more_trbs_coming)
- break;
+/*
+ * If the suspect DMA address is a TRB in this TD, this function returns that
+ * TRB's segment. Otherwise it returns 0.
+ */
+static struct xhci_segment *trb_in_td(struct xhci_td *td, dma_addr_t suspect_dma)
+{
+ dma_addr_t start_dma;
+ dma_addr_t end_seg_dma;
+ dma_addr_t end_trb_dma;
+ struct xhci_segment *cur_seg;
- /* If we're not dealing with 0.95 hardware or isoc rings on
- * AMD 0.96 host, carry over the chain bit of the previous TRB
- * (which may mean the chain bit is cleared).
- */
- if (!xhci_link_chain_quirk(xhci, ring->type)) {
- next->link.control &= cpu_to_le32(~TRB_CHAIN);
- next->link.control |= cpu_to_le32(chain);
- }
- /* Give this link TRB to the hardware */
- wmb();
- next->link.control ^= cpu_to_le32(TRB_CYCLE);
+ start_dma = xhci_trb_virt_to_dma(td->start_seg, td->start_trb);
+ cur_seg = td->start_seg;
- /* Toggle the cycle bit after the last ring segment. */
- if (link_trb_toggles_cycle(next))
- ring->cycle_state ^= 1;
+ do {
+ if (start_dma == 0)
+ return NULL;
+ /* We may get an event for a Link TRB in the middle of a TD */
+ end_seg_dma = xhci_trb_virt_to_dma(cur_seg,
+ &cur_seg->trbs[TRBS_PER_SEGMENT - 1]);
+ /* If the end TRB isn't in this segment, this is set to 0 */
+ end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->end_trb);
- ring->enq_seg = ring->enq_seg->next;
- ring->enqueue = ring->enq_seg->trbs;
- next = ring->enqueue;
+ if (end_trb_dma > 0) {
+ /* The end TRB is in this segment, so suspect should be here */
+ if (start_dma <= end_trb_dma) {
+ if (suspect_dma >= start_dma && suspect_dma <= end_trb_dma)
+ return cur_seg;
+ } else {
+ /* Case for one segment with
+ * a TD wrapped around to the top
+ */
+ if ((suspect_dma >= start_dma &&
+ suspect_dma <= end_seg_dma) ||
+ (suspect_dma >= cur_seg->dma &&
+ suspect_dma <= end_trb_dma))
+ return cur_seg;
+ }
+ return NULL;
+ }
+ /* Might still be somewhere in this segment */
+ if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma)
+ return cur_seg;
- trace_xhci_inc_enq(ring);
+ cur_seg = cur_seg->next;
+ start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]);
+ } while (cur_seg != td->start_seg);
- if (link_trb_count++ > ring->num_segs) {
- xhci_warn(xhci, "%s: Ring link TRB loop\n", __func__);
- break;
- }
- }
+ return NULL;
}
/*
@@ -505,8 +561,8 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
* pointer command pending because the device can choose to start any
* stream once the endpoint is on the HW schedule.
*/
- if ((ep_state & EP_STOP_CMD_PENDING) || (ep_state & SET_DEQ_PENDING) ||
- (ep_state & EP_HALTED) || (ep_state & EP_CLEARING_TT))
+ if (ep_state & (EP_STOP_CMD_PENDING | SET_DEQ_PENDING | EP_HALTED |
+ EP_CLEARING_TT | EP_STALLED))
return;
trace_xhci_ring_ep_doorbell(slot_id, DB_VALUE(ep_index, stream_id));
@@ -1014,7 +1070,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
td->urb->stream_id);
hw_deq &= ~0xf;
- if (td->cancel_status == TD_HALTED || trb_in_td(xhci, td, hw_deq, false)) {
+ if (td->cancel_status == TD_HALTED || trb_in_td(td, hw_deq)) {
switch (td->cancel_status) {
case TD_CLEARED: /* TD is already no-op */
case TD_CLEARING_CACHE: /* set TR deq command already queued */
@@ -1104,7 +1160,7 @@ static struct xhci_td *find_halted_td(struct xhci_virt_ep *ep)
hw_deq = xhci_get_hw_deq(ep->xhci, ep->vdev, ep->ep_index, 0);
hw_deq &= ~0xf;
td = list_first_entry(&ep->ring->td_list, struct xhci_td, td_list);
- if (trb_in_td(ep->xhci, td, hw_deq, false))
+ if (trb_in_td(td, hw_deq))
return td;
}
return NULL;
@@ -1164,7 +1220,14 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
*/
switch (GET_EP_CTX_STATE(ep_ctx)) {
case EP_STATE_HALTED:
- xhci_dbg(xhci, "Stop ep completion raced with stall, reset ep\n");
+ xhci_dbg(xhci, "Stop ep completion raced with stall\n");
+ /*
+ * If the halt happened before Stop Endpoint failed, its transfer event
+ * should have already been handled and Reset Endpoint should be pending.
+ */
+ if (ep->ep_state & EP_HALTED)
+ goto reset_done;
+
if (ep->ep_state & EP_HAS_STREAMS) {
reset_type = EP_SOFT_RESET;
} else {
@@ -1175,8 +1238,11 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
}
/* reset ep, reset handler cleans up cancelled tds */
err = xhci_handle_halted_endpoint(xhci, ep, td, reset_type);
+ xhci_dbg(xhci, "Stop ep completion resetting ep, status %d\n", err);
if (err)
break;
+reset_done:
+ /* Reset EP handler will clean up cancelled TDs */
ep->ep_state &= ~EP_STOP_CMD_PENDING;
return;
case EP_STATE_STOPPED:
@@ -1198,16 +1264,19 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
* Stopped state, but it will soon change to Running.
*
* Assume this bug on unexpected Stop Endpoint failures.
- * Keep retrying until the EP starts and stops again, on
- * chips where this is known to help. Wait for 100ms.
+ * Keep retrying until the EP starts and stops again.
*/
- if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
- break;
fallthrough;
case EP_STATE_RUNNING:
/* Race, HW handled stop ep cmd before ep was running */
xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n",
GET_EP_CTX_STATE(ep_ctx));
+ /*
+ * Don't retry forever if we guessed wrong or a defective HC never starts
+ * the EP or says 'Running' but fails the command. We must give back TDs.
+ */
+ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
+ break;
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
if (!command) {
@@ -1332,43 +1401,6 @@ void xhci_hc_died(struct xhci_hcd *xhci)
usb_hc_died(xhci_to_hcd(xhci));
}
-static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,
- struct xhci_virt_device *dev,
- struct xhci_ring *ep_ring,
- unsigned int ep_index)
-{
- union xhci_trb *dequeue_temp;
-
- dequeue_temp = ep_ring->dequeue;
-
- /* If we get two back-to-back stalls, and the first stalled transfer
- * ends just before a link TRB, the dequeue pointer will be left on
- * the link TRB by the code in the while loop. So we have to update
- * the dequeue pointer one segment further, or we'll jump off
- * the segment into la-la-land.
- */
- if (trb_is_link(ep_ring->dequeue)) {
- ep_ring->deq_seg = ep_ring->deq_seg->next;
- ep_ring->dequeue = ep_ring->deq_seg->trbs;
- }
-
- while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) {
- /* We have more usable TRBs */
- ep_ring->dequeue++;
- if (trb_is_link(ep_ring->dequeue)) {
- if (ep_ring->dequeue ==
- dev->eps[ep_index].queued_deq_ptr)
- break;
- ep_ring->deq_seg = ep_ring->deq_seg->next;
- ep_ring->dequeue = ep_ring->deq_seg->trbs;
- }
- if (ep_ring->dequeue == dequeue_temp) {
- xhci_dbg(xhci, "Unable to find new dequeue pointer\n");
- break;
- }
- }
-}
-
/*
* When we get a completion for a Set Transfer Ring Dequeue Pointer command,
* we need to clear the set deq pending flag in the endpoint ring state, so that
@@ -1473,8 +1505,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
/* Update the ring's dequeue segment and dequeue pointer
* to reflect the new position.
*/
- update_ring_for_set_deq_completion(xhci, ep->vdev,
- ep_ring, ep_index);
+ ep_ring->deq_seg = ep->queued_deq_seg;
+ ep_ring->dequeue = ep->queued_deq_ptr;
} else {
xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n");
xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n",
@@ -2116,67 +2148,6 @@ cleanup:
spin_lock(&xhci->lock);
}
-/*
- * If the suspect DMA address is a TRB in this TD, this function returns that
- * TRB's segment. Otherwise it returns 0.
- */
-struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, dma_addr_t suspect_dma,
- bool debug)
-{
- dma_addr_t start_dma;
- dma_addr_t end_seg_dma;
- dma_addr_t end_trb_dma;
- struct xhci_segment *cur_seg;
-
- start_dma = xhci_trb_virt_to_dma(td->start_seg, td->start_trb);
- cur_seg = td->start_seg;
-
- do {
- if (start_dma == 0)
- return NULL;
- /* We may get an event for a Link TRB in the middle of a TD */
- end_seg_dma = xhci_trb_virt_to_dma(cur_seg,
- &cur_seg->trbs[TRBS_PER_SEGMENT - 1]);
- /* If the end TRB isn't in this segment, this is set to 0 */
- end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->end_trb);
-
- if (debug)
- xhci_warn(xhci,
- "Looking for event-dma %016llx trb-start %016llx trb-end %016llx seg-start %016llx seg-end %016llx\n",
- (unsigned long long)suspect_dma,
- (unsigned long long)start_dma,
- (unsigned long long)end_trb_dma,
- (unsigned long long)cur_seg->dma,
- (unsigned long long)end_seg_dma);
-
- if (end_trb_dma > 0) {
- /* The end TRB is in this segment, so suspect should be here */
- if (start_dma <= end_trb_dma) {
- if (suspect_dma >= start_dma && suspect_dma <= end_trb_dma)
- return cur_seg;
- } else {
- /* Case for one segment with
- * a TD wrapped around to the top
- */
- if ((suspect_dma >= start_dma &&
- suspect_dma <= end_seg_dma) ||
- (suspect_dma >= cur_seg->dma &&
- suspect_dma <= end_trb_dma))
- return cur_seg;
- }
- return NULL;
- } else {
- /* Might still be somewhere in this segment */
- if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma)
- return cur_seg;
- }
- cur_seg = cur_seg->next;
- start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]);
- } while (cur_seg != td->start_seg);
-
- return NULL;
-}
-
static void xhci_clear_hub_tt_buffer(struct xhci_hcd *xhci, struct xhci_td *td,
struct xhci_virt_ep *ep)
{
@@ -2476,6 +2447,12 @@ static void process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
if (ep_trb != td->end_trb)
td->error_mid_td = true;
break;
+ case COMP_MISSED_SERVICE_ERROR:
+ frame->status = -EXDEV;
+ sum_trbs_for_length = true;
+ if (ep_trb != td->end_trb)
+ td->error_mid_td = true;
+ break;
case COMP_INCOMPATIBLE_DEVICE_ERROR:
case COMP_STALL_ERROR:
frame->status = -EPROTO;
@@ -2596,6 +2573,9 @@ static void process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
xhci_handle_halted_endpoint(xhci, ep, td, EP_SOFT_RESET);
return;
+ case COMP_STALL_ERROR:
+ ep->ep_state |= EP_STALLED;
+ break;
default:
/* do nothing */
break;
@@ -2644,6 +2624,22 @@ static int handle_transferless_tx_event(struct xhci_hcd *xhci, struct xhci_virt_
return 0;
}
+static bool xhci_spurious_success_tx_event(struct xhci_hcd *xhci,
+ struct xhci_ring *ring)
+{
+ switch (ring->old_trb_comp_code) {
+ case COMP_SHORT_PACKET:
+ return xhci->quirks & XHCI_SPURIOUS_SUCCESS;
+ case COMP_USB_TRANSACTION_ERROR:
+ case COMP_BABBLE_DETECTED_ERROR:
+ case COMP_ISOCH_BUFFER_OVERRUN:
+ return xhci->quirks & XHCI_ETRON_HOST &&
+ ring->type == TYPE_ISOC;
+ default:
+ return false;
+ }
+}
+
/*
* If this function returns an error condition, it means it got a Transfer
* event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
@@ -2664,6 +2660,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
int status = -EINPROGRESS;
struct xhci_ep_ctx *ep_ctx;
u32 trb_comp_code;
+ bool ring_xrun_event = false;
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
@@ -2697,8 +2694,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
case COMP_SUCCESS:
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
trb_comp_code = COMP_SHORT_PACKET;
- xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n",
- slot_id, ep_index, ep_ring->last_td_was_short);
+ xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td comp code %d\n",
+ slot_id, ep_index, ep_ring->old_trb_comp_code);
}
break;
case COMP_SHORT_PACKET:
@@ -2770,14 +2767,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* Underrun Event for OUT Isoch endpoint.
*/
xhci_dbg(xhci, "Underrun event on slot %u ep %u\n", slot_id, ep_index);
- if (ep->skip)
- break;
- return 0;
+ ring_xrun_event = true;
+ break;
case COMP_RING_OVERRUN:
xhci_dbg(xhci, "Overrun event on slot %u ep %u\n", slot_id, ep_index);
- if (ep->skip)
- break;
- return 0;
+ ring_xrun_event = true;
+ break;
case COMP_MISSED_SERVICE_ERROR:
/*
* When encounter missed service error, one or more isoc tds
@@ -2787,9 +2782,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
ep->skip = true;
xhci_dbg(xhci,
- "Miss service interval error for slot %u ep %u, set skip flag\n",
- slot_id, ep_index);
- return 0;
+ "Miss service interval error for slot %u ep %u, set skip flag%s\n",
+ slot_id, ep_index, ep_trb_dma ? ", skip now" : "");
+ break;
case COMP_NO_PING_RESPONSE_ERROR:
ep->skip = true;
xhci_dbg(xhci,
@@ -2832,11 +2827,15 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
td = list_first_entry_or_null(&ep_ring->td_list, struct xhci_td, td_list);
- if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) {
+ if (td && td->error_mid_td && !trb_in_td(td, ep_trb_dma)) {
xhci_dbg(xhci, "Missing TD completion event after mid TD error\n");
xhci_dequeue_td(xhci, td, ep_ring, td->status);
}
+ /* If the TRB pointer is NULL, missed TDs will be skipped on the next event */
+ if (trb_comp_code == COMP_MISSED_SERVICE_ERROR && !ep_trb_dma)
+ return 0;
+
if (list_empty(&ep_ring->td_list)) {
/*
* Don't print wanings if ring is empty due to a stopped endpoint generating an
@@ -2846,7 +2845,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
if (trb_comp_code != COMP_STOPPED &&
trb_comp_code != COMP_STOPPED_LENGTH_INVALID &&
- !ep_ring->last_td_was_short) {
+ !ring_xrun_event &&
+ !xhci_spurious_success_tx_event(xhci, ep_ring)) {
xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n",
slot_id, ep_index);
}
@@ -2860,14 +2860,31 @@ static int handle_tx_event(struct xhci_hcd *xhci,
td_list);
/* Is this a TRB in the currently executing TD? */
- ep_seg = trb_in_td(xhci, td, ep_trb_dma, false);
+ ep_seg = trb_in_td(td, ep_trb_dma);
if (!ep_seg) {
if (ep->skip && usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
+ /* this event is unlikely to match any TD, don't skip them all */
+ if (trb_comp_code == COMP_STOPPED_LENGTH_INVALID)
+ return 0;
+
skip_isoc_td(xhci, td, ep, status);
- if (!list_empty(&ep_ring->td_list))
+
+ if (!list_empty(&ep_ring->td_list)) {
+ if (ring_xrun_event) {
+ /*
+ * If we are here, we are on xHCI 1.0 host with no
+ * idea how many TDs were missed or where the xrun
+ * occurred. New TDs may have been added after the
+ * xrun, so skip only one TD to be safe.
+ */
+ xhci_dbg(xhci, "Skipped one TD for slot %u ep %u",
+ slot_id, ep_index);
+ return 0;
+ }
continue;
+ }
xhci_dbg(xhci, "All TDs skipped for slot %u ep %u. Clear skip flag.\n",
slot_id, ep_index);
@@ -2876,6 +2893,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
goto check_endpoint_halted;
}
+ /* TD was queued after xrun, maybe xrun was on a link, don't panic yet */
+ if (ring_xrun_event)
+ return 0;
+
/*
* Skip the Force Stopped Event. The 'ep_trb' of FSE is not in the current
* TD pointed by 'ep_ring->dequeue' because that the hardware dequeue
@@ -2890,21 +2911,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/*
* Some hosts give a spurious success event after a short
- * transfer. Ignore it.
+ * transfer or error on last TRB. Ignore it.
*/
- if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
- ep_ring->last_td_was_short) {
- ep_ring->last_td_was_short = false;
+ if (xhci_spurious_success_tx_event(xhci, ep_ring)) {
+ xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n",
+ &ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code);
+ ep_ring->old_trb_comp_code = trb_comp_code;
return 0;
}
/* HC is busted, give up! */
- xhci_err(xhci,
- "ERROR Transfer event TRB DMA ptr not part of current TD ep_index %d comp_code %u\n",
- ep_index, trb_comp_code);
- trb_in_td(xhci, td, ep_trb_dma, true);
-
- return -ESHUTDOWN;
+ goto debug_finding_td;
}
if (ep->skip) {
@@ -2922,10 +2939,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
} while (ep->skip);
- if (trb_comp_code == COMP_SHORT_PACKET)
- ep_ring->last_td_was_short = true;
- else
- ep_ring->last_td_was_short = false;
+ ep_ring->old_trb_comp_code = trb_comp_code;
+
+ /* Get out if a TD was queued at enqueue after the xrun occurred */
+ if (ring_xrun_event)
+ return 0;
ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) / sizeof(*ep_trb)];
trace_xhci_handle_transfer(ep_ring, (struct xhci_generic_trb *) ep_trb, ep_trb_dma);
@@ -2957,6 +2975,17 @@ check_endpoint_halted:
return 0;
+debug_finding_td:
+ xhci_err(xhci, "Event dma %pad for ep %d status %d not part of TD at %016llx - %016llx\n",
+ &ep_trb_dma, ep_index, trb_comp_code,
+ (unsigned long long)xhci_trb_virt_to_dma(td->start_seg, td->start_trb),
+ (unsigned long long)xhci_trb_virt_to_dma(td->end_seg, td->end_trb));
+
+ xhci_for_each_ring_seg(ep_ring->first_seg, ep_seg)
+ xhci_warn(xhci, "Ring seg %u dma %pad\n", ep_seg->num, &ep_seg->dma);
+
+ return -ESHUTDOWN;
+
err_out:
xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n",
(unsigned long long) xhci_trb_virt_to_dma(
@@ -3216,7 +3245,6 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
u32 ep_state, unsigned int num_trbs, gfp_t mem_flags)
{
- unsigned int link_trb_count = 0;
unsigned int new_segs = 0;
/* Make sure the endpoint has been added to xHC schedule */
@@ -3264,33 +3292,9 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
}
}
- while (trb_is_link(ep_ring->enqueue)) {
- /* If we're not dealing with 0.95 hardware or isoc rings
- * on AMD 0.96 host, clear the chain bit.
- */
- if (!xhci_link_chain_quirk(xhci, ep_ring->type))
- ep_ring->enqueue->link.control &=
- cpu_to_le32(~TRB_CHAIN);
- else
- ep_ring->enqueue->link.control |=
- cpu_to_le32(TRB_CHAIN);
-
- wmb();
- ep_ring->enqueue->link.control ^= cpu_to_le32(TRB_CYCLE);
-
- /* Toggle the cycle bit after the last ring segment. */
- if (link_trb_toggles_cycle(ep_ring->enqueue))
- ep_ring->cycle_state ^= 1;
-
- ep_ring->enq_seg = ep_ring->enq_seg->next;
- ep_ring->enqueue = ep_ring->enq_seg->trbs;
-
- /* prevent infinite loop if all first trbs are link trbs */
- if (link_trb_count++ > ep_ring->num_segs) {
- xhci_warn(xhci, "Ring is an endless link TRB loop\n");
- return -EINVAL;
- }
- }
+ /* Ensure that new TRBs won't overwrite a link */
+ if (trb_is_link(ep_ring->enqueue))
+ inc_enq_past_link(xhci, ep_ring, 0);
if (last_trb_on_seg(ep_ring->enq_seg, ep_ring->enqueue)) {
xhci_warn(xhci, "Missing link TRB at end of ring segment\n");
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 22dc86fb5254..b5c362c2051d 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -2162,11 +2162,11 @@ static void tegra_xhci_program_utmi_power_lp0_exit(struct tegra_xusb *tegra)
}
}
-static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool runtime)
+static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool is_auto_resume)
{
struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
struct device *dev = tegra->dev;
- bool wakeup = runtime ? true : device_may_wakeup(dev);
+ bool wakeup = is_auto_resume ? true : device_may_wakeup(dev);
unsigned int i;
int err;
u32 usbcmd;
@@ -2232,11 +2232,11 @@ out:
return err;
}
-static int tegra_xusb_exit_elpg(struct tegra_xusb *tegra, bool runtime)
+static int tegra_xusb_exit_elpg(struct tegra_xusb *tegra, bool is_auto_resume)
{
struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
struct device *dev = tegra->dev;
- bool wakeup = runtime ? true : device_may_wakeup(dev);
+ bool wakeup = is_auto_resume ? true : device_may_wakeup(dev);
unsigned int i;
u32 usbcmd;
int err;
@@ -2287,7 +2287,7 @@ static int tegra_xusb_exit_elpg(struct tegra_xusb *tegra, bool runtime)
if (wakeup)
tegra_xhci_disable_phy_sleepwalk(tegra);
- err = xhci_resume(xhci, runtime ? PMSG_AUTO_RESUME : PMSG_RESUME);
+ err = xhci_resume(xhci, false, is_auto_resume);
if (err < 0) {
dev_err(tegra->dev, "failed to resume XHCI: %d\n", err);
goto disable_phy;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 1a90ebc8a30e..0452b8d65832 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -627,7 +627,7 @@ void xhci_stop(struct usb_hcd *hcd)
/* Deleting Compliance Mode Recovery Timer */
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
(!(xhci_all_ports_seen_u0(xhci)))) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"%s: compliance mode recovery timer deleted",
__func__);
@@ -672,11 +672,11 @@ void xhci_shutdown(struct usb_hcd *hcd)
xhci_dbg(xhci, "%s: stopping usb%d port polling.\n",
__func__, hcd->self.busnum);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
if (xhci->shared_hcd) {
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
- del_timer_sync(&xhci->shared_hcd->rh_timer);
+ timer_delete_sync(&xhci->shared_hcd->rh_timer);
}
spin_lock_irq(&xhci->lock);
@@ -908,10 +908,10 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
xhci_dbg(xhci, "%s: stopping usb%d port polling.\n",
__func__, hcd->self.busnum);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
if (xhci->shared_hcd) {
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
- del_timer_sync(&xhci->shared_hcd->rh_timer);
+ timer_delete_sync(&xhci->shared_hcd->rh_timer);
}
if (xhci->quirks & XHCI_SUSPEND_DELAY)
@@ -978,7 +978,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
*/
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
(!(xhci_all_ports_seen_u0(xhci)))) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"%s: compliance mode recovery timer deleted",
__func__);
@@ -994,16 +994,14 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
* This is called when the machine transition from S3/S4 mode.
*
*/
-int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
+int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume)
{
- bool hibernated = (msg.event == PM_EVENT_RESTORE);
u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
int retval = 0;
bool comp_timer_running = false;
bool pending_portevent = false;
bool suspended_usb3_devs = false;
- bool reinit_xhc = false;
if (!hcd->state)
return 0;
@@ -1022,10 +1020,10 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
spin_lock_irq(&xhci->lock);
- if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
- reinit_xhc = true;
+ if (xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
+ power_lost = true;
- if (!reinit_xhc) {
+ if (!power_lost) {
/*
* Some controllers might lose power during suspend, so wait
* for controller not ready bit to clear, just as in xHC init.
@@ -1065,15 +1063,15 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
/* re-initialize the HC on Restore Error, or Host Controller Error */
if ((temp & (STS_SRE | STS_HCE)) &&
!(xhci->xhc_state & XHCI_STATE_REMOVING)) {
- reinit_xhc = true;
- if (!xhci->broken_suspend)
+ if (!power_lost)
xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
+ power_lost = true;
}
- if (reinit_xhc) {
+ if (power_lost) {
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
!(xhci_all_ports_seen_u0(xhci))) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Compliance Mode Recovery Timer deleted!");
}
@@ -1168,8 +1166,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
pending_portevent = xhci_pending_portevent(xhci);
- if (suspended_usb3_devs && !pending_portevent &&
- msg.event == PM_EVENT_AUTO_RESUME) {
+ if (suspended_usb3_devs && !pending_portevent && is_auto_resume) {
msleep(120);
pending_portevent = xhci_pending_portevent(xhci);
}
@@ -1608,6 +1605,11 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
goto free_priv;
}
+ /* Class driver might not be aware ep halted due to async URB giveback */
+ if (*ep_state & EP_STALLED)
+ dev_dbg(&urb->dev->dev, "URB %p queued before clearing halt\n",
+ urb);
+
switch (usb_endpoint_type(&urb->ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
@@ -1768,8 +1770,8 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
goto done;
}
- /* In this case no commands are pending but the endpoint is stopped */
- if (ep->ep_state & EP_CLEARING_TT) {
+ /* In these cases no commands are pending but the endpoint is stopped */
+ if (ep->ep_state & (EP_CLEARING_TT | EP_STALLED)) {
/* and cancelled TDs can be given back right away */
xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n",
urb->dev->slot_id, ep_index, ep->ep_state);
@@ -3207,8 +3209,11 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
ep = &vdev->eps[ep_index];
- /* Bail out if toggle is already being cleared by a endpoint reset */
spin_lock_irqsave(&xhci->lock, flags);
+
+ ep->ep_state &= ~EP_STALLED;
+
+ /* Bail out if toggle is already being cleared by a endpoint reset */
if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) {
ep->ep_state &= ~EP_HARD_CLEAR_TOGGLE;
spin_unlock_irqrestore(&xhci->lock, flags);
@@ -4759,8 +4764,8 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,
*/
if (timeout_ns <= USB3_LPM_U1_MAX_TIMEOUT)
return timeout_ns;
- dev_dbg(&udev->dev, "Hub-initiated U1 disabled "
- "due to long timeout %llu ms\n", timeout_ns);
+ dev_dbg(&udev->dev, "Hub-initiated U1 disabled due to long timeout %lluus\n",
+ timeout_ns);
return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U1);
}
@@ -4817,8 +4822,8 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,
*/
if (timeout_ns <= USB3_LPM_U2_MAX_TIMEOUT)
return timeout_ns;
- dev_dbg(&udev->dev, "Hub-initiated U2 disabled "
- "due to long timeout %llu ms\n", timeout_ns);
+ dev_dbg(&udev->dev, "Hub-initiated U2 disabled due to long timeout %lluus\n",
+ timeout_ns * 256);
return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U2);
}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 779b01dee068..37860f1e3aba 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -211,6 +211,9 @@ struct xhci_op_regs {
#define CONFIG_CIE (1 << 9)
/* bits 10:31 - reserved and should be preserved */
+/* bits 15:0 - HCD page shift bit */
+#define XHCI_PAGE_SIZE_MASK 0xffff
+
/**
* struct xhci_intr_reg - Interrupt Register Set
* @irq_pending: IMAN - Interrupt Management Register. Used to enable
@@ -661,7 +664,7 @@ struct xhci_virt_ep {
unsigned int err_count;
unsigned int ep_state;
#define SET_DEQ_PENDING (1 << 0)
-#define EP_HALTED (1 << 1) /* For stall handling */
+#define EP_HALTED (1 << 1) /* Halted host ep handling */
#define EP_STOP_CMD_PENDING (1 << 2) /* For URB cancellation */
/* Transitioning the endpoint to using streams, don't enqueue URBs */
#define EP_GETTING_STREAMS (1 << 3)
@@ -672,6 +675,7 @@ struct xhci_virt_ep {
#define EP_SOFT_CLEAR_TOGGLE (1 << 7)
/* usb_hub_clear_tt_buffer is in progress */
#define EP_CLEARING_TT (1 << 8)
+#define EP_STALLED (1 << 9) /* For stall handling */
/* ---- Related to URB cancellation ---- */
struct list_head cancelled_td_list;
struct xhci_hcd *xhci;
@@ -1371,7 +1375,7 @@ struct xhci_ring {
unsigned int num_trbs_free; /* used only by xhci DbC */
unsigned int bounce_buf_len;
enum xhci_ring_type type;
- bool last_td_was_short;
+ u32 old_trb_comp_code;
struct radix_tree_root *trb_address_map;
};
@@ -1514,10 +1518,7 @@ struct xhci_hcd {
u16 max_interrupters;
/* imod_interval in ns (I * 250ns) */
u32 imod_interval;
- /* 4KB min, 128MB max */
- int page_size;
- /* Valid values are 12 to 20, inclusive */
- int page_shift;
+ u32 page_size;
/* MSI-X/MSI vectors */
int nvecs;
/* optional clocks */
@@ -1759,11 +1760,20 @@ static inline void xhci_write_64(struct xhci_hcd *xhci,
}
-/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */
+/*
+ * Reportedly, some chapters of v0.95 spec said that Link TRB always has its chain bit set.
+ * Other chapters and later specs say that it should only be set if the link is inside a TD
+ * which continues from the end of one segment to the next segment.
+ *
+ * Some 0.95 hardware was found to misbehave if any link TRB doesn't have the chain bit set.
+ *
+ * 0.96 hardware from AMD and NEC was found to ignore unchained isochronous link TRBs when
+ * "resynchronizing the pipe" after a Missed Service Error.
+ */
static inline bool xhci_link_chain_quirk(struct xhci_hcd *xhci, enum xhci_ring_type type)
{
return (xhci->quirks & XHCI_LINK_TRB_QUIRK) ||
- (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST));
+ (type == TYPE_ISOC && (xhci->quirks & (XHCI_AMD_0x96_HOST | XHCI_NEC_HOST)));
}
/* xHCI debugging */
@@ -1870,7 +1880,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
int xhci_ext_cap_init(struct xhci_hcd *xhci);
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);
-int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg);
+int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume);
irqreturn_t xhci_irq(struct usb_hcd *hcd);
irqreturn_t xhci_msi_irq(int irq, void *hcd);
@@ -1884,8 +1894,6 @@ int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
/* xHCI ring, segment, TRB, and TD functions */
dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
-struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td,
- dma_addr_t suspect_dma, bool debug);
int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code);
void xhci_ring_cmd_db(struct xhci_hcd *xhci);
int xhci_queue_slot_control(struct xhci_hcd *xhci, struct xhci_command *cmd,
diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c
index add2d2e3b61b..8dcd9cc22413 100644
--- a/drivers/usb/isp1760/isp1760-hcd.c
+++ b/drivers/usb/isp1760/isp1760-hcd.c
@@ -2458,7 +2458,7 @@ static void isp1760_stop(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
- del_timer(&errata2_timer);
+ timer_delete(&errata2_timer);
isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1,
NULL, 0);
diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c
index 5cafd23345ca..2af89ee28baa 100644
--- a/drivers/usb/isp1760/isp1760-udc.c
+++ b/drivers/usb/isp1760/isp1760-udc.c
@@ -1145,7 +1145,7 @@ static void isp1760_udc_disconnect(struct isp1760_udc *udc)
if (udc->driver->disconnect)
udc->driver->disconnect(&udc->gadget);
- del_timer(&udc->vbus_timer);
+ timer_delete(&udc->vbus_timer);
/* TODO Reset all endpoints ? */
}
@@ -1314,7 +1314,7 @@ static int isp1760_udc_stop(struct usb_gadget *gadget)
dev_dbg(udc->isp->dev, "%s\n", __func__);
- del_timer_sync(&udc->vbus_timer);
+ timer_delete_sync(&udc->vbus_timer);
isp1760_reg_write(udc->regs, mode_reg, 0);
diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
index 317b3eb99c02..933797a7e084 100644
--- a/drivers/usb/misc/onboard_usb_dev.h
+++ b/drivers/usb/misc/onboard_usb_dev.h
@@ -23,6 +23,13 @@ static const struct onboard_dev_pdata microchip_usb424_data = {
.is_hub = true,
};
+static const struct onboard_dev_pdata microchip_usb2514_data = {
+ .reset_us = 1,
+ .num_supplies = 2,
+ .supply_names = { "vdd", "vdda" },
+ .is_hub = true,
+};
+
static const struct onboard_dev_pdata microchip_usb5744_data = {
.reset_us = 0,
.power_on_delay_us = 10000,
@@ -96,7 +103,7 @@ static const struct onboard_dev_pdata xmos_xvf3500_data = {
static const struct of_device_id onboard_dev_match[] = {
{ .compatible = "usb424,2412", .data = &microchip_usb424_data, },
- { .compatible = "usb424,2514", .data = &microchip_usb424_data, },
+ { .compatible = "usb424,2514", .data = &microchip_usb2514_data, },
{ .compatible = "usb424,2517", .data = &microchip_usb424_data, },
{ .compatible = "usb424,2744", .data = &microchip_usb5744_data, },
{ .compatible = "usb424,5744", .data = &microchip_usb5744_data, },
diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c
index e24cdb667307..4fb453ca5450 100644
--- a/drivers/usb/misc/usb251xb.c
+++ b/drivers/usb/misc/usb251xb.c
@@ -636,10 +636,8 @@ static int usb251xb_probe(struct usb251xb *hub)
if (np && usb_data) {
err = usb251xb_get_ofdata(hub, usb_data);
- if (err) {
- dev_err(dev, "failed to get ofdata: %d\n", err);
- return err;
- }
+ if (err)
+ return dev_err_probe(dev, err, "failed to get ofdata\n");
}
/*
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 8d379ae835bc..853a5f082a70 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -626,7 +626,7 @@ static int perform_sglist(
mod_timer(&timeout.timer, jiffies +
msecs_to_jiffies(SIMPLE_IO_TIMEOUT));
usb_sg_wait(req);
- if (!del_timer_sync(&timeout.timer))
+ if (!timer_delete_sync(&timeout.timer))
retval = -ETIMEDOUT;
else
retval = req->status;
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 26fd71a5f9b2..eebb24ab3ec8 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -204,7 +204,7 @@ static void __maybe_unused da8xx_musb_try_idle(struct musb *musb, unsigned long
musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) {
dev_dbg(musb->controller, "%s active, deleting timer\n",
usb_otg_state_string(musb->xceiv->otg->state));
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
last_timer = jiffies;
return;
}
@@ -290,7 +290,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
MUSB_HST_MODE(musb);
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
} else if (!(musb->int_usb & MUSB_INTR_BABBLE)) {
/*
* When babble condition happens, drvvbus interrupt
@@ -419,7 +419,7 @@ static int da8xx_musb_exit(struct musb *musb)
{
struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent);
- del_timer_sync(&musb->dev_timer);
+ timer_delete_sync(&musb->dev_timer);
phy_power_off(glue->phy);
phy_exit(glue->phy);
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c
index acdeb1117cd3..df56c972986f 100644
--- a/drivers/usb/musb/jz4740.c
+++ b/drivers/usb/musb/jz4740.c
@@ -59,7 +59,7 @@ static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci)
return IRQ_NONE;
}
-static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = {
+static const struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, },
@@ -205,7 +205,7 @@ static const struct musb_hdrc_platform_data jz4740_musb_pdata = {
.platform_ops = &jz4740_musb_ops,
};
-static struct musb_fifo_cfg jz4770_musb_fifo_cfg[] = {
+static const struct musb_fifo_cfg jz4770_musb_fifo_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
index aa988d74b58d..c6cbe718b1da 100644
--- a/drivers/usb/musb/mediatek.c
+++ b/drivers/usb/musb/mediatek.c
@@ -365,7 +365,7 @@ static const struct musb_platform_ops mtk_musb_ops = {
#define MTK_MUSB_MAX_EP_NUM 8
#define MTK_MUSB_RAM_BITS 11
-static struct musb_fifo_cfg mtk_musb_mode_cfg[] = {
+static const struct musb_fifo_cfg mtk_musb_mode_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
diff --git a/drivers/usb/musb/mpfs.c b/drivers/usb/musb/mpfs.c
index 7edc8429b274..020348a98514 100644
--- a/drivers/usb/musb/mpfs.c
+++ b/drivers/usb/musb/mpfs.c
@@ -29,7 +29,7 @@ struct mpfs_glue {
struct clk *clk;
};
-static struct musb_fifo_cfg mpfs_musb_mode_cfg[] = {
+static const struct musb_fifo_cfg mpfs_musb_mode_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -165,7 +165,7 @@ static void __maybe_unused mpfs_musb_try_idle(struct musb *musb, unsigned long t
musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) {
dev_dbg(musb->controller, "%s active, deleting timer\n",
usb_otg_state_string(musb->xceiv->otg->state));
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
last_timer = jiffies;
return;
}
@@ -232,7 +232,7 @@ static int mpfs_musb_init(struct musb *musb)
static int mpfs_musb_exit(struct musb *musb)
{
- del_timer_sync(&musb->dev_timer);
+ timer_delete_sync(&musb->dev_timer);
return 0;
}
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 7f349f5e781d..cbbb27178024 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -921,7 +921,7 @@ b_host:
musb_set_state(musb, OTG_STATE_B_HOST);
if (musb->hcd)
musb->hcd->self.is_b_host = 1;
- del_timer(&musb->otg_timer);
+ timer_delete(&musb->otg_timer);
break;
default:
if ((devctl & MUSB_DEVCTL_VBUS)
@@ -1015,7 +1015,7 @@ static void musb_handle_intr_reset(struct musb *musb)
+ msecs_to_jiffies(TA_WAIT_BCON(musb)));
break;
case OTG_STATE_A_PERIPHERAL:
- del_timer(&musb->otg_timer);
+ timer_delete(&musb->otg_timer);
musb_g_reset(musb);
break;
case OTG_STATE_B_WAIT_ACON:
@@ -1271,7 +1271,7 @@ MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration");
*/
/* mode 0 - fits in 2KB */
-static struct musb_fifo_cfg mode_0_cfg[] = {
+static const struct musb_fifo_cfg mode_0_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, },
@@ -1280,7 +1280,7 @@ static struct musb_fifo_cfg mode_0_cfg[] = {
};
/* mode 1 - fits in 4KB */
-static struct musb_fifo_cfg mode_1_cfg[] = {
+static const struct musb_fifo_cfg mode_1_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, },
@@ -1289,7 +1289,7 @@ static struct musb_fifo_cfg mode_1_cfg[] = {
};
/* mode 2 - fits in 4KB */
-static struct musb_fifo_cfg mode_2_cfg[] = {
+static const struct musb_fifo_cfg mode_2_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1299,7 +1299,7 @@ static struct musb_fifo_cfg mode_2_cfg[] = {
};
/* mode 3 - fits in 4KB */
-static struct musb_fifo_cfg mode_3_cfg[] = {
+static const struct musb_fifo_cfg mode_3_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1309,7 +1309,7 @@ static struct musb_fifo_cfg mode_3_cfg[] = {
};
/* mode 4 - fits in 16KB */
-static struct musb_fifo_cfg mode_4_cfg[] = {
+static const struct musb_fifo_cfg mode_4_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1340,7 +1340,7 @@ static struct musb_fifo_cfg mode_4_cfg[] = {
};
/* mode 5 - fits in 8KB */
-static struct musb_fifo_cfg mode_5_cfg[] = {
+static const struct musb_fifo_cfg mode_5_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
@@ -1447,7 +1447,7 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep,
return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0));
}
-static struct musb_fifo_cfg ep0_cfg = {
+static const struct musb_fifo_cfg ep0_cfg = {
.style = FIFO_RXTX, .maxpacket = 64,
};
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index f877faf5a930..e5e813f97fac 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -201,7 +201,7 @@ static void dsps_musb_disable(struct musb *musb)
musb_writel(reg_base, wrp->coreintr_clear, wrp->usb_bitmap);
musb_writel(reg_base, wrp->epintr_clear,
wrp->txep_bitmap | wrp->rxep_bitmap);
- del_timer_sync(&musb->dev_timer);
+ timer_delete_sync(&musb->dev_timer);
}
/* Caller must take musb->lock */
@@ -215,7 +215,7 @@ static int dsps_check_status(struct musb *musb, void *unused)
int skip_session = 0;
if (glue->vbus_irq)
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
/*
* We poll because DSPS IP's won't expose several OTG-critical
@@ -499,7 +499,7 @@ static int dsps_musb_exit(struct musb *musb)
struct device *dev = musb->controller;
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
- del_timer_sync(&musb->dev_timer);
+ timer_delete_sync(&musb->dev_timer);
phy_power_off(musb->phy);
phy_exit(musb->phy);
debugfs_remove_recursive(glue->dbgfs_root);
@@ -983,7 +983,7 @@ static int dsps_suspend(struct device *dev)
return ret;
}
- del_timer_sync(&musb->dev_timer);
+ timer_delete_sync(&musb->dev_timer);
mbase = musb->ctrl_base;
glue->context.control = musb_readl(mbase, wrp->control);
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index eac1cde86be3..a6bd3e968cc7 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -629,7 +629,7 @@ static const struct musb_platform_ops sunxi_musb_ops = {
#define SUNXI_MUSB_RAM_BITS 11
/* Allwinner OTG supports up to 5 endpoints */
-static struct musb_fifo_cfg sunxi_musb_mode_cfg_5eps[] = {
+static const struct musb_fifo_cfg sunxi_musb_mode_cfg_5eps[] = {
MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
@@ -643,7 +643,7 @@ static struct musb_fifo_cfg sunxi_musb_mode_cfg_5eps[] = {
};
/* H3/V3s OTG supports only 4 endpoints */
-static struct musb_fifo_cfg sunxi_musb_mode_cfg_4eps[] = {
+static const struct musb_fifo_cfg sunxi_musb_mode_cfg_4eps[] = {
MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 90b760a95e4e..abd2472da7f7 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -525,7 +525,7 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout)
&& (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON))) {
dev_dbg(musb->controller, "%s active, deleting timer\n",
usb_otg_state_string(musb->xceiv->otg->state));
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
last_timer = jiffies;
return;
}
@@ -875,7 +875,7 @@ static irqreturn_t tusb_musb_interrupt(int irq, void *__hci)
}
if (int_src & TUSB_INT_SRC_USB_IP_CONN)
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
/* OTG state change reports (annoyingly) not issued by Mentor core */
if (int_src & (TUSB_INT_SRC_VBUS_SENSE_CHNG
@@ -984,7 +984,7 @@ static void tusb_musb_disable(struct musb *musb)
musb_writel(tbase, TUSB_DMA_INT_MASK, 0x7fffffff);
musb_writel(tbase, TUSB_GPIO_INT_MASK, 0x1ff);
- del_timer(&musb->dev_timer);
+ timer_delete(&musb->dev_timer);
if (is_dma_capable() && !dma_off) {
printk(KERN_WARNING "%s %s: dma still active\n",
@@ -1174,7 +1174,7 @@ static int tusb_musb_exit(struct musb *musb)
{
struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent);
- del_timer_sync(&musb->dev_timer);
+ timer_delete_sync(&musb->dev_timer);
the_musb = NULL;
gpiod_set_value(glue->enable, 0);
diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c
index 30d6c8840a5e..638fba58420c 100644
--- a/drivers/usb/phy/phy-mv-usb.c
+++ b/drivers/usb/phy/phy-mv-usb.c
@@ -110,7 +110,7 @@ static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id)
timer = &mvotg->otg_ctrl.timer[id];
if (timer_pending(timer))
- del_timer(timer);
+ timer_delete(timer);
return 0;
}
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 7490f1798b46..7069dd3f4d0d 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -769,11 +769,9 @@ static int mxs_phy_probe(struct platform_device *pdev)
return PTR_ERR(base);
clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(clk)) {
- dev_err(&pdev->dev,
- "can't get the clock, err=%ld", PTR_ERR(clk));
- return PTR_ERR(clk);
- }
+ if (IS_ERR(clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+ "can't get the clock\n");
mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL);
if (!mxs_phy)
diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c
index e683a37e3a7a..4df63e67bb37 100644
--- a/drivers/usb/phy/phy-ulpi.c
+++ b/drivers/usb/phy/phy-ulpi.c
@@ -256,29 +256,6 @@ static void otg_ulpi_init(struct usb_phy *phy, struct usb_otg *otg,
}
struct usb_phy *
-otg_ulpi_create(struct usb_phy_io_ops *ops,
- unsigned int flags)
-{
- struct usb_phy *phy;
- struct usb_otg *otg;
-
- phy = kzalloc(sizeof(*phy), GFP_KERNEL);
- if (!phy)
- return NULL;
-
- otg = kzalloc(sizeof(*otg), GFP_KERNEL);
- if (!otg) {
- kfree(phy);
- return NULL;
- }
-
- otg_ulpi_init(phy, otg, ops, flags);
-
- return phy;
-}
-EXPORT_SYMBOL_GPL(otg_ulpi_create);
-
-struct usb_phy *
devm_otg_ulpi_create(struct device *dev,
struct usb_phy_io_ops *ops,
unsigned int flags)
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index ca3da79afd23..93710b762893 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -66,29 +66,16 @@
#define MOS_WDR_TIMEOUT 5000 /* default urb timeout */
-#define MOS_PORT1 0x0200
-#define MOS_PORT2 0x0300
-#define MOS_VENREG 0x0000
-#define MOS_MAX_PORT 0x02
-#define MOS_WRITE 0x0E
-#define MOS_READ 0x0D
-
/* Requests */
#define MCS_RD_RTYPE 0xC0
#define MCS_WR_RTYPE 0x40
#define MCS_RDREQ 0x0D
#define MCS_WRREQ 0x0E
-#define MCS_CTRL_TIMEOUT 500
#define VENDOR_READ_LENGTH (0x01)
-#define MAX_NAME_LEN 64
-
#define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */
#define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */
-/* For higher baud Rates use TIOCEXBAUD */
-#define TIOCEXBAUD 0x5462
-
/*
* Vendor id and device id defines
*
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 6263c4e61678..e01f3a42bde4 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -174,7 +174,7 @@ struct alauda_card_info {
unsigned char zoneshift; /* 1<<zs blocks per zone */
};
-static struct alauda_card_info alauda_card_ids[] = {
+static const struct alauda_card_info alauda_card_ids[] = {
/* NAND flash */
{ 0x6e, 20, 8, 4, 8}, /* 1 MB */
{ 0xe8, 20, 8, 4, 8}, /* 1 MB */
@@ -200,7 +200,7 @@ static struct alauda_card_info alauda_card_ids[] = {
{ 0,}
};
-static struct alauda_card_info *alauda_card_find_id(unsigned char id)
+static const struct alauda_card_info *alauda_card_find_id(unsigned char id)
{
int i;
@@ -383,7 +383,7 @@ static int alauda_init_media(struct us_data *us)
{
unsigned char *data = us->iobuf;
int ready = 0;
- struct alauda_card_info *media_info;
+ const struct alauda_card_info *media_info;
unsigned int num_zones;
while (ready == 0) {
@@ -1132,7 +1132,7 @@ static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
int rc;
struct alauda_info *info = (struct alauda_info *) us->extra;
unsigned char *ptr = us->iobuf;
- static unsigned char inquiry_response[36] = {
+ static const unsigned char inquiry_response[36] = {
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
};
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index bbfa2398b170..9ba369483c9b 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -319,7 +319,7 @@ static int datafab_determine_lun(struct us_data *us,
//
// There might be a better way of doing this?
- static unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
+ static const unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
unsigned char *command = us->iobuf;
unsigned char *buf;
int count = 0, rc;
@@ -384,7 +384,7 @@ static int datafab_id_device(struct us_data *us,
// to the ATA spec, 'Sector Count' isn't used but the Windows driver
// sets this bit so we do too...
//
- static unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
+ static const unsigned char scommand[8] = { 0, 1, 0, 0, 0, 0xa0, 0xec, 1 };
unsigned char *command = us->iobuf;
unsigned char *reply;
int rc;
@@ -437,16 +437,16 @@ static int datafab_handle_mode_sense(struct us_data *us,
struct scsi_cmnd * srb,
int sense_6)
{
- static unsigned char rw_err_page[12] = {
+ static const unsigned char rw_err_page[12] = {
0x1, 0xA, 0x21, 1, 0, 0, 0, 0, 1, 0, 0, 0
};
- static unsigned char cache_page[12] = {
+ static const unsigned char cache_page[12] = {
0x8, 0xA, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- static unsigned char rbac_page[12] = {
+ static const unsigned char rbac_page[12] = {
0x1B, 0xA, 0, 0x81, 0, 0, 0, 0, 0, 0, 0, 0
};
- static unsigned char timer_page[8] = {
+ static const unsigned char timer_page[8] = {
0x1C, 0x6, 0, 0, 0, 0
};
unsigned char pc, page_code;
@@ -550,7 +550,7 @@ static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us)
int rc;
unsigned long block, blocks;
unsigned char *ptr = us->iobuf;
- static unsigned char inquiry_reply[8] = {
+ static const unsigned char inquiry_reply[8] = {
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
};
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
index f8f9ce8dc710..b243bd5521a6 100644
--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -54,7 +54,7 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap*) us->iobuf;
int res;
unsigned int partial;
- static char init_string[] = "\xec\x0a\x06\x00$PCCHIPS";
+ static const char init_string[] = "\xec\x0a\x06\x00$PCCHIPS";
usb_stor_dbg(us, "Sending UCR-61S2B initialization packet...\n");
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index 39ca84d68591..089c6f8ac85f 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -367,16 +367,16 @@ static int jumpshot_handle_mode_sense(struct us_data *us,
struct scsi_cmnd * srb,
int sense_6)
{
- static unsigned char rw_err_page[12] = {
+ static const unsigned char rw_err_page[12] = {
0x1, 0xA, 0x21, 1, 0, 0, 0, 0, 1, 0, 0, 0
};
- static unsigned char cache_page[12] = {
+ static const unsigned char cache_page[12] = {
0x8, 0xA, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- static unsigned char rbac_page[12] = {
+ static const unsigned char rbac_page[12] = {
0x1B, 0xA, 0, 0x81, 0, 0, 0, 0, 0, 0, 0, 0
};
- static unsigned char timer_page[8] = {
+ static const unsigned char timer_page[8] = {
0x1C, 0x6, 0, 0, 0, 0
};
unsigned char pc, page_code;
@@ -477,7 +477,7 @@ static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us)
int rc;
unsigned long block, blocks;
unsigned char *ptr = us->iobuf;
- static unsigned char inquiry_response[8] = {
+ static const unsigned char inquiry_response[8] = {
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
};
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index 2a82ed7b68ea..b387863c245f 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -191,7 +191,7 @@ MODULE_DEVICE_TABLE(usb, realtek_cr_ids);
.initFunction = init_function, \
}
-static struct us_unusual_dev realtek_cr_unusual_dev_list[] = {
+static const struct us_unusual_dev realtek_cr_unusual_dev_list[] = {
# include "unusual_realtek.h"
{} /* Terminating entry */
};
@@ -797,10 +797,10 @@ static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra);
static int card_first_show = 1;
- static u8 media_not_present[] = { 0x70, 0, 0x02, 0, 0, 0, 0,
+ static const u8 media_not_present[] = { 0x70, 0, 0x02, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0x3A, 0, 0, 0, 0, 0
};
- static u8 invalid_cmd_field[] = { 0x70, 0, 0x05, 0, 0, 0, 0,
+ static const u8 invalid_cmd_field[] = { 0x70, 0, 0x05, 0, 0, 0, 0,
10, 0, 0, 0, 0, 0x24, 0, 0, 0, 0, 0
};
int ret;
@@ -934,7 +934,7 @@ static void realtek_cr_destructor(void *extra)
#ifdef CONFIG_REALTEK_AUTOPM
if (ss_en) {
- del_timer(&chip->rts51x_suspend_timer);
+ timer_delete(&chip->rts51x_suspend_timer);
chip->timer_expires = 0;
}
#endif
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index d21ce3466e25..e66b920e99e2 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -144,7 +144,7 @@ static inline char *nand_flash_manufacturer(int manuf_id) {
* 256 MB NAND flash has a 5-byte ID with 2nd byte 0xaa, 0xba, 0xca or 0xda.
*/
-static struct nand_flash_dev nand_flash_ids[] = {
+static const struct nand_flash_dev nand_flash_ids[] = {
/* NAND flash */
{ 0x6e, 20, 8, 4, 8, 2}, /* 1 MB */
{ 0xe8, 20, 8, 4, 8, 2}, /* 1 MB */
@@ -169,7 +169,7 @@ static struct nand_flash_dev nand_flash_ids[] = {
{ 0,}
};
-static struct nand_flash_dev *
+static const struct nand_flash_dev *
nand_find_id(unsigned char id) {
int i;
@@ -1133,9 +1133,9 @@ sddr09_reset(struct us_data *us) {
}
#endif
-static struct nand_flash_dev *
+static const struct nand_flash_dev *
sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
- struct nand_flash_dev *cardinfo;
+ const struct nand_flash_dev *cardinfo;
unsigned char deviceID[4];
char blurbtxt[256];
int result;
@@ -1545,12 +1545,12 @@ static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
struct sddr09_card_info *info;
- static unsigned char inquiry_response[8] = {
+ static const unsigned char inquiry_response[8] = {
0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00
};
/* note: no block descriptor support */
- static unsigned char mode_page_01[19] = {
+ static const unsigned char mode_page_01[19] = {
0x00, 0x0F, 0x00, 0x0, 0x0, 0x0, 0x00,
0x01, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -1584,7 +1584,7 @@ static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
}
if (srb->cmnd[0] == READ_CAPACITY) {
- struct nand_flash_dev *cardinfo;
+ const struct nand_flash_dev *cardinfo;
sddr09_get_wp(us, info); /* read WP bit */
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index d5cdff30f6f3..b323f0a36260 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -775,11 +775,11 @@ static void sddr55_card_info_destructor(void *extra) {
static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int result;
- static unsigned char inquiry_response[8] = {
+ static const unsigned char inquiry_response[8] = {
0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00
};
// write-protected for now, no block descriptor support
- static unsigned char mode_page_01[20] = {
+ static const unsigned char mode_page_01[20] = {
0x0, 0x12, 0x00, 0x80, 0x0, 0x0, 0x0, 0x0,
0x01, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index c33cbf177e6f..27faa0ead11d 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -1683,7 +1683,7 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
struct usbat_info *info = (struct usbat_info *) (us->extra);
unsigned long block, blocks;
unsigned char *ptr = us->iobuf;
- static unsigned char inquiry_response[36] = {
+ static const unsigned char inquiry_response[36] = {
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
};
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e6bc8ecaecbb..1aa1bd26c81f 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -528,7 +528,7 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
u32 sector;
/* To Report "Medium Error: Record Not Found */
- static unsigned char record_not_found[18] = {
+ static const unsigned char record_not_found[18] = {
[0] = 0x70, /* current error */
[2] = MEDIUM_ERROR, /* = 0x03 */
[7] = 0x0a, /* additional length */
diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c
index 1b475b1d98e7..6eadf7835f8f 100644
--- a/drivers/usb/typec/altmodes/thunderbolt.c
+++ b/drivers/usb/typec/altmodes/thunderbolt.c
@@ -112,7 +112,7 @@ static void tbt_altmode_work(struct work_struct *work)
return;
disable_plugs:
- for (int i = TYPEC_PLUG_SOP_PP; i > 0; --i) {
+ for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) {
if (tbt->plug[i])
typec_altmode_put_plug(tbt->plug[i]);
@@ -143,7 +143,7 @@ static int tbt_enter_modes_ordered(struct typec_altmode *alt)
if (tbt->plug[TYPEC_PLUG_SOP_P]) {
ret = typec_cable_altmode_enter(alt, TYPEC_PLUG_SOP_P, NULL);
if (ret < 0) {
- for (int i = TYPEC_PLUG_SOP_PP; i > 0; --i) {
+ for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) {
if (tbt->plug[i])
typec_altmode_put_plug(tbt->plug[i]);
@@ -324,7 +324,7 @@ static void tbt_altmode_remove(struct typec_altmode *alt)
{
struct tbt_altmode *tbt = typec_altmode_get_drvdata(alt);
- for (int i = TYPEC_PLUG_SOP_PP; i > 0; --i) {
+ for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) {
if (tbt->plug[i])
typec_altmode_put_plug(tbt->plug[i]);
}
@@ -351,10 +351,10 @@ static bool tbt_ready(struct typec_altmode *alt)
*/
for (int i = 0; i < TYPEC_PLUG_SOP_PP + 1; i++) {
plug = typec_altmode_get_plug(tbt->alt, i);
- if (IS_ERR(plug))
+ if (!plug)
continue;
- if (!plug || plug->svid != USB_TYPEC_TBT_SID)
+ if (plug->svid != USB_TYPEC_TBT_SID)
break;
plug->desc = "Thunderbolt3";
diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
index 67381b4ef4f6..6dd8f961b593 100644
--- a/drivers/usb/typec/mux/Kconfig
+++ b/drivers/usb/typec/mux/Kconfig
@@ -56,6 +56,16 @@ config TYPEC_MUX_NB7VPQ904M
Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
redriver chip found on some devices with a Type-C port.
+config TYPEC_MUX_PS883X
+ tristate "Parade PS883x Type-C retimer driver"
+ depends on I2C
+ depends on DRM || DRM=n
+ select DRM_AUX_BRIDGE if DRM_BRIDGE && OF
+ select REGMAP_I2C
+ help
+ Say Y or M if your system has a Parade PS883x Type-C retimer chip
+ found on some devices with a Type-C port.
+
config TYPEC_MUX_PTN36502
tristate "NXP PTN36502 Type-C redriver driver"
depends on I2C
diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
index 60879446da93..b4f599eb5053 100644
--- a/drivers/usb/typec/mux/Makefile
+++ b/drivers/usb/typec/mux/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_TYPEC_MUX_PI3USB30532) += pi3usb30532.o
obj-$(CONFIG_TYPEC_MUX_INTEL_PMC) += intel_pmc_mux.o
obj-$(CONFIG_TYPEC_MUX_IT5205) += it5205.o
obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M) += nb7vpq904m.o
+obj-$(CONFIG_TYPEC_MUX_PS883X) += ps883x.o
obj-$(CONFIG_TYPEC_MUX_PTN36502) += ptn36502.o
obj-$(CONFIG_TYPEC_MUX_TUSB1046) += tusb1046.o
obj-$(CONFIG_TYPEC_MUX_WCD939X_USBSS) += wcd939x-usbss.o
diff --git a/drivers/usb/typec/mux/ps883x.c b/drivers/usb/typec/mux/ps883x.c
new file mode 100644
index 000000000000..ad59babf7cce
--- /dev/null
+++ b/drivers/usb/typec/mux/ps883x.c
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Parade ps883x usb retimer driver
+ *
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <drm/bridge/aux-bridge.h>
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/usb/typec_retimer.h>
+
+#define REG_USB_PORT_CONN_STATUS_0 0x00
+
+#define CONN_STATUS_0_CONNECTION_PRESENT BIT(0)
+#define CONN_STATUS_0_ORIENTATION_REVERSED BIT(1)
+#define CONN_STATUS_0_USB_3_1_CONNECTED BIT(5)
+
+#define REG_USB_PORT_CONN_STATUS_1 0x01
+
+#define CONN_STATUS_1_DP_CONNECTED BIT(0)
+#define CONN_STATUS_1_DP_SINK_REQUESTED BIT(1)
+#define CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D BIT(2)
+#define CONN_STATUS_1_DP_HPD_LEVEL BIT(7)
+
+#define REG_USB_PORT_CONN_STATUS_2 0x02
+
+struct ps883x_retimer {
+ struct i2c_client *client;
+ struct gpio_desc *reset_gpio;
+ struct regmap *regmap;
+ struct typec_switch_dev *sw;
+ struct typec_retimer *retimer;
+ struct clk *xo_clk;
+ struct regulator *vdd_supply;
+ struct regulator *vdd33_supply;
+ struct regulator *vdd33_cap_supply;
+ struct regulator *vddat_supply;
+ struct regulator *vddar_supply;
+ struct regulator *vddio_supply;
+
+ struct typec_switch *typec_switch;
+ struct typec_mux *typec_mux;
+
+ struct mutex lock; /* protect non-concurrent retimer & switch */
+
+ enum typec_orientation orientation;
+ unsigned long mode;
+ unsigned int svid;
+};
+
+static int ps883x_configure(struct ps883x_retimer *retimer, int cfg0,
+ int cfg1, int cfg2)
+{
+ struct device *dev = &retimer->client->dev;
+ int ret;
+
+ ret = regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_0, cfg0);
+ if (ret) {
+ dev_err(dev, "failed to write conn_status_0: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_1, cfg1);
+ if (ret) {
+ dev_err(dev, "failed to write conn_status_1: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_2, cfg2);
+ if (ret) {
+ dev_err(dev, "failed to write conn_status_2: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ps883x_set(struct ps883x_retimer *retimer)
+{
+ int cfg0 = CONN_STATUS_0_CONNECTION_PRESENT;
+ int cfg1 = 0x00;
+ int cfg2 = 0x00;
+
+ if (retimer->orientation == TYPEC_ORIENTATION_NONE ||
+ retimer->mode == TYPEC_STATE_SAFE) {
+ return ps883x_configure(retimer, cfg0, cfg1, cfg2);
+ }
+
+ if (retimer->mode != TYPEC_STATE_USB && retimer->svid != USB_TYPEC_DP_SID)
+ return -EINVAL;
+
+ if (retimer->orientation == TYPEC_ORIENTATION_REVERSE)
+ cfg0 |= CONN_STATUS_0_ORIENTATION_REVERSED;
+
+ switch (retimer->mode) {
+ case TYPEC_STATE_USB:
+ cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED;
+ break;
+
+ case TYPEC_DP_STATE_C:
+ cfg1 = CONN_STATUS_1_DP_CONNECTED |
+ CONN_STATUS_1_DP_SINK_REQUESTED |
+ CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D |
+ CONN_STATUS_1_DP_HPD_LEVEL;
+ break;
+
+ case TYPEC_DP_STATE_D:
+ cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED;
+ cfg1 = CONN_STATUS_1_DP_CONNECTED |
+ CONN_STATUS_1_DP_SINK_REQUESTED |
+ CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D |
+ CONN_STATUS_1_DP_HPD_LEVEL;
+ break;
+
+ case TYPEC_DP_STATE_E:
+ cfg1 = CONN_STATUS_1_DP_CONNECTED |
+ CONN_STATUS_1_DP_HPD_LEVEL;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return ps883x_configure(retimer, cfg0, cfg1, cfg2);
+}
+
+static int ps883x_sw_set(struct typec_switch_dev *sw,
+ enum typec_orientation orientation)
+{
+ struct ps883x_retimer *retimer = typec_switch_get_drvdata(sw);
+ int ret = 0;
+
+ ret = typec_switch_set(retimer->typec_switch, orientation);
+ if (ret)
+ return ret;
+
+ mutex_lock(&retimer->lock);
+
+ if (retimer->orientation != orientation) {
+ retimer->orientation = orientation;
+
+ ret = ps883x_set(retimer);
+ }
+
+ mutex_unlock(&retimer->lock);
+
+ return ret;
+}
+
+static int ps883x_retimer_set(struct typec_retimer *rtmr,
+ struct typec_retimer_state *state)
+{
+ struct ps883x_retimer *retimer = typec_retimer_get_drvdata(rtmr);
+ struct typec_mux_state mux_state;
+ int ret = 0;
+
+ mutex_lock(&retimer->lock);
+
+ if (state->mode != retimer->mode) {
+ retimer->mode = state->mode;
+
+ if (state->alt)
+ retimer->svid = state->alt->svid;
+ else
+ retimer->svid = 0;
+
+ ret = ps883x_set(retimer);
+ }
+
+ mutex_unlock(&retimer->lock);
+
+ if (ret)
+ return ret;
+
+ mux_state.alt = state->alt;
+ mux_state.data = state->data;
+ mux_state.mode = state->mode;
+
+ return typec_mux_set(retimer->typec_mux, &mux_state);
+}
+
+static int ps883x_enable_vregs(struct ps883x_retimer *retimer)
+{
+ struct device *dev = &retimer->client->dev;
+ int ret;
+
+ ret = regulator_enable(retimer->vdd33_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD 3.3V regulator: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_enable(retimer->vdd33_cap_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD 3.3V CAP regulator: %d\n", ret);
+ goto err_vdd33_disable;
+ }
+
+ usleep_range(4000, 10000);
+
+ ret = regulator_enable(retimer->vdd_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD regulator: %d\n", ret);
+ goto err_vdd33_cap_disable;
+ }
+
+ ret = regulator_enable(retimer->vddar_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD AR regulator: %d\n", ret);
+ goto err_vdd_disable;
+ }
+
+ ret = regulator_enable(retimer->vddat_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD AT regulator: %d\n", ret);
+ goto err_vddar_disable;
+ }
+
+ ret = regulator_enable(retimer->vddio_supply);
+ if (ret) {
+ dev_err(dev, "cannot enable VDD IO regulator: %d\n", ret);
+ goto err_vddat_disable;
+ }
+
+ return 0;
+
+err_vddat_disable:
+ regulator_disable(retimer->vddat_supply);
+err_vddar_disable:
+ regulator_disable(retimer->vddar_supply);
+err_vdd_disable:
+ regulator_disable(retimer->vdd_supply);
+err_vdd33_cap_disable:
+ regulator_disable(retimer->vdd33_cap_supply);
+err_vdd33_disable:
+ regulator_disable(retimer->vdd33_supply);
+
+ return ret;
+}
+
+static void ps883x_disable_vregs(struct ps883x_retimer *retimer)
+{
+ regulator_disable(retimer->vddio_supply);
+ regulator_disable(retimer->vddat_supply);
+ regulator_disable(retimer->vddar_supply);
+ regulator_disable(retimer->vdd_supply);
+ regulator_disable(retimer->vdd33_cap_supply);
+ regulator_disable(retimer->vdd33_supply);
+}
+
+static int ps883x_get_vregs(struct ps883x_retimer *retimer)
+{
+ struct device *dev = &retimer->client->dev;
+
+ retimer->vdd_supply = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(retimer->vdd_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vdd_supply),
+ "failed to get VDD\n");
+
+ retimer->vdd33_supply = devm_regulator_get(dev, "vdd33");
+ if (IS_ERR(retimer->vdd33_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vdd33_supply),
+ "failed to get VDD 3.3V\n");
+
+ retimer->vdd33_cap_supply = devm_regulator_get(dev, "vdd33-cap");
+ if (IS_ERR(retimer->vdd33_cap_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vdd33_cap_supply),
+ "failed to get VDD CAP 3.3V\n");
+
+ retimer->vddat_supply = devm_regulator_get(dev, "vddat");
+ if (IS_ERR(retimer->vddat_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vddat_supply),
+ "failed to get VDD AT\n");
+
+ retimer->vddar_supply = devm_regulator_get(dev, "vddar");
+ if (IS_ERR(retimer->vddar_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vddar_supply),
+ "failed to get VDD AR\n");
+
+ retimer->vddio_supply = devm_regulator_get(dev, "vddio");
+ if (IS_ERR(retimer->vddio_supply))
+ return dev_err_probe(dev, PTR_ERR(retimer->vddio_supply),
+ "failed to get VDD IO\n");
+
+ return 0;
+}
+
+static const struct regmap_config ps883x_retimer_regmap = {
+ .max_register = 0x1f,
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int ps883x_retimer_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct typec_switch_desc sw_desc = { };
+ struct typec_retimer_desc rtmr_desc = { };
+ struct ps883x_retimer *retimer;
+ unsigned int val;
+ int ret;
+
+ retimer = devm_kzalloc(dev, sizeof(*retimer), GFP_KERNEL);
+ if (!retimer)
+ return -ENOMEM;
+
+ retimer->client = client;
+
+ mutex_init(&retimer->lock);
+
+ retimer->regmap = devm_regmap_init_i2c(client, &ps883x_retimer_regmap);
+ if (IS_ERR(retimer->regmap))
+ return dev_err_probe(dev, PTR_ERR(retimer->regmap),
+ "failed to allocate register map\n");
+
+ ret = ps883x_get_vregs(retimer);
+ if (ret)
+ return ret;
+
+ retimer->xo_clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(retimer->xo_clk))
+ return dev_err_probe(dev, PTR_ERR(retimer->xo_clk),
+ "failed to get xo clock\n");
+
+ retimer->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+ if (IS_ERR(retimer->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(retimer->reset_gpio),
+ "failed to get reset gpio\n");
+
+ retimer->typec_switch = typec_switch_get(dev);
+ if (IS_ERR(retimer->typec_switch))
+ return dev_err_probe(dev, PTR_ERR(retimer->typec_switch),
+ "failed to acquire orientation-switch\n");
+
+ retimer->typec_mux = typec_mux_get(dev);
+ if (IS_ERR(retimer->typec_mux)) {
+ ret = dev_err_probe(dev, PTR_ERR(retimer->typec_mux),
+ "failed to acquire mode-mux\n");
+ goto err_switch_put;
+ }
+
+ ret = drm_aux_bridge_register(dev);
+ if (ret)
+ goto err_mux_put;
+
+ ret = ps883x_enable_vregs(retimer);
+ if (ret)
+ goto err_mux_put;
+
+ ret = clk_prepare_enable(retimer->xo_clk);
+ if (ret) {
+ dev_err(dev, "failed to enable XO: %d\n", ret);
+ goto err_vregs_disable;
+ }
+
+ /* skip resetting if already configured */
+ if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
+ CONN_STATUS_0_CONNECTION_PRESENT) == 1) {
+ gpiod_direction_output(retimer->reset_gpio, 0);
+ } else {
+ gpiod_direction_output(retimer->reset_gpio, 1);
+
+ /* VDD IO supply enable to reset release delay */
+ usleep_range(4000, 14000);
+
+ gpiod_set_value(retimer->reset_gpio, 0);
+
+ /* firmware initialization delay */
+ msleep(60);
+
+ /* make sure device is accessible */
+ ret = regmap_read(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
+ &val);
+ if (ret) {
+ dev_err(dev, "failed to read conn_status_0: %d\n", ret);
+ if (ret == -ENXIO)
+ ret = -EIO;
+ goto err_clk_disable;
+ }
+ }
+
+ sw_desc.drvdata = retimer;
+ sw_desc.fwnode = dev_fwnode(dev);
+ sw_desc.set = ps883x_sw_set;
+
+ retimer->sw = typec_switch_register(dev, &sw_desc);
+ if (IS_ERR(retimer->sw)) {
+ ret = PTR_ERR(retimer->sw);
+ dev_err(dev, "failed to register typec switch: %d\n", ret);
+ goto err_clk_disable;
+ }
+
+ rtmr_desc.drvdata = retimer;
+ rtmr_desc.fwnode = dev_fwnode(dev);
+ rtmr_desc.set = ps883x_retimer_set;
+
+ retimer->retimer = typec_retimer_register(dev, &rtmr_desc);
+ if (IS_ERR(retimer->retimer)) {
+ ret = PTR_ERR(retimer->retimer);
+ dev_err(dev, "failed to register typec retimer: %d\n", ret);
+ goto err_switch_unregister;
+ }
+
+ return 0;
+
+err_switch_unregister:
+ typec_switch_unregister(retimer->sw);
+err_clk_disable:
+ clk_disable_unprepare(retimer->xo_clk);
+err_vregs_disable:
+ gpiod_set_value(retimer->reset_gpio, 1);
+ ps883x_disable_vregs(retimer);
+err_mux_put:
+ typec_mux_put(retimer->typec_mux);
+err_switch_put:
+ typec_switch_put(retimer->typec_switch);
+
+ return ret;
+}
+
+static void ps883x_retimer_remove(struct i2c_client *client)
+{
+ struct ps883x_retimer *retimer = i2c_get_clientdata(client);
+
+ typec_retimer_unregister(retimer->retimer);
+ typec_switch_unregister(retimer->sw);
+
+ gpiod_set_value(retimer->reset_gpio, 1);
+
+ clk_disable_unprepare(retimer->xo_clk);
+
+ ps883x_disable_vregs(retimer);
+
+ typec_mux_put(retimer->typec_mux);
+ typec_switch_put(retimer->typec_switch);
+}
+
+static const struct of_device_id ps883x_retimer_of_table[] = {
+ { .compatible = "parade,ps8830" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ps883x_retimer_of_table);
+
+static struct i2c_driver ps883x_retimer_driver = {
+ .driver = {
+ .name = "ps883x_retimer",
+ .of_match_table = ps883x_retimer_of_table,
+ },
+ .probe = ps883x_retimer_probe,
+ .remove = ps883x_retimer_remove,
+};
+
+module_i2c_driver(ps883x_retimer_driver);
+
+MODULE_DESCRIPTION("Parade ps883x Type-C Retimer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c
index c605c8616726..4ec1c6d22310 100644
--- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c
+++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c
@@ -105,12 +105,13 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd)
return 0;
}
-static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd)
+static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci,
+ void *data, size_t size)
{
struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi);
int ret;
- ret = ucsi_sync_control_common(ucsi, cmd);
+ ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size);
switch (ret) {
case -EBUSY:
/* EC may return -EBUSY if CCI.busy is set.
@@ -205,12 +206,19 @@ static int cros_ucsi_event(struct notifier_block *nb,
{
struct cros_ucsi_data *udata = container_of(nb, struct cros_ucsi_data, nb);
- if (!(host_event & PD_EVENT_PPM))
- return NOTIFY_OK;
+ if (host_event & PD_EVENT_INIT) {
+ /* Late init event received from ChromeOS EC. Treat this as a
+ * system resume to re-enable communication with the PPM.
+ */
+ dev_dbg(udata->dev, "Late PD init received\n");
+ ucsi_resume(udata->ucsi);
+ }
- dev_dbg(udata->dev, "UCSI notification received\n");
- flush_work(&udata->work);
- schedule_work(&udata->work);
+ if (host_event & PD_EVENT_PPM) {
+ dev_dbg(udata->dev, "UCSI notification received\n");
+ flush_work(&udata->work);
+ schedule_work(&udata->work);
+ }
return NOTIFY_OK;
}
diff --git a/drivers/usb/typec/ucsi/debugfs.c b/drivers/usb/typec/ucsi/debugfs.c
index 83ff23086d79..eae2b18a2d8a 100644
--- a/drivers/usb/typec/ucsi/debugfs.c
+++ b/drivers/usb/typec/ucsi/debugfs.c
@@ -28,11 +28,12 @@ static int ucsi_cmd(void *data, u64 val)
ucsi->debugfs->status = 0;
switch (UCSI_COMMAND(val)) {
- case UCSI_SET_UOM:
+ case UCSI_SET_CCOM:
case UCSI_SET_UOR:
case UCSI_SET_PDR:
case UCSI_CONNECTOR_RESET:
case UCSI_SET_SINK_PATH:
+ case UCSI_SET_NEW_CAM:
ret = ucsi_send_command(ucsi, val, NULL, 0);
break;
case UCSI_GET_CAPABILITY:
@@ -42,6 +43,9 @@ static int ucsi_cmd(void *data, u64 val)
case UCSI_GET_PDOS:
case UCSI_GET_CABLE_PROPERTY:
case UCSI_GET_CONNECTOR_STATUS:
+ case UCSI_GET_ERROR_STATUS:
+ case UCSI_GET_CAM_CS:
+ case UCSI_GET_LPM_PPM_INFO:
ret = ucsi_send_command(ucsi, val,
&ucsi->debugfs->response,
sizeof(ucsi->debugfs->response));
diff --git a/drivers/usb/typec/ucsi/trace.c b/drivers/usb/typec/ucsi/trace.c
index cb62ad835761..596a9542d401 100644
--- a/drivers/usb/typec/ucsi/trace.c
+++ b/drivers/usb/typec/ucsi/trace.c
@@ -12,7 +12,7 @@ static const char * const ucsi_cmd_strs[] = {
[UCSI_SET_NOTIFICATION_ENABLE] = "SET_NOTIFICATION_ENABLE",
[UCSI_GET_CAPABILITY] = "GET_CAPABILITY",
[UCSI_GET_CONNECTOR_CAPABILITY] = "GET_CONNECTOR_CAPABILITY",
- [UCSI_SET_UOM] = "SET_UOM",
+ [UCSI_SET_CCOM] = "SET_CCOM",
[UCSI_SET_UOR] = "SET_UOR",
[UCSI_SET_PDM] = "SET_PDM",
[UCSI_SET_PDR] = "SET_PDR",
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 2a2915b0a645..e8c7e9dc4930 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -55,7 +55,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
}
EXPORT_SYMBOL_GPL(ucsi_notify_common);
-int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
+int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size)
{
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
int ret;
@@ -80,6 +81,13 @@ out_clear_bit:
else
clear_bit(COMMAND_PENDING, &ucsi->flags);
+ if (!ret && cci)
+ ret = ucsi->ops->read_cci(ucsi, cci);
+
+ if (!ret && data &&
+ (*cci & UCSI_CCI_COMMAND_COMPLETE))
+ ret = ucsi->ops->read_message_in(ucsi, data, size);
+
return ret;
}
EXPORT_SYMBOL_GPL(ucsi_sync_control_common);
@@ -95,7 +103,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
}
- return ucsi->ops->sync_control(ucsi, ctrl);
+ return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0);
}
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
@@ -108,9 +116,7 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
if (size > UCSI_MAX_DATA_LENGTH(ucsi))
return -EINVAL;
- ret = ucsi->ops->sync_control(ucsi, command);
- if (ucsi->ops->read_cci(ucsi, cci))
- return -EIO;
+ ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);
if (*cci & UCSI_CCI_BUSY)
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY;
@@ -127,9 +133,6 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
else
err = 0;
- if (!err && data && UCSI_CCI_LENGTH(*cci))
- err = ucsi->ops->read_message_in(ucsi, data, size);
-
/*
* Don't ACK connection change if there was an error.
*/
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 28780acc4af2..3a2c1762bec1 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -79,7 +79,8 @@ struct ucsi_operations {
int (*read_cci)(struct ucsi *ucsi, u32 *cci);
int (*poll_cci)(struct ucsi *ucsi, u32 *cci);
int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len);
- int (*sync_control)(struct ucsi *ucsi, u64 command);
+ int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size);
int (*async_control)(struct ucsi *ucsi, u64 command);
bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig,
struct ucsi_altmode *updated);
@@ -108,7 +109,7 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
#define UCSI_GET_CAPABILITY_SIZE 128
#define UCSI_GET_CONNECTOR_CAPABILITY 0x07
#define UCSI_GET_CONNECTOR_CAPABILITY_SIZE 32
-#define UCSI_SET_UOM 0x08
+#define UCSI_SET_CCOM 0x08
#define UCSI_SET_UOR 0x09
#define UCSI_SET_PDM 0x0a
#define UCSI_SET_PDR 0x0b
@@ -123,7 +124,9 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
#define UCSI_GET_CONNECTOR_STATUS_SIZE 152
#define UCSI_GET_ERROR_STATUS 0x13
#define UCSI_GET_PD_MESSAGE 0x15
+#define UCSI_GET_CAM_CS 0x18
#define UCSI_SET_SINK_PATH 0x1c
+#define UCSI_GET_LPM_PPM_INFO 0x22
#define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16)
#define UCSI_COMMAND(_cmd_) ((_cmd_) & 0xff)
@@ -531,7 +534,8 @@ void ucsi_altmode_update_active(struct ucsi_connector *con);
int ucsi_resume(struct ucsi *ucsi);
void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
-int ucsi_sync_control_common(struct ucsi *ucsi, u64 command);
+int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size);
#if IS_ENABLED(CONFIG_POWER_SUPPLY)
int ucsi_register_port_psy(struct ucsi_connector *con);
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index ac1ebb5d9527..6b92f296e985 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -105,17 +105,23 @@ static const struct ucsi_operations ucsi_acpi_ops = {
.async_control = ucsi_acpi_async_control
};
-static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_len)
+static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *val, size_t len)
{
u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE |
UCSI_CONSTAT_PDOS_CHANGE;
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
int ret;
- ret = ucsi_acpi_read_message_in(ucsi, val, val_len);
+ ret = ucsi_sync_control_common(ucsi, command, cci, val, len);
if (ret < 0)
return ret;
+ if (UCSI_COMMAND(ua->cmd) == UCSI_GET_PDOS &&
+ ua->cmd & UCSI_GET_PDOS_PARTNER_PDO(1) &&
+ ua->cmd & UCSI_GET_PDOS_SRC_PDOS)
+ ua->check_bogus_event = true;
+
if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS &&
ua->check_bogus_event) {
/* Clear the bogus change */
@@ -128,28 +134,11 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
return ret;
}
-static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command)
-{
- struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
- int ret;
-
- ret = ucsi_sync_control_common(ucsi, command);
- if (ret < 0)
- return ret;
-
- if (UCSI_COMMAND(ua->cmd) == UCSI_GET_PDOS &&
- ua->cmd & UCSI_GET_PDOS_PARTNER_PDO(1) &&
- ua->cmd & UCSI_GET_PDOS_SRC_PDOS)
- ua->check_bogus_event = true;
-
- return ret;
-}
-
static const struct ucsi_operations ucsi_gram_ops = {
.read_version = ucsi_acpi_read_version,
.read_cci = ucsi_acpi_read_cci,
.poll_cci = ucsi_acpi_poll_cci,
- .read_message_in = ucsi_gram_read_message_in,
+ .read_message_in = ucsi_acpi_read_message_in,
.sync_control = ucsi_gram_sync_control,
.async_control = ucsi_acpi_async_control
};
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 4b1668733a4b..f01e4ef6619d 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -222,7 +222,6 @@ struct ucsi_ccg {
u16 fw_build;
struct work_struct pm_work;
- u64 last_cmd_sent;
bool has_multiple_dp;
struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES];
struct ucsi_ccg_altmode updated[UCSI_MAX_ALTMODES];
@@ -538,9 +537,10 @@ static void ucsi_ccg_update_set_new_cam_cmd(struct ucsi_ccg *uc,
* first and then vdo=0x3
*/
static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc,
- struct ucsi_altmode *alt)
+ struct ucsi_altmode *alt,
+ u64 command)
{
- switch (UCSI_ALTMODE_OFFSET(uc->last_cmd_sent)) {
+ switch (UCSI_ALTMODE_OFFSET(command)) {
case NVIDIA_FTB_DP_OFFSET:
if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DBG_VDO)
alt[0].mid = USB_TYPEC_NVIDIA_VLINK_DP_VDO |
@@ -578,37 +578,11 @@ static int ucsi_ccg_read_cci(struct ucsi *ucsi, u32 *cci)
static int ucsi_ccg_read_message_in(struct ucsi *ucsi, void *val, size_t val_len)
{
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
- struct ucsi_capability *cap;
- struct ucsi_altmode *alt;
spin_lock(&uc->op_lock);
memcpy(val, uc->op_data.message_in, val_len);
spin_unlock(&uc->op_lock);
- switch (UCSI_COMMAND(uc->last_cmd_sent)) {
- case UCSI_GET_CURRENT_CAM:
- if (uc->has_multiple_dp)
- ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)val);
- break;
- case UCSI_GET_ALTERNATE_MODES:
- if (UCSI_ALTMODE_RECIPIENT(uc->last_cmd_sent) ==
- UCSI_RECIPIENT_SOP) {
- alt = val;
- if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
- ucsi_ccg_nvidia_altmode(uc, alt);
- }
- break;
- case UCSI_GET_CAPABILITY:
- if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
- cap = val;
- cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
- }
- break;
- default:
- break;
- }
- uc->last_cmd_sent = 0;
-
return 0;
}
@@ -628,7 +602,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command)
return ccg_write(uc, reg, (u8 *)&command, sizeof(command));
}
-static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
+static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size)
{
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
struct ucsi_connector *con;
@@ -638,11 +613,9 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
mutex_lock(&uc->lock);
pm_runtime_get_sync(uc->dev);
- uc->last_cmd_sent = command;
-
- if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM &&
+ if (UCSI_COMMAND(command) == UCSI_SET_NEW_CAM &&
uc->has_multiple_dp) {
- con_index = (uc->last_cmd_sent >> 16) &
+ con_index = (command >> 16) &
UCSI_CMD_CONNECTOR_MASK;
if (con_index == 0) {
ret = -EINVAL;
@@ -652,7 +625,31 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
}
- ret = ucsi_sync_control_common(ucsi, command);
+ ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
+
+ switch (UCSI_COMMAND(command)) {
+ case UCSI_GET_CURRENT_CAM:
+ if (uc->has_multiple_dp)
+ ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)data);
+ break;
+ case UCSI_GET_ALTERNATE_MODES:
+ if (UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_SOP) {
+ struct ucsi_altmode *alt = data;
+
+ if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
+ ucsi_ccg_nvidia_altmode(uc, alt, command);
+ }
+ break;
+ case UCSI_GET_CAPABILITY:
+ if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
+ struct ucsi_capability *cap = data;
+
+ cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
+ }
+ break;
+ default:
+ break;
+ }
err_put:
pm_runtime_put_sync(uc->dev);
@@ -1391,22 +1388,35 @@ static ssize_t do_flash_store(struct device *dev,
if (!flash)
return n;
- if (uc->fw_build == 0x0) {
- dev_err(dev, "fail to flash FW due to missing FW build info\n");
- return -EINVAL;
- }
-
schedule_work(&uc->work);
return n;
}
+static umode_t ucsi_ccg_attrs_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct ucsi_ccg *uc = i2c_get_clientdata(to_i2c_client(dev));
+
+ if (!uc->fw_build)
+ return 0;
+
+ return attr->mode;
+}
+
static DEVICE_ATTR_WO(do_flash);
static struct attribute *ucsi_ccg_attrs[] = {
&dev_attr_do_flash.attr,
NULL,
};
-ATTRIBUTE_GROUPS(ucsi_ccg);
+static struct attribute_group ucsi_ccg_attr_group = {
+ .attrs = ucsi_ccg_attrs,
+ .is_visible = ucsi_ccg_attrs_is_visible,
+};
+static const struct attribute_group *ucsi_ccg_groups[] = {
+ &ucsi_ccg_attr_group,
+ NULL,
+};
static int ucsi_ccg_probe(struct i2c_client *client)
{
@@ -1433,11 +1443,10 @@ static int ucsi_ccg_probe(struct i2c_client *client)
uc->fw_build = CCG_FW_BUILD_NVIDIA_TEGRA;
else if (!strcmp(fw_name, "nvidia,gpu"))
uc->fw_build = CCG_FW_BUILD_NVIDIA;
+ if (!uc->fw_build)
+ dev_err(uc->dev, "failed to get FW build information\n");
}
- if (!uc->fw_build)
- dev_err(uc->dev, "failed to get FW build information\n");
-
/* reset ccg device and initialize ucsi */
status = ucsi_ccg_init(uc);
if (status < 0) {
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 8455f08f5d40..61424342c096 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -190,9 +190,12 @@ again:
klm->bcount = cpu_to_be32(klm_bcount(dmr->end - dmr->start));
preve = dmr->end;
} else {
+ u64 bcount = min_t(u64, dmr->start - preve, MAX_KLM_SIZE);
+
klm->key = cpu_to_be32(mvdev->res.null_mkey);
- klm->bcount = cpu_to_be32(klm_bcount(dmr->start - preve));
- preve = dmr->start;
+ klm->bcount = cpu_to_be32(klm_bcount(bcount));
+ preve += bcount;
+
goto again;
}
}
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 36099047560d..cccc49a08a1a 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -3884,6 +3884,9 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
ndev->mvdev.max_vqs = max_vqs;
mvdev = &ndev->mvdev;
mvdev->mdev = mdev;
+ /* cpu_to_mlx5vdpa16() below depends on this flag */
+ mvdev->actual_features =
+ (device_features & BIT_ULL(VIRTIO_F_VERSION_1));
ndev->vqs = kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
ndev->event_cbs = kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL);
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
index 7ae99691efdf..6a9a37351310 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -144,6 +144,7 @@ static struct workqueue_struct *vduse_irq_bound_wq;
static u32 allowed_device_id[] = {
VIRTIO_ID_BLOCK,
VIRTIO_ID_NET,
+ VIRTIO_ID_FS,
};
static inline struct vduse_dev *vdpa_to_vduse(struct vdpa_device *vdpa)
diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
index bb1817bd4ff3..281a8dc3ed49 100644
--- a/drivers/vfio/device_cdev.c
+++ b/drivers/vfio/device_cdev.c
@@ -162,9 +162,9 @@ void vfio_df_unbind_iommufd(struct vfio_device_file *df)
int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
struct vfio_device_attach_iommufd_pt __user *arg)
{
- struct vfio_device *device = df->device;
struct vfio_device_attach_iommufd_pt attach;
- unsigned long minsz;
+ struct vfio_device *device = df->device;
+ unsigned long minsz, xend = 0;
int ret;
minsz = offsetofend(struct vfio_device_attach_iommufd_pt, pt_id);
@@ -172,11 +172,34 @@ int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
if (copy_from_user(&attach, arg, minsz))
return -EFAULT;
- if (attach.argsz < minsz || attach.flags)
+ if (attach.argsz < minsz)
return -EINVAL;
+ if (attach.flags & ~VFIO_DEVICE_ATTACH_PASID)
+ return -EINVAL;
+
+ if (attach.flags & VFIO_DEVICE_ATTACH_PASID) {
+ if (!device->ops->pasid_attach_ioas)
+ return -EOPNOTSUPP;
+ xend = offsetofend(struct vfio_device_attach_iommufd_pt, pasid);
+ }
+
+ if (xend) {
+ if (attach.argsz < xend)
+ return -EINVAL;
+
+ if (copy_from_user((void *)&attach + minsz,
+ (void __user *)arg + minsz, xend - minsz))
+ return -EFAULT;
+ }
+
mutex_lock(&device->dev_set->lock);
- ret = device->ops->attach_ioas(device, &attach.pt_id);
+ if (attach.flags & VFIO_DEVICE_ATTACH_PASID)
+ ret = device->ops->pasid_attach_ioas(device,
+ attach.pasid,
+ &attach.pt_id);
+ else
+ ret = device->ops->attach_ioas(device, &attach.pt_id);
if (ret)
goto out_unlock;
@@ -198,20 +221,41 @@ out_unlock:
int vfio_df_ioctl_detach_pt(struct vfio_device_file *df,
struct vfio_device_detach_iommufd_pt __user *arg)
{
- struct vfio_device *device = df->device;
struct vfio_device_detach_iommufd_pt detach;
- unsigned long minsz;
+ struct vfio_device *device = df->device;
+ unsigned long minsz, xend = 0;
minsz = offsetofend(struct vfio_device_detach_iommufd_pt, flags);
if (copy_from_user(&detach, arg, minsz))
return -EFAULT;
- if (detach.argsz < minsz || detach.flags)
+ if (detach.argsz < minsz)
return -EINVAL;
+ if (detach.flags & ~VFIO_DEVICE_DETACH_PASID)
+ return -EINVAL;
+
+ if (detach.flags & VFIO_DEVICE_DETACH_PASID) {
+ if (!device->ops->pasid_detach_ioas)
+ return -EOPNOTSUPP;
+ xend = offsetofend(struct vfio_device_detach_iommufd_pt, pasid);
+ }
+
+ if (xend) {
+ if (detach.argsz < xend)
+ return -EINVAL;
+
+ if (copy_from_user((void *)&detach + minsz,
+ (void __user *)arg + minsz, xend - minsz))
+ return -EFAULT;
+ }
+
mutex_lock(&device->dev_set->lock);
- device->ops->detach_ioas(device);
+ if (detach.flags & VFIO_DEVICE_DETACH_PASID)
+ device->ops->pasid_detach_ioas(device, detach.pasid);
+ else
+ device->ops->detach_ioas(device);
mutex_unlock(&device->dev_set->lock);
return 0;
diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c
index 516294fd901b..c8c3a2d53f86 100644
--- a/drivers/vfio/iommufd.c
+++ b/drivers/vfio/iommufd.c
@@ -119,16 +119,24 @@ int vfio_iommufd_physical_bind(struct vfio_device *vdev,
if (IS_ERR(idev))
return PTR_ERR(idev);
vdev->iommufd_device = idev;
+ ida_init(&vdev->pasids);
return 0;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_bind);
void vfio_iommufd_physical_unbind(struct vfio_device *vdev)
{
+ int pasid;
+
lockdep_assert_held(&vdev->dev_set->lock);
+ while ((pasid = ida_find_first(&vdev->pasids)) >= 0) {
+ iommufd_device_detach(vdev->iommufd_device, pasid);
+ ida_free(&vdev->pasids, pasid);
+ }
+
if (vdev->iommufd_attached) {
- iommufd_device_detach(vdev->iommufd_device);
+ iommufd_device_detach(vdev->iommufd_device, IOMMU_NO_PASID);
vdev->iommufd_attached = false;
}
iommufd_device_unbind(vdev->iommufd_device);
@@ -146,9 +154,11 @@ int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
return -EINVAL;
if (vdev->iommufd_attached)
- rc = iommufd_device_replace(vdev->iommufd_device, pt_id);
+ rc = iommufd_device_replace(vdev->iommufd_device,
+ IOMMU_NO_PASID, pt_id);
else
- rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
+ rc = iommufd_device_attach(vdev->iommufd_device,
+ IOMMU_NO_PASID, pt_id);
if (rc)
return rc;
vdev->iommufd_attached = true;
@@ -163,11 +173,53 @@ void vfio_iommufd_physical_detach_ioas(struct vfio_device *vdev)
if (WARN_ON(!vdev->iommufd_device) || !vdev->iommufd_attached)
return;
- iommufd_device_detach(vdev->iommufd_device);
+ iommufd_device_detach(vdev->iommufd_device, IOMMU_NO_PASID);
vdev->iommufd_attached = false;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_detach_ioas);
+int vfio_iommufd_physical_pasid_attach_ioas(struct vfio_device *vdev,
+ u32 pasid, u32 *pt_id)
+{
+ int rc;
+
+ lockdep_assert_held(&vdev->dev_set->lock);
+
+ if (WARN_ON(!vdev->iommufd_device))
+ return -EINVAL;
+
+ if (ida_exists(&vdev->pasids, pasid))
+ return iommufd_device_replace(vdev->iommufd_device,
+ pasid, pt_id);
+
+ rc = ida_alloc_range(&vdev->pasids, pasid, pasid, GFP_KERNEL);
+ if (rc < 0)
+ return rc;
+
+ rc = iommufd_device_attach(vdev->iommufd_device, pasid, pt_id);
+ if (rc)
+ ida_free(&vdev->pasids, pasid);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(vfio_iommufd_physical_pasid_attach_ioas);
+
+void vfio_iommufd_physical_pasid_detach_ioas(struct vfio_device *vdev,
+ u32 pasid)
+{
+ lockdep_assert_held(&vdev->dev_set->lock);
+
+ if (WARN_ON(!vdev->iommufd_device))
+ return;
+
+ if (!ida_exists(&vdev->pasids, pasid))
+ return;
+
+ iommufd_device_detach(vdev->iommufd_device, pasid);
+ ida_free(&vdev->pasids, pasid);
+}
+EXPORT_SYMBOL_GPL(vfio_iommufd_physical_pasid_detach_ioas);
+
/*
* The emulated standard ops mean that vfio_device is going to use the
* "mdev path" and will call vfio_pin_pages()/vfio_dma_rw(). Drivers using this
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index e727941f589d..5ba39f7623bb 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -111,9 +111,7 @@ static int vfio_pci_open_device(struct vfio_device *core_vdev)
if (ret)
return ret;
- if (vfio_pci_is_vga(pdev) &&
- pdev->vendor == PCI_VENDOR_ID_INTEL &&
- IS_ENABLED(CONFIG_VFIO_PCI_IGD)) {
+ if (vfio_pci_is_intel_display(pdev)) {
ret = vfio_pci_igd_init(vdev);
if (ret && ret != -ENODEV) {
pci_warn(pdev, "Failed to setup Intel IGD regions\n");
@@ -144,6 +142,8 @@ static const struct vfio_device_ops vfio_pci_ops = {
.unbind_iommufd = vfio_iommufd_physical_unbind,
.attach_ioas = vfio_iommufd_physical_attach_ioas,
.detach_ioas = vfio_iommufd_physical_detach_ioas,
+ .pasid_attach_ioas = vfio_iommufd_physical_pasid_attach_ioas,
+ .pasid_detach_ioas = vfio_iommufd_physical_pasid_detach_ioas,
};
static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 94142581c98c..14437396d721 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -1814,7 +1814,8 @@ int vfio_config_init(struct vfio_pci_core_device *vdev)
cpu_to_le16(PCI_COMMAND_MEMORY);
}
- if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)
+ if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx ||
+ vdev->pdev->irq == IRQ_NOTCONNECTED)
vconfig[PCI_INTERRUPT_PIN] = 0;
ret = vfio_cap_init(vdev);
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index c8586d47704c..35f9046af315 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -727,15 +727,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_finish_enable);
static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_type)
{
if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) {
- u8 pin;
-
- if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) ||
- vdev->nointx || vdev->pdev->is_virtfn)
- return 0;
-
- pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin);
-
- return pin ? 1 : 0;
+ return vdev->vconfig[PCI_INTERRUPT_PIN] ? 1 : 0;
} else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) {
u8 pos;
u16 flags;
diff --git a/drivers/vfio/pci/vfio_pci_igd.c b/drivers/vfio/pci/vfio_pci_igd.c
index dd70e2431bd7..ef490a4545f4 100644
--- a/drivers/vfio/pci/vfio_pci_igd.c
+++ b/drivers/vfio/pci/vfio_pci_igd.c
@@ -435,6 +435,12 @@ static int vfio_pci_igd_cfg_init(struct vfio_pci_core_device *vdev)
return 0;
}
+bool vfio_pci_is_intel_display(struct pci_dev *pdev)
+{
+ return (pdev->vendor == PCI_VENDOR_ID_INTEL) &&
+ ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY);
+}
+
int vfio_pci_igd_init(struct vfio_pci_core_device *vdev)
{
int ret;
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index 8382c5834335..565966351dfa 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -259,7 +259,7 @@ static int vfio_intx_enable(struct vfio_pci_core_device *vdev,
if (!is_irq_none(vdev))
return -EINVAL;
- if (!pdev->irq)
+ if (!pdev->irq || pdev->irq == IRQ_NOTCONNECTED)
return -ENODEV;
name = kasprintf(GFP_KERNEL_ACCOUNT, "vfio-intx(%s)", pci_name(pdev));
diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h
index 5e4fa69aee16..a9972eacb293 100644
--- a/drivers/vfio/pci/vfio_pci_priv.h
+++ b/drivers/vfio/pci/vfio_pci_priv.h
@@ -67,8 +67,14 @@ void vfio_pci_memory_unlock_and_restore(struct vfio_pci_core_device *vdev,
u16 cmd);
#ifdef CONFIG_VFIO_PCI_IGD
+bool vfio_pci_is_intel_display(struct pci_dev *pdev);
int vfio_pci_igd_init(struct vfio_pci_core_device *vdev);
#else
+static inline bool vfio_pci_is_intel_display(struct pci_dev *pdev)
+{
+ return false;
+}
+
static inline int vfio_pci_igd_init(struct vfio_pci_core_device *vdev)
{
return -ENODEV;
diff --git a/drivers/vfio/pci/virtio/Kconfig b/drivers/vfio/pci/virtio/Kconfig
index 2770f7eb702c..33e04e65bec6 100644
--- a/drivers/vfio/pci/virtio/Kconfig
+++ b/drivers/vfio/pci/virtio/Kconfig
@@ -1,11 +1,11 @@
# SPDX-License-Identifier: GPL-2.0-only
config VIRTIO_VFIO_PCI
- tristate "VFIO support for VIRTIO NET PCI VF devices"
+ tristate "VFIO support for VIRTIO PCI VF devices"
depends on VIRTIO_PCI
select VFIO_PCI_CORE
help
- This provides migration support for VIRTIO NET PCI VF devices
- using the VFIO framework. Migration support requires the
+ This provides migration support for VIRTIO NET and BLOCK PCI VF
+ devices using the VFIO framework. Migration support requires the
SR-IOV PF device to support specific VIRTIO extensions,
otherwise this driver provides no additional functionality
beyond vfio-pci.
diff --git a/drivers/vfio/pci/virtio/legacy_io.c b/drivers/vfio/pci/virtio/legacy_io.c
index 20382ee15fac..832af5ba267c 100644
--- a/drivers/vfio/pci/virtio/legacy_io.c
+++ b/drivers/vfio/pci/virtio/legacy_io.c
@@ -382,7 +382,9 @@ static bool virtiovf_bar0_exists(struct pci_dev *pdev)
bool virtiovf_support_legacy_io(struct pci_dev *pdev)
{
- return virtio_pci_admin_has_legacy_io(pdev) && !virtiovf_bar0_exists(pdev);
+ /* For now, the legacy IO functionality is supported only for virtio-net */
+ return pdev->device == 0x1041 && virtio_pci_admin_has_legacy_io(pdev) &&
+ !virtiovf_bar0_exists(pdev);
}
int virtiovf_init_legacy_io(struct virtiovf_pci_core_device *virtvdev)
diff --git a/drivers/vfio/pci/virtio/main.c b/drivers/vfio/pci/virtio/main.c
index d534d48c4163..515fe1b9f94d 100644
--- a/drivers/vfio/pci/virtio/main.c
+++ b/drivers/vfio/pci/virtio/main.c
@@ -187,8 +187,9 @@ static void virtiovf_pci_remove(struct pci_dev *pdev)
}
static const struct pci_device_id virtiovf_pci_table[] = {
- /* Only virtio-net is supported/tested so far */
+ /* Only virtio-net and virtio-block are supported/tested so far */
{ PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_VENDOR_ID_REDHAT_QUMRANET, 0x1041) },
+ { PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_VENDOR_ID_REDHAT_QUMRANET, 0x1042) },
{}
};
@@ -221,4 +222,4 @@ module_pci_driver(virtiovf_pci_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yishai Hadas <yishaih@nvidia.com>");
MODULE_DESCRIPTION(
- "VIRTIO VFIO PCI - User Level meta-driver for VIRTIO NET devices");
+ "VIRTIO VFIO PCI - User Level meta-driver for VIRTIO NET and BLOCK devices");
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 50ebc9593c9d..0ac56072af9f 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -103,9 +103,9 @@ struct vfio_dma {
struct vfio_batch {
struct page **pages; /* for pin_user_pages_remote */
struct page *fallback_page; /* if pages alloc fails */
- int capacity; /* length of pages array */
- int size; /* of batch currently */
- int offset; /* of next entry in pages */
+ unsigned int capacity; /* length of pages array */
+ unsigned int size; /* of batch currently */
+ unsigned int offset; /* of next entry in pages */
};
struct vfio_iommu_group {
@@ -471,12 +471,12 @@ static int put_pfn(unsigned long pfn, int prot)
#define VFIO_BATCH_MAX_CAPACITY (PAGE_SIZE / sizeof(struct page *))
-static void vfio_batch_init(struct vfio_batch *batch)
+static void __vfio_batch_init(struct vfio_batch *batch, bool single)
{
batch->size = 0;
batch->offset = 0;
- if (unlikely(disable_hugepages))
+ if (single || unlikely(disable_hugepages))
goto fallback;
batch->pages = (struct page **) __get_free_page(GFP_KERNEL);
@@ -491,6 +491,16 @@ fallback:
batch->capacity = 1;
}
+static void vfio_batch_init(struct vfio_batch *batch)
+{
+ __vfio_batch_init(batch, false);
+}
+
+static void vfio_batch_init_single(struct vfio_batch *batch)
+{
+ __vfio_batch_init(batch, true);
+}
+
static void vfio_batch_unpin(struct vfio_batch *batch, struct vfio_dma *dma)
{
while (batch->size) {
@@ -510,7 +520,7 @@ static void vfio_batch_fini(struct vfio_batch *batch)
static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
unsigned long vaddr, unsigned long *pfn,
- bool write_fault)
+ unsigned long *addr_mask, bool write_fault)
{
struct follow_pfnmap_args args = { .vma = vma, .address = vaddr };
int ret;
@@ -534,10 +544,12 @@ static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
return ret;
}
- if (write_fault && !args.writable)
+ if (write_fault && !args.writable) {
ret = -EFAULT;
- else
+ } else {
*pfn = args.pfn;
+ *addr_mask = args.addr_mask;
+ }
follow_pfnmap_end(&args);
return ret;
@@ -545,25 +557,33 @@ static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
/*
* Returns the positive number of pfns successfully obtained or a negative
- * error code.
+ * error code. The initial pfn is stored in the pfn arg. For page-backed
+ * pfns, the provided batch is also updated to indicate the filled pages and
+ * initial offset. For VM_PFNMAP pfns, only the returned number of pfns and
+ * returned initial pfn are provided; subsequent pfns are contiguous.
*/
-static int vaddr_get_pfns(struct mm_struct *mm, unsigned long vaddr,
- long npages, int prot, unsigned long *pfn,
- struct page **pages)
+static long vaddr_get_pfns(struct mm_struct *mm, unsigned long vaddr,
+ unsigned long npages, int prot, unsigned long *pfn,
+ struct vfio_batch *batch)
{
+ unsigned long pin_pages = min_t(unsigned long, npages, batch->capacity);
struct vm_area_struct *vma;
unsigned int flags = 0;
- int ret;
+ long ret;
if (prot & IOMMU_WRITE)
flags |= FOLL_WRITE;
mmap_read_lock(mm);
- ret = pin_user_pages_remote(mm, vaddr, npages, flags | FOLL_LONGTERM,
- pages, NULL);
+ ret = pin_user_pages_remote(mm, vaddr, pin_pages, flags | FOLL_LONGTERM,
+ batch->pages, NULL);
if (ret > 0) {
- *pfn = page_to_pfn(pages[0]);
+ *pfn = page_to_pfn(batch->pages[0]);
+ batch->size = ret;
+ batch->offset = 0;
goto done;
+ } else if (!ret) {
+ ret = -EFAULT;
}
vaddr = untagged_addr_remote(mm, vaddr);
@@ -572,15 +592,22 @@ retry:
vma = vma_lookup(mm, vaddr);
if (vma && vma->vm_flags & VM_PFNMAP) {
- ret = follow_fault_pfn(vma, mm, vaddr, pfn, prot & IOMMU_WRITE);
+ unsigned long addr_mask;
+
+ ret = follow_fault_pfn(vma, mm, vaddr, pfn, &addr_mask,
+ prot & IOMMU_WRITE);
if (ret == -EAGAIN)
goto retry;
if (!ret) {
- if (is_invalid_reserved_pfn(*pfn))
- ret = 1;
- else
+ if (is_invalid_reserved_pfn(*pfn)) {
+ unsigned long epfn;
+
+ epfn = (*pfn | (~addr_mask >> PAGE_SHIFT)) + 1;
+ ret = min_t(long, npages, epfn - *pfn);
+ } else {
ret = -EFAULT;
+ }
}
}
done:
@@ -594,7 +621,7 @@ done:
* first page and all consecutive pages with the same locking.
*/
static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
- long npage, unsigned long *pfn_base,
+ unsigned long npage, unsigned long *pfn_base,
unsigned long limit, struct vfio_batch *batch)
{
unsigned long pfn;
@@ -616,32 +643,42 @@ static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
*pfn_base = 0;
}
+ if (unlikely(disable_hugepages))
+ npage = 1;
+
while (npage) {
if (!batch->size) {
/* Empty batch, so refill it. */
- long req_pages = min_t(long, npage, batch->capacity);
-
- ret = vaddr_get_pfns(mm, vaddr, req_pages, dma->prot,
- &pfn, batch->pages);
+ ret = vaddr_get_pfns(mm, vaddr, npage, dma->prot,
+ &pfn, batch);
if (ret < 0)
goto unpin_out;
- batch->size = ret;
- batch->offset = 0;
-
if (!*pfn_base) {
*pfn_base = pfn;
rsvd = is_invalid_reserved_pfn(*pfn_base);
}
+
+ /* Handle pfnmap */
+ if (!batch->size) {
+ if (pfn != *pfn_base + pinned || !rsvd)
+ goto out;
+
+ pinned += ret;
+ npage -= ret;
+ vaddr += (PAGE_SIZE * ret);
+ iova += (PAGE_SIZE * ret);
+ continue;
+ }
}
/*
- * pfn is preset for the first iteration of this inner loop and
- * updated at the end to handle a VM_PFNMAP pfn. In that case,
- * batch->pages isn't valid (there's no struct page), so allow
- * batch->pages to be touched only when there's more than one
- * pfn to check, which guarantees the pfns are from a
- * !VM_PFNMAP vma.
+ * pfn is preset for the first iteration of this inner loop
+ * due to the fact that vaddr_get_pfns() needs to provide the
+ * initial pfn for pfnmaps. Therefore to reduce redundancy,
+ * the next pfn is fetched at the end of the loop.
+ * A PageReserved() page could still qualify as page backed
+ * and rsvd here, and therefore continues to use the batch.
*/
while (true) {
if (pfn != *pfn_base + pinned ||
@@ -676,21 +713,12 @@ static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
pfn = page_to_pfn(batch->pages[batch->offset]);
}
-
- if (unlikely(disable_hugepages))
- break;
}
out:
ret = vfio_lock_acct(dma, lock_acct, false);
unpin_out:
- if (batch->size == 1 && !batch->offset) {
- /* May be a VM_PFNMAP pfn, which the batch can't remember. */
- put_pfn(pfn, dma->prot);
- batch->size = 0;
- }
-
if (ret < 0) {
if (pinned && !rsvd) {
for (pfn = *pfn_base ; pinned ; pfn++, pinned--)
@@ -705,7 +733,7 @@ unpin_out:
}
static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova,
- unsigned long pfn, long npage,
+ unsigned long pfn, unsigned long npage,
bool do_accounting)
{
long unlocked = 0, locked = 0;
@@ -728,7 +756,7 @@ static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova,
static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr,
unsigned long *pfn_base, bool do_accounting)
{
- struct page *pages[1];
+ struct vfio_batch batch;
struct mm_struct *mm;
int ret;
@@ -736,7 +764,9 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr,
if (!mmget_not_zero(mm))
return -ENODEV;
- ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages);
+ vfio_batch_init_single(&batch);
+
+ ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, &batch);
if (ret != 1)
goto out;
@@ -755,6 +785,7 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr,
}
out:
+ vfio_batch_fini(&batch);
mmput(mm);
return ret;
}
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index b455d9ab6f3d..020d4fbb947c 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -47,6 +47,7 @@ config VHOST_SCSI
tristate "VHOST_SCSI TCM fabric driver"
depends on TARGET_CORE && EVENTFD
select VHOST
+ select SG_POOL
default n
help
Say M here to enable the vhost_scsi TCM fabric module
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 718fa4e0b31e..f6f5a7ac7894 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -45,6 +45,55 @@
#define VHOST_SCSI_PREALLOC_SGLS 2048
#define VHOST_SCSI_PREALLOC_UPAGES 2048
#define VHOST_SCSI_PREALLOC_PROT_SGLS 2048
+/*
+ * For the legacy descriptor case we allocate an iov per byte in the
+ * virtio_scsi_cmd_resp struct.
+ */
+#define VHOST_SCSI_MAX_RESP_IOVS sizeof(struct virtio_scsi_cmd_resp)
+
+static unsigned int vhost_scsi_inline_sg_cnt = VHOST_SCSI_PREALLOC_SGLS;
+
+#ifdef CONFIG_ARCH_NO_SG_CHAIN
+static int vhost_scsi_set_inline_sg_cnt(const char *buf,
+ const struct kernel_param *kp)
+{
+ pr_err("Setting inline_sg_cnt is not supported.\n");
+ return -EOPNOTSUPP;
+}
+#else
+static int vhost_scsi_set_inline_sg_cnt(const char *buf,
+ const struct kernel_param *kp)
+{
+ unsigned int cnt;
+ int ret;
+
+ ret = kstrtouint(buf, 10, &cnt);
+ if (ret)
+ return ret;
+
+ if (ret > VHOST_SCSI_PREALLOC_SGLS) {
+ pr_err("Max inline_sg_cnt is %u\n", VHOST_SCSI_PREALLOC_SGLS);
+ return -EINVAL;
+ }
+
+ vhost_scsi_inline_sg_cnt = cnt;
+ return 0;
+}
+#endif
+
+static int vhost_scsi_get_inline_sg_cnt(char *buf,
+ const struct kernel_param *kp)
+{
+ return sprintf(buf, "%u\n", vhost_scsi_inline_sg_cnt);
+}
+
+static const struct kernel_param_ops vhost_scsi_inline_sg_cnt_op = {
+ .get = vhost_scsi_get_inline_sg_cnt,
+ .set = vhost_scsi_set_inline_sg_cnt,
+};
+
+module_param_cb(inline_sg_cnt, &vhost_scsi_inline_sg_cnt_op, NULL, 0644);
+MODULE_PARM_DESC(inline_sg_cnt, "Set the number of scatterlist entries to pre-allocate. The default is 2048.");
/* Max number of requests before requeueing the job.
* Using this limit prevents one virtqueue from starving others with
@@ -62,40 +111,26 @@ struct vhost_scsi_inflight {
struct vhost_scsi_cmd {
/* Descriptor from vhost_get_vq_desc() for virt_queue segment */
int tvc_vq_desc;
- /* virtio-scsi initiator task attribute */
- int tvc_task_attr;
- /* virtio-scsi response incoming iovecs */
- int tvc_in_iovs;
- /* virtio-scsi initiator data direction */
- enum dma_data_direction tvc_data_direction;
- /* Expected data transfer length from virtio-scsi header */
- u32 tvc_exp_data_len;
- /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */
- u64 tvc_tag;
/* The number of scatterlists associated with this cmd */
u32 tvc_sgl_count;
u32 tvc_prot_sgl_count;
- /* Saved unpacked SCSI LUN for vhost_scsi_target_queue_cmd() */
- u32 tvc_lun;
u32 copied_iov:1;
- const void *saved_iter_addr;
- struct iov_iter saved_iter;
- /* Pointer to the SGL formatted memory from virtio-scsi */
- struct scatterlist *tvc_sgl;
- struct scatterlist *tvc_prot_sgl;
- struct page **tvc_upages;
- /* Pointer to response header iovec */
- struct iovec *tvc_resp_iov;
- /* Pointer to vhost_scsi for our device */
- struct vhost_scsi *tvc_vhost;
+ const void *read_iov;
+ struct iov_iter *read_iter;
+ struct scatterlist *sgl;
+ struct sg_table table;
+ struct scatterlist *prot_sgl;
+ struct sg_table prot_table;
+ /* Fast path response header iovec used when only one vec is needed */
+ struct iovec tvc_resp_iov;
+ /* Number of iovs for response */
+ unsigned int tvc_resp_iovs_cnt;
+ /* Pointer to response header iovecs if more than one is needed */
+ struct iovec *tvc_resp_iovs;
/* Pointer to vhost_virtqueue for the cmd */
struct vhost_virtqueue *tvc_vq;
- /* Pointer to vhost nexus memory */
- struct vhost_scsi_nexus *tvc_nexus;
/* The TCM I/O descriptor that is accessed via container_of() */
struct se_cmd tvc_se_cmd;
- /* Copy of the incoming SCSI command descriptor block (CDB) */
- unsigned char tvc_cdb[VHOST_SCSI_MAX_CDB_SIZE];
/* Sense buffer that will be mapped into outgoing status */
unsigned char tvc_sense_buf[TRANSPORT_SENSE_BUFFER];
/* Completed commands list, serviced from vhost worker thread */
@@ -187,6 +222,7 @@ struct vhost_scsi_virtqueue {
struct vhost_scsi_cmd *scsi_cmds;
struct sbitmap scsi_tags;
int max_cmds;
+ struct page **upages;
struct vhost_work completion_work;
struct llist_head completion_list;
@@ -206,6 +242,8 @@ struct vhost_scsi {
bool vs_events_missed; /* any missed events, protected by vq->mutex */
int vs_events_nr; /* num of pending events, protected by vq->mutex */
+
+ unsigned int inline_sg_cnt;
};
struct vhost_scsi_tmf {
@@ -330,23 +368,38 @@ static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd)
struct vhost_scsi_cmd, tvc_se_cmd);
struct vhost_scsi_virtqueue *svq = container_of(tv_cmd->tvc_vq,
struct vhost_scsi_virtqueue, vq);
+ struct vhost_scsi *vs = svq->vs;
struct vhost_scsi_inflight *inflight = tv_cmd->inflight;
+ struct scatterlist *sg;
+ struct page *page;
int i;
if (tv_cmd->tvc_sgl_count) {
- for (i = 0; i < tv_cmd->tvc_sgl_count; i++) {
+ for_each_sgtable_sg(&tv_cmd->table, sg, i) {
+ page = sg_page(sg);
+ if (!page)
+ continue;
+
if (tv_cmd->copied_iov)
- __free_page(sg_page(&tv_cmd->tvc_sgl[i]));
+ __free_page(page);
else
- put_page(sg_page(&tv_cmd->tvc_sgl[i]));
+ put_page(page);
}
- kfree(tv_cmd->saved_iter_addr);
+ kfree(tv_cmd->read_iter);
+ kfree(tv_cmd->read_iov);
+ sg_free_table_chained(&tv_cmd->table, vs->inline_sg_cnt);
}
if (tv_cmd->tvc_prot_sgl_count) {
- for (i = 0; i < tv_cmd->tvc_prot_sgl_count; i++)
- put_page(sg_page(&tv_cmd->tvc_prot_sgl[i]));
+ for_each_sgtable_sg(&tv_cmd->prot_table, sg, i) {
+ page = sg_page(sg);
+ if (page)
+ put_page(page);
+ }
+ sg_free_table_chained(&tv_cmd->prot_table, vs->inline_sg_cnt);
}
+ if (tv_cmd->tvc_resp_iovs != &tv_cmd->tvc_resp_iov)
+ kfree(tv_cmd->tvc_resp_iovs);
sbitmap_clear_bit(&svq->scsi_tags, se_cmd->map_tag);
vhost_scsi_put_inflight(inflight);
}
@@ -533,15 +586,18 @@ static void vhost_scsi_evt_work(struct vhost_work *work)
static int vhost_scsi_copy_sgl_to_iov(struct vhost_scsi_cmd *cmd)
{
- struct iov_iter *iter = &cmd->saved_iter;
- struct scatterlist *sg = cmd->tvc_sgl;
+ struct iov_iter *iter = cmd->read_iter;
+ struct scatterlist *sg;
struct page *page;
size_t len;
int i;
- for (i = 0; i < cmd->tvc_sgl_count; i++) {
- page = sg_page(&sg[i]);
- len = sg[i].length;
+ for_each_sgtable_sg(&cmd->table, sg, i) {
+ page = sg_page(sg);
+ if (!page)
+ continue;
+
+ len = sg->length;
if (copy_page_to_iter(page, 0, len, iter) != len) {
pr_err("Could not copy data while handling misaligned cmd. Error %zu\n",
@@ -578,7 +634,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
cmd, se_cmd->residual_count, se_cmd->scsi_status);
memset(&v_rsp, 0, sizeof(v_rsp));
- if (cmd->saved_iter_addr && vhost_scsi_copy_sgl_to_iov(cmd)) {
+ if (cmd->read_iter && vhost_scsi_copy_sgl_to_iov(cmd)) {
v_rsp.response = VIRTIO_SCSI_S_BAD_TARGET;
} else {
v_rsp.resid = cpu_to_vhost32(cmd->tvc_vq,
@@ -591,8 +647,8 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
se_cmd->scsi_sense_length);
}
- iov_iter_init(&iov_iter, ITER_DEST, cmd->tvc_resp_iov,
- cmd->tvc_in_iovs, sizeof(v_rsp));
+ iov_iter_init(&iov_iter, ITER_DEST, cmd->tvc_resp_iovs,
+ cmd->tvc_resp_iovs_cnt, sizeof(v_rsp));
ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter);
if (likely(ret == sizeof(v_rsp))) {
signal = true;
@@ -609,55 +665,53 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
}
static struct vhost_scsi_cmd *
-vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg,
- unsigned char *cdb, u64 scsi_tag, u16 lun, u8 task_attr,
- u32 exp_data_len, int data_direction)
+vhost_scsi_get_cmd(struct vhost_virtqueue *vq, u64 scsi_tag)
{
struct vhost_scsi_virtqueue *svq = container_of(vq,
struct vhost_scsi_virtqueue, vq);
struct vhost_scsi_cmd *cmd;
- struct vhost_scsi_nexus *tv_nexus;
- struct scatterlist *sg, *prot_sg;
- struct iovec *tvc_resp_iov;
- struct page **pages;
+ struct scatterlist *sgl, *prot_sgl;
int tag;
- tv_nexus = tpg->tpg_nexus;
- if (!tv_nexus) {
- pr_err("Unable to locate active struct vhost_scsi_nexus\n");
- return ERR_PTR(-EIO);
- }
-
tag = sbitmap_get(&svq->scsi_tags);
if (tag < 0) {
- pr_err("Unable to obtain tag for vhost_scsi_cmd\n");
+ pr_warn_once("Guest sent too many cmds. Returning TASK_SET_FULL.\n");
return ERR_PTR(-ENOMEM);
}
cmd = &svq->scsi_cmds[tag];
- sg = cmd->tvc_sgl;
- prot_sg = cmd->tvc_prot_sgl;
- pages = cmd->tvc_upages;
- tvc_resp_iov = cmd->tvc_resp_iov;
+ sgl = cmd->sgl;
+ prot_sgl = cmd->prot_sgl;
memset(cmd, 0, sizeof(*cmd));
- cmd->tvc_sgl = sg;
- cmd->tvc_prot_sgl = prot_sg;
- cmd->tvc_upages = pages;
+ cmd->sgl = sgl;
+ cmd->prot_sgl = prot_sgl;
cmd->tvc_se_cmd.map_tag = tag;
- cmd->tvc_tag = scsi_tag;
- cmd->tvc_lun = lun;
- cmd->tvc_task_attr = task_attr;
- cmd->tvc_exp_data_len = exp_data_len;
- cmd->tvc_data_direction = data_direction;
- cmd->tvc_nexus = tv_nexus;
cmd->inflight = vhost_scsi_get_inflight(vq);
- cmd->tvc_resp_iov = tvc_resp_iov;
-
- memcpy(cmd->tvc_cdb, cdb, VHOST_SCSI_MAX_CDB_SIZE);
return cmd;
}
+static void vhost_scsi_revert_map_iov_to_sgl(struct iov_iter *iter,
+ struct scatterlist *curr,
+ struct scatterlist *end)
+{
+ size_t revert_bytes = 0;
+ struct page *page;
+
+ while (curr != end) {
+ page = sg_page(curr);
+
+ if (page) {
+ put_page(page);
+ revert_bytes += curr->length;
+ }
+ /* Clear so we can re-use it for the copy path */
+ sg_set_page(curr, NULL, 0, 0);
+ curr = sg_next(curr);
+ }
+ iov_iter_revert(iter, revert_bytes);
+}
+
/*
* Map a user memory range into a scatterlist
*
@@ -666,14 +720,17 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg,
static int
vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
struct iov_iter *iter,
- struct scatterlist *sgl,
+ struct sg_table *sg_table,
+ struct scatterlist **sgl,
bool is_prot)
{
- struct page **pages = cmd->tvc_upages;
- struct scatterlist *sg = sgl;
- ssize_t bytes, mapped_bytes;
- size_t offset, mapped_offset;
- unsigned int npages = 0;
+ struct vhost_scsi_virtqueue *svq = container_of(cmd->tvc_vq,
+ struct vhost_scsi_virtqueue, vq);
+ struct page **pages = svq->upages;
+ struct scatterlist *sg = *sgl;
+ ssize_t bytes;
+ size_t offset;
+ unsigned int n, npages = 0;
bytes = iov_iter_get_pages2(iter, pages, LONG_MAX,
VHOST_SCSI_PREALLOC_UPAGES, &offset);
@@ -681,11 +738,8 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
if (bytes <= 0)
return bytes < 0 ? bytes : -EFAULT;
- mapped_bytes = bytes;
- mapped_offset = offset;
-
while (bytes) {
- unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes);
+ n = min_t(unsigned int, PAGE_SIZE - offset, bytes);
/*
* The block layer requires bios/requests to be a multiple of
* 512 bytes, but Windows can send us vecs that are misaligned.
@@ -706,25 +760,24 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
goto revert_iter_get_pages;
}
- sg_set_page(sg++, pages[npages++], n, offset);
+ sg_set_page(sg, pages[npages++], n, offset);
+ sg = sg_next(sg);
bytes -= n;
offset = 0;
}
+ *sgl = sg;
return npages;
revert_iter_get_pages:
- iov_iter_revert(iter, mapped_bytes);
+ vhost_scsi_revert_map_iov_to_sgl(iter, *sgl, sg);
- npages = 0;
- while (mapped_bytes) {
- unsigned int n = min_t(unsigned int, PAGE_SIZE - mapped_offset,
- mapped_bytes);
+ iov_iter_revert(iter, bytes);
+ while (bytes) {
+ n = min_t(unsigned int, PAGE_SIZE, bytes);
put_page(pages[npages++]);
-
- mapped_bytes -= n;
- mapped_offset = 0;
+ bytes -= n;
}
return -EINVAL;
@@ -752,33 +805,42 @@ vhost_scsi_calc_sgls(struct iov_iter *iter, size_t bytes, int max_sgls)
static int
vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
- struct scatterlist *sg, int sg_count)
+ struct sg_table *sg_table, int sg_count,
+ int data_dir)
{
size_t len = iov_iter_count(iter);
unsigned int nbytes = 0;
+ struct scatterlist *sg;
struct page *page;
- int i;
+ int i, ret;
- if (cmd->tvc_data_direction == DMA_FROM_DEVICE) {
- cmd->saved_iter_addr = dup_iter(&cmd->saved_iter, iter,
- GFP_KERNEL);
- if (!cmd->saved_iter_addr)
+ if (data_dir == DMA_FROM_DEVICE) {
+ cmd->read_iter = kzalloc(sizeof(*cmd->read_iter), GFP_KERNEL);
+ if (!cmd->read_iter)
return -ENOMEM;
+
+ cmd->read_iov = dup_iter(cmd->read_iter, iter, GFP_KERNEL);
+ if (!cmd->read_iov) {
+ ret = -ENOMEM;
+ goto free_iter;
+ }
}
- for (i = 0; i < sg_count; i++) {
+ for_each_sgtable_sg(sg_table, sg, i) {
page = alloc_page(GFP_KERNEL);
if (!page) {
- i--;
+ ret = -ENOMEM;
goto err;
}
nbytes = min_t(unsigned int, PAGE_SIZE, len);
- sg_set_page(&sg[i], page, nbytes, 0);
+ sg_set_page(sg, page, nbytes, 0);
- if (cmd->tvc_data_direction == DMA_TO_DEVICE &&
- copy_page_from_iter(page, 0, nbytes, iter) != nbytes)
+ if (data_dir == DMA_TO_DEVICE &&
+ copy_page_from_iter(page, 0, nbytes, iter) != nbytes) {
+ ret = -EFAULT;
goto err;
+ }
len -= nbytes;
}
@@ -790,66 +852,63 @@ err:
pr_err("Could not read %u bytes while handling misaligned cmd\n",
nbytes);
- for (; i >= 0; i--)
- __free_page(sg_page(&sg[i]));
- kfree(cmd->saved_iter_addr);
- return -ENOMEM;
+ for_each_sgtable_sg(sg_table, sg, i) {
+ page = sg_page(sg);
+ if (page)
+ __free_page(page);
+ }
+ kfree(cmd->read_iov);
+free_iter:
+ kfree(cmd->read_iter);
+ return ret;
}
static int
vhost_scsi_map_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
- struct scatterlist *sg, int sg_count, bool is_prot)
+ struct sg_table *sg_table, int sg_count, bool is_prot)
{
- struct scatterlist *p = sg;
- size_t revert_bytes;
+ struct scatterlist *sg = sg_table->sgl;
int ret;
while (iov_iter_count(iter)) {
- ret = vhost_scsi_map_to_sgl(cmd, iter, sg, is_prot);
+ ret = vhost_scsi_map_to_sgl(cmd, iter, sg_table, &sg, is_prot);
if (ret < 0) {
- revert_bytes = 0;
-
- while (p < sg) {
- struct page *page = sg_page(p);
-
- if (page) {
- put_page(page);
- revert_bytes += p->length;
- }
- p++;
- }
-
- iov_iter_revert(iter, revert_bytes);
+ vhost_scsi_revert_map_iov_to_sgl(iter, sg_table->sgl,
+ sg);
return ret;
}
- sg += ret;
}
return 0;
}
static int
-vhost_scsi_mapal(struct vhost_scsi_cmd *cmd,
+vhost_scsi_mapal(struct vhost_scsi *vs, struct vhost_scsi_cmd *cmd,
size_t prot_bytes, struct iov_iter *prot_iter,
- size_t data_bytes, struct iov_iter *data_iter)
+ size_t data_bytes, struct iov_iter *data_iter, int data_dir)
{
int sgl_count, ret;
if (prot_bytes) {
sgl_count = vhost_scsi_calc_sgls(prot_iter, prot_bytes,
VHOST_SCSI_PREALLOC_PROT_SGLS);
- if (sgl_count < 0)
- return sgl_count;
+ cmd->prot_table.sgl = cmd->prot_sgl;
+ ret = sg_alloc_table_chained(&cmd->prot_table, sgl_count,
+ cmd->prot_table.sgl,
+ vs->inline_sg_cnt);
+ if (ret)
+ return ret;
- sg_init_table(cmd->tvc_prot_sgl, sgl_count);
cmd->tvc_prot_sgl_count = sgl_count;
pr_debug("%s prot_sg %p prot_sgl_count %u\n", __func__,
- cmd->tvc_prot_sgl, cmd->tvc_prot_sgl_count);
+ cmd->prot_table.sgl, cmd->tvc_prot_sgl_count);
ret = vhost_scsi_map_iov_to_sgl(cmd, prot_iter,
- cmd->tvc_prot_sgl,
+ &cmd->prot_table,
cmd->tvc_prot_sgl_count, true);
if (ret < 0) {
+ sg_free_table_chained(&cmd->prot_table,
+ vs->inline_sg_cnt);
cmd->tvc_prot_sgl_count = 0;
return ret;
}
@@ -859,20 +918,23 @@ vhost_scsi_mapal(struct vhost_scsi_cmd *cmd,
if (sgl_count < 0)
return sgl_count;
- sg_init_table(cmd->tvc_sgl, sgl_count);
+ cmd->table.sgl = cmd->sgl;
+ ret = sg_alloc_table_chained(&cmd->table, sgl_count, cmd->table.sgl,
+ vs->inline_sg_cnt);
+ if (ret)
+ return ret;
+
cmd->tvc_sgl_count = sgl_count;
pr_debug("%s data_sg %p data_sgl_count %u\n", __func__,
- cmd->tvc_sgl, cmd->tvc_sgl_count);
+ cmd->table.sgl, cmd->tvc_sgl_count);
- ret = vhost_scsi_map_iov_to_sgl(cmd, data_iter, cmd->tvc_sgl,
+ ret = vhost_scsi_map_iov_to_sgl(cmd, data_iter, &cmd->table,
cmd->tvc_sgl_count, false);
- if (ret == -EINVAL) {
- sg_init_table(cmd->tvc_sgl, cmd->tvc_sgl_count);
- ret = vhost_scsi_copy_iov_to_sgl(cmd, data_iter, cmd->tvc_sgl,
- cmd->tvc_sgl_count);
- }
-
+ if (ret == -EINVAL)
+ ret = vhost_scsi_copy_iov_to_sgl(cmd, data_iter, &cmd->table,
+ cmd->tvc_sgl_count, data_dir);
if (ret < 0) {
+ sg_free_table_chained(&cmd->table, vs->inline_sg_cnt);
cmd->tvc_sgl_count = 0;
return ret;
}
@@ -896,32 +958,33 @@ static int vhost_scsi_to_tcm_attr(int attr)
return TCM_SIMPLE_TAG;
}
-static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd)
+static void vhost_scsi_target_queue_cmd(struct vhost_scsi_nexus *nexus,
+ struct vhost_scsi_cmd *cmd,
+ unsigned char *cdb, u16 lun,
+ int task_attr, int data_dir,
+ u32 exp_data_len)
{
struct se_cmd *se_cmd = &cmd->tvc_se_cmd;
- struct vhost_scsi_nexus *tv_nexus;
struct scatterlist *sg_ptr, *sg_prot_ptr = NULL;
/* FIXME: BIDI operation */
if (cmd->tvc_sgl_count) {
- sg_ptr = cmd->tvc_sgl;
+ sg_ptr = cmd->table.sgl;
if (cmd->tvc_prot_sgl_count)
- sg_prot_ptr = cmd->tvc_prot_sgl;
+ sg_prot_ptr = cmd->prot_table.sgl;
else
se_cmd->prot_pto = true;
} else {
sg_ptr = NULL;
}
- tv_nexus = cmd->tvc_nexus;
se_cmd->tag = 0;
- target_init_cmd(se_cmd, tv_nexus->tvn_se_sess, &cmd->tvc_sense_buf[0],
- cmd->tvc_lun, cmd->tvc_exp_data_len,
- vhost_scsi_to_tcm_attr(cmd->tvc_task_attr),
- cmd->tvc_data_direction, TARGET_SCF_ACK_KREF);
+ target_init_cmd(se_cmd, nexus->tvn_se_sess, &cmd->tvc_sense_buf[0],
+ lun, exp_data_len, vhost_scsi_to_tcm_attr(task_attr),
+ data_dir, TARGET_SCF_ACK_KREF);
- if (target_submit_prep(se_cmd, cmd->tvc_cdb, sg_ptr,
+ if (target_submit_prep(se_cmd, cdb, sg_ptr,
cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr,
cmd->tvc_prot_sgl_count, GFP_KERNEL))
return;
@@ -930,6 +993,24 @@ static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd)
}
static void
+vhost_scsi_send_status(struct vhost_scsi *vs, struct vhost_virtqueue *vq,
+ int head, unsigned int out, u8 status)
+{
+ struct virtio_scsi_cmd_resp __user *resp;
+ struct virtio_scsi_cmd_resp rsp;
+ int ret;
+
+ memset(&rsp, 0, sizeof(rsp));
+ rsp.status = status;
+ resp = vq->iov[out].iov_base;
+ ret = __copy_to_user(resp, &rsp, sizeof(rsp));
+ if (!ret)
+ vhost_add_used_and_signal(&vs->dev, vq, head, 0);
+ else
+ pr_err("Faulted on virtio_scsi_cmd_resp\n");
+}
+
+static void
vhost_scsi_send_bad_target(struct vhost_scsi *vs,
struct vhost_virtqueue *vq,
int head, unsigned out)
@@ -1049,6 +1130,43 @@ out:
return ret;
}
+static int
+vhost_scsi_setup_resp_iovs(struct vhost_scsi_cmd *cmd, struct iovec *in_iovs,
+ unsigned int in_iovs_cnt)
+{
+ int i, cnt;
+
+ if (!in_iovs_cnt)
+ return 0;
+ /*
+ * Initiator's normally just put the virtio_scsi_cmd_resp in the first
+ * iov, but just in case they wedged in some data with it we check for
+ * greater than or equal to the response struct.
+ */
+ if (in_iovs[0].iov_len >= sizeof(struct virtio_scsi_cmd_resp)) {
+ cmd->tvc_resp_iovs = &cmd->tvc_resp_iov;
+ cmd->tvc_resp_iovs_cnt = 1;
+ } else {
+ /*
+ * Legacy descriptor layouts didn't specify that we must put
+ * the entire response in one iov. Worst case we have a
+ * iov per byte.
+ */
+ cnt = min(VHOST_SCSI_MAX_RESP_IOVS, in_iovs_cnt);
+ cmd->tvc_resp_iovs = kcalloc(cnt, sizeof(struct iovec),
+ GFP_KERNEL);
+ if (!cmd->tvc_resp_iovs)
+ return -ENOMEM;
+
+ cmd->tvc_resp_iovs_cnt = cnt;
+ }
+
+ for (i = 0; i < cmd->tvc_resp_iovs_cnt; i++)
+ cmd->tvc_resp_iovs[i] = in_iovs[i];
+
+ return 0;
+}
+
static u16 vhost_buf_to_lun(u8 *lun_buf)
{
return ((lun_buf[2] << 8) | lun_buf[3]) & 0x3FFF;
@@ -1060,16 +1178,17 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
struct vhost_scsi_tpg **vs_tpg, *tpg;
struct virtio_scsi_cmd_req v_req;
struct virtio_scsi_cmd_req_pi v_req_pi;
+ struct vhost_scsi_nexus *nexus;
struct vhost_scsi_ctx vc;
struct vhost_scsi_cmd *cmd;
struct iov_iter in_iter, prot_iter, data_iter;
u64 tag;
u32 exp_data_len, data_direction;
- int ret, prot_bytes, i, c = 0;
+ int ret, prot_bytes, c = 0;
u16 lun;
u8 task_attr;
bool t10_pi = vhost_has_feature(vq, VIRTIO_SCSI_F_T10_PI);
- void *cdb;
+ u8 *cdb;
mutex_lock(&vq->mutex);
/*
@@ -1212,29 +1331,39 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
scsi_command_size(cdb), VHOST_SCSI_MAX_CDB_SIZE);
goto err;
}
- cmd = vhost_scsi_get_cmd(vq, tpg, cdb, tag, lun, task_attr,
- exp_data_len + prot_bytes,
- data_direction);
+
+ nexus = tpg->tpg_nexus;
+ if (!nexus) {
+ vq_err(vq, "Unable to locate active struct vhost_scsi_nexus\n");
+ ret = -EIO;
+ goto err;
+ }
+
+ cmd = vhost_scsi_get_cmd(vq, tag);
if (IS_ERR(cmd)) {
- vq_err(vq, "vhost_scsi_get_cmd failed %ld\n",
- PTR_ERR(cmd));
+ ret = PTR_ERR(cmd);
+ vq_err(vq, "vhost_scsi_get_tag failed %dd\n", ret);
goto err;
}
- cmd->tvc_vhost = vs;
cmd->tvc_vq = vq;
- for (i = 0; i < vc.in ; i++)
- cmd->tvc_resp_iov[i] = vq->iov[vc.out + i];
- cmd->tvc_in_iovs = vc.in;
+
+ ret = vhost_scsi_setup_resp_iovs(cmd, &vq->iov[vc.out], vc.in);
+ if (ret) {
+ vq_err(vq, "Failed to alloc recv iovs\n");
+ vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd);
+ goto err;
+ }
pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
- cmd->tvc_cdb[0], cmd->tvc_lun);
+ cdb[0], lun);
pr_debug("cmd: %p exp_data_len: %d, prot_bytes: %d data_direction:"
" %d\n", cmd, exp_data_len, prot_bytes, data_direction);
if (data_direction != DMA_NONE) {
- if (unlikely(vhost_scsi_mapal(cmd, prot_bytes,
- &prot_iter, exp_data_len,
- &data_iter))) {
+ ret = vhost_scsi_mapal(vs, cmd, prot_bytes, &prot_iter,
+ exp_data_len, &data_iter,
+ data_direction);
+ if (unlikely(ret)) {
vq_err(vq, "Failed to map iov to sgl\n");
vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd);
goto err;
@@ -1246,7 +1375,9 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
* vhost_scsi_queue_data_in() and vhost_scsi_queue_status()
*/
cmd->tvc_vq_desc = vc.head;
- vhost_scsi_target_queue_cmd(cmd);
+ vhost_scsi_target_queue_cmd(nexus, cmd, cdb, lun, task_attr,
+ data_direction,
+ exp_data_len + prot_bytes);
ret = 0;
err:
/*
@@ -1254,11 +1385,15 @@ err:
* EINVAL: Invalid response buffer, drop the request
* EIO: Respond with bad target
* EAGAIN: Pending request
+ * ENOMEM: Could not allocate resources for request
*/
if (ret == -ENXIO)
break;
else if (ret == -EIO)
vhost_scsi_send_bad_target(vs, vq, vc.head, vc.out);
+ else if (ret == -ENOMEM)
+ vhost_scsi_send_status(vs, vq, vc.head, vc.out,
+ SAM_STAT_TASK_SET_FULL);
} while (likely(!vhost_exceeds_weight(vq, ++c, 0)));
out:
mutex_unlock(&vq->mutex);
@@ -1596,13 +1731,12 @@ static void vhost_scsi_destroy_vq_cmds(struct vhost_virtqueue *vq)
for (i = 0; i < svq->max_cmds; i++) {
tv_cmd = &svq->scsi_cmds[i];
- kfree(tv_cmd->tvc_sgl);
- kfree(tv_cmd->tvc_prot_sgl);
- kfree(tv_cmd->tvc_upages);
- kfree(tv_cmd->tvc_resp_iov);
+ kfree(tv_cmd->sgl);
+ kfree(tv_cmd->prot_sgl);
}
sbitmap_free(&svq->scsi_tags);
+ kfree(svq->upages);
kfree(svq->scsi_cmds);
svq->scsi_cmds = NULL;
}
@@ -1611,6 +1745,7 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds)
{
struct vhost_scsi_virtqueue *svq = container_of(vq,
struct vhost_scsi_virtqueue, vq);
+ struct vhost_scsi *vs = svq->vs;
struct vhost_scsi_cmd *tv_cmd;
unsigned int i;
@@ -1628,39 +1763,33 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds)
return -ENOMEM;
}
+ svq->upages = kcalloc(VHOST_SCSI_PREALLOC_UPAGES, sizeof(struct page *),
+ GFP_KERNEL);
+ if (!svq->upages)
+ goto out;
+
for (i = 0; i < max_cmds; i++) {
tv_cmd = &svq->scsi_cmds[i];
- tv_cmd->tvc_sgl = kcalloc(VHOST_SCSI_PREALLOC_SGLS,
- sizeof(struct scatterlist),
- GFP_KERNEL);
- if (!tv_cmd->tvc_sgl) {
- pr_err("Unable to allocate tv_cmd->tvc_sgl\n");
- goto out;
- }
-
- tv_cmd->tvc_upages = kcalloc(VHOST_SCSI_PREALLOC_UPAGES,
- sizeof(struct page *),
- GFP_KERNEL);
- if (!tv_cmd->tvc_upages) {
- pr_err("Unable to allocate tv_cmd->tvc_upages\n");
- goto out;
- }
-
- tv_cmd->tvc_resp_iov = kcalloc(UIO_MAXIOV,
- sizeof(struct iovec),
- GFP_KERNEL);
- if (!tv_cmd->tvc_resp_iov) {
- pr_err("Unable to allocate tv_cmd->tvc_resp_iov\n");
- goto out;
+ if (vs->inline_sg_cnt) {
+ tv_cmd->sgl = kcalloc(vs->inline_sg_cnt,
+ sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (!tv_cmd->sgl) {
+ pr_err("Unable to allocate tv_cmd->sgl\n");
+ goto out;
+ }
}
- tv_cmd->tvc_prot_sgl = kcalloc(VHOST_SCSI_PREALLOC_PROT_SGLS,
- sizeof(struct scatterlist),
- GFP_KERNEL);
- if (!tv_cmd->tvc_prot_sgl) {
- pr_err("Unable to allocate tv_cmd->tvc_prot_sgl\n");
- goto out;
+ if (vhost_has_feature(vq, VIRTIO_SCSI_F_T10_PI) &&
+ vs->inline_sg_cnt) {
+ tv_cmd->prot_sgl = kcalloc(vs->inline_sg_cnt,
+ sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (!tv_cmd->prot_sgl) {
+ pr_err("Unable to allocate tv_cmd->prot_sgl\n");
+ goto out;
+ }
}
}
return 0;
@@ -1699,14 +1828,19 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
}
}
+ if (vs->vs_tpg) {
+ pr_err("vhost-scsi endpoint already set for %s.\n",
+ vs->vs_vhost_wwpn);
+ ret = -EEXIST;
+ goto out;
+ }
+
len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
vs_tpg = kzalloc(len, GFP_KERNEL);
if (!vs_tpg) {
ret = -ENOMEM;
goto out;
}
- if (vs->vs_tpg)
- memcpy(vs_tpg, vs->vs_tpg, len);
mutex_lock(&vhost_scsi_mutex);
list_for_each_entry(tpg, &vhost_scsi_list, tv_tpg_list) {
@@ -1722,12 +1856,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
tv_tport = tpg->tport;
if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
- if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
- mutex_unlock(&tpg->tv_tpg_mutex);
- mutex_unlock(&vhost_scsi_mutex);
- ret = -EEXIST;
- goto undepend;
- }
/*
* In order to ensure individual vhost-scsi configfs
* groups cannot be removed while in use by vhost ioctl,
@@ -1774,15 +1902,15 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
}
ret = 0;
} else {
- ret = -EEXIST;
+ ret = -ENODEV;
+ goto free_tpg;
}
/*
- * Act as synchronize_rcu to make sure access to
- * old vs->vs_tpg is finished.
+ * Act as synchronize_rcu to make sure requests after this point
+ * see a fully setup device.
*/
vhost_scsi_flush(vs);
- kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
goto out;
@@ -1802,6 +1930,7 @@ undepend:
target_undepend_item(&tpg->se_tpg.tpg_group.cg_item);
}
}
+free_tpg:
kfree(vs_tpg);
out:
mutex_unlock(&vs->dev.mutex);
@@ -1904,6 +2033,7 @@ free_vs_tpg:
vhost_scsi_flush(vs);
kfree(vs->vs_tpg);
vs->vs_tpg = NULL;
+ memset(vs->vs_vhost_wwpn, 0, sizeof(vs->vs_vhost_wwpn));
WARN_ON(vs->vs_events_nr);
mutex_unlock(&vs->dev.mutex);
return 0;
@@ -1948,6 +2078,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
vs = kvzalloc(sizeof(*vs), GFP_KERNEL);
if (!vs)
goto err_vs;
+ vs->inline_sg_cnt = vhost_scsi_inline_sg_cnt;
if (nvqs > VHOST_SCSI_MAX_IO_VQ) {
pr_err("Invalid max_io_vqs of %d. Using %d.\n", nvqs,
diff --git a/drivers/video/fbdev/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c
index 9e41d2a18649..bf764c92bcf1 100644
--- a/drivers/video/fbdev/aty/radeon_backlight.c
+++ b/drivers/video/fbdev/aty/radeon_backlight.c
@@ -59,7 +59,7 @@ static int radeon_bl_update_status(struct backlight_device *bd)
*/
level = backlight_get_brightness(bd);
- del_timer_sync(&rinfo->lvds_timer);
+ timer_delete_sync(&rinfo->lvds_timer);
radeon_engine_idle();
lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index d866608da8d1..c6c4753f6415 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -1082,7 +1082,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
}
break;
case MT_LCD:
- del_timer_sync(&rinfo->lvds_timer);
+ timer_delete_sync(&rinfo->lvds_timer);
val = INREG(LVDS_GEN_CNTL);
if (unblank) {
u32 target_val = (val & ~LVDS_DISPLAY_DIS) | LVDS_BLON | LVDS_ON
@@ -2516,7 +2516,7 @@ static void radeonfb_pci_unregister(struct pci_dev *pdev)
if (rinfo->mon2_EDID)
sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
- del_timer_sync(&rinfo->lvds_timer);
+ timer_delete_sync(&rinfo->lvds_timer);
arch_phys_wc_del(rinfo->wc_cookie);
radeonfb_bl_exit(rinfo);
unregister_framebuffer(info);
diff --git a/drivers/video/fbdev/aty/radeon_pm.c b/drivers/video/fbdev/aty/radeon_pm.c
index 97a5972f5b1f..5ff4a964055a 100644
--- a/drivers/video/fbdev/aty/radeon_pm.c
+++ b/drivers/video/fbdev/aty/radeon_pm.c
@@ -2650,7 +2650,7 @@ static int radeonfb_pci_suspend_late(struct device *dev, pm_message_t mesg)
/* Sleep */
rinfo->asleep = 1;
rinfo->lock_blank = 1;
- del_timer_sync(&rinfo->lvds_timer);
+ timer_delete_sync(&rinfo->lvds_timer);
#ifdef CONFIG_PPC_PMAC
/* On powermac, we have hooks to properly suspend/resume AGP now,
diff --git a/drivers/video/fbdev/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c
index 161fc65d6b57..64e76e1f5388 100644
--- a/drivers/video/fbdev/omap/hwa742.c
+++ b/drivers/video/fbdev/omap/hwa742.c
@@ -597,7 +597,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode)
break;
case OMAPFB_AUTO_UPDATE:
hwa742.stop_auto_update = 1;
- del_timer_sync(&hwa742.auto_update_timer);
+ timer_delete_sync(&hwa742.auto_update_timer);
break;
case OMAPFB_UPDATE_DISABLED:
break;
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
index 1f3434c040c1..370e8623754e 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
@@ -835,7 +835,7 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
#ifdef DSI_CATCH_MISSING_TE
if (irqstatus & DSI_IRQ_TE_TRIGGER)
- del_timer(&dsi->te_timer);
+ timer_delete(&dsi->te_timer);
#endif
/* make a copy and unlock, so that isrs can unregister
diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
index c6e9855998ab..f1674f3ed923 100644
--- a/drivers/virt/vboxguest/vboxguest_core.c
+++ b/drivers/virt/vboxguest/vboxguest_core.c
@@ -495,7 +495,7 @@ static int vbg_heartbeat_init(struct vbg_dev *gdev)
*/
static void vbg_heartbeat_exit(struct vbg_dev *gdev)
{
- del_timer_sync(&gdev->heartbeat_timer);
+ timer_delete_sync(&gdev->heartbeat_timer);
vbg_heartbeat_host_config(gdev, false);
vbg_req_free(gdev->guest_heartbeat_req,
sizeof(*gdev->guest_heartbeat_req));
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index ba37665188b5..150753c3b578 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -395,6 +395,34 @@ static const struct cpumask *virtio_irq_get_affinity(struct device *_d,
return dev->config->get_vq_affinity(dev, irq_vec);
}
+static void virtio_dev_shutdown(struct device *_d)
+{
+ struct virtio_device *dev = dev_to_virtio(_d);
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ /*
+ * Stop accesses to or from the device.
+ * We only need to do it if there's a driver - no accesses otherwise.
+ */
+ if (!drv)
+ return;
+
+ /*
+ * Some devices get wedged if you kick them after they are
+ * reset. Mark all vqs as broken to make sure we don't.
+ */
+ virtio_break_device(dev);
+ /*
+ * Guarantee that any callback will see vq->broken as true.
+ */
+ virtio_synchronize_cbs(dev);
+ /*
+ * As IOMMUs are reset on shutdown, this will block device access to memory.
+ * Some devices get wedged if this happens, so reset to make sure it does not.
+ */
+ dev->config->reset(dev);
+}
+
static const struct bus_type virtio_bus = {
.name = "virtio",
.match = virtio_dev_match,
@@ -403,6 +431,7 @@ static const struct bus_type virtio_bus = {
.probe = virtio_dev_probe,
.remove = virtio_dev_remove,
.irq_get_affinity = virtio_irq_get_affinity,
+ .shutdown = virtio_dev_shutdown,
};
int __register_virtio_driver(struct virtio_driver *driver, struct module *owner)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index f81705f8539a..0d8d37f712e8 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -279,6 +279,18 @@ config LENOVO_SE10_WDT
This driver can also be built as a module. If so, the module
will be called lenovo-se10-wdt.
+config LENOVO_SE30_WDT
+ tristate "Lenovo SE30 Watchdog"
+ depends on (X86 && DMI) || COMPILE_TEST
+ depends on HAS_IOPORT
+ select WATCHDOG_CORE
+ help
+ If you say yes here you get support for the watchdog
+ functionality for the Lenovo SE30 platform.
+
+ This driver can also be built as a module. If so, the module
+ will be called lenovo-se30-wdt.
+
config MENF21BMC_WATCHDOG
tristate "MEN 14F021P00 BMC Watchdog"
depends on MFD_MENF21BMC || COMPILE_TEST
@@ -963,13 +975,14 @@ config RENESAS_RZG2LWDT
Renesas RZ/G2L SoCs. These watchdogs can be used to reset a system.
config RENESAS_RZV2HWDT
- tristate "Renesas RZ/V2H(P) WDT Watchdog"
- depends on ARCH_R9A09G057 || COMPILE_TEST
+ tristate "Renesas RZ/{G3E,V2H(P)} WDT Watchdog"
+ depends on ARCH_RENESAS || COMPILE_TEST
depends on PM || COMPILE_TEST
select WATCHDOG_CORE
help
This driver adds watchdog support for the integrated watchdogs in the
- Renesas RZ/V2H(P) SoCs. These watchdogs can be used to reset a system.
+ Renesas RZ/{G3E,V2H(P)} SoCs. These watchdogs can be used to reset a
+ system.
config ASPEED_WATCHDOG
tristate "Aspeed BMC watchdog support"
@@ -1730,7 +1743,8 @@ config NI903X_WDT
config NIC7018_WDT
tristate "NIC7018 Watchdog"
- depends on X86 && ACPI
+ depends on HAS_IOPORT
+ depends on ACPI || COMPILE_TEST
select WATCHDOG_CORE
help
Support for National Instruments NIC7018 Watchdog.
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 8411626fa162..c9482904bf87 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o
obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
obj-$(CONFIG_LENOVO_SE10_WDT) += lenovo_se10_wdt.o
+obj-$(CONFIG_LENOVO_SE30_WDT) += lenovo_se30_wdt.o
ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y)
obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
endif
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 9c7cf939ba3d..03a559b41f5b 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -166,7 +166,7 @@ static void wdt_startup(void)
static void wdt_turnoff(void)
{
/* Stop the timer */
- del_timer_sync(&timer);
+ timer_delete_sync(&timer);
wdt_change(WDT_DISABLE);
pr_info("Watchdog timer is now disabled...\n");
}
@@ -223,7 +223,7 @@ static int fop_close(struct inode *inode, struct file *file)
if (wdt_expect_close == 42)
wdt_turnoff();
else {
- /* wim: shouldn't there be a: del_timer(&timer); */
+ /* wim: shouldn't there be a: timer_delete(&timer); */
pr_crit("device file closed unexpectedly. Will not stop the WDT!\n");
}
clear_bit(0, &wdt_is_open);
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index b4773a6aaf8c..837e15701c0e 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -11,21 +11,30 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kstrtox.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/watchdog.h>
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+struct aspeed_wdt_scu {
+ const char *compatible;
+ u32 reset_status_reg;
+ u32 wdt_reset_mask;
+ u32 wdt_reset_mask_shift;
+};
struct aspeed_wdt_config {
u32 ext_pulse_width_mask;
u32 irq_shift;
u32 irq_mask;
+ struct aspeed_wdt_scu scu;
};
struct aspeed_wdt {
@@ -39,18 +48,36 @@ static const struct aspeed_wdt_config ast2400_config = {
.ext_pulse_width_mask = 0xff,
.irq_shift = 0,
.irq_mask = 0,
+ .scu = {
+ .compatible = "aspeed,ast2400-scu",
+ .reset_status_reg = 0x3c,
+ .wdt_reset_mask = 0x1,
+ .wdt_reset_mask_shift = 1,
+ },
};
static const struct aspeed_wdt_config ast2500_config = {
.ext_pulse_width_mask = 0xfffff,
.irq_shift = 12,
.irq_mask = GENMASK(31, 12),
+ .scu = {
+ .compatible = "aspeed,ast2500-scu",
+ .reset_status_reg = 0x3c,
+ .wdt_reset_mask = 0x1,
+ .wdt_reset_mask_shift = 2,
+ },
};
static const struct aspeed_wdt_config ast2600_config = {
.ext_pulse_width_mask = 0xfffff,
.irq_shift = 0,
.irq_mask = GENMASK(31, 10),
+ .scu = {
+ .compatible = "aspeed,ast2600-scu",
+ .reset_status_reg = 0x74,
+ .wdt_reset_mask = 0xf,
+ .wdt_reset_mask_shift = 16,
+ },
};
static const struct of_device_id aspeed_wdt_of_table[] = {
@@ -213,6 +240,56 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
return 0;
}
+static void aspeed_wdt_update_bootstatus(struct platform_device *pdev,
+ struct aspeed_wdt *wdt)
+{
+ const struct resource *res;
+ struct aspeed_wdt_scu scu = wdt->cfg->scu;
+ struct regmap *scu_base;
+ u32 reset_mask_width;
+ u32 reset_mask_shift;
+ u32 idx = 0;
+ u32 status;
+ int ret;
+
+ if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res);
+ }
+
+ scu_base = syscon_regmap_lookup_by_compatible(scu.compatible);
+ if (IS_ERR(scu_base)) {
+ wdt->wdd.bootstatus = WDIOS_UNKNOWN;
+ return;
+ }
+
+ ret = regmap_read(scu_base, scu.reset_status_reg, &status);
+ if (ret) {
+ wdt->wdd.bootstatus = WDIOS_UNKNOWN;
+ return;
+ }
+
+ reset_mask_width = hweight32(scu.wdt_reset_mask);
+ reset_mask_shift = scu.wdt_reset_mask_shift +
+ reset_mask_width * idx;
+
+ if (status & (scu.wdt_reset_mask << reset_mask_shift))
+ wdt->wdd.bootstatus = WDIOF_CARDRESET;
+
+ /* clear wdt reset event flag */
+ if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt") ||
+ of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-wdt")) {
+ ret = regmap_read(scu_base, scu.reset_status_reg, &status);
+ if (!ret) {
+ status &= ~(scu.wdt_reset_mask << reset_mask_shift);
+ regmap_write(scu_base, scu.reset_status_reg, status);
+ }
+ } else {
+ regmap_write(scu_base, scu.reset_status_reg,
+ scu.wdt_reset_mask << reset_mask_shift);
+ }
+}
+
/* access_cs0 shows if cs0 is accessible, hence the reverted bit */
static ssize_t access_cs0_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -458,10 +535,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
}
+ aspeed_wdt_update_bootstatus(pdev, wdt);
+
status = readl(wdt->base + WDT_TIMEOUT_STATUS);
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) {
- wdt->wdd.bootstatus = WDIOF_CARDRESET;
-
if (of_device_is_compatible(np, "aspeed,ast2400-wdt") ||
of_device_is_compatible(np, "aspeed,ast2500-wdt"))
wdt->wdd.groups = bswitch_groups;
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 7be70b98d091..1b47a2fc7d17 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -242,7 +242,7 @@ static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt)
return 0;
out_stop_timer:
- del_timer(&wdt->timer);
+ timer_delete(&wdt->timer);
return err;
}
@@ -378,7 +378,7 @@ static void at91wdt_remove(struct platform_device *pdev)
watchdog_unregister_device(&wdt->wdd);
pr_warn("I quit now, hardware will probably reboot!\n");
- del_timer(&wdt->timer);
+ timer_delete(&wdt->timer);
}
#if defined(CONFIG_OF)
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 06a54c7de40b..4c0951307421 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -139,7 +139,7 @@ static int bcm47xx_wdt_soft_stop(struct watchdog_device *wdd)
{
struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
- del_timer_sync(&wdt->soft_timer);
+ timer_delete_sync(&wdt->soft_timer);
wdt->timer_set(wdt, 0);
return 0;
@@ -213,7 +213,7 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
err_timer:
if (soft)
- del_timer_sync(&wdt->soft_timer);
+ timer_delete_sync(&wdt->soft_timer);
return ret;
}
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 4fb92c9e046a..13a4d47e68cd 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -240,7 +240,7 @@ static void cpwd_brokentimer(struct timer_list *unused)
* were called directly instead of by kernel timer
*/
if (timer_pending(&cpwd_timer))
- del_timer(&cpwd_timer);
+ timer_delete(&cpwd_timer);
for (id = 0; id < WD_NUMDEVS; id++) {
if (p->devs[id].runstatus & WD_STAT_BSTOP) {
@@ -629,7 +629,7 @@ static void cpwd_remove(struct platform_device *op)
}
if (p->broken)
- del_timer_sync(&cpwd_timer);
+ timer_delete_sync(&cpwd_timer);
if (p->initialized)
free_irq(p->irq, p);
diff --git a/drivers/watchdog/cros_ec_wdt.c b/drivers/watchdog/cros_ec_wdt.c
index ba045e29f9a5..716c23f4388c 100644
--- a/drivers/watchdog/cros_ec_wdt.c
+++ b/drivers/watchdog/cros_ec_wdt.c
@@ -58,7 +58,7 @@ static int cros_ec_wdt_ping(struct watchdog_device *wdd)
arg.req.command = EC_HANG_DETECT_CMD_RELOAD;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
- dev_dbg(wdd->parent, "Failed to ping watchdog (%d)", ret);
+ dev_dbg(wdd->parent, "Failed to ping watchdog (%d)\n", ret);
return ret;
}
@@ -74,7 +74,7 @@ static int cros_ec_wdt_start(struct watchdog_device *wdd)
arg.req.reboot_timeout_sec = wdd->timeout;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
- dev_dbg(wdd->parent, "Failed to start watchdog (%d)", ret);
+ dev_dbg(wdd->parent, "Failed to start watchdog (%d)\n", ret);
return ret;
}
@@ -88,7 +88,7 @@ static int cros_ec_wdt_stop(struct watchdog_device *wdd)
arg.req.command = EC_HANG_DETECT_CMD_CANCEL;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
- dev_dbg(wdd->parent, "Failed to stop watchdog (%d)", ret);
+ dev_dbg(wdd->parent, "Failed to stop watchdog (%d)\n", ret);
return ret;
}
@@ -136,7 +136,7 @@ static int cros_ec_wdt_probe(struct platform_device *pdev)
arg.req.command = EC_HANG_DETECT_CMD_GET_STATUS;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to get watchdog bootstatus");
+ return dev_err_probe(dev, ret, "Failed to get watchdog bootstatus\n");
wdd->parent = &pdev->dev;
wdd->info = &cros_ec_wdt_ident;
@@ -150,7 +150,7 @@ static int cros_ec_wdt_probe(struct platform_device *pdev)
arg.req.command = EC_HANG_DETECT_CMD_CLEAR_STATUS;
ret = cros_ec_wdt_send_cmd(cros_ec, &arg);
if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to clear watchdog bootstatus");
+ return dev_err_probe(dev, ret, "Failed to clear watchdog bootstatus\n");
watchdog_stop_on_reboot(wdd);
watchdog_stop_on_unregister(wdd);
diff --git a/drivers/watchdog/lenovo_se30_wdt.c b/drivers/watchdog/lenovo_se30_wdt.c
new file mode 100644
index 000000000000..024b842499b3
--- /dev/null
+++ b/drivers/watchdog/lenovo_se30_wdt.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * WDT driver for Lenovo SE30 device
+ */
+
+#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/io.h>
+#include <linux/dmi.h>
+#include <linux/delay.h>
+#include <linux/iommu.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+#define IOREGION_OFFSET 4 /* Use EC port 1 */
+#define IOREGION_LENGTH 4
+
+#define WATCHDOG_TIMEOUT 60
+
+#define MIN_TIMEOUT 1
+#define MAX_TIMEOUT 255
+#define MAX_WAIT 10
+
+static int timeout; /* in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+ "Watchdog timeout in seconds. 1 <= timeout <= 255, default="
+ __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define LNV_SE30_NAME "lenovo-se30-wdt"
+#define LNV_SE30_ID 0x0110
+#define CHIPID_MASK 0xFFF0
+
+#define CHIPID_REG 0x20
+#define SIO_REG 0x2e
+#define LDN_REG 0x07
+#define UNLOCK_KEY 0x87
+#define LOCK_KEY 0xAA
+#define LD_NUM_SHM 0x0F
+#define LD_BASE_ADDR 0xF8
+
+#define WDT_MODULE 0x10
+#define WDT_CFG_INDEX 0x15 /* WD configuration register */
+#define WDT_CNT_INDEX 0x16 /* WD timer count register */
+#define WDT_CFG_RESET 0x2
+
+/* Host Interface WIN2 offset definition */
+#define SHM_WIN_SIZE 0xFF
+#define SHM_WIN_MOD_OFFSET 0x01
+#define SHM_WIN_CMD_OFFSET 0x02
+#define SHM_WIN_SEL_OFFSET 0x03
+#define SHM_WIN_CTL_OFFSET 0x04
+#define VAL_SHM_WIN_CTRL_WR 0x40
+#define VAL_SHM_WIN_CTRL_RD 0x80
+#define SHM_WIN_ID_OFFSET 0x08
+#define SHM_WIN_DAT_OFFSET 0x10
+
+struct nct6692_reg {
+ unsigned char mod;
+ unsigned char cmd;
+ unsigned char sel;
+ unsigned int idx;
+};
+
+/* Watchdog is based on NCT6692 device */
+struct lenovo_se30_wdt {
+ unsigned char __iomem *shm_base_addr;
+ struct nct6692_reg wdt_cfg;
+ struct nct6692_reg wdt_cnt;
+ struct watchdog_device wdt;
+};
+
+static inline void superio_outb(int ioreg, int reg, int val)
+{
+ outb(reg, ioreg);
+ outb(val, ioreg + 1);
+}
+
+static inline int superio_inb(int ioreg, int reg)
+{
+ outb(reg, ioreg);
+ return inb(ioreg + 1);
+}
+
+static inline int superio_enter(int key, int addr, const char *name)
+{
+ if (!request_muxed_region(addr, 2, name)) {
+ pr_err("I/O address 0x%04x already in use\n", addr);
+ return -EBUSY;
+ }
+ outb(key, addr); /* Enter extended function mode */
+ outb(key, addr); /* Again according to manual */
+
+ return 0;
+}
+
+static inline void superio_exit(int key, int addr)
+{
+ outb(key, addr); /* Leave extended function mode */
+ release_region(addr, 2);
+}
+
+static int shm_get_ready(unsigned char __iomem *shm_base_addr,
+ const struct nct6692_reg *reg)
+{
+ unsigned char pre_id, new_id;
+ int loop = 0;
+
+ iowrite8(reg->mod, shm_base_addr + SHM_WIN_MOD_OFFSET);
+ iowrite8(reg->cmd, shm_base_addr + SHM_WIN_CMD_OFFSET);
+ iowrite8(reg->sel, shm_base_addr + SHM_WIN_SEL_OFFSET);
+
+ pre_id = ioread8(shm_base_addr + SHM_WIN_ID_OFFSET);
+ iowrite8(VAL_SHM_WIN_CTRL_RD, shm_base_addr + SHM_WIN_CTL_OFFSET);
+
+ /* Loop checking when interface is ready */
+ while (loop < MAX_WAIT) {
+ new_id = ioread8(shm_base_addr + SHM_WIN_ID_OFFSET);
+ if (new_id != pre_id)
+ return 0;
+ loop++;
+ usleep_range(10, 125);
+ }
+ return -ETIMEDOUT;
+}
+
+static int read_shm_win(unsigned char __iomem *shm_base_addr,
+ const struct nct6692_reg *reg,
+ unsigned char idx_offset,
+ unsigned char *data)
+{
+ int err = shm_get_ready(shm_base_addr, reg);
+
+ if (err)
+ return err;
+ *data = ioread8(shm_base_addr + SHM_WIN_DAT_OFFSET + reg->idx + idx_offset);
+ return 0;
+}
+
+static int write_shm_win(unsigned char __iomem *shm_base_addr,
+ const struct nct6692_reg *reg,
+ unsigned char idx_offset,
+ unsigned char val)
+{
+ int err = shm_get_ready(shm_base_addr, reg);
+
+ if (err)
+ return err;
+ iowrite8(val, shm_base_addr + SHM_WIN_DAT_OFFSET + reg->idx + idx_offset);
+ iowrite8(VAL_SHM_WIN_CTRL_WR, shm_base_addr + SHM_WIN_CTL_OFFSET);
+ err = shm_get_ready(shm_base_addr, reg);
+ return err;
+}
+
+static int lenovo_se30_wdt_enable(struct lenovo_se30_wdt *data, unsigned int timeout)
+{
+ if (timeout) {
+ int err = write_shm_win(data->shm_base_addr, &data->wdt_cfg, 0, WDT_CFG_RESET);
+
+ if (err)
+ return err;
+ }
+ return write_shm_win(data->shm_base_addr, &data->wdt_cnt, 0, timeout);
+}
+
+static int lenovo_se30_wdt_start(struct watchdog_device *wdog)
+{
+ struct lenovo_se30_wdt *data = watchdog_get_drvdata(wdog);
+
+ return lenovo_se30_wdt_enable(data, wdog->timeout);
+}
+
+static int lenovo_se30_wdt_stop(struct watchdog_device *wdog)
+{
+ struct lenovo_se30_wdt *data = watchdog_get_drvdata(wdog);
+
+ return lenovo_se30_wdt_enable(data, 0);
+}
+
+static unsigned int lenovo_se30_wdt_get_timeleft(struct watchdog_device *wdog)
+{
+ struct lenovo_se30_wdt *data = watchdog_get_drvdata(wdog);
+ unsigned char timeleft;
+ int err;
+
+ err = read_shm_win(data->shm_base_addr, &data->wdt_cnt, 0, &timeleft);
+ if (err)
+ return 0;
+ return timeleft;
+}
+
+static int lenovo_se30_wdt_ping(struct watchdog_device *wdt)
+{
+ struct lenovo_se30_wdt *data = watchdog_get_drvdata(wdt);
+ int err = 0;
+
+ /*
+ * Device does not support refreshing WDT_TIMER_REG register when
+ * the watchdog is active. Need to disable, feed and enable again
+ */
+ err = lenovo_se30_wdt_enable(data, 0);
+ if (err)
+ return err;
+
+ err = write_shm_win(data->shm_base_addr, &data->wdt_cnt, 0, wdt->timeout);
+ if (!err)
+ err = lenovo_se30_wdt_enable(data, wdt->timeout);
+
+ return err;
+}
+
+static const struct watchdog_info lenovo_se30_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .identity = "Lenovo SE30 watchdog",
+};
+
+static const struct watchdog_ops lenovo_se30_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = lenovo_se30_wdt_start,
+ .stop = lenovo_se30_wdt_stop,
+ .ping = lenovo_se30_wdt_ping,
+ .get_timeleft = lenovo_se30_wdt_get_timeleft,
+};
+
+static int lenovo_se30_wdt_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct lenovo_se30_wdt *priv;
+ unsigned long base_phys;
+ unsigned short val;
+ int err;
+
+ err = superio_enter(UNLOCK_KEY, SIO_REG, LNV_SE30_NAME);
+ if (err)
+ return err;
+
+ val = superio_inb(SIO_REG, CHIPID_REG) << 8;
+ val |= superio_inb(SIO_REG, CHIPID_REG + 1);
+
+ if ((val & CHIPID_MASK) != LNV_SE30_ID) {
+ superio_exit(LOCK_KEY, SIO_REG);
+ return -ENODEV;
+ }
+
+ superio_outb(SIO_REG, LDN_REG, LD_NUM_SHM);
+ base_phys = (superio_inb(SIO_REG, LD_BASE_ADDR) |
+ (superio_inb(SIO_REG, LD_BASE_ADDR + 1) << 8) |
+ (superio_inb(SIO_REG, LD_BASE_ADDR + 2) << 16) |
+ (superio_inb(SIO_REG, LD_BASE_ADDR + 3) << 24)) &
+ 0xFFFFFFFF;
+
+ superio_exit(LOCK_KEY, SIO_REG);
+ if (base_phys == 0xFFFFFFFF || base_phys == 0)
+ return -ENODEV;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (!devm_request_mem_region(dev, base_phys, SHM_WIN_SIZE, LNV_SE30_NAME))
+ return -EBUSY;
+
+ priv->shm_base_addr = devm_ioremap(dev, base_phys, SHM_WIN_SIZE);
+
+ priv->wdt_cfg.mod = WDT_MODULE;
+ priv->wdt_cfg.idx = WDT_CFG_INDEX;
+ priv->wdt_cnt.mod = WDT_MODULE;
+ priv->wdt_cnt.idx = WDT_CNT_INDEX;
+
+ priv->wdt.ops = &lenovo_se30_wdt_ops;
+ priv->wdt.info = &lenovo_se30_wdt_info;
+ priv->wdt.timeout = WATCHDOG_TIMEOUT; /* Set default timeout */
+ priv->wdt.min_timeout = MIN_TIMEOUT;
+ priv->wdt.max_timeout = MAX_TIMEOUT;
+ priv->wdt.parent = dev;
+
+ watchdog_init_timeout(&priv->wdt, timeout, dev);
+ watchdog_set_drvdata(&priv->wdt, priv);
+ watchdog_set_nowayout(&priv->wdt, nowayout);
+ watchdog_stop_on_reboot(&priv->wdt);
+ watchdog_stop_on_unregister(&priv->wdt);
+
+ return devm_watchdog_register_device(dev, &priv->wdt);
+}
+
+static struct platform_device *pdev;
+
+static struct platform_driver lenovo_se30_wdt_driver = {
+ .driver = {
+ .name = LNV_SE30_NAME,
+ },
+ .probe = lenovo_se30_wdt_probe,
+};
+
+static int lenovo_se30_create_platform_device(const struct dmi_system_id *id)
+{
+ int err;
+
+ pdev = platform_device_alloc(LNV_SE30_NAME, -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add(pdev);
+ if (err)
+ platform_device_put(pdev);
+
+ return err;
+}
+
+static const struct dmi_system_id lenovo_se30_wdt_dmi_table[] __initconst = {
+ {
+ .ident = "LENOVO-SE30",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "11NA"),
+ },
+ .callback = lenovo_se30_create_platform_device,
+ },
+ {
+ .ident = "LENOVO-SE30",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "11NB"),
+ },
+ .callback = lenovo_se30_create_platform_device,
+ },
+ {
+ .ident = "LENOVO-SE30",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "11NC"),
+ },
+ .callback = lenovo_se30_create_platform_device,
+ },
+ {
+ .ident = "LENOVO-SE30",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "11NH"),
+ },
+ .callback = lenovo_se30_create_platform_device,
+ },
+ {
+ .ident = "LENOVO-SE30",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "11NJ"),
+ },
+ .callback = lenovo_se30_create_platform_device,
+ },
+ {
+ .ident = "LENOVO-SE30",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "11NK"),
+ },
+ .callback = lenovo_se30_create_platform_device,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(dmi, lenovo_se30_wdt_dmi_table);
+
+static int __init lenovo_se30_wdt_init(void)
+{
+ if (!dmi_check_system(lenovo_se30_wdt_dmi_table))
+ return -ENODEV;
+
+ return platform_driver_register(&lenovo_se30_wdt_driver);
+}
+
+static void __exit lenovo_se30_wdt_exit(void)
+{
+ if (pdev)
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&lenovo_se30_wdt_driver);
+}
+
+module_init(lenovo_se30_wdt_init);
+module_exit(lenovo_se30_wdt_exit);
+
+MODULE_AUTHOR("Mark Pearson <mpearson-lenovo@squebb.ca>");
+MODULE_AUTHOR("David Ober <dober@lenovo.com>");
+MODULE_DESCRIPTION("Lenovo SE30 watchdog driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c
index f19580e1b318..28e3fc0df4c6 100644
--- a/drivers/watchdog/lpc18xx_wdt.c
+++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -135,7 +135,7 @@ static int lpc18xx_wdt_start(struct watchdog_device *wdt_dev)
unsigned int val;
if (timer_pending(&lpc18xx_wdt->timer))
- del_timer(&lpc18xx_wdt->timer);
+ timer_delete(&lpc18xx_wdt->timer);
val = readl(lpc18xx_wdt->base + LPC18XX_WDT_MOD);
val |= LPC18XX_WDT_MOD_WDEN;
@@ -266,7 +266,7 @@ static void lpc18xx_wdt_remove(struct platform_device *pdev)
struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
- del_timer_sync(&lpc18xx_wdt->timer);
+ timer_delete_sync(&lpc18xx_wdt->timer);
}
static const struct of_device_id lpc18xx_wdt_match[] = {
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 73d641486909..0ae8e5bc10ae 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -189,7 +189,7 @@ static void zf_timer_off(void)
unsigned long flags;
/* stop internal ping */
- del_timer_sync(&zf_timer);
+ timer_delete_sync(&zf_timer);
spin_lock_irqsave(&zf_port_lock, flags);
/* stop watchdog timer */
@@ -337,7 +337,7 @@ static int zf_close(struct inode *inode, struct file *file)
if (zf_expect_close == 42)
zf_timer_off();
else {
- del_timer(&zf_timer);
+ timer_delete(&zf_timer);
pr_err("device file closed unexpectedly. Will not stop the WDT!\n");
}
clear_bit(0, &zf_is_open);
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 70d9cf84c342..1ecd5c48a005 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -141,7 +141,7 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
__module_get(THIS_MODULE);
else {
if (mixcomwd_timer_alive) {
- del_timer(&mixcomwd_timer);
+ timer_delete(&mixcomwd_timer);
mixcomwd_timer_alive = 0;
}
}
@@ -295,7 +295,7 @@ static void __exit mixcomwd_exit(void)
if (!nowayout) {
if (mixcomwd_timer_alive) {
pr_warn("I quit now, hardware will probably reboot!\n");
- del_timer_sync(&mixcomwd_timer);
+ timer_delete_sync(&mixcomwd_timer);
mixcomwd_timer_alive = 0;
}
}
diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c
index 44982b37ba6f..44b5298f599a 100644
--- a/drivers/watchdog/nic7018_wdt.c
+++ b/drivers/watchdog/nic7018_wdt.c
@@ -3,12 +3,13 @@
* Copyright (C) 2016 National Instruments Corp.
*/
-#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/io.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/types.h>
#include <linux/watchdog.h>
#define LOCK 0xA5
@@ -229,8 +230,8 @@ static void nic7018_remove(struct platform_device *pdev)
}
static const struct acpi_device_id nic7018_device_ids[] = {
- {"NIC7018", 0},
- {"", 0},
+ { "NIC7018" },
+ { }
};
MODULE_DEVICE_TABLE(acpi, nic7018_device_ids);
@@ -239,7 +240,7 @@ static struct platform_driver watchdog_driver = {
.remove = nic7018_remove,
.driver = {
.name = KBUILD_MODNAME,
- .acpi_match_table = ACPI_PTR(nic7018_device_ids),
+ .acpi_match_table = nic7018_device_ids,
},
};
diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
index a5dd1c230137..e62ea054bc61 100644
--- a/drivers/watchdog/npcm_wdt.c
+++ b/drivers/watchdog/npcm_wdt.c
@@ -68,8 +68,7 @@ static int npcm_wdt_start(struct watchdog_device *wdd)
struct npcm_wdt *wdt = to_npcm_wdt(wdd);
u32 val;
- if (wdt->clk)
- clk_prepare_enable(wdt->clk);
+ clk_prepare_enable(wdt->clk);
if (wdd->timeout < 2)
val = 0x800;
@@ -105,8 +104,7 @@ static int npcm_wdt_stop(struct watchdog_device *wdd)
writel(0, wdt->reg);
- if (wdt->clk)
- clk_disable_unprepare(wdt->clk);
+ clk_disable_unprepare(wdt->clk);
return 0;
}
@@ -156,8 +154,7 @@ static int npcm_wdt_restart(struct watchdog_device *wdd,
struct npcm_wdt *wdt = to_npcm_wdt(wdd);
/* For reset, we start the WDT clock and leave it running. */
- if (wdt->clk)
- clk_prepare_enable(wdt->clk);
+ clk_prepare_enable(wdt->clk);
writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg);
udelay(1000);
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index 31d3dcbf815e..d4ea7d6ccd6a 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -432,7 +432,7 @@ static int pcwd_stop(void)
int stat_reg;
/* Stop the timer */
- del_timer(&pcwd_private.timer);
+ timer_delete(&pcwd_private.timer);
/* Disable the board */
if (pcwd_private.revision == PCWD_REVISION_C) {
diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c
index 393aa4b1bc13..87b8988d2520 100644
--- a/drivers/watchdog/pika_wdt.c
+++ b/drivers/watchdog/pika_wdt.c
@@ -129,7 +129,7 @@ static int pikawdt_release(struct inode *inode, struct file *file)
{
/* stop internal ping */
if (!pikawdt_private.expect_close)
- del_timer(&pikawdt_private.timer);
+ timer_delete(&pikawdt_private.timer);
clear_bit(0, &pikawdt_private.open);
pikawdt_private.expect_close = 0;
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 30450e99e5e9..bdd81d8074b2 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -72,6 +72,8 @@
#define EXYNOS850_CLUSTER1_WDTRESET_BIT 23
#define EXYNOSAUTOV9_CLUSTER0_WDTRESET_BIT 25
#define EXYNOSAUTOV9_CLUSTER1_WDTRESET_BIT 24
+#define EXYNOSAUTOV920_CLUSTER0_WDTRESET_BIT 0
+#define EXYNOSAUTOV920_CLUSTER1_WDTRESET_BIT 1
#define GS_CLUSTER0_NONCPU_OUT 0x1220
#define GS_CLUSTER1_NONCPU_OUT 0x1420
@@ -312,9 +314,9 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl0 = {
.mask_bit = 2,
.mask_reset_inv = true,
.rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET,
- .rst_stat_bit = EXYNOSAUTOV9_CLUSTER0_WDTRESET_BIT,
+ .rst_stat_bit = EXYNOSAUTOV920_CLUSTER0_WDTRESET_BIT,
.cnt_en_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_OUT,
- .cnt_en_bit = 7,
+ .cnt_en_bit = 8,
.quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET |
QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN |
QUIRK_HAS_DBGACK_BIT,
@@ -325,9 +327,9 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = {
.mask_bit = 2,
.mask_reset_inv = true,
.rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET,
- .rst_stat_bit = EXYNOSAUTOV9_CLUSTER1_WDTRESET_BIT,
+ .rst_stat_bit = EXYNOSAUTOV920_CLUSTER1_WDTRESET_BIT,
.cnt_en_reg = EXYNOSAUTOV920_CLUSTER1_NONCPU_OUT,
- .cnt_en_bit = 7,
+ .cnt_en_bit = 8,
.quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET |
QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN |
QUIRK_HAS_DBGACK_BIT,
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index e9bf12918ed8..03eaf48c8f0f 100644
--- a/drivers/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
@@ -146,7 +146,7 @@ static void wdt_startup(void)
static void wdt_turnoff(void)
{
/* Stop the timer */
- del_timer_sync(&timer);
+ timer_delete_sync(&timer);
inb_p(wdt_stop);
pr_info("Watchdog timer is now disabled...\n");
}
@@ -210,7 +210,7 @@ static int fop_close(struct inode *inode, struct file *file)
if (wdt_expect_close == 42)
wdt_turnoff();
else {
- del_timer(&timer);
+ timer_delete(&timer);
pr_crit("device file closed unexpectedly. Will not stop the WDT!\n");
}
clear_bit(0, &wdt_is_open);
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index e849e1af267b..005f62e4a4fb 100644
--- a/drivers/watchdog/sc520_wdt.c
+++ b/drivers/watchdog/sc520_wdt.c
@@ -186,7 +186,7 @@ static int wdt_startup(void)
static int wdt_turnoff(void)
{
/* Stop the timer */
- del_timer_sync(&timer);
+ timer_delete_sync(&timer);
/* Stop the watchdog */
wdt_config(0);
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 7f0150c39421..95af9ad94d16 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -129,7 +129,7 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev)
spin_lock_irqsave(&wdt->lock, flags);
- del_timer(&wdt->timer);
+ timer_delete(&wdt->timer);
csr = sh_wdt_read_csr();
csr &= ~WTCSR_TME;
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index b85354a99582..b6c761acc3de 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -236,10 +236,21 @@ static const struct sunxi_wdt_reg sun20i_wdt_reg = {
.wdt_key_val = 0x16aa0000,
};
+static const struct sunxi_wdt_reg sun55i_wdt_reg = {
+ .wdt_ctrl = 0x0c,
+ .wdt_cfg = 0x10,
+ .wdt_mode = 0x14,
+ .wdt_timeout_shift = 4,
+ .wdt_reset_mask = 0x03,
+ .wdt_reset_val = 0x01,
+ .wdt_key_val = 0x16aa0000,
+};
+
static const struct of_device_id sunxi_wdt_dt_ids[] = {
{ .compatible = "allwinner,sun4i-a10-wdt", .data = &sun4i_wdt_reg },
{ .compatible = "allwinner,sun6i-a31-wdt", .data = &sun6i_wdt_reg },
{ .compatible = "allwinner,sun20i-d1-wdt", .data = &sun20i_wdt_reg },
+ { .compatible = "allwinner,sun55i-a523-wdt", .data = &sun55i_wdt_reg },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index eeb39f96e72e..d647923d68fe 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -233,7 +233,7 @@ err_out_disable_device:
static void wdt_remove(struct pci_dev *pdev)
{
watchdog_unregister_device(&wdt_dev);
- del_timer_sync(&timer);
+ timer_delete_sync(&timer);
iounmap(wdt_mem);
release_mem_region(mmio, VIA_WDT_MMIO_LEN);
release_resource(&wdt_res);
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c
index 1937084c182c..53db59ef774b 100644
--- a/drivers/watchdog/w83877f_wdt.c
+++ b/drivers/watchdog/w83877f_wdt.c
@@ -166,7 +166,7 @@ static void wdt_startup(void)
static void wdt_turnoff(void)
{
/* Stop the timer */
- del_timer_sync(&timer);
+ timer_delete_sync(&timer);
wdt_change(WDT_DISABLE);
@@ -228,7 +228,7 @@ static int fop_close(struct inode *inode, struct file *file)
if (wdt_expect_close == 42)
wdt_turnoff();
else {
- del_timer(&timer);
+ timer_delete(&timer);
pr_crit("device file closed unexpectedly. Will not stop the WDT!\n");
}
clear_bit(0, &wdt_is_open);
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index d46d8c8c01f2..6152dba4b52c 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -33,7 +33,8 @@
#include <linux/init.h> /* For __init/__exit/... */
#include <linux/idr.h> /* For ida_* macros */
#include <linux/err.h> /* For IS_ERR macros */
-#include <linux/of.h> /* For of_get_timeout_sec */
+#include <linux/of.h> /* For of_alias_get_id */
+#include <linux/property.h> /* For device_property_read_u32 */
#include <linux/suspend.h>
#include "watchdog_core.h" /* For watchdog_dev_register/... */
@@ -137,8 +138,7 @@ int watchdog_init_timeout(struct watchdog_device *wdd,
}
/* try to get the timeout_sec property */
- if (dev && dev->of_node &&
- of_property_read_u32(dev->of_node, "timeout-sec", &t) == 0) {
+ if (dev && device_property_read_u32(dev, "timeout-sec", &t) == 0) {
if (t && !watchdog_timeout_invalid(wdd, t)) {
wdd->timeout = t;
return 0;