summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/accessibility/Kconfig4
-rw-r--r--drivers/acpi/acpi_extlog.c19
-rw-r--r--drivers/acpi/acpica/dbdisply.c2
-rw-r--r--drivers/acpi/acpica/utdecode.c3
-rw-r--r--drivers/acpi/device_pm.c2
-rw-r--r--drivers/acpi/nfit/core.c2
-rw-r--r--drivers/acpi/nfit/mce.c1
-rw-r--r--drivers/acpi/numa/srat.c1
-rw-r--r--drivers/acpi/scan.c31
-rw-r--r--drivers/android/Kconfig10
-rw-r--r--drivers/android/binder_alloc.c14
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/atm/Kconfig18
-rw-r--r--drivers/atm/fore200e.c2
-rw-r--r--drivers/auxdisplay/Kconfig54
-rw-r--r--drivers/base/Kconfig3
-rw-r--r--drivers/base/cpu.c8
-rw-r--r--drivers/base/power/main.c2
-rw-r--r--drivers/base/test/Kconfig3
-rw-r--r--drivers/block/Kconfig26
-rw-r--r--drivers/block/loop.c2
-rw-r--r--drivers/block/paride/Kconfig8
-rw-r--r--drivers/block/pktcdvd.c2
-rw-r--r--drivers/block/rbd.c44
-rw-r--r--drivers/block/rbd_types.h2
-rw-r--r--drivers/block/umem.c2
-rw-r--r--drivers/block/z2ram.c2
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/char/Kconfig22
-rw-r--r--drivers/char/agp/Kconfig6
-rw-r--r--drivers/char/agp/frontend.c1
-rw-r--r--drivers/char/agp/generic.c1
-rw-r--r--drivers/char/bsr.c1
-rw-r--r--drivers/char/hw_random/Kconfig62
-rw-r--r--drivers/char/mspec.c3
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/tpm/Kconfig30
-rw-r--r--drivers/char/tpm/st33zp24/Kconfig6
-rw-r--r--drivers/clk/Kconfig75
-rw-r--r--drivers/clk/Makefile4
-rw-r--r--drivers/clk/at91/at91rm9200.c12
-rw-r--r--drivers/clk/at91/at91sam9260.c13
-rw-r--r--drivers/clk/at91/at91sam9g45.c10
-rw-r--r--drivers/clk/at91/at91sam9n12.c12
-rw-r--r--drivers/clk/at91/at91sam9rl.c10
-rw-r--r--drivers/clk/at91/at91sam9x5.c10
-rw-r--r--drivers/clk/at91/pmc.c47
-rw-r--r--drivers/clk/at91/pmc.h8
-rw-r--r--drivers/clk/at91/sam9x60.c10
-rw-r--r--drivers/clk/at91/sama5d2.c13
-rw-r--r--drivers/clk/at91/sama5d3.c10
-rw-r--r--drivers/clk/at91/sama5d4.c10
-rw-r--r--drivers/clk/baikal-t1/Kconfig42
-rw-r--r--drivers/clk/baikal-t1/Makefile3
-rw-r--r--drivers/clk/baikal-t1/ccu-div.c602
-rw-r--r--drivers/clk/baikal-t1/ccu-div.h110
-rw-r--r--drivers/clk/baikal-t1/ccu-pll.c558
-rw-r--r--drivers/clk/baikal-t1/ccu-pll.h64
-rw-r--r--drivers/clk/baikal-t1/clk-ccu-div.c485
-rw-r--r--drivers/clk/baikal-t1/clk-ccu-pll.c204
-rw-r--r--drivers/clk/bcm/clk-bcm2835.c80
-rw-r--r--drivers/clk/clk-ast2600.c31
-rw-r--r--drivers/clk/clk-hsdk-pll.c70
-rw-r--r--drivers/clk/clk-si5341.c69
-rw-r--r--drivers/clk/clk-versaclock5.c11
-rw-r--r--drivers/clk/clk.c4
-rw-r--r--drivers/clk/imgtec/Kconfig2
-rw-r--r--drivers/clk/imx/Kconfig8
-rw-r--r--drivers/clk/imx/clk-composite-8m.c56
-rw-r--r--drivers/clk/imx/clk-gate2.c31
-rw-r--r--drivers/clk/imx/clk-imx6ul.c2
-rw-r--r--drivers/clk/imx/clk-imx7ulp.c6
-rw-r--r--drivers/clk/imx/clk-imx8mm.c27
-rw-r--r--drivers/clk/imx/clk-imx8mn.c25
-rw-r--r--drivers/clk/imx/clk-imx8mp.c148
-rw-r--r--drivers/clk/imx/clk-imx8mq.c29
-rw-r--r--drivers/clk/imx/clk-pll14xx.c8
-rw-r--r--drivers/clk/imx/clk-pllv3.c16
-rw-r--r--drivers/clk/imx/clk-sscg-pll.c10
-rw-r--r--drivers/clk/imx/clk.h62
-rw-r--r--drivers/clk/ingenic/Kconfig10
-rw-r--r--drivers/clk/ingenic/Makefile1
-rw-r--r--drivers/clk/ingenic/cgu.c28
-rw-r--r--drivers/clk/ingenic/cgu.h4
-rw-r--r--drivers/clk/ingenic/jz4725b-cgu.c4
-rw-r--r--drivers/clk/ingenic/jz4740-cgu.c4
-rw-r--r--drivers/clk/ingenic/jz4770-cgu.c8
-rw-r--r--drivers/clk/ingenic/jz4780-cgu.c3
-rw-r--r--drivers/clk/ingenic/tcu.c2
-rw-r--r--drivers/clk/ingenic/x1000-cgu.c123
-rw-r--r--drivers/clk/ingenic/x1830-cgu.c448
-rw-r--r--drivers/clk/keystone/Kconfig4
-rw-r--r--drivers/clk/mediatek/Kconfig150
-rw-r--r--drivers/clk/mediatek/Makefile7
-rw-r--r--drivers/clk/mediatek/clk-mt6765-audio.c100
-rw-r--r--drivers/clk/mediatek/clk-mt6765-cam.c74
-rw-r--r--drivers/clk/mediatek/clk-mt6765-img.c70
-rw-r--r--drivers/clk/mediatek/clk-mt6765-mipi0a.c68
-rw-r--r--drivers/clk/mediatek/clk-mt6765-mm.c96
-rw-r--r--drivers/clk/mediatek/clk-mt6765-vcodec.c70
-rw-r--r--drivers/clk/mediatek/clk-mt6765.c922
-rw-r--r--drivers/clk/mediatek/clk-mux.c2
-rw-r--r--drivers/clk/meson/g12a.c30
-rw-r--r--drivers/clk/meson/gxbb.c40
-rw-r--r--drivers/clk/meson/meson8b.c120
-rw-r--r--drivers/clk/meson/meson8b.h5
-rw-r--r--drivers/clk/mmp/Makefile3
-rw-r--r--drivers/clk/mmp/clk-audio.c443
-rw-r--r--drivers/clk/mmp/clk-frac.c27
-rw-r--r--drivers/clk/mmp/clk-of-mmp2.c104
-rw-r--r--drivers/clk/mmp/clk.h11
-rw-r--r--drivers/clk/mmp/pwr-island.c115
-rw-r--r--drivers/clk/qcom/Kconfig8
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/gcc-msm8916.c8
-rw-r--r--drivers/clk/qcom/gcc-msm8939.c3988
-rw-r--r--drivers/clk/qcom/gcc-msm8998.c27
-rw-r--r--drivers/clk/qcom/gcc-sc7180.c94
-rw-r--r--drivers/clk/qcom/gcc-sm8150.c148
-rw-r--r--drivers/clk/qcom/gdsc.c23
-rw-r--r--drivers/clk/qcom/gdsc.h4
-rw-r--r--drivers/clk/qcom/mmcc-msm8996.c2
-rw-r--r--drivers/clk/renesas/Kconfig8
-rw-r--r--drivers/clk/renesas/Makefile1
-rw-r--r--drivers/clk/renesas/r8a7742-cpg-mssr.c275
-rw-r--r--drivers/clk/renesas/r9a06g032-clocks.c6
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c14
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.h1
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c18
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c3
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c2
-rw-r--r--drivers/clk/socfpga/Makefile2
-rw-r--r--drivers/clk/socfpga/clk-agilex.c454
-rw-r--r--drivers/clk/socfpga/clk-gate-s10.c5
-rw-r--r--drivers/clk/socfpga/clk-periph-s10.c10
-rw-r--r--drivers/clk/socfpga/clk-pll-a10.c4
-rw-r--r--drivers/clk/socfpga/clk-pll-s10.c78
-rw-r--r--drivers/clk/socfpga/clk-pll.c4
-rw-r--r--drivers/clk/socfpga/clk-s10.c160
-rw-r--r--drivers/clk/socfpga/stratix10-clk.h10
-rw-r--r--drivers/clk/sprd/gate.c7
-rw-r--r--drivers/clk/sprd/gate.h9
-rw-r--r--drivers/clk/sprd/pll.c2
-rw-r--r--drivers/clk/sprd/sc9863a-clk.c64
-rw-r--r--drivers/clk/st/clk-flexgen.c1
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c2
-rw-r--r--drivers/clk/tegra/Kconfig4
-rw-r--r--drivers/clk/tegra/Makefile4
-rw-r--r--drivers/clk/tegra/clk-pll.c12
-rw-r--r--drivers/clk/tegra/clk-tegra-super-cclk.c212
-rw-r--r--drivers/clk/tegra/clk-tegra124-emc.c (renamed from drivers/clk/tegra/clk-emc.c)0
-rw-r--r--drivers/clk/tegra/clk-tegra20.c7
-rw-r--r--drivers/clk/tegra/clk-tegra210-emc.c369
-rw-r--r--drivers/clk/tegra/clk-tegra210.c94
-rw-r--r--drivers/clk/tegra/clk-tegra30.c6
-rw-r--r--drivers/clk/tegra/clk.h24
-rw-r--r--drivers/clk/ti/Kconfig2
-rw-r--r--drivers/clk/ti/clk-44xx.c14
-rw-r--r--drivers/clk/ti/clk-54xx.c14
-rw-r--r--drivers/clk/ti/clk-7xx.c15
-rw-r--r--drivers/clk/ti/composite.c1
-rw-r--r--drivers/clk/versatile/Kconfig6
-rw-r--r--drivers/clk/versatile/clk-versatile.c2
-rw-r--r--drivers/clk/x86/Kconfig8
-rw-r--r--drivers/clk/x86/Makefile1
-rw-r--r--drivers/clk/x86/clk-cgu-pll.c156
-rw-r--r--drivers/clk/x86/clk-cgu.c636
-rw-r--r--drivers/clk/x86/clk-cgu.h335
-rw-r--r--drivers/clk/x86/clk-lgm.c475
-rw-r--r--drivers/clk/zynqmp/clk-zynqmp.h1
-rw-r--r--drivers/clk/zynqmp/clkc.c24
-rw-r--r--drivers/clk/zynqmp/divider.c27
-rw-r--r--drivers/clocksource/timer-riscv.c43
-rw-r--r--drivers/connector/Kconfig4
-rw-r--r--drivers/cpufreq/Kconfig.x864
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c14
-rw-r--r--drivers/cpufreq/cppc_cpufreq.c39
-rw-r--r--drivers/cpufreq/cpufreq-dt.c4
-rw-r--r--drivers/cpufreq/cpufreq.c57
-rw-r--r--drivers/cpufreq/tegra186-cpufreq.c3
-rw-r--r--drivers/cpuidle/cpuidle-arm.c3
-rw-r--r--drivers/cpuidle/cpuidle-psci.c3
-rw-r--r--drivers/crypto/Kconfig8
-rw-r--r--drivers/crypto/cavium/nitrox/nitrox_main.c4
-rw-r--r--drivers/crypto/chelsio/Kconfig6
-rw-r--r--drivers/crypto/omap-aes-gcm.c1
-rw-r--r--drivers/crypto/omap-aes.c8
-rw-r--r--drivers/crypto/omap-crypto.c10
-rw-r--r--drivers/crypto/omap-sham.c101
-rw-r--r--drivers/crypto/virtio/virtio_crypto_algs.c21
-rw-r--r--drivers/dma-buf/Kconfig4
-rw-r--r--drivers/dma-buf/dma-resv.c5
-rw-r--r--drivers/dma/Kconfig14
-rw-r--r--drivers/dma/at_hdmac_regs.h2
-rw-r--r--drivers/dma/at_xdmac.c2
-rw-r--r--drivers/dma/dmaengine.c98
-rw-r--r--drivers/dma/dmatest.c24
-rw-r--r--drivers/dma/dw-edma/dw-edma-core.c65
-rw-r--r--drivers/dma/dw-edma/dw-edma-core.h4
-rw-r--r--drivers/dma/dw-edma/dw-edma-pcie.c10
-rw-r--r--drivers/dma/idxd/sysfs.c11
-rw-r--r--drivers/dma/imx-sdma.c2
-rw-r--r--drivers/dma/ioat/dma.c85
-rw-r--r--drivers/dma/ioat/dma.h10
-rw-r--r--drivers/dma/ioat/init.c2
-rw-r--r--drivers/dma/mediatek/Kconfig2
-rw-r--r--drivers/dma/mmp_tdma.c26
-rw-r--r--drivers/dma/moxart-dma.c2
-rw-r--r--drivers/dma/qcom/Kconfig2
-rw-r--r--drivers/dma/qcom/bam_dma.c2
-rw-r--r--drivers/dma/qcom/hidma.c3
-rw-r--r--drivers/dma/sf-pdma/sf-pdma.c25
-rw-r--r--drivers/dma/stm32-dma.c41
-rw-r--r--drivers/dma/ti/Kconfig4
-rw-r--r--drivers/dma/ti/k3-udma.c34
-rw-r--r--drivers/edac/Kconfig2
-rw-r--r--drivers/edac/amd64_edac.c22
-rw-r--r--drivers/edac/amd64_edac.h3
-rw-r--r--drivers/edac/edac_mc.c61
-rw-r--r--drivers/edac/i7core_edac.c5
-rw-r--r--drivers/edac/mce_amd.c28
-rw-r--r--drivers/edac/mce_amd.h2
-rw-r--r--drivers/edac/pnd2_edac.c8
-rw-r--r--drivers/edac/sb_edac.c7
-rw-r--r--drivers/edac/skx_common.c3
-rw-r--r--drivers/eisa/Kconfig10
-rw-r--r--drivers/firmware/efi/Kconfig2
-rw-r--r--drivers/firmware/efi/arm-runtime.c2
-rw-r--r--drivers/firmware/efi/efi.c2
-rw-r--r--drivers/firmware/efi/libstub/Makefile2
-rw-r--r--drivers/fsi/Kconfig16
-rw-r--r--drivers/gnss/Kconfig6
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c171
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c10
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c4
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c30
-rw-r--r--drivers/gpu/drm/amd/powerplay/smu_v11_0.c6
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c1
-rw-r--r--drivers/gpu/drm/bridge/Kconfig16
-rw-r--r--drivers/gpu/drm/drm_connector.c5
-rw-r--r--drivers/gpu/drm/drm_sysfs.c3
-rw-r--r--drivers/gpu/drm/drm_vm.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_global_state.c45
-rw-r--r--drivers/gpu/drm/i915/display/intel_global_state.h3
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_context.c9
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c56
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_mman.c4
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_shmem.c15
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_userptr.c14
-rw-r--r--drivers/gpu/drm/i915/gt/intel_context.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/vgpu.c2
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c4
-rw-r--r--drivers/gpu/drm/i915/i915_ioc32.c14
-rw-r--r--drivers/gpu/drm/i915/i915_mm.c1
-rw-r--r--drivers/gpu/drm/i915/i915_params.c4
-rw-r--r--drivers/gpu/drm/i915/i915_params.h2
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c5
-rw-r--r--drivers/gpu/drm/i915/i915_query.c62
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/i915_request.c359
-rw-r--r--drivers/gpu/drm/i915/i915_scheduler.c16
-rw-r--r--drivers/gpu/drm/msm/Makefile1
-rw-r--r--drivers/gpu/drm/msm/adreno/a2xx_gpu.c16
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c1
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c83
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c7
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx.xml.h14
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c418
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.h37
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h48
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c70
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_hfi.c123
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_hfi.h50
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c35
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c27
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h23
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c23
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c95
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c12
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c48
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h39
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c26
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h3
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c129
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h100
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c18
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h1
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c58
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h2
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c18
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c80
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c4
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c21
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c6
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h15
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c31
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h1
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c232
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c42
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c49
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h4
-rw-r--r--drivers/gpu/drm/msm/msm_gpummu.c10
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.c22
-rw-r--r--drivers/gpu/drm/msm/msm_mmu.h5
-rw-r--r--drivers/gpu/drm/msm/msm_rd.c4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c21
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.c5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/cl5070.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_svm.c22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c73
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c93
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Kconfig2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c6
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi.h2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c10
-rw-r--r--drivers/greybus/Kconfig4
-rw-r--r--drivers/hid/Kconfig208
-rw-r--r--drivers/hid/hid-alps.c3
-rw-r--r--drivers/hid/hid-multitouch.c6
-rw-r--r--drivers/hid/i2c-hid/Kconfig2
-rw-r--r--drivers/hid/usbhid/Kconfig6
-rw-r--r--drivers/hsi/Kconfig2
-rw-r--r--drivers/hsi/clients/Kconfig2
-rw-r--r--drivers/hsi/controllers/Kconfig2
-rw-r--r--drivers/hwmon/k10temp.c1
-rw-r--r--drivers/i2c/Kconfig2
-rw-r--r--drivers/i2c/busses/Kconfig60
-rw-r--r--drivers/i2c/busses/Makefile19
-rw-r--r--drivers/i2c/busses/i2c-altera.c20
-rw-r--r--drivers/i2c/busses/i2c-at91-core.c2
-rw-r--r--drivers/i2c/busses/i2c-at91-master.c49
-rw-r--r--drivers/i2c/busses/i2c-at91.h7
-rw-r--r--drivers/i2c/busses/i2c-axxia.c8
-rw-r--r--drivers/i2c/busses/i2c-bcm-iproc.c10
-rw-r--r--drivers/i2c/busses/i2c-bcm-kona.c7
-rw-r--r--drivers/i2c/busses/i2c-brcmstb.c20
-rw-r--r--drivers/i2c/busses/i2c-cadence.c323
-rw-r--r--drivers/i2c/busses/i2c-cht-wc.c6
-rw-r--r--drivers/i2c/busses/i2c-davinci.c4
-rw-r--r--drivers/i2c/busses/i2c-designware-common.c327
-rw-r--r--drivers/i2c/busses/i2c-designware-core.h75
-rw-r--r--drivers/i2c/busses/i2c-designware-master.c192
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c86
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c276
-rw-r--r--drivers/i2c/busses/i2c-designware-slave.c88
-rw-r--r--drivers/i2c/busses/i2c-digicolor.c4
-rw-r--r--drivers/i2c/busses/i2c-efm32.c4
-rw-r--r--drivers/i2c/busses/i2c-emev2.c4
-rw-r--r--drivers/i2c/busses/i2c-exynos5.c8
-rw-r--r--drivers/i2c/busses/i2c-hix5hd2.c4
-rw-r--r--drivers/i2c/busses/i2c-i801.c6
-rw-r--r--drivers/i2c/busses/i2c-icy.c1
-rw-r--r--drivers/i2c/busses/i2c-img-scb.c8
-rw-r--r--drivers/i2c/busses/i2c-imx-lpi2c.c4
-rw-r--r--drivers/i2c/busses/i2c-jz4780.c4
-rw-r--r--drivers/i2c/busses/i2c-lpc2k.c8
-rw-r--r--drivers/i2c/busses/i2c-meson.c8
-rw-r--r--drivers/i2c/busses/i2c-mt65xx.c329
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c4
-rw-r--r--drivers/i2c/busses/i2c-npcm7xx.c2342
-rw-r--r--drivers/i2c/busses/i2c-nvidia-gpu.c5
-rw-r--r--drivers/i2c/busses/i2c-octeon-platdrv.c4
-rw-r--r--drivers/i2c/busses/i2c-omap.c4
-rw-r--r--drivers/i2c/busses/i2c-owl.c8
-rw-r--r--drivers/i2c/busses/i2c-pca-platform.c3
-rw-r--r--drivers/i2c/busses/i2c-piix4.c3
-rw-r--r--drivers/i2c/busses/i2c-pnx.c1
-rw-r--r--drivers/i2c/busses/i2c-powermac.c18
-rw-r--r--drivers/i2c/busses/i2c-pxa.c802
-rw-r--r--drivers/i2c/busses/i2c-qcom-cci.c791
-rw-r--r--drivers/i2c/busses/i2c-qup.c18
-rw-r--r--drivers/i2c/busses/i2c-rcar.c4
-rw-r--r--drivers/i2c/busses/i2c-rk3x.c8
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c5
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c7
-rw-r--r--drivers/i2c/busses/i2c-sirf.c4
-rw-r--r--drivers/i2c/busses/i2c-sprd.c4
-rw-r--r--drivers/i2c/busses/i2c-stm32.c10
-rw-r--r--drivers/i2c/busses/i2c-stm32f4.c4
-rw-r--r--drivers/i2c/busses/i2c-stm32f7.c138
-rw-r--r--drivers/i2c/busses/i2c-stu300.c4
-rw-r--r--drivers/i2c/busses/i2c-sun6i-p2wi.c8
-rw-r--r--drivers/i2c/busses/i2c-synquacer.c8
-rw-r--r--drivers/i2c/busses/i2c-tegra.c248
-rw-r--r--drivers/i2c/busses/i2c-uniphier-f.c4
-rw-r--r--drivers/i2c/busses/i2c-uniphier.c4
-rw-r--r--drivers/i2c/busses/i2c-xlp9xx.c8
-rw-r--r--drivers/i2c/busses/i2c-xlr.c4
-rw-r--r--drivers/i2c/busses/i2c-zx2967.c4
-rw-r--r--drivers/i2c/i2c-core-acpi.c6
-rw-r--r--drivers/i2c/i2c-core-base.c72
-rw-r--r--drivers/i2c/i2c-core.h6
-rw-r--r--drivers/i2c/i2c-slave-eeprom.c39
-rw-r--r--drivers/i2c/i2c-smbus.c104
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c44
-rw-r--r--drivers/ide/Kconfig10
-rw-r--r--drivers/iio/dac/Kconfig2
-rw-r--r--drivers/infiniband/Kconfig14
-rw-r--r--drivers/infiniband/core/umem_odp.c4
-rw-r--r--drivers/infiniband/core/uverbs_main.c6
-rw-r--r--drivers/infiniband/hw/bnxt_re/Kconfig2
-rw-r--r--drivers/infiniband/hw/cxgb4/Kconfig2
-rw-r--r--drivers/infiniband/hw/hfi1/Kconfig6
-rw-r--r--drivers/infiniband/hw/hfi1/mmu_rb.c2
-rw-r--r--drivers/infiniband/hw/hns/Kconfig6
-rw-r--r--drivers/infiniband/hw/i40iw/Kconfig2
-rw-r--r--drivers/infiniband/hw/mlx4/Kconfig2
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c4
-rw-r--r--drivers/infiniband/hw/mlx5/Kconfig2
-rw-r--r--drivers/infiniband/hw/mthca/Kconfig4
-rw-r--r--drivers/infiniband/hw/ocrdma/Kconfig2
-rw-r--r--drivers/infiniband/hw/qedr/Kconfig2
-rw-r--r--drivers/infiniband/hw/qib/Kconfig4
-rw-r--r--drivers/infiniband/hw/qib/qib_file_ops.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_user_pages.c6
-rw-r--r--drivers/infiniband/hw/usnic/Kconfig2
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom.c4
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/Kconfig2
-rw-r--r--drivers/infiniband/sw/rdmavt/Kconfig2
-rw-r--r--drivers/infiniband/sw/rdmavt/mmap.c1
-rw-r--r--drivers/infiniband/sw/rxe/Kconfig2
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mmap.c1
-rw-r--r--drivers/infiniband/sw/siw/siw_mem.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/Kconfig8
-rw-r--r--drivers/infiniband/ulp/iser/Kconfig2
-rw-r--r--drivers/infiniband/ulp/isert/Kconfig2
-rw-r--r--drivers/infiniband/ulp/opa_vnic/Kconfig2
-rw-r--r--drivers/infiniband/ulp/srp/Kconfig2
-rw-r--r--drivers/infiniband/ulp/srpt/Kconfig2
-rw-r--r--drivers/input/evdev.c7
-rw-r--r--drivers/input/gameport/Kconfig2
-rw-r--r--drivers/input/joystick/Kconfig9
-rw-r--r--drivers/input/keyboard/Kconfig2
-rw-r--r--drivers/input/keyboard/atkbd.c97
-rw-r--r--drivers/input/keyboard/imx_sc_key.c33
-rw-r--r--drivers/input/keyboard/tca6416-keypad.c2
-rw-r--r--drivers/input/misc/Kconfig32
-rw-r--r--drivers/input/misc/Makefile3
-rw-r--r--drivers/input/misc/gp2ap002a00f.c281
-rw-r--r--drivers/input/misc/iqs269a.c1833
-rw-r--r--drivers/input/misc/msm-vibrator.c281
-rw-r--r--drivers/input/misc/xen-kbdfront.c2
-rw-r--r--drivers/input/mouse/elan_i2c_core.c2
-rw-r--r--drivers/input/serio/Kconfig2
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h1
-rw-r--r--drivers/input/serio/i8042.c3
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c7
-rw-r--r--drivers/input/touchscreen/cy8ctma140.c353
-rw-r--r--drivers/input/touchscreen/cyttsp4_core.c5
-rw-r--r--drivers/input/touchscreen/cyttsp_core.c2
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c198
-rw-r--r--drivers/input/touchscreen/elants_i2c.c247
-rw-r--r--drivers/input/touchscreen/melfas_mip4.c4
-rw-r--r--drivers/input/touchscreen/mms114.c19
-rw-r--r--drivers/input/touchscreen/raspberrypi-ts.c2
-rw-r--r--drivers/input/touchscreen/stmfts.c2
-rw-r--r--drivers/interconnect/core.c18
-rw-r--r--drivers/iommu/Kconfig27
-rw-r--r--drivers/iommu/Makefile19
-rw-r--r--drivers/iommu/amd/amd_iommu.h (renamed from drivers/iommu/amd_iommu_proto.h)20
-rw-r--r--drivers/iommu/amd/amd_iommu_types.h (renamed from drivers/iommu/amd_iommu_types.h)9
-rw-r--r--drivers/iommu/amd/debugfs.c (renamed from drivers/iommu/amd_iommu_debugfs.c)5
-rw-r--r--drivers/iommu/amd/init.c (renamed from drivers/iommu/amd_iommu_init.c)6
-rw-r--r--drivers/iommu/amd/iommu.c (renamed from drivers/iommu/amd_iommu.c)371
-rw-r--r--drivers/iommu/amd/iommu_v2.c (renamed from drivers/iommu/amd_iommu_v2.c)18
-rw-r--r--drivers/iommu/amd/quirks.c (renamed from drivers/iommu/amd_iommu_quirks.c)0
-rw-r--r--drivers/iommu/amd_iommu.h14
-rw-r--r--drivers/iommu/arm-smmu-impl.c8
-rw-r--r--drivers/iommu/arm-smmu-qcom.c37
-rw-r--r--drivers/iommu/arm-smmu-v3.c122
-rw-r--r--drivers/iommu/arm-smmu.c53
-rw-r--r--drivers/iommu/arm-smmu.h1
-rw-r--r--drivers/iommu/exynos-iommu.c24
-rw-r--r--drivers/iommu/fsl_pamu_domain.c22
-rw-r--r--drivers/iommu/hyperv-iommu.c2
-rw-r--r--drivers/iommu/intel/debugfs.c (renamed from drivers/iommu/intel-iommu-debugfs.c)62
-rw-r--r--drivers/iommu/intel/dmar.c (renamed from drivers/iommu/dmar.c)101
-rw-r--r--drivers/iommu/intel/intel-pasid.h (renamed from drivers/iommu/intel-pasid.h)27
-rw-r--r--drivers/iommu/intel/iommu.c (renamed from drivers/iommu/intel-iommu.c)954
-rw-r--r--drivers/iommu/intel/irq_remapping.c (renamed from drivers/iommu/intel_irq_remapping.c)4
-rw-r--r--drivers/iommu/intel/pasid.c (renamed from drivers/iommu/intel-pasid.c)309
-rw-r--r--drivers/iommu/intel/svm.c (renamed from drivers/iommu/intel-svm.c)452
-rw-r--r--drivers/iommu/intel/trace.c (renamed from drivers/iommu/intel-trace.c)0
-rw-r--r--drivers/iommu/iommu.c470
-rw-r--r--drivers/iommu/iova.c6
-rw-r--r--drivers/iommu/ipmmu-vmsa.c59
-rw-r--r--drivers/iommu/msm_iommu.c36
-rw-r--r--drivers/iommu/mtk_iommu.c24
-rw-r--r--drivers/iommu/mtk_iommu_v1.c68
-rw-r--r--drivers/iommu/omap-iommu.c103
-rw-r--r--drivers/iommu/qcom_iommu.c24
-rw-r--r--drivers/iommu/rockchip-iommu.c26
-rw-r--r--drivers/iommu/s390-iommu.c30
-rw-r--r--drivers/iommu/sun50i-iommu.c1023
-rw-r--r--drivers/iommu/tegra-gart.c24
-rw-r--r--drivers/iommu/tegra-smmu.c31
-rw-r--r--drivers/iommu/virtio-iommu.c41
-rw-r--r--drivers/ipack/Kconfig2
-rw-r--r--drivers/irqchip/Kconfig13
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-riscv-intc.c138
-rw-r--r--drivers/irqchip/irq-sifive-plic.c46
-rw-r--r--drivers/isdn/Kconfig2
-rw-r--r--drivers/macintosh/Kconfig2
-rw-r--r--drivers/macintosh/macio-adb.c2
-rw-r--r--drivers/macintosh/mediabay.c2
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/mailbox/Kconfig18
-rw-r--r--drivers/mailbox/Makefile4
-rw-r--r--drivers/mailbox/imx-mailbox.c117
-rw-r--r--drivers/mailbox/pcc.c2
-rw-r--r--drivers/mailbox/qcom-apcs-ipc-mailbox.c61
-rw-r--r--drivers/mailbox/qcom-ipcc.c286
-rw-r--r--drivers/mailbox/sprd-mailbox.c361
-rw-r--r--drivers/mailbox/zynqmp-ipi-mailbox.c25
-rw-r--r--drivers/md/Kconfig82
-rw-r--r--drivers/md/persistent-data/Kconfig2
-rw-r--r--drivers/media/cec/Kconfig2
-rw-r--r--drivers/media/cec/platform/Kconfig2
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-contig.c20
-rw-r--r--drivers/media/pci/bt8xx/bt878.c2
-rw-r--r--drivers/media/pci/bt8xx/btcx-risc.c2
-rw-r--r--drivers/media/pci/bt8xx/bttv-risc.c2
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c1
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c6
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c1
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c2
-rw-r--r--drivers/media/v4l2-core/videobuf-core.c4
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-contig.c4
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-sg.c8
-rw-r--r--drivers/media/v4l2-core/videobuf-vmalloc.c2
-rw-r--r--drivers/message/fusion/Kconfig14
-rw-r--r--drivers/mfd/Kconfig10
-rw-r--r--drivers/misc/Kconfig18
-rw-r--r--drivers/misc/cxl/cxllib.c9
-rw-r--r--drivers/misc/cxl/fault.c4
-rw-r--r--drivers/misc/echo/Kconfig2
-rw-r--r--drivers/misc/genwqe/card_utils.c2
-rw-r--r--drivers/misc/mic/Kconfig2
-rw-r--r--drivers/misc/sgi-gru/grufault.c25
-rw-r--r--drivers/misc/sgi-gru/grufile.c4
-rw-r--r--drivers/misc/uacce/uacce.c172
-rw-r--r--drivers/mmc/host/Kconfig4
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c13
-rw-r--r--drivers/mtd/devices/docg3.c10
-rw-r--r--drivers/mtd/maps/physmap-gemini.c5
-rw-r--r--drivers/mtd/mtdblock.c11
-rw-r--r--drivers/mtd/mtdcore.c191
-rw-r--r--drivers/mtd/mtdpart.c54
-rw-r--r--drivers/mtd/nand/raw/Kconfig12
-rw-r--r--drivers/mtd/nand/raw/Makefile2
-rw-r--r--drivers/mtd/nand/raw/ams-delta.c5
-rw-r--r--drivers/mtd/nand/raw/arasan-nand-controller.c1297
-rw-r--r--drivers/mtd/nand/raw/atmel/nand-controller.c2
-rw-r--r--drivers/mtd/nand/raw/au1550nd.c403
-rw-r--r--drivers/mtd/nand/raw/bcm47xxnflash/main.c6
-rw-r--r--drivers/mtd/nand/raw/brcmnand/brcmnand.c164
-rw-r--r--drivers/mtd/nand/raw/cadence-nand-controller.c17
-rw-r--r--drivers/mtd/nand/raw/cafe_nand.c16
-rw-r--r--drivers/mtd/nand/raw/cmx270_nand.c236
-rw-r--r--drivers/mtd/nand/raw/cs553x_nand.c199
-rw-r--r--drivers/mtd/nand/raw/davinci_nand.c312
-rw-r--r--drivers/mtd/nand/raw/denali.c60
-rw-r--r--drivers/mtd/nand/raw/diskonchip.c487
-rw-r--r--drivers/mtd/nand/raw/fsl_elbc_nand.c7
-rw-r--r--drivers/mtd/nand/raw/fsl_ifc_nand.c7
-rw-r--r--drivers/mtd/nand/raw/fsl_upm.c9
-rw-r--r--drivers/mtd/nand/raw/fsmc_nand.c19
-rw-r--r--drivers/mtd/nand/raw/gpio.c6
-rw-r--r--drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c189
-rw-r--r--drivers/mtd/nand/raw/hisi504_nand.c6
-rw-r--r--drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c170
-rw-r--r--drivers/mtd/nand/raw/internals.h12
-rw-r--r--drivers/mtd/nand/raw/lpc32xx_mlc.c7
-rw-r--r--drivers/mtd/nand/raw/lpc32xx_slc.c6
-rw-r--r--drivers/mtd/nand/raw/marvell_nand.c68
-rw-r--r--drivers/mtd/nand/raw/meson_nand.c5
-rw-r--r--drivers/mtd/nand/raw/mpc5121_nfc.c5
-rw-r--r--drivers/mtd/nand/raw/mtk_nand.c19
-rw-r--r--drivers/mtd/nand/raw/mxc_nand.c6
-rw-r--r--drivers/mtd/nand/raw/mxic_nand.c10
-rw-r--r--drivers/mtd/nand/raw/nand_base.c445
-rw-r--r--drivers/mtd/nand/raw/nand_bch.c10
-rw-r--r--drivers/mtd/nand/raw/nand_jedec.c32
-rw-r--r--drivers/mtd/nand/raw/nand_legacy.c8
-rw-r--r--drivers/mtd/nand/raw/nand_micron.c65
-rw-r--r--drivers/mtd/nand/raw/nand_onfi.c71
-rw-r--r--drivers/mtd/nand/raw/nand_timings.c11
-rw-r--r--drivers/mtd/nand/raw/nand_toshiba.c14
-rw-r--r--drivers/mtd/nand/raw/nandsim.c438
-rw-r--r--drivers/mtd/nand/raw/ndfc.c8
-rw-r--r--drivers/mtd/nand/raw/omap2.c8
-rw-r--r--drivers/mtd/nand/raw/omap_elm.c1
-rw-r--r--drivers/mtd/nand/raw/orion_nand.c8
-rw-r--r--drivers/mtd/nand/raw/oxnas_nand.c33
-rw-r--r--drivers/mtd/nand/raw/pasemi_nand.c9
-rw-r--r--drivers/mtd/nand/raw/plat_nand.c8
-rw-r--r--drivers/mtd/nand/raw/qcom_nandc.c13
-rw-r--r--drivers/mtd/nand/raw/r852.c6
-rw-r--r--drivers/mtd/nand/raw/s3c2410.c3
-rw-r--r--drivers/mtd/nand/raw/sh_flctl.c6
-rw-r--r--drivers/mtd/nand/raw/sharpsl.c14
-rw-r--r--drivers/mtd/nand/raw/socrates_nand.c8
-rw-r--r--drivers/mtd/nand/raw/stm32_fmc2_nand.c1067
-rw-r--r--drivers/mtd/nand/raw/sunxi_nand.c16
-rw-r--r--drivers/mtd/nand/raw/tango_nand.c13
-rw-r--r--drivers/mtd/nand/raw/tegra_nand.c6
-rw-r--r--drivers/mtd/nand/raw/tmio_nand.c8
-rw-r--r--drivers/mtd/nand/raw/txx9ndfmc.c6
-rw-r--r--drivers/mtd/nand/raw/vf610_nfc.c10
-rw-r--r--drivers/mtd/nand/raw/xway_nand.c8
-rw-r--r--drivers/mtd/parsers/cmdlinepart.c35
-rw-r--r--drivers/mtd/parsers/ofpart.c3
-rw-r--r--drivers/mtd/spi-nor/Kconfig4
-rw-r--r--drivers/mtd/spi-nor/controllers/Kconfig4
-rw-r--r--drivers/mtd/spi-nor/controllers/aspeed-smc.c2
-rw-r--r--drivers/mtd/spi-nor/controllers/hisi-sfc.c2
-rw-r--r--drivers/mtd/spi-nor/controllers/nxp-spifi.c2
-rw-r--r--drivers/mtd/spi-nor/core.c22
-rw-r--r--drivers/mtd/spi-nor/macronix.c6
-rw-r--r--drivers/mtd/spi-nor/micron-st.c6
-rw-r--r--drivers/mtd/spi-nor/sfdp.c34
-rw-r--r--drivers/mtd/spi-nor/sfdp.h11
-rw-r--r--drivers/mtd/spi-nor/spansion.c44
-rw-r--r--drivers/mtd/spi-nor/winbond.c29
-rw-r--r--drivers/mtd/ubi/build.c5
-rw-r--r--drivers/mtd/ubi/fastmap-wl.c39
-rw-r--r--drivers/mtd/ubi/fastmap.c11
-rw-r--r--drivers/mtd/ubi/ubi.h6
-rw-r--r--drivers/mtd/ubi/wl.c28
-rw-r--r--drivers/net/Kconfig46
-rw-r--r--drivers/net/appletalk/Kconfig4
-rw-r--r--drivers/net/arcnet/Kconfig8
-rw-r--r--drivers/net/caif/Kconfig12
-rw-r--r--drivers/net/can/Kconfig30
-rw-r--r--drivers/net/can/c_can/Kconfig4
-rw-r--r--drivers/net/can/cc770/Kconfig4
-rw-r--r--drivers/net/can/ifi_canfd/Kconfig2
-rw-r--r--drivers/net/can/m_can/Kconfig6
-rw-r--r--drivers/net/can/mscan/Kconfig4
-rw-r--r--drivers/net/can/peak_canfd/Kconfig2
-rw-r--r--drivers/net/can/rcar/Kconfig4
-rw-r--r--drivers/net/can/sja1000/Kconfig18
-rw-r--r--drivers/net/can/softing/Kconfig4
-rw-r--r--drivers/net/can/spi/Kconfig4
-rw-r--r--drivers/net/can/usb/Kconfig16
-rw-r--r--drivers/net/dsa/Kconfig26
-rw-r--r--drivers/net/dsa/qca/Kconfig2
-rw-r--r--drivers/net/ethernet/3com/Kconfig14
-rw-r--r--drivers/net/ethernet/8390/Kconfig32
-rw-r--r--drivers/net/ethernet/Kconfig18
-rw-r--r--drivers/net/ethernet/adaptec/Kconfig4
-rw-r--r--drivers/net/ethernet/aeroflex/Kconfig2
-rw-r--r--drivers/net/ethernet/agere/Kconfig4
-rw-r--r--drivers/net/ethernet/alacritech/Kconfig4
-rw-r--r--drivers/net/ethernet/allwinner/Kconfig4
-rw-r--r--drivers/net/ethernet/alteon/Kconfig6
-rw-r--r--drivers/net/ethernet/altera/Kconfig2
-rw-r--r--drivers/net/ethernet/amazon/Kconfig4
-rw-r--r--drivers/net/ethernet/amd/7990.c2
-rw-r--r--drivers/net/ethernet/amd/Kconfig34
-rw-r--r--drivers/net/ethernet/amd/hplance.c2
-rw-r--r--drivers/net/ethernet/amd/mvme147.c2
-rw-r--r--drivers/net/ethernet/amd/sun3lance.c2
-rw-r--r--drivers/net/ethernet/amd/sunlance.c2
-rw-r--r--drivers/net/ethernet/apple/Kconfig10
-rw-r--r--drivers/net/ethernet/apple/bmac.c2
-rw-r--r--drivers/net/ethernet/apple/mace.c2
-rw-r--r--drivers/net/ethernet/aquantia/Kconfig4
-rw-r--r--drivers/net/ethernet/arc/Kconfig6
-rw-r--r--drivers/net/ethernet/atheros/Kconfig10
-rw-r--r--drivers/net/ethernet/broadcom/Kconfig32
-rw-r--r--drivers/net/ethernet/brocade/Kconfig2
-rw-r--r--drivers/net/ethernet/brocade/bna/Kconfig2
-rw-r--r--drivers/net/ethernet/cadence/Kconfig8
-rw-r--r--drivers/net/ethernet/cavium/Kconfig16
-rw-r--r--drivers/net/ethernet/chelsio/Kconfig18
-rw-r--r--drivers/net/ethernet/cirrus/Kconfig6
-rw-r--r--drivers/net/ethernet/cisco/Kconfig2
-rw-r--r--drivers/net/ethernet/cisco/enic/Kconfig2
-rw-r--r--drivers/net/ethernet/cortina/Kconfig4
-rw-r--r--drivers/net/ethernet/davicom/Kconfig4
-rw-r--r--drivers/net/ethernet/dec/Kconfig2
-rw-r--r--drivers/net/ethernet/dec/tulip/Kconfig26
-rw-r--r--drivers/net/ethernet/dlink/Kconfig8
-rw-r--r--drivers/net/ethernet/emulex/Kconfig2
-rw-r--r--drivers/net/ethernet/ezchip/Kconfig4
-rw-r--r--drivers/net/ethernet/faraday/Kconfig6
-rw-r--r--drivers/net/ethernet/freescale/Kconfig16
-rw-r--r--drivers/net/ethernet/freescale/dpaa/Kconfig2
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c2
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-fcc.c2
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mii-fec.c2
-rw-r--r--drivers/net/ethernet/fujitsu/Kconfig4
-rw-r--r--drivers/net/ethernet/hisilicon/Kconfig22
-rw-r--r--drivers/net/ethernet/huawei/Kconfig2
-rw-r--r--drivers/net/ethernet/huawei/hinic/Kconfig2
-rw-r--r--drivers/net/ethernet/i825xx/82596.c2
-rw-r--r--drivers/net/ethernet/i825xx/Kconfig14
-rw-r--r--drivers/net/ethernet/ibm/Kconfig8
-rw-r--r--drivers/net/ethernet/intel/Kconfig46
-rw-r--r--drivers/net/ethernet/korina.c2
-rw-r--r--drivers/net/ethernet/marvell/Kconfig24
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/Kconfig2
-rw-r--r--drivers/net/ethernet/marvell/pxa168_eth.c2
-rw-r--r--drivers/net/ethernet/mediatek/Kconfig4
-rw-r--r--drivers/net/ethernet/mellanox/Kconfig2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/Kconfig8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Kconfig18
-rw-r--r--drivers/net/ethernet/mellanox/mlxfw/Kconfig2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/Kconfig20
-rw-r--r--drivers/net/ethernet/micrel/Kconfig10
-rw-r--r--drivers/net/ethernet/microchip/Kconfig10
-rw-r--r--drivers/net/ethernet/moxa/Kconfig4
-rw-r--r--drivers/net/ethernet/myricom/Kconfig6
-rw-r--r--drivers/net/ethernet/natsemi/Kconfig12
-rw-r--r--drivers/net/ethernet/natsemi/jazzsonic.c2
-rw-r--r--drivers/net/ethernet/natsemi/macsonic.c2
-rw-r--r--drivers/net/ethernet/natsemi/xtsonic.c2
-rw-r--r--drivers/net/ethernet/neterion/Kconfig8
-rw-r--r--drivers/net/ethernet/netronome/Kconfig8
-rw-r--r--drivers/net/ethernet/nvidia/Kconfig4
-rw-r--r--drivers/net/ethernet/oki-semi/Kconfig2
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/Kconfig2
-rw-r--r--drivers/net/ethernet/packetengines/Kconfig6
-rw-r--r--drivers/net/ethernet/pasemi/Kconfig4
-rw-r--r--drivers/net/ethernet/qlogic/Kconfig20
-rw-r--r--drivers/net/ethernet/qualcomm/Kconfig8
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/Kconfig2
-rw-r--r--drivers/net/ethernet/rdc/Kconfig4
-rw-r--r--drivers/net/ethernet/realtek/Kconfig18
-rw-r--r--drivers/net/ethernet/renesas/Kconfig4
-rw-r--r--drivers/net/ethernet/rocker/Kconfig4
-rw-r--r--drivers/net/ethernet/samsung/Kconfig4
-rw-r--r--drivers/net/ethernet/seeq/Kconfig6
-rw-r--r--drivers/net/ethernet/sfc/Kconfig12
-rw-r--r--drivers/net/ethernet/sfc/falcon/Kconfig4
-rw-r--r--drivers/net/ethernet/sgi/Kconfig4
-rw-r--r--drivers/net/ethernet/silan/Kconfig4
-rw-r--r--drivers/net/ethernet/sis/Kconfig6
-rw-r--r--drivers/net/ethernet/smsc/Kconfig18
-rw-r--r--drivers/net/ethernet/socionext/Kconfig6
-rw-r--r--drivers/net/ethernet/stmicro/Kconfig2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Kconfig24
-rw-r--r--drivers/net/ethernet/sun/Kconfig18
-rw-r--r--drivers/net/ethernet/sun/sunbmac.c2
-rw-r--r--drivers/net/ethernet/sun/sunhme.c1
-rw-r--r--drivers/net/ethernet/sun/sunqe.c2
-rw-r--r--drivers/net/ethernet/synopsys/Kconfig6
-rw-r--r--drivers/net/ethernet/tehuti/Kconfig4
-rw-r--r--drivers/net/ethernet/ti/Kconfig20
-rw-r--r--drivers/net/ethernet/toshiba/Kconfig8
-rw-r--r--drivers/net/ethernet/tundra/Kconfig4
-rw-r--r--drivers/net/ethernet/via/Kconfig8
-rw-r--r--drivers/net/ethernet/wiznet/Kconfig14
-rw-r--r--drivers/net/ethernet/xilinx/Kconfig8
-rw-r--r--drivers/net/ethernet/xircom/Kconfig4
-rw-r--r--drivers/net/ethernet/xscale/Kconfig4
-rw-r--r--drivers/net/fddi/Kconfig8
-rw-r--r--drivers/net/hamradio/Kconfig16
-rw-r--r--drivers/net/hippi/Kconfig6
-rw-r--r--drivers/net/ieee802154/Kconfig24
-rw-r--r--drivers/net/phy/Kconfig78
-rw-r--r--drivers/net/plip/Kconfig2
-rw-r--r--drivers/net/ppp/Kconfig24
-rw-r--r--drivers/net/slip/Kconfig10
-rw-r--r--drivers/net/team/Kconfig12
-rw-r--r--drivers/net/usb/Kconfig12
-rw-r--r--drivers/net/wan/Kconfig16
-rw-r--r--drivers/net/wireless/Kconfig10
-rw-r--r--drivers/net/wireless/admtek/Kconfig4
-rw-r--r--drivers/net/wireless/ath/Kconfig10
-rw-r--r--drivers/net/wireless/ath/ar5523/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath10k/Kconfig22
-rw-r--r--drivers/net/wireless/ath/ath11k/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig12
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig12
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig30
-rw-r--r--drivers/net/wireless/ath/wcn36xx/Kconfig4
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig8
-rw-r--r--drivers/net/wireless/atmel/Kconfig10
-rw-r--r--drivers/net/wireless/broadcom/Kconfig2
-rw-r--r--drivers/net/wireless/broadcom/b43/Kconfig18
-rw-r--r--drivers/net/wireless/broadcom/b43legacy/Kconfig10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/Kconfig6
-rw-r--r--drivers/net/wireless/cisco/Kconfig6
-rw-r--r--drivers/net/wireless/intel/Kconfig2
-rw-r--r--drivers/net/wireless/intel/ipw2x00/Kconfig18
-rw-r--r--drivers/net/wireless/intel/iwlegacy/Kconfig8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/Kconfig6
-rw-r--r--drivers/net/wireless/intersil/Kconfig4
-rw-r--r--drivers/net/wireless/intersil/hostap/Kconfig12
-rw-r--r--drivers/net/wireless/intersil/orinoco/Kconfig12
-rw-r--r--drivers/net/wireless/intersil/p54/Kconfig10
-rw-r--r--drivers/net/wireless/marvell/Kconfig4
-rw-r--r--drivers/net/wireless/marvell/libertas/Kconfig12
-rw-r--r--drivers/net/wireless/marvell/libertas_tf/Kconfig6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/Kconfig8
-rw-r--r--drivers/net/wireless/mediatek/Kconfig2
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/Kconfig2
-rw-r--r--drivers/net/wireless/ralink/Kconfig2
-rw-r--r--drivers/net/wireless/ralink/rt2x00/Kconfig42
-rw-r--r--drivers/net/wireless/realtek/Kconfig2
-rw-r--r--drivers/net/wireless/realtek/rtl818x/Kconfig4
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/Kconfig4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/Kconfig22
-rw-r--r--drivers/net/wireless/rsi/Kconfig12
-rw-r--r--drivers/net/wireless/st/Kconfig2
-rw-r--r--drivers/net/wireless/ti/Kconfig4
-rw-r--r--drivers/net/wireless/ti/wl1251/Kconfig6
-rw-r--r--drivers/net/wireless/ti/wl12xx/Kconfig2
-rw-r--r--drivers/net/wireless/ti/wl18xx/Kconfig2
-rw-r--r--drivers/net/wireless/ti/wlcore/Kconfig6
-rw-r--r--drivers/net/wireless/zydas/Kconfig4
-rw-r--r--drivers/net/wireless/zydas/zd1211rw/Kconfig4
-rw-r--r--drivers/nfc/fdp/Kconfig4
-rw-r--r--drivers/nfc/microread/Kconfig6
-rw-r--r--drivers/nfc/nxp-nci/Kconfig4
-rw-r--r--drivers/nfc/pn533/Kconfig6
-rw-r--r--drivers/nfc/pn544/Kconfig6
-rw-r--r--drivers/nfc/s3fwrn5/Kconfig4
-rw-r--r--drivers/nfc/st-nci/Kconfig6
-rw-r--r--drivers/nfc/st21nfca/Kconfig4
-rw-r--r--drivers/nvdimm/blk.c5
-rw-r--r--drivers/nvdimm/btt.c3
-rw-r--r--drivers/nvdimm/pmem.c9
-rw-r--r--drivers/nvme/host/Kconfig4
-rw-r--r--drivers/nvme/host/core.c4
-rw-r--r--drivers/nvme/host/fc.c5
-rw-r--r--drivers/nvme/host/nvme.h3
-rw-r--r--drivers/nvme/host/pci.c6
-rw-r--r--drivers/nvme/host/tcp.c8
-rw-r--r--drivers/nvme/target/core.c27
-rw-r--r--drivers/nvme/target/tcp.c4
-rw-r--r--drivers/opp/Kconfig2
-rw-r--r--drivers/opp/core.c119
-rw-r--r--drivers/opp/debugfs.c42
-rw-r--r--drivers/opp/of.c205
-rw-r--r--drivers/opp/opp.h10
-rw-r--r--drivers/oprofile/buffer_sync.c12
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/pci/ats.c18
-rw-r--r--drivers/pci/controller/Kconfig2
-rw-r--r--drivers/pci/hotplug/Kconfig2
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c16
-rw-r--r--drivers/pci/iov.c39
-rw-r--r--drivers/pci/xen-pcifront.c27
-rw-r--r--drivers/pcmcia/Kconfig8
-rw-r--r--drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c2
-rw-r--r--drivers/platform/chrome/Kconfig8
-rw-r--r--drivers/platform/mellanox/Kconfig4
-rw-r--r--drivers/platform/mellanox/mlxreg-hotplug.c11
-rw-r--r--drivers/platform/olpc/olpc-xo175-ec.c4
-rw-r--r--drivers/platform/x86/Kconfig142
-rw-r--r--drivers/pnp/Kconfig2
-rw-r--r--drivers/pnp/pnpbios/Kconfig4
-rw-r--r--drivers/power/reset/Kconfig7
-rw-r--r--drivers/power/reset/Makefile1
-rw-r--r--drivers/power/reset/gpio-poweroff.c2
-rw-r--r--drivers/power/reset/ltc2952-poweroff.c3
-rw-r--r--drivers/power/reset/oxnas-restart.c233
-rw-r--r--drivers/power/reset/qcom-pon.c3
-rw-r--r--drivers/power/reset/syscon-reboot.c7
-rw-r--r--drivers/power/supply/88pm860x_battery.c8
-rw-r--r--drivers/power/supply/Kconfig49
-rw-r--r--drivers/power/supply/Makefile2
-rw-r--r--drivers/power/supply/ab8500_fg.c2
-rw-r--r--drivers/power/supply/axp288_charger.c5
-rw-r--r--drivers/power/supply/axp288_fuel_gauge.c6
-rw-r--r--drivers/power/supply/bd70528-charger.c144
-rw-r--r--drivers/power/supply/bd99954-charger.c1142
-rw-r--r--drivers/power/supply/bd99954-charger.h1075
-rw-r--r--drivers/power/supply/bq24190_charger.c2
-rw-r--r--drivers/power/supply/bq25890_charger.c200
-rw-r--r--drivers/power/supply/charger-manager.c40
-rw-r--r--drivers/power/supply/cw2015_battery.c750
-rw-r--r--drivers/power/supply/generic-adc-battery.c22
-rw-r--r--drivers/power/supply/lp8788-charger.c18
-rw-r--r--drivers/power/supply/max14577_charger.c10
-rw-r--r--drivers/power/supply/max14656_charger_detector.c5
-rw-r--r--drivers/power/supply/max17040_battery.c2
-rw-r--r--drivers/power/supply/max17042_battery.c8
-rw-r--r--drivers/power/supply/olpc_battery.c4
-rw-r--r--drivers/power/supply/power_supply_core.c8
-rw-r--r--drivers/power/supply/power_supply_hwmon.c64
-rw-r--r--drivers/power/supply/power_supply_sysfs.c484
-rw-r--r--drivers/power/supply/sbs-battery.c232
-rw-r--r--drivers/power/supply/sc27xx_fuel_gauge.c77
-rw-r--r--drivers/power/supply/smb347-charger.c5
-rw-r--r--drivers/powercap/Kconfig2
-rw-r--r--drivers/powercap/idle_inject.c16
-rw-r--r--drivers/pps/Kconfig2
-rw-r--r--drivers/ptp/Kconfig2
-rw-r--r--drivers/pwm/Kconfig12
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/core.c4
-rw-r--r--drivers/pwm/pwm-img.c8
-rw-r--r--drivers/pwm/pwm-imx27.c20
-rw-r--r--drivers/pwm/pwm-iqs620a.c270
-rw-r--r--drivers/pwm/pwm-jz4740.c55
-rw-r--r--drivers/pwm/pwm-lpss.c15
-rw-r--r--drivers/pwm/pwm-rockchip.c7
-rw-r--r--drivers/pwm/pwm-sun4i.c9
-rw-r--r--drivers/pwm/pwm-tegra.c80
-rw-r--r--drivers/rapidio/Kconfig4
-rw-r--r--drivers/rapidio/devices/Kconfig2
-rw-r--r--drivers/rapidio/switches/Kconfig10
-rw-r--r--drivers/ras/cec.c33
-rw-r--r--drivers/remoteproc/Kconfig9
-rw-r--r--drivers/remoteproc/Makefile1
-rw-r--r--drivers/remoteproc/ingenic_rproc.c280
-rw-r--r--drivers/remoteproc/mtk_scp.c4
-rw-r--r--drivers/remoteproc/qcom_common.c17
-rw-r--r--drivers/remoteproc/qcom_common.h5
-rw-r--r--drivers/remoteproc/qcom_q6v5_adsp.c3
-rw-r--r--drivers/remoteproc/qcom_q6v5_mss.c173
-rw-r--r--drivers/remoteproc/qcom_q6v5_pas.c68
-rw-r--r--drivers/remoteproc/qcom_q6v5_wcss.c6
-rw-r--r--drivers/remoteproc/qcom_sysmon.c116
-rw-r--r--drivers/remoteproc/qcom_wcnss.c1
-rw-r--r--drivers/remoteproc/remoteproc_core.c243
-rw-r--r--drivers/remoteproc/remoteproc_debugfs.c28
-rw-r--r--drivers/remoteproc/remoteproc_elf_loader.c24
-rw-r--r--drivers/remoteproc/remoteproc_internal.h17
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c15
-rw-r--r--drivers/remoteproc/st_remoteproc.c2
-rw-r--r--drivers/remoteproc/st_slim_rproc.c2
-rw-r--r--drivers/remoteproc/stm32_rproc.c3
-rw-r--r--drivers/rpmsg/Kconfig6
-rw-r--r--drivers/rpmsg/Makefile3
-rw-r--r--drivers/rpmsg/qcom_glink_ssr.c (renamed from drivers/soc/qcom/glink_ssr.c)28
-rw-r--r--drivers/rpmsg/rpmsg_core.c2
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c2
-rw-r--r--drivers/s390/cio/Makefile2
-rw-r--r--drivers/s390/cio/chsc.c40
-rw-r--r--drivers/s390/cio/chsc.h50
-rw-r--r--drivers/s390/cio/device_ops.c23
-rw-r--r--drivers/s390/cio/idset.c12
-rw-r--r--drivers/s390/cio/qdio.h16
-rw-r--r--drivers/s390/cio/qdio_main.c299
-rw-r--r--drivers/s390/cio/qdio_setup.c100
-rw-r--r--drivers/s390/cio/qdio_thinint.c61
-rw-r--r--drivers/s390/cio/vfio_ccw_chp.c148
-rw-r--r--drivers/s390/cio/vfio_ccw_cp.c19
-rw-r--r--drivers/s390/cio/vfio_ccw_drv.c165
-rw-r--r--drivers/s390/cio/vfio_ccw_ops.c65
-rw-r--r--drivers/s390/cio/vfio_ccw_private.h16
-rw-r--r--drivers/s390/cio/vfio_ccw_trace.c1
-rw-r--r--drivers/s390/cio/vfio_ccw_trace.h30
-rw-r--r--drivers/s390/crypto/ap_bus.c94
-rw-r--r--drivers/s390/crypto/ap_bus.h25
-rw-r--r--drivers/s390/crypto/ap_card.c47
-rw-r--r--drivers/s390/crypto/ap_queue.c10
-rw-r--r--drivers/s390/net/qeth_l2_main.c198
-rw-r--r--drivers/sbus/char/Kconfig2
-rw-r--r--drivers/sbus/char/flash.c1
-rw-r--r--drivers/sbus/char/uctrl.c1
-rw-r--r--drivers/scsi/53c700.c2
-rw-r--r--drivers/scsi/Kconfig80
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/a3000.c1
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic79xx4
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic7xxx6
-rw-r--r--drivers/scsi/arm/acornscsi.c4
-rw-r--r--drivers/scsi/arm/cumana_2.c2
-rw-r--r--drivers/scsi/arm/eesox.c2
-rw-r--r--drivers/scsi/arm/powertec.c2
-rw-r--r--drivers/scsi/bnx2fc/Kconfig2
-rw-r--r--drivers/scsi/bnx2i/Kconfig2
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/Kconfig2
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/Kconfig2
-rw-r--r--drivers/scsi/cxlflash/main.c3
-rw-r--r--drivers/scsi/dpt_i2o.c2
-rw-r--r--drivers/scsi/esas2r/Kconfig2
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/hpsa.c199
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c2
-rw-r--r--drivers/scsi/iscsi_boot_sysfs.c2
-rw-r--r--drivers/scsi/lasi700.c1
-rw-r--r--drivers/scsi/mac53c94.c2
-rw-r--r--drivers/scsi/mesh.c2
-rw-r--r--drivers/scsi/mpt3sas/Kconfig8
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c5
-rw-r--r--drivers/scsi/mvme147.c1
-rw-r--r--drivers/scsi/qedf/Kconfig2
-rw-r--r--drivers/scsi/qedf/qedf_fip.c2
-rw-r--r--drivers/scsi/qedi/Kconfig2
-rw-r--r--drivers/scsi/qla2xxx/Kconfig6
-rw-r--r--drivers/scsi/qla4xxx/Kconfig2
-rw-r--r--drivers/scsi/qlogicpti.c2
-rw-r--r--drivers/scsi/smartpqi/Kconfig2
-rw-r--r--drivers/scsi/sni_53c710.c1
-rw-r--r--drivers/scsi/sr.c7
-rw-r--r--drivers/scsi/st.c20
-rw-r--r--drivers/scsi/storvsc_drv.c3
-rw-r--r--drivers/scsi/ufs/Kconfig12
-rw-r--r--drivers/scsi/ufs/ufshcd.c6
-rw-r--r--drivers/scsi/zorro_esp.c2
-rw-r--r--drivers/sfi/Kconfig2
-rw-r--r--drivers/soc/aspeed/Kconfig2
-rw-r--r--drivers/soc/qcom/Kconfig9
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/android/ashmem.c4
-rw-r--r--drivers/staging/comedi/comedi_fops.c2
-rw-r--r--drivers/staging/greybus/Kconfig40
-rw-r--r--drivers/staging/kpc2000/kpc_dma/fileops.c4
-rw-r--r--drivers/staging/media/atomisp/Kconfig4
-rw-r--r--drivers/staging/media/atomisp/Makefile20
-rw-r--r--drivers/staging/media/atomisp/TODO154
-rw-r--r--drivers/staging/media/atomisp/i2c/Kconfig17
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc0310.c13
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc2235.c12
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c1
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-lm3554.c12
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c12
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2680.c14
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2722.c12
-rw-r--r--drivers/staging/media/atomisp/i2c/gc0310.h1
-rw-r--r--drivers/staging/media/atomisp/i2c/gc2235.h1
-rw-r--r--drivers/staging/media/atomisp/i2c/mt9m114.h1
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2680.h3
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2722.h1
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/Kconfig3
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/ad5823.h1
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c16
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/ov5693.h1
-rw-r--r--drivers/staging/media/atomisp/include/hmm/hmm.h8
-rw-r--r--drivers/staging/media/atomisp/include/hmm/hmm_bo.h12
-rw-r--r--drivers/staging/media/atomisp/include/hmm/hmm_common.h1
-rw-r--r--drivers/staging/media/atomisp/include/hmm/hmm_pool.h1
-rw-r--r--drivers/staging/media/atomisp/include/hmm/hmm_vm.h65
-rw-r--r--drivers/staging/media/atomisp/include/linux/atomisp.h10
-rw-r--r--drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h1
-rw-r--r--drivers/staging/media/atomisp/include/linux/atomisp_platform.h22
-rw-r--r--drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h1
-rw-r--r--drivers/staging/media/atomisp/include/media/lm3554.h1
-rw-r--r--drivers/staging/media/atomisp/include/mmu/isp_mmu.h1
-rw-r--r--drivers/staging/media/atomisp/include/mmu/sh_mmu_mrfld.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp-regs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_acc.c44
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_acc.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.c794
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.h23
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_common.h7
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat.h282
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_css20.c828
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_css20.h148
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c935
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_csi2.c5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_csi2.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_dfs_tables.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_drvfs.c6
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_drvfs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_file.c10
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_file.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_fops.c123
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_fops.h5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c147
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_helper.h28
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_internal.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_ioctl.c216
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_ioctl.h3
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_subdev.c55
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_subdev.h24
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_tables.h19
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_tpg.c3
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_tpg.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_trace_event.h7
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c173
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.h1
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h1
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h1
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h1
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c1
-rw-r--r--drivers/staging/media/atomisp/pci/base/refcount/interface/ia_css_refcount.h18
-rw-r--r--drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c36
-rw-r--r--drivers/staging/media/atomisp/pci/bits.h1
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h17
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h1
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h1
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c33
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c1
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c1
-rw-r--r--drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h22
-rw-r--r--drivers/staging/media/atomisp/pci/camera/util/src/util.c68
-rw-r--r--drivers/staging/media/atomisp/pci/cell_params.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c3
-rw-r--r--drivers/staging/media/atomisp/pci/css_2400_system/hrt/isp2400_mamoiada_params.h228
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/csi_rx_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c2
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c3
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h5
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio.c1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h5
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hrt/PixelGen_SysBlock_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hrt/ibuf_cntrl_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_common_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hrt/rx_csi_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hrt/stream2mmio_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/ibuf_ctrl_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/isys_dma_global.h2
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/isys_irq_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/isys_stream2mmio_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_receiver_2400_common_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_receiver_2400_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/css_trace.h2
-rw-r--r--drivers/staging/media/atomisp/pci/defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/dma_v2_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/gdc_v2_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/gp_timer_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/gpio_block_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_2401_irq_types_hrt.h68
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/debug_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/dma_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/event_fifo_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/fifo_monitor_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/gdc_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_device_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_timer_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/gpio_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/hmem_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c17
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_private.h11
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c11
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq.c32
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_local.h18
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp.c6
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vamem_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c6
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/input_formatter_global.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h13
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/isp_global.h15
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/mmu_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/sp_global.h13
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/vamem_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/vmem_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/assert_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/bitop_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/csi_rx.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/debug.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/dma.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/error_support.h39
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/event_fifo.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/fifo_monitor.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/gdc_device.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_device.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_timer.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/gpio.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/hmem.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/debug_public.h8
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/dma_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/event_fifo_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/fifo_monitor_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gdc_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_device_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_timer_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gpio_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/hmem_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/ibuf_ctrl_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/input_formatter_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/irq_public.h19
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isp_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_dma_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_irq_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/mmu_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/sp_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/timed_ctrl_public.h3
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vamem_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vmem_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/ibuf_ctrl.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/input_formatter.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/input_system.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/irq.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/isp.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_dma.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_irq.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_stream2mmio.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_access/memory_access.h174
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_realloc.h38
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/misc_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/mmu_device.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/pixelgen.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h4
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/print_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/queue.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/resource.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/sp.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/string_support.h165
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/system_types.h24
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/tag.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/timed_ctrl.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/vamem.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/vmem.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/queue_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/sw_event_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_shared/tag_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_streaming_to_mipi_types_hrt.h1
-rw-r--r--drivers/staging/media/atomisp/pci/hive_types.h4
-rw-r--r--drivers/staging/media/atomisp/pci/hmm/hmm.c40
-rw-r--r--drivers/staging/media/atomisp/pci/hmm/hmm_bo.c156
-rw-r--r--drivers/staging/media/atomisp/pci/hmm/hmm_dynamic_pool.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hmm/hmm_reserved_pool.c1
-rw-r--r--drivers/staging/media/atomisp/pci/hmm/hmm_vm.c212
-rw-r--r--drivers/staging/media/atomisp/pci/hrt/hive_isp_css_custom_host_hrt.h106
-rw-r--r--drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.c124
-rw-r--r--drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.h57
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_3a.h3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_acc_types.h7
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_buffer.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_control.h17
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_device_access.c3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_device_access.h3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_dvs.h5
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_env.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_err.h22
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_event_public.h19
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_firmware.h7
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_frac.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_frame_format.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_frame_public.h23
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_host_data.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_input_port.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_irq.h14
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_configs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_params.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_states.h3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_memory_access.c85
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_metadata.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_mipi.h7
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_mmu.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_mmu_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_morph.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_pipe.h22
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_pipe_public.h79
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_prbs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_properties.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_shading.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_stream.h3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_stream_format.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_stream_public.h71
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_timer.h5
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_tpg.h1
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_types.h8
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_version.h3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_version_data.h1
-rw-r--r--drivers/staging/media/atomisp/pci/if_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_formatter_subsystem_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_selector_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_switch_2400_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_ctrl_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/irq_controller_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/irq_types_hrt.h (renamed from drivers/staging/media/atomisp/pci/css_2400_system/hrt/hive_isp_css_irq_types_hrt.h)1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_param.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.c3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.c4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c14
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h5
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.c4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.c4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c5
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_param.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c16
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_param.h5
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_state.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common.host.h5
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common_types.h10
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c28
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c18
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_state.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/uds/uds_1.0/ia_css_uds_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c25
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h5
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.c4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.c3
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_local.h17
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_public.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_support.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_system_global.h32
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_system_local.h16
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_input_system_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_input_system_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_input_system_private.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_system_global.h32
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_system_local.h16
-rw-r--r--drivers/staging/media/atomisp/pci/isp_acquisition_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp_capture_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/mamoiada_params.h (renamed from drivers/staging/media/atomisp/pci/isp2401_mamoiada_params.h)21
-rw-r--r--drivers/staging/media/atomisp/pci/memory_realloc.c81
-rw-r--r--drivers/staging/media/atomisp/pci/mmu/isp_mmu.c1
-rw-r--r--drivers/staging/media/atomisp/pci/mmu/sh_mmu_mrfld.c4
-rw-r--r--drivers/staging/media/atomisp/pci/mmu_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h18
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c141
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h33
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq_comm.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/bufq/src/bufq.c92
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h10
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_internal.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c80
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/event/interface/ia_css_event.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/event/src/event.c4
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h9
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/eventq/src/eventq.c9
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h11
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame_comm.h5
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c154
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/ifmtr/interface/ia_css_ifmtr.h3
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c29
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/inputfifo/interface/ia_css_inputfifo.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/inputfifo/src/inputfifo.c3
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param.h7
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c32
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h13
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys_comm.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.c13
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.c1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.c1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/isys_init.c1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.c1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/rx.c21
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c30
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h32
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline_common.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c102
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue.h31
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue_comm.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c45
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.c28
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.h4
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h3
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h8
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr.c11
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c17
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl.h11
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl_comm.h1
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c42
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h5
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c7
-rw-r--r--drivers/staging/media/atomisp/pci/scalar_processor_2400_params.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css.c1854
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_defs.h6
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_dvs_info.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_firmware.c127
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_firmware.h10
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_frac.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_host_data.c5
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_hrt.c7
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_hrt.h3
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_internal.h99
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_legacy.h7
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_metadata.c1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_metrics.c10
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_metrics.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mipi.c73
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mipi.h9
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mmu.c2
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_morph.c1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_param_dvs.c46
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_param_dvs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_param_shading.c8
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_param_shading.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_params.c752
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_params.h17
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_params_internal.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_pipe.c16
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_properties.c1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_shading.c1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_sp.c142
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_sp.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_stream.c1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_stream_format.c1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_stream_format.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_struct.h6
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_uds.h1
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_version.c12
-rw-r--r--drivers/staging/media/atomisp/pci/str2mem_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/streaming_to_mipi_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/system_global.h1
-rw-r--r--drivers/staging/media/atomisp/pci/system_local.h1
-rw-r--r--drivers/staging/media/atomisp/pci/timed_controller_defs.h1
-rw-r--r--drivers/staging/media/atomisp/pci/version.h1
-rw-r--r--drivers/staging/media/rkvdec/rkvdec-h264.c70
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.c7
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_dec.c2
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_hw.c106
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_hw.h3
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_video.c36
-rw-r--r--drivers/staging/most/cdev/Kconfig2
-rw-r--r--drivers/staging/most/dim2/Kconfig2
-rw-r--r--drivers/target/iscsi/cxgbit/Kconfig2
-rw-r--r--drivers/target/iscsi/iscsi_target.c29
-rw-r--r--drivers/target/target_core_device.c19
-rw-r--r--drivers/target/target_core_tmr.c4
-rw-r--r--drivers/target/target_core_transport.c55
-rw-r--r--drivers/target/target_core_user.c4
-rw-r--r--drivers/target/target_core_xcopy.c9
-rw-r--r--drivers/tee/optee/call.c4
-rw-r--r--drivers/thermal/Kconfig14
-rw-r--r--drivers/thermal/Makefile11
-rw-r--r--drivers/thermal/clock_cooling.c3
-rw-r--r--drivers/thermal/cpufreq_cooling.c10
-rw-r--r--drivers/thermal/cpuidle_cooling.c63
-rw-r--r--drivers/thermal/devfreq_cooling.c70
-rw-r--r--drivers/thermal/gov_fair_share.c (renamed from drivers/thermal/fair_share.c)0
-rw-r--r--drivers/thermal/gov_power_allocator.c (renamed from drivers/thermal/power_allocator.c)0
-rw-r--r--drivers/thermal/gov_step_wise.c (renamed from drivers/thermal/step_wise.c)0
-rw-r--r--drivers/thermal/gov_user_space.c (renamed from drivers/thermal/user_space.c)2
-rw-r--r--drivers/thermal/imx8mm_thermal.c2
-rw-r--r--drivers/thermal/imx_sc_thermal.c4
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3400_thermal.c223
-rw-r--r--drivers/thermal/k3_bandgap.c264
-rw-r--r--drivers/thermal/qcom/Makefile4
-rw-r--r--drivers/thermal/qcom/tsens-common.c843
-rw-r--r--drivers/thermal/qcom/tsens.c838
-rw-r--r--drivers/thermal/qcom/tsens.h5
-rw-r--r--drivers/thermal/qoriq_thermal.c26
-rw-r--r--drivers/thermal/rcar_thermal.c9
-rw-r--r--drivers/thermal/rockchip_thermal.c4
-rw-r--r--drivers/thermal/st/st_thermal_memmap.c4
-rw-r--r--drivers/thermal/st/stm_thermal.c4
-rw-r--r--drivers/thermal/thermal_core.c12
-rw-r--r--drivers/thermal/thermal_core.h52
-rw-r--r--drivers/thermal/thermal_helpers.c16
-rw-r--r--drivers/thermal/thermal_hwmon.c6
-rw-r--r--drivers/thermal/thermal_of.c (renamed from drivers/thermal/of-thermal.c)10
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.c5
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal-common.c6
-rw-r--r--drivers/tty/Kconfig20
-rw-r--r--drivers/tty/serial/8250/Kconfig12
-rw-r--r--drivers/tty/serial/Kconfig24
-rw-r--r--drivers/tty/sysrq.c2
-rw-r--r--drivers/tty/vt/consolemap.c2
-rw-r--r--drivers/usb/Kconfig8
-rw-r--r--drivers/usb/class/Kconfig4
-rw-r--r--drivers/usb/gadget/function/f_fs.c10
-rw-r--r--drivers/usb/gadget/function/f_tcm.c6
-rw-r--r--drivers/usb/gadget/legacy/inode.c6
-rw-r--r--drivers/usb/host/Kconfig90
-rw-r--r--drivers/usb/image/Kconfig2
-rw-r--r--drivers/usb/misc/Kconfig4
-rw-r--r--drivers/usb/misc/sisusbvga/Kconfig4
-rw-r--r--drivers/usb/serial/Kconfig30
-rw-r--r--drivers/usb/storage/Kconfig8
-rw-r--r--drivers/usb/usbip/Kconfig14
-rw-r--r--drivers/vdpa/Kconfig2
-rw-r--r--drivers/vdpa/ifcvf/ifcvf_base.c3
-rw-r--r--drivers/vdpa/ifcvf/ifcvf_base.h4
-rw-r--r--drivers/vdpa/ifcvf/ifcvf_main.c146
-rw-r--r--drivers/vdpa/vdpa_sim/vdpa_sim.c7
-rw-r--r--drivers/vfio/pci/vfio_pci.c22
-rw-r--r--drivers/vfio/vfio_iommu_type1.c14
-rw-r--r--drivers/vhost/Kconfig25
-rw-r--r--drivers/vhost/net.c2
-rw-r--r--drivers/vhost/scsi.c2
-rw-r--r--drivers/vhost/test.c2
-rw-r--r--drivers/vhost/vdpa.c116
-rw-r--r--drivers/vhost/vhost.c111
-rw-r--r--drivers/vhost/vhost.h8
-rw-r--r--drivers/vhost/vringh.c6
-rw-r--r--drivers/vhost/vsock.c2
-rw-r--r--drivers/video/console/Kconfig4
-rw-r--r--drivers/video/console/newport_con.c1
-rw-r--r--drivers/video/fbdev/Kconfig118
-rw-r--r--drivers/video/fbdev/acornfb.c1
-rw-r--r--drivers/video/fbdev/atafb.c1
-rw-r--r--drivers/video/fbdev/cirrusfb.c1
-rw-r--r--drivers/video/fbdev/cyber2000fb.c1
-rw-r--r--drivers/video/fbdev/fb-puv3.c1
-rw-r--r--drivers/video/fbdev/geode/Kconfig8
-rw-r--r--drivers/video/fbdev/hitfb.c1
-rw-r--r--drivers/video/fbdev/neofb.c1
-rw-r--r--drivers/video/fbdev/q40fb.c1
-rw-r--r--drivers/video/fbdev/savage/savagefb_driver.c1
-rw-r--r--drivers/virt/Kconfig2
-rw-r--r--drivers/virtio/Kconfig31
-rw-r--r--drivers/virtio/Makefile1
-rw-r--r--drivers/virtio/virtio_balloon.c9
-rw-r--r--drivers/virtio/virtio_mem.c1965
-rw-r--r--drivers/virtio/virtio_mmio.c4
-rw-r--r--drivers/virtio/virtio_pci_modern.c1
-rw-r--r--drivers/visorbus/Kconfig2
-rw-r--r--drivers/vme/Kconfig2
-rw-r--r--drivers/w1/Kconfig4
-rw-r--r--drivers/watchdog/Kconfig80
-rw-r--r--drivers/xen/Kconfig4
-rw-r--r--drivers/xen/Makefile2
-rw-r--r--drivers/xen/balloon.c1
-rw-r--r--drivers/xen/cpu_hotplug.c8
-rw-r--r--drivers/xen/events/events_base.c32
-rw-r--r--drivers/xen/gntdev.c6
-rw-r--r--drivers/xen/grant-table.c1
-rw-r--r--drivers/xen/platform-pci.c2
-rw-r--r--drivers/xen/preempt.c42
-rw-r--r--drivers/xen/privcmd.c15
-rw-r--r--drivers/xen/pvcalls-back.c5
-rw-r--r--drivers/xen/time.c2
-rw-r--r--drivers/xen/xen-pciback/conf_space.c16
-rw-r--r--drivers/xen/xen-pciback/conf_space_header.c44
-rw-r--r--drivers/xen/xen-pciback/conf_space_quirks.c6
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c38
-rw-r--r--drivers/xen/xen-pciback/pciback.h2
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c55
-rw-r--r--drivers/xen/xen-pciback/vpci.c10
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c12
-rw-r--r--drivers/xen/xenbus/xenbus_probe_backend.c1
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c1
-rw-r--r--drivers/zorro/Kconfig2
1832 files changed, 50748 insertions, 19776 deletions
diff --git a/drivers/accessibility/Kconfig b/drivers/accessibility/Kconfig
index 00f7512c9cf4..f10c17dc1dee 100644
--- a/drivers/accessibility/Kconfig
+++ b/drivers/accessibility/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig ACCESSIBILITY
bool "Accessibility support"
- ---help---
+ help
Accessibility handles all special kinds of hardware devices or
software adapters which help people with disabilities (e.g.
blindness) to use computers.
@@ -21,7 +21,7 @@ config A11Y_BRAILLE_CONSOLE
bool "Console on braille device"
depends on VT
depends on SERIAL_CORE_CONSOLE
- ---help---
+ help
Enables console output on a braille device connected to a 8250
serial port. For now only the VisioBraille device is supported.
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 8596a106a933..f138e12b7b82 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -42,8 +42,6 @@ struct extlog_l1_head {
u8 rev1[12];
};
-static int old_edac_report_status;
-
static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295";
/* L1 table related physical address */
@@ -146,7 +144,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
static u32 err_seq;
estatus = extlog_elog_entry_check(cpu, bank);
- if (estatus == NULL)
+ if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC))
return NOTIFY_DONE;
memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
@@ -176,7 +174,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
}
out:
- return NOTIFY_STOP;
+ mce->kflags |= MCE_HANDLED_EXTLOG;
+ return NOTIFY_OK;
}
static bool __init extlog_get_l1addr(void)
@@ -228,11 +227,6 @@ static int __init extlog_init(void)
if (!(cap & MCG_ELOG_P) || !extlog_get_l1addr())
return -ENODEV;
- if (edac_get_report_status() == EDAC_REPORTING_FORCE) {
- pr_warn("Not loading eMCA, error reporting force-enabled through EDAC.\n");
- return -EPERM;
- }
-
rc = -EINVAL;
/* get L1 header to fetch necessary information */
l1_hdr_size = sizeof(struct extlog_l1_head);
@@ -280,12 +274,6 @@ static int __init extlog_init(void)
if (elog_buf == NULL)
goto err_release_elog;
- /*
- * eMCA event report method has higher priority than EDAC method,
- * unless EDAC event report method is mandatory.
- */
- old_edac_report_status = edac_get_report_status();
- edac_set_report_status(EDAC_REPORTING_DISABLED);
mce_register_decode_chain(&extlog_mce_dec);
/* enable OS to be involved to take over management from BIOS */
((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN;
@@ -307,7 +295,6 @@ err:
static void __exit extlog_exit(void)
{
- edac_set_report_status(old_edac_report_status);
mce_unregister_decode_chain(&extlog_mce_dec);
((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
if (extlog_l1_addr)
diff --git a/drivers/acpi/acpica/dbdisply.c b/drivers/acpi/acpica/dbdisply.c
index f2df416d0d2d..d41eb9e67500 100644
--- a/drivers/acpi/acpica/dbdisply.c
+++ b/drivers/acpi/acpica/dbdisply.c
@@ -51,6 +51,8 @@ static acpi_adr_space_type acpi_gbl_space_id_list[] = {
ACPI_ADR_SPACE_IPMI,
ACPI_ADR_SPACE_GPIO,
ACPI_ADR_SPACE_GSBUS,
+ ACPI_ADR_SPACE_PLATFORM_COMM,
+ ACPI_ADR_SPACE_PLATFORM_RT,
ACPI_ADR_SPACE_DATA_TABLE,
ACPI_ADR_SPACE_FIXED_HARDWARE
};
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index 177ab88d95de..ed9aedf604a1 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -78,7 +78,8 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
"IPMI", /* 0x07 */
"GeneralPurposeIo", /* 0x08 */
"GenericSerialBus", /* 0x09 */
- "PCC" /* 0x0A */
+ "PCC", /* 0x0A */
+ "PlatformRtMechanism" /* 0x0B */
};
const char *acpi_ut_get_region_name(u8 space_id)
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index b44b12a931e7..94d91c67aeae 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -186,7 +186,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
* possibly drop references to the power resources in use.
*/
state = ACPI_STATE_D3_HOT;
- /* If _PR3 is not available, use D3hot as the target state. */
+ /* If D3cold is not supported, use D3hot as the target state. */
if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
target_state = state;
} else if (!device->power.states[state].flags.valid) {
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index fa4500f9cfd1..7c138a4edc03 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2293,7 +2293,7 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc,
nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
if (!nd_set)
return -ENOMEM;
- guid_copy(&nd_set->type_guid, (guid_t *) spa->range_guid);
+ import_guid(&nd_set->type_guid, spa->range_guid);
info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL);
if (!info)
diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c
index f0ae48515b48..ee8d9973f60b 100644
--- a/drivers/acpi/nfit/mce.c
+++ b/drivers/acpi/nfit/mce.c
@@ -76,6 +76,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
*/
acpi_nfit_ars_rescan(acpi_desc, 0);
}
+ mce->kflags |= MCE_HANDLED_NFIT;
break;
}
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 47b4969d9b93..5be5a977da1b 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -35,6 +35,7 @@ int pxm_to_node(int pxm)
return NUMA_NO_NODE;
return pxm_to_node_map[pxm];
}
+EXPORT_SYMBOL(pxm_to_node);
int node_to_pxm(int node)
{
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5287ab98b8c1..8777faced51a 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -15,8 +15,7 @@
#include <linux/nls.h>
#include <linux/dma-mapping.h>
#include <linux/platform_data/x86/apple.h>
-
-#include <asm/pgtable.h>
+#include <linux/pgtable.h>
#include "internal.h"
@@ -919,12 +918,9 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
if (buffer.length && package
&& package->type == ACPI_TYPE_PACKAGE
- && package->package.count) {
- int err = acpi_extract_power_resources(package, 0,
- &ps->resources);
- if (!err)
- device->power.flags.power_resources = 1;
- }
+ && package->package.count)
+ acpi_extract_power_resources(package, 0, &ps->resources);
+
ACPI_FREE(buffer.pointer);
}
@@ -971,14 +967,27 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
acpi_bus_init_power_state(device, i);
INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources);
- if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
- device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
- /* Set defaults for D0 and D3hot states (always valid) */
+ /* Set the defaults for D0 and D3hot (always supported). */
device->power.states[ACPI_STATE_D0].flags.valid = 1;
device->power.states[ACPI_STATE_D0].power = 100;
device->power.states[ACPI_STATE_D3_HOT].flags.valid = 1;
+ /*
+ * Use power resources only if the D0 list of them is populated, because
+ * some platforms may provide _PR3 only to indicate D3cold support and
+ * in those cases the power resources list returned by it may be bogus.
+ */
+ if (!list_empty(&device->power.states[ACPI_STATE_D0].resources)) {
+ device->power.flags.power_resources = 1;
+ /*
+ * D3cold is supported if the D3hot list of power resources is
+ * not empty.
+ */
+ if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources))
+ device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
+ }
+
if (acpi_bus_init_power(device))
device->flags.power_manageable = 0;
}
diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig
index 6fdf2abe4598..53b22e26266c 100644
--- a/drivers/android/Kconfig
+++ b/drivers/android/Kconfig
@@ -3,7 +3,7 @@ menu "Android"
config ANDROID
bool "Android Drivers"
- ---help---
+ help
Enable support for various drivers needed on the Android platform
if ANDROID
@@ -12,7 +12,7 @@ config ANDROID_BINDER_IPC
bool "Android Binder IPC Driver"
depends on MMU
default n
- ---help---
+ help
Binder is used in Android for both communication between processes,
and remote method invocation.
@@ -24,7 +24,7 @@ config ANDROID_BINDERFS
bool "Android Binderfs filesystem"
depends on ANDROID_BINDER_IPC
default n
- ---help---
+ help
Binderfs is a pseudo-filesystem for the Android Binder IPC driver
which can be mounted per-ipc namespace allowing to run multiple
instances of Android.
@@ -36,7 +36,7 @@ config ANDROID_BINDER_DEVICES
string "Android Binder devices"
depends on ANDROID_BINDER_IPC
default "binder,hwbinder,vndbinder"
- ---help---
+ help
Default value for the binder.devices parameter.
The binder.devices parameter is a comma-separated list of strings
@@ -47,7 +47,7 @@ config ANDROID_BINDER_DEVICES
config ANDROID_BINDER_IPC_SELFTEST
bool "Android Binder IPC Driver Selftest"
depends on ANDROID_BINDER_IPC
- ---help---
+ help
This feature allows binder selftest to run.
Binder selftest checks the allocation and free of binder buffers
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 2d8b9b91dee0..42c672f1584e 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -212,7 +212,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
mm = alloc->vma_vm_mm;
if (mm) {
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = alloc->vma;
}
@@ -270,7 +270,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
trace_binder_alloc_page_end(alloc, index);
}
if (mm) {
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
}
return 0;
@@ -303,7 +303,7 @@ err_page_ptr_cleared:
}
err_no_vma:
if (mm) {
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
}
return vma ? -ENOMEM : -ESRCH;
@@ -932,8 +932,8 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
mm = alloc->vma_vm_mm;
if (!mmget_not_zero(mm))
goto err_mmget;
- if (!down_read_trylock(&mm->mmap_sem))
- goto err_down_read_mmap_sem_failed;
+ if (!mmap_read_trylock(mm))
+ goto err_mmap_read_lock_failed;
vma = binder_alloc_get_vma(alloc);
list_lru_isolate(lru, item);
@@ -946,7 +946,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
trace_binder_unmap_user_end(alloc, index);
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
trace_binder_unmap_kernel_start(alloc, index);
@@ -960,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
mutex_unlock(&alloc->mutex);
return LRU_REMOVED_RETRY;
-err_down_read_mmap_sem_failed:
+err_mmap_read_lock_failed:
mmput_async(mm);
err_mmget:
err_page_already_freed:
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 05ecdce1b702..030cb32da980 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -17,7 +17,7 @@ menuconfig ATA
depends on BLOCK
select SCSI
select GLOB
- ---help---
+ help
If you want to use an ATA hard disk, ATA tape drive, ATA CD-ROM or
any other ATA device under Linux, say Y and make sure that you know
the name of your ATA host adapter (the card inside your computer
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index cfb0d16b60ad..8007e051876c 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -7,7 +7,7 @@ menuconfig ATM_DRIVERS
bool "ATM drivers"
depends on NETDEVICES && ATM
default y
- ---help---
+ help
Say Y here to get to see options for Asynchronous Transfer Mode
device drivers. This option alone does not add any kernel code.
@@ -40,7 +40,7 @@ config ATM_LANAI
config ATM_ENI
tristate "Efficient Networks ENI155P"
depends on PCI
- ---help---
+ help
Driver for the Efficient Networks ENI155p series and SMC ATM
Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
2MB on-board RAM (Efficient calls them "C" and "S", respectively),
@@ -64,7 +64,7 @@ config ATM_ENI_DEBUG
config ATM_ENI_TUNE_BURST
bool "Fine-tune burst settings"
depends on ATM_ENI
- ---help---
+ help
In order to obtain good throughput, the ENI NIC can transfer
multiple words of data per PCI bus access cycle. Such a multi-word
transfer is called a burst.
@@ -256,7 +256,7 @@ config ATM_AMBASSADOR
config ATM_AMBASSADOR_DEBUG
bool "Enable debugging messages"
depends on ATM_AMBASSADOR
- ---help---
+ help
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument (kernel command line argument as well?), changed
@@ -280,7 +280,7 @@ config ATM_HORIZON
config ATM_HORIZON_DEBUG
bool "Enable debugging messages"
depends on ATM_HORIZON
- ---help---
+ help
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument (kernel command line argument as well?), changed
@@ -296,7 +296,7 @@ config ATM_HORIZON_DEBUG
config ATM_IA
tristate "Interphase ATM PCI x575/x525/x531"
depends on PCI
- ---help---
+ help
This is a driver for the Interphase (i)ChipSAR adapter cards
which include a variety of variants in term of the size of the
control memory (128K-1KVC, 512K-4KVC), the size of the packet
@@ -312,7 +312,7 @@ config ATM_IA
config ATM_IA_DEBUG
bool "Enable debugging messages"
depends on ATM_IA
- ---help---
+ help
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument (kernel command line argument as well?), changed
@@ -330,7 +330,7 @@ config ATM_FORE200E
tristate "FORE Systems 200E-series"
depends on (PCI || SBUS)
select FW_LOADER
- ---help---
+ help
This is a driver for the FORE Systems 200E-series ATM adapter
cards. It simultaneously supports PCA-200E and SBA-200E models
on PCI and SBUS hosts. Say Y (or M to compile as a module
@@ -352,7 +352,7 @@ config ATM_FORE200E_TX_RETRY
int "Maximum number of tx retries"
depends on ATM_FORE200E
default "16"
- ---help---
+ help
Specifies the number of times the driver attempts to transmit
a message before giving up, if the transmit queue of the ATM card
is transiently saturated.
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 8fbd36eb8941..f4ad7ce25ae8 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -25,6 +25,7 @@
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/firmware.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/page.h>
@@ -40,7 +41,6 @@
#include <asm/idprom.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
-#include <asm/pgtable.h>
#endif
#if defined(CONFIG_ATM_FORE200E_USE_TASKLET) /* defer interrupt work to a tasklet */
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index 48efa7a047f3..81757eeded68 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -8,7 +8,7 @@
menuconfig AUXDISPLAY
bool "Auxiliary Display support"
- ---help---
+ help
Say Y here to get to see options for auxiliary display drivers.
This option alone does not add any kernel code.
@@ -20,7 +20,7 @@ config HD44780
tristate "HD44780 Character LCD support"
depends on GPIOLIB || COMPILE_TEST
select CHARLCD
- ---help---
+ help
Enable support for Character LCDs using a HD44780 controller.
The LCD is accessible through the /dev/lcd char device (10, 156).
This code can either be compiled as a module, or linked into the
@@ -31,7 +31,7 @@ config KS0108
tristate "KS0108 LCD Controller"
depends on PARPORT_PC
default n
- ---help---
+ help
If you have a LCD controlled by one or more KS0108
controllers, say Y. You will need also another more specific
driver for your LCD.
@@ -49,7 +49,7 @@ config KS0108_PORT
hex "Parallel port where the LCD is connected"
depends on KS0108
default 0x378
- ---help---
+ help
The address of the parallel port where the LCD is connected.
The first standard parallel port address is 0x378.
@@ -71,7 +71,7 @@ config KS0108_DELAY
int "Delay between each control writing (microseconds)"
depends on KS0108
default "2"
- ---help---
+ help
Amount of time the ks0108 should wait between each control write
to the parallel port.
@@ -92,7 +92,7 @@ config CFAG12864B
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
default n
- ---help---
+ help
If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
say Y. You also need the ks0108 LCD Controller driver.
@@ -114,7 +114,7 @@ config CFAG12864B_RATE
int "Refresh rate (hertz)"
depends on CFAG12864B
default "20"
- ---help---
+ help
Refresh rate of the LCD.
As the LCD is not memory mapped, the driver has to make the work by
@@ -168,7 +168,7 @@ menuconfig PARPORT_PANEL
tristate "Parallel port LCD/Keypad Panel support"
depends on PARPORT
select CHARLCD
- ---help---
+ help
Say Y here if you have an HD44780 or KS-0074 LCD connected to your
parallel port. This driver also features 4 and 6-key keypads. The LCD
is accessible through the /dev/lcd char device (10, 156), and the
@@ -182,7 +182,7 @@ config PANEL_PARPORT
int "Default parallel port number (0=LPT1)"
range 0 255
default "0"
- ---help---
+ help
This is the index of the parallel port the panel is connected to. One
driver instance only supports one parallel port, so if your keypad
and LCD are connected to two separate ports, you have to start two
@@ -193,7 +193,7 @@ config PANEL_PROFILE
int "Default panel profile (0-5, 0=custom)"
range 0 5
default "5"
- ---help---
+ help
To ease configuration, the driver supports different configuration
profiles for past and recent wirings. These profiles can also be
used to define an approximative configuration, completed by a few
@@ -215,7 +215,7 @@ config PANEL_KEYPAD
int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)"
range 0 3
default 0
- ---help---
+ help
This enables and configures a keypad connected to the parallel port.
The keys will be read from character device 10,185. Valid values are :
@@ -232,7 +232,7 @@ config PANEL_LCD
int "LCD type (0=none, 1=custom, 2=old //, 3=ks0074, 4=hantronix, 5=Nexcom)"
range 0 5
default 0
- ---help---
+ help
This enables and configures an LCD connected to the parallel port.
The driver includes an interpreter for escape codes starting with
'\e[L' which are specific to the LCD, and a few ANSI codes. The
@@ -255,7 +255,7 @@ config PANEL_LCD_HEIGHT
int "Number of lines on the LCD (1-2)"
range 1 2
default 2
- ---help---
+ help
This is the number of visible character lines on the LCD in custom profile.
It can either be 1 or 2.
@@ -264,7 +264,7 @@ config PANEL_LCD_WIDTH
int "Number of characters per line on the LCD (1-40)"
range 1 40
default 40
- ---help---
+ help
This is the number of characters per line on the LCD in custom profile.
Common values are 16,20,24,40.
@@ -273,7 +273,7 @@ config PANEL_LCD_BWIDTH
int "Internal LCD line width (1-40, 40 by default)"
range 1 40
default 40
- ---help---
+ help
Most LCDs use a standard controller which supports hardware lines of 40
characters, although sometimes only 16, 20 or 24 of them are really wired
to the terminal. This results in some non-visible but addressable characters,
@@ -289,7 +289,7 @@ config PANEL_LCD_HWIDTH
int "Hardware LCD line width (1-64, 64 by default)"
range 1 64
default 64
- ---help---
+ help
Most LCDs use a single address bit to differentiate line 0 and line 1. Since
some of them need to be able to address 40 chars with the lower bits, they
often use the immediately superior power of 2, which is 64, to address the
@@ -303,7 +303,7 @@ config PANEL_LCD_CHARSET
int "LCD character set (0=normal, 1=KS0074)"
range 0 1
default 0
- ---help---
+ help
Some controllers such as the KS0074 use a somewhat strange character set
where many symbols are at unusual places. The driver knows how to map
'standard' ASCII characters to the character sets used by these controllers.
@@ -319,7 +319,7 @@ config PANEL_LCD_PROTO
int "LCD communication mode (0=parallel 8 bits, 1=serial)"
range 0 1
default 0
- ---help---
+ help
This driver now supports any serial or parallel LCD wired to a parallel
port. But before assigning signals, the driver needs to know if it will
be driving a serial LCD or a parallel one. Serial LCDs only use 2 wires
@@ -332,7 +332,7 @@ config PANEL_LCD_PIN_E
int "Parallel port pin number & polarity connected to the LCD E signal (-17...17) "
range -17 17
default 14
- ---help---
+ help
This describes the number of the parallel port pin to which the LCD 'E'
signal has been connected. It can be :
@@ -347,7 +347,7 @@ config PANEL_LCD_PIN_RS
int "Parallel port pin number & polarity connected to the LCD RS signal (-17...17) "
range -17 17
default 17
- ---help---
+ help
This describes the number of the parallel port pin to which the LCD 'RS'
signal has been connected. It can be :
@@ -362,7 +362,7 @@ config PANEL_LCD_PIN_RW
int "Parallel port pin number & polarity connected to the LCD RW signal (-17...17) "
range -17 17
default 16
- ---help---
+ help
This describes the number of the parallel port pin to which the LCD 'RW'
signal has been connected. It can be :
@@ -377,7 +377,7 @@ config PANEL_LCD_PIN_SCL
int "Parallel port pin number & polarity connected to the LCD SCL signal (-17...17) "
range -17 17
default 1
- ---help---
+ help
This describes the number of the parallel port pin to which the serial
LCD 'SCL' signal has been connected. It can be :
@@ -392,7 +392,7 @@ config PANEL_LCD_PIN_SDA
int "Parallel port pin number & polarity connected to the LCD SDA signal (-17...17) "
range -17 17
default 2
- ---help---
+ help
This describes the number of the parallel port pin to which the serial
LCD 'SDA' signal has been connected. It can be :
@@ -407,7 +407,7 @@ config PANEL_LCD_PIN_BL
int "Parallel port pin number & polarity connected to the LCD backlight signal (-17...17) "
range -17 17
default 0
- ---help---
+ help
This describes the number of the parallel port pin to which the LCD 'BL' signal
has been connected. It can be :
@@ -423,7 +423,7 @@ config PANEL_CHANGE_MESSAGE
bool "Change LCD initialization message ?"
depends on CHARLCD
default "n"
- ---help---
+ help
This allows you to replace the boot message indicating the kernel version
and the driver version with a custom message. This is useful on appliances
where a simple 'Starting system' message can be enough to stop a customer
@@ -436,7 +436,7 @@ config PANEL_BOOT_MESSAGE
depends on PANEL_CHANGE_MESSAGE="y"
string "New initialization message"
default ""
- ---help---
+ help
This allows you to replace the boot message indicating the kernel version
and the driver version with a custom message. This is useful on appliances
where a simple 'Starting system' message can be enough to stop a customer
@@ -448,7 +448,7 @@ config PANEL_BOOT_MESSAGE
choice
prompt "Backlight initial state"
default CHARLCD_BL_FLASH
- ---help---
+ help
Select the initial backlight state on boot or module load.
Previously, there was no option for this: the backlight flashed
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 5f0bc74d2409..8d7001712062 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -149,8 +149,9 @@ config DEBUG_TEST_DRIVER_REMOVE
test this functionality.
config PM_QOS_KUNIT_TEST
- bool "KUnit Test for PM QoS features"
+ bool "KUnit Test for PM QoS features" if !KUNIT_ALL_TESTS
depends on KUNIT=y
+ default KUNIT_ALL_TESTS
config HMEM_REPORTING
bool
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 9a1c00fbbaef..d2136ab9b14a 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -562,6 +562,12 @@ ssize_t __weak cpu_show_itlb_multihit(struct device *dev,
return sprintf(buf, "Not affected\n");
}
+ssize_t __weak cpu_show_srbds(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "Not affected\n");
+}
+
static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
@@ -570,6 +576,7 @@ static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL);
static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
+static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
static struct attribute *cpu_root_vulnerabilities_attrs[] = {
&dev_attr_meltdown.attr,
@@ -580,6 +587,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
&dev_attr_mds.attr,
&dev_attr_tsx_async_abort.attr,
&dev_attr_itlb_multihit.attr,
+ &dev_attr_srbds.attr,
NULL
};
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index bb98b813554f..9dd85bea4026 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -519,7 +519,7 @@ static void dpm_watchdog_handler(struct timer_list *t)
struct dpm_watchdog *wd = from_timer(wd, t, timer);
dev_emerg(wd->dev, "**** DPM device timeout ****\n");
- show_stack(wd->tsk, NULL);
+ show_stack(wd->tsk, NULL, KERN_EMERG);
panic("%s %s: unrecoverable failure\n",
dev_driver_string(wd->dev), dev_name(wd->dev));
}
diff --git a/drivers/base/test/Kconfig b/drivers/base/test/Kconfig
index 305c7751184a..ba225eb1b761 100644
--- a/drivers/base/test/Kconfig
+++ b/drivers/base/test/Kconfig
@@ -9,5 +9,6 @@ config TEST_ASYNC_DRIVER_PROBE
If unsure say N.
config KUNIT_DRIVER_PE_TEST
- bool "KUnit Tests for property entry API"
+ bool "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS
depends on KUNIT=y
+ default KUNIT_ALL_TESTS
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 084b9efcefca..ecceaaa1a66f 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -7,7 +7,7 @@ menuconfig BLK_DEV
bool "Block devices"
depends on BLOCK
default y
- ---help---
+ help
Say Y here to get to see options for various different block device
drivers. This option alone does not add any kernel code.
@@ -27,7 +27,7 @@ config BLK_DEV_NULL_BLK_FAULT_INJECTION
config BLK_DEV_FD
tristate "Normal floppy disk support"
depends on ARCH_MAY_HAVE_PC_FDC
- ---help---
+ help
If you want to use the floppy disk drive(s) of your PC under Linux,
say Y. Information about this driver, especially important for IBM
Thinkpad users, is contained in
@@ -91,7 +91,7 @@ config GDROM
config PARIDE
tristate "Parallel port IDE device support"
depends on PARPORT_PC
- ---help---
+ help
There are many external CD-ROM and disk devices that connect through
your computer's parallel port. Most of them are actually IDE devices
using a parallel port IDE adapter. This option enables the PARIDE
@@ -124,7 +124,7 @@ source "drivers/block/zram/Kconfig"
config BLK_DEV_UMEM
tristate "Micro Memory MM5415 Battery Backed RAM support"
depends on PCI
- ---help---
+ help
Saying Y here will include support for the MM5415 family of
battery backed (Non-volatile) RAM cards.
<http://www.umem.com/>
@@ -141,7 +141,7 @@ config BLK_DEV_UMEM
config BLK_DEV_UBD
bool "Virtual block device"
depends on UML
- ---help---
+ help
The User-Mode Linux port includes a driver called UBD which will let
you access arbitrary files on the host computer as block devices.
Unless you know that you do not need such virtual block devices say
@@ -150,7 +150,7 @@ config BLK_DEV_UBD
config BLK_DEV_UBD_SYNC
bool "Always do synchronous disk IO for UBD"
depends on BLK_DEV_UBD
- ---help---
+ help
Writes to the virtual block device are not immediately written to the
host's disk; this may cause problems if, for example, the User-Mode
Linux 'Virtual Machine' uses a journalling filesystem and the host
@@ -173,7 +173,7 @@ config BLK_DEV_COW_COMMON
config BLK_DEV_LOOP
tristate "Loopback device support"
- ---help---
+ help
Saying Y here will allow you to use a regular file as a block
device; you can then create a file system on that block device and
mount it just as you would mount other block devices such as hard
@@ -234,7 +234,7 @@ config BLK_DEV_CRYPTOLOOP
select CRYPTO
select CRYPTO_CBC
depends on BLK_DEV_LOOP
- ---help---
+ help
Say Y here if you want to be able to use the ciphers that are
provided by the CryptoAPI as loop transformation. This might be
used as hard disk encryption.
@@ -249,7 +249,7 @@ source "drivers/block/drbd/Kconfig"
config BLK_DEV_NBD
tristate "Network block device support"
depends on NET
- ---help---
+ help
Saying Y here will allow your computer to be a client for network
block devices, i.e. it will be able to use block devices exported by
servers (mount file systems on them etc.). Communication between
@@ -277,7 +277,7 @@ config BLK_DEV_SKD
tristate "STEC S1120 Block Driver"
depends on PCI
depends on 64BIT
- ---help---
+ help
Saying Y or M here will enable support for the
STEC, Inc. S1120 PCIe SSD.
@@ -286,7 +286,7 @@ config BLK_DEV_SKD
config BLK_DEV_SX8
tristate "Promise SATA SX8 support"
depends on PCI
- ---help---
+ help
Saying Y or M here will enable support for the
Promise SATA SX8 controllers.
@@ -294,7 +294,7 @@ config BLK_DEV_SX8
config BLK_DEV_RAM
tristate "RAM block device support"
- ---help---
+ help
Saying Y here will allow you to use a portion of your RAM memory as
a block device, so that you can make file systems on it, read and
write to it and do all the other things that you can do with normal
@@ -428,7 +428,7 @@ config XEN_BLKDEV_BACKEND
config VIRTIO_BLK
tristate "Virtio block driver"
depends on VIRTIO
- ---help---
+ help
This is the virtual block driver for virtio. It can be used with
QEMU based VMMs (like KVM or Xen). Say Y or M.
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2e96d8b8758b..c33bbbfd1bd9 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1390,7 +1390,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
goto out_unfreeze;
/* Mask out flags that can't be set using LOOP_SET_STATUS. */
- lo->lo_flags &= ~LOOP_SET_STATUS_SETTABLE_FLAGS;
+ lo->lo_flags &= LOOP_SET_STATUS_SETTABLE_FLAGS;
/* For those flags, use the previous values instead */
lo->lo_flags |= prev_lo_flags & ~LOOP_SET_STATUS_SETTABLE_FLAGS;
/* For flags that can't be cleared, use previous values too */
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
index f8bd6ef3605a..7c6ae1036927 100644
--- a/drivers/block/paride/Kconfig
+++ b/drivers/block/paride/Kconfig
@@ -28,7 +28,7 @@ config PARIDE_PCD
depends on PARIDE
select CDROM
select BLK_SCSI_REQUEST # only for the generic cdrom code
- ---help---
+ help
This option enables the high-level driver for ATAPI CD-ROM devices
connected through a parallel port. If you chose to build PARIDE
support into your kernel, you may answer Y here to build in the
@@ -71,7 +71,7 @@ config PARIDE_PT
config PARIDE_PG
tristate "Parallel port generic ATAPI devices"
depends on PARIDE
- ---help---
+ help
This option enables a special high-level driver for generic ATAPI
devices connected through a parallel port. The driver allows user
programs, such as cdrtools, to send ATAPI commands directly to a
@@ -111,7 +111,7 @@ config PARIDE_ATEN
config PARIDE_BPCK
tristate "MicroSolutions backpack (Series 5) protocol"
depends on PARIDE
- ---help---
+ help
This option enables support for the Micro Solutions BACKPACK
parallel port Series 5 IDE protocol. (Most BACKPACK drives made
before 1999 were Series 5) Series 5 drives will NOT always have the
@@ -129,7 +129,7 @@ config PARIDE_BPCK
config PARIDE_BPCK6
tristate "MicroSolutions backpack (Series 6) protocol"
depends on PARIDE && !64BIT
- ---help---
+ help
This option enables support for the Micro Solutions BACKPACK
parallel port Series 6 IDE protocol. (Most BACKPACK drives made
after 1999 were Series 6) Series 6 drives will have the Series noted
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 0b944ac96d6b..27a33adc41e4 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1613,7 +1613,7 @@ static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd,
disc_information di;
track_information ti;
__u32 last_track;
- int ret = -1;
+ int ret;
ret = pkt_get_disc_info(pd, &di);
if (ret)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 67d65ac785e9..7420648a1de6 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -836,6 +836,7 @@ enum {
Opt_lock_timeout,
/* int args above */
Opt_pool_ns,
+ Opt_compression_hint,
/* string args above */
Opt_read_only,
Opt_read_write,
@@ -844,8 +845,23 @@ enum {
Opt_notrim,
};
+enum {
+ Opt_compression_hint_none,
+ Opt_compression_hint_compressible,
+ Opt_compression_hint_incompressible,
+};
+
+static const struct constant_table rbd_param_compression_hint[] = {
+ {"none", Opt_compression_hint_none},
+ {"compressible", Opt_compression_hint_compressible},
+ {"incompressible", Opt_compression_hint_incompressible},
+ {}
+};
+
static const struct fs_parameter_spec rbd_parameters[] = {
fsparam_u32 ("alloc_size", Opt_alloc_size),
+ fsparam_enum ("compression_hint", Opt_compression_hint,
+ rbd_param_compression_hint),
fsparam_flag ("exclusive", Opt_exclusive),
fsparam_flag ("lock_on_read", Opt_lock_on_read),
fsparam_u32 ("lock_timeout", Opt_lock_timeout),
@@ -867,6 +883,8 @@ struct rbd_options {
bool lock_on_read;
bool exclusive;
bool trim;
+
+ u32 alloc_hint_flags; /* CEPH_OSD_OP_ALLOC_HINT_FLAG_* */
};
#define RBD_QUEUE_DEPTH_DEFAULT BLKDEV_MAX_RQ
@@ -2253,7 +2271,8 @@ static void __rbd_osd_setup_write_ops(struct ceph_osd_request *osd_req,
!(obj_req->flags & RBD_OBJ_FLAG_MAY_EXIST)) {
osd_req_op_alloc_hint_init(osd_req, which++,
rbd_dev->layout.object_size,
- rbd_dev->layout.object_size);
+ rbd_dev->layout.object_size,
+ rbd_dev->opts->alloc_hint_flags);
}
if (rbd_obj_is_entire(obj_req))
@@ -6331,6 +6350,29 @@ static int rbd_parse_param(struct fs_parameter *param,
pctx->spec->pool_ns = param->string;
param->string = NULL;
break;
+ case Opt_compression_hint:
+ switch (result.uint_32) {
+ case Opt_compression_hint_none:
+ opt->alloc_hint_flags &=
+ ~(CEPH_OSD_ALLOC_HINT_FLAG_COMPRESSIBLE |
+ CEPH_OSD_ALLOC_HINT_FLAG_INCOMPRESSIBLE);
+ break;
+ case Opt_compression_hint_compressible:
+ opt->alloc_hint_flags |=
+ CEPH_OSD_ALLOC_HINT_FLAG_COMPRESSIBLE;
+ opt->alloc_hint_flags &=
+ ~CEPH_OSD_ALLOC_HINT_FLAG_INCOMPRESSIBLE;
+ break;
+ case Opt_compression_hint_incompressible:
+ opt->alloc_hint_flags |=
+ CEPH_OSD_ALLOC_HINT_FLAG_INCOMPRESSIBLE;
+ opt->alloc_hint_flags &=
+ ~CEPH_OSD_ALLOC_HINT_FLAG_COMPRESSIBLE;
+ break;
+ default:
+ BUG();
+ }
+ break;
case Opt_read_only:
opt->read_only = true;
break;
diff --git a/drivers/block/rbd_types.h b/drivers/block/rbd_types.h
index ac98ab6ccd3b..a600e0eb6b6f 100644
--- a/drivers/block/rbd_types.h
+++ b/drivers/block/rbd_types.h
@@ -93,7 +93,7 @@ struct rbd_image_header_ondisk {
__le32 snap_count;
__le32 reserved;
__le64 snap_names_len;
- struct rbd_image_snap_ondisk snaps[0];
+ struct rbd_image_snap_ondisk snaps[];
} __attribute__((packed));
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index d84e8a878df2..1e2aa5ae2796 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -784,7 +784,7 @@ static const struct block_device_operations mm_fops = {
static int mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- int ret = -ENODEV;
+ int ret;
struct cardinfo *card = &cards[num_cards];
unsigned char mem_present;
unsigned char batt_status;
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 600430685e28..0e734802ee7c 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -35,10 +35,10 @@
#include <linux/bitops.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
-#include <asm/pgtable.h>
#include <linux/zorro.h>
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index a0a7ae705de8..d82b3b7658bd 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -3535,7 +3535,7 @@ static int cdrom_print_info(const char *header, int val, char *info,
}
static int cdrom_sysctl_info(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+ void *buffer, size_t *lenp, loff_t *ppos)
{
int pos;
char *info = cdrom_sysctl_settings.info;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ac25833eb19e..98c3a5d8003e 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -11,7 +11,7 @@ config TTY_PRINTK
tristate "TTY driver to output user messages via printk"
depends on EXPERT && TTY
default n
- ---help---
+ help
If you say Y here, the support for writing user messages (i.e.
console messages) via printk is available.
@@ -33,7 +33,7 @@ config TTY_PRINTK_LEVEL
config PRINTER
tristate "Parallel printer support"
depends on PARPORT
- ---help---
+ help
If you intend to attach a printer to the parallel port of your Linux
box (as opposed to using a serial printer; if the connector at the
printer has 9 or 25 holes ["female"], then it's serial), say Y.
@@ -59,7 +59,7 @@ config PRINTER
config LP_CONSOLE
bool "Support for console on line printer"
depends on PRINTER
- ---help---
+ help
If you want kernel messages to be printed out as they occur, you
can have a console on the printer. This option adds support for
doing that; to actually get it to happen you need to pass the
@@ -76,7 +76,7 @@ config LP_CONSOLE
config PPDEV
tristate "Support for user-space parallel port device drivers"
depends on PARPORT
- ---help---
+ help
Saying Y to this adds support for /dev/parport device nodes. This
is needed for programs that want portable access to the parallel
port, for instance deviceid (which displays Plug-and-Play device
@@ -146,7 +146,7 @@ config DS1620
config NWBUTTON
tristate "NetWinder Button"
depends on ARCH_NETWINDER
- ---help---
+ help
If you say Y here and create a character device node /dev/nwbutton
with major and minor numbers 10 and 158 ("man mknod"), then every
time the orange button is pressed a number of times, the number of
@@ -182,7 +182,7 @@ config NWBUTTON_REBOOT
config NWFLASH
tristate "NetWinder flash support"
depends on ARCH_NETWINDER
- ---help---
+ help
If you say Y here and create a character device /dev/flash with
major 10 and minor 160 you can manipulate the flash ROM containing
the NetWinder firmware. Be careful as accidentally overwriting the
@@ -220,7 +220,7 @@ config XILINX_HWICAP
config R3964
tristate "Siemens R3964 line discipline"
depends on TTY && BROKEN
- ---help---
+ help
This driver allows synchronous communication with devices using the
Siemens R3964 packet protocol. Unless you are dealing with special
hardware like PLCs, you are unlikely to need this.
@@ -233,7 +233,7 @@ config R3964
config APPLICOM
tristate "Applicom intelligent fieldbus card support"
depends on PCI
- ---help---
+ help
This driver provides the kernel-side support for the intelligent
fieldbus cards made by Applicom International. More information
about these cards can be found on the WWW at the address
@@ -248,7 +248,7 @@ config APPLICOM
config SONYPI
tristate "Sony Vaio Programmable I/O Control Device support"
depends on X86_32 && PCI && INPUT
- ---help---
+ help
This driver enables access to the Sony Programmable I/O Control
Device which can be found in many (all ?) Sony Vaio laptops.
@@ -269,7 +269,7 @@ config MWAVE
tristate "ACP Modem (Mwave) support"
depends on X86 && TTY
select SERIAL_8250
- ---help---
+ help
The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
kernel driver and a user level application. Together these components
support direct attachment to public switched telephone networks (PSTNs)
@@ -347,7 +347,7 @@ config NVRAM
tristate "/dev/nvram support"
depends on X86 || HAVE_ARCH_NVRAM_OPS
default M68K || PPC
- ---help---
+ help
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
you get read and write access to the non-volatile memory.
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index bc54235a7022..a086dd34f932 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -3,7 +3,7 @@ menuconfig AGP
tristate "/dev/agpgart (AGP Support)"
depends on ALPHA || IA64 || PARISC || PPC || X86
depends on PCI
- ---help---
+ help
AGP (Accelerated Graphics Port) is a bus system mainly used to
connect graphics cards to the rest of the system.
@@ -30,7 +30,7 @@ menuconfig AGP
config AGP_ALI
tristate "ALI chipset support"
depends on AGP && X86_32
- ---help---
+ help
This option gives you AGP support for the GLX component of
X on the following ALi chipsets. The supported chipsets
include M1541, M1621, M1631, M1632, M1641,M1647,and M1651.
@@ -45,7 +45,7 @@ config AGP_ALI
config AGP_ATI
tristate "ATI chipset support"
depends on AGP && X86_32
- ---help---
+ help
This option gives you AGP support for the GLX component of
X on the ATI RadeonIGP family of chipsets.
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 47098648502d..00ff5fcb808a 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,7 +39,6 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include "agp.h"
struct agp_front_data agp_fe;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 9e84239f88d4..3ffbb1c80c5c 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -42,7 +42,6 @@
#ifdef CONFIG_X86
#include <asm/set_memory.h>
#endif
-#include <asm/pgtable.h>
#include "agp.h"
__u32 *agp_gatt_table;
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index e5e5333f302d..cce2af5df7b4 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -17,7 +17,6 @@
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
/*
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index ac00d78ee9cc..0ad17efc96df 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -6,7 +6,7 @@
menuconfig HW_RANDOM
tristate "Hardware Random Number Generator Core support"
default m
- ---help---
+ help
Hardware Random Number Generator Core infrastructure.
To compile this driver as a module, choose M here: the
@@ -24,7 +24,7 @@ if HW_RANDOM
config HW_RANDOM_TIMERIOMEM
tristate "Timer IOMEM HW Random Number Generator support"
depends on HAS_IOMEM
- ---help---
+ help
This driver provides kernel-side support for a generic Random
Number Generator used by reading a 'dumb' iomem address that
is to be read no faster than, for example, once a second;
@@ -39,7 +39,7 @@ config HW_RANDOM_INTEL
tristate "Intel HW Random Number Generator support"
depends on (X86 || IA64) && PCI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Intel i8xx-based motherboards.
@@ -52,7 +52,7 @@ config HW_RANDOM_AMD
tristate "AMD HW Random Number Generator support"
depends on (X86 || PPC_MAPLE) && PCI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on AMD 76x-based motherboards.
@@ -65,7 +65,7 @@ config HW_RANDOM_ATMEL
tristate "Atmel Random Number Generator support"
depends on ARCH_AT91 && HAVE_CLK && OF
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Atmel AT91 devices.
@@ -79,7 +79,7 @@ config HW_RANDOM_BCM2835
depends on ARCH_BCM2835 || ARCH_BCM_NSP || ARCH_BCM_5301X || \
ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on the Broadcom BCM2835 and BCM63xx SoCs.
@@ -92,7 +92,7 @@ config HW_RANDOM_IPROC_RNG200
tristate "Broadcom iProc/STB RNG200 support"
depends on ARCH_BCM_IPROC || ARCH_BCM2835 || ARCH_BRCMSTB
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the RNG200
hardware found on the Broadcom iProc and STB SoCs.
@@ -105,7 +105,7 @@ config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on X86_32 && PCI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on the AMD Geode LX.
@@ -118,7 +118,7 @@ config HW_RANDOM_N2RNG
tristate "Niagara2 Random Number Generator support"
depends on SPARC64
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Niagara2 cpus.
@@ -131,7 +131,7 @@ config HW_RANDOM_VIA
tristate "VIA HW Random Number Generator support"
depends on X86
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on VIA based motherboards.
@@ -144,7 +144,7 @@ config HW_RANDOM_IXP4XX
tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
depends on ARCH_IXP4XX
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Pseudo-Random
Number Generator hardware found on the Intel IXP45x/46x NPU.
@@ -157,7 +157,7 @@ config HW_RANDOM_OMAP
tristate "OMAP Random Number Generator support"
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS || ARCH_MVEBU
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on OMAP16xx, OMAP2/3/4/5, AM33xx/AM43xx
multimedia processors, and Marvell Armada 7k/8k SoCs.
@@ -171,7 +171,7 @@ config HW_RANDOM_OMAP3_ROM
tristate "OMAP3 ROM Random Number Generator support"
depends on ARCH_OMAP3
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on OMAP34xx processors.
@@ -184,7 +184,7 @@ config HW_RANDOM_OCTEON
tristate "Octeon Random Number Generator support"
depends on CAVIUM_OCTEON_SOC
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Octeon processors.
@@ -197,7 +197,7 @@ config HW_RANDOM_PASEMI
tristate "PA Semi HW Random Number Generator support"
depends on PPC_PASEMI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on PA Semi PWRficient SoCs.
@@ -209,7 +209,7 @@ config HW_RANDOM_PASEMI
config HW_RANDOM_VIRTIO
tristate "VirtIO Random Number Generator support"
depends on VIRTIO
- ---help---
+ help
This driver provides kernel-side support for the virtual Random Number
Generator hardware.
@@ -220,7 +220,7 @@ config HW_RANDOM_TX4939
tristate "TX4939 Random Number Generator support"
depends on SOC_TX4939
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on TX4939 SoC.
@@ -233,7 +233,7 @@ config HW_RANDOM_MXC_RNGA
tristate "Freescale i.MX RNGA Random Number Generator"
depends on SOC_IMX31
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Freescale i.MX processors.
@@ -247,7 +247,7 @@ config HW_RANDOM_IMX_RNGC
depends on HAS_IOMEM && HAVE_CLK
depends on SOC_IMX25 || COMPILE_TEST
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator Version C hardware found on some Freescale i.MX
processors. Version B is also supported by this driver.
@@ -261,7 +261,7 @@ config HW_RANDOM_NOMADIK
tristate "ST-Ericsson Nomadik Random Number Generator support"
depends on ARCH_NOMADIK
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on ST-Ericsson SoCs (8815 and 8500).
@@ -274,7 +274,7 @@ config HW_RANDOM_PSERIES
tristate "pSeries HW Random Number Generator support"
depends on PPC64 && IBMVIO
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on POWER7+ machines and above
@@ -287,7 +287,7 @@ config HW_RANDOM_POWERNV
tristate "PowerNV Random Number Generator support"
depends on PPC_POWERNV
default HW_RANDOM
- ---help---
+ help
This is the driver for Random Number Generator hardware found
in POWER7+ and above machines for PowerNV platform.
@@ -300,7 +300,7 @@ config HW_RANDOM_HISI
tristate "Hisilicon Random Number Generator support"
depends on HW_RANDOM && ARCH_HISI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Hisilicon Hip04 and Hip05 SoC.
@@ -325,7 +325,7 @@ config HW_RANDOM_HISI_V2
config HW_RANDOM_ST
tristate "ST Microelectronics HW Random Number Generator support"
depends on HW_RANDOM && ARCH_STI
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on STi series of SoCs.
@@ -336,7 +336,7 @@ config HW_RANDOM_XGENE
tristate "APM X-Gene True Random Number Generator (TRNG) support"
depends on HW_RANDOM && ARCH_XGENE
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on APM X-Gene SoC.
@@ -363,7 +363,7 @@ config HW_RANDOM_PIC32
tristate "Microchip PIC32 Random Number Generator support"
depends on HW_RANDOM && MACH_PIC32
default y
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on a PIC32.
@@ -377,7 +377,7 @@ config HW_RANDOM_MESON
depends on HW_RANDOM
depends on ARCH_MESON || COMPILE_TEST
default y
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Amlogic Meson SoCs.
@@ -390,7 +390,7 @@ config HW_RANDOM_CAVIUM
tristate "Cavium ThunderX Random Number Generator support"
depends on HW_RANDOM && PCI && (ARM64 || (COMPILE_TEST && 64BIT))
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Cavium SoCs.
@@ -404,7 +404,7 @@ config HW_RANDOM_MTK
depends on HW_RANDOM
depends on ARCH_MEDIATEK || COMPILE_TEST
default y
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Mediatek SoCs.
@@ -417,7 +417,7 @@ config HW_RANDOM_S390
tristate "S390 True Random Number Generator support"
depends on S390
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the True
Random Number Generator available as CPACF extension
on modern s390 hardware platforms.
@@ -431,7 +431,7 @@ config HW_RANDOM_EXYNOS
tristate "Samsung Exynos True Random Number Generator support"
depends on ARCH_EXYNOS || COMPILE_TEST
default HW_RANDOM
- ---help---
+ help
This driver provides support for the True Random Number
Generator available in Exynos SoCs.
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 7d583222e8fa..0fae33319d2e 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -39,7 +39,6 @@
#include <linux/numa.h>
#include <linux/refcount.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <linux/atomic.h>
#include <asm/tlbflush.h>
#include <asm/uncached.h>
@@ -65,7 +64,7 @@ enum mspec_page_type {
* This structure is shared by all vma's that are split off from the
* original vma when split_vma()'s are done.
*
- * The refcnt is incremented atomically because mm->mmap_sem does not
+ * The refcnt is incremented atomically because mm->mmap_lock does not
* protect in fork case where multiple tasks share the vma_data.
*/
struct vma_data {
diff --git a/drivers/char/random.c b/drivers/char/random.c
index a7cf6aa65908..2a41b21623ae 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2087,7 +2087,7 @@ static int proc_do_uuid(struct ctl_table *table, int write,
* Return entropy available scaled to integral bits
*/
static int proc_do_entropy(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+ void *buffer, size_t *lenp, loff_t *ppos)
{
struct ctl_table fake_table;
int entropy_count;
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index aacdeed93320..58b4c573d176 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -9,7 +9,7 @@ menuconfig TCG_TPM
imply SECURITYFS
select CRYPTO
select CRYPTO_HASH_INFO
- ---help---
+ help
If you have a TPM security chip in your system, which
implements the Trusted Computing Group's specification,
say Yes and it will be accessible from within Linux. For
@@ -31,7 +31,7 @@ config HW_RANDOM_TPM
bool "TPM HW Random Number Generator support"
depends on TCG_TPM && HW_RANDOM && !(TCG_TPM=y && HW_RANDOM=m)
default y
- ---help---
+ help
This setting exposes the TPM's Random Number Generator as a hwrng
device. This allows the kernel to collect randomness from the TPM at
boot, and provides the TPM randomines in /dev/hwrng.
@@ -40,7 +40,7 @@ config HW_RANDOM_TPM
config TCG_TIS_CORE
tristate
- ---help---
+ help
TCG TIS TPM core driver. It implements the TPM TCG TIS logic and hooks
into the TPM kernel APIs. Physical layers will register against it.
@@ -48,7 +48,7 @@ config TCG_TIS
tristate "TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface"
depends on X86 || OF
select TCG_TIS_CORE
- ---help---
+ help
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification (TPM1.2) or the TCG PTP FIFO
specification (TPM2.0) say Yes and it will be accessible from
@@ -59,7 +59,7 @@ config TCG_TIS_SPI
tristate "TPM Interface Specification 1.3 Interface / TPM 2.0 FIFO Interface - (SPI)"
depends on SPI
select TCG_TIS_CORE
- ---help---
+ help
If you have a TPM security chip which is connected to a regular,
non-tcg SPI master (i.e. most embedded platforms) that is compliant with the
TCG TIS 1.3 TPM specification (TPM1.2) or the TCG PTP FIFO
@@ -77,7 +77,7 @@ config TCG_TIS_SPI_CR50
config TCG_TIS_I2C_ATMEL
tristate "TPM Interface Specification 1.2 Interface (I2C - Atmel)"
depends on I2C
- ---help---
+ help
If you have an Atmel I2C TPM security chip say Yes and it will be
accessible from within Linux.
To compile this driver as a module, choose M here; the module will
@@ -86,7 +86,7 @@ config TCG_TIS_I2C_ATMEL
config TCG_TIS_I2C_INFINEON
tristate "TPM Interface Specification 1.2 Interface (I2C - Infineon)"
depends on I2C
- ---help---
+ help
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification and Infineon's I2C Protocol Stack
Specification 0.20 say Yes and it will be accessible from within
@@ -97,7 +97,7 @@ config TCG_TIS_I2C_INFINEON
config TCG_TIS_I2C_NUVOTON
tristate "TPM Interface Specification 1.2 Interface (I2C - Nuvoton)"
depends on I2C
- ---help---
+ help
If you have a TPM security chip with an I2C interface from
Nuvoton Technology Corp. say Yes and it will be accessible
from within Linux.
@@ -107,7 +107,7 @@ config TCG_TIS_I2C_NUVOTON
config TCG_NSC
tristate "National Semiconductor TPM Interface"
depends on X86
- ---help---
+ help
If you have a TPM security chip from National Semiconductor
say Yes and it will be accessible from within Linux. To
compile this driver as a module, choose M here; the module
@@ -116,7 +116,7 @@ config TCG_NSC
config TCG_ATMEL
tristate "Atmel TPM Interface"
depends on PPC64 || HAS_IOPORT_MAP
- ---help---
+ help
If you have a TPM security chip from Atmel say Yes and it
will be accessible from within Linux. To compile this driver
as a module, choose M here; the module will be called tpm_atmel.
@@ -124,7 +124,7 @@ config TCG_ATMEL
config TCG_INFINEON
tristate "Infineon Technologies TPM Interface"
depends on PNP
- ---help---
+ help
If you have a TPM security chip from Infineon Technologies
(either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it
will be accessible from within Linux.
@@ -136,7 +136,7 @@ config TCG_INFINEON
config TCG_IBMVTPM
tristate "IBM VTPM Interface"
depends on PPC_PSERIES
- ---help---
+ help
If you have IBM virtual TPM (VTPM) support say Yes and it
will be accessible from within Linux. To compile this driver
as a module, choose M here; the module will be called tpm_ibmvtpm.
@@ -145,7 +145,7 @@ config TCG_XEN
tristate "XEN TPM Interface"
depends on TCG_TPM && XEN
select XEN_XENBUS_FRONTEND
- ---help---
+ help
If you want to make TPM support available to a Xen user domain,
say Yes and it will be accessible from within Linux. See
the manpages for xl, xl.conf, and docs/misc/vtpm.txt in
@@ -156,7 +156,7 @@ config TCG_XEN
config TCG_CRB
tristate "TPM 2.0 CRB Interface"
depends on ACPI
- ---help---
+ help
If you have a TPM security chip that is compliant with the
TCG CRB 2.0 TPM specification say Yes and it will be accessible
from within Linux. To compile this driver as a module, choose
@@ -165,7 +165,7 @@ config TCG_CRB
config TCG_VTPM_PROXY
tristate "VTPM Proxy Interface"
depends on TCG_TPM
- ---help---
+ help
This driver proxies for an emulated TPM (vTPM) running in userspace.
A device /dev/vtpmx is provided that creates a device pair
/dev/vtpmX and a server-side file descriptor on which the vTPM
diff --git a/drivers/char/tpm/st33zp24/Kconfig b/drivers/char/tpm/st33zp24/Kconfig
index e582145076dc..601c2ae5bfcb 100644
--- a/drivers/char/tpm/st33zp24/Kconfig
+++ b/drivers/char/tpm/st33zp24/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config TCG_TIS_ST33ZP24
tristate
- ---help---
+ help
STMicroelectronics ST33ZP24 core driver. It implements the core
TPM1.2 logic and hooks into the TPM kernel APIs. Physical layers will
register against it.
@@ -13,7 +13,7 @@ config TCG_TIS_ST33ZP24_I2C
tristate "STMicroelectronics TPM Interface Specification 1.2 Interface (I2C)"
depends on I2C
select TCG_TIS_ST33ZP24
- ---help---
+ help
This module adds support for the STMicroelectronics TPM security chip
ST33ZP24 with i2c interface.
To compile this driver as a module, choose M here; the module will be
@@ -23,7 +23,7 @@ config TCG_TIS_ST33ZP24_SPI
tristate "STMicroelectronics TPM Interface Specification 1.2 Interface (SPI)"
depends on SPI
select TCG_TIS_ST33ZP24
- ---help---
+ help
This module adds support for the STMicroelectronics TPM security chip
ST33ZP24 with spi interface.
To compile this driver as a module, choose M here; the module will be
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bcb257baed06..69934c0c3dd8 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -1,5 +1,11 @@
# SPDX-License-Identifier: GPL-2.0
+config HAVE_CLK
+ bool
+ help
+ The <linux/clk.h> calls support software clock gating and
+ thus are a key power management tool on many systems.
+
config CLKDEV_LOOKUP
bool
select HAVE_CLK
@@ -7,26 +13,35 @@ config CLKDEV_LOOKUP
config HAVE_CLK_PREPARE
bool
-config COMMON_CLK
+config HAVE_LEGACY_CLK # TODO: Remove once all legacy users are migrated
bool
+ select HAVE_CLK
+ help
+ Select this option when the clock API in <linux/clk.h> is implemented
+ by platform/architecture code. This method is deprecated. Modern
+ code should select COMMON_CLK instead and not define a custom
+ 'struct clk'.
+
+menuconfig COMMON_CLK
+ bool "Common Clock Framework"
+ depends on !HAVE_LEGACY_CLK
select HAVE_CLK_PREPARE
select CLKDEV_LOOKUP
select SRCU
select RATIONAL
- ---help---
+ help
The common clock framework is a single definition of struct
clk, useful across many platforms, as well as an
implementation of the clock API in include/linux/clk.h.
Architectures utilizing the common struct clk should select
this option.
-menu "Common Clock Framework"
- depends on COMMON_CLK
+if COMMON_CLK
config COMMON_CLK_WM831X
tristate "Clock driver for WM831x/2x PMICs"
depends on MFD_WM831X
- ---help---
+ help
Supports the clocking subsystem of the WM831x/2x series of
PMICs from Wolfson Microelectronics.
@@ -35,14 +50,14 @@ source "drivers/clk/versatile/Kconfig"
config CLK_HSDK
bool "PLL Driver for HSDK platform"
depends on OF || COMPILE_TEST
- ---help---
+ help
This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
control.
config COMMON_CLK_MAX77686
tristate "Clock driver for Maxim 77620/77686/77802 MFD"
depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
- ---help---
+ help
This driver supports Maxim 77620/77686/77802 crystal oscillator
clock.
@@ -55,7 +70,7 @@ config COMMON_CLK_MAX9485
config COMMON_CLK_RK808
tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
depends on MFD_RK808
- ---help---
+ help
This driver supports RK805, RK809 and RK817, RK808 and RK818 crystal oscillator clock.
These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
Clkout1 is always on, Clkout2 can off by control register.
@@ -65,7 +80,7 @@ config COMMON_CLK_HI655X
depends on (MFD_HI655X_PMIC || COMPILE_TEST)
depends on REGMAP
default MFD_HI655X_PMIC
- ---help---
+ help
This driver supports the hi655x PMIC clock. This
multi-function device has one fixed-rate oscillator, clocked
at 32KHz.
@@ -73,7 +88,7 @@ config COMMON_CLK_HI655X
config COMMON_CLK_SCMI
tristate "Clock driver controlled via SCMI interface"
depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
- ---help---
+ help
This driver provides support for clocks that are controlled
by firmware that implements the SCMI interface.
@@ -83,7 +98,7 @@ config COMMON_CLK_SCMI
config COMMON_CLK_SCPI
tristate "Clock driver controlled via SCPI interface"
depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
- ---help---
+ help
This driver provides support for clocks that are controlled
by firmware that implements the SCPI interface.
@@ -106,7 +121,7 @@ config COMMON_CLK_SI5351
depends on I2C
select REGMAP_I2C
select RATIONAL
- ---help---
+ help
This driver supports Silicon Labs 5351A/B/C programmable clock
generators.
@@ -148,7 +163,7 @@ config COMMON_CLK_CDCE706
depends on I2C
select REGMAP_I2C
select RATIONAL
- ---help---
+ help
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
config COMMON_CLK_CDCE925
@@ -191,7 +206,7 @@ config COMMON_CLK_GEMINI
depends on ARCH_GEMINI || COMPILE_TEST
select MFD_SYSCON
select RESET_CONTROLLER
- ---help---
+ help
This driver supports the SoC clocks on the Cortina Systems Gemini
platform, also known as SL3516 or CS3516.
@@ -201,7 +216,7 @@ config COMMON_CLK_ASPEED
default ARCH_ASPEED
select MFD_SYSCON
select RESET_CONTROLLER
- ---help---
+ help
This driver supports the SoC clocks on the Aspeed BMC platforms.
The G4 and G5 series, including the ast2400 and ast2500, are supported
@@ -210,7 +225,7 @@ config COMMON_CLK_ASPEED
config COMMON_CLK_S2MPS11
tristate "Clock driver for S2MPS1X/S5M8767 MFD"
depends on MFD_SEC_CORE || COMPILE_TEST
- ---help---
+ help
This driver supports S2MPS11/S2MPS14/S5M8767 crystal oscillator
clock. These multi-function devices have two (S2MPS14) or three
(S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.
@@ -218,7 +233,7 @@ config COMMON_CLK_S2MPS11
config CLK_TWL6040
tristate "External McPDM functional clock from twl6040"
depends on TWL6040_CORE
- ---help---
+ help
Enable the external functional clock support on OMAP4+ platforms for
McPDM. McPDM module is using the external bit clock on the McPDM bus
as functional clock.
@@ -233,7 +248,7 @@ config COMMON_CLK_AXI_CLKGEN
config CLK_QORIQ
bool "Clock driver for Freescale QorIQ platforms"
depends on (PPC_E500MC || ARM || ARM64 || COMPILE_TEST) && OF
- ---help---
+ help
This adds the clock driver support for Freescale QorIQ platforms
using common clock framework.
@@ -251,8 +266,8 @@ config COMMON_CLK_XGENE
bool "Clock driver for APM XGene SoC"
default ARCH_XGENE
depends on ARM64 || COMPILE_TEST
- ---help---
- Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
+ help
+ Support for the APM X-Gene SoC reference, PLL, and device clocks.
config COMMON_CLK_LOCHNAGAR
tristate "Cirrus Logic Lochnagar clock driver"
@@ -265,26 +280,26 @@ config COMMON_CLK_NXP
def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
select REGMAP_MMIO if ARCH_LPC32XX
select MFD_SYSCON if ARCH_LPC18XX
- ---help---
+ help
Support for clock providers on NXP platforms.
config COMMON_CLK_PALMAS
tristate "Clock driver for TI Palmas devices"
depends on MFD_PALMAS
- ---help---
+ help
This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO
using common clock framework.
config COMMON_CLK_PWM
tristate "Clock driver for PWMs used as clock outputs"
depends on PWM
- ---help---
+ help
Adapter driver so that any PWM output can be (mis)used as clock signal
at 50% duty cycle.
config COMMON_CLK_PXA
def_bool COMMON_CLK && ARCH_PXA
- ---help---
+ help
Support for the Marvell PXA SoC.
config COMMON_CLK_PIC32
@@ -294,7 +309,7 @@ config COMMON_CLK_OXNAS
bool "Clock driver for the OXNAS SoC Family"
depends on ARCH_OXNAS || COMPILE_TEST
select MFD_SYSCON
- ---help---
+ help
Support for the OXNAS SoC Family clocks.
config COMMON_CLK_VC5
@@ -326,6 +341,12 @@ config COMMON_CLK_MMP2
help
Support for Marvell MMP2 and MMP3 SoC clocks
+config COMMON_CLK_MMP2_AUDIO
+ tristate "Clock driver for MMP2 Audio subsystem"
+ depends on COMMON_CLK_MMP2 || COMPILE_TEST
+ help
+ This driver supports clocks for Audio subsystem on MMP2 SoC.
+
config COMMON_CLK_BD718XX
tristate "Clock driver for 32K clk gates on ROHM PMICs"
depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828
@@ -341,6 +362,7 @@ config COMMON_CLK_FIXED_MMIO
source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
+source "drivers/clk/baikal-t1/Kconfig"
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/imgtec/Kconfig"
@@ -360,6 +382,7 @@ source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
+source "drivers/clk/x86/Kconfig"
source "drivers/clk/zynqmp/Kconfig"
-endmenu
+endif
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1b431110b6f5..ca9af11d3391 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -75,6 +75,7 @@ obj-y += analogbits/
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
obj-$(CONFIG_ARCH_ARTPEC) += axis/
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
+obj-$(CONFIG_CLK_BAIKAL_T1) += baikal-t1/
obj-y += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
@@ -104,10 +105,11 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
obj-$(CONFIG_CLK_SIFIVE) += sifive/
obj-$(CONFIG_ARCH_SIRF) += sirf/
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
+obj-$(CONFIG_ARCH_AGILEX) += socfpga/
+obj-$(CONFIG_ARCH_STRATIX10) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-y += sprd/
obj-$(CONFIG_ARCH_STI) += st/
-obj-$(CONFIG_ARCH_STRATIX10) += socfpga/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
index c44a431b6c97..38bdb4981315 100644
--- a/drivers/clk/at91/at91rm9200.c
+++ b/drivers/clk/at91/at91rm9200.c
@@ -98,9 +98,9 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ at91rm9200_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
nck(at91rm9200_systemck),
- nck(at91rm9200_periphck), 0);
+ nck(at91rm9200_periphck), 0, 4);
if (!at91rm9200_pmc)
return;
@@ -123,12 +123,16 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ at91rm9200_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
&at91rm9200_pll_layout,
&rm9200_pll_characteristics);
if (IS_ERR(hw))
goto err_free;
+ at91rm9200_pmc->chws[PMC_PLLBCK] = hw;
+
parent_names[0] = slowxtal_name;
parent_names[1] = "mainck";
parent_names[2] = "pllack";
@@ -159,6 +163,8 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
&at91rm9200_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ at91rm9200_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
@@ -187,7 +193,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(at91rm9200_pmc);
+ kfree(at91rm9200_pmc);
}
/*
* While the TCB can be used as the clocksource, the system timer is most likely
diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
index a9d4234758d7..6d0723aa8b13 100644
--- a/drivers/clk/at91/at91sam9260.c
+++ b/drivers/clk/at91/at91sam9260.c
@@ -352,9 +352,10 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
if (IS_ERR(regmap))
return;
- at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ at91sam9260_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
ndck(data->sck, data->num_sck),
- ndck(data->pck, data->num_pck), 0);
+ ndck(data->pck, data->num_pck),
+ 0, data->num_progck);
if (!at91sam9260_pmc)
return;
@@ -398,12 +399,16 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
if (IS_ERR(hw))
goto err_free;
+ at91sam9260_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
data->pllb_layout,
data->pllb_characteristics);
if (IS_ERR(hw))
goto err_free;
+ at91sam9260_pmc->chws[PMC_PLLBCK] = hw;
+
parent_names[0] = slck_name;
parent_names[1] = "mainck";
parent_names[2] = "pllack";
@@ -434,6 +439,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
&at91rm9200_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ at91sam9260_pmc->pchws[i] = hw;
}
for (i = 0; i < data->num_sck; i++) {
@@ -462,7 +469,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
return;
err_free:
- pmc_data_free(at91sam9260_pmc);
+ kfree(at91sam9260_pmc);
}
static void __init at91sam9260_pmc_setup(struct device_node *np)
diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c
index 38a7d2d2df0c..9873b583c260 100644
--- a/drivers/clk/at91/at91sam9g45.c
+++ b/drivers/clk/at91/at91sam9g45.c
@@ -115,9 +115,9 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ at91sam9g45_pmc = pmc_data_allocate(PMC_PLLACK + 1,
nck(at91sam9g45_systemck),
- nck(at91sam9g45_periphck), 0);
+ nck(at91sam9g45_periphck), 0, 2);
if (!at91sam9g45_pmc)
return;
@@ -143,6 +143,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ at91sam9g45_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
if (IS_ERR(hw))
goto err_free;
@@ -182,6 +184,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
&at91sam9g45_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ at91sam9g45_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
@@ -210,7 +214,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(at91sam9g45_pmc);
+ kfree(at91sam9g45_pmc);
}
/*
* The TCB is used as the clocksource so its clock is needed early. This means
diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c
index 8bb39d2ba84b..630dc5d87171 100644
--- a/drivers/clk/at91/at91sam9n12.c
+++ b/drivers/clk/at91/at91sam9n12.c
@@ -128,8 +128,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1,
- nck(at91sam9n12_systemck), 31, 0);
+ at91sam9n12_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
+ nck(at91sam9n12_systemck), 31, 0, 2);
if (!at91sam9n12_pmc)
return;
@@ -162,11 +162,15 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ at91sam9n12_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
&at91rm9200_pll_layout, &pllb_characteristics);
if (IS_ERR(hw))
goto err_free;
+ at91sam9n12_pmc->chws[PMC_PLLBCK] = hw;
+
parent_names[0] = slck_name;
parent_names[1] = "mainck";
parent_names[2] = "plladivck";
@@ -198,6 +202,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
&at91sam9x5_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ at91sam9n12_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
@@ -228,7 +234,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(at91sam9n12_pmc);
+ kfree(at91sam9n12_pmc);
}
/*
* The TCB is used as the clocksource so its clock is needed early. This means
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
index 77fe83a73bf4..0d1cc44b056f 100644
--- a/drivers/clk/at91/at91sam9rl.c
+++ b/drivers/clk/at91/at91sam9rl.c
@@ -87,9 +87,9 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ at91sam9rl_pmc = pmc_data_allocate(PMC_PLLACK + 1,
nck(at91sam9rl_systemck),
- nck(at91sam9rl_periphck), 0);
+ nck(at91sam9rl_periphck), 0, 2);
if (!at91sam9rl_pmc)
return;
@@ -105,6 +105,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ at91sam9rl_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
if (IS_ERR(hw))
goto err_free;
@@ -138,6 +140,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
&at91rm9200_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ at91sam9rl_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
@@ -166,6 +170,6 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(at91sam9rl_pmc);
+ kfree(at91sam9rl_pmc);
}
CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
index 086cf0b4955c..0ce3da080287 100644
--- a/drivers/clk/at91/at91sam9x5.c
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -150,8 +150,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
if (IS_ERR(regmap))
return;
- at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
- nck(at91sam9x5_systemck), 31, 0);
+ at91sam9x5_pmc = pmc_data_allocate(PMC_PLLACK + 1,
+ nck(at91sam9x5_systemck), 31, 0, 2);
if (!at91sam9x5_pmc)
return;
@@ -184,6 +184,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
if (IS_ERR(hw))
goto err_free;
+ at91sam9x5_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
if (IS_ERR(hw))
goto err_free;
@@ -227,6 +229,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
&at91sam9x5_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ at91sam9x5_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
@@ -278,7 +282,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
return;
err_free:
- pmc_data_free(at91sam9x5_pmc);
+ kfree(at91sam9x5_pmc);
}
static void __init at91sam9g15_pmc_setup(struct device_node *np)
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index b71515acdec1..20ee9dccee78 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -67,6 +67,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
if (idx < pmc_data->ngck)
return pmc_data->ghws[idx];
break;
+ case PMC_TYPE_PROGRAMMABLE:
+ if (idx < pmc_data->npck)
+ return pmc_data->pchws[idx];
+ break;
default:
break;
}
@@ -76,48 +80,34 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
return ERR_PTR(-EINVAL);
}
-void pmc_data_free(struct pmc_data *pmc_data)
-{
- kfree(pmc_data->chws);
- kfree(pmc_data->shws);
- kfree(pmc_data->phws);
- kfree(pmc_data->ghws);
-}
-
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
- unsigned int nperiph, unsigned int ngck)
+ unsigned int nperiph, unsigned int ngck,
+ unsigned int npck)
{
- struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
+ unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
+ struct pmc_data *pmc_data;
+ pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
+ GFP_KERNEL);
if (!pmc_data)
return NULL;
pmc_data->ncore = ncore;
- pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
- if (!pmc_data->chws)
- goto err;
+ pmc_data->chws = pmc_data->hwtable;
pmc_data->nsystem = nsystem;
- pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
- if (!pmc_data->shws)
- goto err;
+ pmc_data->shws = pmc_data->chws + ncore;
pmc_data->nperiph = nperiph;
- pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
- if (!pmc_data->phws)
- goto err;
+ pmc_data->phws = pmc_data->shws + nsystem;
pmc_data->ngck = ngck;
- pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
- if (!pmc_data->ghws)
- goto err;
+ pmc_data->ghws = pmc_data->phws + nperiph;
- return pmc_data;
-
-err:
- pmc_data_free(pmc_data);
+ pmc_data->npck = npck;
+ pmc_data->pchws = pmc_data->ghws + ngck;
- return NULL;
+ return pmc_data;
}
#ifdef CONFIG_PM
@@ -274,8 +264,11 @@ static int __init pmc_register_ops(void)
struct device_node *np;
np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
+ if (!np)
+ return -ENODEV;
pmcreg = device_node_to_regmap(np);
+ of_node_put(np);
if (IS_ERR(pmcreg))
return PTR_ERR(pmcreg);
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 9b8db9cdcda5..df616f2937e7 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -24,6 +24,10 @@ struct pmc_data {
struct clk_hw **phws;
unsigned int ngck;
struct clk_hw **ghws;
+ unsigned int npck;
+ struct clk_hw **pchws;
+
+ struct clk_hw *hwtable[];
};
struct clk_range {
@@ -94,8 +98,8 @@ struct clk_pcr_layout {
#define ndck(a, s) (a[s - 1].id + 1)
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
- unsigned int nperiph, unsigned int ngck);
-void pmc_data_free(struct pmc_data *pmc_data);
+ unsigned int nperiph, unsigned int ngck,
+ unsigned int npck);
int of_at91_get_clk_range(struct device_node *np, const char *propname,
struct clk_range *range);
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index cc19e8fb83be..3e20aa68259f 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -182,10 +182,10 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ sam9x60_pmc = pmc_data_allocate(PMC_PLLACK + 1,
nck(sam9x60_systemck),
nck(sam9x60_periphck),
- nck(sam9x60_gck));
+ nck(sam9x60_gck), 8);
if (!sam9x60_pmc)
return;
@@ -214,6 +214,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ sam9x60_pmc->chws[PMC_PLLACK] = hw;
+
hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck",
"main_osc", 1, &upll_characteristics);
if (IS_ERR(hw))
@@ -255,6 +257,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
&sam9x60_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ sam9x60_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
@@ -299,7 +303,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(sam9x60_pmc);
+ kfree(sam9x60_pmc);
}
/* Some clks are used for a clocksource */
CLK_OF_DECLARE(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index ff7e3f727082..d69421d71daf 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -89,6 +89,7 @@ static const struct {
{ .n = "i2s1_clk", .id = 55, .r = { .min = 0, .max = 83000000 }, },
{ .n = "can0_clk", .id = 56, .r = { .min = 0, .max = 83000000 }, },
{ .n = "can1_clk", .id = 57, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "ptc_clk", .id = 58, .r = { .min = 0, .max = 83000000 }, },
{ .n = "classd_clk", .id = 59, .r = { .min = 0, .max = 83000000 }, },
};
@@ -166,10 +167,10 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
+ sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPLLCK + 1,
nck(sama5d2_systemck),
nck(sama5d2_periph32ck),
- nck(sama5d2_gck));
+ nck(sama5d2_gck), 3);
if (!sama5d2_pmc)
return;
@@ -202,6 +203,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ sama5d2_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
"mainck");
if (IS_ERR(hw))
@@ -217,6 +220,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ sama5d2_pmc->chws[PMC_AUDIOPLLCK] = hw;
+
regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
if (IS_ERR(regmap_sfr))
regmap_sfr = NULL;
@@ -267,6 +272,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
&sama5d2_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ sama5d2_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
@@ -350,6 +357,6 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(sama5d2_pmc);
+ kfree(sama5d2_pmc);
}
CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c
index 88506f909c08..5e4e44dd4c37 100644
--- a/drivers/clk/at91/sama5d3.c
+++ b/drivers/clk/at91/sama5d3.c
@@ -125,9 +125,9 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ sama5d3_pmc = pmc_data_allocate(PMC_PLLACK + 1,
nck(sama5d3_systemck),
- nck(sama5d3_periphck), 0);
+ nck(sama5d3_periphck), 0, 3);
if (!sama5d3_pmc)
return;
@@ -158,6 +158,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ sama5d3_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
if (IS_ERR(hw))
goto err_free;
@@ -201,6 +203,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
&at91sam9x5_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ sama5d3_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
@@ -231,7 +235,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(sama5d3_pmc);
+ kfree(sama5d3_pmc);
}
/*
* The TCB is used as the clocksource so its clock is needed early. This means
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
index a6dee4a3b6e4..662ff5fa6e98 100644
--- a/drivers/clk/at91/sama5d4.c
+++ b/drivers/clk/at91/sama5d4.c
@@ -140,9 +140,9 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
if (IS_ERR(regmap))
return;
- sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
+ sama5d4_pmc = pmc_data_allocate(PMC_PLLACK + 1,
nck(sama5d4_systemck),
- nck(sama5d4_periph32ck), 0);
+ nck(sama5d4_periph32ck), 0, 3);
if (!sama5d4_pmc)
return;
@@ -173,6 +173,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ sama5d4_pmc->chws[PMC_PLLACK] = hw;
+
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
if (IS_ERR(hw))
goto err_free;
@@ -224,6 +226,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
&at91sam9x5_programmable_layout);
if (IS_ERR(hw))
goto err_free;
+
+ sama5d4_pmc->pchws[i] = hw;
}
for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
@@ -267,6 +271,6 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
return;
err_free:
- pmc_data_free(sama5d4_pmc);
+ kfree(sama5d4_pmc);
}
CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
diff --git a/drivers/clk/baikal-t1/Kconfig b/drivers/clk/baikal-t1/Kconfig
new file mode 100644
index 000000000000..03102f1094bc
--- /dev/null
+++ b/drivers/clk/baikal-t1/Kconfig
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config CLK_BAIKAL_T1
+ bool "Baikal-T1 Clocks Control Unit interface"
+ depends on (MIPS_BAIKAL_T1 && OF) || COMPILE_TEST
+ default MIPS_BAIKAL_T1
+ help
+ Clocks Control Unit is the core of Baikal-T1 SoC System Controller
+ responsible for the chip subsystems clocking and resetting. It
+ consists of multiple global clock domains, which can be reset by
+ means of the CCU control registers. These domains and devices placed
+ in them are fed with clocks generated by a hierarchy of PLLs,
+ configurable and fixed clock dividers. Enable this option to be able
+ to select Baikal-T1 CCU PLLs and Dividers drivers.
+
+if CLK_BAIKAL_T1
+
+config CLK_BT1_CCU_PLL
+ bool "Baikal-T1 CCU PLLs support"
+ select MFD_SYSCON
+ default MIPS_BAIKAL_T1
+ help
+ Enable this to support the PLLs embedded into the Baikal-T1 SoC
+ System Controller. These are five PLLs placed at the root of the
+ clocks hierarchy, right after an external reference oscillator
+ (normally of 25MHz). They are used to generate high frequency
+ signals, which are either directly wired to the consumers (like
+ CPUs, DDR, etc.) or passed over the clock dividers to be only
+ then used as an individual reference clock of a target device.
+
+config CLK_BT1_CCU_DIV
+ bool "Baikal-T1 CCU Dividers support"
+ select RESET_CONTROLLER
+ select MFD_SYSCON
+ default MIPS_BAIKAL_T1
+ help
+ Enable this to support the CCU dividers used to distribute clocks
+ between AXI-bus and system devices coming from CCU PLLs of Baikal-T1
+ SoC. CCU dividers can be either configurable or with fixed divider,
+ either gateable or ungateable. Some of the CCU dividers can be as well
+ used to reset the domains they're supplying clock to.
+
+endif
diff --git a/drivers/clk/baikal-t1/Makefile b/drivers/clk/baikal-t1/Makefile
new file mode 100644
index 000000000000..b3b9590b95ed
--- /dev/null
+++ b/drivers/clk/baikal-t1/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_CLK_BT1_CCU_PLL) += ccu-pll.o clk-ccu-pll.o
+obj-$(CONFIG_CLK_BT1_CCU_DIV) += ccu-div.o clk-ccu-div.o
diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c
new file mode 100644
index 000000000000..4062092d67f9
--- /dev/null
+++ b/drivers/clk/baikal-t1/ccu-div.c
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
+ *
+ * Baikal-T1 CCU Dividers interface driver
+ */
+
+#define pr_fmt(fmt) "bt1-ccu-div: " fmt
+
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/time64.h>
+#include <linux/debugfs.h>
+
+#include "ccu-div.h"
+
+#define CCU_DIV_CTL 0x00
+#define CCU_DIV_CTL_EN BIT(0)
+#define CCU_DIV_CTL_RST BIT(1)
+#define CCU_DIV_CTL_SET_CLKDIV BIT(2)
+#define CCU_DIV_CTL_CLKDIV_FLD 4
+#define CCU_DIV_CTL_CLKDIV_MASK(_width) \
+ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
+#define CCU_DIV_CTL_LOCK_SHIFTED BIT(27)
+#define CCU_DIV_CTL_LOCK_NORMAL BIT(31)
+
+#define CCU_DIV_RST_DELAY_US 1
+#define CCU_DIV_LOCK_CHECK_RETRIES 50
+
+#define CCU_DIV_CLKDIV_MIN 0
+#define CCU_DIV_CLKDIV_MAX(_mask) \
+ ((_mask) >> CCU_DIV_CTL_CLKDIV_FLD)
+
+/*
+ * Use the next two methods until there are generic field setter and
+ * getter available with non-constant mask support.
+ */
+static inline u32 ccu_div_get(u32 mask, u32 val)
+{
+ return (val & mask) >> CCU_DIV_CTL_CLKDIV_FLD;
+}
+
+static inline u32 ccu_div_prep(u32 mask, u32 val)
+{
+ return (val << CCU_DIV_CTL_CLKDIV_FLD) & mask;
+}
+
+static inline unsigned long ccu_div_lock_delay_ns(unsigned long ref_clk,
+ unsigned long div)
+{
+ u64 ns = 4ULL * (div ?: 1) * NSEC_PER_SEC;
+
+ do_div(ns, ref_clk);
+
+ return ns;
+}
+
+static inline unsigned long ccu_div_calc_freq(unsigned long ref_clk,
+ unsigned long div)
+{
+ return ref_clk / (div ?: 1);
+}
+
+static int ccu_div_var_update_clkdiv(struct ccu_div *div,
+ unsigned long parent_rate,
+ unsigned long divider)
+{
+ unsigned long nd;
+ u32 val = 0;
+ u32 lock;
+ int count;
+
+ nd = ccu_div_lock_delay_ns(parent_rate, divider);
+
+ if (div->features & CCU_DIV_LOCK_SHIFTED)
+ lock = CCU_DIV_CTL_LOCK_SHIFTED;
+ else
+ lock = CCU_DIV_CTL_LOCK_NORMAL;
+
+ regmap_update_bits(div->sys_regs, div->reg_ctl,
+ CCU_DIV_CTL_SET_CLKDIV, CCU_DIV_CTL_SET_CLKDIV);
+
+ /*
+ * Until there is nsec-version of readl_poll_timeout() is available
+ * we have to implement the next polling loop.
+ */
+ count = CCU_DIV_LOCK_CHECK_RETRIES;
+ do {
+ ndelay(nd);
+ regmap_read(div->sys_regs, div->reg_ctl, &val);
+ if (val & lock)
+ return 0;
+ } while (--count);
+
+ return -ETIMEDOUT;
+}
+
+static int ccu_div_var_enable(struct clk_hw *hw)
+{
+ struct clk_hw *parent_hw = clk_hw_get_parent(hw);
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long flags;
+ u32 val = 0;
+ int ret;
+
+ if (!parent_hw) {
+ pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ regmap_read(div->sys_regs, div->reg_ctl, &val);
+ if (val & CCU_DIV_CTL_EN)
+ return 0;
+
+ spin_lock_irqsave(&div->lock, flags);
+ ret = ccu_div_var_update_clkdiv(div, clk_hw_get_rate(parent_hw),
+ ccu_div_get(div->mask, val));
+ if (!ret)
+ regmap_update_bits(div->sys_regs, div->reg_ctl,
+ CCU_DIV_CTL_EN, CCU_DIV_CTL_EN);
+ spin_unlock_irqrestore(&div->lock, flags);
+ if (ret)
+ pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw));
+
+ return ret;
+}
+
+static int ccu_div_gate_enable(struct clk_hw *hw)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl,
+ CCU_DIV_CTL_EN, CCU_DIV_CTL_EN);
+ spin_unlock_irqrestore(&div->lock, flags);
+
+ return 0;
+}
+
+static void ccu_div_gate_disable(struct clk_hw *hw)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl, CCU_DIV_CTL_EN, 0);
+ spin_unlock_irqrestore(&div->lock, flags);
+}
+
+static int ccu_div_gate_is_enabled(struct clk_hw *hw)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ u32 val = 0;
+
+ regmap_read(div->sys_regs, div->reg_ctl, &val);
+
+ return !!(val & CCU_DIV_CTL_EN);
+}
+
+static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long divider;
+ u32 val = 0;
+
+ regmap_read(div->sys_regs, div->reg_ctl, &val);
+ divider = ccu_div_get(div->mask, val);
+
+ return ccu_div_calc_freq(parent_rate, divider);
+}
+
+static inline unsigned long ccu_div_var_calc_divider(unsigned long rate,
+ unsigned long parent_rate,
+ unsigned int mask)
+{
+ unsigned long divider;
+
+ divider = parent_rate / rate;
+ return clamp_t(unsigned long, divider, CCU_DIV_CLKDIV_MIN,
+ CCU_DIV_CLKDIV_MAX(mask));
+}
+
+static long ccu_div_var_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long divider;
+
+ divider = ccu_div_var_calc_divider(rate, *parent_rate, div->mask);
+
+ return ccu_div_calc_freq(*parent_rate, divider);
+}
+
+/*
+ * This method is used for the clock divider blocks, which support the
+ * on-the-fly rate change. So due to lacking the EN bit functionality
+ * they can't be gated before the rate adjustment.
+ */
+static int ccu_div_var_set_rate_slow(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long flags, divider;
+ u32 val;
+ int ret;
+
+ divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask);
+ if (divider == 1 && div->features & CCU_DIV_SKIP_ONE) {
+ divider = 0;
+ } else if (div->features & CCU_DIV_SKIP_ONE_TO_THREE) {
+ if (divider == 1 || divider == 2)
+ divider = 0;
+ else if (divider == 3)
+ divider = 4;
+ }
+
+ val = ccu_div_prep(div->mask, divider);
+
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, val);
+ ret = ccu_div_var_update_clkdiv(div, parent_rate, divider);
+ spin_unlock_irqrestore(&div->lock, flags);
+ if (ret)
+ pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw));
+
+ return ret;
+}
+
+/*
+ * This method is used for the clock divider blocks, which don't support
+ * the on-the-fly rate change.
+ */
+static int ccu_div_var_set_rate_fast(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ unsigned long flags, divider;
+ u32 val;
+
+ divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask);
+ val = ccu_div_prep(div->mask, divider);
+
+ /*
+ * Also disable the clock divider block if it was enabled by default
+ * or by the bootloader.
+ */
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl,
+ div->mask | CCU_DIV_CTL_EN, val);
+ spin_unlock_irqrestore(&div->lock, flags);
+
+ return 0;
+}
+
+static unsigned long ccu_div_fixed_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+
+ return ccu_div_calc_freq(parent_rate, div->divider);
+}
+
+static long ccu_div_fixed_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+
+ return ccu_div_calc_freq(*parent_rate, div->divider);
+}
+
+static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ return 0;
+}
+
+int ccu_div_reset_domain(struct ccu_div *div)
+{
+ unsigned long flags;
+
+ if (!div || !(div->features & CCU_DIV_RESET_DOMAIN))
+ return -EINVAL;
+
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl,
+ CCU_DIV_CTL_RST, CCU_DIV_CTL_RST);
+ spin_unlock_irqrestore(&div->lock, flags);
+
+ /* The next delay must be enough to cover all the resets. */
+ udelay(CCU_DIV_RST_DELAY_US);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+struct ccu_div_dbgfs_bit {
+ struct ccu_div *div;
+ const char *name;
+ u32 mask;
+};
+
+#define CCU_DIV_DBGFS_BIT_ATTR(_name, _mask) { \
+ .name = _name, \
+ .mask = _mask \
+ }
+
+static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
+ CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
+ CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
+ CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
+ CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
+};
+
+#define CCU_DIV_DBGFS_BIT_NUM ARRAY_SIZE(ccu_div_bits)
+
+/*
+ * It can be dangerous to change the Divider settings behind clock framework
+ * back, therefore we don't provide any kernel config based compile time option
+ * for this feature to enable.
+ */
+#undef CCU_DIV_ALLOW_WRITE_DEBUGFS
+#ifdef CCU_DIV_ALLOW_WRITE_DEBUGFS
+
+static int ccu_div_dbgfs_bit_set(void *priv, u64 val)
+{
+ const struct ccu_div_dbgfs_bit *bit = priv;
+ struct ccu_div *div = bit->div;
+ unsigned long flags;
+
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl,
+ bit->mask, val ? bit->mask : 0);
+ spin_unlock_irqrestore(&div->lock, flags);
+
+ return 0;
+}
+
+static int ccu_div_dbgfs_var_clkdiv_set(void *priv, u64 val)
+{
+ struct ccu_div *div = priv;
+ unsigned long flags;
+ u32 data;
+
+ val = clamp_t(u64, val, CCU_DIV_CLKDIV_MIN,
+ CCU_DIV_CLKDIV_MAX(div->mask));
+ data = ccu_div_prep(div->mask, val);
+
+ spin_lock_irqsave(&div->lock, flags);
+ regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, data);
+ spin_unlock_irqrestore(&div->lock, flags);
+
+ return 0;
+}
+
+#define ccu_div_dbgfs_mode 0644
+
+#else /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */
+
+#define ccu_div_dbgfs_bit_set NULL
+#define ccu_div_dbgfs_var_clkdiv_set NULL
+#define ccu_div_dbgfs_mode 0444
+
+#endif /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */
+
+static int ccu_div_dbgfs_bit_get(void *priv, u64 *val)
+{
+ const struct ccu_div_dbgfs_bit *bit = priv;
+ struct ccu_div *div = bit->div;
+ u32 data = 0;
+
+ regmap_read(div->sys_regs, div->reg_ctl, &data);
+ *val = !!(data & bit->mask);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_bit_fops,
+ ccu_div_dbgfs_bit_get, ccu_div_dbgfs_bit_set, "%llu\n");
+
+static int ccu_div_dbgfs_var_clkdiv_get(void *priv, u64 *val)
+{
+ struct ccu_div *div = priv;
+ u32 data = 0;
+
+ regmap_read(div->sys_regs, div->reg_ctl, &data);
+ *val = ccu_div_get(div->mask, data);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_var_clkdiv_fops,
+ ccu_div_dbgfs_var_clkdiv_get, ccu_div_dbgfs_var_clkdiv_set, "%llu\n");
+
+static int ccu_div_dbgfs_fixed_clkdiv_get(void *priv, u64 *val)
+{
+ struct ccu_div *div = priv;
+
+ *val = div->divider;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_fixed_clkdiv_fops,
+ ccu_div_dbgfs_fixed_clkdiv_get, NULL, "%llu\n");
+
+static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ struct ccu_div_dbgfs_bit *bits;
+ int didx, bidx, num = 2;
+ const char *name;
+
+ num += !!(div->flags & CLK_SET_RATE_GATE) +
+ !!(div->features & CCU_DIV_RESET_DOMAIN);
+
+ bits = kcalloc(num, sizeof(*bits), GFP_KERNEL);
+ if (!bits)
+ return;
+
+ for (didx = 0, bidx = 0; bidx < CCU_DIV_DBGFS_BIT_NUM; ++bidx) {
+ name = ccu_div_bits[bidx].name;
+ if (!(div->flags & CLK_SET_RATE_GATE) &&
+ !strcmp("div_en", name)) {
+ continue;
+ }
+
+ if (!(div->features & CCU_DIV_RESET_DOMAIN) &&
+ !strcmp("div_rst", name)) {
+ continue;
+ }
+
+ bits[didx] = ccu_div_bits[bidx];
+ bits[didx].div = div;
+
+ if (div->features & CCU_DIV_LOCK_SHIFTED &&
+ !strcmp("div_lock", name)) {
+ bits[didx].mask = CCU_DIV_CTL_LOCK_SHIFTED;
+ }
+
+ debugfs_create_file_unsafe(bits[didx].name, ccu_div_dbgfs_mode,
+ dentry, &bits[didx],
+ &ccu_div_dbgfs_bit_fops);
+ ++didx;
+ }
+
+ debugfs_create_file_unsafe("div_clkdiv", ccu_div_dbgfs_mode, dentry,
+ div, &ccu_div_dbgfs_var_clkdiv_fops);
+}
+
+static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+ struct ccu_div_dbgfs_bit *bit;
+
+ bit = kmalloc(sizeof(*bit), GFP_KERNEL);
+ if (!bit)
+ return;
+
+ *bit = ccu_div_bits[0];
+ bit->div = div;
+ debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
+ &ccu_div_dbgfs_bit_fops);
+
+ debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div,
+ &ccu_div_dbgfs_fixed_clkdiv_fops);
+}
+
+static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+ struct ccu_div *div = to_ccu_div(hw);
+
+ debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div,
+ &ccu_div_dbgfs_fixed_clkdiv_fops);
+}
+
+#else /* !CONFIG_DEBUG_FS */
+
+#define ccu_div_var_debug_init NULL
+#define ccu_div_gate_debug_init NULL
+#define ccu_div_fixed_debug_init NULL
+
+#endif /* !CONFIG_DEBUG_FS */
+
+static const struct clk_ops ccu_div_var_gate_to_set_ops = {
+ .enable = ccu_div_var_enable,
+ .disable = ccu_div_gate_disable,
+ .is_enabled = ccu_div_gate_is_enabled,
+ .recalc_rate = ccu_div_var_recalc_rate,
+ .round_rate = ccu_div_var_round_rate,
+ .set_rate = ccu_div_var_set_rate_fast,
+ .debug_init = ccu_div_var_debug_init
+};
+
+static const struct clk_ops ccu_div_var_nogate_ops = {
+ .recalc_rate = ccu_div_var_recalc_rate,
+ .round_rate = ccu_div_var_round_rate,
+ .set_rate = ccu_div_var_set_rate_slow,
+ .debug_init = ccu_div_var_debug_init
+};
+
+static const struct clk_ops ccu_div_gate_ops = {
+ .enable = ccu_div_gate_enable,
+ .disable = ccu_div_gate_disable,
+ .is_enabled = ccu_div_gate_is_enabled,
+ .recalc_rate = ccu_div_fixed_recalc_rate,
+ .round_rate = ccu_div_fixed_round_rate,
+ .set_rate = ccu_div_fixed_set_rate,
+ .debug_init = ccu_div_gate_debug_init
+};
+
+static const struct clk_ops ccu_div_fixed_ops = {
+ .recalc_rate = ccu_div_fixed_recalc_rate,
+ .round_rate = ccu_div_fixed_round_rate,
+ .set_rate = ccu_div_fixed_set_rate,
+ .debug_init = ccu_div_fixed_debug_init
+};
+
+struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
+{
+ struct clk_parent_data parent_data = { };
+ struct clk_init_data hw_init = { };
+ struct ccu_div *div;
+ int ret;
+
+ if (!div_init)
+ return ERR_PTR(-EINVAL);
+
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * Note since Baikal-T1 System Controller registers are MMIO-backed
+ * we won't check the regmap IO operations return status, because it
+ * must be zero anyway.
+ */
+ div->hw.init = &hw_init;
+ div->id = div_init->id;
+ div->reg_ctl = div_init->base + CCU_DIV_CTL;
+ div->sys_regs = div_init->sys_regs;
+ div->flags = div_init->flags;
+ div->features = div_init->features;
+ spin_lock_init(&div->lock);
+
+ hw_init.name = div_init->name;
+ hw_init.flags = div_init->flags;
+
+ if (div_init->type == CCU_DIV_VAR) {
+ if (hw_init.flags & CLK_SET_RATE_GATE)
+ hw_init.ops = &ccu_div_var_gate_to_set_ops;
+ else
+ hw_init.ops = &ccu_div_var_nogate_ops;
+ div->mask = CCU_DIV_CTL_CLKDIV_MASK(div_init->width);
+ } else if (div_init->type == CCU_DIV_GATE) {
+ hw_init.ops = &ccu_div_gate_ops;
+ div->divider = div_init->divider;
+ } else if (div_init->type == CCU_DIV_FIXED) {
+ hw_init.ops = &ccu_div_fixed_ops;
+ div->divider = div_init->divider;
+ } else {
+ ret = -EINVAL;
+ goto err_free_div;
+ }
+
+ if (!div_init->parent_name) {
+ ret = -EINVAL;
+ goto err_free_div;
+ }
+ parent_data.fw_name = div_init->parent_name;
+ hw_init.parent_data = &parent_data;
+ hw_init.num_parents = 1;
+
+ ret = of_clk_hw_register(div_init->np, &div->hw);
+ if (ret)
+ goto err_free_div;
+
+ return div;
+
+err_free_div:
+ kfree(div);
+
+ return ERR_PTR(ret);
+}
+
+void ccu_div_hw_unregister(struct ccu_div *div)
+{
+ clk_hw_unregister(&div->hw);
+
+ kfree(div);
+}
diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h
new file mode 100644
index 000000000000..795665caefbd
--- /dev/null
+++ b/drivers/clk/baikal-t1/ccu-div.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Baikal-T1 CCU Dividers interface driver
+ */
+#ifndef __CLK_BT1_CCU_DIV_H__
+#define __CLK_BT1_CCU_DIV_H__
+
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/bits.h>
+#include <linux/of.h>
+
+/*
+ * CCU Divider private flags
+ * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
+ * It can be 0 though, which is functionally the same.
+ * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
+ * It can be either 0 or greater than 3.
+ * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
+ * @CCU_DIV_RESET_DOMAIN: Provide reset clock domain method.
+ */
+#define CCU_DIV_SKIP_ONE BIT(1)
+#define CCU_DIV_SKIP_ONE_TO_THREE BIT(2)
+#define CCU_DIV_LOCK_SHIFTED BIT(3)
+#define CCU_DIV_RESET_DOMAIN BIT(4)
+
+/*
+ * enum ccu_div_type - CCU Divider types
+ * @CCU_DIV_VAR: Clocks gate with variable divider.
+ * @CCU_DIV_GATE: Clocks gate with fixed divider.
+ * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
+ */
+enum ccu_div_type {
+ CCU_DIV_VAR,
+ CCU_DIV_GATE,
+ CCU_DIV_FIXED
+};
+
+/*
+ * struct ccu_div_init_data - CCU Divider initialization data
+ * @id: Clocks private identifier.
+ * @name: Clocks name.
+ * @parent_name: Parent clocks name in a fw node.
+ * @base: Divider register base address with respect to the sys_regs base.
+ * @sys_regs: Baikal-T1 System Controller registers map.
+ * @np: Pointer to the node describing the CCU Dividers.
+ * @type: CCU divider type (variable, fixed with and without gate).
+ * @width: Divider width if it's variable.
+ * @divider: Divider fixed value.
+ * @flags: CCU Divider clock flags.
+ * @features: CCU Divider private features.
+ */
+struct ccu_div_init_data {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ unsigned int base;
+ struct regmap *sys_regs;
+ struct device_node *np;
+ enum ccu_div_type type;
+ union {
+ unsigned int width;
+ unsigned int divider;
+ };
+ unsigned long flags;
+ unsigned long features;
+};
+
+/*
+ * struct ccu_div - CCU Divider descriptor
+ * @hw: clk_hw of the divider.
+ * @id: Clock private identifier.
+ * @reg_ctl: Divider control register base address.
+ * @sys_regs: Baikal-T1 System Controller registers map.
+ * @lock: Divider state change spin-lock.
+ * @mask: Divider field mask.
+ * @divider: Divider fixed value.
+ * @flags: Divider clock flags.
+ * @features: CCU Divider private features.
+ */
+struct ccu_div {
+ struct clk_hw hw;
+ unsigned int id;
+ unsigned int reg_ctl;
+ struct regmap *sys_regs;
+ spinlock_t lock;
+ union {
+ u32 mask;
+ unsigned int divider;
+ };
+ unsigned long flags;
+ unsigned long features;
+};
+#define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
+
+static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
+{
+ return div ? &div->hw : NULL;
+}
+
+struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
+
+void ccu_div_hw_unregister(struct ccu_div *div);
+
+int ccu_div_reset_domain(struct ccu_div *div);
+
+#endif /* __CLK_BT1_CCU_DIV_H__ */
diff --git a/drivers/clk/baikal-t1/ccu-pll.c b/drivers/clk/baikal-t1/ccu-pll.c
new file mode 100644
index 000000000000..13ef28001439
--- /dev/null
+++ b/drivers/clk/baikal-t1/ccu-pll.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
+ *
+ * Baikal-T1 CCU PLL interface driver
+ */
+
+#define pr_fmt(fmt) "bt1-ccu-pll: " fmt
+
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/limits.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/iopoll.h>
+#include <linux/time64.h>
+#include <linux/rational.h>
+#include <linux/debugfs.h>
+
+#include "ccu-pll.h"
+
+#define CCU_PLL_CTL 0x000
+#define CCU_PLL_CTL_EN BIT(0)
+#define CCU_PLL_CTL_RST BIT(1)
+#define CCU_PLL_CTL_CLKR_FLD 2
+#define CCU_PLL_CTL_CLKR_MASK GENMASK(7, CCU_PLL_CTL_CLKR_FLD)
+#define CCU_PLL_CTL_CLKF_FLD 8
+#define CCU_PLL_CTL_CLKF_MASK GENMASK(20, CCU_PLL_CTL_CLKF_FLD)
+#define CCU_PLL_CTL_CLKOD_FLD 21
+#define CCU_PLL_CTL_CLKOD_MASK GENMASK(24, CCU_PLL_CTL_CLKOD_FLD)
+#define CCU_PLL_CTL_BYPASS BIT(30)
+#define CCU_PLL_CTL_LOCK BIT(31)
+#define CCU_PLL_CTL1 0x004
+#define CCU_PLL_CTL1_BWADJ_FLD 3
+#define CCU_PLL_CTL1_BWADJ_MASK GENMASK(14, CCU_PLL_CTL1_BWADJ_FLD)
+
+#define CCU_PLL_LOCK_CHECK_RETRIES 50
+
+#define CCU_PLL_NR_MAX \
+ ((CCU_PLL_CTL_CLKR_MASK >> CCU_PLL_CTL_CLKR_FLD) + 1)
+#define CCU_PLL_NF_MAX \
+ ((CCU_PLL_CTL_CLKF_MASK >> (CCU_PLL_CTL_CLKF_FLD + 1)) + 1)
+#define CCU_PLL_OD_MAX \
+ ((CCU_PLL_CTL_CLKOD_MASK >> CCU_PLL_CTL_CLKOD_FLD) + 1)
+#define CCU_PLL_NB_MAX \
+ ((CCU_PLL_CTL1_BWADJ_MASK >> CCU_PLL_CTL1_BWADJ_FLD) + 1)
+#define CCU_PLL_FDIV_MIN 427000UL
+#define CCU_PLL_FDIV_MAX 3500000000UL
+#define CCU_PLL_FOUT_MIN 200000000UL
+#define CCU_PLL_FOUT_MAX 2500000000UL
+#define CCU_PLL_FVCO_MIN 700000000UL
+#define CCU_PLL_FVCO_MAX 3500000000UL
+#define CCU_PLL_CLKOD_FACTOR 2
+
+static inline unsigned long ccu_pll_lock_delay_us(unsigned long ref_clk,
+ unsigned long nr)
+{
+ u64 us = 500ULL * nr * USEC_PER_SEC;
+
+ do_div(us, ref_clk);
+
+ return us;
+}
+
+static inline unsigned long ccu_pll_calc_freq(unsigned long ref_clk,
+ unsigned long nr,
+ unsigned long nf,
+ unsigned long od)
+{
+ u64 tmp = ref_clk;
+
+ do_div(tmp, nr);
+ tmp *= nf;
+ do_div(tmp, od);
+
+ return tmp;
+}
+
+static int ccu_pll_reset(struct ccu_pll *pll, unsigned long ref_clk,
+ unsigned long nr)
+{
+ unsigned long ud, ut;
+ u32 val;
+
+ ud = ccu_pll_lock_delay_us(ref_clk, nr);
+ ut = ud * CCU_PLL_LOCK_CHECK_RETRIES;
+
+ regmap_update_bits(pll->sys_regs, pll->reg_ctl,
+ CCU_PLL_CTL_RST, CCU_PLL_CTL_RST);
+
+ return regmap_read_poll_timeout_atomic(pll->sys_regs, pll->reg_ctl, val,
+ val & CCU_PLL_CTL_LOCK, ud, ut);
+}
+
+static int ccu_pll_enable(struct clk_hw *hw)
+{
+ struct clk_hw *parent_hw = clk_hw_get_parent(hw);
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ unsigned long flags;
+ u32 val = 0;
+ int ret;
+
+ if (!parent_hw) {
+ pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ regmap_read(pll->sys_regs, pll->reg_ctl, &val);
+ if (val & CCU_PLL_CTL_EN)
+ return 0;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ regmap_write(pll->sys_regs, pll->reg_ctl, val | CCU_PLL_CTL_EN);
+ ret = ccu_pll_reset(pll, clk_hw_get_rate(parent_hw),
+ FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1);
+ spin_unlock_irqrestore(&pll->lock, flags);
+ if (ret)
+ pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw));
+
+ return ret;
+}
+
+static void ccu_pll_disable(struct clk_hw *hw)
+{
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ regmap_update_bits(pll->sys_regs, pll->reg_ctl, CCU_PLL_CTL_EN, 0);
+ spin_unlock_irqrestore(&pll->lock, flags);
+}
+
+static int ccu_pll_is_enabled(struct clk_hw *hw)
+{
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ u32 val = 0;
+
+ regmap_read(pll->sys_regs, pll->reg_ctl, &val);
+
+ return !!(val & CCU_PLL_CTL_EN);
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ unsigned long nr, nf, od;
+ u32 val = 0;
+
+ regmap_read(pll->sys_regs, pll->reg_ctl, &val);
+ nr = FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1;
+ nf = FIELD_GET(CCU_PLL_CTL_CLKF_MASK, val) + 1;
+ od = FIELD_GET(CCU_PLL_CTL_CLKOD_MASK, val) + 1;
+
+ return ccu_pll_calc_freq(parent_rate, nr, nf, od);
+}
+
+static void ccu_pll_calc_factors(unsigned long rate, unsigned long parent_rate,
+ unsigned long *nr, unsigned long *nf,
+ unsigned long *od)
+{
+ unsigned long err, freq, min_err = ULONG_MAX;
+ unsigned long num, denom, n1, d1, nri;
+ unsigned long nr_max, nf_max, od_max;
+
+ /*
+ * Make sure PLL is working with valid input signal (Fdiv). If
+ * you want to speed the function up just reduce CCU_PLL_NR_MAX.
+ * This will cause a worse approximation though.
+ */
+ nri = (parent_rate / CCU_PLL_FDIV_MAX) + 1;
+ nr_max = min(parent_rate / CCU_PLL_FDIV_MIN, CCU_PLL_NR_MAX);
+
+ /*
+ * Find a closest [nr;nf;od] vector taking into account the
+ * limitations like: 1) 700MHz <= Fvco <= 3.5GHz, 2) PLL Od is
+ * either 1 or even number within the acceptable range (alas 1s
+ * is also excluded by the next loop).
+ */
+ for (; nri <= nr_max; ++nri) {
+ /* Use Od factor to fulfill the limitation 2). */
+ num = CCU_PLL_CLKOD_FACTOR * rate;
+ denom = parent_rate / nri;
+
+ /*
+ * Make sure Fvco is within the acceptable range to fulfill
+ * the condition 1). Note due to the CCU_PLL_CLKOD_FACTOR value
+ * the actual upper limit is also divided by that factor.
+ * It's not big problem for us since practically there is no
+ * need in clocks with that high frequency.
+ */
+ nf_max = min(CCU_PLL_FVCO_MAX / denom, CCU_PLL_NF_MAX);
+ od_max = CCU_PLL_OD_MAX / CCU_PLL_CLKOD_FACTOR;
+
+ /*
+ * Bypass the out-of-bound values, which can't be properly
+ * handled by the rational fraction approximation algorithm.
+ */
+ if (num / denom >= nf_max) {
+ n1 = nf_max;
+ d1 = 1;
+ } else if (denom / num >= od_max) {
+ n1 = 1;
+ d1 = od_max;
+ } else {
+ rational_best_approximation(num, denom, nf_max, od_max,
+ &n1, &d1);
+ }
+
+ /* Select the best approximation of the target rate. */
+ freq = ccu_pll_calc_freq(parent_rate, nri, n1, d1);
+ err = abs((int64_t)freq - num);
+ if (err < min_err) {
+ min_err = err;
+ *nr = nri;
+ *nf = n1;
+ *od = CCU_PLL_CLKOD_FACTOR * d1;
+ }
+ }
+}
+
+static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long nr = 1, nf = 1, od = 1;
+
+ ccu_pll_calc_factors(rate, *parent_rate, &nr, &nf, &od);
+
+ return ccu_pll_calc_freq(*parent_rate, nr, nf, od);
+}
+
+/*
+ * This method is used for PLLs, which support the on-the-fly dividers
+ * adjustment. So there is no need in gating such clocks.
+ */
+static int ccu_pll_set_rate_reset(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ unsigned long nr, nf, od;
+ unsigned long flags;
+ u32 mask, val;
+ int ret;
+
+ ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od);
+
+ mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK |
+ CCU_PLL_CTL_CLKOD_MASK;
+ val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) |
+ FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) |
+ FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1);
+
+ spin_lock_irqsave(&pll->lock, flags);
+ regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val);
+ ret = ccu_pll_reset(pll, parent_rate, nr);
+ spin_unlock_irqrestore(&pll->lock, flags);
+ if (ret)
+ pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw));
+
+ return ret;
+}
+
+/*
+ * This method is used for PLLs, which don't support the on-the-fly dividers
+ * adjustment. So the corresponding clocks are supposed to be gated first.
+ */
+static int ccu_pll_set_rate_norst(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ unsigned long nr, nf, od;
+ unsigned long flags;
+ u32 mask, val;
+
+ ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od);
+
+ /*
+ * Disable PLL if it was enabled by default or left enabled by the
+ * system bootloader.
+ */
+ mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK |
+ CCU_PLL_CTL_CLKOD_MASK | CCU_PLL_CTL_EN;
+ val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) |
+ FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) |
+ FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1);
+
+ spin_lock_irqsave(&pll->lock, flags);
+ regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val);
+ spin_unlock_irqrestore(&pll->lock, flags);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+struct ccu_pll_dbgfs_bit {
+ struct ccu_pll *pll;
+ const char *name;
+ unsigned int reg;
+ u32 mask;
+};
+
+struct ccu_pll_dbgfs_fld {
+ struct ccu_pll *pll;
+ const char *name;
+ unsigned int reg;
+ unsigned int lsb;
+ u32 mask;
+ u32 min;
+ u32 max;
+};
+
+#define CCU_PLL_DBGFS_BIT_ATTR(_name, _reg, _mask) \
+ { \
+ .name = _name, \
+ .reg = _reg, \
+ .mask = _mask \
+ }
+
+#define CCU_PLL_DBGFS_FLD_ATTR(_name, _reg, _lsb, _mask, _min, _max) \
+ { \
+ .name = _name, \
+ .reg = _reg, \
+ .lsb = _lsb, \
+ .mask = _mask, \
+ .min = _min, \
+ .max = _max \
+ }
+
+static const struct ccu_pll_dbgfs_bit ccu_pll_bits[] = {
+ CCU_PLL_DBGFS_BIT_ATTR("pll_en", CCU_PLL_CTL, CCU_PLL_CTL_EN),
+ CCU_PLL_DBGFS_BIT_ATTR("pll_rst", CCU_PLL_CTL, CCU_PLL_CTL_RST),
+ CCU_PLL_DBGFS_BIT_ATTR("pll_bypass", CCU_PLL_CTL, CCU_PLL_CTL_BYPASS),
+ CCU_PLL_DBGFS_BIT_ATTR("pll_lock", CCU_PLL_CTL, CCU_PLL_CTL_LOCK)
+};
+
+#define CCU_PLL_DBGFS_BIT_NUM ARRAY_SIZE(ccu_pll_bits)
+
+static const struct ccu_pll_dbgfs_fld ccu_pll_flds[] = {
+ CCU_PLL_DBGFS_FLD_ATTR("pll_nr", CCU_PLL_CTL, CCU_PLL_CTL_CLKR_FLD,
+ CCU_PLL_CTL_CLKR_MASK, 1, CCU_PLL_NR_MAX),
+ CCU_PLL_DBGFS_FLD_ATTR("pll_nf", CCU_PLL_CTL, CCU_PLL_CTL_CLKF_FLD,
+ CCU_PLL_CTL_CLKF_MASK, 1, CCU_PLL_NF_MAX),
+ CCU_PLL_DBGFS_FLD_ATTR("pll_od", CCU_PLL_CTL, CCU_PLL_CTL_CLKOD_FLD,
+ CCU_PLL_CTL_CLKOD_MASK, 1, CCU_PLL_OD_MAX),
+ CCU_PLL_DBGFS_FLD_ATTR("pll_nb", CCU_PLL_CTL1, CCU_PLL_CTL1_BWADJ_FLD,
+ CCU_PLL_CTL1_BWADJ_MASK, 1, CCU_PLL_NB_MAX)
+};
+
+#define CCU_PLL_DBGFS_FLD_NUM ARRAY_SIZE(ccu_pll_flds)
+
+/*
+ * It can be dangerous to change the PLL settings behind clock framework back,
+ * therefore we don't provide any kernel config based compile time option for
+ * this feature to enable.
+ */
+#undef CCU_PLL_ALLOW_WRITE_DEBUGFS
+#ifdef CCU_PLL_ALLOW_WRITE_DEBUGFS
+
+static int ccu_pll_dbgfs_bit_set(void *priv, u64 val)
+{
+ const struct ccu_pll_dbgfs_bit *bit = priv;
+ struct ccu_pll *pll = bit->pll;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ regmap_update_bits(pll->sys_regs, pll->reg_ctl + bit->reg,
+ bit->mask, val ? bit->mask : 0);
+ spin_unlock_irqrestore(&pll->lock, flags);
+
+ return 0;
+}
+
+static int ccu_pll_dbgfs_fld_set(void *priv, u64 val)
+{
+ struct ccu_pll_dbgfs_fld *fld = priv;
+ struct ccu_pll *pll = fld->pll;
+ unsigned long flags;
+ u32 data;
+
+ val = clamp_t(u64, val, fld->min, fld->max);
+ data = ((val - 1) << fld->lsb) & fld->mask;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ regmap_update_bits(pll->sys_regs, pll->reg_ctl + fld->reg, fld->mask,
+ data);
+ spin_unlock_irqrestore(&pll->lock, flags);
+
+ return 0;
+}
+
+#define ccu_pll_dbgfs_mode 0644
+
+#else /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */
+
+#define ccu_pll_dbgfs_bit_set NULL
+#define ccu_pll_dbgfs_fld_set NULL
+#define ccu_pll_dbgfs_mode 0444
+
+#endif /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */
+
+static int ccu_pll_dbgfs_bit_get(void *priv, u64 *val)
+{
+ struct ccu_pll_dbgfs_bit *bit = priv;
+ struct ccu_pll *pll = bit->pll;
+ u32 data = 0;
+
+ regmap_read(pll->sys_regs, pll->reg_ctl + bit->reg, &data);
+ *val = !!(data & bit->mask);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_bit_fops,
+ ccu_pll_dbgfs_bit_get, ccu_pll_dbgfs_bit_set, "%llu\n");
+
+static int ccu_pll_dbgfs_fld_get(void *priv, u64 *val)
+{
+ struct ccu_pll_dbgfs_fld *fld = priv;
+ struct ccu_pll *pll = fld->pll;
+ u32 data = 0;
+
+ regmap_read(pll->sys_regs, pll->reg_ctl + fld->reg, &data);
+ *val = ((data & fld->mask) >> fld->lsb) + 1;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_fld_fops,
+ ccu_pll_dbgfs_fld_get, ccu_pll_dbgfs_fld_set, "%llu\n");
+
+static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+ struct ccu_pll *pll = to_ccu_pll(hw);
+ struct ccu_pll_dbgfs_bit *bits;
+ struct ccu_pll_dbgfs_fld *flds;
+ int idx;
+
+ bits = kcalloc(CCU_PLL_DBGFS_BIT_NUM, sizeof(*bits), GFP_KERNEL);
+ if (!bits)
+ return;
+
+ for (idx = 0; idx < CCU_PLL_DBGFS_BIT_NUM; ++idx) {
+ bits[idx] = ccu_pll_bits[idx];
+ bits[idx].pll = pll;
+
+ debugfs_create_file_unsafe(bits[idx].name, ccu_pll_dbgfs_mode,
+ dentry, &bits[idx],
+ &ccu_pll_dbgfs_bit_fops);
+ }
+
+ flds = kcalloc(CCU_PLL_DBGFS_FLD_NUM, sizeof(*flds), GFP_KERNEL);
+ if (!flds)
+ return;
+
+ for (idx = 0; idx < CCU_PLL_DBGFS_FLD_NUM; ++idx) {
+ flds[idx] = ccu_pll_flds[idx];
+ flds[idx].pll = pll;
+
+ debugfs_create_file_unsafe(flds[idx].name, ccu_pll_dbgfs_mode,
+ dentry, &flds[idx],
+ &ccu_pll_dbgfs_fld_fops);
+ }
+}
+
+#else /* !CONFIG_DEBUG_FS */
+
+#define ccu_pll_debug_init NULL
+
+#endif /* !CONFIG_DEBUG_FS */
+
+static const struct clk_ops ccu_pll_gate_to_set_ops = {
+ .enable = ccu_pll_enable,
+ .disable = ccu_pll_disable,
+ .is_enabled = ccu_pll_is_enabled,
+ .recalc_rate = ccu_pll_recalc_rate,
+ .round_rate = ccu_pll_round_rate,
+ .set_rate = ccu_pll_set_rate_norst,
+ .debug_init = ccu_pll_debug_init
+};
+
+static const struct clk_ops ccu_pll_straight_set_ops = {
+ .enable = ccu_pll_enable,
+ .disable = ccu_pll_disable,
+ .is_enabled = ccu_pll_is_enabled,
+ .recalc_rate = ccu_pll_recalc_rate,
+ .round_rate = ccu_pll_round_rate,
+ .set_rate = ccu_pll_set_rate_reset,
+ .debug_init = ccu_pll_debug_init
+};
+
+struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *pll_init)
+{
+ struct clk_parent_data parent_data = { };
+ struct clk_init_data hw_init = { };
+ struct ccu_pll *pll;
+ int ret;
+
+ if (!pll_init)
+ return ERR_PTR(-EINVAL);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * Note since Baikal-T1 System Controller registers are MMIO-backed
+ * we won't check the regmap IO operations return status, because it
+ * must be zero anyway.
+ */
+ pll->hw.init = &hw_init;
+ pll->reg_ctl = pll_init->base + CCU_PLL_CTL;
+ pll->reg_ctl1 = pll_init->base + CCU_PLL_CTL1;
+ pll->sys_regs = pll_init->sys_regs;
+ pll->id = pll_init->id;
+ spin_lock_init(&pll->lock);
+
+ hw_init.name = pll_init->name;
+ hw_init.flags = pll_init->flags;
+
+ if (hw_init.flags & CLK_SET_RATE_GATE)
+ hw_init.ops = &ccu_pll_gate_to_set_ops;
+ else
+ hw_init.ops = &ccu_pll_straight_set_ops;
+
+ if (!pll_init->parent_name) {
+ ret = -EINVAL;
+ goto err_free_pll;
+ }
+ parent_data.fw_name = pll_init->parent_name;
+ hw_init.parent_data = &parent_data;
+ hw_init.num_parents = 1;
+
+ ret = of_clk_hw_register(pll_init->np, &pll->hw);
+ if (ret)
+ goto err_free_pll;
+
+ return pll;
+
+err_free_pll:
+ kfree(pll);
+
+ return ERR_PTR(ret);
+}
+
+void ccu_pll_hw_unregister(struct ccu_pll *pll)
+{
+ clk_hw_unregister(&pll->hw);
+
+ kfree(pll);
+}
diff --git a/drivers/clk/baikal-t1/ccu-pll.h b/drivers/clk/baikal-t1/ccu-pll.h
new file mode 100644
index 000000000000..76cd9132a219
--- /dev/null
+++ b/drivers/clk/baikal-t1/ccu-pll.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Baikal-T1 CCU PLL interface driver
+ */
+#ifndef __CLK_BT1_CCU_PLL_H__
+#define __CLK_BT1_CCU_PLL_H__
+
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/bits.h>
+#include <linux/of.h>
+
+/*
+ * struct ccu_pll_init_data - CCU PLL initialization data
+ * @id: Clock private identifier.
+ * @name: Clocks name.
+ * @parent_name: Clocks parent name in a fw node.
+ * @base: PLL registers base address with respect to the sys_regs base.
+ * @sys_regs: Baikal-T1 System Controller registers map.
+ * @np: Pointer to the node describing the CCU PLLs.
+ * @flags: PLL clock flags.
+ */
+struct ccu_pll_init_data {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ unsigned int base;
+ struct regmap *sys_regs;
+ struct device_node *np;
+ unsigned long flags;
+};
+
+/*
+ * struct ccu_pll - CCU PLL descriptor
+ * @hw: clk_hw of the PLL.
+ * @id: Clock private identifier.
+ * @reg_ctl: PLL control register base.
+ * @reg_ctl1: PLL control1 register base.
+ * @sys_regs: Baikal-T1 System Controller registers map.
+ * @lock: PLL state change spin-lock.
+ */
+struct ccu_pll {
+ struct clk_hw hw;
+ unsigned int id;
+ unsigned int reg_ctl;
+ unsigned int reg_ctl1;
+ struct regmap *sys_regs;
+ spinlock_t lock;
+};
+#define to_ccu_pll(_hw) container_of(_hw, struct ccu_pll, hw)
+
+static inline struct clk_hw *ccu_pll_get_clk_hw(struct ccu_pll *pll)
+{
+ return pll ? &pll->hw : NULL;
+}
+
+struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *init);
+
+void ccu_pll_hw_unregister(struct ccu_pll *pll);
+
+#endif /* __CLK_BT1_CCU_PLL_H__ */
diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c
new file mode 100644
index 000000000000..f141fda12b09
--- /dev/null
+++ b/drivers/clk/baikal-t1/clk-ccu-div.c
@@ -0,0 +1,485 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
+ *
+ * Baikal-T1 CCU Dividers clock driver
+ */
+
+#define pr_fmt(fmt) "bt1-ccu-div: " fmt
+
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/reset-controller.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/ioport.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/bt1-ccu.h>
+#include <dt-bindings/reset/bt1-ccu.h>
+
+#include "ccu-div.h"
+
+#define CCU_AXI_MAIN_BASE 0x030
+#define CCU_AXI_DDR_BASE 0x034
+#define CCU_AXI_SATA_BASE 0x038
+#define CCU_AXI_GMAC0_BASE 0x03C
+#define CCU_AXI_GMAC1_BASE 0x040
+#define CCU_AXI_XGMAC_BASE 0x044
+#define CCU_AXI_PCIE_M_BASE 0x048
+#define CCU_AXI_PCIE_S_BASE 0x04C
+#define CCU_AXI_USB_BASE 0x050
+#define CCU_AXI_HWA_BASE 0x054
+#define CCU_AXI_SRAM_BASE 0x058
+
+#define CCU_SYS_SATA_REF_BASE 0x060
+#define CCU_SYS_APB_BASE 0x064
+#define CCU_SYS_GMAC0_BASE 0x068
+#define CCU_SYS_GMAC1_BASE 0x06C
+#define CCU_SYS_XGMAC_BASE 0x070
+#define CCU_SYS_USB_BASE 0x074
+#define CCU_SYS_PVT_BASE 0x078
+#define CCU_SYS_HWA_BASE 0x07C
+#define CCU_SYS_UART_BASE 0x084
+#define CCU_SYS_TIMER0_BASE 0x088
+#define CCU_SYS_TIMER1_BASE 0x08C
+#define CCU_SYS_TIMER2_BASE 0x090
+#define CCU_SYS_WDT_BASE 0x150
+
+#define CCU_DIV_VAR_INFO(_id, _name, _pname, _base, _width, _flags, _features) \
+ { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _pname, \
+ .base = _base, \
+ .type = CCU_DIV_VAR, \
+ .width = _width, \
+ .flags = _flags, \
+ .features = _features \
+ }
+
+#define CCU_DIV_GATE_INFO(_id, _name, _pname, _base, _divider) \
+ { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _pname, \
+ .base = _base, \
+ .type = CCU_DIV_GATE, \
+ .divider = _divider \
+ }
+
+#define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \
+ { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _pname, \
+ .type = CCU_DIV_FIXED, \
+ .divider = _divider \
+ }
+
+#define CCU_DIV_RST_MAP(_rst_id, _clk_id) \
+ { \
+ .rst_id = _rst_id, \
+ .clk_id = _clk_id \
+ }
+
+struct ccu_div_info {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ unsigned int base;
+ enum ccu_div_type type;
+ union {
+ unsigned int width;
+ unsigned int divider;
+ };
+ unsigned long flags;
+ unsigned long features;
+};
+
+struct ccu_div_rst_map {
+ unsigned int rst_id;
+ unsigned int clk_id;
+};
+
+struct ccu_div_data {
+ struct device_node *np;
+ struct regmap *sys_regs;
+
+ unsigned int divs_num;
+ const struct ccu_div_info *divs_info;
+ struct ccu_div **divs;
+
+ unsigned int rst_num;
+ const struct ccu_div_rst_map *rst_map;
+ struct reset_controller_dev rcdev;
+};
+#define to_ccu_div_data(_rcdev) container_of(_rcdev, struct ccu_div_data, rcdev)
+
+/*
+ * AXI Main Interconnect (axi_main_clk) and DDR AXI-bus (axi_ddr_clk) clocks
+ * must be left enabled in any case, since former one is responsible for
+ * clocking a bus between CPU cores and the rest of the SoC components, while
+ * the later is clocking the AXI-bus between DDR controller and the Main
+ * Interconnect. So should any of these clocks get to be disabled, the system
+ * will literally stop working. That's why we marked them as critical.
+ */
+static const struct ccu_div_info axi_info[] = {
+ CCU_DIV_VAR_INFO(CCU_AXI_MAIN_CLK, "axi_main_clk", "pcie_clk",
+ CCU_AXI_MAIN_BASE, 4,
+ CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_DDR_CLK, "axi_ddr_clk", "sata_clk",
+ CCU_AXI_DDR_BASE, 4,
+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+ CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_SATA_CLK, "axi_sata_clk", "sata_clk",
+ CCU_AXI_SATA_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_GMAC0_CLK, "axi_gmac0_clk", "eth_clk",
+ CCU_AXI_GMAC0_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_GMAC1_CLK, "axi_gmac1_clk", "eth_clk",
+ CCU_AXI_GMAC1_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_XGMAC_CLK, "axi_xgmac_clk", "eth_clk",
+ CCU_AXI_XGMAC_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_PCIE_M_CLK, "axi_pcie_m_clk", "pcie_clk",
+ CCU_AXI_PCIE_M_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_PCIE_S_CLK, "axi_pcie_s_clk", "pcie_clk",
+ CCU_AXI_PCIE_S_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_USB_CLK, "axi_usb_clk", "sata_clk",
+ CCU_AXI_USB_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_HWA_CLK, "axi_hwa_clk", "sata_clk",
+ CCU_AXI_HWA_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_AXI_SRAM_CLK, "axi_sram_clk", "eth_clk",
+ CCU_AXI_SRAM_BASE, 4,
+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN)
+};
+
+static const struct ccu_div_rst_map axi_rst_map[] = {
+ CCU_DIV_RST_MAP(CCU_AXI_MAIN_RST, CCU_AXI_MAIN_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_DDR_RST, CCU_AXI_DDR_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_SATA_RST, CCU_AXI_SATA_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_GMAC0_RST, CCU_AXI_GMAC0_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_GMAC1_RST, CCU_AXI_GMAC1_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_XGMAC_RST, CCU_AXI_XGMAC_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_PCIE_M_RST, CCU_AXI_PCIE_M_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_PCIE_S_RST, CCU_AXI_PCIE_S_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_USB_RST, CCU_AXI_USB_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_HWA_RST, CCU_AXI_HWA_CLK),
+ CCU_DIV_RST_MAP(CCU_AXI_SRAM_RST, CCU_AXI_SRAM_CLK)
+};
+
+/*
+ * APB-bus clock is marked as critical since it's a main communication bus
+ * for the SoC devices registers IO-operations.
+ */
+static const struct ccu_div_info sys_info[] = {
+ CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
+ "sata_clk", CCU_SYS_SATA_REF_BASE, 4,
+ CLK_SET_RATE_GATE,
+ CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
+ CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
+ "pcie_clk", CCU_SYS_APB_BASE, 5,
+ CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
+ CCU_DIV_GATE_INFO(CCU_SYS_GMAC0_TX_CLK, "sys_gmac0_tx_clk",
+ "eth_clk", CCU_SYS_GMAC0_BASE, 5),
+ CCU_DIV_FIXED_INFO(CCU_SYS_GMAC0_PTP_CLK, "sys_gmac0_ptp_clk",
+ "eth_clk", 10),
+ CCU_DIV_GATE_INFO(CCU_SYS_GMAC1_TX_CLK, "sys_gmac1_tx_clk",
+ "eth_clk", CCU_SYS_GMAC1_BASE, 5),
+ CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
+ "eth_clk", 10),
+ CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
+ "eth_clk", CCU_SYS_XGMAC_BASE, 8),
+ CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
+ "eth_clk", 10),
+ CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
+ "eth_clk", CCU_SYS_USB_BASE, 10),
+ CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
+ "ref_clk", CCU_SYS_PVT_BASE, 5,
+ CLK_SET_RATE_GATE, 0),
+ CCU_DIV_VAR_INFO(CCU_SYS_HWA_CLK, "sys_hwa_clk",
+ "sata_clk", CCU_SYS_HWA_BASE, 4,
+ CLK_SET_RATE_GATE, 0),
+ CCU_DIV_VAR_INFO(CCU_SYS_UART_CLK, "sys_uart_clk",
+ "eth_clk", CCU_SYS_UART_BASE, 17,
+ CLK_SET_RATE_GATE, 0),
+ CCU_DIV_FIXED_INFO(CCU_SYS_I2C1_CLK, "sys_i2c1_clk",
+ "eth_clk", 10),
+ CCU_DIV_FIXED_INFO(CCU_SYS_I2C2_CLK, "sys_i2c2_clk",
+ "eth_clk", 10),
+ CCU_DIV_FIXED_INFO(CCU_SYS_GPIO_CLK, "sys_gpio_clk",
+ "ref_clk", 25),
+ CCU_DIV_VAR_INFO(CCU_SYS_TIMER0_CLK, "sys_timer0_clk",
+ "ref_clk", CCU_SYS_TIMER0_BASE, 17,
+ CLK_SET_RATE_GATE, 0),
+ CCU_DIV_VAR_INFO(CCU_SYS_TIMER1_CLK, "sys_timer1_clk",
+ "ref_clk", CCU_SYS_TIMER1_BASE, 17,
+ CLK_SET_RATE_GATE, 0),
+ CCU_DIV_VAR_INFO(CCU_SYS_TIMER2_CLK, "sys_timer2_clk",
+ "ref_clk", CCU_SYS_TIMER2_BASE, 17,
+ CLK_SET_RATE_GATE, 0),
+ CCU_DIV_VAR_INFO(CCU_SYS_WDT_CLK, "sys_wdt_clk",
+ "eth_clk", CCU_SYS_WDT_BASE, 17,
+ CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE_TO_THREE)
+};
+
+static const struct ccu_div_rst_map sys_rst_map[] = {
+ CCU_DIV_RST_MAP(CCU_SYS_SATA_REF_RST, CCU_SYS_SATA_REF_CLK),
+ CCU_DIV_RST_MAP(CCU_SYS_APB_RST, CCU_SYS_APB_CLK),
+};
+
+static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data,
+ unsigned int clk_id)
+{
+ struct ccu_div *div;
+ int idx;
+
+ for (idx = 0; idx < data->divs_num; ++idx) {
+ div = data->divs[idx];
+ if (div && div->id == clk_id)
+ return div;
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+static int ccu_div_reset(struct reset_controller_dev *rcdev,
+ unsigned long rst_id)
+{
+ struct ccu_div_data *data = to_ccu_div_data(rcdev);
+ const struct ccu_div_rst_map *map;
+ struct ccu_div *div;
+ int idx, ret;
+
+ for (idx = 0, map = data->rst_map; idx < data->rst_num; ++idx, ++map) {
+ if (map->rst_id == rst_id)
+ break;
+ }
+ if (idx == data->rst_num) {
+ pr_err("Invalid reset ID %lu specified\n", rst_id);
+ return -EINVAL;
+ }
+
+ div = ccu_div_find_desc(data, map->clk_id);
+ if (IS_ERR(div)) {
+ pr_err("Invalid clock ID %d in mapping\n", map->clk_id);
+ return PTR_ERR(div);
+ }
+
+ ret = ccu_div_reset_domain(div);
+ if (ret) {
+ pr_err("Reset isn't supported by divider %s\n",
+ clk_hw_get_name(ccu_div_get_clk_hw(div)));
+ }
+
+ return ret;
+}
+
+static const struct reset_control_ops ccu_div_rst_ops = {
+ .reset = ccu_div_reset,
+};
+
+static struct ccu_div_data *ccu_div_create_data(struct device_node *np)
+{
+ struct ccu_div_data *data;
+ int ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+
+ data->np = np;
+ if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) {
+ data->divs_num = ARRAY_SIZE(axi_info);
+ data->divs_info = axi_info;
+ data->rst_num = ARRAY_SIZE(axi_rst_map);
+ data->rst_map = axi_rst_map;
+ } else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) {
+ data->divs_num = ARRAY_SIZE(sys_info);
+ data->divs_info = sys_info;
+ data->rst_num = ARRAY_SIZE(sys_rst_map);
+ data->rst_map = sys_rst_map;
+ } else {
+ pr_err("Incompatible DT node '%s' specified\n",
+ of_node_full_name(np));
+ ret = -EINVAL;
+ goto err_kfree_data;
+ }
+
+ data->divs = kcalloc(data->divs_num, sizeof(*data->divs), GFP_KERNEL);
+ if (!data->divs) {
+ ret = -ENOMEM;
+ goto err_kfree_data;
+ }
+
+ return data;
+
+err_kfree_data:
+ kfree(data);
+
+ return ERR_PTR(ret);
+}
+
+static void ccu_div_free_data(struct ccu_div_data *data)
+{
+ kfree(data->divs);
+
+ kfree(data);
+}
+
+static int ccu_div_find_sys_regs(struct ccu_div_data *data)
+{
+ data->sys_regs = syscon_node_to_regmap(data->np->parent);
+ if (IS_ERR(data->sys_regs)) {
+ pr_err("Failed to find syscon regs for '%s'\n",
+ of_node_full_name(data->np));
+ return PTR_ERR(data->sys_regs);
+ }
+
+ return 0;
+}
+
+static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec,
+ void *priv)
+{
+ struct ccu_div_data *data = priv;
+ struct ccu_div *div;
+ unsigned int clk_id;
+
+ clk_id = clkspec->args[0];
+ div = ccu_div_find_desc(data, clk_id);
+ if (IS_ERR(div)) {
+ pr_info("Invalid clock ID %d specified\n", clk_id);
+ return ERR_CAST(div);
+ }
+
+ return ccu_div_get_clk_hw(div);
+}
+
+static int ccu_div_clk_register(struct ccu_div_data *data)
+{
+ int idx, ret;
+
+ for (idx = 0; idx < data->divs_num; ++idx) {
+ const struct ccu_div_info *info = &data->divs_info[idx];
+ struct ccu_div_init_data init = {0};
+
+ init.id = info->id;
+ init.name = info->name;
+ init.parent_name = info->parent_name;
+ init.np = data->np;
+ init.type = info->type;
+ init.flags = info->flags;
+ init.features = info->features;
+
+ if (init.type == CCU_DIV_VAR) {
+ init.base = info->base;
+ init.sys_regs = data->sys_regs;
+ init.width = info->width;
+ } else if (init.type == CCU_DIV_GATE) {
+ init.base = info->base;
+ init.sys_regs = data->sys_regs;
+ init.divider = info->divider;
+ } else {
+ init.divider = info->divider;
+ }
+
+ data->divs[idx] = ccu_div_hw_register(&init);
+ if (IS_ERR(data->divs[idx])) {
+ ret = PTR_ERR(data->divs[idx]);
+ pr_err("Couldn't register divider '%s' hw\n",
+ init.name);
+ goto err_hw_unregister;
+ }
+ }
+
+ ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data);
+ if (ret) {
+ pr_err("Couldn't register dividers '%s' clock provider\n",
+ of_node_full_name(data->np));
+ goto err_hw_unregister;
+ }
+
+ return 0;
+
+err_hw_unregister:
+ for (--idx; idx >= 0; --idx)
+ ccu_div_hw_unregister(data->divs[idx]);
+
+ return ret;
+}
+
+static void ccu_div_clk_unregister(struct ccu_div_data *data)
+{
+ int idx;
+
+ of_clk_del_provider(data->np);
+
+ for (idx = 0; idx < data->divs_num; ++idx)
+ ccu_div_hw_unregister(data->divs[idx]);
+}
+
+static int ccu_div_rst_register(struct ccu_div_data *data)
+{
+ int ret;
+
+ data->rcdev.ops = &ccu_div_rst_ops;
+ data->rcdev.of_node = data->np;
+ data->rcdev.nr_resets = data->rst_num;
+
+ ret = reset_controller_register(&data->rcdev);
+ if (ret)
+ pr_err("Couldn't register divider '%s' reset controller\n",
+ of_node_full_name(data->np));
+
+ return ret;
+}
+
+static void ccu_div_init(struct device_node *np)
+{
+ struct ccu_div_data *data;
+ int ret;
+
+ data = ccu_div_create_data(np);
+ if (IS_ERR(data))
+ return;
+
+ ret = ccu_div_find_sys_regs(data);
+ if (ret)
+ goto err_free_data;
+
+ ret = ccu_div_clk_register(data);
+ if (ret)
+ goto err_free_data;
+
+ ret = ccu_div_rst_register(data);
+ if (ret)
+ goto err_clk_unregister;
+
+ return;
+
+err_clk_unregister:
+ ccu_div_clk_unregister(data);
+
+err_free_data:
+ ccu_div_free_data(data);
+}
+
+CLK_OF_DECLARE(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init);
+CLK_OF_DECLARE(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);
diff --git a/drivers/clk/baikal-t1/clk-ccu-pll.c b/drivers/clk/baikal-t1/clk-ccu-pll.c
new file mode 100644
index 000000000000..1eec8c0b8f50
--- /dev/null
+++ b/drivers/clk/baikal-t1/clk-ccu-pll.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
+ *
+ * Baikal-T1 CCU PLL clocks driver
+ */
+
+#define pr_fmt(fmt) "bt1-ccu-pll: " fmt
+
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/ioport.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/bt1-ccu.h>
+
+#include "ccu-pll.h"
+
+#define CCU_CPU_PLL_BASE 0x000
+#define CCU_SATA_PLL_BASE 0x008
+#define CCU_DDR_PLL_BASE 0x010
+#define CCU_PCIE_PLL_BASE 0x018
+#define CCU_ETH_PLL_BASE 0x020
+
+#define CCU_PLL_INFO(_id, _name, _pname, _base, _flags) \
+ { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _pname, \
+ .base = _base, \
+ .flags = _flags \
+ }
+
+#define CCU_PLL_NUM ARRAY_SIZE(pll_info)
+
+struct ccu_pll_info {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ unsigned int base;
+ unsigned long flags;
+};
+
+/*
+ * Mark as critical all PLLs except Ethernet one. CPU and DDR PLLs are sources
+ * of CPU cores and DDR controller reference clocks, due to which they
+ * obviously shouldn't be ever gated. SATA and PCIe PLLs are the parents of
+ * APB-bus and DDR controller AXI-bus clocks. If they are gated the system will
+ * be unusable.
+ */
+static const struct ccu_pll_info pll_info[] = {
+ CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE,
+ CLK_IS_CRITICAL),
+ CCU_PLL_INFO(CCU_SATA_PLL, "sata_pll", "ref_clk", CCU_SATA_PLL_BASE,
+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE),
+ CCU_PLL_INFO(CCU_DDR_PLL, "ddr_pll", "ref_clk", CCU_DDR_PLL_BASE,
+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE),
+ CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE,
+ CLK_IS_CRITICAL),
+ CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE,
+ CLK_SET_RATE_GATE)
+};
+
+struct ccu_pll_data {
+ struct device_node *np;
+ struct regmap *sys_regs;
+ struct ccu_pll *plls[CCU_PLL_NUM];
+};
+
+static struct ccu_pll *ccu_pll_find_desc(struct ccu_pll_data *data,
+ unsigned int clk_id)
+{
+ struct ccu_pll *pll;
+ int idx;
+
+ for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
+ pll = data->plls[idx];
+ if (pll && pll->id == clk_id)
+ return pll;
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+static struct ccu_pll_data *ccu_pll_create_data(struct device_node *np)
+{
+ struct ccu_pll_data *data;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+
+ data->np = np;
+
+ return data;
+}
+
+static void ccu_pll_free_data(struct ccu_pll_data *data)
+{
+ kfree(data);
+}
+
+static int ccu_pll_find_sys_regs(struct ccu_pll_data *data)
+{
+ data->sys_regs = syscon_node_to_regmap(data->np->parent);
+ if (IS_ERR(data->sys_regs)) {
+ pr_err("Failed to find syscon regs for '%s'\n",
+ of_node_full_name(data->np));
+ return PTR_ERR(data->sys_regs);
+ }
+
+ return 0;
+}
+
+static struct clk_hw *ccu_pll_of_clk_hw_get(struct of_phandle_args *clkspec,
+ void *priv)
+{
+ struct ccu_pll_data *data = priv;
+ struct ccu_pll *pll;
+ unsigned int clk_id;
+
+ clk_id = clkspec->args[0];
+ pll = ccu_pll_find_desc(data, clk_id);
+ if (IS_ERR(pll)) {
+ pr_info("Invalid PLL clock ID %d specified\n", clk_id);
+ return ERR_CAST(pll);
+ }
+
+ return ccu_pll_get_clk_hw(pll);
+}
+
+static int ccu_pll_clk_register(struct ccu_pll_data *data)
+{
+ int idx, ret;
+
+ for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
+ const struct ccu_pll_info *info = &pll_info[idx];
+ struct ccu_pll_init_data init = {0};
+
+ init.id = info->id;
+ init.name = info->name;
+ init.parent_name = info->parent_name;
+ init.base = info->base;
+ init.sys_regs = data->sys_regs;
+ init.np = data->np;
+ init.flags = info->flags;
+
+ data->plls[idx] = ccu_pll_hw_register(&init);
+ if (IS_ERR(data->plls[idx])) {
+ ret = PTR_ERR(data->plls[idx]);
+ pr_err("Couldn't register PLL hw '%s'\n",
+ init.name);
+ goto err_hw_unregister;
+ }
+ }
+
+ ret = of_clk_add_hw_provider(data->np, ccu_pll_of_clk_hw_get, data);
+ if (ret) {
+ pr_err("Couldn't register PLL provider of '%s'\n",
+ of_node_full_name(data->np));
+ goto err_hw_unregister;
+ }
+
+ return 0;
+
+err_hw_unregister:
+ for (--idx; idx >= 0; --idx)
+ ccu_pll_hw_unregister(data->plls[idx]);
+
+ return ret;
+}
+
+static __init void ccu_pll_init(struct device_node *np)
+{
+ struct ccu_pll_data *data;
+ int ret;
+
+ data = ccu_pll_create_data(np);
+ if (IS_ERR(data))
+ return;
+
+ ret = ccu_pll_find_sys_regs(data);
+ if (ret)
+ goto err_free_data;
+
+ ret = ccu_pll_clk_register(data);
+ if (ret)
+ goto err_free_data;
+
+ return;
+
+err_free_data:
+ ccu_pll_free_data(data);
+}
+CLK_OF_DECLARE(ccu_pll, "baikal,bt1-ccu-pll", ccu_pll_init);
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index ded13ccf768e..6bb7efa12037 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -396,8 +396,8 @@ out:
}
static void bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
- struct debugfs_reg32 *regs, size_t nregs,
- struct dentry *dentry)
+ const struct debugfs_reg32 *regs,
+ size_t nregs, struct dentry *dentry)
{
struct debugfs_regset32 *regset;
@@ -1240,7 +1240,7 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
}
-static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
+static const struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
{
.name = "ctl",
.offset = 0,
@@ -1296,8 +1296,9 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
};
static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
- const struct bcm2835_pll_data *data)
+ const void *data)
{
+ const struct bcm2835_pll_data *pll_data = data;
struct bcm2835_pll *pll;
struct clk_init_data init;
int ret;
@@ -1307,7 +1308,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
/* All of the PLLs derive from the external oscillator. */
init.parent_names = &cprman->real_parent_names[0];
init.num_parents = 1;
- init.name = data->name;
+ init.name = pll_data->name;
init.ops = &bcm2835_pll_clk_ops;
init.flags = CLK_IGNORE_UNUSED;
@@ -1316,7 +1317,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
return NULL;
pll->cprman = cprman;
- pll->data = data;
+ pll->data = pll_data;
pll->hw.init = &init;
ret = devm_clk_hw_register(cprman->dev, &pll->hw);
@@ -1327,35 +1328,36 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
static struct clk_hw *
bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
- const struct bcm2835_pll_divider_data *data)
+ const void *data)
{
+ const struct bcm2835_pll_divider_data *divider_data = data;
struct bcm2835_pll_divider *divider;
struct clk_init_data init;
const char *divider_name;
int ret;
- if (data->fixed_divider != 1) {
+ if (divider_data->fixed_divider != 1) {
divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
- "%s_prediv", data->name);
+ "%s_prediv", divider_data->name);
if (!divider_name)
return NULL;
} else {
- divider_name = data->name;
+ divider_name = divider_data->name;
}
memset(&init, 0, sizeof(init));
- init.parent_names = &data->source_pll;
+ init.parent_names = &divider_data->source_pll;
init.num_parents = 1;
init.name = divider_name;
init.ops = &bcm2835_pll_divider_clk_ops;
- init.flags = data->flags | CLK_IGNORE_UNUSED;
+ init.flags = divider_data->flags | CLK_IGNORE_UNUSED;
divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
if (!divider)
return NULL;
- divider->div.reg = cprman->regs + data->a2w_reg;
+ divider->div.reg = cprman->regs + divider_data->a2w_reg;
divider->div.shift = A2W_PLL_DIV_SHIFT;
divider->div.width = A2W_PLL_DIV_BITS;
divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO;
@@ -1364,7 +1366,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
divider->div.table = NULL;
divider->cprman = cprman;
- divider->data = data;
+ divider->data = divider_data;
ret = devm_clk_hw_register(cprman->dev, &divider->div.hw);
if (ret)
@@ -1374,20 +1376,22 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
* PLLH's channels have a fixed divide by 10 afterwards, which
* is what our consumers are actually using.
*/
- if (data->fixed_divider != 1) {
- return clk_hw_register_fixed_factor(cprman->dev, data->name,
+ if (divider_data->fixed_divider != 1) {
+ return clk_hw_register_fixed_factor(cprman->dev,
+ divider_data->name,
divider_name,
CLK_SET_RATE_PARENT,
1,
- data->fixed_divider);
+ divider_data->fixed_divider);
}
return &divider->div.hw;
}
static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
- const struct bcm2835_clock_data *data)
+ const void *data)
{
+ const struct bcm2835_clock_data *clock_data = data;
struct bcm2835_clock *clock;
struct clk_init_data init;
const char *parents[1 << CM_SRC_BITS];
@@ -1398,8 +1402,8 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
* Replace our strings referencing parent clocks with the
* actual clock-output-name of the parent.
*/
- for (i = 0; i < data->num_mux_parents; i++) {
- parents[i] = data->parents[i];
+ for (i = 0; i < clock_data->num_mux_parents; i++) {
+ parents[i] = clock_data->parents[i];
ret = match_string(cprman_parent_names,
ARRAY_SIZE(cprman_parent_names),
@@ -1410,18 +1414,18 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
memset(&init, 0, sizeof(init));
init.parent_names = parents;
- init.num_parents = data->num_mux_parents;
- init.name = data->name;
- init.flags = data->flags | CLK_IGNORE_UNUSED;
+ init.num_parents = clock_data->num_mux_parents;
+ init.name = clock_data->name;
+ init.flags = clock_data->flags | CLK_IGNORE_UNUSED;
/*
* Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate
* rate changes on at least of the parents.
*/
- if (data->set_rate_parent)
+ if (clock_data->set_rate_parent)
init.flags |= CLK_SET_RATE_PARENT;
- if (data->is_vpu_clock) {
+ if (clock_data->is_vpu_clock) {
init.ops = &bcm2835_vpu_clock_clk_ops;
} else {
init.ops = &bcm2835_clock_clk_ops;
@@ -1430,7 +1434,7 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
/* If the clock wasn't actually enabled at boot, it's not
* critical.
*/
- if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE))
+ if (!(cprman_read(cprman, clock_data->ctl_reg) & CM_ENABLE))
init.flags &= ~CLK_IS_CRITICAL;
}
@@ -1439,7 +1443,7 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
return NULL;
clock->cprman = cprman;
- clock->data = data;
+ clock->data = clock_data;
clock->hw.init = &init;
ret = devm_clk_hw_register(cprman->dev, &clock->hw);
@@ -1448,25 +1452,27 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
return &clock->hw;
}
-static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
- const struct bcm2835_gate_data *data)
+static struct clk_hw *bcm2835_register_gate(struct bcm2835_cprman *cprman,
+ const void *data)
{
- return clk_register_gate(cprman->dev, data->name, data->parent,
- CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
- cprman->regs + data->ctl_reg,
- CM_GATE_BIT, 0, &cprman->regs_lock);
+ const struct bcm2835_gate_data *gate_data = data;
+
+ return clk_hw_register_gate(cprman->dev, gate_data->name,
+ gate_data->parent,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
+ cprman->regs + gate_data->ctl_reg,
+ CM_GATE_BIT, 0, &cprman->regs_lock);
}
-typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
- const void *data);
struct bcm2835_clk_desc {
- bcm2835_clk_register clk_register;
+ struct clk_hw *(*clk_register)(struct bcm2835_cprman *cprman,
+ const void *data);
unsigned int supported;
const void *data;
};
/* assignment helper macros for different clock types */
-#define _REGISTER(f, s, ...) { .clk_register = (bcm2835_clk_register)f, \
+#define _REGISTER(f, s, ...) { .clk_register = f, \
.supported = s, \
.data = __VA_ARGS__ }
#define REGISTER_PLL(s, ...) _REGISTER(&bcm2835_register_pll, \
diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
index 392d01705b97..99afc949925f 100644
--- a/drivers/clk/clk-ast2600.c
+++ b/drivers/clk/clk-ast2600.c
@@ -642,14 +642,22 @@ static const u32 ast2600_a0_axi_ahb_div_table[] = {
2, 2, 3, 5,
};
-static const u32 ast2600_a1_axi_ahb_div_table[] = {
- 4, 6, 2, 4,
+static const u32 ast2600_a1_axi_ahb_div0_tbl[] = {
+ 3, 2, 3, 4,
+};
+
+static const u32 ast2600_a1_axi_ahb_div1_tbl[] = {
+ 3, 4, 6, 8,
+};
+
+static const u32 ast2600_a1_axi_ahb200_tbl[] = {
+ 3, 4, 3, 4, 2, 2, 2, 2,
};
static void __init aspeed_g6_cc(struct regmap *map)
{
struct clk_hw *hw;
- u32 val, div, chip_id, axi_div, ahb_div;
+ u32 val, div, divbits, chip_id, axi_div, ahb_div;
clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, 25000000);
@@ -679,11 +687,22 @@ static void __init aspeed_g6_cc(struct regmap *map)
else
axi_div = 2;
+ divbits = (val >> 11) & 0x3;
regmap_read(map, ASPEED_G6_SILICON_REV, &chip_id);
- if (chip_id & BIT(16))
- ahb_div = ast2600_a1_axi_ahb_div_table[(val >> 11) & 0x3];
- else
+ if (chip_id & BIT(16)) {
+ if (!divbits) {
+ ahb_div = ast2600_a1_axi_ahb200_tbl[(val >> 8) & 0x3];
+ if (val & BIT(16))
+ ahb_div *= 2;
+ } else {
+ if (val & BIT(16))
+ ahb_div = ast2600_a1_axi_ahb_div1_tbl[divbits];
+ else
+ ahb_div = ast2600_a1_axi_ahb_div0_tbl[divbits];
+ }
+ } else {
ahb_div = ast2600_a0_axi_ahb_div_table[(val >> 11) & 0x3];
+ }
hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, axi_div * ahb_div);
aspeed_g6_clk_data->hws[ASPEED_CLK_AHB] = hw;
diff --git a/drivers/clk/clk-hsdk-pll.c b/drivers/clk/clk-hsdk-pll.c
index 97d1e8c35b71..b4f8852201cb 100644
--- a/drivers/clk/clk-hsdk-pll.c
+++ b/drivers/clk/clk-hsdk-pll.c
@@ -53,35 +53,38 @@ struct hsdk_pll_cfg {
u32 fbdiv;
u32 odiv;
u32 band;
+ u32 bypass;
};
static const struct hsdk_pll_cfg asdt_pll_cfg[] = {
- { 100000000, 0, 11, 3, 0 },
- { 133000000, 0, 15, 3, 0 },
- { 200000000, 1, 47, 3, 0 },
- { 233000000, 1, 27, 2, 0 },
- { 300000000, 1, 35, 2, 0 },
- { 333000000, 1, 39, 2, 0 },
- { 400000000, 1, 47, 2, 0 },
- { 500000000, 0, 14, 1, 0 },
- { 600000000, 0, 17, 1, 0 },
- { 700000000, 0, 20, 1, 0 },
- { 800000000, 0, 23, 1, 0 },
- { 900000000, 1, 26, 0, 0 },
- { 1000000000, 1, 29, 0, 0 },
- { 1100000000, 1, 32, 0, 0 },
- { 1200000000, 1, 35, 0, 0 },
- { 1300000000, 1, 38, 0, 0 },
- { 1400000000, 1, 41, 0, 0 },
- { 1500000000, 1, 44, 0, 0 },
- { 1600000000, 1, 47, 0, 0 },
+ { 100000000, 0, 11, 3, 0, 0 },
+ { 133000000, 0, 15, 3, 0, 0 },
+ { 200000000, 1, 47, 3, 0, 0 },
+ { 233000000, 1, 27, 2, 0, 0 },
+ { 300000000, 1, 35, 2, 0, 0 },
+ { 333000000, 1, 39, 2, 0, 0 },
+ { 400000000, 1, 47, 2, 0, 0 },
+ { 500000000, 0, 14, 1, 0, 0 },
+ { 600000000, 0, 17, 1, 0, 0 },
+ { 700000000, 0, 20, 1, 0, 0 },
+ { 800000000, 0, 23, 1, 0, 0 },
+ { 900000000, 1, 26, 0, 0, 0 },
+ { 1000000000, 1, 29, 0, 0, 0 },
+ { 1100000000, 1, 32, 0, 0, 0 },
+ { 1200000000, 1, 35, 0, 0, 0 },
+ { 1300000000, 1, 38, 0, 0, 0 },
+ { 1400000000, 1, 41, 0, 0, 0 },
+ { 1500000000, 1, 44, 0, 0, 0 },
+ { 1600000000, 1, 47, 0, 0, 0 },
{}
};
static const struct hsdk_pll_cfg hdmi_pll_cfg[] = {
- { 297000000, 0, 21, 2, 0 },
- { 540000000, 0, 19, 1, 0 },
- { 594000000, 0, 21, 1, 0 },
+ { 27000000, 0, 0, 0, 0, 1 },
+ { 148500000, 0, 21, 3, 0, 0 },
+ { 297000000, 0, 21, 2, 0, 0 },
+ { 540000000, 0, 19, 1, 0, 0 },
+ { 594000000, 0, 21, 1, 0, 0 },
{}
};
@@ -134,11 +137,16 @@ static inline void hsdk_pll_set_cfg(struct hsdk_pll_clk *clk,
{
u32 val = 0;
- /* Powerdown and Bypass bits should be cleared */
- val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT;
- val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT;
- val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT;
- val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT;
+ if (cfg->bypass) {
+ val = hsdk_pll_read(clk, CGU_PLL_CTRL);
+ val |= CGU_PLL_CTRL_BYPASS;
+ } else {
+ /* Powerdown and Bypass bits should be cleared */
+ val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT;
+ val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT;
+ val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT;
+ val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT;
+ }
dev_dbg(clk->dev, "write configuration: %#x\n", val);
@@ -172,14 +180,14 @@ static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw,
dev_dbg(clk->dev, "current configuration: %#x\n", val);
- /* Check if PLL is disabled */
- if (val & CGU_PLL_CTRL_PD)
- return 0;
-
/* Check if PLL is bypassed */
if (val & CGU_PLL_CTRL_BYPASS)
return parent_rate;
+ /* Check if PLL is disabled */
+ if (val & CGU_PLL_CTRL_PD)
+ return 0;
+
/* input divider = reg.idiv + 1 */
idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT);
/* fb divider = 2*(reg.fbdiv + 1) */
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
index 3c228b018116..3d7acab9d280 100644
--- a/drivers/clk/clk-si5341.c
+++ b/drivers/clk/clk-si5341.c
@@ -1,8 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Driver for Silicon Labs Si5341/Si5340 Clock generator
+ * Driver for Silicon Labs Si5340, Si5341, Si5342, Si5344 and Si5345
* Copyright (C) 2019 Topic Embedded Products
* Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * The Si5341 has 10 outputs and 5 synthesizers.
+ * The Si5340 is a smaller version of the Si5341 with only 4 outputs.
+ * The Si5345 is similar to the Si5341, with the addition of fractional input
+ * dividers and automatic input selection.
+ * The Si5342 and Si5344 are smaller versions of the Si5345.
*/
#include <linux/clk.h>
@@ -18,11 +24,17 @@
#define SI5341_NUM_INPUTS 4
-#define SI5341_MAX_NUM_OUTPUTS 10
#define SI5340_MAX_NUM_OUTPUTS 4
+#define SI5341_MAX_NUM_OUTPUTS 10
+#define SI5342_MAX_NUM_OUTPUTS 2
+#define SI5344_MAX_NUM_OUTPUTS 4
+#define SI5345_MAX_NUM_OUTPUTS 10
-#define SI5341_NUM_SYNTH 5
#define SI5340_NUM_SYNTH 4
+#define SI5341_NUM_SYNTH 5
+#define SI5342_NUM_SYNTH 2
+#define SI5344_NUM_SYNTH 4
+#define SI5345_NUM_SYNTH 5
/* Range of the synthesizer fractional divider */
#define SI5341_SYNTH_N_MIN 10
@@ -65,6 +77,7 @@ struct clk_si5341 {
u64 freq_vco; /* 13500–14256 MHz */
u8 num_outputs;
u8 num_synth;
+ u16 chip_id;
};
#define to_clk_si5341(_hw) container_of(_hw, struct clk_si5341, hw)
@@ -142,6 +155,7 @@ static const char * const si5341_input_clock_names[] = {
};
/* Output configuration registers 0..9 are not quite logically organized */
+/* Also for si5345 */
static const u16 si5341_reg_output_offset[] = {
0x0108,
0x010D,
@@ -155,6 +169,7 @@ static const u16 si5341_reg_output_offset[] = {
0x013A,
};
+/* for si5340, si5342 and si5344 */
static const u16 si5340_reg_output_offset[] = {
0x0112,
0x0117,
@@ -974,12 +989,32 @@ static int si5341_probe_chip_id(struct clk_si5341 *data)
data->reg_output_offset = si5341_reg_output_offset;
data->reg_rdiv_offset = si5341_reg_rdiv_offset;
break;
+ case 0x5342:
+ data->num_outputs = SI5342_MAX_NUM_OUTPUTS;
+ data->num_synth = SI5342_NUM_SYNTH;
+ data->reg_output_offset = si5340_reg_output_offset;
+ data->reg_rdiv_offset = si5340_reg_rdiv_offset;
+ break;
+ case 0x5344:
+ data->num_outputs = SI5344_MAX_NUM_OUTPUTS;
+ data->num_synth = SI5344_NUM_SYNTH;
+ data->reg_output_offset = si5340_reg_output_offset;
+ data->reg_rdiv_offset = si5340_reg_rdiv_offset;
+ break;
+ case 0x5345:
+ data->num_outputs = SI5345_MAX_NUM_OUTPUTS;
+ data->num_synth = SI5345_NUM_SYNTH;
+ data->reg_output_offset = si5341_reg_output_offset;
+ data->reg_rdiv_offset = si5341_reg_rdiv_offset;
+ break;
default:
dev_err(&data->i2c_client->dev, "Model '%x' not supported\n",
model);
return -EINVAL;
}
+ data->chip_id = model;
+
return 0;
}
@@ -1054,6 +1089,11 @@ static const struct si5341_reg_default si5341_preamble[] = {
{ 0x0B4E, 0x1A },
};
+static const struct si5341_reg_default si5345_preamble[] = {
+ { 0x0B25, 0x00 },
+ { 0x0540, 0x01 },
+};
+
static int si5341_send_preamble(struct clk_si5341 *data)
{
int res;
@@ -1068,8 +1108,14 @@ static int si5341_send_preamble(struct clk_si5341 *data)
res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xD8 : 0xC0);
if (res < 0)
return res;
- res = si5341_write_multiple(data,
- si5341_preamble, ARRAY_SIZE(si5341_preamble));
+
+ /* The si5342..si5345 require a different preamble */
+ if (data->chip_id > 0x5341)
+ res = si5341_write_multiple(data,
+ si5345_preamble, ARRAY_SIZE(si5345_preamble));
+ else
+ res = si5341_write_multiple(data,
+ si5341_preamble, ARRAY_SIZE(si5341_preamble));
if (res < 0)
return res;
@@ -1095,6 +1141,13 @@ static int si5341_finalize_defaults(struct clk_si5341 *data)
if (res < 0)
return res;
+ /* The si5342..si5345 have an additional post-amble */
+ if (data->chip_id > 0x5341) {
+ res = regmap_write(data->regmap, 0x540, 0x0);
+ if (res < 0)
+ return res;
+ }
+
/* Datasheet does not explain these nameless registers */
res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xDB : 0xC3);
if (res < 0)
@@ -1499,6 +1552,9 @@ static int si5341_probe(struct i2c_client *client,
static const struct i2c_device_id si5341_id[] = {
{ "si5340", 0 },
{ "si5341", 1 },
+ { "si5342", 2 },
+ { "si5344", 4 },
+ { "si5345", 5 },
{ }
};
MODULE_DEVICE_TABLE(i2c, si5341_id);
@@ -1506,6 +1562,9 @@ MODULE_DEVICE_TABLE(i2c, si5341_id);
static const struct of_device_id clk_si5341_of_match[] = {
{ .compatible = "silabs,si5340" },
{ .compatible = "silabs,si5341" },
+ { .compatible = "silabs,si5342" },
+ { .compatible = "silabs,si5344" },
+ { .compatible = "silabs,si5345" },
{ }
};
MODULE_DEVICE_TABLE(of, clk_si5341_of_match);
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 24fef51fbcb5..fa96659f8023 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -124,6 +124,7 @@ enum vc5_model {
IDT_VC5_5P49V5933,
IDT_VC5_5P49V5935,
IDT_VC6_5P49V6901,
+ IDT_VC6_5P49V6965,
};
/* Structure to describe features of a particular VC5 model */
@@ -683,6 +684,7 @@ static int vc5_map_index_to_output(const enum vc5_model model,
case IDT_VC5_5P49V5925:
case IDT_VC5_5P49V5935:
case IDT_VC6_5P49V6901:
+ case IDT_VC6_5P49V6965:
default:
return n;
}
@@ -956,12 +958,20 @@ static const struct vc5_chip_info idt_5p49v6901_info = {
.flags = VC5_HAS_PFD_FREQ_DBL,
};
+static const struct vc5_chip_info idt_5p49v6965_info = {
+ .model = IDT_VC6_5P49V6965,
+ .clk_fod_cnt = 4,
+ .clk_out_cnt = 5,
+ .flags = 0,
+};
+
static const struct i2c_device_id vc5_id[] = {
{ "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
{ "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
{ "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
{ "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
{ "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
+ { "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
{ }
};
MODULE_DEVICE_TABLE(i2c, vc5_id);
@@ -972,6 +982,7 @@ static const struct of_device_id clk_vc5_of_match[] = {
{ .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
{ .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
{ .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
+ { .compatible = "idt,5p49v6965", .data = &idt_5p49v6965_info },
{ },
};
MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 407f6919604c..3f588ed06ce3 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3299,10 +3299,6 @@ static int __init clk_debug_init(void)
late_initcall(clk_debug_init);
#else
static inline void clk_debug_register(struct clk_core *core) { }
-static inline void clk_debug_reparent(struct clk_core *core,
- struct clk_core *new_parent)
-{
-}
static inline void clk_debug_unregister(struct clk_core *core)
{
}
diff --git a/drivers/clk/imgtec/Kconfig b/drivers/clk/imgtec/Kconfig
index 30f5265cca8d..c965fd0917dd 100644
--- a/drivers/clk/imgtec/Kconfig
+++ b/drivers/clk/imgtec/Kconfig
@@ -3,7 +3,7 @@ config COMMON_CLK_BOSTON
bool "Clock driver for MIPS Boston boards"
depends on MIPS || COMPILE_TEST
select MFD_SYSCON
- ---help---
+ help
Enable this to support the system & CPU clocks on the MIPS Boston
development board from Imagination Technologies. These are simple
fixed rate clocks whose rate is determined by reading a platform
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 01eadee88d66..db0253fa3d64 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -10,25 +10,25 @@ config MXC_CLK_SCU
config CLK_IMX8MM
bool "IMX8MM CCM Clock Driver"
- depends on ARCH_MXC && ARM64
+ depends on ARCH_MXC
help
Build the driver for i.MX8MM CCM Clock Driver
config CLK_IMX8MN
bool "IMX8MN CCM Clock Driver"
- depends on ARCH_MXC && ARM64
+ depends on ARCH_MXC
help
Build the driver for i.MX8MN CCM Clock Driver
config CLK_IMX8MP
bool "IMX8MP CCM Clock Driver"
- depends on ARCH_MXC && ARM64
+ depends on ARCH_MXC
help
Build the driver for i.MX8MP CCM Clock Driver
config CLK_IMX8MQ
bool "IMX8MQ CCM Clock Driver"
- depends on ARCH_MXC && ARM64
+ depends on ARCH_MXC
help
Build the driver for i.MX8MQ CCM Clock Driver
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
index 99773519b5a5..d2b5af826f2c 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -124,6 +124,52 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
.set_rate = imx8m_clk_composite_divider_set_rate,
};
+static u8 imx8m_clk_composite_mux_get_parent(struct clk_hw *hw)
+{
+ return clk_mux_ops.get_parent(hw);
+}
+
+static int imx8m_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_mux *mux = to_clk_mux(hw);
+ u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
+ unsigned long flags = 0;
+ u32 reg;
+
+ if (mux->lock)
+ spin_lock_irqsave(mux->lock, flags);
+
+ reg = readl(mux->reg);
+ reg &= ~(mux->mask << mux->shift);
+ val = val << mux->shift;
+ reg |= val;
+ /*
+ * write twice to make sure non-target interface
+ * SEL_A/B point the same clk input.
+ */
+ writel(reg, mux->reg);
+ writel(reg, mux->reg);
+
+ if (mux->lock)
+ spin_unlock_irqrestore(mux->lock, flags);
+
+ return 0;
+}
+
+static int
+imx8m_clk_composite_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ return clk_mux_ops.determine_rate(hw, req);
+}
+
+
+static const struct clk_ops imx8m_clk_composite_mux_ops = {
+ .get_parent = imx8m_clk_composite_mux_get_parent,
+ .set_parent = imx8m_clk_composite_mux_set_parent,
+ .determine_rate = imx8m_clk_composite_mux_determine_rate,
+};
+
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
const char * const *parent_names,
int num_parents, void __iomem *reg,
@@ -136,6 +182,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
struct clk_gate *gate = NULL;
struct clk_mux *mux = NULL;
const struct clk_ops *divider_ops;
+ const struct clk_ops *mux_ops;
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
@@ -157,10 +204,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
div->shift = PCG_DIV_SHIFT;
div->width = PCG_CORE_DIV_WIDTH;
divider_ops = &clk_divider_ops;
+ mux_ops = &imx8m_clk_composite_mux_ops;
+ } else if (composite_flags & IMX_COMPOSITE_BUS) {
+ div->shift = PCG_PREDIV_SHIFT;
+ div->width = PCG_PREDIV_WIDTH;
+ divider_ops = &imx8m_clk_composite_divider_ops;
+ mux_ops = &imx8m_clk_composite_mux_ops;
} else {
div->shift = PCG_PREDIV_SHIFT;
div->width = PCG_PREDIV_WIDTH;
divider_ops = &imx8m_clk_composite_divider_ops;
+ mux_ops = &clk_mux_ops;
}
div->lock = &imx_ccm_lock;
@@ -176,7 +230,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
gate->lock = &imx_ccm_lock;
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
- mux_hw, &clk_mux_ops, div_hw,
+ mux_hw, mux_ops, div_hw,
divider_ops, gate_hw, &clk_gate_ops, flags);
if (IS_ERR(hw))
goto fail;
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index ce0060e8873e..b87ab3c3ba1e 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -41,21 +41,26 @@ static int clk_gate2_enable(struct clk_hw *hw)
struct clk_gate2 *gate = to_clk_gate2(hw);
u32 reg;
unsigned long flags;
+ int ret = 0;
spin_lock_irqsave(gate->lock, flags);
if (gate->share_count && (*gate->share_count)++ > 0)
goto out;
- reg = readl(gate->reg);
- reg &= ~(3 << gate->bit_idx);
- reg |= gate->cgr_val << gate->bit_idx;
- writel(reg, gate->reg);
+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
+ ret = clk_gate_ops.enable(hw);
+ } else {
+ reg = readl(gate->reg);
+ reg &= ~(3 << gate->bit_idx);
+ reg |= gate->cgr_val << gate->bit_idx;
+ writel(reg, gate->reg);
+ }
out:
spin_unlock_irqrestore(gate->lock, flags);
- return 0;
+ return ret;
}
static void clk_gate2_disable(struct clk_hw *hw)
@@ -73,9 +78,13 @@ static void clk_gate2_disable(struct clk_hw *hw)
goto out;
}
- reg = readl(gate->reg);
- reg &= ~(3 << gate->bit_idx);
- writel(reg, gate->reg);
+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
+ clk_gate_ops.disable(hw);
+ } else {
+ reg = readl(gate->reg);
+ reg &= ~(3 << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
out:
spin_unlock_irqrestore(gate->lock, flags);
@@ -95,6 +104,9 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
{
struct clk_gate2 *gate = to_clk_gate2(hw);
+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
+ return clk_gate_ops.is_enabled(hw);
+
return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
}
@@ -104,6 +116,9 @@ static void clk_gate2_disable_unused(struct clk_hw *hw)
unsigned long flags;
u32 reg;
+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
+ return;
+
spin_lock_irqsave(gate->lock, flags);
if (!gate->share_count || *gate->share_count == 0) {
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index dafc8806b03e..5dbb6a937732 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -503,7 +503,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clk_prepare_enable(hws[IMX6UL_CLK_USBPHY2_GATE]->clk);
}
- clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_60M]->clk);
+ clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_80M]->clk);
if (clk_on_imx6ul())
clk_set_parent(hws[IMX6UL_CLK_SIM_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_USB_OTG]->clk);
else if (clk_on_imx6ull())
diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c
index 3710aa0dee9b..634c0b6636b0 100644
--- a/drivers/clk/imx/clk-imx7ulp.c
+++ b/drivers/clk/imx/clk-imx7ulp.c
@@ -29,7 +29,7 @@ static const char * const ddr_sels[] = { "apll_pfd_sel", "dummy", "dummy", "dum
static const char * const nic_sels[] = { "firc", "ddr_clk", };
static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", };
static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", };
-static const char * const arm_sels[] = { "divcore", "dummy", "dummy", "hsrun_divcore", };
+static const char * const arm_sels[] = { "core", "dummy", "dummy", "hsrun_core", };
/* used by sosc/sirc/firc/ddr/spll/apll dividers */
static const struct clk_div_table ulp_div_table[] = {
@@ -121,7 +121,9 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
hws[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
hws[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
+ hws[IMX7ULP_CLK_CORE] = imx_clk_hw_cpu("core", "divcore", hws[IMX7ULP_CLK_CORE_DIV]->clk, hws[IMX7ULP_CLK_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
+ hws[IMX7ULP_CLK_HSRUN_CORE] = imx_clk_hw_cpu("hsrun_core", "hsrun_divcore", hws[IMX7ULP_CLK_HSRUN_CORE_DIV]->clk, hws[IMX7ULP_CLK_HSRUN_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
hws[IMX7ULP_CLK_DDR_DIV] = imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
0, ulp_div_table, &imx_ccm_lock);
@@ -270,7 +272,7 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
base = of_iomap(np, 0);
WARN_ON(!base);
- hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
+ hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_SET_RATE_PARENT);
imx_check_clk_hws(hws, clk_data->num);
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 925670438f23..b793264c21c6 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -416,9 +416,9 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
return PTR_ERR(base);
/* Core Slice */
- hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
- hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
- hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+ hws[IMX8MM_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mm_a53_sels, base + 0x8000);
+ hws[IMX8MM_CLK_A53_CG] = hws[IMX8MM_CLK_A53_DIV];
+ hws[IMX8MM_CLK_A53_SRC] = hws[IMX8MM_CLK_A53_DIV];
hws[IMX8MM_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mm_m4_sels, base + 0x8080);
hws[IMX8MM_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mm_vpu_sels, base + 0x8100);
@@ -444,21 +444,21 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
/* BUS */
hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
- hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
+ hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
- hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
- hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
- hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
- hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
- hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
- hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
- hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
+ hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
+ hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
+ hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
+ hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite_bus("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
+ hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
+ hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
+ hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
hws[IMX8MM_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
hws[IMX8MM_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
/* AHB */
hws[IMX8MM_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
- hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
+ hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
/* IPG */
hws[IMX8MM_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
@@ -614,9 +614,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
hws[IMX8MM_ARM_PLL_OUT]->clk,
hws[IMX8MM_CLK_A53_DIV]->clk);
- clk_hw_set_parent(hws[IMX8MM_CLK_A53_SRC], hws[IMX8MM_SYS_PLL1_800M]);
- clk_hw_set_parent(hws[IMX8MM_CLK_A53_CORE], hws[IMX8MM_ARM_PLL_OUT]);
-
imx_check_clk_hws(hws, IMX8MM_CLK_END);
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 0bc7070235bd..213cc37b3173 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -413,9 +413,9 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
}
/* CORE */
- hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
- hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
- hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+ hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
+ hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
+ hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
@@ -432,17 +432,17 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
/* BUS */
hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
- hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
- hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
- hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
- hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
- hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
- hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
- hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
+ hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
+ hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
+ hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
+ hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
+ hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
+ hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
+ hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
- hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
+ hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
@@ -565,9 +565,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
hws[IMX8MN_ARM_PLL_OUT]->clk,
hws[IMX8MN_CLK_A53_DIV]->clk);
- clk_hw_set_parent(hws[IMX8MN_CLK_A53_SRC], hws[IMX8MN_SYS_PLL1_800M]);
- clk_hw_set_parent(hws[IMX8MN_CLK_A53_CORE], hws[IMX8MN_ARM_PLL_OUT]);
-
imx_check_clk_hws(hws, IMX8MN_CLK_END);
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 41469e2cc3de..b4d9db9d5bf1 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -486,16 +486,16 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
- hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
- hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
@@ -504,79 +504,82 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
- hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
- hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
- hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
- hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
- hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
- hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
- hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
- hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
- hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
- hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+ hws[IMX8MP_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1_bypass", anatop_base + 0x94, 27);
+ hws[IMX8MP_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1_bypass", anatop_base + 0x94, 25);
+ hws[IMX8MP_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1_bypass", anatop_base + 0x94, 23);
+ hws[IMX8MP_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1_bypass", anatop_base + 0x94, 21);
+ hws[IMX8MP_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1_bypass", anatop_base + 0x94, 19);
+ hws[IMX8MP_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1_bypass", anatop_base + 0x94, 17);
+ hws[IMX8MP_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1_bypass", anatop_base + 0x94, 15);
+ hws[IMX8MP_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1_bypass", anatop_base + 0x94, 13);
+ hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
+
+ hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
+ hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
+ hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
+ hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
+ hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
+ hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
+ hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
+ hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
- hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
- hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
- hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
- hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
- hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
- hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
- hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
- hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+ hws[IMX8MP_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2_bypass", anatop_base + 0x104, 27);
+ hws[IMX8MP_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2_bypass", anatop_base + 0x104, 25);
+ hws[IMX8MP_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2_bypass", anatop_base + 0x104, 23);
+ hws[IMX8MP_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2_bypass", anatop_base + 0x104, 21);
+ hws[IMX8MP_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2_bypass", anatop_base + 0x104, 19);
+ hws[IMX8MP_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2_bypass", anatop_base + 0x104, 17);
+ hws[IMX8MP_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2_bypass", anatop_base + 0x104, 15);
+ hws[IMX8MP_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2_bypass", anatop_base + 0x104, 13);
+ hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
+
+ hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
+ hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
+ hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
+ hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
+ hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
+ hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
+ hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
+ hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
- hws[IMX8MP_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", ccm_base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels));
- hws[IMX8MP_CLK_M7_SRC] = imx_clk_hw_mux2("arm_m7_src", ccm_base + 0x8080, 24, 3, imx8mp_m7_sels, ARRAY_SIZE(imx8mp_m7_sels));
- hws[IMX8MP_CLK_ML_SRC] = imx_clk_hw_mux2("ml_src", ccm_base + 0x8100, 24, 3, imx8mp_ml_sels, ARRAY_SIZE(imx8mp_ml_sels));
- hws[IMX8MP_CLK_GPU3D_CORE_SRC] = imx_clk_hw_mux2("gpu3d_core_src", ccm_base + 0x8180, 24, 3, imx8mp_gpu3d_core_sels, ARRAY_SIZE(imx8mp_gpu3d_core_sels));
- hws[IMX8MP_CLK_GPU3D_SHADER_SRC] = imx_clk_hw_mux2("gpu3d_shader_src", ccm_base + 0x8200, 24, 3, imx8mp_gpu3d_shader_sels, ARRAY_SIZE(imx8mp_gpu3d_shader_sels));
- hws[IMX8MP_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", ccm_base + 0x8280, 24, 3, imx8mp_gpu2d_sels, ARRAY_SIZE(imx8mp_gpu2d_sels));
- hws[IMX8MP_CLK_AUDIO_AXI_SRC] = imx_clk_hw_mux2("audio_axi_src", ccm_base + 0x8300, 24, 3, imx8mp_audio_axi_sels, ARRAY_SIZE(imx8mp_audio_axi_sels));
- hws[IMX8MP_CLK_HSIO_AXI_SRC] = imx_clk_hw_mux2("hsio_axi_src", ccm_base + 0x8380, 24, 3, imx8mp_hsio_axi_sels, ARRAY_SIZE(imx8mp_hsio_axi_sels));
- hws[IMX8MP_CLK_MEDIA_ISP_SRC] = imx_clk_hw_mux2("media_isp_src", ccm_base + 0x8400, 24, 3, imx8mp_media_isp_sels, ARRAY_SIZE(imx8mp_media_isp_sels));
- hws[IMX8MP_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", ccm_base + 0x8000, 28);
- hws[IMX8MP_CLK_M4_CG] = imx_clk_hw_gate3("arm_m7_cg", "arm_m7_src", ccm_base + 0x8080, 28);
- hws[IMX8MP_CLK_ML_CG] = imx_clk_hw_gate3("ml_cg", "ml_src", ccm_base + 0x8100, 28);
- hws[IMX8MP_CLK_GPU3D_CORE_CG] = imx_clk_hw_gate3("gpu3d_core_cg", "gpu3d_core_src", ccm_base + 0x8180, 28);
- hws[IMX8MP_CLK_GPU3D_SHADER_CG] = imx_clk_hw_gate3("gpu3d_shader_cg", "gpu3d_shader_src", ccm_base + 0x8200, 28);
- hws[IMX8MP_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", ccm_base + 0x8280, 28);
- hws[IMX8MP_CLK_AUDIO_AXI_CG] = imx_clk_hw_gate3("audio_axi_cg", "audio_axi_src", ccm_base + 0x8300, 28);
- hws[IMX8MP_CLK_HSIO_AXI_CG] = imx_clk_hw_gate3("hsio_axi_cg", "hsio_axi_src", ccm_base + 0x8380, 28);
- hws[IMX8MP_CLK_MEDIA_ISP_CG] = imx_clk_hw_gate3("media_isp_cg", "media_isp_src", ccm_base + 0x8400, 28);
- hws[IMX8MP_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", ccm_base + 0x8000, 0, 3);
- hws[IMX8MP_CLK_M7_DIV] = imx_clk_hw_divider2("arm_m7_div", "arm_m7_cg", ccm_base + 0x8080, 0, 3);
- hws[IMX8MP_CLK_ML_DIV] = imx_clk_hw_divider2("ml_div", "ml_cg", ccm_base + 0x8100, 0, 3);
- hws[IMX8MP_CLK_GPU3D_CORE_DIV] = imx_clk_hw_divider2("gpu3d_core_div", "gpu3d_core_cg", ccm_base + 0x8180, 0, 3);
- hws[IMX8MP_CLK_GPU3D_SHADER_DIV] = imx_clk_hw_divider2("gpu3d_shader_div", "gpu3d_shader_cg", ccm_base + 0x8200, 0, 3);
- hws[IMX8MP_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", ccm_base + 0x8280, 0, 3);
- hws[IMX8MP_CLK_AUDIO_AXI_DIV] = imx_clk_hw_divider2("audio_axi_div", "audio_axi_cg", ccm_base + 0x8300, 0, 3);
- hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3);
- hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3);
+ hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
+ hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
+ hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
+ hws[IMX8MP_CLK_M7_CORE] = imx8m_clk_hw_composite_core("m7_core", imx8mp_m7_sels, ccm_base + 0x8080);
+ hws[IMX8MP_CLK_ML_CORE] = imx8m_clk_hw_composite_core("ml_core", imx8mp_ml_sels, ccm_base + 0x8100);
+ hws[IMX8MP_CLK_GPU3D_CORE] = imx8m_clk_hw_composite_core("gpu3d_core", imx8mp_gpu3d_core_sels, ccm_base + 0x8180);
+ hws[IMX8MP_CLK_GPU3D_SHADER_CORE] = imx8m_clk_hw_composite("gpu3d_shader_core", imx8mp_gpu3d_shader_sels, ccm_base + 0x8200);
+ hws[IMX8MP_CLK_GPU2D_CORE] = imx8m_clk_hw_composite("gpu2d_core", imx8mp_gpu2d_sels, ccm_base + 0x8280);
+ hws[IMX8MP_CLK_AUDIO_AXI] = imx8m_clk_hw_composite("audio_axi", imx8mp_audio_axi_sels, ccm_base + 0x8300);
+ hws[IMX8MP_CLK_AUDIO_AXI_SRC] = hws[IMX8MP_CLK_AUDIO_AXI];
+ hws[IMX8MP_CLK_HSIO_AXI] = imx8m_clk_hw_composite("hsio_axi", imx8mp_hsio_axi_sels, ccm_base + 0x8380);
+ hws[IMX8MP_CLK_MEDIA_ISP] = imx8m_clk_hw_composite("media_isp", imx8mp_media_isp_sels, ccm_base + 0x8400);
/* CORE SEL */
hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels));
hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
- hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
+ hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
- hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
- hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
- hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
- hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
- hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
- hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
- hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
+ hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
+ hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite_bus("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
+ hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite_bus("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
+ hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite_bus("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
+ hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite_bus("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
+ hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
+ hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
- hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
- hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
+ hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite_bus("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
+ hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite_bus("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
- hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
- hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
+ hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
+ hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1);
@@ -695,8 +698,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
- hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", ccm_base + 0x4450, 0);
- hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core_div", ccm_base + 0x4460, 0);
+ hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
+ hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0);
hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
@@ -713,7 +716,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
- hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_div", ccm_base + 0x45b0, 0);
+ hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_core", ccm_base + 0x45b0, 0);
hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
@@ -721,7 +724,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
- hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp_div", ccm_base + 0x45d0, 0, &share_count_media);
+ hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media);
hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
@@ -735,9 +738,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_ARM_PLL_OUT]->clk,
hws[IMX8MP_CLK_A53_DIV]->clk);
- clk_hw_set_parent(hws[IMX8MP_CLK_A53_SRC], hws[IMX8MP_SYS_PLL1_800M]);
- clk_hw_set_parent(hws[IMX8MP_CLK_A53_CORE], hws[IMX8MP_ARM_PLL_OUT]);
-
imx_check_clk_hws(hws, IMX8MP_CLK_END);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index fdc68db68de5..a64aace213c2 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -405,9 +405,9 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
return PTR_ERR(base);
/* CORE */
- hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
- hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
- hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+ hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000);
+ hws[IMX8MQ_CLK_A53_CG] = hws[IMX8MQ_CLK_A53_DIV];
+ hws[IMX8MQ_CLK_A53_SRC] = hws[IMX8MQ_CLK_A53_DIV];
hws[IMX8MQ_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mq_arm_m4_sels, base + 0x8080);
hws[IMX8MQ_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mq_vpu_sels, base + 0x8100);
@@ -432,22 +432,22 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
/* BUS */
hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
- hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
- hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
- hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
- hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
- hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
- hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
- hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
- hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
- hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
+ hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
+ hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
+ hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
+ hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
+ hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
+ hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite_bus("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
+ hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
+ hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
+ hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
hws[IMX8MQ_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
hws[IMX8MQ_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
/* AHB */
/* AHB clock is used by the AHB bus therefore marked as critical */
hws[IMX8MQ_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
- hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
+ hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
/* IPG */
hws[IMX8MQ_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
@@ -599,9 +599,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
hws[IMX8MQ_ARM_PLL_OUT]->clk,
hws[IMX8MQ_CLK_A53_DIV]->clk);
- clk_hw_set_parent(hws[IMX8MQ_CLK_A53_SRC], hws[IMX8MQ_SYS1_PLL_800M]);
- clk_hw_set_parent(hws[IMX8MQ_CLK_A53_CORE], hws[IMX8MQ_ARM_PLL_OUT]);
-
imx_check_clk_hws(hws, IMX8MQ_CLK_END);
err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index a83bbbee77d9..f9eb189b93c0 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -378,9 +378,9 @@ static const struct clk_ops clk_pll1443x_ops = {
.set_rate = clk_pll1443x_set_rate,
};
-struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
- void __iomem *base,
- const struct imx_pll14xx_clk *pll_clk)
+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
+ const char *parent_name, void __iomem *base,
+ const struct imx_pll14xx_clk *pll_clk)
{
struct clk_pll14xx *pll;
struct clk_hw *hw;
@@ -426,7 +426,7 @@ struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
hw = &pll->hw;
- ret = clk_hw_register(NULL, hw);
+ ret = clk_hw_register(dev, hw);
if (ret) {
pr_err("%s: failed to register pll %s %d\n",
__func__, name, ret);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index df91a8244fb4..a7db93030e02 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -7,6 +7,7 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/err.h>
@@ -25,6 +26,8 @@
#define IMX7_ENET_PLL_POWER (0x1 << 5)
#define IMX7_DDR_PLL_POWER (0x1 << 20)
+#define PLL_LOCK_TIMEOUT 10000
+
/**
* struct clk_pllv3 - IMX PLL clock version 3
* @clk_hw: clock source
@@ -53,23 +56,14 @@ struct clk_pllv3 {
static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
{
- unsigned long timeout = jiffies + msecs_to_jiffies(10);
u32 val = readl_relaxed(pll->base) & pll->power_bit;
/* No need to wait for lock when pll is not powered up */
if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
return 0;
- /* Wait for PLL to lock */
- do {
- if (readl_relaxed(pll->base) & BM_PLL_LOCK)
- break;
- if (time_after(jiffies, timeout))
- break;
- usleep_range(50, 500);
- } while (1);
-
- return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
+ return readl_relaxed_poll_timeout(pll->base, val, val & BM_PLL_LOCK,
+ 500, PLL_LOCK_TIMEOUT);
}
static int clk_pllv3_prepare(struct clk_hw *hw)
diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c
index d4a2be16d132..773d8a545cdf 100644
--- a/drivers/clk/imx/clk-sscg-pll.c
+++ b/drivers/clk/imx/clk-sscg-pll.c
@@ -72,7 +72,6 @@ struct clk_sscg_pll_setup {
int divr2, divf2;
int divq;
int bypass;
-
uint64_t vco1;
uint64_t vco2;
uint64_t fout;
@@ -86,11 +85,8 @@ struct clk_sscg_pll_setup {
struct clk_sscg_pll {
struct clk_hw hw;
const struct clk_ops ops;
-
void __iomem *base;
-
struct clk_sscg_pll_setup setup;
-
u8 parent;
u8 bypass1;
u8 bypass2;
@@ -194,7 +190,6 @@ static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup,
struct clk_sscg_pll_setup *temp_setup,
uint64_t ref)
{
-
int ret;
if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
@@ -253,7 +248,6 @@ static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup,
struct clk_sscg_pll_setup *temp_setup,
uint64_t ref)
{
-
int ret;
if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
@@ -280,7 +274,6 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
temp_setup.fout_request = rate;
switch (try_bypass) {
-
case PLL_BYPASS2:
if (prate == rate) {
setup->bypass = PLL_BYPASS2;
@@ -288,11 +281,9 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
ret = 0;
}
break;
-
case PLL_BYPASS1:
ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate);
break;
-
case PLL_BYPASS_NONE:
ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate);
break;
@@ -301,7 +292,6 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
return ret;
}
-
static int clk_sscg_pll_is_prepared(struct clk_hw *hw)
{
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index f074dd8ec42e..16adbc34e05f 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -5,6 +5,8 @@
#include <linux/spinlock.h>
#include <linux/clk-provider.h>
+#define IMX_CLK_GATE2_SINGLE_BIT 1
+
extern spinlock_t imx_ccm_lock;
void imx_check_clocks(struct clk *clks[], unsigned int count);
@@ -131,9 +133,9 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
#define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
-struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
- void __iomem *base,
- const struct imx_pll14xx_clk *pll_clk);
+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
+ const char *parent_name, void __iomem *base,
+ const struct imx_pll14xx_clk *pll_clk);
struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
const char *parent, void __iomem *base);
@@ -240,6 +242,13 @@ static inline struct clk *to_clk(struct clk_hw *hw)
return hw->clk;
}
+static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
+ void __iomem *base,
+ const struct imx_pll14xx_clk *pll_clk)
+{
+ return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk);
+}
+
static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
{
return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
@@ -310,6 +319,13 @@ static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *paren
shift, 0, &imx_ccm_lock);
}
+static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name,
+ const char *parent, void __iomem *reg, u8 shift)
+{
+ return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock);
+}
+
static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
@@ -355,6 +371,17 @@ static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name,
&imx_ccm_lock, share_count);
}
+static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev,
+ const char *name, const char *parent,
+ void __iomem *reg, u8 shift,
+ unsigned int *share_count)
+{
+ return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
+ CLK_OPS_PARENT_ENABLE, reg, shift, 0x3,
+ IMX_CLK_GATE2_SINGLE_BIT,
+ &imx_ccm_lock, share_count);
+}
+
static inline struct clk *imx_clk_gate2_cgr(const char *name,
const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
{
@@ -411,6 +438,15 @@ static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
width, 0, &imx_ccm_lock);
}
+static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev,
+ const char *name, void __iomem *reg, u8 shift,
+ u8 width, const char * const *parents, int num_parents)
+{
+ return clk_hw_register_mux(dev, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
u8 shift, u8 width, const char * const *parents,
int num_parents)
@@ -473,11 +509,25 @@ static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
reg, shift, width, 0, &imx_ccm_lock);
}
+static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev,
+ const char *name,
+ void __iomem *reg, u8 shift,
+ u8 width,
+ const char * const *parents,
+ int num_parents,
+ unsigned long flags)
+{
+ return clk_hw_register_mux(dev, name, parents, num_parents,
+ flags | CLK_SET_RATE_NO_REPARENT,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step);
#define IMX_COMPOSITE_CORE BIT(0)
+#define IMX_COMPOSITE_BUS BIT(1)
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
const char * const *parent_names,
@@ -486,6 +536,12 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
u32 composite_flags,
unsigned long flags);
+#define imx8m_clk_hw_composite_bus(name, parent_names, reg) \
+ imx8m_clk_hw_composite_flags(name, parent_names, \
+ ARRAY_SIZE(parent_names), reg, \
+ IMX_COMPOSITE_BUS, \
+ CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+
#define imx8m_clk_hw_composite_core(name, parent_names, reg) \
imx8m_clk_hw_composite_flags(name, parent_names, \
ARRAY_SIZE(parent_names), reg, \
diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
index b4555b465ea6..580b0cf69ed5 100644
--- a/drivers/clk/ingenic/Kconfig
+++ b/drivers/clk/ingenic/Kconfig
@@ -55,6 +55,16 @@ config INGENIC_CGU_X1000
If building for a X1000 SoC, you want to say Y here.
+config INGENIC_CGU_X1830
+ bool "Ingenic X1830 CGU driver"
+ default MACH_X1830
+ select INGENIC_CGU_COMMON
+ help
+ Support the clocks provided by the CGU hardware on Ingenic X1830
+ and compatible SoCs.
+
+ If building for a X1830 SoC, you want to say Y here.
+
config INGENIC_TCU_CLK
bool "Ingenic JZ47xx TCU clocks driver"
default MACH_INGENIC
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index 8b1dad9b74a7..aaa4bffe03c6 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o
obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o
+obj-$(CONFIG_INGENIC_CGU_X1830) += x1830-cgu.o
obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 6e963031cd87..d7981b670221 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -76,16 +76,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
const struct ingenic_cgu_pll_info *pll_info;
unsigned m, n, od_enc, od;
bool bypass;
- unsigned long flags;
u32 ctl;
clk_info = &cgu->clock_info[ingenic_clk->idx];
BUG_ON(clk_info->type != CGU_CLK_PLL);
pll_info = &clk_info->pll;
- spin_lock_irqsave(&cgu->lock, flags);
ctl = readl(cgu->base + pll_info->reg);
- spin_unlock_irqrestore(&cgu->lock, flags);
m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
m += pll_info->m_offset;
@@ -93,6 +90,9 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
n += pll_info->n_offset;
od_enc = ctl >> pll_info->od_shift;
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
+
+ ctl = readl(cgu->base + pll_info->bypass_reg);
+
bypass = !pll_info->no_bypass_bit &&
!!(ctl & BIT(pll_info->bypass_bit));
@@ -106,7 +106,8 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
BUG_ON(od == pll_info->od_max);
od++;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static unsigned long
@@ -139,7 +140,8 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
if (pod)
*pod = od;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static inline const struct ingenic_cgu_clk_info *to_clk_info(
@@ -212,9 +214,14 @@ static int ingenic_pll_enable(struct clk_hw *hw)
u32 ctl;
spin_lock_irqsave(&cgu->lock, flags);
- ctl = readl(cgu->base + pll_info->reg);
+ ctl = readl(cgu->base + pll_info->bypass_reg);
ctl &= ~BIT(pll_info->bypass_bit);
+
+ writel(ctl, cgu->base + pll_info->bypass_reg);
+
+ ctl = readl(cgu->base + pll_info->reg);
+
ctl |= BIT(pll_info->enable_bit);
writel(ctl, cgu->base + pll_info->reg);
@@ -259,12 +266,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw)
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
- unsigned long flags;
u32 ctl;
- spin_lock_irqsave(&cgu->lock, flags);
ctl = readl(cgu->base + pll_info->reg);
- spin_unlock_irqrestore(&cgu->lock, flags);
return !!(ctl & BIT(pll_info->enable_bit));
}
@@ -562,16 +566,12 @@ static int ingenic_clk_is_enabled(struct clk_hw *hw)
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info;
- unsigned long flags;
int enabled = 1;
clk_info = &cgu->clock_info[ingenic_clk->idx];
- if (clk_info->type & CGU_CLK_GATE) {
- spin_lock_irqsave(&cgu->lock, flags);
+ if (clk_info->type & CGU_CLK_GATE)
enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
- spin_unlock_irqrestore(&cgu->lock, flags);
- }
return enabled;
}
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 0dc8004079ee..2c75ef4a36f5 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -17,6 +17,7 @@
/**
* struct ingenic_cgu_pll_info - information about a PLL
* @reg: the offset of the PLL's control register within the CGU
+ * @rate_multiplier: the multiplier needed by pll rate calculation
* @m_shift: the number of bits to shift the multiplier value by (ie. the
* index of the lowest bit of the multiplier value in the PLL's
* control register)
@@ -37,6 +38,7 @@
* @od_encoding: a pointer to an array mapping post-VCO divider values to
* their encoded values in the PLL control register, or -1 for
* unsupported values
+ * @bypass_reg: the offset of the bypass control register within the CGU
* @bypass_bit: the index of the bypass bit in the PLL control register
* @enable_bit: the index of the enable bit in the PLL control register
* @stable_bit: the index of the stable bit in the PLL control register
@@ -44,10 +46,12 @@
*/
struct ingenic_cgu_pll_info {
unsigned reg;
+ unsigned rate_multiplier;
const s8 *od_encoding;
u8 m_shift, m_bits, m_offset;
u8 n_shift, n_bits, n_offset;
u8 od_shift, od_bits, od_max;
+ unsigned bypass_reg;
u8 bypass_bit;
u8 enable_bit;
u8 stable_bit;
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
index a3b4635f6278..8c38e72d14a7 100644
--- a/drivers/clk/ingenic/jz4725b-cgu.c
+++ b/drivers/clk/ingenic/jz4725b-cgu.c
@@ -9,7 +9,9 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4725b-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -54,6 +56,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
.pll = {
.reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
.m_shift = 23,
.m_bits = 9,
.m_offset = 2,
@@ -65,6 +68,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
.od_max = 4,
.od_encoding = pll_od_encoding,
.stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
.bypass_bit = 9,
.enable_bit = 8,
},
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
index 4f0e92c877d6..c0ac9196a581 100644
--- a/drivers/clk/ingenic/jz4740-cgu.c
+++ b/drivers/clk/ingenic/jz4740-cgu.c
@@ -10,7 +10,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4740-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -69,6 +71,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
.pll = {
.reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
.m_shift = 23,
.m_bits = 9,
.m_offset = 2,
@@ -80,6 +83,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
.od_max = 4,
.od_encoding = pll_od_encoding,
.stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
.bypass_bit = 9,
.enable_bit = 8,
},
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
index c051ecba5cf8..9ea4490ecb7f 100644
--- a/drivers/clk/ingenic/jz4770-cgu.c
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -9,7 +9,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4770-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -102,6 +104,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.parents = { JZ4770_CLK_EXT },
.pll = {
.reg = CGU_REG_CPPCR0,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -112,6 +115,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR0,
.bypass_bit = 9,
.enable_bit = 8,
.stable_bit = 10,
@@ -124,6 +128,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.parents = { JZ4770_CLK_EXT },
.pll = {
.reg = CGU_REG_CPPCR1,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -134,9 +139,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR1,
+ .no_bypass_bit = true,
.enable_bit = 7,
.stable_bit = 6,
- .no_bypass_bit = true,
},
},
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index c758f1643067..6c5b8029cc8a 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -13,6 +13,7 @@
#include <linux/of.h>
#include <dt-bindings/clock/jz4780-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -266,6 +267,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
#define DEF_PLL(name) { \
.reg = CGU_REG_ ## name, \
+ .rate_multiplier = 1, \
.m_shift = 19, \
.m_bits = 13, \
.m_offset = 1, \
@@ -277,6 +279,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
.od_max = 16, \
.od_encoding = pll_od_encoding, \
.stable_bit = 6, \
+ .bypass_reg = CGU_REG_ ## name, \
.bypass_bit = 1, \
.enable_bit = 0, \
}
diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c
index 153a954b0d2f..9382dc3aa27e 100644
--- a/drivers/clk/ingenic/tcu.c
+++ b/drivers/clk/ingenic/tcu.c
@@ -323,7 +323,7 @@ static const struct ingenic_soc_info x1000_soc_info = {
.has_tcu_clk = false,
};
-static const struct of_device_id ingenic_tcu_of_match[] __initconst = {
+static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
{ .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, },
{ .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, },
{ .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, },
diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c
index b22d87b3f555..453f3323cb99 100644
--- a/drivers/clk/ingenic/x1000-cgu.c
+++ b/drivers/clk/ingenic/x1000-cgu.c
@@ -1,13 +1,16 @@
// SPDX-License-Identifier: GPL-2.0
/*
* X1000 SoC CGU driver
- * Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
*/
#include <linux/clk-provider.h>
#include <linux/delay.h>
+#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/x1000-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -18,6 +21,9 @@
#define CGU_REG_CLKGR 0x20
#define CGU_REG_OPCR 0x24
#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_USBCDR 0x50
#define CGU_REG_MACCDR 0x54
#define CGU_REG_I2SCDR 0x60
#define CGU_REG_LPCDR 0x64
@@ -38,8 +44,47 @@
#define OPCR_SPENDN0 BIT(7)
#define OPCR_SPENDN1 BIT(6)
+/* bits within the USBPCR register */
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
+
static struct ingenic_cgu *cgu;
+static int x1000_usb_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+
+static void x1000_usb_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops x1000_otg_phy_ops = {
+ .enable = x1000_usb_phy_enable,
+ .disable = x1000_usb_phy_disable,
+ .is_enabled = x1000_usb_phy_is_enabled,
+};
+
static const s8 pll_od_encoding[8] = {
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
};
@@ -58,6 +103,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
.pll = {
.reg = CGU_REG_APLL,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -68,6 +114,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_APLL,
.bypass_bit = 9,
.enable_bit = 8,
.stable_bit = 10,
@@ -79,6 +126,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
.pll = {
.reg = CGU_REG_MPLL,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -89,12 +137,22 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_MPLL,
.bypass_bit = 6,
.enable_bit = 7,
.stable_bit = 0,
},
},
+
+ /* Custom (SoC-specific) OTG PHY */
+
+ [X1000_CLK_OTGPHY] = {
+ "otg_phy", CGU_CLK_CUSTOM,
+ .parents = { -1, -1, X1000_CLK_EXCLK, -1 },
+ .custom = { &x1000_otg_phy_ops },
+ },
+
/* Muxes & dividers */
[X1000_CLK_SCLKA] = {
@@ -110,9 +168,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
[X1000_CLK_CPU] = {
- "cpu", CGU_CLK_DIV,
+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 30 },
},
[X1000_CLK_L2CACHE] = {
@@ -141,9 +200,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
[X1000_CLK_PCLK] = {
- "pclk", CGU_CLK_DIV,
+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
.parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 },
.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 28 },
},
[X1000_CLK_DDR] = {
@@ -156,12 +216,20 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
[X1000_CLK_MAC] = {
"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
- .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
.mux = { CGU_REG_MACCDR, 31, 1 },
.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
.gate = { CGU_REG_CLKGR, 25 },
},
+ [X1000_CLK_LCD] = {
+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
+ .mux = { CGU_REG_LPCDR, 31, 1 },
+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
+ .gate = { CGU_REG_CLKGR, 23 },
+ },
+
[X1000_CLK_MSCMUX] = {
"msc_mux", CGU_CLK_MUX,
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
@@ -182,6 +250,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR, 5 },
},
+ [X1000_CLK_OTG] = {
+ "otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { X1000_CLK_EXCLK, -1,
+ X1000_CLK_APLL, X1000_CLK_MPLL },
+ .mux = { CGU_REG_USBCDR, 30, 2 },
+ .div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR, 3 },
+ },
+
[X1000_CLK_SSIPLL] = {
"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 },
@@ -189,14 +266,32 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
},
+ [X1000_CLK_SSIPLL_DIV2] = {
+ "ssi_pll_div2", CGU_CLK_FIXDIV,
+ .parents = { X1000_CLK_SSIPLL },
+ .fixdiv = { 2 },
+ },
+
[X1000_CLK_SSIMUX] = {
"ssi_mux", CGU_CLK_MUX,
- .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 },
+ .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 },
.mux = { CGU_REG_SSICDR, 30, 1 },
},
/* Gate-only clocks */
+ [X1000_CLK_EMC] = {
+ "emc", CGU_CLK_GATE,
+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 0 },
+ },
+
+ [X1000_CLK_EFUSE] = {
+ "efuse", CGU_CLK_GATE,
+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 1 },
+ },
+
[X1000_CLK_SFC] = {
"sfc", CGU_CLK_GATE,
.parents = { X1000_CLK_SSIPLL, -1, -1, -1 },
@@ -239,12 +334,24 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR, 16 },
},
+ [X1000_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 18 },
+ },
+
[X1000_CLK_SSI] = {
"ssi", CGU_CLK_GATE,
.parents = { X1000_CLK_SSIMUX, -1, -1, -1 },
.gate = { CGU_REG_CLKGR, 19 },
},
+ [X1000_CLK_OST] = {
+ "ost", CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 20 },
+ },
+
[X1000_CLK_PDMA] = {
"pdma", CGU_CLK_GATE,
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
@@ -271,4 +378,8 @@ static void __init x1000_cgu_init(struct device_node *np)
ingenic_cgu_register_syscore_ops(cgu);
}
-CLK_OF_DECLARE(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
+/*
+ * CGU has some children devices, this is useful for probing children devices
+ * in the case where the device node is compatible with "simple-mfd".
+ */
+CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c
new file mode 100644
index 000000000000..a1b2ff0ee487
--- /dev/null
+++ b/drivers/clk/ingenic/x1830-cgu.c
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * X1830 SoC CGU driver
+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/x1830-cgu.h>
+
+#include "cgu.h"
+#include "pm.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR 0x00
+#define CGU_REG_CPPCR 0x0c
+#define CGU_REG_APLL 0x10
+#define CGU_REG_MPLL 0x14
+#define CGU_REG_CLKGR0 0x20
+#define CGU_REG_OPCR 0x24
+#define CGU_REG_CLKGR1 0x28
+#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBRDT 0x40
+#define CGU_REG_USBVBFIL 0x44
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_MACCDR 0x54
+#define CGU_REG_EPLL 0x58
+#define CGU_REG_I2SCDR 0x60
+#define CGU_REG_LPCDR 0x64
+#define CGU_REG_MSC0CDR 0x68
+#define CGU_REG_I2SCDR1 0x70
+#define CGU_REG_SSICDR 0x74
+#define CGU_REG_CIMCDR 0x7c
+#define CGU_REG_MSC1CDR 0xa4
+#define CGU_REG_CMP_INTR 0xb0
+#define CGU_REG_CMP_INTRE 0xb4
+#define CGU_REG_DRCG 0xd0
+#define CGU_REG_CPCSR 0xd4
+#define CGU_REG_VPLL 0xe0
+#define CGU_REG_MACPHYC 0xe8
+
+/* bits within the OPCR register */
+#define OPCR_GATE_USBPHYCLK BIT(23)
+#define OPCR_SPENDN0 BIT(7)
+#define OPCR_SPENDN1 BIT(6)
+
+/* bits within the USBPCR register */
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
+
+static struct ingenic_cgu *cgu;
+
+static int x1830_usb_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel((readl(reg_opcr) | OPCR_SPENDN0) & ~OPCR_GATE_USBPHYCLK, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+
+static void x1830_usb_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel((readl(reg_opcr) & ~OPCR_SPENDN0) | OPCR_GATE_USBPHYCLK, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int x1830_usb_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops x1830_otg_phy_ops = {
+ .enable = x1830_usb_phy_enable,
+ .disable = x1830_usb_phy_disable,
+ .is_enabled = x1830_usb_phy_is_enabled,
+};
+
+static const s8 pll_od_encoding[64] = {
+ 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
+ -1, -1, -1, -1, -1, -1, -1, 0x4,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0x5,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0x6,
+};
+
+static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
+
+ /* External clocks */
+
+ [X1830_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
+ [X1830_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
+
+ /* PLLs */
+
+ [X1830_CLK_APLL] = {
+ "apll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_APLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 30,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_MPLL] = {
+ "mpll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_MPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 28,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_EPLL] = {
+ "epll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_EPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 24,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_VPLL] = {
+ "vpll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_VPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 26,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ /* Custom (SoC-specific) OTG PHY */
+
+ [X1830_CLK_OTGPHY] = {
+ "otg_phy", CGU_CLK_CUSTOM,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .custom = { &x1830_otg_phy_ops },
+ },
+
+ /* Muxes & dividers */
+
+ [X1830_CLK_SCLKA] = {
+ "sclk_a", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_EXCLK, X1830_CLK_APLL, -1 },
+ .mux = { CGU_REG_CPCCR, 30, 2 },
+ },
+
+ [X1830_CLK_CPUMUX] = {
+ "cpu_mux", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 28, 2 },
+ },
+
+ [X1830_CLK_CPU] = {
+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 15 },
+ },
+
+ [X1830_CLK_L2CACHE] = {
+ "l2cache", CGU_CLK_DIV,
+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
+ },
+
+ [X1830_CLK_AHB0] = {
+ "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 26, 2 },
+ .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 },
+ },
+
+ [X1830_CLK_AHB2PMUX] = {
+ "ahb2_apb_mux", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 24, 2 },
+ },
+
+ [X1830_CLK_AHB2] = {
+ "ahb2", CGU_CLK_DIV,
+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 },
+ },
+
+ [X1830_CLK_PCLK] = {
+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 14 },
+ },
+
+ [X1830_CLK_DDR] = {
+ "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_DDRCDR, 30, 2 },
+ .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 31 },
+ },
+
+ [X1830_CLK_MAC] = {
+ "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_MACCDR, 30, 2 },
+ .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR1, 4 },
+ },
+
+ [X1830_CLK_LCD] = {
+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_LPCDR, 30, 2 },
+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
+ .gate = { CGU_REG_CLKGR1, 9 },
+ },
+
+ [X1830_CLK_MSCMUX] = {
+ "msc_mux", CGU_CLK_MUX,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_MSC0CDR, 30, 2 },
+ },
+
+ [X1830_CLK_MSC0] = {
+ "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
+ .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 4 },
+ },
+
+ [X1830_CLK_MSC1] = {
+ "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
+ .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 5 },
+ },
+
+ [X1830_CLK_SSIPLL] = {
+ "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_SSICDR, 30, 2 },
+ .div = { CGU_REG_SSICDR, 0, 1, 8, 28, 27, 26 },
+ },
+
+ [X1830_CLK_SSIPLL_DIV2] = {
+ "ssi_pll_div2", CGU_CLK_FIXDIV,
+ .parents = { X1830_CLK_SSIPLL },
+ .fixdiv = { 2 },
+ },
+
+ [X1830_CLK_SSIMUX] = {
+ "ssi_mux", CGU_CLK_MUX,
+ .parents = { X1830_CLK_EXCLK, X1830_CLK_SSIPLL_DIV2, -1, -1 },
+ .mux = { CGU_REG_SSICDR, 29, 1 },
+ },
+
+ /* Gate-only clocks */
+
+ [X1830_CLK_EMC] = {
+ "emc", CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 0 },
+ },
+
+ [X1830_CLK_EFUSE] = {
+ "efuse", CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 1 },
+ },
+
+ [X1830_CLK_OTG] = {
+ "otg", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 3 },
+ },
+
+ [X1830_CLK_SSI0] = {
+ "ssi0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 6 },
+ },
+
+ [X1830_CLK_SMB0] = {
+ "smb0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 7 },
+ },
+
+ [X1830_CLK_SMB1] = {
+ "smb1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 8 },
+ },
+
+ [X1830_CLK_SMB2] = {
+ "smb2", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 9 },
+ },
+
+ [X1830_CLK_UART0] = {
+ "uart0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 14 },
+ },
+
+ [X1830_CLK_UART1] = {
+ "uart1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 15 },
+ },
+
+ [X1830_CLK_SSI1] = {
+ "ssi1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 19 },
+ },
+
+ [X1830_CLK_SFC] = {
+ "sfc", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIPLL, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 20 },
+ },
+
+ [X1830_CLK_PDMA] = {
+ "pdma", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 21 },
+ },
+
+ [X1830_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 30 },
+ },
+
+ [X1830_CLK_DTRNG] = {
+ "dtrng", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 1 },
+ },
+
+ [X1830_CLK_OST] = {
+ "ost", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 11 },
+ },
+};
+
+static void __init x1830_cgu_init(struct device_node *np)
+{
+ int retval;
+
+ cgu = ingenic_cgu_new(x1830_cgu_clocks,
+ ARRAY_SIZE(x1830_cgu_clocks), np);
+ if (!cgu) {
+ pr_err("%s: failed to initialise CGU\n", __func__);
+ return;
+ }
+
+ retval = ingenic_cgu_register_clocks(cgu);
+ if (retval) {
+ pr_err("%s: failed to register CGU Clocks\n", __func__);
+ return;
+ }
+
+ ingenic_cgu_register_syscore_ops(cgu);
+}
+/*
+ * CGU has some children devices, this is useful for probing children devices
+ * in the case where the device node is compatible with "simple-mfd".
+ */
+CLK_OF_DECLARE_DRIVER(x1830_cgu, "ingenic,x1830-cgu", x1830_cgu_init);
diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig
index ab613f28b502..e64d6726048f 100644
--- a/drivers/clk/keystone/Kconfig
+++ b/drivers/clk/keystone/Kconfig
@@ -2,7 +2,7 @@
config COMMON_CLK_KEYSTONE
tristate "Clock drivers for Keystone based SOCs"
depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
- ---help---
+ help
Supports clock drivers for Keystone based SOCs. These SOCs have local
a power sleep control module that gate the clock to the IPs and PLLs.
@@ -11,7 +11,7 @@ config TI_SCI_CLK
depends on (ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST) && OF
depends on TI_SCI_PROTOCOL
default ARCH_KEYSTONE
- ---help---
+ help
This adds the clock driver support over TI System Control Interface.
If you wish to use clock resources from the PMMC firmware, say Y.
Otherwise, say N.
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 9e28db8125cd..89ceb2fbc7c4 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -8,7 +8,7 @@ menu "Clock driver for MediaTek SoC"
config COMMON_CLK_MEDIATEK
bool
select RESET_CONTROLLER
- ---help---
+ help
MediaTek SoCs' clock support.
config COMMON_CLK_MT2701
@@ -16,55 +16,55 @@ config COMMON_CLK_MT2701
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM
- ---help---
+ help
This driver supports MediaTek MT2701 basic clocks.
config COMMON_CLK_MT2701_MMSYS
bool "Clock driver for MediaTek MT2701 mmsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 mmsys clocks.
config COMMON_CLK_MT2701_IMGSYS
bool "Clock driver for MediaTek MT2701 imgsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 imgsys clocks.
config COMMON_CLK_MT2701_VDECSYS
bool "Clock driver for MediaTek MT2701 vdecsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 vdecsys clocks.
config COMMON_CLK_MT2701_HIFSYS
bool "Clock driver for MediaTek MT2701 hifsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 hifsys clocks.
config COMMON_CLK_MT2701_ETHSYS
bool "Clock driver for MediaTek MT2701 ethsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 ethsys clocks.
config COMMON_CLK_MT2701_BDPSYS
bool "Clock driver for MediaTek MT2701 bdpsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 bdpsys clocks.
config COMMON_CLK_MT2701_AUDSYS
bool "Clock driver for Mediatek MT2701 audsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports Mediatek MT2701 audsys clocks.
config COMMON_CLK_MT2701_G3DSYS
bool "Clock driver for MediaTek MT2701 g3dsys"
depends on COMMON_CLK_MT2701
- ---help---
+ help
This driver supports MediaTek MT2701 g3dsys clocks.
config COMMON_CLK_MT2712
@@ -72,51 +72,137 @@ config COMMON_CLK_MT2712
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM64
- ---help---
+ help
This driver supports MediaTek MT2712 basic clocks.
config COMMON_CLK_MT2712_BDPSYS
bool "Clock driver for MediaTek MT2712 bdpsys"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 bdpsys clocks.
config COMMON_CLK_MT2712_IMGSYS
bool "Clock driver for MediaTek MT2712 imgsys"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 imgsys clocks.
config COMMON_CLK_MT2712_JPGDECSYS
bool "Clock driver for MediaTek MT2712 jpgdecsys"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 jpgdecsys clocks.
config COMMON_CLK_MT2712_MFGCFG
bool "Clock driver for MediaTek MT2712 mfgcfg"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 mfgcfg clocks.
config COMMON_CLK_MT2712_MMSYS
bool "Clock driver for MediaTek MT2712 mmsys"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 mmsys clocks.
config COMMON_CLK_MT2712_VDECSYS
bool "Clock driver for MediaTek MT2712 vdecsys"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 vdecsys clocks.
config COMMON_CLK_MT2712_VENCSYS
bool "Clock driver for MediaTek MT2712 vencsys"
depends on COMMON_CLK_MT2712
- ---help---
+ help
This driver supports MediaTek MT2712 vencsys clocks.
+config COMMON_CLK_MT6765
+ bool "Clock driver for MediaTek MT6765"
+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+ select COMMON_CLK_MEDIATEK
+ default ARCH_MEDIATEK && ARM64
+ help
+ This driver supports MediaTek MT6765 basic clocks.
+
+config COMMON_CLK_MT6765_AUDIOSYS
+ bool "Clock driver for MediaTek MT6765 audiosys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 audiosys clocks.
+
+config COMMON_CLK_MT6765_CAMSYS
+ bool "Clock driver for MediaTek MT6765 camsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 camsys clocks.
+
+config COMMON_CLK_MT6765_GCESYS
+ bool "Clock driver for MediaTek MT6765 gcesys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 gcesys clocks.
+
+config COMMON_CLK_MT6765_MMSYS
+ bool "Clock driver for MediaTek MT6765 mmsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mmsys clocks.
+
+config COMMON_CLK_MT6765_IMGSYS
+ bool "Clock driver for MediaTek MT6765 imgsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 imgsys clocks.
+
+config COMMON_CLK_MT6765_VCODECSYS
+ bool "Clock driver for MediaTek MT6765 vcodecsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 vcodecsys clocks.
+
+config COMMON_CLK_MT6765_MFGSYS
+ bool "Clock driver for MediaTek MT6765 mfgsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mfgsys clocks.
+
+config COMMON_CLK_MT6765_MIPI0ASYS
+ bool "Clock driver for MediaTek MT6765 mipi0asys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mipi0asys clocks.
+
+config COMMON_CLK_MT6765_MIPI0BSYS
+ bool "Clock driver for MediaTek MT6765 mipi0bsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mipi0bsys clocks.
+
+config COMMON_CLK_MT6765_MIPI1ASYS
+ bool "Clock driver for MediaTek MT6765 mipi1asys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mipi1asys clocks.
+
+config COMMON_CLK_MT6765_MIPI1BSYS
+ bool "Clock driver for MediaTek MT6765 mipi1bsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mipi1bsys clocks.
+
+config COMMON_CLK_MT6765_MIPI2ASYS
+ bool "Clock driver for MediaTek MT6765 mipi2asys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mipi2asys clocks.
+
+config COMMON_CLK_MT6765_MIPI2BSYS
+ bool "Clock driver for MediaTek MT6765 mipi2bsys"
+ depends on COMMON_CLK_MT6765
+ help
+ This driver supports MediaTek MT6765 mipi2bsys clocks.
+
config COMMON_CLK_MT6779
bool "Clock driver for MediaTek MT6779"
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
@@ -178,31 +264,31 @@ config COMMON_CLK_MT6797
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM64
- ---help---
+ help
This driver supports MediaTek MT6797 basic clocks.
config COMMON_CLK_MT6797_MMSYS
bool "Clock driver for MediaTek MT6797 mmsys"
depends on COMMON_CLK_MT6797
- ---help---
+ help
This driver supports MediaTek MT6797 mmsys clocks.
config COMMON_CLK_MT6797_IMGSYS
bool "Clock driver for MediaTek MT6797 imgsys"
depends on COMMON_CLK_MT6797
- ---help---
+ help
This driver supports MediaTek MT6797 imgsys clocks.
config COMMON_CLK_MT6797_VDECSYS
bool "Clock driver for MediaTek MT6797 vdecsys"
depends on COMMON_CLK_MT6797
- ---help---
+ help
This driver supports MediaTek MT6797 vdecsys clocks.
config COMMON_CLK_MT6797_VENCSYS
bool "Clock driver for MediaTek MT6797 vencsys"
depends on COMMON_CLK_MT6797
- ---help---
+ help
This driver supports MediaTek MT6797 vencsys clocks.
config COMMON_CLK_MT7622
@@ -210,28 +296,28 @@ config COMMON_CLK_MT7622
depends on ARCH_MEDIATEK || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK
- ---help---
+ help
This driver supports MediaTek MT7622 basic clocks and clocks
required for various periperals found on MediaTek.
config COMMON_CLK_MT7622_ETHSYS
bool "Clock driver for MediaTek MT7622 ETHSYS"
depends on COMMON_CLK_MT7622
- ---help---
+ help
This driver add support for clocks for Ethernet and SGMII
required on MediaTek MT7622 SoC.
config COMMON_CLK_MT7622_HIFSYS
bool "Clock driver for MediaTek MT7622 HIFSYS"
depends on COMMON_CLK_MT7622
- ---help---
+ help
This driver supports MediaTek MT7622 HIFSYS clocks providing
to PCI-E and USB.
config COMMON_CLK_MT7622_AUDSYS
bool "Clock driver for MediaTek MT7622 AUDSYS"
depends on COMMON_CLK_MT7622
- ---help---
+ help
This driver supports MediaTek MT7622 AUDSYS clocks providing
to audio consumers such as I2S and TDM.
@@ -240,21 +326,21 @@ config COMMON_CLK_MT7629
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM
- ---help---
+ help
This driver supports MediaTek MT7629 basic clocks and clocks
required for various periperals found on MediaTek.
config COMMON_CLK_MT7629_ETHSYS
bool "Clock driver for MediaTek MT7629 ETHSYS"
depends on COMMON_CLK_MT7629
- ---help---
+ help
This driver add support for clocks for Ethernet and SGMII
required on MediaTek MT7629 SoC.
config COMMON_CLK_MT7629_HIFSYS
bool "Clock driver for MediaTek MT7629 HIFSYS"
depends on COMMON_CLK_MT7629
- ---help---
+ help
This driver supports MediaTek MT7629 HIFSYS clocks providing
to PCI-E and USB.
@@ -263,7 +349,7 @@ config COMMON_CLK_MT8135
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM
- ---help---
+ help
This driver supports MediaTek MT8135 clocks.
config COMMON_CLK_MT8173
@@ -271,7 +357,7 @@ config COMMON_CLK_MT8173
depends on ARCH_MEDIATEK || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK
- ---help---
+ help
This driver supports MediaTek MT8173 clocks.
config COMMON_CLK_MT8173_MMSYS
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index bb0536942075..959b556d32ea 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,6 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
+obj-$(CONFIG_COMMON_CLK_MT6765) += clk-mt6765.o
+obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) += clk-mt6765-audio.o
+obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) += clk-mt6765-cam.o
+obj-$(CONFIG_COMMON_CLK_MT6765_IMGSYS) += clk-mt6765-img.o
+obj-$(CONFIG_COMMON_CLK_MT6765_MIPI0ASYS) += clk-mt6765-mipi0a.o
+obj-$(CONFIG_COMMON_CLK_MT6765_MMSYS) += clk-mt6765-mm.o
+obj-$(CONFIG_COMMON_CLK_MT6765_VCODECSYS) += clk-mt6765-vcodec.o
obj-$(CONFIG_COMMON_CLK_MT6779) += clk-mt6779.o
obj-$(CONFIG_COMMON_CLK_MT6779_MMSYS) += clk-mt6779-mm.o
obj-$(CONFIG_COMMON_CLK_MT6779_IMGSYS) += clk-mt6779-img.o
diff --git a/drivers/clk/mediatek/clk-mt6765-audio.c b/drivers/clk/mediatek/clk-mt6765-audio.c
new file mode 100644
index 000000000000..4c989165d795
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-audio.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+static const struct mtk_gate_regs audio0_cg_regs = {
+ .set_ofs = 0x0,
+ .clr_ofs = 0x0,
+ .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs audio1_cg_regs = {
+ .set_ofs = 0x4,
+ .clr_ofs = 0x4,
+ .sta_ofs = 0x4,
+};
+
+#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &audio0_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr, \
+ }
+
+#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &audio1_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr, \
+ }
+
+static const struct mtk_gate audio_clks[] = {
+ /* AUDIO0 */
+ GATE_AUDIO0(CLK_AUDIO_AFE, "aud_afe", "audio_ck", 2),
+ GATE_AUDIO0(CLK_AUDIO_22M, "aud_22m", "aud_engen1_ck", 8),
+ GATE_AUDIO0(CLK_AUDIO_APLL_TUNER, "aud_apll_tuner",
+ "aud_engen1_ck", 19),
+ GATE_AUDIO0(CLK_AUDIO_ADC, "aud_adc", "audio_ck", 24),
+ GATE_AUDIO0(CLK_AUDIO_DAC, "aud_dac", "audio_ck", 25),
+ GATE_AUDIO0(CLK_AUDIO_DAC_PREDIS, "aud_dac_predis",
+ "audio_ck", 26),
+ GATE_AUDIO0(CLK_AUDIO_TML, "aud_tml", "audio_ck", 27),
+ /* AUDIO1 */
+ GATE_AUDIO1(CLK_AUDIO_I2S1_BCLK, "aud_i2s1_bclk",
+ "audio_ck", 4),
+ GATE_AUDIO1(CLK_AUDIO_I2S2_BCLK, "aud_i2s2_bclk",
+ "audio_ck", 5),
+ GATE_AUDIO1(CLK_AUDIO_I2S3_BCLK, "aud_i2s3_bclk",
+ "audio_ck", 6),
+ GATE_AUDIO1(CLK_AUDIO_I2S4_BCLK, "aud_i2s4_bclk",
+ "audio_ck", 7),
+};
+
+static int clk_mt6765_audio_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
+
+ mtk_clk_register_gates(node, audio_clks,
+ ARRAY_SIZE(audio_clks), clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_audio[] = {
+ { .compatible = "mediatek,mt6765-audsys", },
+ {}
+};
+
+static struct platform_driver clk_mt6765_audio_drv = {
+ .probe = clk_mt6765_audio_probe,
+ .driver = {
+ .name = "clk-mt6765-audio",
+ .of_match_table = of_match_clk_mt6765_audio,
+ },
+};
+
+builtin_platform_driver(clk_mt6765_audio_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-cam.c b/drivers/clk/mediatek/clk-mt6765-cam.c
new file mode 100644
index 000000000000..c96394893bcf
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-cam.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+static const struct mtk_gate_regs cam_cg_regs = {
+ .set_ofs = 0x4,
+ .clr_ofs = 0x8,
+ .sta_ofs = 0x0,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &cam_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static const struct mtk_gate cam_clks[] = {
+ GATE_CAM(CLK_CAM_LARB3, "cam_larb3", "mm_ck", 0),
+ GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "mm_ck", 1),
+ GATE_CAM(CLK_CAM, "cam", "mm_ck", 6),
+ GATE_CAM(CLK_CAMTG, "camtg", "mm_ck", 7),
+ GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "mm_ck", 8),
+ GATE_CAM(CLK_CAMSV0, "camsv0", "mm_ck", 9),
+ GATE_CAM(CLK_CAMSV1, "camsv1", "mm_ck", 10),
+ GATE_CAM(CLK_CAMSV2, "camsv2", "mm_ck", 11),
+ GATE_CAM(CLK_CAM_CCU, "cam_ccu", "mm_ck", 12),
+};
+
+static int clk_mt6765_cam_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
+
+ mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_cam[] = {
+ { .compatible = "mediatek,mt6765-camsys", },
+ {}
+};
+
+static struct platform_driver clk_mt6765_cam_drv = {
+ .probe = clk_mt6765_cam_probe,
+ .driver = {
+ .name = "clk-mt6765-cam",
+ .of_match_table = of_match_clk_mt6765_cam,
+ },
+};
+
+builtin_platform_driver(clk_mt6765_cam_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-img.c b/drivers/clk/mediatek/clk-mt6765-img.c
new file mode 100644
index 000000000000..6fd8bf8030fc
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-img.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+ .set_ofs = 0x4,
+ .clr_ofs = 0x8,
+ .sta_ofs = 0x0,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &img_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static const struct mtk_gate img_clks[] = {
+ GATE_IMG(CLK_IMG_LARB2, "img_larb2", "mm_ck", 0),
+ GATE_IMG(CLK_IMG_DIP, "img_dip", "mm_ck", 2),
+ GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_ck", 3),
+ GATE_IMG(CLK_IMG_DPE, "img_dpe", "mm_ck", 4),
+ GATE_IMG(CLK_IMG_RSC, "img_rsc", "mm_ck", 5),
+};
+
+static int clk_mt6765_img_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_img[] = {
+ { .compatible = "mediatek,mt6765-imgsys", },
+ {}
+};
+
+static struct platform_driver clk_mt6765_img_drv = {
+ .probe = clk_mt6765_img_probe,
+ .driver = {
+ .name = "clk-mt6765-img",
+ .of_match_table = of_match_clk_mt6765_img,
+ },
+};
+
+builtin_platform_driver(clk_mt6765_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-mipi0a.c b/drivers/clk/mediatek/clk-mt6765-mipi0a.c
new file mode 100644
index 000000000000..81744d0f95a0
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-mipi0a.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+static const struct mtk_gate_regs mipi0a_cg_regs = {
+ .set_ofs = 0x80,
+ .clr_ofs = 0x80,
+ .sta_ofs = 0x80,
+};
+
+#define GATE_MIPI0A(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &mipi0a_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+ }
+
+static const struct mtk_gate mipi0a_clks[] = {
+ GATE_MIPI0A(CLK_MIPI0A_CSR_CSI_EN_0A,
+ "mipi0a_csr_0a", "f_fseninf_ck", 1),
+};
+
+static int clk_mt6765_mipi0a_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_MIPI0A_NR_CLK);
+
+ mtk_clk_register_gates(node, mipi0a_clks,
+ ARRAY_SIZE(mipi0a_clks), clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_mipi0a[] = {
+ { .compatible = "mediatek,mt6765-mipi0a", },
+ {}
+};
+
+static struct platform_driver clk_mt6765_mipi0a_drv = {
+ .probe = clk_mt6765_mipi0a_probe,
+ .driver = {
+ .name = "clk-mt6765-mipi0a",
+ .of_match_table = of_match_clk_mt6765_mipi0a,
+ },
+};
+
+builtin_platform_driver(clk_mt6765_mipi0a_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-mm.c b/drivers/clk/mediatek/clk-mt6765-mm.c
new file mode 100644
index 000000000000..6d8214c51684
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-mm.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+static const struct mtk_gate_regs mm_cg_regs = {
+ .set_ofs = 0x104,
+ .clr_ofs = 0x108,
+ .sta_ofs = 0x100,
+};
+
+#define GATE_MM(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &mm_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static const struct mtk_gate mm_clks[] = {
+ /* MM */
+ GATE_MM(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_ck", 0),
+ GATE_MM(CLK_MM_MDP_CCORR0, "mm_mdp_ccorr0", "mm_ck", 1),
+ GATE_MM(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_ck", 2),
+ GATE_MM(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_ck", 3),
+ GATE_MM(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_ck", 4),
+ GATE_MM(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_ck", 5),
+ GATE_MM(CLK_MM_MDP_WDMA0, "mm_mdp_wdma0", "mm_ck", 6),
+ GATE_MM(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_ck", 7),
+ GATE_MM(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_ck", 8),
+ GATE_MM(CLK_MM_DISP_RSZ0, "mm_disp_rsz0", "mm_ck", 9),
+ GATE_MM(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_ck", 10),
+ GATE_MM(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_ck", 11),
+ GATE_MM(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_ck", 12),
+ GATE_MM(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_ck", 13),
+ GATE_MM(CLK_MM_DISP_AAL0, "mm_disp_aal0", "mm_ck", 14),
+ GATE_MM(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_ck", 15),
+ GATE_MM(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "mm_ck", 16),
+ GATE_MM(CLK_MM_DSI0, "mm_dsi0", "mm_ck", 17),
+ GATE_MM(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_ck", 18),
+ GATE_MM(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_ck", 19),
+ GATE_MM(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_ck", 20),
+ GATE_MM(CLK_MM_SMI_COMM0, "mm_smi_comm0", "mm_ck", 21),
+ GATE_MM(CLK_MM_SMI_COMM1, "mm_smi_comm1", "mm_ck", 22),
+ GATE_MM(CLK_MM_CAM_MDP, "mm_cam_mdp_ck", "mm_ck", 23),
+ GATE_MM(CLK_MM_SMI_IMG, "mm_smi_img_ck", "mm_ck", 24),
+ GATE_MM(CLK_MM_SMI_CAM, "mm_smi_cam_ck", "mm_ck", 25),
+ GATE_MM(CLK_MM_IMG_DL_RELAY, "mm_img_dl_relay", "mm_ck", 26),
+ GATE_MM(CLK_MM_IMG_DL_ASYNC_TOP, "mm_imgdl_async", "mm_ck", 27),
+ GATE_MM(CLK_MM_DIG_DSI, "mm_dig_dsi_ck", "mm_ck", 28),
+ GATE_MM(CLK_MM_F26M_HRTWT, "mm_hrtwt", "f_f26m_ck", 29),
+};
+
+static int clk_mt6765_mm_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_mm[] = {
+ { .compatible = "mediatek,mt6765-mmsys", },
+ {}
+};
+
+static struct platform_driver clk_mt6765_mm_drv = {
+ .probe = clk_mt6765_mm_probe,
+ .driver = {
+ .name = "clk-mt6765-mm",
+ .of_match_table = of_match_clk_mt6765_mm,
+ },
+};
+
+builtin_platform_driver(clk_mt6765_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765-vcodec.c b/drivers/clk/mediatek/clk-mt6765-vcodec.c
new file mode 100644
index 000000000000..baae665fab31
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765-vcodec.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+ .set_ofs = 0x4,
+ .clr_ofs = 0x8,
+ .sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &venc_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr_inv, \
+ }
+
+static const struct mtk_gate venc_clks[] = {
+ GATE_VENC(CLK_VENC_SET0_LARB, "venc_set0_larb", "mm_ck", 0),
+ GATE_VENC(CLK_VENC_SET1_VENC, "venc_set1_venc", "mm_ck", 4),
+ GATE_VENC(CLK_VENC_SET2_JPGENC, "jpgenc", "mm_ck", 8),
+ GATE_VENC(CLK_VENC_SET3_VDEC, "venc_set3_vdec", "mm_ck", 12),
+};
+
+static int clk_mt6765_vcodec_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+
+ clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
+
+ mtk_clk_register_gates(node, venc_clks,
+ ARRAY_SIZE(venc_clks), clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765_vcodec[] = {
+ { .compatible = "mediatek,mt6765-vcodecsys", },
+ {}
+};
+
+static struct platform_driver clk_mt6765_vcodec_drv = {
+ .probe = clk_mt6765_vcodec_probe,
+ .driver = {
+ .name = "clk-mt6765-vcodec",
+ .of_match_table = of_match_clk_mt6765_vcodec,
+ },
+};
+
+builtin_platform_driver(clk_mt6765_vcodec_drv);
diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
new file mode 100644
index 000000000000..db8db1b3b79d
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt6765.c
@@ -0,0 +1,922 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Owen Chen <owen.chen@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt6765-clk.h>
+
+/*fmeter div select 4*/
+#define _DIV4_ 1
+
+static DEFINE_SPINLOCK(mt6765_clk_lock);
+
+/* Total 12 subsys */
+static void __iomem *cksys_base;
+static void __iomem *apmixed_base;
+
+/* CKSYS */
+#define CLK_SCP_CFG_0 (cksys_base + 0x200)
+#define CLK_SCP_CFG_1 (cksys_base + 0x204)
+
+/* CG */
+#define AP_PLL_CON3 (apmixed_base + 0x0C)
+#define PLLON_CON0 (apmixed_base + 0x44)
+#define PLLON_CON1 (apmixed_base + 0x48)
+
+/* clk cfg update */
+#define CLK_CFG_0 0x40
+#define CLK_CFG_0_SET 0x44
+#define CLK_CFG_0_CLR 0x48
+#define CLK_CFG_1 0x50
+#define CLK_CFG_1_SET 0x54
+#define CLK_CFG_1_CLR 0x58
+#define CLK_CFG_2 0x60
+#define CLK_CFG_2_SET 0x64
+#define CLK_CFG_2_CLR 0x68
+#define CLK_CFG_3 0x70
+#define CLK_CFG_3_SET 0x74
+#define CLK_CFG_3_CLR 0x78
+#define CLK_CFG_4 0x80
+#define CLK_CFG_4_SET 0x84
+#define CLK_CFG_4_CLR 0x88
+#define CLK_CFG_5 0x90
+#define CLK_CFG_5_SET 0x94
+#define CLK_CFG_5_CLR 0x98
+#define CLK_CFG_6 0xa0
+#define CLK_CFG_6_SET 0xa4
+#define CLK_CFG_6_CLR 0xa8
+#define CLK_CFG_7 0xb0
+#define CLK_CFG_7_SET 0xb4
+#define CLK_CFG_7_CLR 0xb8
+#define CLK_CFG_8 0xc0
+#define CLK_CFG_8_SET 0xc4
+#define CLK_CFG_8_CLR 0xc8
+#define CLK_CFG_9 0xd0
+#define CLK_CFG_9_SET 0xd4
+#define CLK_CFG_9_CLR 0xd8
+#define CLK_CFG_10 0xe0
+#define CLK_CFG_10_SET 0xe4
+#define CLK_CFG_10_CLR 0xe8
+#define CLK_CFG_UPDATE 0x004
+
+static const struct mtk_fixed_clk fixed_clks[] = {
+ FIXED_CLK(CLK_TOP_F_FRTC, "f_frtc_ck", "clk32k", 32768),
+ FIXED_CLK(CLK_TOP_CLK26M, "clk_26m_ck", "clk26m", 26000000),
+ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", NULL, 466000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
+ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
+ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
+ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
+ FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2),
+ FACTOR(CLK_TOP_USB20_192M, "usb20_192m_ck", "univpll", 2, 13),
+ FACTOR(CLK_TOP_USB20_192M_D4, "usb20_192m_d4", "usb20_192m_ck", 1, 4),
+ FACTOR(CLK_TOP_USB20_192M_D8, "usb20_192m_d8", "usb20_192m_ck", 1, 8),
+ FACTOR(CLK_TOP_USB20_192M_D16,
+ "usb20_192m_d16", "usb20_192m_ck", 1, 16),
+ FACTOR(CLK_TOP_USB20_192M_D32,
+ "usb20_192m_d32", "usb20_192m_ck", 1, 32),
+ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
+ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
+ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
+ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
+ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll_ck", 1, 2),
+ FACTOR(CLK_TOP_MPLL, "mpll_ck", "mpll", 1, 1),
+ FACTOR(CLK_TOP_DA_MPLL_104M_DIV, "mpll_104m_div", "mpll_ck", 1, 2),
+ FACTOR(CLK_TOP_DA_MPLL_52M_DIV, "mpll_52m_div", "mpll_ck", 1, 4),
+ FACTOR(CLK_TOP_MFGPLL, "mfgpll_ck", "mfgpll", 1, 1),
+ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
+ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, 2),
+ FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
+ FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, 2),
+ FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1, 4),
+ FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1, 8),
+ FACTOR(CLK_TOP_ULPOSC1, "ulposc1_ck", "ulposc1", 1, 1),
+ FACTOR(CLK_TOP_ULPOSC1_D2, "ulposc1_d2", "ulposc1_ck", 1, 2),
+ FACTOR(CLK_TOP_ULPOSC1_D4, "ulposc1_d4", "ulposc1_ck", 1, 4),
+ FACTOR(CLK_TOP_ULPOSC1_D8, "ulposc1_d8", "ulposc1_ck", 1, 8),
+ FACTOR(CLK_TOP_ULPOSC1_D16, "ulposc1_d16", "ulposc1_ck", 1, 16),
+ FACTOR(CLK_TOP_ULPOSC1_D32, "ulposc1_d32", "ulposc1_ck", 1, 32),
+ FACTOR(CLK_TOP_F_F26M, "f_f26m_ck", "clk_26m_ck", 1, 1),
+ FACTOR(CLK_TOP_AXI, "axi_ck", "axi_sel", 1, 1),
+ FACTOR(CLK_TOP_MM, "mm_ck", "mm_sel", 1, 1),
+ FACTOR(CLK_TOP_SCP, "scp_ck", "scp_sel", 1, 1),
+ FACTOR(CLK_TOP_MFG, "mfg_ck", "mfg_sel", 1, 1),
+ FACTOR(CLK_TOP_F_FUART, "f_fuart_ck", "uart_sel", 1, 1),
+ FACTOR(CLK_TOP_SPI, "spi_ck", "spi_sel", 1, 1),
+ FACTOR(CLK_TOP_MSDC50_0, "msdc50_0_ck", "msdc50_0_sel", 1, 1),
+ FACTOR(CLK_TOP_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 1, 1),
+ FACTOR(CLK_TOP_AUDIO, "audio_ck", "audio_sel", 1, 1),
+ FACTOR(CLK_TOP_AUD_1, "aud_1_ck", "aud_1_sel", 1, 1),
+ FACTOR(CLK_TOP_AUD_ENGEN1, "aud_engen1_ck", "aud_engen1_sel", 1, 1),
+ FACTOR(CLK_TOP_F_FDISP_PWM, "f_fdisp_pwm_ck", "disp_pwm_sel", 1, 1),
+ FACTOR(CLK_TOP_SSPM, "sspm_ck", "sspm_sel", 1, 1),
+ FACTOR(CLK_TOP_DXCC, "dxcc_ck", "dxcc_sel", 1, 1),
+ FACTOR(CLK_TOP_I2C, "i2c_ck", "i2c_sel", 1, 1),
+ FACTOR(CLK_TOP_F_FPWM, "f_fpwm_ck", "pwm_sel", 1, 1),
+ FACTOR(CLK_TOP_F_FSENINF, "f_fseninf_ck", "seninf_sel", 1, 1),
+ FACTOR(CLK_TOP_AES_FDE, "aes_fde_ck", "aes_fde_sel", 1, 1),
+ FACTOR(CLK_TOP_F_BIST2FPC, "f_bist2fpc_ck", "univpll2_d2", 1, 1),
+ FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL0, "arm_div_pll0", "syspll_d2", 1, 1),
+ FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL1, "arm_div_pll1", "syspll_ck", 1, 1),
+ FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL2, "arm_div_pll2", "univpll_d2", 1, 1),
+ FACTOR(CLK_TOP_DA_USB20_48M_DIV,
+ "usb20_48m_div", "usb20_192m_d4", 1, 1),
+ FACTOR(CLK_TOP_DA_UNIV_48M_DIV, "univ_48m_div", "usb20_192m_d4", 1, 1),
+};
+
+static const char * const axi_parents[] = {
+ "clk26m",
+ "syspll_d7",
+ "syspll1_d4",
+ "syspll3_d2"
+};
+
+static const char * const mem_parents[] = {
+ "clk26m",
+ "dmpll_ck",
+ "apll1_ck"
+};
+
+static const char * const mm_parents[] = {
+ "clk26m",
+ "mmpll_ck",
+ "syspll1_d2",
+ "syspll_d5",
+ "syspll1_d4",
+ "univpll_d5",
+ "univpll1_d2",
+ "mmpll_d2"
+};
+
+static const char * const scp_parents[] = {
+ "clk26m",
+ "syspll4_d2",
+ "univpll2_d2",
+ "syspll1_d2",
+ "univpll1_d2",
+ "syspll_d3",
+ "univpll_d3"
+};
+
+static const char * const mfg_parents[] = {
+ "clk26m",
+ "mfgpll_ck",
+ "syspll_d3",
+ "univpll_d3"
+};
+
+static const char * const atb_parents[] = {
+ "clk26m",
+ "syspll1_d4",
+ "syspll1_d2"
+};
+
+static const char * const camtg_parents[] = {
+ "clk26m",
+ "usb20_192m_d8",
+ "univpll2_d8",
+ "usb20_192m_d4",
+ "univpll2_d32",
+ "usb20_192m_d16",
+ "usb20_192m_d32"
+};
+
+static const char * const uart_parents[] = {
+ "clk26m",
+ "univpll2_d8"
+};
+
+static const char * const spi_parents[] = {
+ "clk26m",
+ "syspll3_d2",
+ "syspll4_d2",
+ "syspll2_d4"
+};
+
+static const char * const msdc5hclk_parents[] = {
+ "clk26m",
+ "syspll1_d2",
+ "univpll1_d4",
+ "syspll2_d2"
+};
+
+static const char * const msdc50_0_parents[] = {
+ "clk26m",
+ "msdcpll_ck",
+ "syspll2_d2",
+ "syspll4_d2",
+ "univpll1_d2",
+ "syspll1_d2",
+ "univpll_d5",
+ "univpll1_d4"
+};
+
+static const char * const msdc30_1_parents[] = {
+ "clk26m",
+ "msdcpll_d2",
+ "univpll2_d2",
+ "syspll2_d2",
+ "syspll1_d4",
+ "univpll1_d4",
+ "usb20_192m_d4",
+ "syspll2_d4"
+};
+
+static const char * const audio_parents[] = {
+ "clk26m",
+ "syspll3_d4",
+ "syspll4_d4",
+ "syspll1_d16"
+};
+
+static const char * const aud_intbus_parents[] = {
+ "clk26m",
+ "syspll1_d4",
+ "syspll4_d2"
+};
+
+static const char * const aud_1_parents[] = {
+ "clk26m",
+ "apll1_ck"
+};
+
+static const char * const aud_engen1_parents[] = {
+ "clk26m",
+ "apll1_d2",
+ "apll1_d4",
+ "apll1_d8"
+};
+
+static const char * const disp_pwm_parents[] = {
+ "clk26m",
+ "univpll2_d4",
+ "ulposc1_d2",
+ "ulposc1_d8"
+};
+
+static const char * const sspm_parents[] = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll_d3"
+};
+
+static const char * const dxcc_parents[] = {
+ "clk26m",
+ "syspll1_d2",
+ "syspll1_d4",
+ "syspll1_d8"
+};
+
+static const char * const usb_top_parents[] = {
+ "clk26m",
+ "univpll3_d4"
+};
+
+static const char * const spm_parents[] = {
+ "clk26m",
+ "syspll1_d8"
+};
+
+static const char * const i2c_parents[] = {
+ "clk26m",
+ "univpll3_d4",
+ "univpll3_d2",
+ "syspll1_d8",
+ "syspll2_d8"
+};
+
+static const char * const pwm_parents[] = {
+ "clk26m",
+ "univpll3_d4",
+ "syspll1_d8"
+};
+
+static const char * const seninf_parents[] = {
+ "clk26m",
+ "univpll1_d4",
+ "univpll1_d2",
+ "univpll2_d2"
+};
+
+static const char * const aes_fde_parents[] = {
+ "clk26m",
+ "msdcpll_ck",
+ "univpll_d3",
+ "univpll2_d2",
+ "univpll1_d2",
+ "syspll1_d2"
+};
+
+static const char * const ulposc_parents[] = {
+ "clk26m",
+ "ulposc1_d4",
+ "ulposc1_d8",
+ "ulposc1_d16",
+ "ulposc1_d32"
+};
+
+static const char * const camtm_parents[] = {
+ "clk26m",
+ "univpll1_d4",
+ "univpll1_d2",
+ "univpll2_d2"
+};
+
+#define INVALID_UPDATE_REG 0xFFFFFFFF
+#define INVALID_UPDATE_SHIFT -1
+#define INVALID_MUX_GATE -1
+
+static const struct mtk_mux top_muxes[] = {
+ /* CLK_CFG_0 */
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
+ CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR,
+ 0, 2, 7, CLK_CFG_UPDATE, 0, CLK_IS_CRITICAL),
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
+ CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR,
+ 8, 2, 15, CLK_CFG_UPDATE, 1, CLK_IS_CRITICAL),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MM_SEL, "mm_sel", mm_parents, CLK_CFG_0,
+ CLK_CFG_0_SET, CLK_CFG_0_CLR, 16, 3, 23,
+ CLK_CFG_UPDATE, 2),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, CLK_CFG_0,
+ CLK_CFG_0_SET, CLK_CFG_0_CLR, 24, 3, 31,
+ CLK_CFG_UPDATE, 3),
+ /* CLK_CFG_1 */
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, CLK_CFG_1,
+ CLK_CFG_1_SET, CLK_CFG_1_CLR, 0, 2, 7,
+ CLK_CFG_UPDATE, 4),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, CLK_CFG_1,
+ CLK_CFG_1_SET, CLK_CFG_1_CLR, 8, 2, 15,
+ CLK_CFG_UPDATE, 5),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel",
+ camtg_parents, CLK_CFG_1, CLK_CFG_1_SET,
+ CLK_CFG_1_CLR, 16, 3, 23, CLK_CFG_UPDATE, 6),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG1_SEL, "camtg1_sel", camtg_parents,
+ CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR,
+ 24, 3, 31, CLK_CFG_UPDATE, 7),
+ /* CLK_CFG_2 */
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2_SEL, "camtg2_sel",
+ camtg_parents, CLK_CFG_2, CLK_CFG_2_SET,
+ CLK_CFG_2_CLR, 0, 3, 7, CLK_CFG_UPDATE, 8),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3_SEL, "camtg3_sel", camtg_parents,
+ CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR,
+ 8, 3, 15, CLK_CFG_UPDATE, 9),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
+ CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 16, 1, 23,
+ CLK_CFG_UPDATE, 10),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, CLK_CFG_2,
+ CLK_CFG_2_SET, CLK_CFG_2_CLR, 24, 2, 31,
+ CLK_CFG_UPDATE, 11),
+ /* CLK_CFG_3 */
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK_SEL, "msdc5hclk",
+ msdc5hclk_parents, CLK_CFG_3, CLK_CFG_3_SET,
+ CLK_CFG_3_CLR, 0, 2, 7, CLK_CFG_UPDATE, 12),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
+ msdc50_0_parents, CLK_CFG_3, CLK_CFG_3_SET,
+ CLK_CFG_3_CLR, 8, 3, 15, CLK_CFG_UPDATE, 13),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
+ msdc30_1_parents, CLK_CFG_3, CLK_CFG_3_SET,
+ CLK_CFG_3_CLR, 16, 3, 23, CLK_CFG_UPDATE, 14),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents,
+ CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR,
+ 24, 2, 31, CLK_CFG_UPDATE, 15),
+ /* CLK_CFG_4 */
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
+ aud_intbus_parents, CLK_CFG_4, CLK_CFG_4_SET,
+ CLK_CFG_4_CLR, 0, 2, 7, CLK_CFG_UPDATE, 16),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents,
+ CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR,
+ 8, 1, 15, CLK_CFG_UPDATE, 17),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel",
+ aud_engen1_parents, CLK_CFG_4, CLK_CFG_4_SET,
+ CLK_CFG_4_CLR, 16, 2, 23, CLK_CFG_UPDATE, 18),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM_SEL, "disp_pwm_sel",
+ disp_pwm_parents, CLK_CFG_4, CLK_CFG_4_SET,
+ CLK_CFG_4_CLR, 24, 2, 31, CLK_CFG_UPDATE, 19),
+ /* CLK_CFG_5 */
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPM_SEL, "sspm_sel", sspm_parents,
+ CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 0, 2, 7,
+ CLK_CFG_UPDATE, 20),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel", dxcc_parents,
+ CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 8, 2, 15,
+ CLK_CFG_UPDATE, 21),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_SEL, "usb_top_sel",
+ usb_top_parents, CLK_CFG_5, CLK_CFG_5_SET,
+ CLK_CFG_5_CLR, 16, 1, 23, CLK_CFG_UPDATE, 22),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPM_SEL, "spm_sel", spm_parents, CLK_CFG_5,
+ CLK_CFG_5_SET, CLK_CFG_5_CLR, 24, 1, 31,
+ CLK_CFG_UPDATE, 23),
+ /* CLK_CFG_6 */
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, CLK_CFG_6,
+ CLK_CFG_6_SET, CLK_CFG_6_CLR, 0, 3, 7, CLK_CFG_UPDATE,
+ 24),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, CLK_CFG_6,
+ CLK_CFG_6_SET, CLK_CFG_6_CLR, 8, 2, 15, CLK_CFG_UPDATE,
+ 25),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF_SEL, "seninf_sel", seninf_parents,
+ CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 16, 2, 23,
+ CLK_CFG_UPDATE, 26),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_FDE_SEL, "aes_fde_sel",
+ aes_fde_parents, CLK_CFG_6, CLK_CFG_6_SET,
+ CLK_CFG_6_CLR, 24, 3, 31, CLK_CFG_UPDATE, 27),
+ /* CLK_CFG_7 */
+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_PWRAP_ULPOSC_SEL, "ulposc_sel",
+ ulposc_parents, CLK_CFG_7, CLK_CFG_7_SET,
+ CLK_CFG_7_CLR, 0, 3, 7, CLK_CFG_UPDATE, 28,
+ CLK_IS_CRITICAL),
+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM_SEL, "camtm_sel", camtm_parents,
+ CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, 8, 2, 15,
+ CLK_CFG_UPDATE, 29),
+};
+
+static const struct mtk_gate_regs top0_cg_regs = {
+ .set_ofs = 0x0,
+ .clr_ofs = 0x0,
+ .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs top1_cg_regs = {
+ .set_ofs = 0x104,
+ .clr_ofs = 0x104,
+ .sta_ofs = 0x104,
+};
+
+static const struct mtk_gate_regs top2_cg_regs = {
+ .set_ofs = 0x320,
+ .clr_ofs = 0x320,
+ .sta_ofs = 0x320,
+};
+
+#define GATE_TOP0(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &top0_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr, \
+ }
+
+#define GATE_TOP1(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &top1_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+ }
+
+#define GATE_TOP2(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &top2_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr, \
+ }
+
+static const struct mtk_gate top_clks[] = {
+ /* TOP0 */
+ GATE_TOP0(CLK_TOP_MD_32K, "md_32k", "f_frtc_ck", 8),
+ GATE_TOP0(CLK_TOP_MD_26M, "md_26m", "f_f26m_ck", 9),
+ GATE_TOP0(CLK_TOP_MD2_32K, "md2_32k", "f_frtc_ck", 10),
+ GATE_TOP0(CLK_TOP_MD2_26M, "md2_26m", "f_f26m_ck", 11),
+ /* TOP1 */
+ GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL0_EN,
+ "arm_div_pll0_en", "arm_div_pll0", 3),
+ GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL1_EN,
+ "arm_div_pll1_en", "arm_div_pll1", 4),
+ GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL2_EN,
+ "arm_div_pll2_en", "arm_div_pll2", 5),
+ GATE_TOP1(CLK_TOP_FMEM_OCC_DRC_EN, "drc_en", "univpll2_d2", 6),
+ GATE_TOP1(CLK_TOP_USB20_48M_EN, "usb20_48m_en", "usb20_48m_div", 8),
+ GATE_TOP1(CLK_TOP_UNIVPLL_48M_EN, "univpll_48m_en", "univ_48m_div", 9),
+ GATE_TOP1(CLK_TOP_F_UFS_MP_SAP_CFG_EN, "ufs_sap", "f_f26m_ck", 12),
+ GATE_TOP1(CLK_TOP_F_BIST2FPC_EN, "bist2fpc", "f_bist2fpc_ck", 16),
+ /* TOP2 */
+ GATE_TOP2(CLK_TOP_APLL12_DIV0, "apll12_div0", "aud_1_ck", 2),
+ GATE_TOP2(CLK_TOP_APLL12_DIV1, "apll12_div1", "aud_1_ck", 3),
+ GATE_TOP2(CLK_TOP_APLL12_DIV2, "apll12_div2", "aud_1_ck", 4),
+ GATE_TOP2(CLK_TOP_APLL12_DIV3, "apll12_div3", "aud_1_ck", 5),
+};
+
+static const struct mtk_gate_regs ifr2_cg_regs = {
+ .set_ofs = 0x80,
+ .clr_ofs = 0x84,
+ .sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs ifr3_cg_regs = {
+ .set_ofs = 0x88,
+ .clr_ofs = 0x8c,
+ .sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs ifr4_cg_regs = {
+ .set_ofs = 0xa4,
+ .clr_ofs = 0xa8,
+ .sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs ifr5_cg_regs = {
+ .set_ofs = 0xc0,
+ .clr_ofs = 0xc4,
+ .sta_ofs = 0xc8,
+};
+
+#define GATE_IFR2(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &ifr2_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_IFR3(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &ifr3_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_IFR4(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &ifr4_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+#define GATE_IFR5(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &ifr5_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_setclr, \
+ }
+
+static const struct mtk_gate ifr_clks[] = {
+ /* INFRA_TOPAXI */
+ /* INFRA PERI */
+ /* INFRA mode 0 */
+ GATE_IFR2(CLK_IFR_ICUSB, "ifr_icusb", "axi_ck", 8),
+ GATE_IFR2(CLK_IFR_GCE, "ifr_gce", "axi_ck", 9),
+ GATE_IFR2(CLK_IFR_THERM, "ifr_therm", "axi_ck", 10),
+ GATE_IFR2(CLK_IFR_I2C_AP, "ifr_i2c_ap", "i2c_ck", 11),
+ GATE_IFR2(CLK_IFR_I2C_CCU, "ifr_i2c_ccu", "i2c_ck", 12),
+ GATE_IFR2(CLK_IFR_I2C_SSPM, "ifr_i2c_sspm", "i2c_ck", 13),
+ GATE_IFR2(CLK_IFR_I2C_RSV, "ifr_i2c_rsv", "i2c_ck", 14),
+ GATE_IFR2(CLK_IFR_PWM_HCLK, "ifr_pwm_hclk", "axi_ck", 15),
+ GATE_IFR2(CLK_IFR_PWM1, "ifr_pwm1", "f_fpwm_ck", 16),
+ GATE_IFR2(CLK_IFR_PWM2, "ifr_pwm2", "f_fpwm_ck", 17),
+ GATE_IFR2(CLK_IFR_PWM3, "ifr_pwm3", "f_fpwm_ck", 18),
+ GATE_IFR2(CLK_IFR_PWM4, "ifr_pwm4", "f_fpwm_ck", 19),
+ GATE_IFR2(CLK_IFR_PWM5, "ifr_pwm5", "f_fpwm_ck", 20),
+ GATE_IFR2(CLK_IFR_PWM, "ifr_pwm", "f_fpwm_ck", 21),
+ GATE_IFR2(CLK_IFR_UART0, "ifr_uart0", "f_fuart_ck", 22),
+ GATE_IFR2(CLK_IFR_UART1, "ifr_uart1", "f_fuart_ck", 23),
+ GATE_IFR2(CLK_IFR_GCE_26M, "ifr_gce_26m", "f_f26m_ck", 27),
+ GATE_IFR2(CLK_IFR_CQ_DMA_FPC, "ifr_dma", "axi_ck", 28),
+ GATE_IFR2(CLK_IFR_BTIF, "ifr_btif", "axi_ck", 31),
+ /* INFRA mode 1 */
+ GATE_IFR3(CLK_IFR_SPI0, "ifr_spi0", "spi_ck", 1),
+ GATE_IFR3(CLK_IFR_MSDC0, "ifr_msdc0", "msdc5hclk", 2),
+ GATE_IFR3(CLK_IFR_MSDC1, "ifr_msdc1", "axi_ck", 4),
+ GATE_IFR3(CLK_IFR_TRNG, "ifr_trng", "axi_ck", 9),
+ GATE_IFR3(CLK_IFR_AUXADC, "ifr_auxadc", "f_f26m_ck", 10),
+ GATE_IFR3(CLK_IFR_CCIF1_AP, "ifr_ccif1_ap", "axi_ck", 12),
+ GATE_IFR3(CLK_IFR_CCIF1_MD, "ifr_ccif1_md", "axi_ck", 13),
+ GATE_IFR3(CLK_IFR_AUXADC_MD, "ifr_auxadc_md", "f_f26m_ck", 14),
+ GATE_IFR3(CLK_IFR_AP_DMA, "ifr_ap_dma", "axi_ck", 18),
+ GATE_IFR3(CLK_IFR_DEVICE_APC, "ifr_dapc", "axi_ck", 20),
+ GATE_IFR3(CLK_IFR_CCIF_AP, "ifr_ccif_ap", "axi_ck", 23),
+ GATE_IFR3(CLK_IFR_AUDIO, "ifr_audio", "axi_ck", 25),
+ GATE_IFR3(CLK_IFR_CCIF_MD, "ifr_ccif_md", "axi_ck", 26),
+ /* INFRA mode 2 */
+ GATE_IFR4(CLK_IFR_RG_PWM_FBCLK6, "ifr_pwmfb", "f_f26m_ck", 0),
+ GATE_IFR4(CLK_IFR_DISP_PWM, "ifr_disp_pwm", "f_fdisp_pwm_ck", 2),
+ GATE_IFR4(CLK_IFR_CLDMA_BCLK, "ifr_cldmabclk", "axi_ck", 3),
+ GATE_IFR4(CLK_IFR_AUDIO_26M_BCLK, "ifr_audio26m", "f_f26m_ck", 4),
+ GATE_IFR4(CLK_IFR_SPI1, "ifr_spi1", "spi_ck", 6),
+ GATE_IFR4(CLK_IFR_I2C4, "ifr_i2c4", "i2c_ck", 7),
+ GATE_IFR4(CLK_IFR_SPI2, "ifr_spi2", "spi_ck", 9),
+ GATE_IFR4(CLK_IFR_SPI3, "ifr_spi3", "spi_ck", 10),
+ GATE_IFR4(CLK_IFR_I2C5, "ifr_i2c5", "i2c_ck", 18),
+ GATE_IFR4(CLK_IFR_I2C5_ARBITER, "ifr_i2c5a", "i2c_ck", 19),
+ GATE_IFR4(CLK_IFR_I2C5_IMM, "ifr_i2c5_imm", "i2c_ck", 20),
+ GATE_IFR4(CLK_IFR_I2C1_ARBITER, "ifr_i2c1a", "i2c_ck", 21),
+ GATE_IFR4(CLK_IFR_I2C1_IMM, "ifr_i2c1_imm", "i2c_ck", 22),
+ GATE_IFR4(CLK_IFR_I2C2_ARBITER, "ifr_i2c2a", "i2c_ck", 23),
+ GATE_IFR4(CLK_IFR_I2C2_IMM, "ifr_i2c2_imm", "i2c_ck", 24),
+ GATE_IFR4(CLK_IFR_SPI4, "ifr_spi4", "spi_ck", 25),
+ GATE_IFR4(CLK_IFR_SPI5, "ifr_spi5", "spi_ck", 26),
+ GATE_IFR4(CLK_IFR_CQ_DMA, "ifr_cq_dma", "axi_ck", 27),
+ GATE_IFR4(CLK_IFR_FAES_FDE, "ifr_faes_fde_ck", "aes_fde_ck", 29),
+ /* INFRA mode 3 */
+ GATE_IFR5(CLK_IFR_MSDC0_SELF, "ifr_msdc0sf", "msdc50_0_ck", 0),
+ GATE_IFR5(CLK_IFR_MSDC1_SELF, "ifr_msdc1sf", "msdc50_0_ck", 1),
+ GATE_IFR5(CLK_IFR_I2C6, "ifr_i2c6", "i2c_ck", 6),
+ GATE_IFR5(CLK_IFR_AP_MSDC0, "ifr_ap_msdc0", "msdc50_0_ck", 7),
+ GATE_IFR5(CLK_IFR_MD_MSDC0, "ifr_md_msdc0", "msdc50_0_ck", 8),
+ GATE_IFR5(CLK_IFR_MSDC0_SRC, "ifr_msdc0_clk", "msdc50_0_ck", 9),
+ GATE_IFR5(CLK_IFR_MSDC1_SRC, "ifr_msdc1_clk", "msdc30_1_ck", 10),
+ GATE_IFR5(CLK_IFR_MCU_PM_BCLK, "ifr_mcu_pm_bclk", "axi_ck", 17),
+ GATE_IFR5(CLK_IFR_CCIF2_AP, "ifr_ccif2_ap", "axi_ck", 18),
+ GATE_IFR5(CLK_IFR_CCIF2_MD, "ifr_ccif2_md", "axi_ck", 19),
+ GATE_IFR5(CLK_IFR_CCIF3_AP, "ifr_ccif3_ap", "axi_ck", 20),
+ GATE_IFR5(CLK_IFR_CCIF3_MD, "ifr_ccif3_md", "axi_ck", 21),
+};
+
+/* additional CCF control for mipi26M race condition(disp/camera) */
+static const struct mtk_gate_regs apmixed_cg_regs = {
+ .set_ofs = 0x14,
+ .clr_ofs = 0x14,
+ .sta_ofs = 0x14,
+};
+
+#define GATE_APMIXED(_id, _name, _parent, _shift) { \
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .regs = &apmixed_cg_regs, \
+ .shift = _shift, \
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+ }
+
+static const struct mtk_gate apmixed_clks[] = {
+ /* AUDIO0 */
+ GATE_APMIXED(CLK_APMIXED_SSUSB26M, "apmixed_ssusb26m", "f_f26m_ck",
+ 4),
+ GATE_APMIXED(CLK_APMIXED_APPLL26M, "apmixed_appll26m", "f_f26m_ck",
+ 5),
+ GATE_APMIXED(CLK_APMIXED_MIPIC0_26M, "apmixed_mipic026m", "f_f26m_ck",
+ 6),
+ GATE_APMIXED(CLK_APMIXED_MDPLLGP26M, "apmixed_mdpll26m", "f_f26m_ck",
+ 7),
+ GATE_APMIXED(CLK_APMIXED_MMSYS_F26M, "apmixed_mmsys26m", "f_f26m_ck",
+ 8),
+ GATE_APMIXED(CLK_APMIXED_UFS26M, "apmixed_ufs26m", "f_f26m_ck",
+ 9),
+ GATE_APMIXED(CLK_APMIXED_MIPIC1_26M, "apmixed_mipic126m", "f_f26m_ck",
+ 11),
+ GATE_APMIXED(CLK_APMIXED_MEMPLL26M, "apmixed_mempll26m", "f_f26m_ck",
+ 13),
+ GATE_APMIXED(CLK_APMIXED_CLKSQ_LVPLL_26M, "apmixed_lvpll26m",
+ "f_f26m_ck", 14),
+ GATE_APMIXED(CLK_APMIXED_MIPID0_26M, "apmixed_mipid026m", "f_f26m_ck",
+ 16),
+};
+
+#define MT6765_PLL_FMAX (3800UL * MHZ)
+#define MT6765_PLL_FMIN (1500UL * MHZ)
+
+#define CON0_MT6765_RST_BAR BIT(23)
+
+#define PLL_INFO_NULL (0xFF)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
+ _pcwibits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,\
+ _tuner_en_bit, _pcw_reg, _pcw_shift, _div_table) {\
+ .id = _id, \
+ .name = _name, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .flags = _flags, \
+ .rst_bar_mask = CON0_MT6765_RST_BAR, \
+ .fmax = MT6765_PLL_FMAX, \
+ .fmin = MT6765_PLL_FMIN, \
+ .pcwbits = _pcwbits, \
+ .pcwibits = _pcwibits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .tuner_reg = _tuner_reg, \
+ .tuner_en_reg = _tuner_en_reg, \
+ .tuner_en_bit = _tuner_en_bit, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ .div_table = _div_table, \
+ }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
+ _pcwibits, _pd_reg, _pd_shift, _tuner_reg, \
+ _tuner_en_reg, _tuner_en_bit, _pcw_reg, \
+ _pcw_shift) \
+ PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \
+ _pcwbits, _pcwibits, _pd_reg, _pd_shift, \
+ _tuner_reg, _tuner_en_reg, _tuner_en_bit, \
+ _pcw_reg, _pcw_shift, NULL) \
+
+static const struct mtk_pll_data plls[] = {
+ PLL(CLK_APMIXED_ARMPLL_L, "armpll_l", 0x021C, 0x0228, BIT(0),
+ PLL_AO, 22, 8, 0x0220, 24, 0, 0, 0, 0x0220, 0),
+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x020C, 0x0218, BIT(0),
+ PLL_AO, 22, 8, 0x0210, 24, 0, 0, 0, 0x0210, 0),
+ PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x022C, 0x0238, BIT(0),
+ PLL_AO, 22, 8, 0x0230, 24, 0, 0, 0, 0x0230, 0),
+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x023C, 0x0248, BIT(0),
+ (HAVE_RST_BAR | PLL_AO), 22, 8, 0x0240, 24, 0, 0, 0, 0x0240,
+ 0),
+ PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x024C, 0x0258, BIT(0),
+ 0, 22, 8, 0x0250, 24, 0, 0, 0, 0x0250, 0),
+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x025C, 0x0268, BIT(0),
+ 0, 22, 8, 0x0260, 24, 0, 0, 0, 0x0260, 0),
+ PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x026C, 0x0278, BIT(0),
+ HAVE_RST_BAR, 22, 8, 0x0270, 24, 0, 0, 0, 0x0270, 0),
+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x027C, 0x0288, BIT(0),
+ 0, 22, 8, 0x0280, 24, 0, 0, 0, 0x0280, 0),
+ PLL(CLK_APMIXED_APLL1, "apll1", 0x028C, 0x029C, BIT(0),
+ 0, 32, 8, 0x0290, 24, 0x0040, 0x000C, 0, 0x0294, 0),
+ PLL(CLK_APMIXED_MPLL, "mpll", 0x02A0, 0x02AC, BIT(0),
+ PLL_AO, 22, 8, 0x02A4, 24, 0, 0, 0, 0x02A4, 0),
+};
+
+static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+ void __iomem *base;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return PTR_ERR(base);
+ }
+
+ clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+ mtk_clk_register_gates(node, apmixed_clks,
+ ARRAY_SIZE(apmixed_clks), clk_data);
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ apmixed_base = base;
+ /* MPLL, CCIPLL, MAINPLL set HW mode, TDCLKSQ, CLKSQ1 */
+ writel(readl(AP_PLL_CON3) & 0xFFFFFFE1, AP_PLL_CON3);
+ writel(readl(PLLON_CON0) & 0x01041041, PLLON_CON0);
+ writel(readl(PLLON_CON1) & 0x01041041, PLLON_CON1);
+
+ return r;
+}
+
+static int clk_mt6765_top_probe(struct platform_device *pdev)
+{
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+ void __iomem *base;
+ struct clk_onecell_data *clk_data;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return PTR_ERR(base);
+ }
+
+ clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+
+ mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
+ clk_data);
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
+ clk_data);
+ mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+ &mt6765_clk_lock, clk_data);
+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+ clk_data);
+
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ cksys_base = base;
+ /* [4]:no need */
+ writel(readl(CLK_SCP_CFG_0) | 0x3EF, CLK_SCP_CFG_0);
+ /*[1,2,3,8]: no need*/
+ writel(readl(CLK_SCP_CFG_1) | 0x1, CLK_SCP_CFG_1);
+
+ return r;
+}
+
+static int clk_mt6765_ifr_probe(struct platform_device *pdev)
+{
+ struct clk_onecell_data *clk_data;
+ int r;
+ struct device_node *node = pdev->dev.of_node;
+ void __iomem *base;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base)) {
+ pr_err("%s(): ioremap failed\n", __func__);
+ return PTR_ERR(base);
+ }
+
+ clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
+
+ mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks),
+ clk_data);
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
+
+ return r;
+}
+
+static const struct of_device_id of_match_clk_mt6765[] = {
+ {
+ .compatible = "mediatek,mt6765-apmixedsys",
+ .data = clk_mt6765_apmixed_probe,
+ }, {
+ .compatible = "mediatek,mt6765-topckgen",
+ .data = clk_mt6765_top_probe,
+ }, {
+ .compatible = "mediatek,mt6765-infracfg",
+ .data = clk_mt6765_ifr_probe,
+ }, {
+ /* sentinel */
+ }
+};
+
+static int clk_mt6765_probe(struct platform_device *pdev)
+{
+ int (*clk_probe)(struct platform_device *d);
+ int r;
+
+ clk_probe = of_device_get_match_data(&pdev->dev);
+ if (!clk_probe)
+ return -EINVAL;
+
+ r = clk_probe(pdev);
+ if (r)
+ dev_err(&pdev->dev,
+ "could not register clock provider: %s: %d\n",
+ pdev->name, r);
+
+ return r;
+}
+
+static struct platform_driver clk_mt6765_drv = {
+ .probe = clk_mt6765_probe,
+ .driver = {
+ .name = "clk-mt6765",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_clk_mt6765,
+ },
+};
+
+static int __init clk_mt6765_init(void)
+{
+ return platform_driver_register(&clk_mt6765_drv);
+}
+
+arch_initcall(clk_mt6765_init);
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 76f9cd039195..14e127e9a740 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -160,7 +160,7 @@ struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
spinlock_t *lock)
{
struct mtk_clk_mux *clk_mux;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct clk *clk;
clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL);
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index fad616cac01e..30c15766ebb1 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -3702,7 +3702,9 @@ static struct clk_regmap g12a_hdmi = {
/*
* The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
- * muxed by a glitch-free switch.
+ * muxed by a glitch-free switch. The CCF can manage this glitch-free
+ * mux because it does top-to-bottom updates the each clock tree and
+ * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
*/
static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
{ .fw_name = "xtal", },
@@ -3726,7 +3728,13 @@ static struct clk_regmap g12a_mali_0_sel = {
.ops = &clk_regmap_mux_ops,
.parent_data = g12a_mali_0_1_parent_data,
.num_parents = 8,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ /*
+ * Don't request the parent to change the rate because
+ * all GPU frequencies can be derived from the fclk_*
+ * clocks and one special GP0_PLL setting. This is
+ * important because we need the MPLL clocks for audio.
+ */
+ .flags = 0,
},
};
@@ -3743,7 +3751,7 @@ static struct clk_regmap g12a_mali_0_div = {
&g12a_mali_0_sel.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -3759,7 +3767,7 @@ static struct clk_regmap g12a_mali_0 = {
&g12a_mali_0_div.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
},
};
@@ -3774,7 +3782,13 @@ static struct clk_regmap g12a_mali_1_sel = {
.ops = &clk_regmap_mux_ops,
.parent_data = g12a_mali_0_1_parent_data,
.num_parents = 8,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ /*
+ * Don't request the parent to change the rate because
+ * all GPU frequencies can be derived from the fclk_*
+ * clocks and one special GP0_PLL setting. This is
+ * important because we need the MPLL clocks for audio.
+ */
+ .flags = 0,
},
};
@@ -3791,7 +3805,7 @@ static struct clk_regmap g12a_mali_1_div = {
&g12a_mali_1_sel.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -3807,7 +3821,7 @@ static struct clk_regmap g12a_mali_1 = {
&g12a_mali_1_div.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
},
};
@@ -3827,7 +3841,7 @@ static struct clk_regmap g12a_mali = {
.ops = &clk_regmap_mux_ops,
.parent_hws = g12a_mali_parent_hws,
.num_parents = 2,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 5fd6a574f8c3..0a68af6eec3d 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -957,7 +957,9 @@ static struct clk_regmap gxbb_sar_adc_clk = {
/*
* The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
- * muxed by a glitch-free switch.
+ * muxed by a glitch-free switch. The CCF can manage this glitch-free
+ * mux because it does top-to-bottom updates the each clock tree and
+ * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
*/
static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = {
@@ -980,14 +982,15 @@ static struct clk_regmap gxbb_mali_0_sel = {
.hw.init = &(struct clk_init_data){
.name = "mali_0_sel",
.ops = &clk_regmap_mux_ops,
- /*
- * bits 10:9 selects from 8 possible parents:
- * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
- * fclk_div4, fclk_div3, fclk_div5
- */
.parent_data = gxbb_mali_0_1_parent_data,
.num_parents = 8,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ /*
+ * Don't request the parent to change the rate because
+ * all GPU frequencies can be derived from the fclk_*
+ * clocks and one special GP0_PLL setting. This is
+ * important because we need the MPLL clocks for audio.
+ */
+ .flags = 0,
},
};
@@ -1004,7 +1007,7 @@ static struct clk_regmap gxbb_mali_0_div = {
&gxbb_mali_0_sel.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -1020,7 +1023,7 @@ static struct clk_regmap gxbb_mali_0 = {
&gxbb_mali_0_div.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
},
};
@@ -1033,14 +1036,15 @@ static struct clk_regmap gxbb_mali_1_sel = {
.hw.init = &(struct clk_init_data){
.name = "mali_1_sel",
.ops = &clk_regmap_mux_ops,
- /*
- * bits 10:9 selects from 8 possible parents:
- * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
- * fclk_div4, fclk_div3, fclk_div5
- */
.parent_data = gxbb_mali_0_1_parent_data,
.num_parents = 8,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ /*
+ * Don't request the parent to change the rate because
+ * all GPU frequencies can be derived from the fclk_*
+ * clocks and one special GP0_PLL setting. This is
+ * important because we need the MPLL clocks for audio.
+ */
+ .flags = 0,
},
};
@@ -1057,7 +1061,7 @@ static struct clk_regmap gxbb_mali_1_div = {
&gxbb_mali_1_sel.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -1073,7 +1077,7 @@ static struct clk_regmap gxbb_mali_1 = {
&gxbb_mali_1_div.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
},
};
@@ -1093,7 +1097,7 @@ static struct clk_regmap gxbb_mali = {
.ops = &clk_regmap_mux_ops,
.parent_hws = gxbb_mali_parent_hws,
.num_parents = 2,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 34a70c4b4899..edc09d050ecf 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -1077,7 +1077,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
* Meson8m2: vid2_pll
*/
.parent_hws = (const struct clk_hw *[]) {
- &meson8b_hdmi_pll_dco.hw
+ &meson8b_hdmi_pll_lvds_out.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1213,7 +1213,7 @@ static struct clk_regmap meson8b_vclk_in_en = {
static struct clk_regmap meson8b_vclk_div1_gate = {
.data = &(struct clk_regmap_gate_data){
- .offset = HHI_VID_CLK_DIV,
+ .offset = HHI_VID_CLK_CNTL,
.bit_idx = 0,
},
.hw.init = &(struct clk_init_data){
@@ -1243,7 +1243,7 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = {
static struct clk_regmap meson8b_vclk_div2_div_gate = {
.data = &(struct clk_regmap_gate_data){
- .offset = HHI_VID_CLK_DIV,
+ .offset = HHI_VID_CLK_CNTL,
.bit_idx = 1,
},
.hw.init = &(struct clk_init_data){
@@ -1273,7 +1273,7 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = {
static struct clk_regmap meson8b_vclk_div4_div_gate = {
.data = &(struct clk_regmap_gate_data){
- .offset = HHI_VID_CLK_DIV,
+ .offset = HHI_VID_CLK_CNTL,
.bit_idx = 2,
},
.hw.init = &(struct clk_init_data){
@@ -1303,7 +1303,7 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = {
static struct clk_regmap meson8b_vclk_div6_div_gate = {
.data = &(struct clk_regmap_gate_data){
- .offset = HHI_VID_CLK_DIV,
+ .offset = HHI_VID_CLK_CNTL,
.bit_idx = 3,
},
.hw.init = &(struct clk_init_data){
@@ -1333,7 +1333,7 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = {
static struct clk_regmap meson8b_vclk_div12_div_gate = {
.data = &(struct clk_regmap_gate_data){
- .offset = HHI_VID_CLK_DIV,
+ .offset = HHI_VID_CLK_CNTL,
.bit_idx = 4,
},
.hw.init = &(struct clk_init_data){
@@ -1725,7 +1725,7 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_sys_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
/* FIXME: all other parents are unknown */
.parent_data = &(const struct clk_parent_data) {
.fw_name = "xtal",
@@ -1745,7 +1745,7 @@ static struct clk_regmap meson8b_hdmi_sys_div = {
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_sys_div",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&meson8b_hdmi_sys_sel.hw
},
@@ -1761,7 +1761,7 @@ static struct clk_regmap meson8b_hdmi_sys = {
},
.hw.init = &(struct clk_init_data) {
.name = "hdmi_sys",
- .ops = &clk_regmap_gate_ro_ops,
+ .ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&meson8b_hdmi_sys_div.hw
},
@@ -1918,6 +1918,13 @@ static struct clk_regmap meson8b_mali = {
},
};
+static const struct reg_sequence meson8m2_gp_pll_init_regs[] = {
+ { .reg = HHI_GP_PLL_CNTL2, .def = 0x59c88000 },
+ { .reg = HHI_GP_PLL_CNTL3, .def = 0xca463823 },
+ { .reg = HHI_GP_PLL_CNTL4, .def = 0x0286a027 },
+ { .reg = HHI_GP_PLL_CNTL5, .def = 0x00003000 },
+};
+
static const struct pll_params_table meson8m2_gp_pll_params_table[] = {
PLL_PARAMS(182, 3),
{ /* sentinel */ },
@@ -1951,6 +1958,8 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
.width = 1,
},
.table = meson8m2_gp_pll_params_table,
+ .init_regs = meson8m2_gp_pll_init_regs,
+ .init_count = ARRAY_SIZE(meson8m2_gp_pll_init_regs),
},
.hw.init = &(struct clk_init_data){
.name = "gp_pll_dco",
@@ -2063,7 +2072,7 @@ static struct clk_regmap meson8b_vpu_0 = {
&meson8b_vpu_0_div.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
},
};
@@ -2134,10 +2143,18 @@ static struct clk_regmap meson8b_vpu_1 = {
&meson8b_vpu_1_div.hw
},
.num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
},
};
+/*
+ * The VPU clock has two two identical clock trees (vpu_0 and vpu_1)
+ * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
+ * actually manage this glitch-free mux because it does top-to-bottom
+ * updates the each clock tree and switches to the "inactive" one when
+ * CLK_SET_RATE_GATE is set.
+ * Meson8 only has vpu_0 and no glitch-free mux.
+ */
static struct clk_regmap meson8b_vpu = {
.data = &(struct clk_regmap_mux_data){
.offset = HHI_VPU_CLK_CNTL,
@@ -2152,7 +2169,7 @@ static struct clk_regmap meson8b_vpu = {
&meson8b_vpu_1.hw,
},
.num_parents = 2,
- .flags = CLK_SET_RATE_NO_REPARENT,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -3506,54 +3523,87 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
static const struct meson8b_clk_reset_line {
u32 reg;
u8 bit_idx;
+ bool active_low;
} meson8b_clk_reset_bits[] = {
[CLKC_RESET_L2_CACHE_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 30,
+ .active_low = false,
},
[CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 29,
+ .active_low = false,
},
[CLKC_RESET_SCU_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 28,
+ .active_low = false,
},
[CLKC_RESET_CPU3_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 27,
+ .active_low = false,
},
[CLKC_RESET_CPU2_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 26,
+ .active_low = false,
},
[CLKC_RESET_CPU1_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 25,
+ .active_low = false,
},
[CLKC_RESET_CPU0_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 24,
+ .active_low = false,
},
[CLKC_RESET_A5_GLOBAL_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 18,
+ .active_low = false,
},
[CLKC_RESET_A5_AXI_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 17,
+ .active_low = false,
},
[CLKC_RESET_A5_ABP_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
+ .reg = HHI_SYS_CPU_CLK_CNTL0,
+ .bit_idx = 16,
+ .active_low = false,
},
[CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
- .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
+ .reg = HHI_SYS_CPU_CLK_CNTL1,
+ .bit_idx = 30,
+ .active_low = false,
},
[CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
- .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
+ .reg = HHI_VID_CLK_CNTL,
+ .bit_idx = 15,
+ .active_low = false,
},
[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
- .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
+ .reg = HHI_VID_DIVIDER_CNTL,
+ .bit_idx = 7,
+ .active_low = false,
},
[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
- .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
+ .reg = HHI_VID_DIVIDER_CNTL,
+ .bit_idx = 3,
+ .active_low = false,
},
[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
- .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
+ .reg = HHI_VID_DIVIDER_CNTL,
+ .bit_idx = 1,
+ .active_low = true,
},
[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
- .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
+ .reg = HHI_VID_DIVIDER_CNTL,
+ .bit_idx = 0,
+ .active_low = true,
},
};
@@ -3562,22 +3612,22 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
{
struct meson8b_clk_reset *meson8b_clk_reset =
container_of(rcdev, struct meson8b_clk_reset, reset);
- unsigned long flags;
const struct meson8b_clk_reset_line *reset;
+ unsigned int value = 0;
+ unsigned long flags;
if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
return -EINVAL;
reset = &meson8b_clk_reset_bits[id];
+ if (assert != reset->active_low)
+ value = BIT(reset->bit_idx);
+
spin_lock_irqsave(&meson_clk_lock, flags);
- if (assert)
- regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
- BIT(reset->bit_idx), BIT(reset->bit_idx));
- else
- regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
- BIT(reset->bit_idx), 0);
+ regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
+ BIT(reset->bit_idx), value);
spin_unlock_irqrestore(&meson_clk_lock, flags);
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index c889fbeec30f..cd38ae2a9cb5 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -20,6 +20,10 @@
* [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
*/
#define HHI_GP_PLL_CNTL 0x40 /* 0x10 offset in data sheet */
+#define HHI_GP_PLL_CNTL2 0x44 /* 0x11 offset in data sheet */
+#define HHI_GP_PLL_CNTL3 0x48 /* 0x12 offset in data sheet */
+#define HHI_GP_PLL_CNTL4 0x4C /* 0x13 offset in data sheet */
+#define HHI_GP_PLL_CNTL5 0x50 /* 0x14 offset in data sheet */
#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
@@ -146,7 +150,6 @@
#define CLKID_CTS_VDAC0 171
#define CLKID_HDMI_SYS_SEL 172
#define CLKID_HDMI_SYS_DIV 173
-#define CLKID_HDMI_SYS 174
#define CLKID_MALI_0_SEL 175
#define CLKID_MALI_0_DIV 176
#define CLKID_MALI_0 177
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 14dc8a8a9d08..cbcc2f8430a2 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -8,7 +8,8 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
-obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o
+obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o pwr-island.o
+obj-$(CONFIG_COMMON_CLK_MMP2_AUDIO) += clk-audio.o
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-audio.c b/drivers/clk/mmp/clk-audio.c
new file mode 100644
index 000000000000..eea69d498bd2
--- /dev/null
+++ b/drivers/clk/mmp/clk-audio.c
@@ -0,0 +1,443 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MMP Audio Clock Controller driver
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/marvell,mmp2-audio.h>
+
+/* Audio Controller Registers */
+#define SSPA_AUD_CTRL 0x04
+#define SSPA_AUD_PLL_CTRL0 0x08
+#define SSPA_AUD_PLL_CTRL1 0x0c
+
+/* SSPA Audio Control Register */
+#define SSPA_AUD_CTRL_SYSCLK_SHIFT 0
+#define SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT 1
+#define SSPA_AUD_CTRL_SSPA0_MUX_SHIFT 7
+#define SSPA_AUD_CTRL_SSPA0_SHIFT 8
+#define SSPA_AUD_CTRL_SSPA0_DIV_SHIFT 9
+#define SSPA_AUD_CTRL_SSPA1_SHIFT 16
+#define SSPA_AUD_CTRL_SSPA1_DIV_SHIFT 17
+#define SSPA_AUD_CTRL_SSPA1_MUX_SHIFT 23
+#define SSPA_AUD_CTRL_DIV_MASK 0x7e
+
+/* SSPA Audio PLL Control 0 Register */
+#define SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO_MASK (0x7 << 28)
+#define SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(x) ((x) << 28)
+#define SSPA_AUD_PLL_CTRL0_FRACT_MASK (0xfffff << 8)
+#define SSPA_AUD_PLL_CTRL0_FRACT(x) ((x) << 8)
+#define SSPA_AUD_PLL_CTRL0_ENA_DITHER (1 << 7)
+#define SSPA_AUD_PLL_CTRL0_ICP_2UA (0 << 5)
+#define SSPA_AUD_PLL_CTRL0_ICP_5UA (1 << 5)
+#define SSPA_AUD_PLL_CTRL0_ICP_7UA (2 << 5)
+#define SSPA_AUD_PLL_CTRL0_ICP_10UA (3 << 5)
+#define SSPA_AUD_PLL_CTRL0_DIV_FBCCLK_MASK (0x3 << 3)
+#define SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(x) ((x) << 3)
+#define SSPA_AUD_PLL_CTRL0_DIV_MCLK_MASK (0x1 << 2)
+#define SSPA_AUD_PLL_CTRL0_DIV_MCLK(x) ((x) << 2)
+#define SSPA_AUD_PLL_CTRL0_PD_OVPROT_DIS (1 << 1)
+#define SSPA_AUD_PLL_CTRL0_PU (1 << 0)
+
+/* SSPA Audio PLL Control 1 Register */
+#define SSPA_AUD_PLL_CTRL1_SEL_FAST_CLK (1 << 24)
+#define SSPA_AUD_PLL_CTRL1_CLK_SEL_MASK (1 << 11)
+#define SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL (1 << 11)
+#define SSPA_AUD_PLL_CTRL1_CLK_SEL_VCXO (0 << 11)
+#define SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN_MASK (0x7ff << 0)
+#define SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(x) ((x) << 0)
+
+struct mmp2_audio_clk {
+ void __iomem *mmio_base;
+
+ struct clk_hw audio_pll_hw;
+ struct clk_mux sspa_mux;
+ struct clk_mux sspa1_mux;
+ struct clk_divider sysclk_div;
+ struct clk_divider sspa0_div;
+ struct clk_divider sspa1_div;
+ struct clk_gate sysclk_gate;
+ struct clk_gate sspa0_gate;
+ struct clk_gate sspa1_gate;
+
+ u32 aud_ctrl;
+ u32 aud_pll_ctrl0;
+ u32 aud_pll_ctrl1;
+
+ spinlock_t lock;
+
+ /* Must be last */
+ struct clk_hw_onecell_data clk_data;
+};
+
+static const struct {
+ unsigned long parent_rate;
+ unsigned long freq_vco;
+ unsigned char mclk;
+ unsigned char fbcclk;
+ unsigned short fract;
+} predivs[] = {
+ { 26000000, 135475200, 0, 0, 0x8a18 },
+ { 26000000, 147456000, 0, 1, 0x0da1 },
+ { 38400000, 135475200, 1, 2, 0x8208 },
+ { 38400000, 147456000, 1, 3, 0xaaaa },
+};
+
+static const struct {
+ unsigned char divisor;
+ unsigned char modulo;
+ unsigned char pattern;
+} postdivs[] = {
+ { 1, 3, 0, },
+ { 2, 5, 0, },
+ { 4, 0, 0, },
+ { 6, 1, 1, },
+ { 8, 1, 0, },
+ { 9, 1, 2, },
+ { 12, 2, 1, },
+ { 16, 2, 0, },
+ { 18, 2, 2, },
+ { 24, 4, 1, },
+ { 36, 4, 2, },
+ { 48, 6, 1, },
+ { 72, 6, 2, },
+};
+
+static unsigned long audio_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mmp2_audio_clk *priv = container_of(hw, struct mmp2_audio_clk, audio_pll_hw);
+ unsigned int prediv;
+ unsigned int postdiv;
+ u32 aud_pll_ctrl0;
+ u32 aud_pll_ctrl1;
+
+ aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0);
+ aud_pll_ctrl0 &= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO_MASK |
+ SSPA_AUD_PLL_CTRL0_FRACT_MASK |
+ SSPA_AUD_PLL_CTRL0_ENA_DITHER |
+ SSPA_AUD_PLL_CTRL0_DIV_FBCCLK_MASK |
+ SSPA_AUD_PLL_CTRL0_DIV_MCLK_MASK |
+ SSPA_AUD_PLL_CTRL0_PU;
+
+ aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1);
+ aud_pll_ctrl1 &= SSPA_AUD_PLL_CTRL1_CLK_SEL_MASK |
+ SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN_MASK;
+
+ for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
+ if (predivs[prediv].parent_rate != parent_rate)
+ continue;
+ for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
+ unsigned long freq;
+ u32 val;
+
+ val = SSPA_AUD_PLL_CTRL0_ENA_DITHER;
+ val |= SSPA_AUD_PLL_CTRL0_PU;
+ val |= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(postdivs[postdiv].modulo);
+ val |= SSPA_AUD_PLL_CTRL0_FRACT(predivs[prediv].fract);
+ val |= SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(predivs[prediv].fbcclk);
+ val |= SSPA_AUD_PLL_CTRL0_DIV_MCLK(predivs[prediv].mclk);
+ if (val != aud_pll_ctrl0)
+ continue;
+
+ val = SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL;
+ val |= SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(postdivs[postdiv].pattern);
+ if (val != aud_pll_ctrl1)
+ continue;
+
+ freq = predivs[prediv].freq_vco;
+ freq /= postdivs[postdiv].divisor;
+ return freq;
+ }
+ }
+
+ return 0;
+}
+
+static long audio_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned int prediv;
+ unsigned int postdiv;
+ long rounded = 0;
+
+ for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
+ if (predivs[prediv].parent_rate != *parent_rate)
+ continue;
+ for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
+ long freq = predivs[prediv].freq_vco;
+
+ freq /= postdivs[postdiv].divisor;
+ if (freq == rate)
+ return rate;
+ if (freq < rate)
+ continue;
+ if (rounded && freq > rounded)
+ continue;
+ rounded = freq;
+ }
+ }
+
+ return rounded;
+}
+
+static int audio_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct mmp2_audio_clk *priv = container_of(hw, struct mmp2_audio_clk, audio_pll_hw);
+ unsigned int prediv;
+ unsigned int postdiv;
+ unsigned long val;
+
+ for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
+ if (predivs[prediv].parent_rate != parent_rate)
+ continue;
+
+ for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
+ if (rate * postdivs[postdiv].divisor != predivs[prediv].freq_vco)
+ continue;
+
+ val = SSPA_AUD_PLL_CTRL0_ENA_DITHER;
+ val |= SSPA_AUD_PLL_CTRL0_PU;
+ val |= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(postdivs[postdiv].modulo);
+ val |= SSPA_AUD_PLL_CTRL0_FRACT(predivs[prediv].fract);
+ val |= SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(predivs[prediv].fbcclk);
+ val |= SSPA_AUD_PLL_CTRL0_DIV_MCLK(predivs[prediv].mclk);
+ writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL0);
+
+ val = SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL;
+ val |= SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(postdivs[postdiv].pattern);
+ writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL1);
+
+ return 0;
+ }
+ }
+
+ return -ERANGE;
+}
+
+static const struct clk_ops audio_pll_ops = {
+ .recalc_rate = audio_pll_recalc_rate,
+ .round_rate = audio_pll_round_rate,
+ .set_rate = audio_pll_set_rate,
+};
+
+static int register_clocks(struct mmp2_audio_clk *priv, struct device *dev)
+{
+ const struct clk_parent_data sspa_mux_parents[] = {
+ { .hw = &priv->audio_pll_hw },
+ { .fw_name = "i2s0" },
+ };
+ const struct clk_parent_data sspa1_mux_parents[] = {
+ { .hw = &priv->audio_pll_hw },
+ { .fw_name = "i2s1" },
+ };
+ int ret;
+
+ priv->audio_pll_hw.init = CLK_HW_INIT_FW_NAME("audio_pll",
+ "vctcxo", &audio_pll_ops,
+ CLK_SET_RATE_PARENT);
+ ret = devm_clk_hw_register(dev, &priv->audio_pll_hw);
+ if (ret)
+ return ret;
+
+ priv->sspa_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa_mux",
+ sspa_mux_parents, &clk_mux_ops,
+ CLK_SET_RATE_PARENT);
+ priv->sspa_mux.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sspa_mux.mask = 1;
+ priv->sspa_mux.shift = SSPA_AUD_CTRL_SSPA0_MUX_SHIFT;
+ ret = devm_clk_hw_register(dev, &priv->sspa_mux.hw);
+ if (ret)
+ return ret;
+
+ priv->sysclk_div.hw.init = CLK_HW_INIT_HW("sys_div",
+ &priv->sspa_mux.hw, &clk_divider_ops,
+ CLK_SET_RATE_PARENT);
+ priv->sysclk_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sysclk_div.shift = SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT;
+ priv->sysclk_div.width = 6;
+ priv->sysclk_div.flags = CLK_DIVIDER_ONE_BASED;
+ priv->sysclk_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
+ priv->sysclk_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
+ ret = devm_clk_hw_register(dev, &priv->sysclk_div.hw);
+ if (ret)
+ return ret;
+
+ priv->sysclk_gate.hw.init = CLK_HW_INIT_HW("sys_clk",
+ &priv->sysclk_div.hw, &clk_gate_ops,
+ CLK_SET_RATE_PARENT);
+ priv->sysclk_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sysclk_gate.bit_idx = SSPA_AUD_CTRL_SYSCLK_SHIFT;
+ ret = devm_clk_hw_register(dev, &priv->sysclk_gate.hw);
+ if (ret)
+ return ret;
+
+ priv->sspa0_div.hw.init = CLK_HW_INIT_HW("sspa0_div",
+ &priv->sspa_mux.hw, &clk_divider_ops, 0);
+ priv->sspa0_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sspa0_div.shift = SSPA_AUD_CTRL_SSPA0_DIV_SHIFT;
+ priv->sspa0_div.width = 6;
+ priv->sspa0_div.flags = CLK_DIVIDER_ONE_BASED;
+ priv->sspa0_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
+ priv->sspa0_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
+ ret = devm_clk_hw_register(dev, &priv->sspa0_div.hw);
+ if (ret)
+ return ret;
+
+ priv->sspa0_gate.hw.init = CLK_HW_INIT_HW("sspa0_clk",
+ &priv->sspa0_div.hw, &clk_gate_ops,
+ CLK_SET_RATE_PARENT);
+ priv->sspa0_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sspa0_gate.bit_idx = SSPA_AUD_CTRL_SSPA0_SHIFT;
+ ret = devm_clk_hw_register(dev, &priv->sspa0_gate.hw);
+ if (ret)
+ return ret;
+
+ priv->sspa1_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa1_mux",
+ sspa1_mux_parents, &clk_mux_ops,
+ CLK_SET_RATE_PARENT);
+ priv->sspa1_mux.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sspa1_mux.mask = 1;
+ priv->sspa1_mux.shift = SSPA_AUD_CTRL_SSPA1_MUX_SHIFT;
+ ret = devm_clk_hw_register(dev, &priv->sspa1_mux.hw);
+ if (ret)
+ return ret;
+
+ priv->sspa1_div.hw.init = CLK_HW_INIT_HW("sspa1_div",
+ &priv->sspa1_mux.hw, &clk_divider_ops, 0);
+ priv->sspa1_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sspa1_div.shift = SSPA_AUD_CTRL_SSPA1_DIV_SHIFT;
+ priv->sspa1_div.width = 6;
+ priv->sspa1_div.flags = CLK_DIVIDER_ONE_BASED;
+ priv->sspa1_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
+ priv->sspa1_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
+ ret = devm_clk_hw_register(dev, &priv->sspa1_div.hw);
+ if (ret)
+ return ret;
+
+ priv->sspa1_gate.hw.init = CLK_HW_INIT_HW("sspa1_clk",
+ &priv->sspa1_div.hw, &clk_gate_ops,
+ CLK_SET_RATE_PARENT);
+ priv->sspa1_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
+ priv->sspa1_gate.bit_idx = SSPA_AUD_CTRL_SSPA1_SHIFT;
+ ret = devm_clk_hw_register(dev, &priv->sspa1_gate.hw);
+ if (ret)
+ return ret;
+
+ priv->clk_data.hws[MMP2_CLK_AUDIO_SYSCLK] = &priv->sysclk_gate.hw;
+ priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA0] = &priv->sspa0_gate.hw;
+ priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA1] = &priv->sspa1_gate.hw;
+ priv->clk_data.num = MMP2_CLK_AUDIO_NR_CLKS;
+
+ return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+ &priv->clk_data);
+}
+
+static int mmp2_audio_clk_probe(struct platform_device *pdev)
+{
+ struct mmp2_audio_clk *priv;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev,
+ struct_size(priv, clk_data.hws,
+ MMP2_CLK_AUDIO_NR_CLKS),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+ platform_set_drvdata(pdev, priv);
+
+ priv->mmio_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->mmio_base))
+ return PTR_ERR(priv->mmio_base);
+
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_clk_create(&pdev->dev);
+ if (ret)
+ goto disable_pm_runtime;
+
+ ret = pm_clk_add(&pdev->dev, "audio");
+ if (ret)
+ goto destroy_pm_clk;
+
+ ret = register_clocks(priv, &pdev->dev);
+ if (ret)
+ goto destroy_pm_clk;
+
+ return 0;
+
+destroy_pm_clk:
+ pm_clk_destroy(&pdev->dev);
+disable_pm_runtime:
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static int mmp2_audio_clk_remove(struct platform_device *pdev)
+{
+ pm_clk_destroy(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev)
+{
+ struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
+
+ priv->aud_ctrl = readl(priv->mmio_base + SSPA_AUD_CTRL);
+ priv->aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0);
+ priv->aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1);
+ pm_clk_suspend(dev);
+
+ return 0;
+}
+
+static int __maybe_unused mmp2_audio_clk_resume(struct device *dev)
+{
+ struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
+
+ pm_clk_resume(dev);
+ writel(priv->aud_ctrl, priv->mmio_base + SSPA_AUD_CTRL);
+ writel(priv->aud_pll_ctrl0, priv->mmio_base + SSPA_AUD_PLL_CTRL0);
+ writel(priv->aud_pll_ctrl1, priv->mmio_base + SSPA_AUD_PLL_CTRL1);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mmp2_audio_clk_pm_ops = {
+ SET_RUNTIME_PM_OPS(mmp2_audio_clk_suspend, mmp2_audio_clk_resume, NULL)
+};
+
+static const struct of_device_id mmp2_audio_clk_of_match[] = {
+ { .compatible = "marvell,mmp2-audio-clock" },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, mmp2_audio_clk_of_match);
+
+static struct platform_driver mmp2_audio_clk_driver = {
+ .driver = {
+ .name = "mmp2-audio-clock",
+ .of_match_table = of_match_ptr(mmp2_audio_clk_of_match),
+ .pm = &mmp2_audio_clk_pm_ops,
+ },
+ .probe = mmp2_audio_clk_probe,
+ .remove = mmp2_audio_clk_remove,
+};
+module_platform_driver(mmp2_audio_clk_driver);
+
+MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
+MODULE_DESCRIPTION("Clock driver for MMP2 Audio subsystem");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index fabc09aca6c4..48f592bd633d 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -28,13 +28,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
unsigned long *prate)
{
struct mmp_clk_factor *factor = to_clk_factor(hw);
- unsigned long rate = 0, prev_rate;
+ u64 rate = 0, prev_rate;
int i;
for (i = 0; i < factor->ftbl_cnt; i++) {
prev_rate = rate;
- rate = (((*prate / 10000) * factor->ftbl[i].den) /
- (factor->ftbl[i].num * factor->masks->factor)) * 10000;
+ rate = *prate;
+ rate *= factor->ftbl[i].den;
+ do_div(rate, factor->ftbl[i].num * factor->masks->factor);
+
if (rate > drate)
break;
}
@@ -54,6 +56,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
struct mmp_clk_factor *factor = to_clk_factor(hw);
struct mmp_clk_factor_masks *masks = factor->masks;
unsigned int val, num, den;
+ u64 rate;
val = readl_relaxed(factor->base);
@@ -66,8 +69,11 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
if (!den)
return 0;
- return (((parent_rate / 10000) * den) /
- (num * factor->masks->factor)) * 10000;
+ rate = parent_rate;
+ rate *= den;
+ do_div(rate, num * factor->masks->factor);
+
+ return rate;
}
/* Configures new clock rate*/
@@ -78,12 +84,14 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
struct mmp_clk_factor_masks *masks = factor->masks;
int i;
unsigned long val;
- unsigned long rate = 0;
unsigned long flags = 0;
+ u64 rate = 0;
for (i = 0; i < factor->ftbl_cnt; i++) {
- rate = (((prate / 10000) * factor->ftbl[i].den) /
- (factor->ftbl[i].num * factor->masks->factor)) * 10000;
+ rate = prate;
+ rate *= factor->ftbl[i].den;
+ do_div(rate, factor->ftbl[i].num * factor->masks->factor);
+
if (rate > drate)
break;
}
@@ -140,7 +148,10 @@ static int clk_factor_init(struct clk_hw *hw)
val &= ~(masks->den_mask << masks->den_shift);
val |= (factor->ftbl[0].den & masks->den_mask) <<
masks->den_shift;
+ }
+ if (!(val & masks->enable_mask) || i >= factor->ftbl_cnt) {
+ val |= masks->enable_mask;
writel(val, factor->base);
}
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 52dc8b43acd9..67208aea94c5 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -17,8 +17,10 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/of_address.h>
+#include <linux/clk.h>
#include <dt-bindings/clock/marvell,mmp2.h>
+#include <dt-bindings/power/marvell,mmp2.h>
#include "clk.h"
#include "reset.h"
@@ -45,6 +47,10 @@
#define APBC_SSP1 0x54
#define APBC_SSP2 0x58
#define APBC_SSP3 0x5c
+#define APBC_THERMAL0 0x90
+#define APBC_THERMAL1 0x98
+#define APBC_THERMAL2 0x9c
+#define APBC_THERMAL3 0xa0
#define APMU_SDH0 0x54
#define APMU_SDH1 0x58
#define APMU_SDH2 0xe8
@@ -55,18 +61,19 @@
#define APMU_DISP1 0x110
#define APMU_CCIC0 0x50
#define APMU_CCIC1 0xf4
-#define APBC_THERMAL0 0x90
-#define APBC_THERMAL1 0x98
-#define APBC_THERMAL2 0x9c
-#define APBC_THERMAL3 0xa0
#define APMU_USBHSIC0 0xf8
#define APMU_USBHSIC1 0xfc
#define APMU_GPU 0xcc
+#define APMU_AUDIO 0x10c
+#define APMU_CAMERA 0x1fc
#define MPMU_FCCR 0x8
#define MPMU_POSR 0x10
#define MPMU_UART_PLL 0x14
#define MPMU_PLL2_CR 0x34
+#define MPMU_I2S0_PLL 0x40
+#define MPMU_I2S1_PLL 0x44
+#define MPMU_ACGR 0x1024
/* MMP3 specific below */
#define MPMU_PLL3_CR 0x50
#define MPMU_PLL3_CTRL1 0x58
@@ -82,6 +89,8 @@ enum mmp2_clk_model {
struct mmp2_clk_unit {
struct mmp_clk_unit unit;
enum mmp2_clk_model model;
+ struct genpd_onecell_data pd_data;
+ struct generic_pm_domain *pm_domains[MMP2_NR_POWER_DOMAINS];
void __iomem *mpmu_base;
void __iomem *apmu_base;
void __iomem *apbc_base;
@@ -91,6 +100,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
{MMP2_CLK_CLK32, "clk32", NULL, 0, 32768},
{MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
{MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
+ {0, "i2s_pll", NULL, 0, 99666667},
};
static struct mmp_param_pll_clk pll_clks[] = {
@@ -139,7 +149,35 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
{.num = 3521, .den = 689}, /*19.23MHZ */
};
-static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
+static struct mmp_clk_factor_masks i2s_factor_masks = {
+ .factor = 2,
+ .num_mask = 0x7fff,
+ .den_mask = 0x1fff,
+ .num_shift = 0,
+ .den_shift = 15,
+ .enable_mask = 0xd0000000,
+};
+
+static struct mmp_clk_factor_tbl i2s_factor_tbl[] = {
+ {.num = 24868, .den = 511}, /* 2.0480 MHz */
+ {.num = 28003, .den = 793}, /* 2.8224 MHz */
+ {.num = 24941, .den = 1025}, /* 4.0960 MHz */
+ {.num = 28003, .den = 1586}, /* 5.6448 MHz */
+ {.num = 31158, .den = 2561}, /* 8.1920 MHz */
+ {.num = 16288, .den = 1845}, /* 11.2896 MHz */
+ {.num = 20772, .den = 2561}, /* 12.2880 MHz */
+ {.num = 8144, .den = 1845}, /* 22.5792 MHz */
+ {.num = 10386, .den = 2561}, /* 24.5760 MHz */
+};
+
+static DEFINE_SPINLOCK(acgr_lock);
+
+static struct mmp_param_gate_clk mpmu_gate_clks[] = {
+ {MMP2_CLK_I2S0, "i2s0_clk", "i2s0_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x200000, 0x200000, 0x0, 0, &acgr_lock},
+ {MMP2_CLK_I2S1, "i2s1_clk", "i2s1_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x100000, 0x100000, 0x0, 0, &acgr_lock},
+};
+
+static void mmp2_main_clk_init(struct mmp2_clk_unit *pxa_unit)
{
struct clk *clk;
struct mmp_clk_unit *unit = &pxa_unit->unit;
@@ -166,6 +204,20 @@ static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
&uart_factor_masks, uart_factor_tbl,
ARRAY_SIZE(uart_factor_tbl), NULL);
mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk);
+
+ mmp_clk_register_factor("i2s0_pll", "pll1_4",
+ CLK_SET_RATE_PARENT,
+ pxa_unit->mpmu_base + MPMU_I2S0_PLL,
+ &i2s_factor_masks, i2s_factor_tbl,
+ ARRAY_SIZE(i2s_factor_tbl), NULL);
+ mmp_clk_register_factor("i2s1_pll", "pll1_4",
+ CLK_SET_RATE_PARENT,
+ pxa_unit->mpmu_base + MPMU_I2S1_PLL,
+ &i2s_factor_masks, i2s_factor_tbl,
+ ARRAY_SIZE(i2s_factor_tbl), NULL);
+
+ mmp_register_gate_clks(unit, mpmu_gate_clks, pxa_unit->mpmu_base,
+ ARRAY_SIZE(mpmu_gate_clks));
}
static DEFINE_SPINLOCK(uart0_lock);
@@ -271,6 +323,8 @@ static u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030,
static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"};
static const char * const mmp3_gpu_gc_parent_names[] = {"pll1", "pll2", "pll1_p", "pll2_p"};
+static DEFINE_SPINLOCK(audio_lock);
+
static struct mmp_clk_mix_config ccic0_mix_config = {
.reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32),
};
@@ -326,6 +380,7 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
{MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
{MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
{MMP2_CLK_GPU_BUS, "gpu_bus_clk", "gpu_bus_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0xa, 0xa, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
+ {MMP2_CLK_AUDIO, "audio_clk", "audio_mix_clk", CLK_SET_RATE_PARENT, APMU_AUDIO, 0x12, 0x12, 0x0, 0, &audio_lock},
};
static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = {
@@ -423,6 +478,41 @@ static void mmp2_clk_reset_init(struct device_node *np,
mmp_clk_reset_register(np, cells, nr_resets);
}
+static void mmp2_pm_domain_init(struct device_node *np,
+ struct mmp2_clk_unit *pxa_unit)
+{
+ if (pxa_unit->model == CLK_MODEL_MMP3) {
+ pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
+ = mmp_pm_domain_register("gpu",
+ pxa_unit->apmu_base + APMU_GPU,
+ 0x0600, 0x40003, 0x18000c, 0, &gpu_lock);
+ } else {
+ pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
+ = mmp_pm_domain_register("gpu",
+ pxa_unit->apmu_base + APMU_GPU,
+ 0x8600, 0x00003, 0x00000c,
+ MMP_PM_DOMAIN_NO_DISABLE, &gpu_lock);
+ }
+ pxa_unit->pd_data.num_domains++;
+
+ pxa_unit->pm_domains[MMP2_POWER_DOMAIN_AUDIO]
+ = mmp_pm_domain_register("audio",
+ pxa_unit->apmu_base + APMU_AUDIO,
+ 0x600, 0x2, 0, 0, &audio_lock);
+ pxa_unit->pd_data.num_domains++;
+
+ if (pxa_unit->model == CLK_MODEL_MMP3) {
+ pxa_unit->pm_domains[MMP3_POWER_DOMAIN_CAMERA]
+ = mmp_pm_domain_register("camera",
+ pxa_unit->apmu_base + APMU_CAMERA,
+ 0x600, 0, 0, 0, NULL);
+ pxa_unit->pd_data.num_domains++;
+ }
+
+ pxa_unit->pd_data.domains = pxa_unit->pm_domains;
+ of_genpd_add_provider_onecell(np, &pxa_unit->pd_data);
+}
+
static void __init mmp2_clk_init(struct device_node *np)
{
struct mmp2_clk_unit *pxa_unit;
@@ -454,9 +544,11 @@ static void __init mmp2_clk_init(struct device_node *np)
goto unmap_apmu_region;
}
+ mmp2_pm_domain_init(np, pxa_unit);
+
mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
- mmp2_pll_init(pxa_unit);
+ mmp2_main_clk_init(pxa_unit);
mmp2_apb_periph_clk_init(pxa_unit);
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 20dc1e5dd756..55ac05379781 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -3,6 +3,7 @@
#define __MACH_MMP_CLK_H
#include <linux/clk-provider.h>
+#include <linux/pm_domain.h>
#include <linux/clkdev.h>
#define APBC_NO_BUS_CTRL BIT(0)
@@ -16,6 +17,7 @@ struct mmp_clk_factor_masks {
unsigned int den_mask;
unsigned int num_shift;
unsigned int den_shift;
+ unsigned int enable_mask;
};
struct mmp_clk_factor_tbl {
@@ -251,4 +253,13 @@ void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
int nr_clks);
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
struct clk *clk);
+
+/* Power islands */
+#define MMP_PM_DOMAIN_NO_DISABLE BIT(0)
+
+struct generic_pm_domain *mmp_pm_domain_register(const char *name,
+ void __iomem *reg,
+ u32 power_on, u32 reset, u32 clock_enable,
+ unsigned int flags, spinlock_t *lock);
+
#endif
diff --git a/drivers/clk/mmp/pwr-island.c b/drivers/clk/mmp/pwr-island.c
new file mode 100644
index 000000000000..ab57c0e995c1
--- /dev/null
+++ b/drivers/clk/mmp/pwr-island.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MMP PMU power island support
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <linux/pm_domain.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include "clk.h"
+
+#define to_mmp_pm_domain(genpd) container_of(genpd, struct mmp_pm_domain, genpd)
+
+struct mmp_pm_domain {
+ struct generic_pm_domain genpd;
+ void __iomem *reg;
+ spinlock_t *lock;
+ u32 power_on;
+ u32 reset;
+ u32 clock_enable;
+ unsigned int flags;
+};
+
+static int mmp_pm_domain_power_on(struct generic_pm_domain *genpd)
+{
+ struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
+ unsigned long flags = 0;
+ u32 val;
+
+ if (pm_domain->lock)
+ spin_lock_irqsave(pm_domain->lock, flags);
+
+ val = readl(pm_domain->reg);
+
+ /* Turn on the power island */
+ val |= pm_domain->power_on;
+ writel(val, pm_domain->reg);
+
+ /* Disable isolation */
+ val |= 0x100;
+ writel(val, pm_domain->reg);
+
+ /* Some blocks need to be reset after a power up */
+ if (pm_domain->reset || pm_domain->clock_enable) {
+ u32 after_power_on = val;
+
+ val &= ~pm_domain->reset;
+ writel(val, pm_domain->reg);
+
+ val |= pm_domain->clock_enable;
+ writel(val, pm_domain->reg);
+
+ val |= pm_domain->reset;
+ writel(val, pm_domain->reg);
+
+ writel(after_power_on, pm_domain->reg);
+ }
+
+ if (pm_domain->lock)
+ spin_unlock_irqrestore(pm_domain->lock, flags);
+
+ return 0;
+}
+
+static int mmp_pm_domain_power_off(struct generic_pm_domain *genpd)
+{
+ struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
+ unsigned long flags = 0;
+ u32 val;
+
+ if (pm_domain->flags & MMP_PM_DOMAIN_NO_DISABLE)
+ return 0;
+
+ if (pm_domain->lock)
+ spin_lock_irqsave(pm_domain->lock, flags);
+
+ /* Turn off and isolate the the power island. */
+ val = readl(pm_domain->reg);
+ val &= ~pm_domain->power_on;
+ val &= ~0x100;
+ writel(val, pm_domain->reg);
+
+ if (pm_domain->lock)
+ spin_unlock_irqrestore(pm_domain->lock, flags);
+
+ return 0;
+}
+
+struct generic_pm_domain *mmp_pm_domain_register(const char *name,
+ void __iomem *reg,
+ u32 power_on, u32 reset, u32 clock_enable,
+ unsigned int flags, spinlock_t *lock)
+{
+ struct mmp_pm_domain *pm_domain;
+
+ pm_domain = kzalloc(sizeof(*pm_domain), GFP_KERNEL);
+ if (!pm_domain)
+ return ERR_PTR(-ENOMEM);
+
+ pm_domain->reg = reg;
+ pm_domain->power_on = power_on;
+ pm_domain->reset = reset;
+ pm_domain->clock_enable = clock_enable;
+ pm_domain->flags = flags;
+ pm_domain->lock = lock;
+
+ pm_genpd_init(&pm_domain->genpd, NULL, true);
+ pm_domain->genpd.name = name;
+ pm_domain->genpd.power_on = mmp_pm_domain_power_on;
+ pm_domain->genpd.power_off = mmp_pm_domain_power_off;
+
+ return &pm_domain->genpd;
+}
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index abb121f8de52..cde6ca90a06b 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -142,6 +142,14 @@ config MSM_GCC_8916
Say Y if you want to use devices such as UART, SPI i2c, USB,
SD/eMMC, display, graphics, camera etc.
+config MSM_GCC_8939
+ tristate "MSM8939 Global Clock Controller"
+ select QCOM_GDSC
+ help
+ Support for the global clock controller on msm8939 devices.
+ Say Y if you want to use devices such as UART, SPI i2c, USB,
+ SD/eMMC, display, graphics, camera etc.
+
config MSM_GCC_8960
tristate "APQ8064/MSM8960 Global Clock Controller"
help
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 691efbf7e81f..7ec8561a1270 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
+obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o
obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index 4e329a7baf2b..17e4a5a2a9fd 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -260,7 +260,7 @@ static struct clk_pll gpll0 = {
.l_reg = 0x21004,
.m_reg = 0x21008,
.n_reg = 0x2100c,
- .config_reg = 0x21014,
+ .config_reg = 0x21010,
.mode_reg = 0x21000,
.status_reg = 0x2101c,
.status_bit = 17,
@@ -287,7 +287,7 @@ static struct clk_pll gpll1 = {
.l_reg = 0x20004,
.m_reg = 0x20008,
.n_reg = 0x2000c,
- .config_reg = 0x20014,
+ .config_reg = 0x20010,
.mode_reg = 0x20000,
.status_reg = 0x2001c,
.status_bit = 17,
@@ -314,7 +314,7 @@ static struct clk_pll gpll2 = {
.l_reg = 0x4a004,
.m_reg = 0x4a008,
.n_reg = 0x4a00c,
- .config_reg = 0x4a014,
+ .config_reg = 0x4a010,
.mode_reg = 0x4a000,
.status_reg = 0x4a01c,
.status_bit = 17,
@@ -341,7 +341,7 @@ static struct clk_pll bimc_pll = {
.l_reg = 0x23004,
.m_reg = 0x23008,
.n_reg = 0x2300c,
- .config_reg = 0x23014,
+ .config_reg = 0x23010,
.mode_reg = 0x23000,
.status_reg = 0x2301c,
.status_bit = 17,
diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
new file mode 100644
index 000000000000..778354f82b1e
--- /dev/null
+++ b/drivers/clk/qcom/gcc-msm8939.c
@@ -0,0 +1,3988 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Linaro Limited
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-msm8939.h>
+#include <dt-bindings/reset/qcom,gcc-msm8939.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+#include "gdsc.h"
+
+enum {
+ P_XO,
+ P_GPLL0,
+ P_GPLL0_AUX,
+ P_BIMC,
+ P_GPLL1,
+ P_GPLL1_AUX,
+ P_GPLL2,
+ P_GPLL2_AUX,
+ P_GPLL3,
+ P_GPLL3_AUX,
+ P_GPLL4,
+ P_GPLL5,
+ P_GPLL5_AUX,
+ P_GPLL5_EARLY,
+ P_GPLL6,
+ P_GPLL6_AUX,
+ P_SLEEP_CLK,
+ P_DSI0_PHYPLL_BYTE,
+ P_DSI0_PHYPLL_DSI,
+ P_EXT_PRI_I2S,
+ P_EXT_SEC_I2S,
+ P_EXT_MCLK,
+};
+
+static struct clk_pll gpll0 = {
+ .l_reg = 0x21004,
+ .m_reg = 0x21008,
+ .n_reg = 0x2100c,
+ .config_reg = 0x21010,
+ .mode_reg = 0x21000,
+ .status_reg = 0x2101c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll0",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll0_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll0_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll0.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll gpll1 = {
+ .l_reg = 0x20004,
+ .m_reg = 0x20008,
+ .n_reg = 0x2000c,
+ .config_reg = 0x20010,
+ .mode_reg = 0x20000,
+ .status_reg = 0x2001c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll1",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll1_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll1_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll1.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll gpll2 = {
+ .l_reg = 0x4a004,
+ .m_reg = 0x4a008,
+ .n_reg = 0x4a00c,
+ .config_reg = 0x4a010,
+ .mode_reg = 0x4a000,
+ .status_reg = 0x4a01c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll2",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll2_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll2_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll2.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll bimc_pll = {
+ .l_reg = 0x23004,
+ .m_reg = 0x23008,
+ .n_reg = 0x2300c,
+ .config_reg = 0x23010,
+ .mode_reg = 0x23000,
+ .status_reg = 0x2301c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "bimc_pll",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap bimc_pll_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(3),
+ .hw.init = &(struct clk_init_data){
+ .name = "bimc_pll_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &bimc_pll.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll gpll3 = {
+ .l_reg = 0x22004,
+ .m_reg = 0x22008,
+ .n_reg = 0x2200c,
+ .config_reg = 0x22010,
+ .mode_reg = 0x22000,
+ .status_reg = 0x2201c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll3",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll3_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll3_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll3.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+/* GPLL3 at 1100 MHz, main output enabled. */
+static const struct pll_config gpll3_config = {
+ .l = 57,
+ .m = 7,
+ .n = 24,
+ .vco_val = 0x0,
+ .vco_mask = BIT(20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BIT(12),
+ .post_div_val = 0x0,
+ .post_div_mask = BIT(9) | BIT(8),
+ .mn_ena_mask = BIT(24),
+ .main_output_mask = BIT(0),
+ .aux_output_mask = BIT(1),
+};
+
+static struct clk_pll gpll4 = {
+ .l_reg = 0x24004,
+ .m_reg = 0x24008,
+ .n_reg = 0x2400c,
+ .config_reg = 0x24010,
+ .mode_reg = 0x24000,
+ .status_reg = 0x2401c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll4",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll4_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(5),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll4_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll4.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+/* GPLL4 at 1200 MHz, main output enabled. */
+static struct pll_config gpll4_config = {
+ .l = 62,
+ .m = 1,
+ .n = 2,
+ .vco_val = 0x0,
+ .vco_mask = BIT(20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BIT(12),
+ .post_div_val = 0x0,
+ .post_div_mask = BIT(9) | BIT(8),
+ .mn_ena_mask = BIT(24),
+ .main_output_mask = BIT(0),
+};
+
+static struct clk_pll gpll5 = {
+ .l_reg = 0x25004,
+ .m_reg = 0x25008,
+ .n_reg = 0x2500c,
+ .config_reg = 0x25010,
+ .mode_reg = 0x25000,
+ .status_reg = 0x2501c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll5",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll5_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(6),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll5_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll5.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll gpll6 = {
+ .l_reg = 0x37004,
+ .m_reg = 0x37008,
+ .n_reg = 0x3700c,
+ .config_reg = 0x37010,
+ .mode_reg = 0x37000,
+ .status_reg = 0x3701c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll6",
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xo",
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll6_vote = {
+ .enable_reg = 0x45000,
+ .enable_mask = BIT(7),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll6_vote",
+ .parent_data = &(const struct clk_parent_data) {
+ .hw = &gpll6.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static const struct parent_map gcc_xo_gpll0_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_bimc_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_BIMC, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_bimc_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &bimc_pll_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll6a_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL6_AUX, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll6a_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll6_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll2a_gpll3_gpll6a_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL2_AUX, 4 },
+ { P_GPLL3, 2 },
+ { P_GPLL6_AUX, 3 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll2a_gpll3_gpll6a_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll2_vote.hw },
+ { .hw = &gpll3_vote.hw },
+ { .hw = &gpll6_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll2_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL2, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll2_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll2_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll2_gpll4_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL2, 3 },
+ { P_GPLL4, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll2_gpll4_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll2_vote.hw },
+ { .hw = &gpll4_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0a_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0_AUX, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0a_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll1a_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL1_AUX, 2 },
+ { P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll1_vote.hw },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll1a_gpll6_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL1_AUX, 2 },
+ { P_GPLL6, 2 },
+ { P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll1_vote.hw },
+ { .hw = &gpll6_vote.hw },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll1a_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL1_AUX, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll1_vote.hw },
+};
+
+static const struct parent_map gcc_xo_dsibyte_map[] = {
+ { P_XO, 0, },
+ { P_DSI0_PHYPLL_BYTE, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_dsibyte_parent_data[] = {
+ { .fw_name = "xo" },
+ { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
+};
+
+static const struct parent_map gcc_xo_gpll0a_dsibyte_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0_AUX, 2 },
+ { P_DSI0_PHYPLL_BYTE, 1 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0a_dsibyte_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
+};
+
+static const struct parent_map gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_DSI0_PHYPLL_DSI, 2 },
+ { P_GPLL6, 3 },
+ { P_GPLL3_AUX, 4 },
+ { P_GPLL0_AUX, 5 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll1_vote.hw },
+ { .fw_name = "dsi0pll", .name = "dsi0pll" },
+ { .hw = &gpll6_vote.hw },
+ { .hw = &gpll3_vote.hw },
+ { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0a_dsiphy_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0_AUX, 2 },
+ { P_DSI0_PHYPLL_DSI, 1 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0a_dsiphy_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .fw_name = "dsi0pll", .name = "dsi0pll" },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll5a_gpll6_bimc_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL5_AUX, 3 },
+ { P_GPLL6, 2 },
+ { P_BIMC, 4 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll5_vote.hw },
+ { .hw = &gpll6_vote.hw },
+ { .hw = &bimc_pll_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL1, 2 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll1_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .hw = &gpll1_vote.hw },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_EXT_PRI_I2S, 2 },
+ { P_EXT_MCLK, 3 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const struct clk_parent_data gcc_xo_gpll1_epi2s_emclk_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll0_vote.hw },
+ { .fw_name = "ext_pri_i2s", .name = "ext_pri_i2s" },
+ { .fw_name = "ext_mclk", .name = "ext_mclk" },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_EXT_SEC_I2S, 2 },
+ { P_EXT_MCLK, 3 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const struct clk_parent_data gcc_xo_gpll1_esi2s_emclk_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll1_vote.hw },
+ { .fw_name = "ext_sec_i2s", .name = "ext_sec_i2s" },
+ { .fw_name = "ext_mclk", .name = "ext_mclk" },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_sleep_map[] = {
+ { P_XO, 0 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const struct clk_parent_data gcc_xo_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
+ { P_XO, 0 },
+ { P_GPLL1, 1 },
+ { P_EXT_MCLK, 2 },
+ { P_SLEEP_CLK, 6 }
+};
+
+static const struct clk_parent_data gcc_xo_gpll1_emclk_sleep_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll1_vote.hw },
+ { .fw_name = "ext_mclk", .name = "ext_mclk" },
+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll6_gpll0_map[] = {
+ { P_XO, 0 },
+ { P_GPLL6, 1 },
+ { P_GPLL0, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll6_gpll0_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll6_vote.hw },
+ { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_xo_gpll6_gpll0a_map[] = {
+ { P_XO, 0 },
+ { P_GPLL6, 1 },
+ { P_GPLL0_AUX, 2 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll6_gpll0a_parent_data[] = {
+ { .fw_name = "xo" },
+ { .hw = &gpll6_vote.hw },
+ { .hw = &gpll0_vote.hw },
+};
+
+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
+ .cmd_rcgr = 0x27000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pcnoc_bfdcd_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 system_noc_bfdcd_clk_src = {
+ .cmd_rcgr = 0x26004,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll6a_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "system_noc_bfdcd_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll6a_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 bimc_ddr_clk_src = {
+ .cmd_rcgr = 0x32004,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_bimc_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "bimc_ddr_clk_src",
+ .parent_data = gcc_xo_gpll0_bimc_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ .flags = CLK_GET_RATE_NOCACHE,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_ahb_clk[] = {
+ F(40000000, P_GPLL0, 10, 1, 2),
+ F(80000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 camss_ahb_clk_src = {
+ .cmd_rcgr = 0x5a000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_camss_ahb_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "camss_ahb_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_apss_ahb_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(50000000, P_GPLL0, 16, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(133330000, P_GPLL0, 6, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 apss_ahb_clk_src = {
+ .cmd_rcgr = 0x46000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_apss_ahb_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "apss_ahb_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_csi0_1_clk[] = {
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+ .cmd_rcgr = 0x4e020,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_camss_csi0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi0_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+ .cmd_rcgr = 0x4f020,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_camss_csi0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi1_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_oxili_gfx3d_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(50000000, P_GPLL0, 16, 0, 0),
+ F(80000000, P_GPLL0, 10, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ F(220000000, P_GPLL3, 5, 0, 0),
+ F(266670000, P_GPLL0, 3, 0, 0),
+ F(310000000, P_GPLL2_AUX, 3, 0, 0),
+ F(400000000, P_GPLL0, 2, 0, 0),
+ F(465000000, P_GPLL2_AUX, 2, 0, 0),
+ F(550000000, P_GPLL3, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gfx3d_clk_src = {
+ .cmd_rcgr = 0x59000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll2a_gpll3_gpll6a_map,
+ .freq_tbl = ftbl_gcc_oxili_gfx3d_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gfx3d_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll2a_gpll3_gpll6a_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_vfe0_clk[] = {
+ F(50000000, P_GPLL0, 16, 0, 0),
+ F(80000000, P_GPLL0, 10, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(177780000, P_GPLL0, 4.5, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ F(266670000, P_GPLL0, 3, 0, 0),
+ F(320000000, P_GPLL0, 2.5, 0, 0),
+ F(400000000, P_GPLL0, 2, 0, 0),
+ F(465000000, P_GPLL2, 2, 0, 0),
+ F(480000000, P_GPLL4, 2.5, 0, 0),
+ F(600000000, P_GPLL4, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+ .cmd_rcgr = 0x58000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll2_gpll4_map,
+ .freq_tbl = ftbl_gcc_camss_vfe0_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vfe0_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll2_gpll4_parent_data,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(50000000, P_GPLL0, 16, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0200c,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup1_i2c_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
+ F(960000, P_XO, 10, 1, 2),
+ F(4800000, P_XO, 4, 0, 0),
+ F(9600000, P_XO, 2, 0, 0),
+ F(16000000, P_GPLL0, 10, 1, 5),
+ F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_GPLL0, 16, 1, 2),
+ F(50000000, P_GPLL0, 16, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+ .cmd_rcgr = 0x02024,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup1_spi_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x03000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup2_i2c_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+ .cmd_rcgr = 0x03014,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup2_spi_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x04000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup3_i2c_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+ .cmd_rcgr = 0x04024,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup3_spi_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x05000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup4_i2c_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+ .cmd_rcgr = 0x05024,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup4_spi_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x06000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup5_i2c_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+ .cmd_rcgr = 0x06024,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup5_spi_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x07000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup6_i2c_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+ .cmd_rcgr = 0x07024,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup6_spi_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+ F(3686400, P_GPLL0, 1, 72, 15625),
+ F(7372800, P_GPLL0, 1, 144, 15625),
+ F(14745600, P_GPLL0, 1, 288, 15625),
+ F(16000000, P_GPLL0, 10, 1, 5),
+ F(19200000, P_XO, 1, 0, 0),
+ F(24000000, P_GPLL0, 1, 3, 100),
+ F(25000000, P_GPLL0, 16, 1, 2),
+ F(32000000, P_GPLL0, 1, 1, 25),
+ F(40000000, P_GPLL0, 1, 1, 20),
+ F(46400000, P_GPLL0, 1, 29, 500),
+ F(48000000, P_GPLL0, 1, 3, 50),
+ F(51200000, P_GPLL0, 1, 8, 125),
+ F(56000000, P_GPLL0, 1, 7, 100),
+ F(58982400, P_GPLL0, 1, 1152, 15625),
+ F(60000000, P_GPLL0, 1, 3, 40),
+ { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+ .cmd_rcgr = 0x02044,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart1_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+ .cmd_rcgr = 0x03034,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart2_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 cci_clk_src = {
+ .cmd_rcgr = 0x51000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0a_map,
+ .freq_tbl = ftbl_gcc_camss_cci_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "cci_clk_src",
+ .parent_data = gcc_xo_gpll0a_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_gp0_1_clk[] = {
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 camss_gp0_clk_src = {
+ .cmd_rcgr = 0x54000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
+ .freq_tbl = ftbl_gcc_camss_gp0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "camss_gp0_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 camss_gp1_clk_src = {
+ .cmd_rcgr = 0x55000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
+ .freq_tbl = ftbl_gcc_camss_gp0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "camss_gp1_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_jpeg0_clk[] = {
+ F(133330000, P_GPLL0, 6, 0, 0),
+ F(266670000, P_GPLL0, 3, 0, 0),
+ F(320000000, P_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 jpeg0_clk_src = {
+ .cmd_rcgr = 0x57000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_camss_jpeg0_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "jpeg0_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_mclk0_1_clk[] = {
+ F(24000000, P_GPLL0, 1, 1, 45),
+ F(66670000, P_GPLL0, 12, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+ .cmd_rcgr = 0x52000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_gpll6_sleep_map,
+ .freq_tbl = ftbl_gcc_camss_mclk0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mclk0_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+ .cmd_rcgr = 0x53000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_gpll6_sleep_map,
+ .freq_tbl = ftbl_gcc_camss_mclk0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mclk1_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_csi0_1phytimer_clk[] = {
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+ .cmd_rcgr = 0x4e000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_map,
+ .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi0phytimer_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi1phytimer_clk_src = {
+ .cmd_rcgr = 0x4f000,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_map,
+ .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi1phytimer_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_cpp_clk[] = {
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(320000000, P_GPLL0, 2.5, 0, 0),
+ F(465000000, P_GPLL2, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 cpp_clk_src = {
+ .cmd_rcgr = 0x58018,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll2_map,
+ .freq_tbl = ftbl_gcc_camss_cpp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "cpp_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll2_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_crypto_clk[] = {
+ F(50000000, P_GPLL0, 16, 0, 0),
+ F(80000000, P_GPLL0, 10, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(160000000, P_GPLL0, 5, 0, 0),
+ { }
+};
+
+/* This is not in the documentation but is in the downstream driver */
+static struct clk_rcg2 crypto_clk_src = {
+ .cmd_rcgr = 0x16004,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_crypto_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "crypto_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_3_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+ .cmd_rcgr = 0x08004,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
+ .freq_tbl = ftbl_gcc_gp1_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gp1_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+ .cmd_rcgr = 0x09004,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
+ .freq_tbl = ftbl_gcc_gp1_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gp2_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+ .cmd_rcgr = 0x0a004,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
+ .freq_tbl = ftbl_gcc_gp1_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gp3_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+ .cmd_rcgr = 0x4d044,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0a_dsibyte_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "byte0_clk_src",
+ .parent_data = gcc_xo_gpll0a_dsibyte_parent_data,
+ .num_parents = 3,
+ .ops = &clk_byte2_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_rcg2 byte1_clk_src = {
+ .cmd_rcgr = 0x4d0b0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0a_dsibyte_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "byte1_clk_src",
+ .parent_data = gcc_xo_gpll0a_dsibyte_parent_data,
+ .num_parents = 3,
+ .ops = &clk_byte2_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_mdss_esc_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+ .cmd_rcgr = 0x4d060,
+ .hid_width = 5,
+ .parent_map = gcc_xo_dsibyte_map,
+ .freq_tbl = ftbl_gcc_mdss_esc_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "esc0_clk_src",
+ .parent_data = gcc_xo_dsibyte_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 esc1_clk_src = {
+ .cmd_rcgr = 0x4d0a8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_dsibyte_map,
+ .freq_tbl = ftbl_gcc_mdss_esc_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "esc1_clk_src",
+ .parent_data = gcc_xo_dsibyte_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_mdss_mdp_clk[] = {
+ F(50000000, P_GPLL0_AUX, 16, 0, 0),
+ F(80000000, P_GPLL0_AUX, 10, 0, 0),
+ F(100000000, P_GPLL0_AUX, 8, 0, 0),
+ F(160000000, P_GPLL0_AUX, 5, 0, 0),
+ F(177780000, P_GPLL0_AUX, 4.5, 0, 0),
+ F(200000000, P_GPLL0_AUX, 4, 0, 0),
+ F(266670000, P_GPLL0_AUX, 3, 0, 0),
+ F(307200000, P_GPLL1, 2, 0, 0),
+ F(366670000, P_GPLL3_AUX, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+ .cmd_rcgr = 0x4d014,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_map,
+ .freq_tbl = ftbl_gcc_mdss_mdp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mdp_clk_src",
+ .parent_data = gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_parent_data,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+ .cmd_rcgr = 0x4d000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0a_dsiphy_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pclk0_clk_src",
+ .parent_data = gcc_xo_gpll0a_dsiphy_parent_data,
+ .num_parents = 3,
+ .ops = &clk_pixel_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_rcg2 pclk1_clk_src = {
+ .cmd_rcgr = 0x4d0b8,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0a_dsiphy_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pclk1_clk_src",
+ .parent_data = gcc_xo_gpll0a_dsiphy_parent_data,
+ .num_parents = 3,
+ .ops = &clk_pixel_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_mdss_vsync_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+ .cmd_rcgr = 0x4d02c,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0a_map,
+ .freq_tbl = ftbl_gcc_mdss_vsync_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vsync_clk_src",
+ .parent_data = gcc_xo_gpll0a_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk[] = {
+ F(64000000, P_GPLL0, 12.5, 0, 0),
+ { }
+};
+
+/* This is not in the documentation but is in the downstream driver */
+static struct clk_rcg2 pdm2_clk_src = {
+ .cmd_rcgr = 0x44010,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_pdm2_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pdm2_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc_apps_clk[] = {
+ F(144000, P_XO, 16, 3, 25),
+ F(400000, P_XO, 12, 1, 4),
+ F(20000000, P_GPLL0, 10, 1, 4),
+ F(25000000, P_GPLL0, 16, 1, 2),
+ F(50000000, P_GPLL0, 16, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(177770000, P_GPLL0, 4.5, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+ .cmd_rcgr = 0x42004,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sdcc_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sdcc1_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_floor_ops,
+ },
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+ .cmd_rcgr = 0x43004,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sdcc_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sdcc2_apps_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_floor_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_apss_tcu_clk[] = {
+ F(154285000, P_GPLL6, 7, 0, 0),
+ F(320000000, P_GPLL0, 2.5, 0, 0),
+ F(400000000, P_GPLL0, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 apss_tcu_clk_src = {
+ .cmd_rcgr = 0x1207c,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll5a_gpll6_bimc_map,
+ .freq_tbl = ftbl_gcc_apss_tcu_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "apss_tcu_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_bimc_gpu_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ F(266500000, P_BIMC, 4, 0, 0),
+ F(400000000, P_GPLL0, 2, 0, 0),
+ F(533000000, P_BIMC, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 bimc_gpu_clk_src = {
+ .cmd_rcgr = 0x31028,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll5a_gpll6_bimc_map,
+ .freq_tbl = ftbl_gcc_bimc_gpu_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "bimc_gpu_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data,
+ .num_parents = 5,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+ F(80000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hs_system_clk_src = {
+ .cmd_rcgr = 0x41010,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hs_system_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_fs_system_clk[] = {
+ F(64000000, P_GPLL0, 12.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_fs_system_clk_src = {
+ .cmd_rcgr = 0x3f010,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_fs_system_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_fs_system_clk_src",
+ .parent_data = gcc_xo_gpll6_gpll0_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_fs_ic_clk[] = {
+ F(60000000, P_GPLL6, 1, 1, 18),
+ { }
+};
+
+static struct clk_rcg2 usb_fs_ic_clk_src = {
+ .cmd_rcgr = 0x3f034,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_fs_ic_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_fs_ic_clk_src",
+ .parent_data = gcc_xo_gpll6_gpll0a_parent_data,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_ahb_clk[] = {
+ F(3200000, P_XO, 6, 0, 0),
+ F(6400000, P_XO, 3, 0, 0),
+ F(9600000, P_XO, 2, 0, 0),
+ F(19200000, P_XO, 1, 0, 0),
+ F(40000000, P_GPLL0, 10, 1, 2),
+ F(66670000, P_GPLL0, 12, 0, 0),
+ F(80000000, P_GPLL0, 10, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
+ .cmd_rcgr = 0x1c010,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll0_gpll1_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_ahb_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_ahbfabric_clk_src",
+ .parent_data = gcc_xo_gpll0_gpll1_sleep_parent_data,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
+ .halt_reg = 0x1c028,
+ .clkr = {
+ .enable_reg = 0x1c028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_ahbfabric_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
+ .halt_reg = 0x1c024,
+ .clkr = {
+ .enable_reg = 0x1c024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_ahbfabric_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_lpaif_i2s_clk[] = {
+ F(128000, P_XO, 10, 1, 15),
+ F(256000, P_XO, 5, 1, 15),
+ F(384000, P_XO, 5, 1, 10),
+ F(512000, P_XO, 5, 2, 15),
+ F(576000, P_XO, 5, 3, 20),
+ F(705600, P_GPLL1, 16, 1, 80),
+ F(768000, P_XO, 5, 1, 5),
+ F(800000, P_XO, 5, 5, 24),
+ F(1024000, P_XO, 5, 4, 15),
+ F(1152000, P_XO, 1, 3, 50),
+ F(1411200, P_GPLL1, 16, 1, 40),
+ F(1536000, P_XO, 1, 2, 25),
+ F(1600000, P_XO, 12, 0, 0),
+ F(1728000, P_XO, 5, 9, 20),
+ F(2048000, P_XO, 5, 8, 15),
+ F(2304000, P_XO, 5, 3, 5),
+ F(2400000, P_XO, 8, 0, 0),
+ F(2822400, P_GPLL1, 16, 1, 20),
+ F(3072000, P_XO, 5, 4, 5),
+ F(4096000, P_GPLL1, 9, 2, 49),
+ F(4800000, P_XO, 4, 0, 0),
+ F(5644800, P_GPLL1, 16, 1, 10),
+ F(6144000, P_GPLL1, 7, 1, 21),
+ F(8192000, P_GPLL1, 9, 4, 49),
+ F(9600000, P_XO, 2, 0, 0),
+ F(11289600, P_GPLL1, 16, 1, 5),
+ F(12288000, P_GPLL1, 7, 2, 21),
+ { }
+};
+
+static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
+ .cmd_rcgr = 0x1c054,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll1_epi2s_emclk_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_lpaif_pri_i2s_clk_src",
+ .parent_data = gcc_xo_gpll1_epi2s_emclk_sleep_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
+ .halt_reg = 0x1c068,
+ .clkr = {
+ .enable_reg = 0x1c068,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_lpaif_pri_i2s_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
+ .cmd_rcgr = 0x1c06c,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll1_esi2s_emclk_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_lpaif_sec_i2s_clk_src",
+ .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
+ .halt_reg = 0x1c080,
+ .clkr = {
+ .enable_reg = 0x1c080,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_lpaif_sec_i2s_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
+ .cmd_rcgr = 0x1c084,
+ .hid_width = 5,
+ .mnd_width = 8,
+ .parent_map = gcc_xo_gpll1_emclk_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_lpaif_aux_i2s_clk_src",
+ .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep_parent_data,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
+ .halt_reg = 0x1c098,
+ .clkr = {
+ .enable_reg = 0x1c098,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_lpaif_aux_i2s_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_xo_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ultaudio_xo_clk_src = {
+ .cmd_rcgr = 0x1c034,
+ .hid_width = 5,
+ .parent_map = gcc_xo_sleep_map,
+ .freq_tbl = ftbl_gcc_ultaudio_xo_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ultaudio_xo_clk_src",
+ .parent_data = gcc_xo_sleep_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
+ .halt_reg = 0x1c04c,
+ .clkr = {
+ .enable_reg = 0x1c04c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_avsync_xo_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_xo_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_stc_xo_clk = {
+ .halt_reg = 0x1c050,
+ .clkr = {
+ .enable_reg = 0x1c050,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_stc_xo_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &ultaudio_xo_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_codec_clk[] = {
+ F(9600000, P_XO, 2, 0, 0),
+ F(12288000, P_XO, 1, 16, 25),
+ F(19200000, P_XO, 1, 0, 0),
+ F(11289600, P_EXT_MCLK, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 codec_digcodec_clk_src = {
+ .cmd_rcgr = 0x1c09c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll1_emclk_sleep_map,
+ .freq_tbl = ftbl_codec_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "codec_digcodec_clk_src",
+ .parent_data = gcc_xo_gpll1_emclk_sleep_parent_data,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_codec_digcodec_clk = {
+ .halt_reg = 0x1c0b0,
+ .clkr = {
+ .enable_reg = 0x1c0b0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_codec_digcodec_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &codec_digcodec_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
+ .halt_reg = 0x1c000,
+ .clkr = {
+ .enable_reg = 0x1c000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_pcnoc_mport_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
+ .halt_reg = 0x1c004,
+ .clkr = {
+ .enable_reg = 0x1c004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ultaudio_pcnoc_sway_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = {
+ F(100000000, P_GPLL0, 8, 0, 0),
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(228570000, P_GPLL0, 3.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vcodec0_clk_src = {
+ .cmd_rcgr = 0x4C000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_venus0_vcodec0_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vcodec0_clk_src",
+ .parent_data = gcc_xo_gpll0_parent_data,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+ .halt_reg = 0x01008,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x45004,
+ .enable_mask = BIT(10),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_sleep_clk = {
+ .halt_reg = 0x01004,
+ .clkr = {
+ .enable_reg = 0x01004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_sleep_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+ .halt_reg = 0x02008,
+ .clkr = {
+ .enable_reg = 0x02008,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup1_i2c_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+ .halt_reg = 0x02004,
+ .clkr = {
+ .enable_reg = 0x02004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup1_spi_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup1_spi_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+ .halt_reg = 0x03010,
+ .clkr = {
+ .enable_reg = 0x03010,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup2_i2c_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+ .halt_reg = 0x0300c,
+ .clkr = {
+ .enable_reg = 0x0300c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup2_spi_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup2_spi_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+ .halt_reg = 0x04020,
+ .clkr = {
+ .enable_reg = 0x04020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup3_i2c_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+ .halt_reg = 0x0401c,
+ .clkr = {
+ .enable_reg = 0x0401c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup3_spi_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup3_spi_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+ .halt_reg = 0x05020,
+ .clkr = {
+ .enable_reg = 0x05020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup4_i2c_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+ .halt_reg = 0x0501c,
+ .clkr = {
+ .enable_reg = 0x0501c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup4_spi_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup4_spi_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+ .halt_reg = 0x06020,
+ .clkr = {
+ .enable_reg = 0x06020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup5_i2c_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+ .halt_reg = 0x0601c,
+ .clkr = {
+ .enable_reg = 0x0601c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup5_spi_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup5_spi_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
+ .halt_reg = 0x07020,
+ .clkr = {
+ .enable_reg = 0x07020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup6_i2c_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+ .halt_reg = 0x0701c,
+ .clkr = {
+ .enable_reg = 0x0701c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup6_spi_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_qup6_spi_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+ .halt_reg = 0x0203c,
+ .clkr = {
+ .enable_reg = 0x0203c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart1_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_uart1_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+ .halt_reg = 0x0302c,
+ .clkr = {
+ .enable_reg = 0x0302c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart2_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &blsp1_uart2_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+ .halt_reg = 0x1300c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x45004,
+ .enable_mask = BIT(7),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_boot_rom_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_cci_ahb_clk = {
+ .halt_reg = 0x5101c,
+ .clkr = {
+ .enable_reg = 0x5101c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_cci_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_cci_clk = {
+ .halt_reg = 0x51018,
+ .clkr = {
+ .enable_reg = 0x51018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_cci_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &cci_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi0_ahb_clk = {
+ .halt_reg = 0x4e040,
+ .clkr = {
+ .enable_reg = 0x4e040,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi0_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi0_clk = {
+ .halt_reg = 0x4e03c,
+ .clkr = {
+ .enable_reg = 0x4e03c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi0phy_clk = {
+ .halt_reg = 0x4e048,
+ .clkr = {
+ .enable_reg = 0x4e048,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi0phy_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi0pix_clk = {
+ .halt_reg = 0x4e058,
+ .clkr = {
+ .enable_reg = 0x4e058,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi0pix_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi0rdi_clk = {
+ .halt_reg = 0x4e050,
+ .clkr = {
+ .enable_reg = 0x4e050,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi0rdi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi1_ahb_clk = {
+ .halt_reg = 0x4f040,
+ .clkr = {
+ .enable_reg = 0x4f040,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi1_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi1_clk = {
+ .halt_reg = 0x4f03c,
+ .clkr = {
+ .enable_reg = 0x4f03c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi1phy_clk = {
+ .halt_reg = 0x4f048,
+ .clkr = {
+ .enable_reg = 0x4f048,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi1phy_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi1pix_clk = {
+ .halt_reg = 0x4f058,
+ .clkr = {
+ .enable_reg = 0x4f058,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi1pix_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi1rdi_clk = {
+ .halt_reg = 0x4f050,
+ .clkr = {
+ .enable_reg = 0x4f050,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi1rdi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi_vfe0_clk = {
+ .halt_reg = 0x58050,
+ .clkr = {
+ .enable_reg = 0x58050,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi_vfe0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &vfe0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_gp0_clk = {
+ .halt_reg = 0x54018,
+ .clkr = {
+ .enable_reg = 0x54018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_gp0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_gp0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_gp1_clk = {
+ .halt_reg = 0x55018,
+ .clkr = {
+ .enable_reg = 0x55018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_gp1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_gp1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_ispif_ahb_clk = {
+ .halt_reg = 0x50004,
+ .clkr = {
+ .enable_reg = 0x50004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_ispif_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_jpeg0_clk = {
+ .halt_reg = 0x57020,
+ .clkr = {
+ .enable_reg = 0x57020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_jpeg0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &jpeg0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_jpeg_ahb_clk = {
+ .halt_reg = 0x57024,
+ .clkr = {
+ .enable_reg = 0x57024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_jpeg_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_jpeg_axi_clk = {
+ .halt_reg = 0x57028,
+ .clkr = {
+ .enable_reg = 0x57028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_jpeg_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_mclk0_clk = {
+ .halt_reg = 0x52018,
+ .clkr = {
+ .enable_reg = 0x52018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_mclk0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &mclk0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_mclk1_clk = {
+ .halt_reg = 0x53018,
+ .clkr = {
+ .enable_reg = 0x53018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_mclk1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &mclk1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_micro_ahb_clk = {
+ .halt_reg = 0x5600c,
+ .clkr = {
+ .enable_reg = 0x5600c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_micro_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi0phytimer_clk = {
+ .halt_reg = 0x4e01c,
+ .clkr = {
+ .enable_reg = 0x4e01c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi0phytimer_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi0phytimer_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_csi1phytimer_clk = {
+ .halt_reg = 0x4f01c,
+ .clkr = {
+ .enable_reg = 0x4f01c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_csi1phytimer_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &csi1phytimer_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_ahb_clk = {
+ .halt_reg = 0x5a014,
+ .clkr = {
+ .enable_reg = 0x5a014,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_top_ahb_clk = {
+ .halt_reg = 0x56004,
+ .clkr = {
+ .enable_reg = 0x56004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_top_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_cpp_ahb_clk = {
+ .halt_reg = 0x58040,
+ .clkr = {
+ .enable_reg = 0x58040,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_cpp_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_cpp_clk = {
+ .halt_reg = 0x5803c,
+ .clkr = {
+ .enable_reg = 0x5803c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_cpp_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &cpp_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_vfe0_clk = {
+ .halt_reg = 0x58038,
+ .clkr = {
+ .enable_reg = 0x58038,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_vfe0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &vfe0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_vfe_ahb_clk = {
+ .halt_reg = 0x58044,
+ .clkr = {
+ .enable_reg = 0x58044,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_vfe_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &camss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_camss_vfe_axi_clk = {
+ .halt_reg = 0x58048,
+ .clkr = {
+ .enable_reg = 0x58048,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_vfe_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_crypto_ahb_clk = {
+ .halt_reg = 0x16024,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x45004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_crypto_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_crypto_axi_clk = {
+ .halt_reg = 0x16020,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x45004,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_crypto_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_crypto_clk = {
+ .halt_reg = 0x1601c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x45004,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_crypto_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &crypto_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_oxili_gmem_clk = {
+ .halt_reg = 0x59024,
+ .clkr = {
+ .enable_reg = 0x59024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_oxili_gmem_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gfx3d_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+ .halt_reg = 0x08000,
+ .clkr = {
+ .enable_reg = 0x08000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gp1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gp1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+ .halt_reg = 0x09000,
+ .clkr = {
+ .enable_reg = 0x09000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gp2_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gp2_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+ .halt_reg = 0x0a000,
+ .clkr = {
+ .enable_reg = 0x0a000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gp3_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gp3_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_ahb_clk = {
+ .halt_reg = 0x4d07c,
+ .clkr = {
+ .enable_reg = 0x4d07c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_axi_clk = {
+ .halt_reg = 0x4d080,
+ .clkr = {
+ .enable_reg = 0x4d080,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_byte0_clk = {
+ .halt_reg = 0x4d094,
+ .clkr = {
+ .enable_reg = 0x4d094,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_byte0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &byte0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_byte1_clk = {
+ .halt_reg = 0x4d0a0,
+ .clkr = {
+ .enable_reg = 0x4d0a0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_byte1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &byte1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_esc0_clk = {
+ .halt_reg = 0x4d098,
+ .clkr = {
+ .enable_reg = 0x4d098,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_esc0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &esc0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_esc1_clk = {
+ .halt_reg = 0x4d09c,
+ .clkr = {
+ .enable_reg = 0x4d09c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_esc1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &esc1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_mdp_clk = {
+ .halt_reg = 0x4D088,
+ .clkr = {
+ .enable_reg = 0x4D088,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_mdp_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &mdp_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_pclk0_clk = {
+ .halt_reg = 0x4d084,
+ .clkr = {
+ .enable_reg = 0x4d084,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_pclk0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pclk0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_pclk1_clk = {
+ .halt_reg = 0x4d0a4,
+ .clkr = {
+ .enable_reg = 0x4d0a4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_pclk1_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pclk1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdss_vsync_clk = {
+ .halt_reg = 0x4d090,
+ .clkr = {
+ .enable_reg = 0x4d090,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_vsync_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &vsync_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+ .halt_reg = 0x49000,
+ .clkr = {
+ .enable_reg = 0x49000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_cfg_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+ .halt_reg = 0x49004,
+ .clkr = {
+ .enable_reg = 0x49004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_q6_bimc_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &bimc_ddr_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_oxili_ahb_clk = {
+ .halt_reg = 0x59028,
+ .clkr = {
+ .enable_reg = 0x59028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_oxili_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_oxili_gfx3d_clk = {
+ .halt_reg = 0x59020,
+ .clkr = {
+ .enable_reg = 0x59020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_oxili_gfx3d_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &gfx3d_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+ .halt_reg = 0x4400c,
+ .clkr = {
+ .enable_reg = 0x4400c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pdm2_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pdm2_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+ .halt_reg = 0x44004,
+ .clkr = {
+ .enable_reg = 0x44004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pdm_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+ .halt_reg = 0x13004,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x45004,
+ .enable_mask = BIT(8),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_prng_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+ .halt_reg = 0x4201c,
+ .clkr = {
+ .enable_reg = 0x4201c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+ .halt_reg = 0x42018,
+ .clkr = {
+ .enable_reg = 0x42018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &sdcc1_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+ .halt_reg = 0x4301c,
+ .clkr = {
+ .enable_reg = 0x4301c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc2_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+ .halt_reg = 0x43018,
+ .clkr = {
+ .enable_reg = 0x43018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc2_apps_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &sdcc2_apps_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_apss_tcu_clk = {
+ .halt_reg = 0x12018,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_apss_tcu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &bimc_ddr_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gfx_tcu_clk = {
+ .halt_reg = 0x12020,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gfx_tcu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &bimc_ddr_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gfx_tbu_clk = {
+ .halt_reg = 0x12010,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(3),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gfx_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &bimc_ddr_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdp_tbu_clk = {
+ .halt_reg = 0x1201c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdp_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_venus_tbu_clk = {
+ .halt_reg = 0x12014,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(5),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_vfe_tbu_clk = {
+ .halt_reg = 0x1203c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vfe_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_jpeg_tbu_clk = {
+ .halt_reg = 0x12034,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(10),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_jpeg_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_smmu_cfg_clk = {
+ .halt_reg = 0x12038,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(12),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_smmu_cfg_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gtcu_ahb_clk = {
+ .halt_reg = 0x12044,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(13),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gtcu_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_cpp_tbu_clk = {
+ .halt_reg = 0x12040,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(14),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_cpp_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mdp_rt_tbu_clk = {
+ .halt_reg = 0x1201c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x4500c,
+ .enable_mask = BIT(15),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdp_rt_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_bimc_gfx_clk = {
+ .halt_reg = 0x31024,
+ .clkr = {
+ .enable_reg = 0x31024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_bimc_gfx_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &bimc_gpu_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_bimc_gpu_clk = {
+ .halt_reg = 0x31040,
+ .clkr = {
+ .enable_reg = 0x31040,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_bimc_gpu_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &bimc_gpu_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb2a_phy_sleep_clk = {
+ .halt_reg = 0x4102c,
+ .clkr = {
+ .enable_reg = 0x4102c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb2a_phy_sleep_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_fs_ahb_clk = {
+ .halt_reg = 0x3f008,
+ .clkr = {
+ .enable_reg = 0x3f008,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_fs_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_fs_ic_clk = {
+ .halt_reg = 0x3f030,
+ .clkr = {
+ .enable_reg = 0x3f030,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_fs_ic_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &usb_fs_ic_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_fs_system_clk = {
+ .halt_reg = 0x3f004,
+ .clkr = {
+ .enable_reg = 0x3f004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_fs_system_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &usb_fs_system_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_ahb_clk = {
+ .halt_reg = 0x41008,
+ .clkr = {
+ .enable_reg = 0x41008,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hs_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_system_clk = {
+ .halt_reg = 0x41004,
+ .clkr = {
+ .enable_reg = 0x41004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hs_system_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &usb_hs_system_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_venus0_ahb_clk = {
+ .halt_reg = 0x4c020,
+ .clkr = {
+ .enable_reg = 0x4c020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus0_ahb_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_venus0_axi_clk = {
+ .halt_reg = 0x4c024,
+ .clkr = {
+ .enable_reg = 0x4c024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus0_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_venus0_vcodec0_clk = {
+ .halt_reg = 0x4c01c,
+ .clkr = {
+ .enable_reg = 0x4c01c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus0_vcodec0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &vcodec0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
+ .halt_reg = 0x4c02c,
+ .clkr = {
+ .enable_reg = 0x4c02c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus0_core0_vcodec0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &vcodec0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_venus0_core1_vcodec0_clk = {
+ .halt_reg = 0x4c034,
+ .clkr = {
+ .enable_reg = 0x4c034,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus0_core1_vcodec0_clk",
+ .parent_data = &(const struct clk_parent_data){
+ .hw = &vcodec0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_oxili_timer_clk = {
+ .halt_reg = 0x59040,
+ .clkr = {
+ .enable_reg = 0x59040,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_oxili_timer_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct gdsc venus_gdsc = {
+ .gdscr = 0x4c018,
+ .pd = {
+ .name = "venus",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+ .gdscr = 0x4d078,
+ .pd = {
+ .name = "mdss",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+ .gdscr = 0x5701c,
+ .pd = {
+ .name = "jpeg",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe_gdsc = {
+ .gdscr = 0x58034,
+ .pd = {
+ .name = "vfe",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+ .gdscr = 0x5901c,
+ .pd = {
+ .name = "oxili",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core0_gdsc = {
+ .gdscr = 0x4c028,
+ .pd = {
+ .name = "venus_core0",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core1_gdsc = {
+ .gdscr = 0x4c030,
+ .pd = {
+ .name = "venus_core1",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *gcc_msm8939_clocks[] = {
+ [GPLL0] = &gpll0.clkr,
+ [GPLL0_VOTE] = &gpll0_vote,
+ [BIMC_PLL] = &bimc_pll.clkr,
+ [BIMC_PLL_VOTE] = &bimc_pll_vote,
+ [GPLL1] = &gpll1.clkr,
+ [GPLL1_VOTE] = &gpll1_vote,
+ [GPLL2] = &gpll2.clkr,
+ [GPLL2_VOTE] = &gpll2_vote,
+ [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
+ [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr,
+ [CAMSS_AHB_CLK_SRC] = &camss_ahb_clk_src.clkr,
+ [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+ [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+ [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+ [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
+ [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+ [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+ [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+ [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+ [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+ [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
+ [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
+ [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+ [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+ [CCI_CLK_SRC] = &cci_clk_src.clkr,
+ [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr,
+ [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr,
+ [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
+ [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+ [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+ [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+ [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
+ [CPP_CLK_SRC] = &cpp_clk_src.clkr,
+ [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr,
+ [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+ [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+ [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+ [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+ [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+ [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+ [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+ [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+ [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+ [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+ [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+ [APSS_TCU_CLK_SRC] = &apss_tcu_clk_src.clkr,
+ [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
+ [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr,
+ [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+ [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr,
+ [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
+ [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+ [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+ [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+ [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr,
+ [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr,
+ [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr,
+ [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr,
+ [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr,
+ [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr,
+ [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr,
+ [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr,
+ [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr,
+ [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr,
+ [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr,
+ [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr,
+ [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr,
+ [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr,
+ [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr,
+ [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr,
+ [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr,
+ [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr,
+ [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr,
+ [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
+ [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
+ [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr,
+ [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
+ [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr,
+ [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr,
+ [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
+ [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr,
+ [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr,
+ [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr,
+ [GCC_CAMSS_VFE_AHB_CLK] = &gcc_camss_vfe_ahb_clk.clkr,
+ [GCC_CAMSS_VFE_AXI_CLK] = &gcc_camss_vfe_axi_clk.clkr,
+ [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
+ [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
+ [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
+ [GCC_OXILI_GMEM_CLK] = &gcc_oxili_gmem_clk.clkr,
+ [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+ [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+ [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+ [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr,
+ [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr,
+ [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr,
+ [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr,
+ [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr,
+ [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr,
+ [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr,
+ [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+ [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr,
+ [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr,
+ [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+ [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+ [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+ [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+ [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+ [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+ [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+ [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr,
+ [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr,
+ [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr,
+ [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
+ [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr,
+ [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr,
+ [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr,
+ [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
+ [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
+ [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
+ [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
+ [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
+ [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr,
+ [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
+ [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
+ [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr,
+ [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+ [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
+ [ULTAUDIO_AHBFABRIC_CLK_SRC] = &ultaudio_ahbfabric_clk_src.clkr,
+ [ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC] = &ultaudio_lpaif_pri_i2s_clk_src.clkr,
+ [ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC] = &ultaudio_lpaif_sec_i2s_clk_src.clkr,
+ [ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC] = &ultaudio_lpaif_aux_i2s_clk_src.clkr,
+ [ULTAUDIO_XO_CLK_SRC] = &ultaudio_xo_clk_src.clkr,
+ [CODEC_DIGCODEC_CLK_SRC] = &codec_digcodec_clk_src.clkr,
+ [GCC_ULTAUDIO_PCNOC_MPORT_CLK] = &gcc_ultaudio_pcnoc_mport_clk.clkr,
+ [GCC_ULTAUDIO_PCNOC_SWAY_CLK] = &gcc_ultaudio_pcnoc_sway_clk.clkr,
+ [GCC_ULTAUDIO_AVSYNC_XO_CLK] = &gcc_ultaudio_avsync_xo_clk.clkr,
+ [GCC_ULTAUDIO_STC_XO_CLK] = &gcc_ultaudio_stc_xo_clk.clkr,
+ [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_clk.clkr,
+ [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_lpm_clk.clkr,
+ [GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK] = &gcc_ultaudio_lpaif_pri_i2s_clk.clkr,
+ [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
+ [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
+ [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
+ [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+ [GPLL3] = &gpll3.clkr,
+ [GPLL3_VOTE] = &gpll3_vote,
+ [GPLL4] = &gpll4.clkr,
+ [GPLL4_VOTE] = &gpll4_vote,
+ [GPLL5] = &gpll5.clkr,
+ [GPLL5_VOTE] = &gpll5_vote,
+ [GPLL6] = &gpll6.clkr,
+ [GPLL6_VOTE] = &gpll6_vote,
+ [BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
+ [GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr,
+ [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
+ [GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr,
+ [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
+ [GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr,
+ [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr,
+ [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr,
+ [GCC_MDP_RT_TBU_CLK] = &gcc_mdp_rt_tbu_clk.clkr,
+ [USB_FS_SYSTEM_CLK_SRC] = &usb_fs_system_clk_src.clkr,
+ [USB_FS_IC_CLK_SRC] = &usb_fs_ic_clk_src.clkr,
+ [GCC_USB_FS_AHB_CLK] = &gcc_usb_fs_ahb_clk.clkr,
+ [GCC_USB_FS_IC_CLK] = &gcc_usb_fs_ic_clk.clkr,
+ [GCC_USB_FS_SYSTEM_CLK] = &gcc_usb_fs_system_clk.clkr,
+ [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr,
+ [GCC_VENUS0_CORE1_VCODEC0_CLK] = &gcc_venus0_core1_vcodec0_clk.clkr,
+ [GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr,
+};
+
+static struct gdsc *gcc_msm8939_gdscs[] = {
+ [VENUS_GDSC] = &venus_gdsc,
+ [MDSS_GDSC] = &mdss_gdsc,
+ [JPEG_GDSC] = &jpeg_gdsc,
+ [VFE_GDSC] = &vfe_gdsc,
+ [OXILI_GDSC] = &oxili_gdsc,
+ [VENUS_CORE0_GDSC] = &venus_core0_gdsc,
+ [VENUS_CORE1_GDSC] = &venus_core1_gdsc,
+};
+
+static const struct qcom_reset_map gcc_msm8939_resets[] = {
+ [GCC_BLSP1_BCR] = { 0x01000 },
+ [GCC_BLSP1_QUP1_BCR] = { 0x02000 },
+ [GCC_BLSP1_UART1_BCR] = { 0x02038 },
+ [GCC_BLSP1_QUP2_BCR] = { 0x03008 },
+ [GCC_BLSP1_UART2_BCR] = { 0x03028 },
+ [GCC_BLSP1_QUP3_BCR] = { 0x04018 },
+ [GCC_BLSP1_UART3_BCR] = { 0x04038 },
+ [GCC_BLSP1_QUP4_BCR] = { 0x05018 },
+ [GCC_BLSP1_QUP5_BCR] = { 0x06018 },
+ [GCC_BLSP1_QUP6_BCR] = { 0x07018 },
+ [GCC_IMEM_BCR] = { 0x0e000 },
+ [GCC_SMMU_BCR] = { 0x12000 },
+ [GCC_APSS_TCU_BCR] = { 0x12050 },
+ [GCC_SMMU_XPU_BCR] = { 0x12054 },
+ [GCC_PCNOC_TBU_BCR] = { 0x12058 },
+ [GCC_PRNG_BCR] = { 0x13000 },
+ [GCC_BOOT_ROM_BCR] = { 0x13008 },
+ [GCC_CRYPTO_BCR] = { 0x16000 },
+ [GCC_SEC_CTRL_BCR] = { 0x1a000 },
+ [GCC_AUDIO_CORE_BCR] = { 0x1c008 },
+ [GCC_ULT_AUDIO_BCR] = { 0x1c0b4 },
+ [GCC_DEHR_BCR] = { 0x1f000 },
+ [GCC_SYSTEM_NOC_BCR] = { 0x26000 },
+ [GCC_PCNOC_BCR] = { 0x27018 },
+ [GCC_TCSR_BCR] = { 0x28000 },
+ [GCC_QDSS_BCR] = { 0x29000 },
+ [GCC_DCD_BCR] = { 0x2a000 },
+ [GCC_MSG_RAM_BCR] = { 0x2b000 },
+ [GCC_MPM_BCR] = { 0x2c000 },
+ [GCC_SPMI_BCR] = { 0x2e000 },
+ [GCC_SPDM_BCR] = { 0x2f000 },
+ [GCC_MM_SPDM_BCR] = { 0x2f024 },
+ [GCC_BIMC_BCR] = { 0x31000 },
+ [GCC_RBCPR_BCR] = { 0x33000 },
+ [GCC_TLMM_BCR] = { 0x34000 },
+ [GCC_CAMSS_CSI2_BCR] = { 0x3c038 },
+ [GCC_CAMSS_CSI2PHY_BCR] = { 0x3c044 },
+ [GCC_CAMSS_CSI2RDI_BCR] = { 0x3c04c },
+ [GCC_CAMSS_CSI2PIX_BCR] = { 0x3c054 },
+ [GCC_USB_FS_BCR] = { 0x3f000 },
+ [GCC_USB_HS_BCR] = { 0x41000 },
+ [GCC_USB2A_PHY_BCR] = { 0x41028 },
+ [GCC_SDCC1_BCR] = { 0x42000 },
+ [GCC_SDCC2_BCR] = { 0x43000 },
+ [GCC_PDM_BCR] = { 0x44000 },
+ [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x47000 },
+ [GCC_PCNOC_BUS_TIMEOUT0_BCR] = { 0x48000 },
+ [GCC_PCNOC_BUS_TIMEOUT1_BCR] = { 0x48008 },
+ [GCC_PCNOC_BUS_TIMEOUT2_BCR] = { 0x48010 },
+ [GCC_PCNOC_BUS_TIMEOUT3_BCR] = { 0x48018 },
+ [GCC_PCNOC_BUS_TIMEOUT4_BCR] = { 0x48020 },
+ [GCC_PCNOC_BUS_TIMEOUT5_BCR] = { 0x48028 },
+ [GCC_PCNOC_BUS_TIMEOUT6_BCR] = { 0x48030 },
+ [GCC_PCNOC_BUS_TIMEOUT7_BCR] = { 0x48038 },
+ [GCC_PCNOC_BUS_TIMEOUT8_BCR] = { 0x48040 },
+ [GCC_PCNOC_BUS_TIMEOUT9_BCR] = { 0x48048 },
+ [GCC_MMSS_BCR] = { 0x4b000 },
+ [GCC_VENUS0_BCR] = { 0x4c014 },
+ [GCC_MDSS_BCR] = { 0x4d074 },
+ [GCC_CAMSS_PHY0_BCR] = { 0x4e018 },
+ [GCC_CAMSS_CSI0_BCR] = { 0x4e038 },
+ [GCC_CAMSS_CSI0PHY_BCR] = { 0x4e044 },
+ [GCC_CAMSS_CSI0RDI_BCR] = { 0x4e04c },
+ [GCC_CAMSS_CSI0PIX_BCR] = { 0x4e054 },
+ [GCC_CAMSS_PHY1_BCR] = { 0x4f018 },
+ [GCC_CAMSS_CSI1_BCR] = { 0x4f038 },
+ [GCC_CAMSS_CSI1PHY_BCR] = { 0x4f044 },
+ [GCC_CAMSS_CSI1RDI_BCR] = { 0x4f04c },
+ [GCC_CAMSS_CSI1PIX_BCR] = { 0x4f054 },
+ [GCC_CAMSS_ISPIF_BCR] = { 0x50000 },
+ [GCC_BLSP1_QUP4_SPI_APPS_CBCR] = { 0x0501c },
+ [GCC_CAMSS_CCI_BCR] = { 0x51014 },
+ [GCC_CAMSS_MCLK0_BCR] = { 0x52014 },
+ [GCC_CAMSS_MCLK1_BCR] = { 0x53014 },
+ [GCC_CAMSS_GP0_BCR] = { 0x54014 },
+ [GCC_CAMSS_GP1_BCR] = { 0x55014 },
+ [GCC_CAMSS_TOP_BCR] = { 0x56000 },
+ [GCC_CAMSS_MICRO_BCR] = { 0x56008 },
+ [GCC_CAMSS_JPEG_BCR] = { 0x57018 },
+ [GCC_CAMSS_VFE_BCR] = { 0x58030 },
+ [GCC_CAMSS_CSI_VFE0_BCR] = { 0x5804c },
+ [GCC_OXILI_BCR] = { 0x59018 },
+ [GCC_GMEM_BCR] = { 0x5902c },
+ [GCC_CAMSS_AHB_BCR] = { 0x5a018 },
+ [GCC_CAMSS_MCLK2_BCR] = { 0x5c014 },
+ [GCC_MDP_TBU_BCR] = { 0x62000 },
+ [GCC_GFX_TBU_BCR] = { 0x63000 },
+ [GCC_GFX_TCU_BCR] = { 0x64000 },
+ [GCC_MSS_TBU_AXI_BCR] = { 0x65000 },
+ [GCC_MSS_TBU_GSS_AXI_BCR] = { 0x66000 },
+ [GCC_MSS_TBU_Q6_AXI_BCR] = { 0x67000 },
+ [GCC_GTCU_AHB_BCR] = { 0x68000 },
+ [GCC_SMMU_CFG_BCR] = { 0x69000 },
+ [GCC_VFE_TBU_BCR] = { 0x6a000 },
+ [GCC_VENUS_TBU_BCR] = { 0x6b000 },
+ [GCC_JPEG_TBU_BCR] = { 0x6c000 },
+ [GCC_PRONTO_TBU_BCR] = { 0x6d000 },
+ [GCC_CPP_TBU_BCR] = { 0x6e000 },
+ [GCC_MDP_RT_TBU_BCR] = { 0x6f000 },
+ [GCC_SMMU_CATS_BCR] = { 0x7c000 },
+};
+
+static const struct regmap_config gcc_msm8939_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x80000,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_msm8939_desc = {
+ .config = &gcc_msm8939_regmap_config,
+ .clks = gcc_msm8939_clocks,
+ .num_clks = ARRAY_SIZE(gcc_msm8939_clocks),
+ .resets = gcc_msm8939_resets,
+ .num_resets = ARRAY_SIZE(gcc_msm8939_resets),
+ .gdscs = gcc_msm8939_gdscs,
+ .num_gdscs = ARRAY_SIZE(gcc_msm8939_gdscs),
+};
+
+static const struct of_device_id gcc_msm8939_match_table[] = {
+ { .compatible = "qcom,gcc-msm8939" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gcc_msm8939_match_table);
+
+static int gcc_msm8939_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+
+ regmap = qcom_cc_map(pdev, &gcc_msm8939_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_pll_configure_sr_hpm_lp(&gpll3, regmap, &gpll3_config, true);
+ clk_pll_configure_sr_hpm_lp(&gpll4, regmap, &gpll4_config, true);
+
+ return qcom_cc_really_probe(pdev, &gcc_msm8939_desc, regmap);
+}
+
+static struct platform_driver gcc_msm8939_driver = {
+ .probe = gcc_msm8939_probe,
+ .driver = {
+ .name = "gcc-msm8939",
+ .of_match_table = gcc_msm8939_match_table,
+ },
+};
+
+static int __init gcc_msm8939_init(void)
+{
+ return platform_driver_register(&gcc_msm8939_driver);
+}
+core_initcall(gcc_msm8939_init);
+
+static void __exit gcc_msm8939_exit(void)
+{
+ platform_driver_unregister(&gcc_msm8939_driver);
+}
+module_exit(gcc_msm8939_exit);
+
+MODULE_DESCRIPTION("Qualcomm GCC MSM8939 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c
index df1d7056436c..9d7016bcd680 100644
--- a/drivers/clk/qcom/gcc-msm8998.c
+++ b/drivers/clk/qcom/gcc-msm8998.c
@@ -1110,6 +1110,27 @@ static struct clk_rcg2 ufs_axi_clk_src = {
},
};
+static const struct freq_tbl ftbl_ufs_unipro_core_clk_src[] = {
+ F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+ F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+ F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ufs_unipro_core_clk_src = {
+ .cmd_rcgr = 0x76028,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_parent_map_0,
+ .freq_tbl = ftbl_ufs_unipro_core_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ufs_unipro_core_clk_src",
+ .parent_names = gcc_parent_names_0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
@@ -2549,6 +2570,11 @@ static struct clk_branch gcc_ufs_unipro_core_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_unipro_core_clk",
+ .parent_names = (const char *[]){
+ "ufs_unipro_core_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2904,6 +2930,7 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
[SDCC4_APPS_CLK_SRC] = &sdcc4_apps_clk_src.clkr,
[TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr,
[UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
+ [UFS_UNIPRO_CORE_CLK_SRC] = &ufs_unipro_core_clk_src.clkr,
[USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
[USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
[USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c
index 6a51b5b5fc19..ca4383e3a02a 100644
--- a/drivers/clk/qcom/gcc-sc7180.c
+++ b/drivers/clk/qcom/gcc-sc7180.c
@@ -390,6 +390,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625),
F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75),
F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25),
+ F(51200000, P_GPLL6_OUT_MAIN, 7.5, 0, 0),
F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75),
F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15),
@@ -405,8 +406,8 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
.name = "gcc_qupv3_wrap0_s0_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -414,15 +415,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
.cmd_rcgr = 0x17034,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
.name = "gcc_qupv3_wrap0_s1_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -430,15 +431,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
.cmd_rcgr = 0x17164,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
.name = "gcc_qupv3_wrap0_s2_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -446,15 +447,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
.cmd_rcgr = 0x17294,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
.name = "gcc_qupv3_wrap0_s3_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -462,15 +463,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
.cmd_rcgr = 0x173c4,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
.name = "gcc_qupv3_wrap0_s4_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -478,15 +479,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
.cmd_rcgr = 0x174f4,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
.name = "gcc_qupv3_wrap0_s5_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -494,15 +495,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
.cmd_rcgr = 0x17624,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
.name = "gcc_qupv3_wrap1_s0_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -510,15 +511,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
.cmd_rcgr = 0x18018,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
.name = "gcc_qupv3_wrap1_s1_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -526,15 +527,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
.cmd_rcgr = 0x18148,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
.name = "gcc_qupv3_wrap1_s2_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -542,15 +543,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
.cmd_rcgr = 0x18278,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
.name = "gcc_qupv3_wrap1_s3_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -558,15 +559,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
.cmd_rcgr = 0x183a8,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
.name = "gcc_qupv3_wrap1_s4_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -574,15 +575,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
.cmd_rcgr = 0x184d8,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
.name = "gcc_qupv3_wrap1_s5_clk_src",
- .parent_data = gcc_parent_data_0,
- .num_parents = 4,
+ .parent_data = gcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
.ops = &clk_rcg2_ops,
};
@@ -590,7 +591,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
.cmd_rcgr = 0x18608,
.mnd_width = 16,
.hid_width = 5,
- .parent_map = gcc_parent_map_0,
+ .parent_map = gcc_parent_map_1,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
};
@@ -816,6 +817,26 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
},
};
+static const struct freq_tbl ftbl_gcc_sec_ctrl_clk_src[] = {
+ F(4800000, P_BI_TCXO, 4, 0, 0),
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gcc_sec_ctrl_clk_src = {
+ .cmd_rcgr = 0x3d030,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = gcc_parent_map_3,
+ .freq_tbl = ftbl_gcc_sec_ctrl_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gcc_sec_ctrl_clk_src",
+ .parent_data = gcc_parent_data_3,
+ .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
.halt_reg = 0x82024,
.halt_check = BRANCH_HALT_DELAY,
@@ -2406,6 +2427,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
[GCC_MSS_NAV_AXI_CLK] = &gcc_mss_nav_axi_clk.clkr,
[GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+ [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr,
};
static const struct qcom_reset_map gcc_sc7180_resets[] = {
diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c
index 732bc7c937e6..72524cf11048 100644
--- a/drivers/clk/qcom/gcc-sm8150.c
+++ b/drivers/clk/qcom/gcc-sm8150.c
@@ -1616,6 +1616,36 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = {
},
};
+static struct clk_branch gcc_gpu_gpll0_clk_src = {
+ .clkr = {
+ .enable_reg = 0x52004,
+ .enable_mask = BIT(15),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gpu_gpll0_clk_src",
+ .parent_hws = (const struct clk_hw *[]){
+ &gpll0.clkr.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+ .clkr = {
+ .enable_reg = 0x52004,
+ .enable_mask = BIT(16),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gpu_gpll0_div_clk_src",
+ .parent_hws = (const struct clk_hw *[]){
+ &gcc_gpu_gpll0_clk_src.clkr.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_gpu_iref_clk = {
.halt_reg = 0x8c010,
.halt_check = BRANCH_HALT,
@@ -1698,6 +1728,36 @@ static struct clk_branch gcc_npu_cfg_ahb_clk = {
},
};
+static struct clk_branch gcc_npu_gpll0_clk_src = {
+ .clkr = {
+ .enable_reg = 0x52004,
+ .enable_mask = BIT(18),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_npu_gpll0_clk_src",
+ .parent_hws = (const struct clk_hw *[]){
+ &gpll0.clkr.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_npu_gpll0_div_clk_src = {
+ .clkr = {
+ .enable_reg = 0x52004,
+ .enable_mask = BIT(19),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_npu_gpll0_div_clk_src",
+ .parent_hws = (const struct clk_hw *[]){
+ &gcc_npu_gpll0_clk_src.clkr.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_npu_trig_clk = {
.halt_reg = 0x4d00c,
.halt_check = BRANCH_VOTED,
@@ -2812,6 +2872,45 @@ static struct clk_branch gcc_ufs_card_phy_aux_hw_ctl_clk = {
},
};
+/* external clocks so add BRANCH_HALT_SKIP */
+static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
+ .halt_check = BRANCH_HALT_SKIP,
+ .clkr = {
+ .enable_reg = 0x7501c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_card_rx_symbol_0_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+/* external clocks so add BRANCH_HALT_SKIP */
+static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = {
+ .halt_check = BRANCH_HALT_SKIP,
+ .clkr = {
+ .enable_reg = 0x750ac,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_card_rx_symbol_1_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+/* external clocks so add BRANCH_HALT_SKIP */
+static struct clk_branch gcc_ufs_card_tx_symbol_0_clk = {
+ .halt_check = BRANCH_HALT_SKIP,
+ .clkr = {
+ .enable_reg = 0x75018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_card_tx_symbol_0_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_ufs_card_unipro_core_clk = {
.halt_reg = 0x75058,
.halt_check = BRANCH_HALT,
@@ -2992,6 +3091,45 @@ static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = {
},
};
+/* external clocks so add BRANCH_HALT_SKIP */
+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
+ .halt_check = BRANCH_HALT_SKIP,
+ .clkr = {
+ .enable_reg = 0x7701c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_phy_rx_symbol_0_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+/* external clocks so add BRANCH_HALT_SKIP */
+static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = {
+ .halt_check = BRANCH_HALT_SKIP,
+ .clkr = {
+ .enable_reg = 0x770ac,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_phy_rx_symbol_1_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+/* external clocks so add BRANCH_HALT_SKIP */
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+ .halt_check = BRANCH_HALT_SKIP,
+ .clkr = {
+ .enable_reg = 0x77018,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_phy_tx_symbol_0_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
.halt_reg = 0x77058,
.halt_check = BRANCH_HALT,
@@ -3374,12 +3512,16 @@ static struct clk_regmap *gcc_sm8150_clocks[] = {
[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
[GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
[GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+ [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+ [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
[GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
[GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
[GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
[GCC_NPU_AT_CLK] = &gcc_npu_at_clk.clkr,
[GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr,
[GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr,
+ [GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr,
+ [GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr,
[GCC_NPU_TRIG_CLK] = &gcc_npu_trig_clk.clkr,
[GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr,
[GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr,
@@ -3484,6 +3626,9 @@ static struct clk_regmap *gcc_sm8150_clocks[] = {
[GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr,
[GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK] =
&gcc_ufs_card_phy_aux_hw_ctl_clk.clkr,
+ [GCC_UFS_CARD_RX_SYMBOL_0_CLK] = &gcc_ufs_card_rx_symbol_0_clk.clkr,
+ [GCC_UFS_CARD_RX_SYMBOL_1_CLK] = &gcc_ufs_card_rx_symbol_1_clk.clkr,
+ [GCC_UFS_CARD_TX_SYMBOL_0_CLK] = &gcc_ufs_card_tx_symbol_0_clk.clkr,
[GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr,
[GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] =
&gcc_ufs_card_unipro_core_clk_src.clkr,
@@ -3501,6 +3646,9 @@ static struct clk_regmap *gcc_sm8150_clocks[] = {
[GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
[GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
[GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr,
+ [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+ [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
+ [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
[GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
[GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
&gcc_ufs_phy_unipro_core_clk_src.clkr,
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index a250f59708d8..04944f11659b 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -11,6 +11,7 @@
#include <linux/ktime.h>
#include <linux/pm_domain.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
#include "gdsc.h"
@@ -112,6 +113,12 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status)
int ret;
u32 val = (status == GDSC_ON) ? 0 : SW_COLLAPSE_MASK;
+ if (status == GDSC_ON && sc->rsupply) {
+ ret = regulator_enable(sc->rsupply);
+ if (ret < 0)
+ return ret;
+ }
+
ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
if (ret)
return ret;
@@ -143,6 +150,13 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status)
ret = gdsc_poll_status(sc, status);
WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n");
+
+ if (!ret && status == GDSC_OFF && sc->rsupply) {
+ ret = regulator_disable(sc->rsupply);
+ if (ret < 0)
+ return ret;
+ }
+
return ret;
}
@@ -371,6 +385,15 @@ int gdsc_register(struct gdsc_desc *desc,
if (!data->domains)
return -ENOMEM;
+ for (i = 0; i < num; i++) {
+ if (!scs[i] || !scs[i]->supply)
+ continue;
+
+ scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
+ if (IS_ERR(scs[i]->rsupply))
+ return PTR_ERR(scs[i]->rsupply);
+ }
+
data->num_domains = num;
for (i = 0; i < num; i++) {
if (!scs[i])
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 64cdc8cf0d4d..c36fc26dcdff 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -10,6 +10,7 @@
#include <linux/pm_domain.h>
struct regmap;
+struct regulator;
struct reset_controller_dev;
/**
@@ -52,6 +53,9 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;
+
+ const char *supply;
+ struct regulator *rsupply;
};
struct gdsc_desc {
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index 6c7592ddf8bb..3b3aac07fb2d 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -3064,7 +3064,9 @@ static struct gdsc gpu_gx_gdsc = {
.name = "gpu_gx",
},
.pwrsts = PWRSTS_OFF_ON,
+ .parent = &gpu_gdsc.pd,
.flags = CLAMP_IO,
+ .supply = "vdd-gfx",
};
static struct clk_regmap *mmcc_msm8996_clocks[] = {
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index ac2dd92ce2ef..9eb79bf90643 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -8,6 +8,7 @@ config CLK_RENESAS
select CLK_R7S9210 if ARCH_R7S9210
select CLK_R8A73A4 if ARCH_R8A73A4
select CLK_R8A7740 if ARCH_R8A7740
+ select CLK_R8A7742 if ARCH_R8A7742
select CLK_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744
select CLK_R8A7745 if ARCH_R8A7745
select CLK_R8A77470 if ARCH_R8A77470
@@ -55,6 +56,10 @@ config CLK_R8A7740
select CLK_RENESAS_CPG_MSTP
select CLK_RENESAS_DIV6
+config CLK_R8A7742
+ bool "RZ/G1H clock support" if COMPILE_TEST
+ select CLK_RCAR_GEN2_CPG
+
config CLK_R8A7743
bool "RZ/G1M clock support" if COMPILE_TEST
select CLK_RCAR_GEN2_CPG
@@ -90,12 +95,10 @@ config CLK_R8A7779
config CLK_R8A7790
bool "R-Car H2 clock support" if COMPILE_TEST
select CLK_RCAR_GEN2_CPG
- select CLK_RENESAS_DIV6
config CLK_R8A7791
bool "R-Car M2-W/N clock support" if COMPILE_TEST
select CLK_RCAR_GEN2_CPG
- select CLK_RENESAS_DIV6
config CLK_R8A7792
bool "R-Car V2H clock support" if COMPILE_TEST
@@ -104,7 +107,6 @@ config CLK_R8A7792
config CLK_R8A7794
bool "R-Car E2 clock support" if COMPILE_TEST
select CLK_RCAR_GEN2_CPG
- select CLK_RENESAS_DIV6
config CLK_R8A7795
bool "R-Car H3 clock support" if COMPILE_TEST
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index 4a722bc5aac7..a4066f9b34ef 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_CLK_RZA1) += clk-rz.o
obj-$(CONFIG_CLK_R7S9210) += r7s9210-cpg-mssr.o
obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o
obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o
+obj-$(CONFIG_CLK_R8A7742) += r8a7742-cpg-mssr.o
obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o
obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o
obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o
diff --git a/drivers/clk/renesas/r8a7742-cpg-mssr.c b/drivers/clk/renesas/r8a7742-cpg-mssr.c
new file mode 100644
index 000000000000..e919828668a4
--- /dev/null
+++ b/drivers/clk/renesas/r8a7742-cpg-mssr.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a7742 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a7742-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen2-cpg.h"
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R8A7742_CLK_OSC,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+ CLK_USB_EXTAL,
+
+ /* Internal Core Clocks */
+ CLK_MAIN,
+ CLK_PLL0,
+ CLK_PLL1,
+ CLK_PLL3,
+ CLK_PLL1_DIV2,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a7742_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+ DEF_INPUT("usb_extal", CLK_USB_EXTAL),
+
+ /* Internal Core Clocks */
+ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
+ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
+ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
+ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
+
+ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+
+ /* Core Clock Outputs */
+ DEF_BASE("z", R8A7742_CLK_Z, CLK_TYPE_GEN2_Z, CLK_PLL0),
+ DEF_BASE("lb", R8A7742_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1),
+ DEF_BASE("sdh", R8A7742_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1),
+ DEF_BASE("sd0", R8A7742_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1),
+ DEF_BASE("sd1", R8A7742_CLK_SD1, CLK_TYPE_GEN2_SD1, CLK_PLL1),
+ DEF_BASE("qspi", R8A7742_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2),
+ DEF_BASE("rcan", R8A7742_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL),
+
+ DEF_FIXED("z2", R8A7742_CLK_Z2, CLK_PLL1, 2, 1),
+ DEF_FIXED("zg", R8A7742_CLK_ZG, CLK_PLL1, 3, 1),
+ DEF_FIXED("zx", R8A7742_CLK_ZX, CLK_PLL1, 3, 1),
+ DEF_FIXED("zs", R8A7742_CLK_ZS, CLK_PLL1, 6, 1),
+ DEF_FIXED("hp", R8A7742_CLK_HP, CLK_PLL1, 12, 1),
+ DEF_FIXED("b", R8A7742_CLK_B, CLK_PLL1, 12, 1),
+ DEF_FIXED("p", R8A7742_CLK_P, CLK_PLL1, 24, 1),
+ DEF_FIXED("cl", R8A7742_CLK_CL, CLK_PLL1, 48, 1),
+ DEF_FIXED("m2", R8A7742_CLK_M2, CLK_PLL1, 8, 1),
+ DEF_FIXED("zb3", R8A7742_CLK_ZB3, CLK_PLL3, 4, 1),
+ DEF_FIXED("zb3d2", R8A7742_CLK_ZB3D2, CLK_PLL3, 8, 1),
+ DEF_FIXED("ddr", R8A7742_CLK_DDR, CLK_PLL3, 8, 1),
+ DEF_FIXED("mp", R8A7742_CLK_MP, CLK_PLL1_DIV2, 15, 1),
+ DEF_FIXED("cp", R8A7742_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("r", R8A7742_CLK_R, CLK_PLL1, 49152, 1),
+ DEF_FIXED("osc", R8A7742_CLK_OSC, CLK_PLL1, 12288, 1),
+
+ DEF_DIV6P1("sd2", R8A7742_CLK_SD2, CLK_PLL1_DIV2, 0x078),
+ DEF_DIV6P1("sd3", R8A7742_CLK_SD3, CLK_PLL1_DIV2, 0x26c),
+ DEF_DIV6P1("mmc0", R8A7742_CLK_MMC0, CLK_PLL1_DIV2, 0x240),
+ DEF_DIV6P1("mmc1", R8A7742_CLK_MMC1, CLK_PLL1_DIV2, 0x244),
+};
+
+static const struct mssr_mod_clk r8a7742_mod_clks[] __initconst = {
+ DEF_MOD("msiof0", 0, R8A7742_CLK_MP),
+ DEF_MOD("vcp1", 100, R8A7742_CLK_ZS),
+ DEF_MOD("vcp0", 101, R8A7742_CLK_ZS),
+ DEF_MOD("vpc1", 102, R8A7742_CLK_ZS),
+ DEF_MOD("vpc0", 103, R8A7742_CLK_ZS),
+ DEF_MOD("tmu1", 111, R8A7742_CLK_P),
+ DEF_MOD("3dg", 112, R8A7742_CLK_ZG),
+ DEF_MOD("2d-dmac", 115, R8A7742_CLK_ZS),
+ DEF_MOD("fdp1-2", 117, R8A7742_CLK_ZS),
+ DEF_MOD("fdp1-1", 118, R8A7742_CLK_ZS),
+ DEF_MOD("fdp1-0", 119, R8A7742_CLK_ZS),
+ DEF_MOD("tmu3", 121, R8A7742_CLK_P),
+ DEF_MOD("tmu2", 122, R8A7742_CLK_P),
+ DEF_MOD("cmt0", 124, R8A7742_CLK_R),
+ DEF_MOD("tmu0", 125, R8A7742_CLK_CP),
+ DEF_MOD("vsp1du1", 127, R8A7742_CLK_ZS),
+ DEF_MOD("vsp1du0", 128, R8A7742_CLK_ZS),
+ DEF_MOD("vsp1-sy", 131, R8A7742_CLK_ZS),
+ DEF_MOD("scifa2", 202, R8A7742_CLK_MP),
+ DEF_MOD("scifa1", 203, R8A7742_CLK_MP),
+ DEF_MOD("scifa0", 204, R8A7742_CLK_MP),
+ DEF_MOD("msiof2", 205, R8A7742_CLK_MP),
+ DEF_MOD("scifb0", 206, R8A7742_CLK_MP),
+ DEF_MOD("scifb1", 207, R8A7742_CLK_MP),
+ DEF_MOD("msiof1", 208, R8A7742_CLK_MP),
+ DEF_MOD("msiof3", 215, R8A7742_CLK_MP),
+ DEF_MOD("scifb2", 216, R8A7742_CLK_MP),
+ DEF_MOD("sys-dmac1", 218, R8A7742_CLK_ZS),
+ DEF_MOD("sys-dmac0", 219, R8A7742_CLK_ZS),
+ DEF_MOD("iic2", 300, R8A7742_CLK_HP),
+ DEF_MOD("tpu0", 304, R8A7742_CLK_CP),
+ DEF_MOD("mmcif1", 305, R8A7742_CLK_MMC1),
+ DEF_MOD("scif2", 310, R8A7742_CLK_P),
+ DEF_MOD("sdhi3", 311, R8A7742_CLK_SD3),
+ DEF_MOD("sdhi2", 312, R8A7742_CLK_SD2),
+ DEF_MOD("sdhi1", 313, R8A7742_CLK_SD1),
+ DEF_MOD("sdhi0", 314, R8A7742_CLK_SD0),
+ DEF_MOD("mmcif0", 315, R8A7742_CLK_MMC0),
+ DEF_MOD("iic0", 318, R8A7742_CLK_HP),
+ DEF_MOD("pciec", 319, R8A7742_CLK_MP),
+ DEF_MOD("iic1", 323, R8A7742_CLK_HP),
+ DEF_MOD("usb3.0", 328, R8A7742_CLK_MP),
+ DEF_MOD("cmt1", 329, R8A7742_CLK_R),
+ DEF_MOD("usbhs-dmac0", 330, R8A7742_CLK_HP),
+ DEF_MOD("usbhs-dmac1", 331, R8A7742_CLK_HP),
+ DEF_MOD("rwdt", 402, R8A7742_CLK_R),
+ DEF_MOD("irqc", 407, R8A7742_CLK_CP),
+ DEF_MOD("intc-sys", 408, R8A7742_CLK_ZS),
+ DEF_MOD("audio-dmac1", 501, R8A7742_CLK_HP),
+ DEF_MOD("audio-dmac0", 502, R8A7742_CLK_HP),
+ DEF_MOD("thermal", 522, CLK_EXTAL),
+ DEF_MOD("pwm", 523, R8A7742_CLK_P),
+ DEF_MOD("usb-ehci", 703, R8A7742_CLK_MP),
+ DEF_MOD("usbhs", 704, R8A7742_CLK_HP),
+ DEF_MOD("hscif1", 716, R8A7742_CLK_ZS),
+ DEF_MOD("hscif0", 717, R8A7742_CLK_ZS),
+ DEF_MOD("scif1", 720, R8A7742_CLK_P),
+ DEF_MOD("scif0", 721, R8A7742_CLK_P),
+ DEF_MOD("du2", 722, R8A7742_CLK_ZX),
+ DEF_MOD("du1", 723, R8A7742_CLK_ZX),
+ DEF_MOD("du0", 724, R8A7742_CLK_ZX),
+ DEF_MOD("lvds1", 725, R8A7742_CLK_ZX),
+ DEF_MOD("lvds0", 726, R8A7742_CLK_ZX),
+ DEF_MOD("r-gp2d", 807, R8A7742_CLK_ZX),
+ DEF_MOD("vin3", 808, R8A7742_CLK_ZG),
+ DEF_MOD("vin2", 809, R8A7742_CLK_ZG),
+ DEF_MOD("vin1", 810, R8A7742_CLK_ZG),
+ DEF_MOD("vin0", 811, R8A7742_CLK_ZG),
+ DEF_MOD("etheravb", 812, R8A7742_CLK_HP),
+ DEF_MOD("ether", 813, R8A7742_CLK_P),
+ DEF_MOD("sata1", 814, R8A7742_CLK_ZS),
+ DEF_MOD("sata0", 815, R8A7742_CLK_ZS),
+ DEF_MOD("imr-x2-1", 820, R8A7742_CLK_ZG),
+ DEF_MOD("imr-x2-0", 821, R8A7742_CLK_HP),
+ DEF_MOD("imr-lsx2-1", 822, R8A7742_CLK_P),
+ DEF_MOD("imr-lsx2-0", 823, R8A7742_CLK_ZS),
+ DEF_MOD("gpio5", 907, R8A7742_CLK_CP),
+ DEF_MOD("gpio4", 908, R8A7742_CLK_CP),
+ DEF_MOD("gpio3", 909, R8A7742_CLK_CP),
+ DEF_MOD("gpio2", 910, R8A7742_CLK_CP),
+ DEF_MOD("gpio1", 911, R8A7742_CLK_CP),
+ DEF_MOD("gpio0", 912, R8A7742_CLK_CP),
+ DEF_MOD("can1", 915, R8A7742_CLK_P),
+ DEF_MOD("can0", 916, R8A7742_CLK_P),
+ DEF_MOD("qspi_mod", 917, R8A7742_CLK_QSPI),
+ DEF_MOD("iicdvfs", 926, R8A7742_CLK_CP),
+ DEF_MOD("i2c3", 928, R8A7742_CLK_HP),
+ DEF_MOD("i2c2", 929, R8A7742_CLK_HP),
+ DEF_MOD("i2c1", 930, R8A7742_CLK_HP),
+ DEF_MOD("i2c0", 931, R8A7742_CLK_HP),
+ DEF_MOD("ssi-all", 1005, R8A7742_CLK_P),
+ DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
+ DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
+ DEF_MOD("scu-all", 1017, R8A7742_CLK_P),
+ DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
+ DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
+};
+
+static const unsigned int r8a7742_crit_mod_clks[] __initconst = {
+ MOD_CLK_ID(402), /* RWDT */
+ MOD_CLK_ID(408), /* INTC-SYS (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD EXTAL PLL0 PLL1 PLL3
+ * 14 13 19 (MHz) *1 *1
+ *---------------------------------------------------
+ * 0 0 0 15 x172/2 x208/2 x106
+ * 0 0 1 15 x172/2 x208/2 x88
+ * 0 1 0 20 x130/2 x156/2 x80
+ * 0 1 1 20 x130/2 x156/2 x66
+ * 1 0 0 26 / 2 x200/2 x240/2 x122
+ * 1 0 1 26 / 2 x200/2 x240/2 x102
+ * 1 1 0 30 / 2 x172/2 x208/2 x106
+ * 1 1 1 30 / 2 x172/2 x208/2 x88
+ *
+ * *1 : Table 7.5a indicates VCO output (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
+ (((md) & BIT(13)) >> 12) | \
+ (((md) & BIT(19)) >> 19))
+
+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
+ /* EXTAL div PLL1 mult PLL3 mult */
+ { 1, 208, 106, },
+ { 1, 208, 88, },
+ { 1, 156, 80, },
+ { 1, 156, 66, },
+ { 2, 240, 122, },
+ { 2, 240, 102, },
+ { 2, 208, 106, },
+ { 2, 208, 88, },
+};
+
+static int __init r8a7742_cpg_mssr_init(struct device *dev)
+{
+ const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
+ u32 cpg_mode;
+ int error;
+
+ error = rcar_rst_read_mode_pins(&cpg_mode);
+ if (error)
+ return error;
+
+ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+ return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a7742_cpg_mssr_info __initconst = {
+ /* Core Clocks */
+ .core_clks = r8a7742_core_clks,
+ .num_core_clks = ARRAY_SIZE(r8a7742_core_clks),
+ .last_dt_core_clk = LAST_DT_CORE_CLK,
+ .num_total_core_clks = MOD_CLK_BASE,
+
+ /* Module Clocks */
+ .mod_clks = r8a7742_mod_clks,
+ .num_mod_clks = ARRAY_SIZE(r8a7742_mod_clks),
+ .num_hw_mod_clks = 12 * 32,
+
+ /* Critical Module Clocks */
+ .crit_mod_clks = r8a7742_crit_mod_clks,
+ .num_crit_mod_clks = ARRAY_SIZE(r8a7742_crit_mod_clks),
+
+ /* Callbacks */
+ .init = r8a7742_cpg_mssr_init,
+ .cpg_clk_register = rcar_gen2_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index 1907ee195a08..d900f6bf53d0 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * R9A09G032 clock driver
+ * R9A06G032 clock driver
*
* Copyright (C) 2018 Renesas Electronics Europe Limited
*
@@ -338,8 +338,8 @@ clk_rdesc_get(struct r9a06g032_priv *clocks,
}
/*
- * This implements the R9A09G032 clock gate 'driver'. We cannot use the system's
- * clock gate framework as the gates on the R9A09G032 have a special enabling
+ * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's
+ * clock gate framework as the gates on the R9A06G032 have a special enabling
* sequence, therefore we use this little proxy.
*/
struct r9a06g032_clk_gate {
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index a2663fbbd7a5..dcb6e2706d37 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -673,6 +673,12 @@ static const struct of_device_id cpg_mssr_match[] = {
.data = &r7s9210_cpg_mssr_info,
},
#endif
+#ifdef CONFIG_CLK_R8A7742
+ {
+ .compatible = "renesas,r8a7742-cpg-mssr",
+ .data = &r8a7742_cpg_mssr_info,
+ },
+#endif
#ifdef CONFIG_CLK_R8A7743
{
.compatible = "renesas,r8a7743-cpg-mssr",
@@ -812,7 +818,8 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
/* Save module registers with bits under our control */
for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
if (priv->smstpcr_saved[reg].mask)
- priv->smstpcr_saved[reg].val =
+ priv->smstpcr_saved[reg].val = priv->stbyctrl ?
+ readb(priv->base + STBCR(reg)) :
readl(priv->base + SMSTPCR(reg));
}
@@ -872,8 +879,9 @@ static int cpg_mssr_resume_noirq(struct device *dev)
}
if (!i)
- dev_warn(dev, "Failed to enable SMSTP %p[0x%x]\n",
- priv->base + SMSTPCR(reg), oldval & mask);
+ dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
+ priv->stbyctrl ? "STB" : "SMSTP", reg,
+ oldval & mask);
}
return 0;
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index 3b852ba0ecec..55a18ef0efaf 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -155,6 +155,7 @@ struct cpg_mssr_info {
};
extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a7742_cpg_mssr_info;
extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
extern const struct cpg_mssr_info r8a77470_cpg_mssr_info;
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index c9e5a1fb6653..fea33399a632 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -540,7 +540,7 @@ static const struct samsung_div_clock exynos5800_div_clks[] __initconst = {
static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = {
GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam",
- GATE_BUS_TOP, 24, 0, 0),
+ GATE_BUS_TOP, 24, CLK_IS_CRITICAL, 0),
GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0),
};
@@ -943,25 +943,25 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
GATE(0, "aclk300_jpeg", "mout_user_aclk300_jpeg",
GATE_BUS_TOP, 4, CLK_IGNORE_UNUSED, 0),
GATE(0, "aclk333_432_isp0", "mout_user_aclk333_432_isp0",
- GATE_BUS_TOP, 5, 0, 0),
+ GATE_BUS_TOP, 5, CLK_IS_CRITICAL, 0),
GATE(0, "aclk300_gscl", "mout_user_aclk300_gscl",
GATE_BUS_TOP, 6, CLK_IS_CRITICAL, 0),
GATE(0, "aclk333_432_gscl", "mout_user_aclk333_432_gscl",
GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0),
GATE(0, "aclk333_432_isp", "mout_user_aclk333_432_isp",
- GATE_BUS_TOP, 8, 0, 0),
+ GATE_BUS_TOP, 8, CLK_IS_CRITICAL, 0),
GATE(CLK_PCLK66_GPIO, "pclk66_gpio", "mout_user_pclk66_gpio",
GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0),
GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen",
GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0),
GATE(0, "aclk266_isp", "mout_user_aclk266_isp",
- GATE_BUS_TOP, 13, 0, 0),
+ GATE_BUS_TOP, 13, CLK_IS_CRITICAL, 0),
GATE(0, "aclk166", "mout_user_aclk166",
GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0),
GATE(CLK_ACLK333, "aclk333", "mout_user_aclk333",
GATE_BUS_TOP, 15, CLK_IS_CRITICAL, 0),
GATE(0, "aclk400_isp", "mout_user_aclk400_isp",
- GATE_BUS_TOP, 16, 0, 0),
+ GATE_BUS_TOP, 16, CLK_IS_CRITICAL, 0),
GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl",
GATE_BUS_TOP, 17, CLK_IS_CRITICAL, 0),
GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1",
@@ -1161,9 +1161,11 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
GATE_IP_GSCL1, 3, 0, 0),
GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333",
GATE_IP_GSCL1, 4, 0, 0),
- GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0),
- GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0),
- GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333",
+ GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12,
+ CLK_IS_CRITICAL, 0),
+ GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13,
+ CLK_IS_CRITICAL, 0),
+ GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3", "dout_gscl_blk_333",
GATE_IP_GSCL1, 16, 0, 0),
GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl",
GATE_IP_GSCL1, 17, 0, 0),
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 4b1aa9382ad2..6f29ecd0442e 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -1706,7 +1706,8 @@ static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric",
ENABLE_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0),
GATE(CLK_SCLK_I2S1, "sclk_i2s1", "sclk_i2s1_peric",
- ENABLE_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0),
+ ENABLE_SCLK_PERIC, 6,
+ CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
GATE(CLK_SCLK_SPI2, "sclk_spi2", "sclk_spi2_peric", ENABLE_SCLK_PERIC,
5, CLK_SET_RATE_PARENT, 0),
GATE(CLK_SCLK_SPI1, "sclk_spi1", "sclk_spi1_peric", ENABLE_SCLK_PERIC,
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index 5f30fe72cd51..c7aba1e1af70 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -387,7 +387,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
ARRAY_SIZE(s3c2450_gates));
samsung_clk_register_alias(ctx, s3c2450_aliases,
ARRAY_SIZE(s3c2450_aliases));
- /* fall through - as s3c2450 extends the s3c2416 clocks */
+ fallthrough; /* as s3c2450 extends the s3c2416 clocks */
case S3C2416:
samsung_clk_register_div(ctx, s3c2416_dividers,
ARRAY_SIZE(s3c2416_dividers));
diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile
index ce5aa7802eb8..bf736f8d201a 100644
--- a/drivers/clk/socfpga/Makefile
+++ b/drivers/clk/socfpga/Makefile
@@ -3,3 +3,5 @@ obj-$(CONFIG_ARCH_SOCFPGA) += clk.o clk-gate.o clk-pll.o clk-periph.o
obj-$(CONFIG_ARCH_SOCFPGA) += clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o
obj-$(CONFIG_ARCH_STRATIX10) += clk-s10.o
obj-$(CONFIG_ARCH_STRATIX10) += clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
+obj-$(CONFIG_ARCH_AGILEX) += clk-agilex.o
+obj-$(CONFIG_ARCH_AGILEX) += clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c
new file mode 100644
index 000000000000..699527f7e764
--- /dev/null
+++ b/drivers/clk/socfpga/clk-agilex.c
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019, Intel Corporation
+ */
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/agilex-clock.h>
+
+#include "stratix10-clk.h"
+
+static const struct clk_parent_data pll_mux[] = {
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data cntr_mux[] = {
+ { .fw_name = "main_pll",
+ .name = "main_pll", },
+ { .fw_name = "periph_pll",
+ .name = "periph_pll", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data boot_mux[] = {
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+};
+
+static const struct clk_parent_data mpu_free_mux[] = {
+ { .fw_name = "main_pll_c0",
+ .name = "main_pll_c0", },
+ { .fw_name = "peri_pll_c0",
+ .name = "peri_pll_c0", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data noc_free_mux[] = {
+ { .fw_name = "main_pll_c1",
+ .name = "main_pll_c1", },
+ { .fw_name = "peri_pll_c1",
+ .name = "peri_pll_c1", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emaca_free_mux[] = {
+ { .fw_name = "main_pll_c2",
+ .name = "main_pll_c2", },
+ { .fw_name = "peri_pll_c2",
+ .name = "peri_pll_c2", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emacb_free_mux[] = {
+ { .fw_name = "main_pll_c3",
+ .name = "main_pll_c3", },
+ { .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emac_ptp_free_mux[] = {
+ { .fw_name = "main_pll_c3",
+ .name = "main_pll_c3", },
+ { .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data gpio_db_free_mux[] = {
+ { .fw_name = "main_pll_c3",
+ .name = "main_pll_c3", },
+ { .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data psi_ref_free_mux[] = {
+ { .fw_name = "main_pll_c3",
+ .name = "main_pll_c3", },
+ { .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data sdmmc_free_mux[] = {
+ { .fw_name = "main_pll_c3",
+ .name = "main_pll_c3", },
+ { .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data s2f_usr0_free_mux[] = {
+ { .fw_name = "main_pll_c2",
+ .name = "main_pll_c2", },
+ { .fw_name = "peri_pll_c2",
+ .name = "peri_pll_c2", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data s2f_usr1_free_mux[] = {
+ { .fw_name = "main_pll_c2",
+ .name = "main_pll_c2", },
+ { .fw_name = "peri_pll_c2",
+ .name = "peri_pll_c2", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data mpu_mux[] = {
+ { .fw_name = "mpu_free_clk",
+ .name = "mpu_free_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data s2f_usr0_mux[] = {
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emac_mux[] = {
+ { .fw_name = "emaca_free_clk",
+ .name = "emaca_free_clk", },
+ { .fw_name = "emacb_free_clk",
+ .name = "emacb_free_clk", },
+};
+
+static const struct clk_parent_data noc_mux[] = {
+ { .fw_name = "noc_free_clk",
+ .name = "noc_free_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+/* clocks in AO (always on) controller */
+static const struct stratix10_pll_clock agilex_pll_clks[] = {
+ { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
+ 0x0},
+ { AGILEX_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
+ 0, 0x48},
+ { AGILEX_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
+ 0, 0x9c},
+};
+
+static const struct stratix10_perip_c_clock agilex_main_perip_c_clks[] = {
+ { AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x58},
+ { AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x5C},
+ { AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x64},
+ { AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x68},
+ { AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xAC},
+ { AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xB0},
+ { AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xB8},
+ { AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xBC},
+};
+
+static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
+ { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
+ 0, 0x3C, 0, 0, 0},
+ { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
+ 0, 0x40, 0, 0, 1},
+ { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0,
+ 0, 4, 0, 0},
+ { AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
+ 0, 0, 0, 0x30, 1},
+ { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
+ 0, 0xD4, 0, 0x88, 0},
+ { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
+ 0, 0xD8, 0, 0x88, 1},
+ { AGILEX_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
+ ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2},
+ { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
+ ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
+ { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
+ ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4},
+ { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
+ ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0},
+ { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
+ ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
+ { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
+ ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6},
+};
+
+static const struct stratix10_gate_clock agilex_gate_clks[] = {
+ { AGILEX_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x24,
+ 0, 0, 0, 0, 0x30, 0, 0},
+ { AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
+ 0, 0, 0, 0, 0, 0, 4},
+ { AGILEX_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x24,
+ 0, 0, 0, 0, 0, 0, 2},
+ { AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24,
+ 1, 0x44, 0, 2, 0, 0, 0},
+ { AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24,
+ 2, 0x44, 8, 2, 0, 0, 0},
+ /*
+ * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
+ * being the SP timers, thus cannot get gated.
+ */
+ { AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24,
+ 3, 0x44, 16, 2, 0, 0, 0},
+ { AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24,
+ 4, 0x44, 24, 2, 0, 0, 0},
+ { AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24,
+ 4, 0x44, 26, 2, 0, 0, 0},
+ { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
+ 4, 0x44, 28, 1, 0, 0, 0},
+ { AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24,
+ 5, 0, 0, 0, 0, 0, 0},
+ { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24,
+ 6, 0, 0, 0, 0, 0, 0},
+ { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
+ 0, 0, 0, 0, 0x94, 26, 0},
+ { AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
+ 1, 0, 0, 0, 0x94, 27, 0},
+ { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
+ 2, 0, 0, 0, 0x94, 28, 0},
+ { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C,
+ 3, 0, 0, 0, 0, 0, 0},
+ { AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C,
+ 4, 0x98, 0, 16, 0, 0, 0},
+ { AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C,
+ 5, 0, 0, 0, 0, 0, 4},
+ { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C,
+ 6, 0, 0, 0, 0, 0, 0},
+ { AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C,
+ 7, 0, 0, 0, 0, 0, 0},
+ { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+ 8, 0, 0, 0, 0, 0, 0},
+ { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+ 9, 0, 0, 0, 0, 0, 0},
+ { AGILEX_NAND_CLK, "nand_clk", "l4_main_clk", NULL, 1, 0, 0x7C,
+ 10, 0, 0, 0, 0, 0, 0},
+};
+
+static int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
+ int nums, struct stratix10_clock_data *data)
+{
+ struct clk *clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ clk = s10_register_periph(&clks[i], base);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n",
+ __func__, clks[i].name);
+ continue;
+ }
+ data->clk_data.clks[clks[i].id] = clk;
+ }
+ return 0;
+}
+
+static int agilex_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
+ int nums, struct stratix10_clock_data *data)
+{
+ struct clk *clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ clk = s10_register_cnt_periph(&clks[i], base);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n",
+ __func__, clks[i].name);
+ continue;
+ }
+ data->clk_data.clks[clks[i].id] = clk;
+ }
+
+ return 0;
+}
+
+static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks, int nums, struct stratix10_clock_data *data)
+{
+ struct clk *clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ clk = s10_register_gate(&clks[i], base);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n",
+ __func__, clks[i].name);
+ continue;
+ }
+ data->clk_data.clks[clks[i].id] = clk;
+ }
+
+ return 0;
+}
+
+static int agilex_clk_register_pll(const struct stratix10_pll_clock *clks,
+ int nums, struct stratix10_clock_data *data)
+{
+ struct clk *clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ clk = agilex_register_pll(&clks[i], base);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n",
+ __func__, clks[i].name);
+ continue;
+ }
+ data->clk_data.clks[clks[i].id] = clk;
+ }
+
+ return 0;
+}
+
+static struct stratix10_clock_data *__socfpga_agilex_clk_init(struct platform_device *pdev,
+ int nr_clks)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct stratix10_clock_data *clk_data;
+ struct clk **clk_table;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return ERR_CAST(base);
+
+ clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return ERR_PTR(-ENOMEM);
+
+ clk_data->base = base;
+ clk_table = devm_kcalloc(dev, nr_clks, sizeof(*clk_table), GFP_KERNEL);
+ if (!clk_table)
+ return ERR_PTR(-ENOMEM);
+
+ clk_data->clk_data.clks = clk_table;
+ clk_data->clk_data.clk_num = nr_clks;
+ ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return clk_data;
+}
+
+static int agilex_clkmgr_probe(struct platform_device *pdev)
+{
+ struct stratix10_clock_data *clk_data;
+
+ clk_data = __socfpga_agilex_clk_init(pdev, AGILEX_NUM_CLKS);
+ if (IS_ERR(clk_data))
+ return PTR_ERR(clk_data);
+
+ agilex_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
+
+ agilex_clk_register_c_perip(agilex_main_perip_c_clks,
+ ARRAY_SIZE(agilex_main_perip_c_clks), clk_data);
+
+ agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
+ ARRAY_SIZE(agilex_main_perip_cnt_clks),
+ clk_data);
+
+ agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
+ clk_data);
+ return 0;
+}
+
+static const struct of_device_id agilex_clkmgr_match_table[] = {
+ { .compatible = "intel,agilex-clkmgr",
+ .data = agilex_clkmgr_probe },
+ { }
+};
+
+static struct platform_driver agilex_clkmgr_driver = {
+ .probe = agilex_clkmgr_probe,
+ .driver = {
+ .name = "agilex-clkmgr",
+ .suppress_bind_attrs = true,
+ .of_match_table = agilex_clkmgr_match_table,
+ },
+};
+
+static int __init agilex_clk_init(void)
+{
+ return platform_driver_register(&agilex_clkmgr_driver);
+}
+core_initcall(agilex_clk_init);
diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c
index 8be4722f6064..083b2ec21fdd 100644
--- a/drivers/clk/socfpga/clk-gate-s10.c
+++ b/drivers/clk/socfpga/clk-gate-s10.c
@@ -70,7 +70,6 @@ struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __io
struct clk *clk;
struct socfpga_gate_clk *socfpga_clk;
struct clk_init_data init;
- const char * const *parent_names = clks->parent_names;
const char *parent_name = clks->parent_name;
socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
@@ -108,7 +107,9 @@ struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __io
init.flags = clks->flags;
init.num_parents = clks->num_parents;
- init.parent_names = parent_names ? parent_names : &parent_name;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ if (init.parent_names == NULL)
+ init.parent_data = clks->parent_data;
socfpga_clk->hw.hw.init = &init;
clk = clk_register(NULL, &socfpga_clk->hw.hw);
diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c
index dd6d4056e9de..397b77b89b16 100644
--- a/drivers/clk/socfpga/clk-periph-s10.c
+++ b/drivers/clk/socfpga/clk-periph-s10.c
@@ -81,7 +81,6 @@ struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks,
struct clk_init_data init;
const char *name = clks->name;
const char *parent_name = clks->parent_name;
- const char * const *parent_names = clks->parent_names;
periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk))
@@ -94,7 +93,9 @@ struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks,
init.flags = clks->flags;
init.num_parents = clks->num_parents;
- init.parent_names = parent_names ? parent_names : &parent_name;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ if (init.parent_names == NULL)
+ init.parent_data = clks->parent_data;
periph_clk->hw.hw.init = &init;
@@ -114,7 +115,6 @@ struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks
struct clk_init_data init;
const char *name = clks->name;
const char *parent_name = clks->parent_name;
- const char * const *parent_names = clks->parent_names;
periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk))
@@ -137,7 +137,9 @@ struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks
init.flags = clks->flags;
init.num_parents = clks->num_parents;
- init.parent_names = parent_names ? parent_names : &parent_name;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ if (init.parent_names == NULL)
+ init.parent_data = clks->parent_data;
periph_clk->hw.hw.init = &init;
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
index 3816fc04b274..db54f7d806a0 100644
--- a/drivers/clk/socfpga/clk-pll-a10.c
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -58,7 +58,7 @@ static u8 clk_pll_get_parent(struct clk_hw *hwclk)
CLK_MGR_PLL_CLK_SRC_MASK;
}
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops clk_pll_ops = {
.recalc_rate = clk_pll_recalc_rate,
.get_parent = clk_pll_get_parent,
};
@@ -102,8 +102,6 @@ static struct clk * __init __socfpga_pll_init(struct device_node *node,
pll_clk->hw.hw.init = &init;
pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
- clk_pll_ops.enable = clk_gate_ops.enable;
- clk_pll_ops.disable = clk_gate_ops.disable;
clk = clk_register(NULL, &pll_clk->hw.hw);
if (WARN_ON(IS_ERR(clk))) {
diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c
index a301bb22f36c..4e268953b7da 100644
--- a/drivers/clk/socfpga/clk-pll-s10.c
+++ b/drivers/clk/socfpga/clk-pll-s10.c
@@ -18,8 +18,12 @@
#define SOCFPGA_PLL_RESET_MASK 0x2
#define SOCFPGA_PLL_REFDIV_MASK 0x00003F00
#define SOCFPGA_PLL_REFDIV_SHIFT 8
+#define SOCFPGA_PLL_AREFDIV_MASK 0x00000F00
+#define SOCFPGA_PLL_DREFDIV_MASK 0x00003000
+#define SOCFPGA_PLL_DREFDIV_SHIFT 12
#define SOCFPGA_PLL_MDIV_MASK 0xFF000000
#define SOCFPGA_PLL_MDIV_SHIFT 24
+#define SOCFPGA_AGILEX_PLL_MDIV_MASK 0x000003FF
#define SWCTRLBTCLKSEL_MASK 0x200
#define SWCTRLBTCLKSEL_SHIFT 9
@@ -27,6 +31,27 @@
#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
+static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+ unsigned long arefdiv, reg, mdiv;
+ unsigned long long vco_freq;
+
+ /* read VCO1 reg for numerator and denominator */
+ reg = readl(socfpgaclk->hw.reg);
+ arefdiv = (reg & SOCFPGA_PLL_AREFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT;
+
+ vco_freq = (unsigned long long)parent_rate / arefdiv;
+
+ /* Read mdiv and fdiv from the fdbck register */
+ reg = readl(socfpgaclk->hw.reg + 0x24);
+ mdiv = reg & SOCFPGA_AGILEX_PLL_MDIV_MASK;
+
+ vco_freq = (unsigned long long)vco_freq * mdiv;
+ return (unsigned long)vco_freq;
+}
+
static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
unsigned long parent_rate)
{
@@ -98,13 +123,19 @@ static int clk_pll_prepare(struct clk_hw *hwclk)
return 0;
}
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops agilex_clk_pll_ops = {
+ .recalc_rate = agilex_clk_pll_recalc_rate,
+ .get_parent = clk_pll_get_parent,
+ .prepare = clk_pll_prepare,
+};
+
+static const struct clk_ops clk_pll_ops = {
.recalc_rate = clk_pll_recalc_rate,
.get_parent = clk_pll_get_parent,
.prepare = clk_pll_prepare,
};
-static struct clk_ops clk_boot_ops = {
+static const struct clk_ops clk_boot_ops = {
.recalc_rate = clk_boot_clk_recalc_rate,
.get_parent = clk_boot_get_parent,
.prepare = clk_pll_prepare,
@@ -117,7 +148,6 @@ struct clk *s10_register_pll(const struct stratix10_pll_clock *clks,
struct socfpga_pll *pll_clk;
struct clk_init_data init;
const char *name = clks->name;
- const char * const *parent_names = clks->parent_names;
pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
if (WARN_ON(!pll_clk))
@@ -134,12 +164,48 @@ struct clk *s10_register_pll(const struct stratix10_pll_clock *clks,
init.flags = clks->flags;
init.num_parents = clks->num_parents;
- init.parent_names = parent_names;
+ init.parent_names = NULL;
+ init.parent_data = clks->parent_data;
+ pll_clk->hw.hw.init = &init;
+
+ pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
+
+ clk = clk_register(NULL, &pll_clk->hw.hw);
+ if (WARN_ON(IS_ERR(clk))) {
+ kfree(pll_clk);
+ return NULL;
+ }
+ return clk;
+}
+
+struct clk *agilex_register_pll(const struct stratix10_pll_clock *clks,
+ void __iomem *reg)
+{
+ struct clk *clk;
+ struct socfpga_pll *pll_clk;
+ struct clk_init_data init;
+ const char *name = clks->name;
+
+ pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
+ if (WARN_ON(!pll_clk))
+ return NULL;
+
+ pll_clk->hw.reg = reg + clks->offset;
+
+ if (streq(name, SOCFPGA_BOOT_CLK))
+ init.ops = &clk_boot_ops;
+ else
+ init.ops = &agilex_clk_pll_ops;
+
+ init.name = name;
+ init.flags = clks->flags;
+
+ init.num_parents = clks->num_parents;
+ init.parent_names = NULL;
+ init.parent_data = clks->parent_data;
pll_clk->hw.hw.init = &init;
pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
- clk_pll_ops.enable = clk_gate_ops.enable;
- clk_pll_ops.disable = clk_gate_ops.disable;
clk = clk_register(NULL, &pll_clk->hw.hw);
if (WARN_ON(IS_ERR(clk))) {
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
index dc65cc0fd3bd..e5fb786843f3 100644
--- a/drivers/clk/socfpga/clk-pll.c
+++ b/drivers/clk/socfpga/clk-pll.c
@@ -65,7 +65,7 @@ static u8 clk_pll_get_parent(struct clk_hw *hwclk)
CLK_MGR_PLL_CLK_SRC_MASK;
}
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops clk_pll_ops = {
.recalc_rate = clk_pll_recalc_rate,
.get_parent = clk_pll_get_parent,
};
@@ -105,8 +105,6 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
pll_clk->hw.hw.init = &init;
pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
- clk_pll_ops.enable = clk_gate_ops.enable;
- clk_pll_ops.disable = clk_gate_ops.disable;
clk = clk_register(NULL, &pll_clk->hw.hw);
if (WARN_ON(IS_ERR(clk))) {
diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c
index dea7c6c7d269..c1dfc9b34e4e 100644
--- a/drivers/clk/socfpga/clk-s10.c
+++ b/drivers/clk/socfpga/clk-s10.c
@@ -12,35 +12,137 @@
#include "stratix10-clk.h"
-static const char * const pll_mux[] = { "osc1", "cb-intosc-hs-div2-clk",
- "f2s-free-clk",};
-static const char * const cntr_mux[] = { "main_pll", "periph_pll",
- "osc1", "cb-intosc-hs-div2-clk",
- "f2s-free-clk"};
-static const char * const boot_mux[] = { "osc1", "cb-intosc-hs-div2-clk",};
-
-static const char * const noc_free_mux[] = {"main_noc_base_clk",
- "peri_noc_base_clk",
- "osc1", "cb-intosc-hs-div2-clk",
- "f2s-free-clk"};
-
-static const char * const emaca_free_mux[] = {"peri_emaca_clk", "boot_clk"};
-static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"};
-static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"};
-static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"};
-static const char * const sdmmc_free_mux[] = {"main_sdmmc_clk", "boot_clk"};
-static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"};
-static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"};
-static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",};
-
-static const char * const s2f_usr0_mux[] = {"f2s-free-clk", "boot_clk"};
-static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"};
-static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"};
-
-static const char * const mpu_free_mux[] = {"main_mpu_base_clk",
- "peri_mpu_base_clk",
- "osc1", "cb-intosc-hs-div2-clk",
- "f2s-free-clk"};
+static const struct clk_parent_data pll_mux[] = {
+ { .fw_name = "osc1",
+ .name = "osc1" },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk" },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk" },
+};
+
+static const struct clk_parent_data cntr_mux[] = {
+ { .fw_name = "main_pll",
+ .name = "main_pll", },
+ { .fw_name = "periph_pll",
+ .name = "periph_pll", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data boot_mux[] = {
+ { .fw_name = "osc1",
+ .name = "osc1" },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk" },
+};
+
+static const struct clk_parent_data noc_free_mux[] = {
+ { .fw_name = "main_noc_base_clk",
+ .name = "main_noc_base_clk", },
+ { .fw_name = "peri_noc_base_clk",
+ .name = "peri_noc_base_clk", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emaca_free_mux[] = {
+ { .fw_name = "peri_emaca_clk",
+ .name = "peri_emaca_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emacb_free_mux[] = {
+ { .fw_name = "peri_emacb_clk",
+ .name = "peri_emacb_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emac_ptp_free_mux[] = {
+ { .fw_name = "peri_emac_ptp_clk",
+ .name = "peri_emac_ptp_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data gpio_db_free_mux[] = {
+ { .fw_name = "peri_gpio_db_clk",
+ .name = "peri_gpio_db_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data sdmmc_free_mux[] = {
+ { .fw_name = "main_sdmmc_clk",
+ .name = "main_sdmmc_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data s2f_usr1_free_mux[] = {
+ { .fw_name = "peri_s2f_usr1_clk",
+ .name = "peri_s2f_usr1_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data psi_ref_free_mux[] = {
+ { .fw_name = "peri_psi_ref_clk",
+ .name = "peri_psi_ref_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data mpu_mux[] = {
+ { .fw_name = "mpu_free_clk",
+ .name = "mpu_free_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data s2f_usr0_mux[] = {
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emac_mux[] = {
+ { .fw_name = "emaca_free_clk",
+ .name = "emaca_free_clk", },
+ { .fw_name = "emacb_free_clk",
+ .name = "emacb_free_clk", },
+};
+
+static const struct clk_parent_data noc_mux[] = {
+ { .fw_name = "noc_free_clk",
+ .name = "noc_free_clk", },
+ { .fw_name = "boot_clk",
+ .name = "boot_clk", },
+};
+
+static const struct clk_parent_data mpu_free_mux[] = {
+ { .fw_name = "main_mpu_base_clk",
+ .name = "main_mpu_base_clk", },
+ { .fw_name = "peri_mpu_base_clk",
+ .name = "peri_mpu_base_clk", },
+ { .fw_name = "osc1",
+ .name = "osc1", },
+ { .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk", },
+ { .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk", },
+};
/* clocks in AO (always on) controller */
static const struct stratix10_pll_clock s10_pll_clks[] = {
diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h
index fcabef42249c..f9d5d724c694 100644
--- a/drivers/clk/socfpga/stratix10-clk.h
+++ b/drivers/clk/socfpga/stratix10-clk.h
@@ -14,7 +14,7 @@ struct stratix10_clock_data {
struct stratix10_pll_clock {
unsigned int id;
const char *name;
- const char *const *parent_names;
+ const struct clk_parent_data *parent_data;
u8 num_parents;
unsigned long flags;
unsigned long offset;
@@ -24,7 +24,7 @@ struct stratix10_perip_c_clock {
unsigned int id;
const char *name;
const char *parent_name;
- const char *const *parent_names;
+ const struct clk_parent_data *parent_data;
u8 num_parents;
unsigned long flags;
unsigned long offset;
@@ -34,7 +34,7 @@ struct stratix10_perip_cnt_clock {
unsigned int id;
const char *name;
const char *parent_name;
- const char *const *parent_names;
+ const struct clk_parent_data *parent_data;
u8 num_parents;
unsigned long flags;
unsigned long offset;
@@ -47,7 +47,7 @@ struct stratix10_gate_clock {
unsigned int id;
const char *name;
const char *parent_name;
- const char *const *parent_names;
+ const struct clk_parent_data *parent_data;
u8 num_parents;
unsigned long flags;
unsigned long gate_reg;
@@ -62,6 +62,8 @@ struct stratix10_gate_clock {
struct clk *s10_register_pll(const struct stratix10_pll_clock *,
void __iomem *);
+struct clk *agilex_register_pll(const struct stratix10_pll_clock *,
+ void __iomem *);
struct clk *s10_register_periph(const struct stratix10_perip_c_clock *,
void __iomem *);
struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *,
diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c
index 574cfc116bbc..56e1714b541e 100644
--- a/drivers/clk/sprd/gate.c
+++ b/drivers/clk/sprd/gate.c
@@ -94,8 +94,15 @@ static int sprd_gate_is_enabled(struct clk_hw *hw)
{
struct sprd_gate *sg = hw_to_sprd_gate(hw);
struct sprd_clk_common *common = &sg->common;
+ struct clk_hw *parent;
unsigned int reg;
+ if (sg->flags & SPRD_GATE_NON_AON) {
+ parent = clk_hw_get_parent(hw);
+ if (!parent || !clk_hw_is_enabled(parent))
+ return 0;
+ }
+
regmap_read(common->regmap, common->reg, &reg);
if (sg->flags & CLK_GATE_SET_TO_DISABLE)
diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h
index b55817869367..e738dafa4fe9 100644
--- a/drivers/clk/sprd/gate.h
+++ b/drivers/clk/sprd/gate.h
@@ -19,6 +19,15 @@ struct sprd_gate {
struct sprd_clk_common common;
};
+/*
+ * sprd_gate->flags is used for:
+ * CLK_GATE_SET_TO_DISABLE BIT(0)
+ * CLK_GATE_HIWORD_MASK BIT(1)
+ * CLK_GATE_BIG_ENDIAN BIT(2)
+ * so we define new flags from BIT(3)
+ */
+#define SPRD_GATE_NON_AON BIT(3) /* not alway powered on, check before read */
+
#define SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \
_sc_offset, _enable_mask, _flags, \
_gate_flags, _udelay, _ops, _fn) \
diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c
index 15791484388f..13a322b2535a 100644
--- a/drivers/clk/sprd/pll.c
+++ b/drivers/clk/sprd/pll.c
@@ -106,7 +106,7 @@ static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
if (!cfg)
- return -ENOMEM;
+ return parent_rate;
for (i = 0; i < regs_num; i++)
cfg[i] = sprd_pll_read(pll, i);
diff --git a/drivers/clk/sprd/sc9863a-clk.c b/drivers/clk/sprd/sc9863a-clk.c
index 2e2dfb2d48ff..ad2e0f9f8563 100644
--- a/drivers/clk/sprd/sc9863a-clk.c
+++ b/drivers/clk/sprd/sc9863a-clk.c
@@ -23,22 +23,22 @@
#include "pll.h"
/* mpll*_gate clocks control cpu cores, they were enabled by default */
-SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94,
- 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98,
- 0x1000, BIT(0), 0, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0x9c,
- 0x1000, BIT(0), 0, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8,
- 0x1000, BIT(0), 0, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc,
- 0x1000, BIT(0), 0, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0,
- 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4,
- 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
-SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", 0x1e8,
- 0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94,
+ 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98,
+ 0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0x9c,
+ 0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8,
+ 0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc,
+ 0x1000, BIT(0), 0, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0,
+ 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4,
+ 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
+static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m",
+ 0x1e8, 0x1000, BIT(0), 0, 0, 240);
static struct sprd_clk_common *sc9863a_pmu_gate_clks[] = {
/* address base is 0x402b0000 */
@@ -1615,6 +1615,36 @@ static const struct sprd_clk_desc sc9863a_mm_gate_desc = {
.hw_clks = &sc9863a_mm_gate_hws,
};
+/* camera sensor clocks */
+static SPRD_GATE_CLK_HW(mipi_csi_clk, "mipi-csi-clk", &mahb_ckg_eb.common.hw,
+ 0x20, BIT(16), 0, SPRD_GATE_NON_AON);
+static SPRD_GATE_CLK_HW(mipi_csi_s_clk, "mipi-csi-s-clk", &mahb_ckg_eb.common.hw,
+ 0x24, BIT(16), 0, SPRD_GATE_NON_AON);
+static SPRD_GATE_CLK_HW(mipi_csi_m_clk, "mipi-csi-m-clk", &mahb_ckg_eb.common.hw,
+ 0x28, BIT(16), 0, SPRD_GATE_NON_AON);
+
+static struct sprd_clk_common *sc9863a_mm_clk_clks[] = {
+ /* address base is 0x60900000 */
+ &mipi_csi_clk.common,
+ &mipi_csi_s_clk.common,
+ &mipi_csi_m_clk.common,
+};
+
+static struct clk_hw_onecell_data sc9863a_mm_clk_hws = {
+ .hws = {
+ [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw,
+ [CLK_MIPI_CSI_S] = &mipi_csi_s_clk.common.hw,
+ [CLK_MIPI_CSI_M] = &mipi_csi_m_clk.common.hw,
+ },
+ .num = CLK_MM_CLK_NUM,
+};
+
+static const struct sprd_clk_desc sc9863a_mm_clk_desc = {
+ .clk_clks = sc9863a_mm_clk_clks,
+ .num_clk_clks = ARRAY_SIZE(sc9863a_mm_clk_clks),
+ .hw_clks = &sc9863a_mm_clk_hws,
+};
+
static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m", 0x0,
0x1000, BIT(0), 0, 0);
static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m", 0x0,
@@ -1738,6 +1768,8 @@ static const struct of_device_id sprd_sc9863a_clk_ids[] = {
.data = &sc9863a_aonapb_gate_desc },
{ .compatible = "sprd,sc9863a-mm-gate", /* 0x60800000 */
.data = &sc9863a_mm_gate_desc },
+ { .compatible = "sprd,sc9863a-mm-clk", /* 0x60900000 */
+ .data = &sc9863a_mm_clk_desc },
{ .compatible = "sprd,sc9863a-apapb-gate", /* 0x71300000 */
.data = &sc9863a_apapb_gate_desc },
{ }
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index 4413b6e04a8e..55873d4b7603 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -375,6 +375,7 @@ static void __init st_of_flexgen_setup(struct device_node *np)
break;
}
+ flex_flags &= ~CLK_IS_CRITICAL;
of_clk_detect_critical(np, i, &flex_flags);
/*
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 27201fd26e44..e1aa1fbac48a 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -90,7 +90,7 @@ static void sun6i_a31_get_pll1_factors(struct factors_request *req)
* Round down the frequency to the closest multiple of either
* 6 or 16
*/
- u32 round_freq_6 = round_down(freq_mhz, 6);
+ u32 round_freq_6 = rounddown(freq_mhz, 6);
u32 round_freq_16 = round_down(freq_mhz, 16);
if (round_freq_6 > round_freq_16)
diff --git a/drivers/clk/tegra/Kconfig b/drivers/clk/tegra/Kconfig
index 4d99a8770485..deaa4605824c 100644
--- a/drivers/clk/tegra/Kconfig
+++ b/drivers/clk/tegra/Kconfig
@@ -1,8 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
-config TEGRA_CLK_EMC
- def_bool y
- depends on TEGRA124_EMC
-
config CLK_TEGRA_BPMP
def_bool y
depends on TEGRA_BPMP
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index 1f7c30f87ece..eec2313fd37e 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -13,8 +13,8 @@ obj-y += clk-super.o
obj-y += clk-tegra-audio.o
obj-y += clk-tegra-periph.o
obj-y += clk-tegra-fixed.o
+obj-y += clk-tegra-super-cclk.o
obj-y += clk-tegra-super-gen4.o
-obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20-emc.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
@@ -22,8 +22,10 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra20-emc.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o
obj-$(CONFIG_TEGRA_CLK_DFLL) += clk-tegra124-dfll-fcpu.o
+obj-$(CONFIG_TEGRA124_EMC) += clk-tegra124-emc.o
obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
obj-y += cvb.o
obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o
+obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210-emc.o
obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o
obj-y += clk-utils.o
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 531c2b3d814e..0b212cf2e794 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -744,13 +744,19 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
state = clk_pll_is_enabled(hw);
+ if (state && pll->params->pre_rate_change) {
+ ret = pll->params->pre_rate_change();
+ if (WARN_ON(ret))
+ return ret;
+ }
+
_get_pll_mnp(pll, &old_cfg);
if (state && pll->params->defaults_set && pll->params->dyn_ramp &&
(cfg->m == old_cfg.m) && (cfg->p == old_cfg.p)) {
ret = pll->params->dyn_ramp(pll, cfg);
if (!ret)
- return 0;
+ goto done;
}
if (state) {
@@ -772,6 +778,10 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
pll_clk_start_ss(pll);
}
+done:
+ if (state && pll->params->post_rate_change)
+ pll->params->post_rate_change();
+
return ret;
}
diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
new file mode 100644
index 000000000000..a03119c30456
--- /dev/null
+++ b/drivers/clk/tegra/clk-tegra-super-cclk.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Based on clk-super.c
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Based on older tegra20-cpufreq driver by Colin Cross <ccross@google.com>
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author: Dmitry Osipenko <digetx@gmail.com>
+ * Copyright (C) 2019 GRATE-DRIVER project
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+#define PLLP_INDEX 4
+#define PLLX_INDEX 8
+
+#define SUPER_CDIV_ENB BIT(31)
+
+static struct tegra_clk_super_mux *cclk_super;
+static bool cclk_on_pllx;
+
+static u8 cclk_super_get_parent(struct clk_hw *hw)
+{
+ return tegra_clk_super_ops.get_parent(hw);
+}
+
+static int cclk_super_set_parent(struct clk_hw *hw, u8 index)
+{
+ return tegra_clk_super_ops.set_parent(hw, index);
+}
+
+static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ return tegra_clk_super_ops.set_rate(hw, rate, parent_rate);
+}
+
+static unsigned long cclk_super_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ if (cclk_super_get_parent(hw) == PLLX_INDEX)
+ return parent_rate;
+
+ return tegra_clk_super_ops.recalc_rate(hw, parent_rate);
+}
+
+static int cclk_super_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_hw *pllp_hw = clk_hw_get_parent_by_index(hw, PLLP_INDEX);
+ struct clk_hw *pllx_hw = clk_hw_get_parent_by_index(hw, PLLX_INDEX);
+ struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+ unsigned long pllp_rate;
+ long rate = req->rate;
+
+ if (WARN_ON_ONCE(!pllp_hw || !pllx_hw))
+ return -EINVAL;
+
+ /*
+ * Switch parent to PLLP for all CCLK rates that are suitable for PLLP.
+ * PLLX will be disabled in this case, saving some power.
+ */
+ pllp_rate = clk_hw_get_rate(pllp_hw);
+
+ if (rate <= pllp_rate) {
+ if (super->flags & TEGRA20_SUPER_CLK)
+ rate = pllp_rate;
+ else
+ rate = tegra_clk_super_ops.round_rate(hw, rate,
+ &pllp_rate);
+
+ req->best_parent_rate = pllp_rate;
+ req->best_parent_hw = pllp_hw;
+ req->rate = rate;
+ } else {
+ rate = clk_hw_round_rate(pllx_hw, rate);
+ req->best_parent_rate = rate;
+ req->best_parent_hw = pllx_hw;
+ req->rate = rate;
+ }
+
+ if (WARN_ON_ONCE(rate <= 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct clk_ops tegra_cclk_super_ops = {
+ .get_parent = cclk_super_get_parent,
+ .set_parent = cclk_super_set_parent,
+ .set_rate = cclk_super_set_rate,
+ .recalc_rate = cclk_super_recalc_rate,
+ .determine_rate = cclk_super_determine_rate,
+};
+
+static const struct clk_ops tegra_cclk_super_mux_ops = {
+ .get_parent = cclk_super_get_parent,
+ .set_parent = cclk_super_set_parent,
+ .determine_rate = cclk_super_determine_rate,
+};
+
+struct clk *tegra_clk_register_super_cclk(const char *name,
+ const char * const *parent_names, u8 num_parents,
+ unsigned long flags, void __iomem *reg, u8 clk_super_flags,
+ spinlock_t *lock)
+{
+ struct tegra_clk_super_mux *super;
+ struct clk *clk;
+ struct clk_init_data init;
+ u32 val;
+
+ if (WARN_ON(cclk_super))
+ return ERR_PTR(-EBUSY);
+
+ super = kzalloc(sizeof(*super), GFP_KERNEL);
+ if (!super)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = flags;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ super->reg = reg;
+ super->lock = lock;
+ super->width = 4;
+ super->flags = clk_super_flags;
+ super->hw.init = &init;
+
+ if (super->flags & TEGRA20_SUPER_CLK) {
+ init.ops = &tegra_cclk_super_mux_ops;
+ } else {
+ init.ops = &tegra_cclk_super_ops;
+
+ super->frac_div.reg = reg + 4;
+ super->frac_div.shift = 16;
+ super->frac_div.width = 8;
+ super->frac_div.frac_width = 1;
+ super->frac_div.lock = lock;
+ super->div_ops = &tegra_clk_frac_div_ops;
+ }
+
+ /*
+ * Tegra30+ has the following CPUG clock topology:
+ *
+ * +---+ +-------+ +-+ +-+ +-+
+ * PLLP+->+ +->+DIVIDER+->+0| +-------->+0| ------------->+0|
+ * | | +-------+ | | | +---+ | | | | |
+ * PLLC+->+MUX| | +->+ | S | | +->+ | +->+CPU
+ * ... | | | | | | K | | | | +-------+ | |
+ * PLLX+->+-->+------------>+1| +->+ I +->+1| +->+ DIV2 +->+1|
+ * +---+ +++ | P | +++ |SKIPPER| +++
+ * ^ | P | ^ +-------+ ^
+ * | | E | | |
+ * PLLX_SEL+--+ | R | | OVERHEAT+--+
+ * +---+ |
+ * |
+ * SUPER_CDIV_ENB+--+
+ *
+ * Tegra20 is similar, but simpler. It doesn't have the divider and
+ * thermal DIV2 skipper.
+ *
+ * At least for now we're not going to use clock-skipper, hence let's
+ * ensure that it is disabled.
+ */
+ val = readl_relaxed(reg + 4);
+ val &= ~SUPER_CDIV_ENB;
+ writel_relaxed(val, reg + 4);
+
+ clk = clk_register(NULL, &super->hw);
+ if (IS_ERR(clk))
+ kfree(super);
+ else
+ cclk_super = super;
+
+ return clk;
+}
+
+int tegra_cclk_pre_pllx_rate_change(void)
+{
+ if (IS_ERR_OR_NULL(cclk_super))
+ return -EINVAL;
+
+ if (cclk_super_get_parent(&cclk_super->hw) == PLLX_INDEX)
+ cclk_on_pllx = true;
+ else
+ cclk_on_pllx = false;
+
+ /*
+ * CPU needs to be temporarily re-parented away from PLLX if PLLX
+ * changes its rate. PLLP is a safe parent for CPU on all Tegra SoCs.
+ */
+ if (cclk_on_pllx)
+ cclk_super_set_parent(&cclk_super->hw, PLLP_INDEX);
+
+ return 0;
+}
+
+void tegra_cclk_post_pllx_rate_change(void)
+{
+ if (cclk_on_pllx)
+ cclk_super_set_parent(&cclk_super->hw, PLLX_INDEX);
+}
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c
index 745f9faa98d8..745f9faa98d8 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-tegra124-emc.c
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 085feb04e913..3efc651b42e3 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -391,6 +391,8 @@ static struct tegra_clk_pll_params pll_x_params = {
.lock_delay = 300,
.freq_table = pll_x_freq_table,
.flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
+ .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
+ .post_rate_change = tegra_cclk_post_pllx_rate_change,
};
static struct tegra_clk_pll_params pll_e_params = {
@@ -702,9 +704,10 @@ static void tegra20_super_clk_init(void)
struct clk *clk;
/* CCLK */
- clk = tegra_clk_register_super_mux("cclk", cclk_parents,
+ clk = tegra_clk_register_super_cclk("cclk", cclk_parents,
ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
- clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
+ clk_base + CCLK_BURST_POLICY, TEGRA20_SUPER_CLK,
+ NULL);
clks[TEGRA20_CLK_CCLK] = clk;
/* SCLK */
diff --git a/drivers/clk/tegra/clk-tegra210-emc.c b/drivers/clk/tegra/clk-tegra210-emc.c
new file mode 100644
index 000000000000..352a2c3fc374
--- /dev/null
+++ b/drivers/clk/tegra/clk-tegra210-emc.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2015-2020, NVIDIA CORPORATION. All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/tegra.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define CLK_SOURCE_EMC 0x19c
+#define CLK_SOURCE_EMC_2X_CLK_SRC GENMASK(31, 29)
+#define CLK_SOURCE_EMC_MC_EMC_SAME_FREQ BIT(16)
+#define CLK_SOURCE_EMC_2X_CLK_DIVISOR GENMASK(7, 0)
+
+#define CLK_SRC_PLLM 0
+#define CLK_SRC_PLLC 1
+#define CLK_SRC_PLLP 2
+#define CLK_SRC_CLK_M 3
+#define CLK_SRC_PLLM_UD 4
+#define CLK_SRC_PLLMB_UD 5
+#define CLK_SRC_PLLMB 6
+#define CLK_SRC_PLLP_UD 7
+
+struct tegra210_clk_emc {
+ struct clk_hw hw;
+ void __iomem *regs;
+
+ struct tegra210_clk_emc_provider *provider;
+
+ struct clk *parents[8];
+};
+
+static inline struct tegra210_clk_emc *
+to_tegra210_clk_emc(struct clk_hw *hw)
+{
+ return container_of(hw, struct tegra210_clk_emc, hw);
+}
+
+static const char *tegra210_clk_emc_parents[] = {
+ "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb_ud",
+ "pll_mb", "pll_p_ud",
+};
+
+static u8 tegra210_clk_emc_get_parent(struct clk_hw *hw)
+{
+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+ u32 value;
+ u8 src;
+
+ value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
+ src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, value);
+
+ return src;
+}
+
+static unsigned long tegra210_clk_emc_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+ u32 value, div;
+
+ /*
+ * CCF assumes that neither the parent nor its rate will change during
+ * ->set_rate(), so the parent rate passed in here was cached from the
+ * parent before the ->set_rate() call.
+ *
+ * This can lead to wrong results being reported for the EMC clock if
+ * the parent and/or parent rate have changed as part of the EMC rate
+ * change sequence. Fix this by overriding the parent clock with what
+ * we know to be the correct value after the rate change.
+ */
+ parent_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
+
+ value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
+
+ div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, value);
+ div += 2;
+
+ return DIV_ROUND_UP(parent_rate * 2, div);
+}
+
+static long tegra210_clk_emc_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+ struct tegra210_clk_emc_provider *provider = emc->provider;
+ unsigned int i;
+
+ if (!provider || !provider->configs || provider->num_configs == 0)
+ return clk_hw_get_rate(hw);
+
+ for (i = 0; i < provider->num_configs; i++) {
+ if (provider->configs[i].rate >= rate)
+ return provider->configs[i].rate;
+ }
+
+ return provider->configs[i - 1].rate;
+}
+
+static struct clk *tegra210_clk_emc_find_parent(struct tegra210_clk_emc *emc,
+ u8 index)
+{
+ struct clk_hw *parent = clk_hw_get_parent_by_index(&emc->hw, index);
+ const char *name = clk_hw_get_name(parent);
+
+ /* XXX implement cache? */
+
+ return __clk_lookup(name);
+}
+
+static int tegra210_clk_emc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+ struct tegra210_clk_emc_provider *provider = emc->provider;
+ struct tegra210_clk_emc_config *config;
+ struct device *dev = provider->dev;
+ struct clk_hw *old, *new, *parent;
+ u8 old_idx, new_idx, index;
+ struct clk *clk;
+ unsigned int i;
+ int err;
+
+ if (!provider || !provider->configs || provider->num_configs == 0)
+ return -EINVAL;
+
+ for (i = 0; i < provider->num_configs; i++) {
+ if (provider->configs[i].rate >= rate) {
+ config = &provider->configs[i];
+ break;
+ }
+ }
+
+ if (i == provider->num_configs)
+ config = &provider->configs[i - 1];
+
+ old_idx = tegra210_clk_emc_get_parent(hw);
+ new_idx = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
+
+ old = clk_hw_get_parent_by_index(hw, old_idx);
+ new = clk_hw_get_parent_by_index(hw, new_idx);
+
+ /* if the rate has changed... */
+ if (config->parent_rate != clk_hw_get_rate(old)) {
+ /* ... but the clock source remains the same ... */
+ if (new_idx == old_idx) {
+ /* ... switch to the alternative clock source. */
+ switch (new_idx) {
+ case CLK_SRC_PLLM:
+ new_idx = CLK_SRC_PLLMB;
+ break;
+
+ case CLK_SRC_PLLM_UD:
+ new_idx = CLK_SRC_PLLMB_UD;
+ break;
+
+ case CLK_SRC_PLLMB_UD:
+ new_idx = CLK_SRC_PLLM_UD;
+ break;
+
+ case CLK_SRC_PLLMB:
+ new_idx = CLK_SRC_PLLM;
+ break;
+ }
+
+ /*
+ * This should never happen because we can't deal with
+ * it.
+ */
+ if (WARN_ON(new_idx == old_idx))
+ return -EINVAL;
+
+ new = clk_hw_get_parent_by_index(hw, new_idx);
+ }
+
+ index = new_idx;
+ parent = new;
+ } else {
+ index = old_idx;
+ parent = old;
+ }
+
+ clk = tegra210_clk_emc_find_parent(emc, index);
+ if (IS_ERR(clk)) {
+ err = PTR_ERR(clk);
+ dev_err(dev, "failed to get parent clock for index %u: %d\n",
+ index, err);
+ return err;
+ }
+
+ /* set the new parent clock to the required rate */
+ if (clk_get_rate(clk) != config->parent_rate) {
+ err = clk_set_rate(clk, config->parent_rate);
+ if (err < 0) {
+ dev_err(dev, "failed to set rate %lu Hz for %pC: %d\n",
+ config->parent_rate, clk, err);
+ return err;
+ }
+ }
+
+ /* enable the new parent clock */
+ if (parent != old) {
+ err = clk_prepare_enable(clk);
+ if (err < 0) {
+ dev_err(dev, "failed to enable parent clock %pC: %d\n",
+ clk, err);
+ return err;
+ }
+ }
+
+ /* update the EMC source configuration to reflect the new parent */
+ config->value &= ~CLK_SOURCE_EMC_2X_CLK_SRC;
+ config->value |= FIELD_PREP(CLK_SOURCE_EMC_2X_CLK_SRC, index);
+
+ /*
+ * Finally, switch the EMC programming with both old and new parent
+ * clocks enabled.
+ */
+ err = provider->set_rate(dev, config);
+ if (err < 0) {
+ dev_err(dev, "failed to set EMC rate to %lu Hz: %d\n", rate,
+ err);
+
+ /*
+ * If we're unable to switch to the new EMC frequency, we no
+ * longer need the new parent to be enabled.
+ */
+ if (parent != old)
+ clk_disable_unprepare(clk);
+
+ return err;
+ }
+
+ /* reparent to new parent clock and disable the old parent clock */
+ if (parent != old) {
+ clk = tegra210_clk_emc_find_parent(emc, old_idx);
+ if (IS_ERR(clk)) {
+ err = PTR_ERR(clk);
+ dev_err(dev,
+ "failed to get parent clock for index %u: %d\n",
+ old_idx, err);
+ return err;
+ }
+
+ clk_hw_reparent(hw, parent);
+ clk_disable_unprepare(clk);
+ }
+
+ return err;
+}
+
+static const struct clk_ops tegra210_clk_emc_ops = {
+ .get_parent = tegra210_clk_emc_get_parent,
+ .recalc_rate = tegra210_clk_emc_recalc_rate,
+ .round_rate = tegra210_clk_emc_round_rate,
+ .set_rate = tegra210_clk_emc_set_rate,
+};
+
+struct clk *tegra210_clk_register_emc(struct device_node *np,
+ void __iomem *regs)
+{
+ struct tegra210_clk_emc *emc;
+ struct clk_init_data init;
+ struct clk *clk;
+
+ emc = kzalloc(sizeof(*emc), GFP_KERNEL);
+ if (!emc)
+ return ERR_PTR(-ENOMEM);
+
+ emc->regs = regs;
+
+ init.name = "emc";
+ init.ops = &tegra210_clk_emc_ops;
+ init.flags = CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE;
+ init.parent_names = tegra210_clk_emc_parents;
+ init.num_parents = ARRAY_SIZE(tegra210_clk_emc_parents);
+ emc->hw.init = &init;
+
+ clk = clk_register(NULL, &emc->hw);
+ if (IS_ERR(clk)) {
+ kfree(emc);
+ return clk;
+ }
+
+ return clk;
+}
+
+int tegra210_clk_emc_attach(struct clk *clk,
+ struct tegra210_clk_emc_provider *provider)
+{
+ struct clk_hw *hw = __clk_get_hw(clk);
+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+ struct device *dev = provider->dev;
+ unsigned int i;
+ int err;
+
+ if (!try_module_get(provider->owner))
+ return -ENODEV;
+
+ for (i = 0; i < provider->num_configs; i++) {
+ struct tegra210_clk_emc_config *config = &provider->configs[i];
+ struct clk_hw *parent;
+ bool same_freq;
+ u8 div, src;
+
+ div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, config->value);
+ src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
+
+ /* do basic sanity checking on the EMC timings */
+ if (div & 0x1) {
+ dev_err(dev, "invalid odd divider %u for rate %lu Hz\n",
+ div, config->rate);
+ err = -EINVAL;
+ goto put;
+ }
+
+ same_freq = config->value & CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
+
+ if (same_freq != config->same_freq) {
+ dev_err(dev,
+ "ambiguous EMC to MC ratio for rate %lu Hz\n",
+ config->rate);
+ err = -EINVAL;
+ goto put;
+ }
+
+ parent = clk_hw_get_parent_by_index(hw, src);
+ config->parent = src;
+
+ if (src == CLK_SRC_PLLM || src == CLK_SRC_PLLM_UD) {
+ config->parent_rate = config->rate * (1 + div / 2);
+ } else {
+ unsigned long rate = config->rate * (1 + div / 2);
+
+ config->parent_rate = clk_hw_get_rate(parent);
+
+ if (config->parent_rate != rate) {
+ dev_err(dev,
+ "rate %lu Hz does not match input\n",
+ config->rate);
+ err = -EINVAL;
+ goto put;
+ }
+ }
+ }
+
+ emc->provider = provider;
+
+ return 0;
+
+put:
+ module_put(provider->owner);
+ return err;
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_attach);
+
+void tegra210_clk_emc_detach(struct clk *clk)
+{
+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(__clk_get_hw(clk));
+
+ module_put(emc->provider->owner);
+ emc->provider = NULL;
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_detach);
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index defe3b7ebfa4..68cbb98af567 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -37,6 +37,7 @@
#define CLK_SOURCE_LA 0x1f8
#define CLK_SOURCE_SDMMC2 0x154
#define CLK_SOURCE_SDMMC4 0x164
+#define CLK_SOURCE_EMC_DLL 0x664
#define PLLC_BASE 0x80
#define PLLC_OUT 0x84
@@ -227,6 +228,10 @@
#define RST_DFLL_DVCO 0x2f4
#define DVFS_DFLL_RESET_SHIFT 0
+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET 0x284
+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR 0x288
+#define CLK_OUT_ENB_X_CLK_ENB_EMC_DLL BIT(14)
+
#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
#define CPU_SOFTRST_CTRL 0x380
@@ -314,12 +319,6 @@ static unsigned long tegra210_input_freq[] = {
[8] = 12000000,
};
-static const char *mux_pllmcp_clkm[] = {
- "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb", "pll_mb",
- "pll_p",
-};
-#define mux_pllmcp_clkm_idx NULL
-
#define PLL_ENABLE (1 << 30)
#define PLLCX_MISC1_IDDQ (1 << 27)
@@ -555,6 +554,27 @@ void tegra210_set_sata_pll_seq_sw(bool state)
}
EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
+void tegra210_clk_emc_dll_enable(bool flag)
+{
+ u32 offset = flag ? CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET :
+ CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR;
+
+ writel_relaxed(CLK_OUT_ENB_X_CLK_ENB_EMC_DLL, clk_base + offset);
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_enable);
+
+void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value)
+{
+ writel_relaxed(emc_dll_src_value, clk_base + CLK_SOURCE_EMC_DLL);
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_update_setting);
+
+void tegra210_clk_emc_update_setting(u32 emc_src_value)
+{
+ writel_relaxed(emc_src_value, clk_base + CLK_SOURCE_EMC);
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_update_setting);
+
static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
{
u32 val;
@@ -2310,7 +2330,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
[tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true },
[tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true },
[tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true },
- [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true },
[tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true },
[tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true },
[tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true },
@@ -2953,6 +2972,27 @@ static const char * const sor1_parents[] = {
static u32 sor1_parents_idx[] = { 0, 2, 5, 6 };
+static const struct clk_div_table mc_div_table_tegra210[] = {
+ { .val = 0, .div = 2 },
+ { .val = 1, .div = 4 },
+ { .val = 2, .div = 1 },
+ { .val = 3, .div = 2 },
+ { .val = 0, .div = 0 },
+};
+
+static void tegra210_clk_register_mc(const char *name,
+ const char *parent_name)
+{
+ struct clk *clk;
+
+ clk = clk_register_divider_table(NULL, name, parent_name,
+ CLK_IS_CRITICAL,
+ clk_base + CLK_SOURCE_EMC,
+ 15, 2, CLK_DIVIDER_READ_ONLY,
+ mc_div_table_tegra210, &emc_lock);
+ clks[TEGRA210_CLK_MC] = clk;
+}
+
static const char * const sor1_out_parents[] = {
/*
* Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so
@@ -2995,7 +3035,8 @@ static const char * const la_parents[] = {
static struct tegra_clk_periph tegra210_la =
TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, NULL);
-static __init void tegra210_periph_clk_init(void __iomem *clk_base,
+static __init void tegra210_periph_clk_init(struct device_node *np,
+ void __iomem *clk_base,
void __iomem *pmc_base)
{
struct clk *clk;
@@ -3035,22 +3076,19 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
periph_clk_enb_refcnt);
clks[TEGRA210_CLK_DSIB] = clk;
+ /* csi_tpg */
+ clk = clk_register_gate(NULL, "csi_tpg", "pll_d",
+ CLK_SET_RATE_PARENT, clk_base + PLLD_BASE,
+ 23, 0, &pll_d_lock);
+ clk_register_clkdev(clk, "csi_tpg", NULL);
+ clks[TEGRA210_CLK_CSI_TPG] = clk;
+
/* la */
clk = tegra_clk_register_periph("la", la_parents,
ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
CLK_SOURCE_LA, 0);
clks[TEGRA210_CLK_LA] = clk;
- /* emc mux */
- clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
- ARRAY_SIZE(mux_pllmcp_clkm), 0,
- clk_base + CLK_SOURCE_EMC,
- 29, 3, 0, &emc_lock);
-
- clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
- &emc_lock);
- clks[TEGRA210_CLK_MC] = clk;
-
/* cml0 */
clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
0, 0, &pll_e_lock);
@@ -3093,6 +3131,13 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
}
tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
+
+ /* emc */
+ clk = tegra210_clk_register_emc(np, clk_base);
+ clks[TEGRA210_CLK_EMC] = clk;
+
+ /* mc */
+ tegra210_clk_register_mc("mc", "emc");
}
static void __init tegra210_pll_init(void __iomem *clk_base,
@@ -3153,6 +3198,17 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
clk_register_clkdev(clk, "pll_m_ud", NULL);
clks[TEGRA210_CLK_PLL_M_UD] = clk;
+ /* PLLMB_UD */
+ clk = clk_register_fixed_factor(NULL, "pll_mb_ud", "pll_mb",
+ CLK_SET_RATE_PARENT, 1, 1);
+ clk_register_clkdev(clk, "pll_mb_ud", NULL);
+ clks[TEGRA210_CLK_PLL_MB_UD] = clk;
+
+ /* PLLP_UD */
+ clk = clk_register_fixed_factor(NULL, "pll_p_ud", "pll_p",
+ 0, 1, 1);
+ clks[TEGRA210_CLK_PLL_P_UD] = clk;
+
/* PLLU_VCO */
if (!tegra210_init_pllu()) {
clk = clk_register_fixed_rate(NULL, "pll_u_vco", "pll_ref", 0,
@@ -3680,7 +3736,7 @@ static void __init tegra210_clock_init(struct device_node *np)
tegra_fixed_clk_init(tegra210_clks);
tegra210_pll_init(clk_base, pmc_base);
- tegra210_periph_clk_init(clk_base, pmc_base);
+ tegra210_periph_clk_init(np, clk_base, pmc_base);
tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
tegra210_audio_plls,
ARRAY_SIZE(tegra210_audio_plls), 24576000);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 3255f82e61b5..37244a7e68c2 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -499,6 +499,8 @@ static struct tegra_clk_pll_params pll_x_params __ro_after_init = {
.freq_table = pll_x_freq_table,
.flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON |
TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
+ .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
+ .post_rate_change = tegra_cclk_post_pllx_rate_change,
};
static struct tegra_clk_pll_params pll_e_params __ro_after_init = {
@@ -926,11 +928,11 @@ static void __init tegra30_super_clk_init(void)
clk_register_clkdev(clk, "pll_p_out4_cclkg", NULL);
/* CCLKG */
- clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
+ clk = tegra_clk_register_super_cclk("cclk_g", cclk_g_parents,
ARRAY_SIZE(cclk_g_parents),
CLK_SET_RATE_PARENT,
clk_base + CCLKG_BURST_POLICY,
- 0, 4, 0, 0, NULL);
+ 0, NULL);
clks[TEGRA30_CLK_CCLK_G] = clk;
/*
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 2c9a68302e02..6b565f6b5f66 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -266,6 +266,10 @@ struct tegra_clk_pll;
* disabled.
* @dyn_ramp: Callback which can be used to define a custom
* dynamic ramp function for a given PLL.
+ * @pre_rate_change: Callback which is invoked just before changing
+ * PLL's rate.
+ * @post_rate_change: Callback which is invoked right after changing
+ * PLL's rate.
*
* Flags:
* TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
@@ -342,6 +346,8 @@ struct tegra_clk_pll_params {
void (*set_defaults)(struct tegra_clk_pll *pll);
int (*dyn_ramp)(struct tegra_clk_pll *pll,
struct tegra_clk_pll_freq_table *cfg);
+ int (*pre_rate_change)(void);
+ void (*post_rate_change)(void);
};
#define TEGRA_PLL_USE_LOCK BIT(0)
@@ -729,8 +735,10 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
* TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
* that this is LP cluster clock.
* TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
- * super mux parent using PLLP branches. To use PLLP branches to CPU, need
- * to configure additional bit PLLP_OUT_CPU in the clock registers.
+ * super mux parent using PLLP branches. To use PLLP branches to CPU, need
+ * to configure additional bit PLLP_OUT_CPU in the clock registers.
+ * TEGRA20_SUPER_CLK - Tegra20 doesn't have a dedicated divider for Super
+ * clocks, it only has a clock-skipper.
*/
struct tegra_clk_super_mux {
struct clk_hw hw;
@@ -748,6 +756,7 @@ struct tegra_clk_super_mux {
#define TEGRA_DIVIDER_2 BIT(0)
#define TEGRA210_CPU_CLK BIT(1)
+#define TEGRA20_SUPER_CLK BIT(2)
extern const struct clk_ops tegra_clk_super_ops;
struct clk *tegra_clk_register_super_mux(const char *name,
@@ -758,6 +767,12 @@ struct clk *tegra_clk_register_super_clk(const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags, void __iomem *reg, u8 clk_super_flags,
spinlock_t *lock);
+struct clk *tegra_clk_register_super_cclk(const char *name,
+ const char * const *parent_names, u8 num_parents,
+ unsigned long flags, void __iomem *reg, u8 clk_super_flags,
+ spinlock_t *lock);
+int tegra_cclk_pre_pllx_rate_change(void);
+void tegra_cclk_post_pllx_rate_change(void);
/**
* struct tegra_sdmmc_mux - switch divider with Low Jitter inputs for SDMMC
@@ -866,7 +881,7 @@ void tegra_super_clk_gen5_init(void __iomem *clk_base,
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
-#ifdef CONFIG_TEGRA_CLK_EMC
+#ifdef CONFIG_TEGRA124_EMC
struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
spinlock_t *lock);
#else
@@ -907,4 +922,7 @@ void tegra_clk_periph_resume(void);
bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw);
struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
+struct clk *tegra210_clk_register_emc(struct device_node *np,
+ void __iomem *regs);
+
#endif /* TEGRA_CLK_H */
diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index d913d8663f73..4972912307ef 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -3,5 +3,5 @@ config COMMON_CLK_TI_ADPLL
tristate "Clock driver for dm814x ADPLL"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
default y if SOC_TI81XX
- ---help---
+ help
ADPLL clock driver for the dm814x SoC using common clock framework.
diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c
index 312a20f8ec0e..a38c92153979 100644
--- a/drivers/clk/ti/clk-44xx.c
+++ b/drivers/clk/ti/clk-44xx.c
@@ -606,13 +606,13 @@ static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initcons
static const struct
omap_clkctrl_reg_data omap4_l4_secure_clkctrl_regs[] __initconst = {
- { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "" },
- { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "" },
- { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "" },
- { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
- { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
- { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "" },
- { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+ { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
+ { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
+ { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "l4_div_ck" },
+ { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_div_ck" },
+ { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_div_ck" },
+ { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
+ { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_div_ck" },
{ 0 },
};
diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c
index 92bf2dda95b9..8694bc9f5fc7 100644
--- a/drivers/clk/ti/clk-54xx.c
+++ b/drivers/clk/ti/clk-54xx.c
@@ -303,13 +303,13 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst
static const struct
omap_clkctrl_reg_data omap5_l4_secure_clkctrl_regs[] __initconst = {
- { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "" },
- { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "" },
- { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "" },
- { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
- { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
- { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "" },
- { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+ { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+ { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+ { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
+ { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" },
+ { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
+ { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+ { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_iclk_div" },
{ 0 },
};
diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index 14b645093107..b4cf578a69e1 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -312,15 +312,6 @@ static const char * const dra7_gpu_hyd_mux_parents[] __initconst = {
NULL,
};
-static const char * const dra7_gpu_sys_clk_parents[] __initconst = {
- "sys_clkin",
- NULL,
-};
-
-static const struct omap_clkctrl_div_data dra7_gpu_sys_clk_data __initconst = {
- .max_div = 2,
-};
-
static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst = {
{ 24, TI_CLK_MUX, dra7_gpu_core_mux_parents, NULL, },
{ 26, TI_CLK_MUX, dra7_gpu_hyd_mux_parents, NULL, },
@@ -328,7 +319,7 @@ static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst =
};
static const struct omap_clkctrl_reg_data dra7_gpu_clkctrl_regs[] __initconst = {
- { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu_cm:clk:0000:24", },
+ { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu-clkctrl:0000:24", },
{ 0 },
};
@@ -644,7 +635,7 @@ static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst
{ DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
{ DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
{ DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
- { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+ { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
{ DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
{ 0 },
};
@@ -815,7 +806,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons
{ DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
{ DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" },
{ DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" },
- { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk" },
+ { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SOC_DRA76, "mcan_clk" },
{ 0 },
};
diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
index 6a89936ba03a..eaa43575cfa5 100644
--- a/drivers/clk/ti/composite.c
+++ b/drivers/clk/ti/composite.c
@@ -196,6 +196,7 @@ cleanup:
if (!cclk->comp_clks[i])
continue;
list_del(&cclk->comp_clks[i]->link);
+ kfree(cclk->comp_clks[i]->parent_names);
kfree(cclk->comp_clks[i]);
}
diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig
index 8c1b0e8e8d32..91f0ff54237d 100644
--- a/drivers/clk/versatile/Kconfig
+++ b/drivers/clk/versatile/Kconfig
@@ -7,7 +7,7 @@ menu "Clock driver for ARM Reference designs"
config ICST
bool "Clock driver for ARM Reference designs ICST"
select REGMAP_MMIO
- ---help---
+ help
Supports clocking on ARM Reference designs:
- Integrator/AP and Integrator/CP
- RealView PB1176, EB, PB11MP and PBX
@@ -15,7 +15,7 @@ config ICST
config CLK_SP810
bool "Clock driver for ARM SP810 System Controller"
default y if (ARCH_VEXPRESS && ARM)
- ---help---
+ help
Supports clock muxing (REFCLK/TIMCLK to TIMERCLKEN0-3) capabilities
of the ARM SP810 System Controller cell.
@@ -24,7 +24,7 @@ config CLK_VEXPRESS_OSC
depends on VEXPRESS_CONFIG
select REGMAP_MMIO
default y if ARCH_VEXPRESS
- ---help---
+ help
Simple regmap-based driver driving clock generators on Versatile
Express platforms hidden behind its configuration infrastructure,
commonly known as OSCs.
diff --git a/drivers/clk/versatile/clk-versatile.c b/drivers/clk/versatile/clk-versatile.c
index fd54d5c0251c..8ed7a179f651 100644
--- a/drivers/clk/versatile/clk-versatile.c
+++ b/drivers/clk/versatile/clk-versatile.c
@@ -56,7 +56,7 @@ static const struct clk_icst_desc versatile_auxosc_desc __initconst = {
static void __init cm_osc_setup(struct device_node *np,
const struct clk_icst_desc *desc)
{
- struct clk *clk = ERR_PTR(-EINVAL);
+ struct clk *clk;
const char *clk_name = np->name;
const char *parent_name;
diff --git a/drivers/clk/x86/Kconfig b/drivers/clk/x86/Kconfig
new file mode 100644
index 000000000000..69642e15fcc1
--- /dev/null
+++ b/drivers/clk/x86/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config CLK_LGM_CGU
+ depends on OF && HAS_IOMEM && (X86 || COMPILE_TEST)
+ select OF_EARLY_FLATTREE
+ bool "Clock driver for Lightning Mountain(LGM) platform"
+ help
+ Clock Generation Unit(CGU) driver for Intel Lightning Mountain(LGM)
+ network processor SoC.
diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
index e3ec81e2a1c2..7c774ea7ddeb 100644
--- a/drivers/clk/x86/Makefile
+++ b/drivers/clk/x86/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o
obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE) += clk-st.o
clk-x86-lpss-objs := clk-lpt.o
obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o
+obj-$(CONFIG_CLK_LGM_CGU) += clk-cgu.o clk-cgu-pll.o clk-lgm.o
diff --git a/drivers/clk/x86/clk-cgu-pll.c b/drivers/clk/x86/clk-cgu-pll.c
new file mode 100644
index 000000000000..c03cc6b85b9f
--- /dev/null
+++ b/drivers/clk/x86/clk-cgu-pll.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel Corporation.
+ * Zhu YiXin <yixin.zhu@intel.com>
+ * Rahul Tanwar <rahul.tanwar@intel.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/iopoll.h>
+#include <linux/of.h>
+
+#include "clk-cgu.h"
+
+#define to_lgm_clk_pll(_hw) container_of(_hw, struct lgm_clk_pll, hw)
+#define PLL_REF_DIV(x) ((x) + 0x08)
+
+/*
+ * Calculate formula:
+ * rate = (prate * mult + (prate * frac) / frac_div) / div
+ */
+static unsigned long
+lgm_pll_calc_rate(unsigned long prate, unsigned int mult,
+ unsigned int div, unsigned int frac, unsigned int frac_div)
+{
+ u64 crate, frate, rate64;
+
+ rate64 = prate;
+ crate = rate64 * mult;
+ frate = rate64 * frac;
+ do_div(frate, frac_div);
+ crate += frate;
+ do_div(crate, div);
+
+ return crate;
+}
+
+static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
+{
+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
+ unsigned int div, mult, frac;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12);
+ div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6);
+ frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24);
+ spin_unlock_irqrestore(&pll->lock, flags);
+
+ if (pll->type == TYPE_LJPLL)
+ div *= 4;
+
+ return lgm_pll_calc_rate(prate, mult, div, frac, BIT(24));
+}
+
+static int lgm_pll_is_enabled(struct clk_hw *hw)
+{
+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
+ unsigned long flags;
+ unsigned int ret;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1);
+ spin_unlock_irqrestore(&pll->lock, flags);
+
+ return ret;
+}
+
+static int lgm_pll_enable(struct clk_hw *hw)
+{
+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
+ unsigned long flags;
+ u32 val;
+ int ret;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1);
+ ret = readl_poll_timeout_atomic(pll->membase + pll->reg,
+ val, (val & 0x1), 1, 100);
+ spin_unlock_irqrestore(&pll->lock, flags);
+
+ return ret;
+}
+
+static void lgm_pll_disable(struct clk_hw *hw)
+{
+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&pll->lock, flags);
+ lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0);
+ spin_unlock_irqrestore(&pll->lock, flags);
+}
+
+static const struct clk_ops lgm_pll_ops = {
+ .recalc_rate = lgm_pll_recalc_rate,
+ .is_enabled = lgm_pll_is_enabled,
+ .enable = lgm_pll_enable,
+ .disable = lgm_pll_disable,
+};
+
+static struct clk_hw *
+lgm_clk_register_pll(struct lgm_clk_provider *ctx,
+ const struct lgm_pll_clk_data *list)
+{
+ struct clk_init_data init = {};
+ struct lgm_clk_pll *pll;
+ struct device *dev = ctx->dev;
+ struct clk_hw *hw;
+ int ret;
+
+ init.ops = &lgm_pll_ops;
+ init.name = list->name;
+ init.flags = list->flags;
+ init.parent_data = list->parent_data;
+ init.num_parents = list->num_parents;
+
+ pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->membase = ctx->membase;
+ pll->lock = ctx->lock;
+ pll->reg = list->reg;
+ pll->flags = list->flags;
+ pll->type = list->type;
+ pll->hw.init = &init;
+
+ hw = &pll->hw;
+ ret = clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return hw;
+}
+
+int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
+ const struct lgm_pll_clk_data *list,
+ unsigned int nr_clk)
+{
+ struct clk_hw *hw;
+ int i;
+
+ for (i = 0; i < nr_clk; i++, list++) {
+ hw = lgm_clk_register_pll(ctx, list);
+ if (IS_ERR(hw)) {
+ dev_err(ctx->dev, "failed to register pll: %s\n",
+ list->name);
+ return PTR_ERR(hw);
+ }
+ ctx->clk_data.hws[list->id] = hw;
+ }
+
+ return 0;
+}
diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c
new file mode 100644
index 000000000000..56af0e04ec1e
--- /dev/null
+++ b/drivers/clk/x86/clk-cgu.c
@@ -0,0 +1,636 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel Corporation.
+ * Zhu YiXin <yixin.zhu@intel.com>
+ * Rahul Tanwar <rahul.tanwar@intel.com>
+ */
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/of.h>
+
+#include "clk-cgu.h"
+
+#define GATE_HW_REG_STAT(reg) ((reg) + 0x0)
+#define GATE_HW_REG_EN(reg) ((reg) + 0x4)
+#define GATE_HW_REG_DIS(reg) ((reg) + 0x8)
+#define MAX_DDIV_REG 8
+#define MAX_DIVIDER_VAL 64
+
+#define to_lgm_clk_mux(_hw) container_of(_hw, struct lgm_clk_mux, hw)
+#define to_lgm_clk_divider(_hw) container_of(_hw, struct lgm_clk_divider, hw)
+#define to_lgm_clk_gate(_hw) container_of(_hw, struct lgm_clk_gate, hw)
+#define to_lgm_clk_ddiv(_hw) container_of(_hw, struct lgm_clk_ddiv, hw)
+
+static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list)
+{
+ unsigned long flags;
+
+ if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
+ spin_lock_irqsave(&ctx->lock, flags);
+ lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
+ list->div_width, list->div_val);
+ spin_unlock_irqrestore(&ctx->lock, flags);
+ }
+
+ return clk_hw_register_fixed_rate(NULL, list->name,
+ list->parent_data[0].name,
+ list->flags, list->mux_flags);
+}
+
+static u8 lgm_clk_mux_get_parent(struct clk_hw *hw)
+{
+ struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&mux->lock, flags);
+ if (mux->flags & MUX_CLK_SW)
+ val = mux->reg;
+ else
+ val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift,
+ mux->width);
+ spin_unlock_irqrestore(&mux->lock, flags);
+ return clk_mux_val_to_index(hw, NULL, mux->flags, val);
+}
+
+static int lgm_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
+ unsigned long flags;
+ u32 val;
+
+ val = clk_mux_index_to_val(NULL, mux->flags, index);
+ spin_lock_irqsave(&mux->lock, flags);
+ if (mux->flags & MUX_CLK_SW)
+ mux->reg = val;
+ else
+ lgm_set_clk_val(mux->membase, mux->reg, mux->shift,
+ mux->width, val);
+ spin_unlock_irqrestore(&mux->lock, flags);
+
+ return 0;
+}
+
+static int lgm_clk_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
+
+ return clk_mux_determine_rate_flags(hw, req, mux->flags);
+}
+
+static const struct clk_ops lgm_clk_mux_ops = {
+ .get_parent = lgm_clk_mux_get_parent,
+ .set_parent = lgm_clk_mux_set_parent,
+ .determine_rate = lgm_clk_mux_determine_rate,
+};
+
+static struct clk_hw *
+lgm_clk_register_mux(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list)
+{
+ unsigned long flags, cflags = list->mux_flags;
+ struct device *dev = ctx->dev;
+ u8 shift = list->mux_shift;
+ u8 width = list->mux_width;
+ struct clk_init_data init = {};
+ struct lgm_clk_mux *mux;
+ u32 reg = list->mux_off;
+ struct clk_hw *hw;
+ int ret;
+
+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = list->name;
+ init.ops = &lgm_clk_mux_ops;
+ init.flags = list->flags;
+ init.parent_data = list->parent_data;
+ init.num_parents = list->num_parents;
+
+ mux->membase = ctx->membase;
+ mux->lock = ctx->lock;
+ mux->reg = reg;
+ mux->shift = shift;
+ mux->width = width;
+ mux->flags = cflags;
+ mux->hw.init = &init;
+
+ hw = &mux->hw;
+ ret = clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (cflags & CLOCK_FLAG_VAL_INIT) {
+ spin_lock_irqsave(&mux->lock, flags);
+ lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val);
+ spin_unlock_irqrestore(&mux->lock, flags);
+ }
+
+ return hw;
+}
+
+static unsigned long
+lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
+ unsigned long flags;
+ unsigned int val;
+
+ spin_lock_irqsave(&divider->lock, flags);
+ val = lgm_get_clk_val(divider->membase, divider->reg,
+ divider->shift, divider->width);
+ spin_unlock_irqrestore(&divider->lock, flags);
+
+ return divider_recalc_rate(hw, parent_rate, val, divider->table,
+ divider->flags, divider->width);
+}
+
+static long
+lgm_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
+
+ return divider_round_rate(hw, rate, prate, divider->table,
+ divider->width, divider->flags);
+}
+
+static int
+lgm_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate)
+{
+ struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
+ unsigned long flags;
+ int value;
+
+ value = divider_get_val(rate, prate, divider->table,
+ divider->width, divider->flags);
+ if (value < 0)
+ return value;
+
+ spin_lock_irqsave(&divider->lock, flags);
+ lgm_set_clk_val(divider->membase, divider->reg,
+ divider->shift, divider->width, value);
+ spin_unlock_irqrestore(&divider->lock, flags);
+
+ return 0;
+}
+
+static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable)
+{
+ struct lgm_clk_divider *div = to_lgm_clk_divider(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&div->lock, flags);
+ lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
+ div->width_gate, enable);
+ spin_unlock_irqrestore(&div->lock, flags);
+ return 0;
+}
+
+static int lgm_clk_divider_enable(struct clk_hw *hw)
+{
+ return lgm_clk_divider_enable_disable(hw, 1);
+}
+
+static void lgm_clk_divider_disable(struct clk_hw *hw)
+{
+ lgm_clk_divider_enable_disable(hw, 0);
+}
+
+static const struct clk_ops lgm_clk_divider_ops = {
+ .recalc_rate = lgm_clk_divider_recalc_rate,
+ .round_rate = lgm_clk_divider_round_rate,
+ .set_rate = lgm_clk_divider_set_rate,
+ .enable = lgm_clk_divider_enable,
+ .disable = lgm_clk_divider_disable,
+};
+
+static struct clk_hw *
+lgm_clk_register_divider(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list)
+{
+ unsigned long flags, cflags = list->div_flags;
+ struct device *dev = ctx->dev;
+ struct lgm_clk_divider *div;
+ struct clk_init_data init = {};
+ u8 shift = list->div_shift;
+ u8 width = list->div_width;
+ u8 shift_gate = list->div_shift_gate;
+ u8 width_gate = list->div_width_gate;
+ u32 reg = list->div_off;
+ struct clk_hw *hw;
+ int ret;
+
+ div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = list->name;
+ init.ops = &lgm_clk_divider_ops;
+ init.flags = list->flags;
+ init.parent_data = list->parent_data;
+ init.num_parents = 1;
+
+ div->membase = ctx->membase;
+ div->lock = ctx->lock;
+ div->reg = reg;
+ div->shift = shift;
+ div->width = width;
+ div->shift_gate = shift_gate;
+ div->width_gate = width_gate;
+ div->flags = cflags;
+ div->table = list->div_table;
+ div->hw.init = &init;
+
+ hw = &div->hw;
+ ret = clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (cflags & CLOCK_FLAG_VAL_INIT) {
+ spin_lock_irqsave(&div->lock, flags);
+ lgm_set_clk_val(div->membase, reg, shift, width, list->div_val);
+ spin_unlock_irqrestore(&div->lock, flags);
+ }
+
+ return hw;
+}
+
+static struct clk_hw *
+lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list)
+{
+ unsigned long flags;
+ struct clk_hw *hw;
+
+ hw = clk_hw_register_fixed_factor(ctx->dev, list->name,
+ list->parent_data[0].name, list->flags,
+ list->mult, list->div);
+ if (IS_ERR(hw))
+ return ERR_CAST(hw);
+
+ if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
+ spin_lock_irqsave(&ctx->lock, flags);
+ lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
+ list->div_width, list->div_val);
+ spin_unlock_irqrestore(&ctx->lock, flags);
+ }
+
+ return hw;
+}
+
+static int lgm_clk_gate_enable(struct clk_hw *hw)
+{
+ struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
+ unsigned long flags;
+ unsigned int reg;
+
+ spin_lock_irqsave(&gate->lock, flags);
+ reg = GATE_HW_REG_EN(gate->reg);
+ lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
+ spin_unlock_irqrestore(&gate->lock, flags);
+
+ return 0;
+}
+
+static void lgm_clk_gate_disable(struct clk_hw *hw)
+{
+ struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
+ unsigned long flags;
+ unsigned int reg;
+
+ spin_lock_irqsave(&gate->lock, flags);
+ reg = GATE_HW_REG_DIS(gate->reg);
+ lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
+ spin_unlock_irqrestore(&gate->lock, flags);
+}
+
+static int lgm_clk_gate_is_enabled(struct clk_hw *hw)
+{
+ struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
+ unsigned int reg, ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gate->lock, flags);
+ reg = GATE_HW_REG_STAT(gate->reg);
+ ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1);
+ spin_unlock_irqrestore(&gate->lock, flags);
+
+ return ret;
+}
+
+static const struct clk_ops lgm_clk_gate_ops = {
+ .enable = lgm_clk_gate_enable,
+ .disable = lgm_clk_gate_disable,
+ .is_enabled = lgm_clk_gate_is_enabled,
+};
+
+static struct clk_hw *
+lgm_clk_register_gate(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list)
+{
+ unsigned long flags, cflags = list->gate_flags;
+ const char *pname = list->parent_data[0].name;
+ struct device *dev = ctx->dev;
+ u8 shift = list->gate_shift;
+ struct clk_init_data init = {};
+ struct lgm_clk_gate *gate;
+ u32 reg = list->gate_off;
+ struct clk_hw *hw;
+ int ret;
+
+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = list->name;
+ init.ops = &lgm_clk_gate_ops;
+ init.flags = list->flags;
+ init.parent_names = pname ? &pname : NULL;
+ init.num_parents = pname ? 1 : 0;
+
+ gate->membase = ctx->membase;
+ gate->lock = ctx->lock;
+ gate->reg = reg;
+ gate->shift = shift;
+ gate->flags = cflags;
+ gate->hw.init = &init;
+
+ hw = &gate->hw;
+ ret = clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (cflags & CLOCK_FLAG_VAL_INIT) {
+ spin_lock_irqsave(&gate->lock, flags);
+ lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val);
+ spin_unlock_irqrestore(&gate->lock, flags);
+ }
+
+ return hw;
+}
+
+int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list,
+ unsigned int nr_clk)
+{
+ struct clk_hw *hw;
+ unsigned int idx;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ switch (list->type) {
+ case CLK_TYPE_FIXED:
+ hw = lgm_clk_register_fixed(ctx, list);
+ break;
+ case CLK_TYPE_MUX:
+ hw = lgm_clk_register_mux(ctx, list);
+ break;
+ case CLK_TYPE_DIVIDER:
+ hw = lgm_clk_register_divider(ctx, list);
+ break;
+ case CLK_TYPE_FIXED_FACTOR:
+ hw = lgm_clk_register_fixed_factor(ctx, list);
+ break;
+ case CLK_TYPE_GATE:
+ hw = lgm_clk_register_gate(ctx, list);
+ break;
+ default:
+ dev_err(ctx->dev, "invalid clk type\n");
+ return -EINVAL;
+ }
+
+ if (IS_ERR(hw)) {
+ dev_err(ctx->dev,
+ "register clk: %s, type: %u failed!\n",
+ list->name, list->type);
+ return -EIO;
+ }
+ ctx->clk_data.hws[list->id] = hw;
+ }
+
+ return 0;
+}
+
+static unsigned long
+lgm_clk_ddiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
+ unsigned int div0, div1, exdiv;
+ unsigned long flags;
+ u64 prate;
+
+ spin_lock_irqsave(&ddiv->lock, flags);
+ div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
+ ddiv->shift0, ddiv->width0) + 1;
+ div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
+ ddiv->shift1, ddiv->width1) + 1;
+ exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg,
+ ddiv->shift2, ddiv->width2);
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+
+ prate = (u64)parent_rate;
+ do_div(prate, div0);
+ do_div(prate, div1);
+
+ if (exdiv) {
+ do_div(prate, ddiv->div);
+ prate *= ddiv->mult;
+ }
+
+ return prate;
+}
+
+static int lgm_clk_ddiv_enable(struct clk_hw *hw)
+{
+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ddiv->lock, flags);
+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
+ ddiv->width_gate, 1);
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+ return 0;
+}
+
+static void lgm_clk_ddiv_disable(struct clk_hw *hw)
+{
+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ddiv->lock, flags);
+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
+ ddiv->width_gate, 0);
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+}
+
+static int
+lgm_clk_get_ddiv_val(u32 div, u32 *ddiv1, u32 *ddiv2)
+{
+ u32 idx, temp;
+
+ *ddiv1 = 1;
+ *ddiv2 = 1;
+
+ if (div > MAX_DIVIDER_VAL)
+ div = MAX_DIVIDER_VAL;
+
+ if (div > 1) {
+ for (idx = 2; idx <= MAX_DDIV_REG; idx++) {
+ temp = DIV_ROUND_UP_ULL((u64)div, idx);
+ if (div % idx == 0 && temp <= MAX_DDIV_REG)
+ break;
+ }
+
+ if (idx > MAX_DDIV_REG)
+ return -EINVAL;
+
+ *ddiv1 = temp;
+ *ddiv2 = idx;
+ }
+
+ return 0;
+}
+
+static int
+lgm_clk_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate)
+{
+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
+ u32 div, ddiv1, ddiv2;
+ unsigned long flags;
+
+ div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
+
+ spin_lock_irqsave(&ddiv->lock, flags);
+ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
+ div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
+ div = div * 2;
+ }
+
+ if (div <= 0) {
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+ return -EINVAL;
+ }
+
+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) {
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+ return -EINVAL;
+ }
+
+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0,
+ ddiv1 - 1);
+
+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1,
+ ddiv2 - 1);
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+
+ return 0;
+}
+
+static long
+lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
+ u32 div, ddiv1, ddiv2;
+ unsigned long flags;
+ u64 rate64;
+
+ div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate);
+
+ /* if predivide bit is enabled, modify div by factor of 2.5 */
+ spin_lock_irqsave(&ddiv->lock, flags);
+ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
+ div = div * 2;
+ div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
+ }
+
+ if (div <= 0) {
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+ return *prate;
+ }
+
+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) {
+ if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) {
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+ return -EINVAL;
+ }
+ }
+
+ rate64 = *prate;
+ do_div(rate64, ddiv1);
+ do_div(rate64, ddiv2);
+
+ /* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
+ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
+ rate64 = rate64 * 2;
+ rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
+ }
+ spin_unlock_irqrestore(&ddiv->lock, flags);
+
+ return rate64;
+}
+
+static const struct clk_ops lgm_clk_ddiv_ops = {
+ .recalc_rate = lgm_clk_ddiv_recalc_rate,
+ .enable = lgm_clk_ddiv_enable,
+ .disable = lgm_clk_ddiv_disable,
+ .set_rate = lgm_clk_ddiv_set_rate,
+ .round_rate = lgm_clk_ddiv_round_rate,
+};
+
+int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_ddiv_data *list,
+ unsigned int nr_clk)
+{
+ struct device *dev = ctx->dev;
+ struct clk_init_data init = {};
+ struct lgm_clk_ddiv *ddiv;
+ struct clk_hw *hw;
+ unsigned int idx;
+ int ret;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ ddiv = NULL;
+ ddiv = devm_kzalloc(dev, sizeof(*ddiv), GFP_KERNEL);
+ if (!ddiv)
+ return -ENOMEM;
+
+ memset(&init, 0, sizeof(init));
+ init.name = list->name;
+ init.ops = &lgm_clk_ddiv_ops;
+ init.flags = list->flags;
+ init.parent_data = list->parent_data;
+ init.num_parents = 1;
+
+ ddiv->membase = ctx->membase;
+ ddiv->lock = ctx->lock;
+ ddiv->reg = list->reg;
+ ddiv->shift0 = list->shift0;
+ ddiv->width0 = list->width0;
+ ddiv->shift1 = list->shift1;
+ ddiv->width1 = list->width1;
+ ddiv->shift_gate = list->shift_gate;
+ ddiv->width_gate = list->width_gate;
+ ddiv->shift2 = list->ex_shift;
+ ddiv->width2 = list->ex_width;
+ ddiv->flags = list->div_flags;
+ ddiv->mult = 2;
+ ddiv->div = 5;
+ ddiv->hw.init = &init;
+
+ hw = &ddiv->hw;
+ ret = clk_hw_register(dev, hw);
+ if (ret) {
+ dev_err(dev, "register clk: %s failed!\n", list->name);
+ return ret;
+ }
+ ctx->clk_data.hws[list->id] = hw;
+ }
+
+ return 0;
+}
diff --git a/drivers/clk/x86/clk-cgu.h b/drivers/clk/x86/clk-cgu.h
new file mode 100644
index 000000000000..4e22bfb22312
--- /dev/null
+++ b/drivers/clk/x86/clk-cgu.h
@@ -0,0 +1,335 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ * Zhu YiXin <yixin.zhu@intel.com>
+ * Rahul Tanwar <rahul.tanwar@intel.com>
+ */
+
+#ifndef __CLK_CGU_H
+#define __CLK_CGU_H
+
+#include <linux/io.h>
+
+struct lgm_clk_mux {
+ struct clk_hw hw;
+ void __iomem *membase;
+ unsigned int reg;
+ u8 shift;
+ u8 width;
+ unsigned long flags;
+ spinlock_t lock;
+};
+
+struct lgm_clk_divider {
+ struct clk_hw hw;
+ void __iomem *membase;
+ unsigned int reg;
+ u8 shift;
+ u8 width;
+ u8 shift_gate;
+ u8 width_gate;
+ unsigned long flags;
+ const struct clk_div_table *table;
+ spinlock_t lock;
+};
+
+struct lgm_clk_ddiv {
+ struct clk_hw hw;
+ void __iomem *membase;
+ unsigned int reg;
+ u8 shift0;
+ u8 width0;
+ u8 shift1;
+ u8 width1;
+ u8 shift2;
+ u8 width2;
+ u8 shift_gate;
+ u8 width_gate;
+ unsigned int mult;
+ unsigned int div;
+ unsigned long flags;
+ spinlock_t lock;
+};
+
+struct lgm_clk_gate {
+ struct clk_hw hw;
+ void __iomem *membase;
+ unsigned int reg;
+ u8 shift;
+ unsigned long flags;
+ spinlock_t lock;
+};
+
+enum lgm_clk_type {
+ CLK_TYPE_FIXED,
+ CLK_TYPE_MUX,
+ CLK_TYPE_DIVIDER,
+ CLK_TYPE_FIXED_FACTOR,
+ CLK_TYPE_GATE,
+ CLK_TYPE_NONE,
+};
+
+/**
+ * struct lgm_clk_provider
+ * @membase: IO mem base address for CGU.
+ * @np: device node
+ * @dev: device
+ * @clk_data: array of hw clocks and clk number.
+ */
+struct lgm_clk_provider {
+ void __iomem *membase;
+ struct device_node *np;
+ struct device *dev;
+ struct clk_hw_onecell_data clk_data;
+ spinlock_t lock;
+};
+
+enum pll_type {
+ TYPE_ROPLL,
+ TYPE_LJPLL,
+ TYPE_NONE,
+};
+
+struct lgm_clk_pll {
+ struct clk_hw hw;
+ void __iomem *membase;
+ unsigned int reg;
+ unsigned long flags;
+ enum pll_type type;
+ spinlock_t lock;
+};
+
+/**
+ * struct lgm_pll_clk_data
+ * @id: platform specific id of the clock.
+ * @name: name of this pll clock.
+ * @parent_data: parent clock data.
+ * @num_parents: number of parents.
+ * @flags: optional flags for basic clock.
+ * @type: platform type of pll.
+ * @reg: offset of the register.
+ */
+struct lgm_pll_clk_data {
+ unsigned int id;
+ const char *name;
+ const struct clk_parent_data *parent_data;
+ u8 num_parents;
+ unsigned long flags;
+ enum pll_type type;
+ int reg;
+};
+
+#define LGM_PLL(_id, _name, _pdata, _flags, \
+ _reg, _type) \
+ { \
+ .id = _id, \
+ .name = _name, \
+ .parent_data = _pdata, \
+ .num_parents = ARRAY_SIZE(_pdata), \
+ .flags = _flags, \
+ .reg = _reg, \
+ .type = _type, \
+ }
+
+struct lgm_clk_ddiv_data {
+ unsigned int id;
+ const char *name;
+ const struct clk_parent_data *parent_data;
+ u8 flags;
+ unsigned long div_flags;
+ unsigned int reg;
+ u8 shift0;
+ u8 width0;
+ u8 shift1;
+ u8 width1;
+ u8 shift_gate;
+ u8 width_gate;
+ u8 ex_shift;
+ u8 ex_width;
+};
+
+#define LGM_DDIV(_id, _name, _pname, _flags, _reg, \
+ _shft0, _wdth0, _shft1, _wdth1, \
+ _shft_gate, _wdth_gate, _xshft, _df) \
+ { \
+ .id = _id, \
+ .name = _name, \
+ .parent_data = &(const struct clk_parent_data){ \
+ .fw_name = _pname, \
+ .name = _pname, \
+ }, \
+ .flags = _flags, \
+ .reg = _reg, \
+ .shift0 = _shft0, \
+ .width0 = _wdth0, \
+ .shift1 = _shft1, \
+ .width1 = _wdth1, \
+ .shift_gate = _shft_gate, \
+ .width_gate = _wdth_gate, \
+ .ex_shift = _xshft, \
+ .ex_width = 1, \
+ .div_flags = _df, \
+ }
+
+struct lgm_clk_branch {
+ unsigned int id;
+ enum lgm_clk_type type;
+ const char *name;
+ const struct clk_parent_data *parent_data;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned int mux_off;
+ u8 mux_shift;
+ u8 mux_width;
+ unsigned long mux_flags;
+ unsigned int mux_val;
+ unsigned int div_off;
+ u8 div_shift;
+ u8 div_width;
+ u8 div_shift_gate;
+ u8 div_width_gate;
+ unsigned long div_flags;
+ unsigned int div_val;
+ const struct clk_div_table *div_table;
+ unsigned int gate_off;
+ u8 gate_shift;
+ unsigned long gate_flags;
+ unsigned int gate_val;
+ unsigned int mult;
+ unsigned int div;
+};
+
+/* clock flags definition */
+#define CLOCK_FLAG_VAL_INIT BIT(16)
+#define MUX_CLK_SW BIT(17)
+
+#define LGM_MUX(_id, _name, _pdata, _f, _reg, \
+ _shift, _width, _cf, _v) \
+ { \
+ .id = _id, \
+ .type = CLK_TYPE_MUX, \
+ .name = _name, \
+ .parent_data = _pdata, \
+ .num_parents = ARRAY_SIZE(_pdata), \
+ .flags = _f, \
+ .mux_off = _reg, \
+ .mux_shift = _shift, \
+ .mux_width = _width, \
+ .mux_flags = _cf, \
+ .mux_val = _v, \
+ }
+
+#define LGM_DIV(_id, _name, _pname, _f, _reg, _shift, _width, \
+ _shift_gate, _width_gate, _cf, _v, _dtable) \
+ { \
+ .id = _id, \
+ .type = CLK_TYPE_DIVIDER, \
+ .name = _name, \
+ .parent_data = &(const struct clk_parent_data){ \
+ .fw_name = _pname, \
+ .name = _pname, \
+ }, \
+ .num_parents = 1, \
+ .flags = _f, \
+ .div_off = _reg, \
+ .div_shift = _shift, \
+ .div_width = _width, \
+ .div_shift_gate = _shift_gate, \
+ .div_width_gate = _width_gate, \
+ .div_flags = _cf, \
+ .div_val = _v, \
+ .div_table = _dtable, \
+ }
+
+#define LGM_GATE(_id, _name, _pname, _f, _reg, \
+ _shift, _cf, _v) \
+ { \
+ .id = _id, \
+ .type = CLK_TYPE_GATE, \
+ .name = _name, \
+ .parent_data = &(const struct clk_parent_data){ \
+ .fw_name = _pname, \
+ .name = _pname, \
+ }, \
+ .num_parents = !_pname ? 0 : 1, \
+ .flags = _f, \
+ .gate_off = _reg, \
+ .gate_shift = _shift, \
+ .gate_flags = _cf, \
+ .gate_val = _v, \
+ }
+
+#define LGM_FIXED(_id, _name, _pname, _f, _reg, \
+ _shift, _width, _cf, _freq, _v) \
+ { \
+ .id = _id, \
+ .type = CLK_TYPE_FIXED, \
+ .name = _name, \
+ .parent_data = &(const struct clk_parent_data){ \
+ .fw_name = _pname, \
+ .name = _pname, \
+ }, \
+ .num_parents = !_pname ? 0 : 1, \
+ .flags = _f, \
+ .div_off = _reg, \
+ .div_shift = _shift, \
+ .div_width = _width, \
+ .div_flags = _cf, \
+ .div_val = _v, \
+ .mux_flags = _freq, \
+ }
+
+#define LGM_FIXED_FACTOR(_id, _name, _pname, _f, _reg, \
+ _shift, _width, _cf, _v, _m, _d) \
+ { \
+ .id = _id, \
+ .type = CLK_TYPE_FIXED_FACTOR, \
+ .name = _name, \
+ .parent_data = &(const struct clk_parent_data){ \
+ .fw_name = _pname, \
+ .name = _pname, \
+ }, \
+ .num_parents = 1, \
+ .flags = _f, \
+ .div_off = _reg, \
+ .div_shift = _shift, \
+ .div_width = _width, \
+ .div_flags = _cf, \
+ .div_val = _v, \
+ .mult = _m, \
+ .div = _d, \
+ }
+
+static inline void lgm_set_clk_val(void __iomem *membase, u32 reg,
+ u8 shift, u8 width, u32 set_val)
+{
+ u32 mask = (GENMASK(width - 1, 0) << shift);
+ u32 regval;
+
+ regval = readl(membase + reg);
+ regval = (regval & ~mask) | ((set_val << shift) & mask);
+ writel(regval, membase + reg);
+}
+
+static inline u32 lgm_get_clk_val(void __iomem *membase, u32 reg,
+ u8 shift, u8 width)
+{
+ u32 mask = (GENMASK(width - 1, 0) << shift);
+ u32 val;
+
+ val = readl(membase + reg);
+ val = (val & mask) >> shift;
+
+ return val;
+}
+
+int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_branch *list,
+ unsigned int nr_clk);
+int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
+ const struct lgm_pll_clk_data *list,
+ unsigned int nr_clk);
+int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
+ const struct lgm_clk_ddiv_data *list,
+ unsigned int nr_clk);
+#endif /* __CLK_CGU_H */
diff --git a/drivers/clk/x86/clk-lgm.c b/drivers/clk/x86/clk-lgm.c
new file mode 100644
index 000000000000..020f4e83a5cc
--- /dev/null
+++ b/drivers/clk/x86/clk-lgm.c
@@ -0,0 +1,475 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel Corporation.
+ * Zhu YiXin <yixin.zhu@intel.com>
+ * Rahul Tanwar <rahul.tanwar@intel.com>
+ */
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/intel,lgm-clk.h>
+#include "clk-cgu.h"
+
+#define PLL_DIV_WIDTH 4
+#define PLL_DDIV_WIDTH 3
+
+/* Gate0 clock shift */
+#define G_C55_SHIFT 7
+#define G_QSPI_SHIFT 9
+#define G_EIP197_SHIFT 11
+#define G_VAULT130_SHIFT 12
+#define G_TOE_SHIFT 13
+#define G_SDXC_SHIFT 14
+#define G_EMMC_SHIFT 15
+#define G_SPIDBG_SHIFT 17
+#define G_DMA3_SHIFT 28
+
+/* Gate1 clock shift */
+#define G_DMA0_SHIFT 0
+#define G_LEDC0_SHIFT 1
+#define G_LEDC1_SHIFT 2
+#define G_I2S0_SHIFT 3
+#define G_I2S1_SHIFT 4
+#define G_EBU_SHIFT 5
+#define G_PWM_SHIFT 6
+#define G_I2C0_SHIFT 7
+#define G_I2C1_SHIFT 8
+#define G_I2C2_SHIFT 9
+#define G_I2C3_SHIFT 10
+
+#define G_SSC0_SHIFT 12
+#define G_SSC1_SHIFT 13
+#define G_SSC2_SHIFT 14
+#define G_SSC3_SHIFT 15
+
+#define G_GPTC0_SHIFT 17
+#define G_GPTC1_SHIFT 18
+#define G_GPTC2_SHIFT 19
+#define G_GPTC3_SHIFT 20
+
+#define G_ASC0_SHIFT 22
+#define G_ASC1_SHIFT 23
+#define G_ASC2_SHIFT 24
+#define G_ASC3_SHIFT 25
+
+#define G_PCM0_SHIFT 27
+#define G_PCM1_SHIFT 28
+#define G_PCM2_SHIFT 29
+
+/* Gate2 clock shift */
+#define G_PCIE10_SHIFT 1
+#define G_PCIE11_SHIFT 2
+#define G_PCIE30_SHIFT 3
+#define G_PCIE31_SHIFT 4
+#define G_PCIE20_SHIFT 5
+#define G_PCIE21_SHIFT 6
+#define G_PCIE40_SHIFT 7
+#define G_PCIE41_SHIFT 8
+
+#define G_XPCS0_SHIFT 10
+#define G_XPCS1_SHIFT 11
+#define G_XPCS2_SHIFT 12
+#define G_XPCS3_SHIFT 13
+#define G_SATA0_SHIFT 14
+#define G_SATA1_SHIFT 15
+#define G_SATA2_SHIFT 16
+#define G_SATA3_SHIFT 17
+
+/* Gate3 clock shift */
+#define G_ARCEM4_SHIFT 0
+#define G_IDMAR1_SHIFT 2
+#define G_IDMAT0_SHIFT 3
+#define G_IDMAT1_SHIFT 4
+#define G_IDMAT2_SHIFT 5
+
+#define G_PPV4_SHIFT 8
+#define G_GSWIPO_SHIFT 9
+#define G_CQEM_SHIFT 10
+#define G_XPCS5_SHIFT 14
+#define G_USB1_SHIFT 25
+#define G_USB2_SHIFT 26
+
+
+/* Register definition */
+#define CGU_PLL0CZ_CFG0 0x000
+#define CGU_PLL0CM0_CFG0 0x020
+#define CGU_PLL0CM1_CFG0 0x040
+#define CGU_PLL0B_CFG0 0x060
+#define CGU_PLL1_CFG0 0x080
+#define CGU_PLL2_CFG0 0x0A0
+#define CGU_PLLPP_CFG0 0x0C0
+#define CGU_LJPLL3_CFG0 0x0E0
+#define CGU_LJPLL4_CFG0 0x100
+#define CGU_C55_PCMCR 0x18C
+#define CGU_PCMCR 0x190
+#define CGU_IF_CLK1 0x1A0
+#define CGU_IF_CLK2 0x1A4
+#define CGU_GATE0 0x300
+#define CGU_GATE1 0x310
+#define CGU_GATE2 0x320
+#define CGU_GATE3 0x310
+
+#define PLL_DIV(x) ((x) + 0x04)
+#define PLL_SSC(x) ((x) + 0x10)
+
+#define CLK_NR_CLKS (LGM_GCLK_USB2 + 1)
+
+/*
+ * Below table defines the pair's of regval & effective dividers.
+ * It's more efficient to provide an explicit table due to non-linear
+ * relation between values.
+ */
+static const struct clk_div_table pll_div[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },
+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 5 },
+ { .val = 5, .div = 6 },
+ { .val = 6, .div = 8 },
+ { .val = 7, .div = 10 },
+ { .val = 8, .div = 12 },
+ { .val = 9, .div = 16 },
+ { .val = 10, .div = 20 },
+ { .val = 11, .div = 24 },
+ { .val = 12, .div = 32 },
+ { .val = 13, .div = 40 },
+ { .val = 14, .div = 48 },
+ { .val = 15, .div = 64 },
+ {}
+};
+
+static const struct clk_div_table dcl_div[] = {
+ { .val = 0, .div = 6 },
+ { .val = 1, .div = 12 },
+ { .val = 2, .div = 24 },
+ { .val = 3, .div = 32 },
+ { .val = 4, .div = 48 },
+ { .val = 5, .div = 96 },
+ {}
+};
+
+static const struct clk_parent_data pll_p[] = {
+ { .fw_name = "osc", .name = "osc" },
+};
+static const struct clk_parent_data pllcm_p[] = {
+ { .fw_name = "cpu_cm", .name = "cpu_cm" },
+};
+static const struct clk_parent_data emmc_p[] = {
+ { .fw_name = "emmc4", .name = "emmc4" },
+ { .fw_name = "noc4", .name = "noc4" },
+};
+static const struct clk_parent_data sdxc_p[] = {
+ { .fw_name = "sdxc3", .name = "sdxc3" },
+ { .fw_name = "sdxc2", .name = "sdxc2" },
+};
+static const struct clk_parent_data pcm_p[] = {
+ { .fw_name = "v_docsis", .name = "v_docsis" },
+ { .fw_name = "dcl", .name = "dcl" },
+};
+static const struct clk_parent_data cbphy_p[] = {
+ { .fw_name = "dd_serdes", .name = "dd_serdes" },
+ { .fw_name = "dd_pcie", .name = "dd_pcie" },
+};
+
+static const struct lgm_pll_clk_data lgm_pll_clks[] = {
+ LGM_PLL(LGM_CLK_PLL0CZ, "pll0cz", pll_p, CLK_IGNORE_UNUSED,
+ CGU_PLL0CZ_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_PLL0CM0, "pll0cm0", pllcm_p, CLK_IGNORE_UNUSED,
+ CGU_PLL0CM0_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_PLL0CM1, "pll0cm1", pllcm_p, CLK_IGNORE_UNUSED,
+ CGU_PLL0CM1_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_PLL0B, "pll0b", pll_p, CLK_IGNORE_UNUSED,
+ CGU_PLL0B_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_PLL1, "pll1", pll_p, 0, CGU_PLL1_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_PLL2, "pll2", pll_p, CLK_IGNORE_UNUSED,
+ CGU_PLL2_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_PLLPP, "pllpp", pll_p, 0, CGU_PLLPP_CFG0, TYPE_ROPLL),
+ LGM_PLL(LGM_CLK_LJPLL3, "ljpll3", pll_p, 0, CGU_LJPLL3_CFG0, TYPE_LJPLL),
+ LGM_PLL(LGM_CLK_LJPLL4, "ljpll4", pll_p, 0, CGU_LJPLL4_CFG0, TYPE_LJPLL),
+};
+
+static const struct lgm_clk_branch lgm_branch_clks[] = {
+ LGM_DIV(LGM_CLK_PP_HW, "pp_hw", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_PP_UC, "pp_uc", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
+ 4, PLL_DIV_WIDTH, 25, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_PP_FXD, "pp_fxd", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_PP_TBM, "pp_tbm", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
+ 12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_DDR, "ddr", "pll2", CLK_IGNORE_UNUSED,
+ PLL_DIV(CGU_PLL2_CFG0), 0, PLL_DIV_WIDTH, 24, 1, 0, 0,
+ pll_div),
+ LGM_DIV(LGM_CLK_CM, "cpu_cm", "pll0cz", 0, PLL_DIV(CGU_PLL0CZ_CFG0),
+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
+
+ LGM_DIV(LGM_CLK_IC, "cpu_ic", "pll0cz", CLK_IGNORE_UNUSED,
+ PLL_DIV(CGU_PLL0CZ_CFG0), 4, PLL_DIV_WIDTH, 25,
+ 1, 0, 0, pll_div),
+
+ LGM_DIV(LGM_CLK_SDXC3, "sdxc3", "pll0cz", 0, PLL_DIV(CGU_PLL0CZ_CFG0),
+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
+
+ LGM_DIV(LGM_CLK_CPU0, "cm0", "pll0cm0",
+ CLK_IGNORE_UNUSED, PLL_DIV(CGU_PLL0CM0_CFG0),
+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_CPU1, "cm1", "pll0cm1",
+ CLK_IGNORE_UNUSED, PLL_DIV(CGU_PLL0CM1_CFG0),
+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
+
+ /*
+ * Marking ngi_clk (next generation interconnect) and noc_clk
+ * (network on chip peripheral clk) as critical clocks because
+ * these are shared parent clock sources for many different
+ * peripherals.
+ */
+ LGM_DIV(LGM_CLK_NGI, "ngi", "pll0b",
+ (CLK_IGNORE_UNUSED|CLK_IS_CRITICAL), PLL_DIV(CGU_PLL0B_CFG0),
+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_NOC4, "noc4", "pll0b",
+ (CLK_IGNORE_UNUSED|CLK_IS_CRITICAL), PLL_DIV(CGU_PLL0B_CFG0),
+ 4, PLL_DIV_WIDTH, 25, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_SW, "switch", "pll0b", 0, PLL_DIV(CGU_PLL0B_CFG0),
+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_QSPI, "qspi", "pll0b", 0, PLL_DIV(CGU_PLL0B_CFG0),
+ 12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_CT, "v_ct", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_DSP, "v_dsp", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
+ LGM_DIV(LGM_CLK_VIF, "v_ifclk", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
+ 12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
+
+ LGM_FIXED_FACTOR(LGM_CLK_EMMC4, "emmc4", "sdxc3", 0, 0,
+ 0, 0, 0, 0, 1, 4),
+ LGM_FIXED_FACTOR(LGM_CLK_SDXC2, "sdxc2", "noc4", 0, 0,
+ 0, 0, 0, 0, 1, 4),
+ LGM_MUX(LGM_CLK_EMMC, "emmc", emmc_p, 0, CGU_IF_CLK1,
+ 0, 1, CLK_MUX_ROUND_CLOSEST, 0),
+ LGM_MUX(LGM_CLK_SDXC, "sdxc", sdxc_p, 0, CGU_IF_CLK1,
+ 1, 1, CLK_MUX_ROUND_CLOSEST, 0),
+ LGM_FIXED(LGM_CLK_OSC, "osc", NULL, 0, 0, 0, 0, 0, 40000000, 0),
+ LGM_FIXED(LGM_CLK_SLIC, "slic", NULL, 0, CGU_IF_CLK1,
+ 8, 2, CLOCK_FLAG_VAL_INIT, 8192000, 2),
+ LGM_FIXED(LGM_CLK_DOCSIS, "v_docsis", NULL, 0, 0, 0, 0, 0, 16000000, 0),
+ LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", 0, CGU_PCMCR,
+ 25, 3, 0, 0, 0, 0, dcl_div),
+ LGM_MUX(LGM_CLK_PCM, "pcm", pcm_p, 0, CGU_C55_PCMCR,
+ 0, 1, CLK_MUX_ROUND_CLOSEST, 0),
+ LGM_FIXED_FACTOR(LGM_CLK_DDR_PHY, "ddr_phy", "ddr",
+ CLK_IGNORE_UNUSED, 0,
+ 0, 0, 0, 0, 2, 1),
+ LGM_FIXED_FACTOR(LGM_CLK_PONDEF, "pondef", "dd_pool",
+ CLK_SET_RATE_PARENT, 0, 0, 0, 0, 0, 1, 2),
+ LGM_MUX(LGM_CLK_CBPHY0, "cbphy0", cbphy_p, 0, 0,
+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
+ LGM_MUX(LGM_CLK_CBPHY1, "cbphy1", cbphy_p, 0, 0,
+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
+ LGM_MUX(LGM_CLK_CBPHY2, "cbphy2", cbphy_p, 0, 0,
+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
+ LGM_MUX(LGM_CLK_CBPHY3, "cbphy3", cbphy_p, 0, 0,
+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
+
+ LGM_GATE(LGM_GCLK_C55, "g_c55", NULL, 0, CGU_GATE0,
+ G_C55_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_QSPI, "g_qspi", "qspi", 0, CGU_GATE0,
+ G_QSPI_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_EIP197, "g_eip197", NULL, 0, CGU_GATE0,
+ G_EIP197_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_VAULT, "g_vault130", NULL, 0, CGU_GATE0,
+ G_VAULT130_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_TOE, "g_toe", NULL, 0, CGU_GATE0,
+ G_TOE_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SDXC, "g_sdxc", "sdxc", 0, CGU_GATE0,
+ G_SDXC_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_EMMC, "g_emmc", "emmc", 0, CGU_GATE0,
+ G_EMMC_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SPI_DBG, "g_spidbg", NULL, 0, CGU_GATE0,
+ G_SPIDBG_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_DMA3, "g_dma3", NULL, 0, CGU_GATE0,
+ G_DMA3_SHIFT, 0, 0),
+
+ LGM_GATE(LGM_GCLK_DMA0, "g_dma0", NULL, 0, CGU_GATE1,
+ G_DMA0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_LEDC0, "g_ledc0", NULL, 0, CGU_GATE1,
+ G_LEDC0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_LEDC1, "g_ledc1", NULL, 0, CGU_GATE1,
+ G_LEDC1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_I2S0, "g_i2s0", NULL, 0, CGU_GATE1,
+ G_I2S0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_I2S1, "g_i2s1", NULL, 0, CGU_GATE1,
+ G_I2S1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_EBU, "g_ebu", NULL, 0, CGU_GATE1,
+ G_EBU_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PWM, "g_pwm", NULL, 0, CGU_GATE1,
+ G_PWM_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_I2C0, "g_i2c0", NULL, 0, CGU_GATE1,
+ G_I2C0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_I2C1, "g_i2c1", NULL, 0, CGU_GATE1,
+ G_I2C1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_I2C2, "g_i2c2", NULL, 0, CGU_GATE1,
+ G_I2C2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_I2C3, "g_i2c3", NULL, 0, CGU_GATE1,
+ G_I2C3_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SSC0, "g_ssc0", "noc4", 0, CGU_GATE1,
+ G_SSC0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SSC1, "g_ssc1", "noc4", 0, CGU_GATE1,
+ G_SSC1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SSC2, "g_ssc2", "noc4", 0, CGU_GATE1,
+ G_SSC2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SSC3, "g_ssc3", "noc4", 0, CGU_GATE1,
+ G_SSC3_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_GPTC0, "g_gptc0", "noc4", 0, CGU_GATE1,
+ G_GPTC0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_GPTC1, "g_gptc1", "noc4", 0, CGU_GATE1,
+ G_GPTC1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_GPTC2, "g_gptc2", "noc4", 0, CGU_GATE1,
+ G_GPTC2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_GPTC3, "g_gptc3", "osc", 0, CGU_GATE1,
+ G_GPTC3_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_ASC0, "g_asc0", "noc4", 0, CGU_GATE1,
+ G_ASC0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_ASC1, "g_asc1", "noc4", 0, CGU_GATE1,
+ G_ASC1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_ASC2, "g_asc2", "noc4", 0, CGU_GATE1,
+ G_ASC2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_ASC3, "g_asc3", "osc", 0, CGU_GATE1,
+ G_ASC3_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCM0, "g_pcm0", NULL, 0, CGU_GATE1,
+ G_PCM0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCM1, "g_pcm1", NULL, 0, CGU_GATE1,
+ G_PCM1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCM2, "g_pcm2", NULL, 0, CGU_GATE1,
+ G_PCM2_SHIFT, 0, 0),
+
+ LGM_GATE(LGM_GCLK_PCIE10, "g_pcie10", NULL, 0, CGU_GATE2,
+ G_PCIE10_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE11, "g_pcie11", NULL, 0, CGU_GATE2,
+ G_PCIE11_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE30, "g_pcie30", NULL, 0, CGU_GATE2,
+ G_PCIE30_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE31, "g_pcie31", NULL, 0, CGU_GATE2,
+ G_PCIE31_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE20, "g_pcie20", NULL, 0, CGU_GATE2,
+ G_PCIE20_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE21, "g_pcie21", NULL, 0, CGU_GATE2,
+ G_PCIE21_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE40, "g_pcie40", NULL, 0, CGU_GATE2,
+ G_PCIE40_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PCIE41, "g_pcie41", NULL, 0, CGU_GATE2,
+ G_PCIE41_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_XPCS0, "g_xpcs0", NULL, 0, CGU_GATE2,
+ G_XPCS0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_XPCS1, "g_xpcs1", NULL, 0, CGU_GATE2,
+ G_XPCS1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_XPCS2, "g_xpcs2", NULL, 0, CGU_GATE2,
+ G_XPCS2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_XPCS3, "g_xpcs3", NULL, 0, CGU_GATE2,
+ G_XPCS3_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SATA0, "g_sata0", NULL, 0, CGU_GATE2,
+ G_SATA0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SATA1, "g_sata1", NULL, 0, CGU_GATE2,
+ G_SATA1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SATA2, "g_sata2", NULL, 0, CGU_GATE2,
+ G_SATA2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_SATA3, "g_sata3", NULL, 0, CGU_GATE2,
+ G_SATA3_SHIFT, 0, 0),
+
+ LGM_GATE(LGM_GCLK_ARCEM4, "g_arcem4", NULL, 0, CGU_GATE3,
+ G_ARCEM4_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_IDMAR1, "g_idmar1", NULL, 0, CGU_GATE3,
+ G_IDMAR1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_IDMAT0, "g_idmat0", NULL, 0, CGU_GATE3,
+ G_IDMAT0_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_IDMAT1, "g_idmat1", NULL, 0, CGU_GATE3,
+ G_IDMAT1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_IDMAT2, "g_idmat2", NULL, 0, CGU_GATE3,
+ G_IDMAT2_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_PPV4, "g_ppv4", NULL, 0, CGU_GATE3,
+ G_PPV4_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_GSWIPO, "g_gswipo", "switch", 0, CGU_GATE3,
+ G_GSWIPO_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_CQEM, "g_cqem", "switch", 0, CGU_GATE3,
+ G_CQEM_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_XPCS5, "g_xpcs5", NULL, 0, CGU_GATE3,
+ G_XPCS5_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_USB1, "g_usb1", NULL, 0, CGU_GATE3,
+ G_USB1_SHIFT, 0, 0),
+ LGM_GATE(LGM_GCLK_USB2, "g_usb2", NULL, 0, CGU_GATE3,
+ G_USB2_SHIFT, 0, 0),
+};
+
+
+static const struct lgm_clk_ddiv_data lgm_ddiv_clks[] = {
+ LGM_DDIV(LGM_CLK_CML, "dd_cml", "ljpll3", 0,
+ PLL_DIV(CGU_LJPLL3_CFG0), 0, PLL_DDIV_WIDTH,
+ 3, PLL_DDIV_WIDTH, 24, 1, 29, 0),
+ LGM_DDIV(LGM_CLK_SERDES, "dd_serdes", "ljpll3", 0,
+ PLL_DIV(CGU_LJPLL3_CFG0), 6, PLL_DDIV_WIDTH,
+ 9, PLL_DDIV_WIDTH, 25, 1, 28, 0),
+ LGM_DDIV(LGM_CLK_POOL, "dd_pool", "ljpll3", 0,
+ PLL_DIV(CGU_LJPLL3_CFG0), 12, PLL_DDIV_WIDTH,
+ 15, PLL_DDIV_WIDTH, 26, 1, 28, 0),
+ LGM_DDIV(LGM_CLK_PTP, "dd_ptp", "ljpll3", 0,
+ PLL_DIV(CGU_LJPLL3_CFG0), 18, PLL_DDIV_WIDTH,
+ 21, PLL_DDIV_WIDTH, 27, 1, 28, 0),
+ LGM_DDIV(LGM_CLK_PCIE, "dd_pcie", "ljpll4", 0,
+ PLL_DIV(CGU_LJPLL4_CFG0), 0, PLL_DDIV_WIDTH,
+ 3, PLL_DDIV_WIDTH, 24, 1, 29, 0),
+};
+
+static int lgm_cgu_probe(struct platform_device *pdev)
+{
+ struct lgm_clk_provider *ctx;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ ctx = devm_kzalloc(dev, struct_size(ctx, clk_data.hws, CLK_NR_CLKS),
+ GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->clk_data.num = CLK_NR_CLKS;
+
+ ctx->membase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ctx->membase))
+ return PTR_ERR(ctx->membase);
+
+ ctx->np = np;
+ ctx->dev = dev;
+ spin_lock_init(&ctx->lock);
+
+ ret = lgm_clk_register_plls(ctx, lgm_pll_clks,
+ ARRAY_SIZE(lgm_pll_clks));
+ if (ret)
+ return ret;
+
+ ret = lgm_clk_register_branches(ctx, lgm_branch_clks,
+ ARRAY_SIZE(lgm_branch_clks));
+ if (ret)
+ return ret;
+
+ ret = lgm_clk_register_ddiv(ctx, lgm_ddiv_clks,
+ ARRAY_SIZE(lgm_ddiv_clks));
+ if (ret)
+ return ret;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+ &ctx->clk_data);
+}
+
+static const struct of_device_id of_lgm_cgu_match[] = {
+ { .compatible = "intel,cgu-lgm" },
+ {}
+};
+
+static struct platform_driver lgm_cgu_driver = {
+ .probe = lgm_cgu_probe,
+ .driver = {
+ .name = "cgu-lgm",
+ .of_match_table = of_lgm_cgu_match,
+ },
+};
+builtin_platform_driver(lgm_cgu_driver);
diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
index fec9a15c8786..5beeb41b29fa 100644
--- a/drivers/clk/zynqmp/clk-zynqmp.h
+++ b/drivers/clk/zynqmp/clk-zynqmp.h
@@ -30,6 +30,7 @@ struct clock_topology {
u32 type;
u32 flag;
u32 type_flag;
+ u8 custom_type_flag;
};
struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index 5eed5ce10179..db8d0d7161ce 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -84,6 +84,7 @@ struct name_resp {
struct topology_resp {
#define CLK_TOPOLOGY_TYPE GENMASK(3, 0)
+#define CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS GENMASK(7, 4)
#define CLK_TOPOLOGY_FLAGS GENMASK(23, 8)
#define CLK_TOPOLOGY_TYPE_FLAGS GENMASK(31, 24)
u32 topology[CLK_GET_TOPOLOGY_RESP_WORDS];
@@ -395,6 +396,9 @@ static int __zynqmp_clock_get_topology(struct clock_topology *topology,
topology[*nnodes].type_flag =
FIELD_GET(CLK_TOPOLOGY_TYPE_FLAGS,
response->topology[i]);
+ topology[*nnodes].custom_type_flag =
+ FIELD_GET(CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS,
+ response->topology[i]);
(*nnodes)++;
}
@@ -557,7 +561,7 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
{
int j;
u32 num_nodes, clk_dev_id;
- char *clk_out = NULL;
+ char *clk_out[MAX_NODES];
struct clock_topology *nodes;
struct clk_hw *hw = NULL;
@@ -571,16 +575,16 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
* Intermediate clock names are postfixed with type of clock.
*/
if (j != (num_nodes - 1)) {
- clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name,
+ clk_out[j] = kasprintf(GFP_KERNEL, "%s%s", clk_name,
clk_type_postfix[nodes[j].type]);
} else {
- clk_out = kasprintf(GFP_KERNEL, "%s", clk_name);
+ clk_out[j] = kasprintf(GFP_KERNEL, "%s", clk_name);
}
if (!clk_topology[nodes[j].type])
continue;
- hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id,
+ hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id,
parent_names,
num_parents,
&nodes[j]);
@@ -589,9 +593,12 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
__func__, clk_dev_id, clk_name,
PTR_ERR(hw));
- parent_names[0] = clk_out;
+ parent_names[0] = clk_out[j];
}
- kfree(clk_out);
+
+ for (j = 0; j < num_nodes; j++)
+ kfree(clk_out[j]);
+
return hw;
}
@@ -662,6 +669,11 @@ static void zynqmp_get_clock_info(void)
continue;
clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
+ /* skip query for Invalid clock */
+ ret = zynqmp_is_valid_clock(i);
+ if (ret != CLK_ATTR_VALID)
+ continue;
+
clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;
diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index 8eed715707e3..66da02b83d39 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -25,7 +25,8 @@
#define to_zynqmp_clk_divider(_hw) \
container_of(_hw, struct zynqmp_clk_divider, hw)
-#define CLK_FRAC BIT(13) /* has a fractional parent */
+#define CLK_FRAC BIT(13) /* has a fractional parent */
+#define CUSTOM_FLAG_CLK_FRAC BIT(0) /* has a fractional parent in custom type flag */
/**
* struct zynqmp_clk_divider - adjustable divider clock
@@ -110,23 +111,30 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
static void zynqmp_get_divider2_val(struct clk_hw *hw,
unsigned long rate,
- unsigned long parent_rate,
struct zynqmp_clk_divider *divider,
int *bestdiv)
{
int div1;
int div2;
long error = LONG_MAX;
- struct clk_hw *parent_hw = clk_hw_get_parent(hw);
- struct zynqmp_clk_divider *pdivider = to_zynqmp_clk_divider(parent_hw);
+ unsigned long div1_prate;
+ struct clk_hw *div1_parent_hw;
+ struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw);
+ struct zynqmp_clk_divider *pdivider =
+ to_zynqmp_clk_divider(div2_parent_hw);
if (!pdivider)
return;
+ div1_parent_hw = clk_hw_get_parent(div2_parent_hw);
+ if (!div1_parent_hw)
+ return;
+
+ div1_prate = clk_hw_get_rate(div1_parent_hw);
*bestdiv = 1;
for (div1 = 1; div1 <= pdivider->max_div;) {
for (div2 = 1; div2 <= divider->max_div;) {
- long new_error = ((parent_rate / div1) / div2) - rate;
+ long new_error = ((div1_prate / div1) / div2) - rate;
if (abs(new_error) < abs(error)) {
*bestdiv = div2;
@@ -190,11 +198,13 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
*/
if (div_type == TYPE_DIV2 &&
(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
- zynqmp_get_divider2_val(hw, rate, *prate, divider, &bestdiv);
+ zynqmp_get_divider2_val(hw, rate, divider, &bestdiv);
}
if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
bestdiv = rate % *prate ? 1 : bestdiv;
+
+ bestdiv = min_t(u32, bestdiv, divider->max_div);
*prate = rate * bestdiv;
return rate;
@@ -253,7 +263,7 @@ static const struct clk_ops zynqmp_clk_divider_ops = {
* Return: Maximum divisor of a clock if query data is successful
* U16_MAX in case of query data is not success
*/
-u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type)
+static u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type)
{
struct zynqmp_pm_query_data qdata = {0};
u32 ret_payload[PAYLOAD_ARG_CNT];
@@ -307,7 +317,8 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
init.num_parents = 1;
/* struct clk_divider assignments */
- div->is_frac = !!(nodes->flag & CLK_FRAC);
+ div->is_frac = !!((nodes->flag & CLK_FRAC) |
+ (nodes->custom_type_flag & CUSTOM_FLAG_CLK_FRAC));
div->flags = nodes->type_flag;
div->hw.init = &init;
div->clk_id = clk_id;
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index c4f15c4068c0..9de1dabfb126 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -12,8 +12,11 @@
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/sched_clock.h>
#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
#include <asm/smp.h>
#include <asm/sbi.h>
@@ -39,6 +42,7 @@ static int riscv_clock_next_event(unsigned long delta,
return 0;
}
+static unsigned int riscv_clock_event_irq;
static DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = {
.name = "riscv_timer_clockevent",
.features = CLOCK_EVT_FEAT_ONESHOT,
@@ -74,30 +78,36 @@ static int riscv_timer_starting_cpu(unsigned int cpu)
struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu);
ce->cpumask = cpumask_of(cpu);
+ ce->irq = riscv_clock_event_irq;
clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff);
- csr_set(CSR_IE, IE_TIE);
+ enable_percpu_irq(riscv_clock_event_irq,
+ irq_get_trigger_type(riscv_clock_event_irq));
return 0;
}
static int riscv_timer_dying_cpu(unsigned int cpu)
{
- csr_clear(CSR_IE, IE_TIE);
+ disable_percpu_irq(riscv_clock_event_irq);
return 0;
}
/* called directly from the low-level interrupt handler */
-void riscv_timer_interrupt(void)
+static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event);
csr_clear(CSR_IE, IE_TIE);
evdev->event_handler(evdev);
+
+ return IRQ_HANDLED;
}
static int __init riscv_timer_init_dt(struct device_node *n)
{
int cpuid, hartid, error;
+ struct device_node *child;
+ struct irq_domain *domain;
hartid = riscv_of_processor_hartid(n);
if (hartid < 0) {
@@ -115,6 +125,25 @@ static int __init riscv_timer_init_dt(struct device_node *n)
if (cpuid != smp_processor_id())
return 0;
+ domain = NULL;
+ child = of_get_compatible_child(n, "riscv,cpu-intc");
+ if (!child) {
+ pr_err("Failed to find INTC node [%pOF]\n", n);
+ return -ENODEV;
+ }
+ domain = irq_find_host(child);
+ of_node_put(child);
+ if (!domain) {
+ pr_err("Failed to find IRQ domain for node [%pOF]\n", n);
+ return -ENODEV;
+ }
+
+ riscv_clock_event_irq = irq_create_mapping(domain, RV_IRQ_TIMER);
+ if (!riscv_clock_event_irq) {
+ pr_err("Failed to map timer interrupt for node [%pOF]\n", n);
+ return -ENODEV;
+ }
+
pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
__func__, cpuid, hartid);
error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
@@ -126,6 +155,14 @@ static int __init riscv_timer_init_dt(struct device_node *n)
sched_clock_register(riscv_sched_clock, 64, riscv_timebase);
+ error = request_percpu_irq(riscv_clock_event_irq,
+ riscv_timer_interrupt,
+ "riscv-timer", &riscv_clock_event);
+ if (error) {
+ pr_err("registering percpu irq failed [%d]\n", error);
+ return error;
+ }
+
error = cpuhp_setup_state(CPUHP_AP_RISCV_TIMER_STARTING,
"clockevents/riscv/timer:starting",
riscv_timer_starting_cpu, riscv_timer_dying_cpu);
diff --git a/drivers/connector/Kconfig b/drivers/connector/Kconfig
index ba1f3f421cc6..0c2d2aa82d8c 100644
--- a/drivers/connector/Kconfig
+++ b/drivers/connector/Kconfig
@@ -3,7 +3,7 @@
menuconfig CONNECTOR
tristate "Connector - unified userspace <-> kernelspace linker"
depends on NET
- ---help---
+ help
This is unified userspace <-> kernelspace connector working on top
of the netlink socket protocol.
@@ -16,7 +16,7 @@ config PROC_EVENTS
bool "Report process events to userspace"
depends on CONNECTOR=y
default y
- ---help---
+ help
Provide a connector that reports process events to userspace. Send
events such as fork, exec, id change (uid, gid, suid, etc), and exit.
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index bc58a0809d11..399526289320 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -75,7 +75,7 @@ config X86_SFI_CPUFREQ
config ELAN_CPUFREQ
tristate "AMD Elan SC400 and SC410"
depends on MELAN
- ---help---
+ help
This adds the CPUFreq driver for AMD Elan SC400 and SC410
processors.
@@ -90,7 +90,7 @@ config ELAN_CPUFREQ
config SC520_CPUFREQ
tristate "AMD Elan SC520"
depends on MELAN
- ---help---
+ help
This adds the CPUFreq driver for AMD Elan SC520 processor.
For details, take a look at <file:Documentation/cpu-freq/>.
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 289e8ce3fd13..429e5a36c08a 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -126,12 +126,12 @@ static void boost_set_msr_each(void *p_en)
boost_set_msr(enable);
}
-static int set_boost(int val)
+static int set_boost(struct cpufreq_policy *policy, int val)
{
- get_online_cpus();
- on_each_cpu(boost_set_msr_each, (void *)(long)val, 1);
- put_online_cpus();
- pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
+ on_each_cpu_mask(policy->cpus, boost_set_msr_each,
+ (void *)(long)val, 1);
+ pr_debug("CPU %*pbl: Core Boosting %sabled.\n",
+ cpumask_pr_args(policy->cpus), val ? "en" : "dis");
return 0;
}
@@ -162,7 +162,9 @@ static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
if (ret || val > 1)
return -EINVAL;
- set_boost(val);
+ get_online_cpus();
+ set_boost(policy, val);
+ put_online_cpus();
return count;
}
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index bda0b2406fba..257d726a4456 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -37,6 +37,7 @@
* requested etc.
*/
static struct cppc_cpudata **all_cpu_data;
+static bool boost_supported;
struct cppc_workaround_oem_info {
char oem_id[ACPI_OEM_ID_SIZE + 1];
@@ -310,7 +311,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
*/
policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf);
- policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
+ policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
/*
* Set cpuinfo.min_freq to Lowest to make the full range of performance
@@ -318,7 +319,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
* nonlinear perf
*/
policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf);
- policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf);
+ policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf);
policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
policy->shared_type = cpu->shared_type;
@@ -343,6 +344,13 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpu->cur_policy = policy;
+ /*
+ * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
+ * is supported.
+ */
+ if (cpu->perf_caps.highest_perf > cpu->perf_caps.nominal_perf)
+ boost_supported = true;
+
/* Set policy->cur to max now. The governors will adjust later. */
policy->cur = cppc_cpufreq_perf_to_khz(cpu,
cpu->perf_caps.highest_perf);
@@ -410,6 +418,32 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum)
return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1);
}
+static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
+{
+ struct cppc_cpudata *cpudata;
+ int ret;
+
+ if (!boost_supported) {
+ pr_err("BOOST not supported by CPU or firmware\n");
+ return -EINVAL;
+ }
+
+ cpudata = all_cpu_data[policy->cpu];
+ if (state)
+ policy->max = cppc_cpufreq_perf_to_khz(cpudata,
+ cpudata->perf_caps.highest_perf);
+ else
+ policy->max = cppc_cpufreq_perf_to_khz(cpudata,
+ cpudata->perf_caps.nominal_perf);
+ policy->cpuinfo.max_freq = policy->max;
+
+ ret = freq_qos_update_request(policy->max_freq_req, policy->max);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static struct cpufreq_driver cppc_cpufreq_driver = {
.flags = CPUFREQ_CONST_LOOPS,
.verify = cppc_verify_policy,
@@ -417,6 +451,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
.get = cppc_cpufreq_get_rate,
.init = cppc_cpufreq_cpu_init,
.stop_cpu = cppc_cpufreq_stop_cpu,
+ .set_boost = cppc_cpufreq_set_boost,
.name = "cppc_cpufreq",
};
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 26fe8dfb9ce6..79742bbd221f 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -121,6 +121,10 @@ static int resources_available(void)
clk_put(cpu_clk);
+ ret = dev_pm_opp_of_find_icc_paths(cpu_dev, NULL);
+ if (ret)
+ return ret;
+
name = find_supply_name(cpu_dev);
/* Platform doesn't require regulator */
if (!name)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index d03f250f68e4..0128de3603df 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2532,34 +2532,29 @@ EXPORT_SYMBOL_GPL(cpufreq_update_limits);
/*********************************************************************
* BOOST *
*********************************************************************/
-static int cpufreq_boost_set_sw(int state)
+static int cpufreq_boost_set_sw(struct cpufreq_policy *policy, int state)
{
- struct cpufreq_policy *policy;
-
- for_each_active_policy(policy) {
- int ret;
+ int ret;
- if (!policy->freq_table)
- return -ENXIO;
+ if (!policy->freq_table)
+ return -ENXIO;
- ret = cpufreq_frequency_table_cpuinfo(policy,
- policy->freq_table);
- if (ret) {
- pr_err("%s: Policy frequency update failed\n",
- __func__);
- return ret;
- }
-
- ret = freq_qos_update_request(policy->max_freq_req, policy->max);
- if (ret < 0)
- return ret;
+ ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table);
+ if (ret) {
+ pr_err("%s: Policy frequency update failed\n", __func__);
+ return ret;
}
+ ret = freq_qos_update_request(policy->max_freq_req, policy->max);
+ if (ret < 0)
+ return ret;
+
return 0;
}
int cpufreq_boost_trigger_state(int state)
{
+ struct cpufreq_policy *policy;
unsigned long flags;
int ret = 0;
@@ -2570,15 +2565,25 @@ int cpufreq_boost_trigger_state(int state)
cpufreq_driver->boost_enabled = state;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
- ret = cpufreq_driver->set_boost(state);
- if (ret) {
- write_lock_irqsave(&cpufreq_driver_lock, flags);
- cpufreq_driver->boost_enabled = !state;
- write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
- pr_err("%s: Cannot %s BOOST\n",
- __func__, state ? "enable" : "disable");
+ get_online_cpus();
+ for_each_active_policy(policy) {
+ ret = cpufreq_driver->set_boost(policy, state);
+ if (ret)
+ goto err_reset_state;
}
+ put_online_cpus();
+
+ return 0;
+
+err_reset_state:
+ put_online_cpus();
+
+ write_lock_irqsave(&cpufreq_driver_lock, flags);
+ cpufreq_driver->boost_enabled = !state;
+ write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+ pr_err("%s: Cannot %s BOOST\n",
+ __func__, state ? "enable" : "disable");
return ret;
}
diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c
index 2e233ad72758..3d2f143748ef 100644
--- a/drivers/cpufreq/tegra186-cpufreq.c
+++ b/drivers/cpufreq/tegra186-cpufreq.c
@@ -93,7 +93,8 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
static struct cpufreq_driver tegra186_cpufreq_driver = {
.name = "tegra186",
- .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
+ .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
+ CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify,
.target_index = tegra186_cpufreq_set_target,
.init = tegra186_cpufreq_init,
diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 9e5156d39627..8c758920d699 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -8,6 +8,7 @@
#define pr_fmt(fmt) "CPUidle arm: " fmt
+#include <linux/cpu_cooling.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/cpu_pm.h>
@@ -124,6 +125,8 @@ static int __init arm_idle_init_cpu(int cpu)
if (ret)
goto out_kfree_drv;
+ cpuidle_cooling_register(drv);
+
return 0;
out_kfree_drv:
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index d0fb585073c6..3806f911b61c 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -9,6 +9,7 @@
#define pr_fmt(fmt) "CPUidle PSCI: " fmt
#include <linux/cpuhotplug.h>
+#include <linux/cpu_cooling.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/cpu_pm.h>
@@ -319,6 +320,8 @@ static int __init psci_idle_init_cpu(int cpu)
if (ret)
goto out_kfree_drv;
+ cpuidle_cooling_register(drv);
+
return 0;
out_kfree_drv:
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 2c887e4d005a..802b9ada4e9e 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -3,7 +3,7 @@
menuconfig CRYPTO_HW
bool "Hardware crypto devices"
default y
- ---help---
+ help
Say Y here to get to see options for hardware crypto devices and
processors. This option alone does not add any kernel code.
@@ -334,7 +334,7 @@ config HW_RANDOM_PPC4XX
bool "PowerPC 4xx generic true random number generator support"
depends on CRYPTO_DEV_PPC4XX && HW_RANDOM
default y
- ---help---
+ help
This option provides the kernel-side support for the TRNG hardware
found in the security function of some PowerPC 4xx SoCs.
@@ -420,7 +420,7 @@ config CRYPTO_DEV_EXYNOS_RNG
depends on ARCH_EXYNOS || COMPILE_TEST
depends on HAS_IOMEM
select CRYPTO_RNG
- ---help---
+ help
This driver provides kernel-side support through the
cryptographic API for the pseudo random number generator hardware
found on Exynos SoCs.
@@ -597,7 +597,7 @@ source "drivers/crypto/marvell/Kconfig"
config CRYPTO_DEV_CAVIUM_ZIP
tristate "Cavium ZIP driver"
depends on PCI && 64BIT && (ARM64 || COMPILE_TEST)
- ---help---
+ help
Select this option if you want to enable compression/decompression
acceleration on Cavium's ARM based SoCs
diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c
index 788c6607078b..cee2a2713038 100644
--- a/drivers/crypto/cavium/nitrox/nitrox_main.c
+++ b/drivers/crypto/cavium/nitrox/nitrox_main.c
@@ -278,7 +278,7 @@ static void nitrox_remove_from_devlist(struct nitrox_device *ndev)
struct nitrox_device *nitrox_get_first_device(void)
{
- struct nitrox_device *ndev = NULL;
+ struct nitrox_device *ndev;
mutex_lock(&devlist_lock);
list_for_each_entry(ndev, &ndevlist, list) {
@@ -286,7 +286,7 @@ struct nitrox_device *nitrox_get_first_device(void)
break;
}
mutex_unlock(&devlist_lock);
- if (!ndev)
+ if (&ndev->list == &ndevlist)
return NULL;
refcount_inc(&ndev->refcnt);
diff --git a/drivers/crypto/chelsio/Kconfig b/drivers/crypto/chelsio/Kconfig
index f2756836093f..2984fdf51e85 100644
--- a/drivers/crypto/chelsio/Kconfig
+++ b/drivers/crypto/chelsio/Kconfig
@@ -8,7 +8,7 @@ config CRYPTO_DEV_CHELSIO
select CRYPTO_SHA512
select CRYPTO_AUTHENC
select CRYPTO_GF128MUL
- ---help---
+ help
The Chelsio Crypto Co-processor driver for T6 adapters.
For general information about Chelsio and our products, visit
@@ -29,7 +29,7 @@ config CHELSIO_IPSEC_INLINE
depends on XFRM_OFFLOAD
depends on INET_ESP_OFFLOAD || INET6_ESP_OFFLOAD
default n
- ---help---
+ help
Enable support for IPSec Tx Inline.
config CRYPTO_DEV_CHELSIO_TLS
@@ -37,7 +37,7 @@ config CRYPTO_DEV_CHELSIO_TLS
depends on CHELSIO_T4
depends on TLS_TOE
select CRYPTO_DEV_CHELSIO
- ---help---
+ help
Support Chelsio Inline TLS with Chelsio crypto accelerator.
To compile this driver as a module, choose M here: the module
diff --git a/drivers/crypto/omap-aes-gcm.c b/drivers/crypto/omap-aes-gcm.c
index 32dc00dc570b..9f937bdc53a7 100644
--- a/drivers/crypto/omap-aes-gcm.c
+++ b/drivers/crypto/omap-aes-gcm.c
@@ -77,7 +77,6 @@ static void omap_aes_gcm_done_task(struct omap_aes_dev *dd)
tag = (u8 *)rctx->auth_tag;
for (i = 0; i < dd->authsize; i++) {
if (tag[i]) {
- dev_err(dd->dev, "GCM decryption: Tag Message is wrong\n");
ret = -EBADMSG;
}
}
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 824ddf2a66ff..b5aff20c5900 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -1269,13 +1269,17 @@ static int omap_aes_remove(struct platform_device *pdev)
spin_unlock(&list_lock);
for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
- for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
+ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) {
crypto_unregister_skcipher(
&dd->pdata->algs_info[i].algs_list[j]);
+ dd->pdata->algs_info[i].registered--;
+ }
- for (i = dd->pdata->aead_algs_info->size - 1; i >= 0; i--) {
+ for (i = dd->pdata->aead_algs_info->registered - 1; i >= 0; i--) {
aalg = &dd->pdata->aead_algs_info->algs_list[i];
crypto_unregister_aead(aalg);
+ dd->pdata->aead_algs_info->registered--;
+
}
crypto_engine_exit(dd->engine);
diff --git a/drivers/crypto/omap-crypto.c b/drivers/crypto/omap-crypto.c
index cc88b7362bc2..94b2dba90f0d 100644
--- a/drivers/crypto/omap-crypto.c
+++ b/drivers/crypto/omap-crypto.c
@@ -178,11 +178,17 @@ static void omap_crypto_copy_data(struct scatterlist *src,
amt = min(src->length - srco, dst->length - dsto);
amt = min(len, amt);
- srcb = sg_virt(src) + srco;
- dstb = sg_virt(dst) + dsto;
+ srcb = kmap_atomic(sg_page(src)) + srco + src->offset;
+ dstb = kmap_atomic(sg_page(dst)) + dsto + dst->offset;
memcpy(dstb, srcb, amt);
+ if (!PageSlab(sg_page(dst)))
+ flush_kernel_dcache_page(sg_page(dst));
+
+ kunmap_atomic(srcb);
+ kunmap_atomic(dstb);
+
srco += amt;
dsto += amt;
len -= amt;
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 063ad5d03f33..82691a057d2a 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -168,8 +168,6 @@ struct omap_sham_hmac_ctx {
};
struct omap_sham_ctx {
- struct omap_sham_dev *dd;
-
unsigned long flags;
/* fallback stuff */
@@ -750,8 +748,17 @@ static int omap_sham_align_sgs(struct scatterlist *sg,
int offset = rctx->offset;
int bufcnt = rctx->bufcnt;
- if (!sg || !sg->length || !nbytes)
+ if (!sg || !sg->length || !nbytes) {
+ if (bufcnt) {
+ bufcnt = DIV_ROUND_UP(bufcnt, bs) * bs;
+ sg_init_table(rctx->sgl, 1);
+ sg_set_buf(rctx->sgl, rctx->dd->xmit_buf, bufcnt);
+ rctx->sg = rctx->sgl;
+ rctx->sg_len = 1;
+ }
+
return 0;
+ }
new_len = nbytes;
@@ -895,7 +902,7 @@ static int omap_sham_prepare_request(struct ahash_request *req, bool update)
if (hash_later < 0)
hash_later = 0;
- if (hash_later) {
+ if (hash_later && hash_later <= rctx->buflen) {
scatterwalk_map_and_copy(rctx->buffer,
req->src,
req->nbytes - hash_later,
@@ -925,27 +932,35 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
return 0;
}
+struct omap_sham_dev *omap_sham_find_dev(struct omap_sham_reqctx *ctx)
+{
+ struct omap_sham_dev *dd;
+
+ if (ctx->dd)
+ return ctx->dd;
+
+ spin_lock_bh(&sham.lock);
+ dd = list_first_entry(&sham.dev_list, struct omap_sham_dev, list);
+ list_move_tail(&dd->list, &sham.dev_list);
+ ctx->dd = dd;
+ spin_unlock_bh(&sham.lock);
+
+ return dd;
+}
+
static int omap_sham_init(struct ahash_request *req)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm);
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
- struct omap_sham_dev *dd = NULL, *tmp;
+ struct omap_sham_dev *dd;
int bs = 0;
- spin_lock_bh(&sham.lock);
- if (!tctx->dd) {
- list_for_each_entry(tmp, &sham.dev_list, list) {
- dd = tmp;
- break;
- }
- tctx->dd = dd;
- } else {
- dd = tctx->dd;
- }
- spin_unlock_bh(&sham.lock);
+ ctx->dd = NULL;
- ctx->dd = dd;
+ dd = omap_sham_find_dev(ctx);
+ if (!dd)
+ return -ENODEV;
ctx->flags = 0;
@@ -1215,8 +1230,7 @@ err1:
static int omap_sham_enqueue(struct ahash_request *req, unsigned int op)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
- struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
- struct omap_sham_dev *dd = tctx->dd;
+ struct omap_sham_dev *dd = ctx->dd;
ctx->op = op;
@@ -1226,7 +1240,7 @@ static int omap_sham_enqueue(struct ahash_request *req, unsigned int op)
static int omap_sham_update(struct ahash_request *req)
{
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
- struct omap_sham_dev *dd = ctx->dd;
+ struct omap_sham_dev *dd = omap_sham_find_dev(ctx);
if (!req->nbytes)
return 0;
@@ -1319,21 +1333,8 @@ static int omap_sham_setkey(struct crypto_ahash *tfm, const u8 *key,
struct omap_sham_hmac_ctx *bctx = tctx->base;
int bs = crypto_shash_blocksize(bctx->shash);
int ds = crypto_shash_digestsize(bctx->shash);
- struct omap_sham_dev *dd = NULL, *tmp;
int err, i;
- spin_lock_bh(&sham.lock);
- if (!tctx->dd) {
- list_for_each_entry(tmp, &sham.dev_list, list) {
- dd = tmp;
- break;
- }
- tctx->dd = dd;
- } else {
- dd = tctx->dd;
- }
- spin_unlock_bh(&sham.lock);
-
err = crypto_shash_setkey(tctx->fallback, key, keylen);
if (err)
return err;
@@ -1350,7 +1351,7 @@ static int omap_sham_setkey(struct crypto_ahash *tfm, const u8 *key,
memset(bctx->ipad + keylen, 0, bs - keylen);
- if (!test_bit(FLAGS_AUTO_XOR, &dd->flags)) {
+ if (!test_bit(FLAGS_AUTO_XOR, &sham.flags)) {
memcpy(bctx->opad, bctx->ipad, bs);
for (i = 0; i < bs; i++) {
@@ -1571,7 +1572,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.cra_name = "sha224",
.cra_driver_name = "omap-sha224",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx),
@@ -1592,7 +1594,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.cra_name = "sha256",
.cra_driver_name = "omap-sha256",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx),
@@ -1614,7 +1617,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.cra_name = "hmac(sha224)",
.cra_driver_name = "omap-hmac-sha224",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx) +
@@ -1637,7 +1641,8 @@ static struct ahash_alg algs_sha224_sha256[] = {
.cra_name = "hmac(sha256)",
.cra_driver_name = "omap-hmac-sha256",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx) +
@@ -1662,7 +1667,8 @@ static struct ahash_alg algs_sha384_sha512[] = {
.cra_name = "sha384",
.cra_driver_name = "omap-sha384",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx),
@@ -1683,7 +1689,8 @@ static struct ahash_alg algs_sha384_sha512[] = {
.cra_name = "sha512",
.cra_driver_name = "omap-sha512",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx),
@@ -1705,7 +1712,8 @@ static struct ahash_alg algs_sha384_sha512[] = {
.cra_name = "hmac(sha384)",
.cra_driver_name = "omap-hmac-sha384",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx) +
@@ -1728,7 +1736,8 @@ static struct ahash_alg algs_sha384_sha512[] = {
.cra_name = "hmac(sha512)",
.cra_driver_name = "omap-hmac-sha512",
.cra_priority = 400,
- .cra_flags = CRYPTO_ALG_ASYNC |
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK,
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_sham_ctx) +
@@ -2154,6 +2163,7 @@ static int omap_sham_probe(struct platform_device *pdev)
}
dd->flags |= dd->pdata->flags;
+ sham.flags |= dd->pdata->flags;
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
@@ -2181,6 +2191,9 @@ static int omap_sham_probe(struct platform_device *pdev)
spin_unlock(&sham.lock);
for (i = 0; i < dd->pdata->algs_info_size; i++) {
+ if (dd->pdata->algs_info[i].registered)
+ break;
+
for (j = 0; j < dd->pdata->algs_info[i].size; j++) {
struct ahash_alg *alg;
@@ -2232,9 +2245,11 @@ static int omap_sham_remove(struct platform_device *pdev)
list_del(&dd->list);
spin_unlock(&sham.lock);
for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
- for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
+ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) {
crypto_unregister_ahash(
&dd->pdata->algs_info[i].algs_list[j]);
+ dd->pdata->algs_info[i].registered--;
+ }
tasklet_kill(&dd->done_task);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c b/drivers/crypto/virtio/virtio_crypto_algs.c
index fd045e64972a..cb8a6ea2a4bc 100644
--- a/drivers/crypto/virtio/virtio_crypto_algs.c
+++ b/drivers/crypto/virtio/virtio_crypto_algs.c
@@ -350,13 +350,18 @@ __virtio_crypto_skcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
int err;
unsigned long flags;
struct scatterlist outhdr, iv_sg, status_sg, **sgs;
- int i;
u64 dst_len;
unsigned int num_out = 0, num_in = 0;
int sg_total;
uint8_t *iv;
+ struct scatterlist *sg;
src_nents = sg_nents_for_len(req->src, req->cryptlen);
+ if (src_nents < 0) {
+ pr_err("Invalid number of src SG.\n");
+ return src_nents;
+ }
+
dst_nents = sg_nents(req->dst);
pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n",
@@ -402,6 +407,7 @@ __virtio_crypto_skcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
goto free;
}
+ dst_len = min_t(unsigned int, req->cryptlen, dst_len);
pr_debug("virtio_crypto: src_len: %u, dst_len: %llu\n",
req->cryptlen, dst_len);
@@ -442,12 +448,12 @@ __virtio_crypto_skcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
vc_sym_req->iv = iv;
/* Source data */
- for (i = 0; i < src_nents; i++)
- sgs[num_out++] = &req->src[i];
+ for (sg = req->src; src_nents; sg = sg_next(sg), src_nents--)
+ sgs[num_out++] = sg;
/* Destination data */
- for (i = 0; i < dst_nents; i++)
- sgs[num_out + num_in++] = &req->dst[i];
+ for (sg = req->dst; sg; sg = sg_next(sg))
+ sgs[num_out + num_in++] = sg;
/* Status */
sg_init_one(&status_sg, &vc_req->status, sizeof(vc_req->status));
@@ -577,10 +583,11 @@ static void virtio_crypto_skcipher_finalize_req(
scatterwalk_map_and_copy(req->iv, req->dst,
req->cryptlen - AES_BLOCK_SIZE,
AES_BLOCK_SIZE, 0);
- crypto_finalize_skcipher_request(vc_sym_req->base.dataq->engine,
- req, err);
kzfree(vc_sym_req->iv);
virtcrypto_clear_request(&vc_sym_req->base);
+
+ crypto_finalize_skcipher_request(vc_sym_req->base.dataq->engine,
+ req, err);
}
static struct virtio_crypto_algo virtio_crypto_algs[] = { {
diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig
index 9626673f1d83..4f8224a6ac95 100644
--- a/drivers/dma-buf/Kconfig
+++ b/drivers/dma-buf/Kconfig
@@ -5,7 +5,7 @@ config SYNC_FILE
bool "Explicit Synchronization Framework"
default n
select DMA_SHARED_BUFFER
- ---help---
+ help
The Sync File Framework adds explicit synchronization via
userspace. It enables send/receive 'struct dma_fence' objects to/from
userspace via Sync File fds for synchronization between drivers via
@@ -22,7 +22,7 @@ config SW_SYNC
default n
depends on SYNC_FILE
depends on DEBUG_FS
- ---help---
+ help
A sync object driver that uses a 32bit counter to coordinate
synchronization. Useful when there is no hardware primitive backing
the synchronization.
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 4264e64788c4..b45f8514dc82 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -34,6 +34,7 @@
#include <linux/dma-resv.h>
#include <linux/export.h>
+#include <linux/mm.h>
#include <linux/sched/mm.h>
/**
@@ -109,7 +110,7 @@ static int __init dma_resv_lockdep(void)
dma_resv_init(&obj);
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
ww_acquire_init(&ctx, &reservation_ww_class);
ret = dma_resv_lock(&obj, &ctx);
if (ret == -EDEADLK)
@@ -118,7 +119,7 @@ static int __init dma_resv_lockdep(void)
fs_reclaim_release(GFP_KERNEL);
ww_mutex_unlock(&obj.lock);
ww_acquire_fini(&ctx);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 023db6883d05..de41d7928bff 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -106,7 +106,7 @@ config AXI_DMAC
select REGMAP_MMIO
help
Enable support for the Analog Devices AXI-DMAC peripheral. This DMA
- controller is often used in Analog Device's reference designs for FPGA
+ controller is often used in Analog Devices' reference designs for FPGA
platforms.
config BCM_SBA_RAID
@@ -198,7 +198,7 @@ config FSL_DMA
depends on FSL_SOC
select DMA_ENGINE
select ASYNC_TX_ENABLE_CHANNEL_SWITCH
- ---help---
+ help
Enable support for the Freescale Elo series DMA controllers.
The Elo is the DMA controller on some mpc82xx and mpc83xx parts, the
EloPlus is on mpc85xx and mpc86xx and Pxxx parts, and the Elo3 is on
@@ -233,7 +233,7 @@ config FSL_RAID
depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
select DMA_ENGINE
select DMA_ENGINE_RAID
- ---help---
+ help
Enable support for Freescale RAID Engine. RAID Engine is
available on some QorIQ SoCs (like P5020/P5040). It has
the capability to offload memcpy, xor and pq computation
@@ -395,12 +395,10 @@ config MMP_TDMA
bool "MMP Two-Channel DMA support"
depends on ARCH_MMP || COMPILE_TEST
select DMA_ENGINE
- select MMP_SRAM if ARCH_MMP
select GENERIC_ALLOCATOR
help
Support the MMP Two-Channel DMA engine.
This engine used for MMP Audio DMA and pxa910 SQU.
- It needs sram driver under mach-mmp.
config MOXART_DMA
tristate "MOXART DMA support"
@@ -416,7 +414,7 @@ config MPC512X_DMA
tristate "Freescale MPC512x built-in DMA engine support"
depends on PPC_MPC512x || PPC_MPC831x
select DMA_ENGINE
- ---help---
+ help
Enable support for the Freescale MPC512x built-in DMA engine.
config MV_XOR
@@ -425,7 +423,7 @@ config MV_XOR
select DMA_ENGINE
select DMA_ENGINE_RAID
select ASYNC_TX_ENABLE_CHANNEL_SWITCH
- ---help---
+ help
Enable support for the Marvell XOR engine.
config MV_XOR_V2
@@ -435,7 +433,7 @@ config MV_XOR_V2
select DMA_ENGINE_RAID
select ASYNC_TX_ENABLE_CHANNEL_SWITCH
select GENERIC_MSI_IRQ_DOMAIN
- ---help---
+ help
Enable support for the Marvell version 2 XOR engine.
This engine provides acceleration for copy, XOR and RAID6
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index 397692e937b3..80fc2fe8c77e 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -331,7 +331,7 @@ struct at_dma {
struct dma_pool *dma_desc_pool;
struct dma_pool *memset_pool;
/* AT THE END channels table */
- struct at_dma_chan chan[0];
+ struct at_dma_chan chan[];
};
#define dma_readl(atdma, name) \
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index bb0eaf38b594..fd92f048c491 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -212,7 +212,7 @@ struct at_xdmac {
struct clk *clk;
u32 save_gim;
struct dma_pool *at_xdmac_desc_pool;
- struct at_xdmac_chan chan[0];
+ struct at_xdmac_chan chan[];
};
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index d31076d9ef25..2b06a7a8629d 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -53,6 +53,8 @@
#include <linux/mempool.h>
#include <linux/numa.h>
+#include "dmaengine.h"
+
static DEFINE_MUTEX(dma_list_mutex);
static DEFINE_IDA(dma_ida);
static LIST_HEAD(dma_device_list);
@@ -145,9 +147,9 @@ static inline void dmaengine_debug_unregister(struct dma_device *dma_dev) { }
/**
* dev_to_dma_chan - convert a device pointer to its sysfs container object
- * @dev - device node
+ * @dev: device node
*
- * Must be called under dma_list_mutex
+ * Must be called under dma_list_mutex.
*/
static struct dma_chan *dev_to_dma_chan(struct device *dev)
{
@@ -243,22 +245,18 @@ static struct class dma_devclass = {
/* --- client and device registration --- */
-/**
- * dma_cap_mask_all - enable iteration over all operation types
- */
+/* enable iteration over all operation types */
static dma_cap_mask_t dma_cap_mask_all;
/**
- * dma_chan_tbl_ent - tracks channel allocations per core/operation
- * @chan - associated channel for this entry
+ * struct dma_chan_tbl_ent - tracks channel allocations per core/operation
+ * @chan: associated channel for this entry
*/
struct dma_chan_tbl_ent {
struct dma_chan *chan;
};
-/**
- * channel_table - percpu lookup table for memory-to-memory offload providers
- */
+/* percpu lookup table for memory-to-memory offload providers */
static struct dma_chan_tbl_ent __percpu *channel_table[DMA_TX_TYPE_END];
static int __init dma_channel_table_init(void)
@@ -295,8 +293,11 @@ static int __init dma_channel_table_init(void)
arch_initcall(dma_channel_table_init);
/**
- * dma_chan_is_local - returns true if the channel is in the same numa-node as
- * the cpu
+ * dma_chan_is_local - checks if the channel is in the same NUMA-node as the CPU
+ * @chan: DMA channel to test
+ * @cpu: CPU index which the channel should be close to
+ *
+ * Returns true if the channel is in the same NUMA-node as the CPU.
*/
static bool dma_chan_is_local(struct dma_chan *chan, int cpu)
{
@@ -306,14 +307,14 @@ static bool dma_chan_is_local(struct dma_chan *chan, int cpu)
}
/**
- * min_chan - returns the channel with min count and in the same numa-node as
- * the cpu
- * @cap: capability to match
- * @cpu: cpu index which the channel should be close to
+ * min_chan - finds the channel with min count and in the same NUMA-node as the CPU
+ * @cap: capability to match
+ * @cpu: CPU index which the channel should be close to
*
- * If some channels are close to the given cpu, the one with the lowest
- * reference count is returned. Otherwise, cpu is ignored and only the
+ * If some channels are close to the given CPU, the one with the lowest
+ * reference count is returned. Otherwise, CPU is ignored and only the
* reference count is taken into account.
+ *
* Must be called under dma_list_mutex.
*/
static struct dma_chan *min_chan(enum dma_transaction_type cap, int cpu)
@@ -351,10 +352,11 @@ static struct dma_chan *min_chan(enum dma_transaction_type cap, int cpu)
/**
* dma_channel_rebalance - redistribute the available channels
*
- * Optimize for cpu isolation (each cpu gets a dedicated channel for an
- * operation type) in the SMP case, and operation isolation (avoid
- * multi-tasking channels) in the non-SMP case. Must be called under
- * dma_list_mutex.
+ * Optimize for CPU isolation (each CPU gets a dedicated channel for an
+ * operation type) in the SMP case, and operation isolation (avoid
+ * multi-tasking channels) in the non-SMP case.
+ *
+ * Must be called under dma_list_mutex.
*/
static void dma_channel_rebalance(void)
{
@@ -404,9 +406,9 @@ static struct module *dma_chan_to_owner(struct dma_chan *chan)
/**
* balance_ref_count - catch up the channel reference count
- * @chan - channel to balance ->client_count versus dmaengine_ref_count
+ * @chan: channel to balance ->client_count versus dmaengine_ref_count
*
- * balance_ref_count must be called under dma_list_mutex
+ * Must be called under dma_list_mutex.
*/
static void balance_ref_count(struct dma_chan *chan)
{
@@ -436,10 +438,10 @@ static void dma_device_put(struct dma_device *device)
}
/**
- * dma_chan_get - try to grab a dma channel's parent driver module
- * @chan - channel to grab
+ * dma_chan_get - try to grab a DMA channel's parent driver module
+ * @chan: channel to grab
*
- * Must be called under dma_list_mutex
+ * Must be called under dma_list_mutex.
*/
static int dma_chan_get(struct dma_chan *chan)
{
@@ -483,10 +485,10 @@ module_put_out:
}
/**
- * dma_chan_put - drop a reference to a dma channel's parent driver module
- * @chan - channel to release
+ * dma_chan_put - drop a reference to a DMA channel's parent driver module
+ * @chan: channel to release
*
- * Must be called under dma_list_mutex
+ * Must be called under dma_list_mutex.
*/
static void dma_chan_put(struct dma_chan *chan)
{
@@ -537,7 +539,7 @@ EXPORT_SYMBOL(dma_sync_wait);
/**
* dma_find_channel - find a channel to carry out the operation
- * @tx_type: transaction type
+ * @tx_type: transaction type
*/
struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
{
@@ -677,7 +679,7 @@ static struct dma_chan *find_candidate(struct dma_device *device,
/**
* dma_get_slave_channel - try to get specific channel exclusively
- * @chan: target channel
+ * @chan: target channel
*/
struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
{
@@ -731,10 +733,10 @@ EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
/**
* __dma_request_channel - try to allocate an exclusive channel
- * @mask: capabilities that the channel must satisfy
- * @fn: optional callback to disposition available channels
- * @fn_param: opaque parameter to pass to dma_filter_fn
- * @np: device node to look for DMA channels
+ * @mask: capabilities that the channel must satisfy
+ * @fn: optional callback to disposition available channels
+ * @fn_param: opaque parameter to pass to dma_filter_fn()
+ * @np: device node to look for DMA channels
*
* Returns pointer to appropriate DMA channel on success or NULL.
*/
@@ -877,7 +879,7 @@ EXPORT_SYMBOL_GPL(dma_request_slave_channel);
/**
* dma_request_chan_by_mask - allocate a channel satisfying certain capabilities
- * @mask: capabilities that the channel must satisfy
+ * @mask: capabilities that the channel must satisfy
*
* Returns pointer to appropriate DMA channel on success or an error pointer.
*/
@@ -968,7 +970,7 @@ void dmaengine_get(void)
EXPORT_SYMBOL(dmaengine_get);
/**
- * dmaengine_put - let dma drivers be removed when ref_count == 0
+ * dmaengine_put - let DMA drivers be removed when ref_count == 0
*/
void dmaengine_put(void)
{
@@ -1132,7 +1134,7 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_unregister);
/**
* dma_async_device_register - registers DMA devices found
- * @device: &dma_device
+ * @device: pointer to &struct dma_device
*
* After calling this routine the structure should not be freed except in the
* device_release() callback which will be called after
@@ -1304,7 +1306,7 @@ EXPORT_SYMBOL(dma_async_device_register);
/**
* dma_async_device_unregister - unregister a DMA device
- * @device: &dma_device
+ * @device: pointer to &struct dma_device
*
* This routine is called by dma driver exit routines, dmaengine holds module
* references to prevent it being called while channels are in use.
@@ -1341,7 +1343,7 @@ static void dmam_device_release(struct device *dev, void *res)
/**
* dmaenginem_async_device_register - registers DMA devices found
- * @device: &dma_device
+ * @device: pointer to &struct dma_device
*
* The operation is managed and will be undone on driver detach.
*/
@@ -1578,8 +1580,9 @@ int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
}
EXPORT_SYMBOL_GPL(dmaengine_desc_set_metadata_len);
-/* dma_wait_for_async_tx - spin wait for a transaction to complete
- * @tx: in-flight transaction to wait on
+/**
+ * dma_wait_for_async_tx - spin wait for a transaction to complete
+ * @tx: in-flight transaction to wait on
*/
enum dma_status
dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
@@ -1602,9 +1605,12 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
}
EXPORT_SYMBOL_GPL(dma_wait_for_async_tx);
-/* dma_run_dependencies - helper routine for dma drivers to process
- * (start) dependent operations on their target channel
- * @tx: transaction with dependencies
+/**
+ * dma_run_dependencies - process dependent operations on the target channel
+ * @tx: transaction with dependencies
+ *
+ * Helper routine for DMA drivers to process (start) dependent operations
+ * on their target channel.
*/
void dma_run_dependencies(struct dma_async_tx_descriptor *tx)
{
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 0425984db118..b175229a4b01 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -60,9 +60,9 @@ MODULE_PARM_DESC(pq_sources,
"Number of p+q source buffers (default: 3)");
static int timeout = 3000;
-module_param(timeout, uint, S_IRUGO | S_IWUSR);
+module_param(timeout, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), "
- "Pass 0xFFFFFFFF (4294967295) for maximum timeout");
+ "Pass -1 for infinite timeout");
static bool noverify;
module_param(noverify, bool, S_IRUGO | S_IWUSR);
@@ -72,10 +72,6 @@ static bool norandom;
module_param(norandom, bool, 0644);
MODULE_PARM_DESC(norandom, "Disable random offset setup (default: random)");
-static bool polled;
-module_param(polled, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts");
-
static bool verbose;
module_param(verbose, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(verbose, "Enable \"success\" result messages (default: off)");
@@ -88,6 +84,10 @@ static unsigned int transfer_size;
module_param(transfer_size, uint, 0644);
MODULE_PARM_DESC(transfer_size, "Optional custom transfer size in bytes (default: not used (0))");
+static bool polled;
+module_param(polled, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts");
+
/**
* struct dmatest_params - test parameters.
* @buf_size: size of the memcpy test buffer
@@ -98,7 +98,12 @@ MODULE_PARM_DESC(transfer_size, "Optional custom transfer size in bytes (default
* @iterations: iterations before stopping test
* @xor_sources: number of xor source buffers
* @pq_sources: number of p+q source buffers
- * @timeout: transfer timeout in msec, 0 - 0xFFFFFFFF (4294967295)
+ * @timeout: transfer timeout in msec, -1 for infinite timeout
+ * @noverify: disable data verification
+ * @norandom: disable random offset setup
+ * @alignment: custom data address alignment taken as 2^alignment
+ * @transfer_size: custom transfer size in bytes
+ * @polled: use polling for completion instead of interrupts
*/
struct dmatest_params {
unsigned int buf_size;
@@ -109,7 +114,7 @@ struct dmatest_params {
unsigned int iterations;
unsigned int xor_sources;
unsigned int pq_sources;
- unsigned int timeout;
+ int timeout;
bool noverify;
bool norandom;
int alignment;
@@ -120,7 +125,10 @@ struct dmatest_params {
/**
* struct dmatest_info - test information.
* @params: test parameters
+ * @channels: channels under test
+ * @nr_channels: number of channels under test
* @lock: access protection to the fields of this structure
+ * @did_init: module has been initialized completely
*/
static struct dmatest_info {
/* Test parameters */
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index ff392c01bad1..ed430ad9b3dd 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c
@@ -13,8 +13,9 @@
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/dma/edma.h>
-#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include "dw-edma-core.h"
#include "dw-edma-v0-core.h"
@@ -322,7 +323,7 @@ static struct dma_async_tx_descriptor *
dw_edma_device_transfer(struct dw_edma_transfer *xfer)
{
struct dw_edma_chan *chan = dchan2dw_edma_chan(xfer->dchan);
- enum dma_transfer_direction direction = xfer->direction;
+ enum dma_transfer_direction dir = xfer->direction;
phys_addr_t src_addr, dst_addr;
struct scatterlist *sg = NULL;
struct dw_edma_chunk *chunk;
@@ -331,10 +332,26 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
u32 cnt;
int i;
- if ((direction == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_WRITE) ||
- (direction == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_READ))
+ if (!chan->configured)
return NULL;
+ switch (chan->config.direction) {
+ case DMA_DEV_TO_MEM: /* local dma */
+ if (dir == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_READ)
+ break;
+ return NULL;
+ case DMA_MEM_TO_DEV: /* local dma */
+ if (dir == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_WRITE)
+ break;
+ return NULL;
+ default: /* remote dma */
+ if (dir == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_READ)
+ break;
+ if (dir == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_WRITE)
+ break;
+ return NULL;
+ }
+
if (xfer->cyclic) {
if (!xfer->xfer.cyclic.len || !xfer->xfer.cyclic.cnt)
return NULL;
@@ -343,9 +360,6 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
return NULL;
}
- if (!chan->configured)
- return NULL;
-
desc = dw_edma_alloc_desc(chan);
if (unlikely(!desc))
goto err_alloc;
@@ -386,7 +400,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
chunk->ll_region.sz += burst->sz;
desc->alloc_sz += burst->sz;
- if (direction == DMA_DEV_TO_MEM) {
+ if (chan->dir == EDMA_DIR_WRITE) {
burst->sar = src_addr;
if (xfer->cyclic) {
burst->dar = xfer->xfer.cyclic.paddr;
@@ -773,6 +787,7 @@ static int dw_edma_irq_request(struct dw_edma_chip *chip,
u32 rd_mask = 1;
int i, err = 0;
u32 ch_cnt;
+ int irq;
ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt;
@@ -781,16 +796,16 @@ static int dw_edma_irq_request(struct dw_edma_chip *chip,
if (dw->nr_irqs == 1) {
/* Common IRQ shared among all channels */
- err = request_irq(pci_irq_vector(to_pci_dev(dev), 0),
- dw_edma_interrupt_common,
+ irq = dw->ops->irq_vector(dev, 0);
+ err = request_irq(irq, dw_edma_interrupt_common,
IRQF_SHARED, dw->name, &dw->irq[0]);
if (err) {
dw->nr_irqs = 0;
return err;
}
- get_cached_msi_msg(pci_irq_vector(to_pci_dev(dev), 0),
- &dw->irq[0].msi);
+ if (irq_get_msi_desc(irq))
+ get_cached_msi_msg(irq, &dw->irq[0].msi);
} else {
/* Distribute IRQs equally among all channels */
int tmp = dw->nr_irqs;
@@ -804,7 +819,8 @@ static int dw_edma_irq_request(struct dw_edma_chip *chip,
dw_edma_add_irq_mask(&rd_mask, *rd_alloc, dw->rd_ch_cnt);
for (i = 0; i < (*wr_alloc + *rd_alloc); i++) {
- err = request_irq(pci_irq_vector(to_pci_dev(dev), i),
+ irq = dw->ops->irq_vector(dev, i);
+ err = request_irq(irq,
i < *wr_alloc ?
dw_edma_interrupt_write :
dw_edma_interrupt_read,
@@ -815,8 +831,8 @@ static int dw_edma_irq_request(struct dw_edma_chip *chip,
return err;
}
- get_cached_msi_msg(pci_irq_vector(to_pci_dev(dev), i),
- &dw->irq[i].msi);
+ if (irq_get_msi_desc(irq))
+ get_cached_msi_msg(irq, &dw->irq[i].msi);
}
dw->nr_irqs = i;
@@ -827,12 +843,23 @@ static int dw_edma_irq_request(struct dw_edma_chip *chip,
int dw_edma_probe(struct dw_edma_chip *chip)
{
- struct device *dev = chip->dev;
- struct dw_edma *dw = chip->dw;
+ struct device *dev;
+ struct dw_edma *dw;
u32 wr_alloc = 0;
u32 rd_alloc = 0;
int i, err;
+ if (!chip)
+ return -EINVAL;
+
+ dev = chip->dev;
+ if (!dev)
+ return -EINVAL;
+
+ dw = chip->dw;
+ if (!dw || !dw->irq || !dw->ops || !dw->ops->irq_vector)
+ return -EINVAL;
+
raw_spin_lock_init(&dw->lock);
/* Find out how many write channels are supported by hardware */
@@ -884,7 +911,7 @@ int dw_edma_probe(struct dw_edma_chip *chip)
err_irq_free:
for (i = (dw->nr_irqs - 1); i >= 0; i--)
- free_irq(pci_irq_vector(to_pci_dev(dev), i), &dw->irq[i]);
+ free_irq(dw->ops->irq_vector(dev, i), &dw->irq[i]);
dw->nr_irqs = 0;
@@ -904,7 +931,7 @@ int dw_edma_remove(struct dw_edma_chip *chip)
/* Free irqs */
for (i = (dw->nr_irqs - 1); i >= 0; i--)
- free_irq(pci_irq_vector(to_pci_dev(dev), i), &dw->irq[i]);
+ free_irq(dw->ops->irq_vector(dev, i), &dw->irq[i]);
/* Power management */
pm_runtime_disable(dev);
diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h
index 4e5f9f6e901b..31fc50d31792 100644
--- a/drivers/dma/dw-edma/dw-edma-core.h
+++ b/drivers/dma/dw-edma/dw-edma-core.h
@@ -103,6 +103,10 @@ struct dw_edma_irq {
struct dw_edma *dw;
};
+struct dw_edma_core_ops {
+ int (*irq_vector)(struct device *dev, unsigned int nr);
+};
+
struct dw_edma {
char name[20];
diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c
index dc85f55e1bb8..1eafc602e17e 100644
--- a/drivers/dma/dw-edma/dw-edma-pcie.c
+++ b/drivers/dma/dw-edma/dw-edma-pcie.c
@@ -54,6 +54,15 @@ static const struct dw_edma_pcie_data snps_edda_data = {
.irqs = 1,
};
+static int dw_edma_pcie_irq_vector(struct device *dev, unsigned int nr)
+{
+ return pci_irq_vector(to_pci_dev(dev), nr);
+}
+
+static const struct dw_edma_core_ops dw_edma_pcie_core_ops = {
+ .irq_vector = dw_edma_pcie_irq_vector,
+};
+
static int dw_edma_pcie_probe(struct pci_dev *pdev,
const struct pci_device_id *pid)
{
@@ -151,6 +160,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev,
dw->version = pdata->version;
dw->mode = pdata->mode;
dw->nr_irqs = nr_irqs;
+ dw->ops = &dw_edma_pcie_core_ops;
/* Debug info */
pci_dbg(pdev, "Version:\t%u\n", dw->version);
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 3999827970ab..052dae5d6ddd 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -1092,6 +1092,16 @@ static const struct attribute_group *idxd_wq_attribute_groups[] = {
};
/* IDXD device attribs */
+static ssize_t version_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct idxd_device *idxd =
+ container_of(dev, struct idxd_device, conf_dev);
+
+ return sprintf(buf, "%#x\n", idxd->hw.version);
+}
+static DEVICE_ATTR_RO(version);
+
static ssize_t max_work_queues_size_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1313,6 +1323,7 @@ static ssize_t cdev_major_show(struct device *dev,
static DEVICE_ATTR_RO(cdev_major);
static struct attribute *idxd_device_attributes[] = {
+ &dev_attr_version.attr,
&dev_attr_max_groups.attr,
&dev_attr_max_work_queues.attr,
&dev_attr_max_work_queues_size.attr,
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 4d4477df4ede..91774039ae5d 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -2063,7 +2063,7 @@ static int sdma_probe(struct platform_device *pdev)
/* initially no scripts available */
saddr_arr = (s32 *)sdma->script_addrs;
- for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
+ for (i = 0; i < sizeof(*sdma->script_addrs) / sizeof(s32); i++)
saddr_arr[i] = -EINVAL;
dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 18c011e57592..8ad0ad861c86 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -332,8 +332,8 @@ ioat_alloc_ring_ent(struct dma_chan *chan, int idx, gfp_t flags)
u8 *pos;
off_t offs;
- chunk = idx / IOAT_DESCS_PER_2M;
- idx &= (IOAT_DESCS_PER_2M - 1);
+ chunk = idx / IOAT_DESCS_PER_CHUNK;
+ idx &= (IOAT_DESCS_PER_CHUNK - 1);
offs = idx * IOAT_DESC_SZ;
pos = (u8 *)ioat_chan->descs[chunk].virt + offs;
phys = ioat_chan->descs[chunk].hw + offs;
@@ -370,7 +370,8 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags)
if (!ring)
return NULL;
- ioat_chan->desc_chunks = chunks = (total_descs * IOAT_DESC_SZ) / SZ_2M;
+ chunks = (total_descs * IOAT_DESC_SZ) / IOAT_CHUNK_SIZE;
+ ioat_chan->desc_chunks = chunks;
for (i = 0; i < chunks; i++) {
struct ioat_descs *descs = &ioat_chan->descs[i];
@@ -382,8 +383,9 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags)
for (idx = 0; idx < i; idx++) {
descs = &ioat_chan->descs[idx];
- dma_free_coherent(to_dev(ioat_chan), SZ_2M,
- descs->virt, descs->hw);
+ dma_free_coherent(to_dev(ioat_chan),
+ IOAT_CHUNK_SIZE,
+ descs->virt, descs->hw);
descs->virt = NULL;
descs->hw = 0;
}
@@ -404,7 +406,7 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags)
for (idx = 0; idx < ioat_chan->desc_chunks; idx++) {
dma_free_coherent(to_dev(ioat_chan),
- SZ_2M,
+ IOAT_CHUNK_SIZE,
ioat_chan->descs[idx].virt,
ioat_chan->descs[idx].hw);
ioat_chan->descs[idx].virt = NULL;
@@ -867,6 +869,23 @@ static void check_active(struct ioatdma_chan *ioat_chan)
mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
}
+static void ioat_reboot_chan(struct ioatdma_chan *ioat_chan)
+{
+ spin_lock_bh(&ioat_chan->prep_lock);
+ set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
+ spin_unlock_bh(&ioat_chan->prep_lock);
+
+ ioat_abort_descs(ioat_chan);
+ dev_warn(to_dev(ioat_chan), "Reset channel...\n");
+ ioat_reset_hw(ioat_chan);
+ dev_warn(to_dev(ioat_chan), "Restart channel...\n");
+ ioat_restart_channel(ioat_chan);
+
+ spin_lock_bh(&ioat_chan->prep_lock);
+ clear_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
+ spin_unlock_bh(&ioat_chan->prep_lock);
+}
+
void ioat_timer_event(struct timer_list *t)
{
struct ioatdma_chan *ioat_chan = from_timer(ioat_chan, t, timer);
@@ -889,19 +908,7 @@ void ioat_timer_event(struct timer_list *t)
if (test_bit(IOAT_RUN, &ioat_chan->state)) {
spin_lock_bh(&ioat_chan->cleanup_lock);
- spin_lock_bh(&ioat_chan->prep_lock);
- set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
- spin_unlock_bh(&ioat_chan->prep_lock);
-
- ioat_abort_descs(ioat_chan);
- dev_warn(to_dev(ioat_chan), "Reset channel...\n");
- ioat_reset_hw(ioat_chan);
- dev_warn(to_dev(ioat_chan), "Restart channel...\n");
- ioat_restart_channel(ioat_chan);
-
- spin_lock_bh(&ioat_chan->prep_lock);
- clear_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
- spin_unlock_bh(&ioat_chan->prep_lock);
+ ioat_reboot_chan(ioat_chan);
spin_unlock_bh(&ioat_chan->cleanup_lock);
}
@@ -915,17 +922,23 @@ void ioat_timer_event(struct timer_list *t)
spin_lock_bh(&ioat_chan->prep_lock);
check_active(ioat_chan);
spin_unlock_bh(&ioat_chan->prep_lock);
- spin_unlock_bh(&ioat_chan->cleanup_lock);
- return;
+ goto unlock_out;
+ }
+
+ /* handle the missed cleanup case */
+ if (ioat_cleanup_preamble(ioat_chan, &phys_complete)) {
+ /* timer restarted in ioat_cleanup_preamble
+ * and IOAT_COMPLETION_ACK cleared
+ */
+ __cleanup(ioat_chan, phys_complete);
+ goto unlock_out;
}
/* if we haven't made progress and we have already
* acknowledged a pending completion once, then be more
* forceful with a restart
*/
- if (ioat_cleanup_preamble(ioat_chan, &phys_complete))
- __cleanup(ioat_chan, phys_complete);
- else if (test_bit(IOAT_COMPLETION_ACK, &ioat_chan->state)) {
+ if (test_bit(IOAT_COMPLETION_ACK, &ioat_chan->state)) {
u32 chanerr;
chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
@@ -937,25 +950,23 @@ void ioat_timer_event(struct timer_list *t)
dev_dbg(to_dev(ioat_chan), "Active descriptors: %d\n",
ioat_ring_active(ioat_chan));
- spin_lock_bh(&ioat_chan->prep_lock);
- set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
- spin_unlock_bh(&ioat_chan->prep_lock);
+ ioat_reboot_chan(ioat_chan);
- ioat_abort_descs(ioat_chan);
- dev_warn(to_dev(ioat_chan), "Resetting channel...\n");
- ioat_reset_hw(ioat_chan);
- dev_warn(to_dev(ioat_chan), "Restarting channel...\n");
- ioat_restart_channel(ioat_chan);
+ goto unlock_out;
+ }
+ /* handle missed issue pending case */
+ if (ioat_ring_pending(ioat_chan)) {
+ dev_warn(to_dev(ioat_chan),
+ "Completion timeout with pending descriptors\n");
spin_lock_bh(&ioat_chan->prep_lock);
- clear_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
+ __ioat_issue_pending(ioat_chan);
spin_unlock_bh(&ioat_chan->prep_lock);
- spin_unlock_bh(&ioat_chan->cleanup_lock);
- return;
- } else
- set_bit(IOAT_COMPLETION_ACK, &ioat_chan->state);
+ }
+ set_bit(IOAT_COMPLETION_ACK, &ioat_chan->state);
mod_timer(&ioat_chan->timer, jiffies + COMPLETION_TIMEOUT);
+unlock_out:
spin_unlock_bh(&ioat_chan->cleanup_lock);
}
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index b8e8e0b9693c..e6b622e1ba92 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -81,6 +81,11 @@ struct ioatdma_device {
u32 msixpba;
};
+#define IOAT_MAX_ORDER 16
+#define IOAT_MAX_DESCS (1 << IOAT_MAX_ORDER)
+#define IOAT_CHUNK_SIZE (SZ_512K)
+#define IOAT_DESCS_PER_CHUNK (IOAT_CHUNK_SIZE / IOAT_DESC_SZ)
+
struct ioat_descs {
void *virt;
dma_addr_t hw;
@@ -128,7 +133,7 @@ struct ioatdma_chan {
u16 produce;
struct ioat_ring_ent **ring;
spinlock_t prep_lock;
- struct ioat_descs descs[2];
+ struct ioat_descs descs[IOAT_MAX_DESCS / IOAT_DESCS_PER_CHUNK];
int desc_chunks;
int intr_coalesce;
int prev_intr_coalesce;
@@ -301,9 +306,6 @@ static inline bool is_ioat_bug(unsigned long err)
return !!err;
}
-#define IOAT_MAX_ORDER 16
-#define IOAT_MAX_DESCS 65536
-#define IOAT_DESCS_PER_2M 32768
static inline u32 ioat_ring_size(struct ioatdma_chan *ioat_chan)
{
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c
index 60e9afbb896c..58d13564f88b 100644
--- a/drivers/dma/ioat/init.c
+++ b/drivers/dma/ioat/init.c
@@ -651,7 +651,7 @@ static void ioat_free_chan_resources(struct dma_chan *c)
}
for (i = 0; i < ioat_chan->desc_chunks; i++) {
- dma_free_coherent(to_dev(ioat_chan), SZ_2M,
+ dma_free_coherent(to_dev(ioat_chan), IOAT_CHUNK_SIZE,
ioat_chan->descs[i].virt,
ioat_chan->descs[i].hw);
ioat_chan->descs[i].virt = NULL;
diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 1ad63ddc292d..7a46a5455957 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -5,7 +5,7 @@ config MTK_HSDMA
depends on ARCH_MEDIATEK || COMPILE_TEST
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
- ---help---
+ help
Enable support for High-Speed DMA controller on MediaTek
SoCs.
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index d683232d7fea..dbc6a48424fa 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -235,7 +235,7 @@ static int mmp_tdma_config_chan(struct dma_chan *chan)
tdcr |= TDCR_BURSTSZ_128B;
break;
default:
- dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n");
+ dev_err(tdmac->dev, "unknown burst size.\n");
return -EINVAL;
}
@@ -250,7 +250,7 @@ static int mmp_tdma_config_chan(struct dma_chan *chan)
tdcr |= TDCR_SSZ_32_BITS;
break;
default:
- dev_err(tdmac->dev, "mmp_tdma: unknown bus size.\n");
+ dev_err(tdmac->dev, "unknown bus size.\n");
return -EINVAL;
}
} else if (tdmac->type == PXA910_SQU) {
@@ -276,7 +276,7 @@ static int mmp_tdma_config_chan(struct dma_chan *chan)
tdcr |= TDCR_BURSTSZ_SQU_32B;
break;
default:
- dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n");
+ dev_err(tdmac->dev, "unknown burst size.\n");
return -EINVAL;
}
}
@@ -429,8 +429,15 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic(
int num_periods = buf_len / period_len;
int i = 0, buf = 0;
- if (tdmac->status != DMA_COMPLETE)
+ if (!is_slave_direction(direction)) {
+ dev_err(tdmac->dev, "unsupported transfer direction\n");
return NULL;
+ }
+
+ if (tdmac->status != DMA_COMPLETE) {
+ dev_err(tdmac->dev, "controller busy");
+ return NULL;
+ }
if (period_len > TDMA_MAX_XFER_BYTES) {
dev_err(tdmac->dev,
@@ -704,6 +711,17 @@ static int mmp_tdma_probe(struct platform_device *pdev)
tdev->device.device_terminate_all = mmp_tdma_terminate_all;
tdev->device.copy_align = DMAENGINE_ALIGN_8_BYTES;
+ tdev->device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ if (type == MMP_AUD_TDMA) {
+ tdev->device.max_burst = SZ_128;
+ tdev->device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ tdev->device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ } else if (type == PXA910_SQU) {
+ tdev->device.max_burst = SZ_32;
+ }
+ tdev->device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+ tdev->device.descriptor_reuse = true;
+
dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
platform_set_drvdata(pdev, tdev);
diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c
index e04499c1f27f..4ab493d46375 100644
--- a/drivers/dma/moxart-dma.c
+++ b/drivers/dma/moxart-dma.c
@@ -568,7 +568,7 @@ static int moxart_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct resource *res;
- static void __iomem *dma_base_addr;
+ void __iomem *dma_base_addr;
int ret, i;
unsigned int irq;
struct moxart_chan *ch;
diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 1d189438aeb0..3bcb689162c6 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -4,7 +4,7 @@ config QCOM_BAM_DMA
depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
- ---help---
+ help
Enable support for the QCOM BAM DMA controller. This controller
provides DMA capabilities for a variety of on-chip devices.
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index ef73f65224b1..5a08dd0d3388 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -74,7 +74,7 @@ struct bam_async_desc {
struct list_head desc_node;
enum dma_transfer_direction dir;
size_t length;
- struct bam_desc_hw desc[0];
+ struct bam_desc_hw desc[];
};
enum bam_reg {
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 411f91fde734..0a6d3ea08c78 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -550,7 +550,7 @@ static void hidma_free_chan_resources(struct dma_chan *dmach)
kfree(mdesc);
}
- mchan->allocated = 0;
+ mchan->allocated = false;
spin_unlock_irqrestore(&mchan->lock, irqflags);
}
@@ -897,7 +897,6 @@ uninit:
if (msi)
hidma_free_msis(dmadev);
- hidma_debug_uninit(dmadev);
hidma_ll_uninit(dmadev->lldev);
dmafree:
if (dmadev)
diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
index 6d0bec947636..5c118c7e02bd 100644
--- a/drivers/dma/sf-pdma/sf-pdma.c
+++ b/drivers/dma/sf-pdma/sf-pdma.c
@@ -506,11 +506,11 @@ static int sf_pdma_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pdma->membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pdma->membase))
- goto ERR_MEMBASE;
+ return PTR_ERR(pdma->membase);
ret = sf_pdma_irq_init(pdev, pdma);
if (ret)
- goto ERR_INITIRQ;
+ return ret;
sf_pdma_setup_chans(pdma);
@@ -544,24 +544,13 @@ static int sf_pdma_probe(struct platform_device *pdev)
"Failed to set DMA mask. Fall back to default.\n");
ret = dma_async_device_register(&pdma->dma_dev);
- if (ret)
- goto ERR_REG_DMADEVICE;
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Can't register SiFive Platform DMA. (%d)\n", ret);
+ return ret;
+ }
return 0;
-
-ERR_MEMBASE:
- devm_kfree(&pdev->dev, pdma);
- return PTR_ERR(pdma->membase);
-
-ERR_INITIRQ:
- devm_kfree(&pdev->dev, pdma);
- return ret;
-
-ERR_REG_DMADEVICE:
- devm_kfree(&pdev->dev, pdma);
- dev_err(&pdev->dev,
- "Can't register SiFive Platform DMA. (%d)\n", ret);
- return ret;
}
static int sf_pdma_remove(struct platform_device *pdev)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 0ddbaa4b4f0b..96ad1b3d24c6 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -117,6 +117,7 @@
#define STM32_DMA_FIFO_THRESHOLD_HALFFULL 0x01
#define STM32_DMA_FIFO_THRESHOLD_3QUARTERSFULL 0x02
#define STM32_DMA_FIFO_THRESHOLD_FULL 0x03
+#define STM32_DMA_FIFO_THRESHOLD_NONE 0x04
#define STM32_DMA_MAX_DATA_ITEMS 0xffff
/*
@@ -136,6 +137,9 @@
/* DMA Features */
#define STM32_DMA_THRESHOLD_FTR_MASK GENMASK(1, 0)
#define STM32_DMA_THRESHOLD_FTR_GET(n) ((n) & STM32_DMA_THRESHOLD_FTR_MASK)
+#define STM32_DMA_DIRECT_MODE_MASK BIT(2)
+#define STM32_DMA_DIRECT_MODE_GET(n) (((n) & STM32_DMA_DIRECT_MODE_MASK) \
+ >> 2)
enum stm32_dma_width {
STM32_DMA_BYTE,
@@ -281,6 +285,9 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
{
u32 remaining;
+ if (threshold == STM32_DMA_FIFO_THRESHOLD_NONE)
+ return false;
+
if (width != DMA_SLAVE_BUSWIDTH_UNDEFINED) {
if (burst != 0) {
/*
@@ -302,6 +309,10 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
static bool stm32_dma_is_burst_possible(u32 buf_len, u32 threshold)
{
+ /* If FIFO direct mode, burst is not possible */
+ if (threshold == STM32_DMA_FIFO_THRESHOLD_NONE)
+ return false;
+
/*
* Buffer or period length has to be aligned on FIFO depth.
* Otherwise bytes may be stuck within FIFO at buffer or period
@@ -657,6 +668,12 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
dev_dbg(chan2dev(chan), "FIFO over/underrun\n");
}
}
+ if (status & STM32_DMA_DMEI) {
+ stm32_dma_irq_clear(chan, STM32_DMA_DMEI);
+ status &= ~STM32_DMA_DMEI;
+ if (sfcr & STM32_DMA_SCR_DMEIE)
+ dev_dbg(chan2dev(chan), "Direct mode overrun\n");
+ }
if (status) {
stm32_dma_irq_clear(chan, status);
dev_err(chan2dev(chan), "DMA error: status=0x%08x\n", status);
@@ -692,13 +709,13 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
int src_bus_width, dst_bus_width;
int src_burst_size, dst_burst_size;
u32 src_maxburst, dst_maxburst, src_best_burst, dst_best_burst;
- u32 dma_scr, threshold;
+ u32 dma_scr, fifoth;
src_addr_width = chan->dma_sconfig.src_addr_width;
dst_addr_width = chan->dma_sconfig.dst_addr_width;
src_maxburst = chan->dma_sconfig.src_maxburst;
dst_maxburst = chan->dma_sconfig.dst_maxburst;
- threshold = chan->threshold;
+ fifoth = chan->threshold;
switch (direction) {
case DMA_MEM_TO_DEV:
@@ -710,7 +727,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
/* Set device burst size */
dst_best_burst = stm32_dma_get_best_burst(buf_len,
dst_maxburst,
- threshold,
+ fifoth,
dst_addr_width);
dst_burst_size = stm32_dma_get_burst(chan, dst_best_burst);
@@ -718,7 +735,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
return dst_burst_size;
/* Set memory data size */
- src_addr_width = stm32_dma_get_max_width(buf_len, threshold);
+ src_addr_width = stm32_dma_get_max_width(buf_len, fifoth);
chan->mem_width = src_addr_width;
src_bus_width = stm32_dma_get_width(chan, src_addr_width);
if (src_bus_width < 0)
@@ -728,7 +745,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
src_maxburst = STM32_DMA_MAX_BURST;
src_best_burst = stm32_dma_get_best_burst(buf_len,
src_maxburst,
- threshold,
+ fifoth,
src_addr_width);
src_burst_size = stm32_dma_get_burst(chan, src_best_burst);
if (src_burst_size < 0)
@@ -742,7 +759,8 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
/* Set FIFO threshold */
chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_FTH_MASK;
- chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(threshold);
+ if (fifoth != STM32_DMA_FIFO_THRESHOLD_NONE)
+ chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(fifoth);
/* Set peripheral address */
chan->chan_reg.dma_spar = chan->dma_sconfig.dst_addr;
@@ -758,7 +776,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
/* Set device burst size */
src_best_burst = stm32_dma_get_best_burst(buf_len,
src_maxburst,
- threshold,
+ fifoth,
src_addr_width);
chan->mem_burst = src_best_burst;
src_burst_size = stm32_dma_get_burst(chan, src_best_burst);
@@ -766,7 +784,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
return src_burst_size;
/* Set memory data size */
- dst_addr_width = stm32_dma_get_max_width(buf_len, threshold);
+ dst_addr_width = stm32_dma_get_max_width(buf_len, fifoth);
chan->mem_width = dst_addr_width;
dst_bus_width = stm32_dma_get_width(chan, dst_addr_width);
if (dst_bus_width < 0)
@@ -776,7 +794,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
dst_maxburst = STM32_DMA_MAX_BURST;
dst_best_burst = stm32_dma_get_best_burst(buf_len,
dst_maxburst,
- threshold,
+ fifoth,
dst_addr_width);
chan->mem_burst = dst_best_burst;
dst_burst_size = stm32_dma_get_burst(chan, dst_best_burst);
@@ -791,7 +809,8 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
/* Set FIFO threshold */
chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_FTH_MASK;
- chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(threshold);
+ if (fifoth != STM32_DMA_FIFO_THRESHOLD_NONE)
+ chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(fifoth);
/* Set peripheral address */
chan->chan_reg.dma_spar = chan->dma_sconfig.src_addr;
@@ -1216,6 +1235,8 @@ static void stm32_dma_set_config(struct stm32_dma_chan *chan,
chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE;
chan->threshold = STM32_DMA_THRESHOLD_FTR_GET(cfg->features);
+ if (STM32_DMA_DIRECT_MODE_GET(cfg->features))
+ chan->threshold = STM32_DMA_FIFO_THRESHOLD_NONE;
}
static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig
index f76e06651f80..79618fac119a 100644
--- a/drivers/dma/ti/Kconfig
+++ b/drivers/dma/ti/Kconfig
@@ -36,7 +36,7 @@ config DMA_OMAP
config TI_K3_UDMA
bool "Texas Instruments UDMA support"
- depends on ARCH_K3 || COMPILE_TEST
+ depends on ARCH_K3
depends on TI_SCI_PROTOCOL
depends on TI_SCI_INTA_IRQCHIP
select DMA_ENGINE
@@ -49,7 +49,7 @@ config TI_K3_UDMA
config TI_K3_UDMA_GLUE_LAYER
bool "Texas Instruments UDMA Glue layer for non DMAengine users"
- depends on ARCH_K3 || COMPILE_TEST
+ depends on ARCH_K3
depends on TI_K3_UDMA
help
Say y here to support the K3 NAVSS DMA glue interface
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index a90e154b0ae0..945b7c604f91 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -231,7 +231,6 @@ struct udma_chan {
struct udma_tx_drain tx_drain;
u32 bcnt; /* number of bytes completed since the start of the channel */
- u32 in_ring_cnt; /* number of descriptors in flight */
/* Channel configuration parameters */
struct udma_chan_config config;
@@ -574,7 +573,6 @@ static int udma_push_to_ring(struct udma_chan *uc, int idx)
struct udma_desc *d = uc->desc;
struct k3_ring *ring = NULL;
dma_addr_t paddr;
- int ret;
switch (uc->config.dir) {
case DMA_DEV_TO_MEM:
@@ -598,11 +596,7 @@ static int udma_push_to_ring(struct udma_chan *uc, int idx)
udma_sync_for_device(uc, idx);
}
- ret = k3_ringacc_ring_push(ring, &paddr);
- if (!ret)
- uc->in_ring_cnt++;
-
- return ret;
+ return k3_ringacc_ring_push(ring, &paddr);
}
static bool udma_desc_is_rx_flush(struct udma_chan *uc, dma_addr_t addr)
@@ -655,9 +649,6 @@ static int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr)
d->hwdesc[0].cppi5_desc_size,
DMA_FROM_DEVICE);
rmb(); /* Ensure that reads are not moved before this point */
-
- if (!ret)
- uc->in_ring_cnt--;
}
return ret;
@@ -697,8 +688,6 @@ static void udma_reset_rings(struct udma_chan *uc)
udma_desc_free(&uc->terminated_desc->vd);
uc->terminated_desc = NULL;
}
-
- uc->in_ring_cnt = 0;
}
static void udma_reset_counters(struct udma_chan *uc)
@@ -1073,9 +1062,6 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
/* Teardown completion message */
if (cppi5_desc_is_tdcm(paddr)) {
- /* Compensate our internal pop/push counter */
- uc->in_ring_cnt++;
-
complete_all(&uc->teardown_completed);
if (uc->terminated_desc) {
@@ -1291,10 +1277,8 @@ static int udma_get_tchan(struct udma_chan *uc)
}
uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl, -1);
- if (IS_ERR(uc->tchan))
- return PTR_ERR(uc->tchan);
- return 0;
+ return PTR_ERR_OR_ZERO(uc->tchan);
}
static int udma_get_rchan(struct udma_chan *uc)
@@ -1308,10 +1292,8 @@ static int udma_get_rchan(struct udma_chan *uc)
}
uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl, -1);
- if (IS_ERR(uc->rchan))
- return PTR_ERR(uc->rchan);
- return 0;
+ return PTR_ERR_OR_ZERO(uc->rchan);
}
static int udma_get_chan_pair(struct udma_chan *uc)
@@ -1373,10 +1355,8 @@ static int udma_get_rflow(struct udma_chan *uc, int flow_id)
}
uc->rflow = __udma_get_rflow(ud, flow_id);
- if (IS_ERR(uc->rflow))
- return PTR_ERR(uc->rflow);
- return 0;
+ return PTR_ERR_OR_ZERO(uc->rflow);
}
static void udma_put_rchan(struct udma_chan *uc)
@@ -1870,6 +1850,7 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
udma_stop(uc);
if (udma_is_chan_running(uc)) {
dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+ ret = -EBUSY;
goto err_res_free;
}
}
@@ -3189,7 +3170,7 @@ static struct udma_match_data am654_main_data = {
static struct udma_match_data am654_mcu_data = {
.psil_base = 0x6000,
- .enable_memcpy_support = true, /* TEST: DMA domains */
+ .enable_memcpy_support = false,
.statictr_z_mask = GENMASK(11, 0),
.rchan_oes_offset = 0x2000,
.tpl_levels = 2,
@@ -3471,6 +3452,9 @@ static int udma_setup_rx_flush(struct udma_dev *ud)
tr_req->icnt0 = rx_flush->buffer_size;
tr_req->icnt1 = 1;
+ dma_sync_single_for_device(dev, hwdesc->cppi5_desc_paddr,
+ hwdesc->cppi5_desc_size, DMA_TO_DEVICE);
+
/* Set up descriptor to be used for packet mode */
hwdesc = &rx_flush->hwdescs[1];
hwdesc->cppi5_desc_size = ALIGN(sizeof(struct cppi5_host_desc_t) +
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index fe2eb892a1bd..7b6ec3014ba2 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -44,7 +44,7 @@ config EDAC_DECODE_MCE
tristate "Decode MCEs in human-readable form (only on AMD for now)"
depends on CPU_SUP_AMD && X86_MCE_AMD
default y
- ---help---
+ help
Enable this option if you want to decode Machine Check Exceptions
occurring on your machine in human-readable form.
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 9cf7cc1f3f72..ef90070a9194 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -4,9 +4,6 @@
static struct edac_pci_ctl_info *pci_ctl;
-static int report_gart_errors;
-module_param(report_gart_errors, int, 0644);
-
/*
* Set by command line parameter. If BIOS has enabled the ECC, this override is
* cleared to prevent re-enabling the hardware by this driver.
@@ -2319,6 +2316,16 @@ static struct amd64_family_type family_types[] = {
.dbam_to_cs = f17_addr_mask_to_cs_size,
}
},
+ [F17_M60H_CPUS] = {
+ .ctl_name = "F17h_M60h",
+ .f0_id = PCI_DEVICE_ID_AMD_17H_M60H_DF_F0,
+ .f6_id = PCI_DEVICE_ID_AMD_17H_M60H_DF_F6,
+ .max_mcs = 2,
+ .ops = {
+ .early_channel_count = f17_early_channel_count,
+ .dbam_to_cs = f17_addr_mask_to_cs_size,
+ }
+ },
[F17_M70H_CPUS] = {
.ctl_name = "F17h_M70h",
.f0_id = PCI_DEVICE_ID_AMD_17H_M70H_DF_F0,
@@ -3357,6 +3364,10 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
fam_type = &family_types[F17_M30H_CPUS];
pvt->ops = &family_types[F17_M30H_CPUS].ops;
break;
+ } else if (pvt->model >= 0x60 && pvt->model <= 0x6f) {
+ fam_type = &family_types[F17_M60H_CPUS];
+ pvt->ops = &family_types[F17_M60H_CPUS].ops;
+ break;
} else if (pvt->model >= 0x70 && pvt->model <= 0x7f) {
fam_type = &family_types[F17_M70H_CPUS];
pvt->ops = &family_types[F17_M70H_CPUS].ops;
@@ -3681,9 +3692,6 @@ static int __init amd64_edac_init(void)
}
/* register stuff with EDAC MCE */
- if (report_gart_errors)
- amd_report_gart_errors(true);
-
if (boot_cpu_data.x86 >= 0x17)
amd_register_ecc_decoder(decode_umc_error);
else
@@ -3718,8 +3726,6 @@ static void __exit amd64_edac_exit(void)
edac_pci_release_generic_ctl(pci_ctl);
/* unregister from EDAC MCE */
- amd_report_gart_errors(false);
-
if (boot_cpu_data.x86 >= 0x17)
amd_unregister_ecc_decoder(decode_umc_error);
else
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index abbf3c274d74..52b5d03eeba0 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -120,6 +120,8 @@
#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F6 0x15ee
#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F0 0x1490
#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F6 0x1496
+#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F0 0x1448
+#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F6 0x144e
#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F0 0x1440
#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F6 0x1446
#define PCI_DEVICE_ID_AMD_19H_DF_F0 0x1650
@@ -293,6 +295,7 @@ enum amd_families {
F17_CPUS,
F17_M10H_CPUS,
F17_M30H_CPUS,
+ F17_M60H_CPUS,
F17_M70H_CPUS,
F19_CPUS,
NUM_FAMILIES,
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 75ede27bdf6a..5813e931f2f0 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -43,8 +43,6 @@
int edac_op_state = EDAC_OPSTATE_INVAL;
EXPORT_SYMBOL_GPL(edac_op_state);
-static int edac_report = EDAC_REPORTING_ENABLED;
-
/* lock to memory controller's control array */
static DEFINE_MUTEX(mem_ctls_mutex);
static LIST_HEAD(mc_devices);
@@ -60,65 +58,6 @@ static struct mem_ctl_info *error_desc_to_mci(struct edac_raw_error_desc *e)
return container_of(e, struct mem_ctl_info, error_desc);
}
-int edac_get_report_status(void)
-{
- return edac_report;
-}
-EXPORT_SYMBOL_GPL(edac_get_report_status);
-
-void edac_set_report_status(int new)
-{
- if (new == EDAC_REPORTING_ENABLED ||
- new == EDAC_REPORTING_DISABLED ||
- new == EDAC_REPORTING_FORCE)
- edac_report = new;
-}
-EXPORT_SYMBOL_GPL(edac_set_report_status);
-
-static int edac_report_set(const char *str, const struct kernel_param *kp)
-{
- if (!str)
- return -EINVAL;
-
- if (!strncmp(str, "on", 2))
- edac_report = EDAC_REPORTING_ENABLED;
- else if (!strncmp(str, "off", 3))
- edac_report = EDAC_REPORTING_DISABLED;
- else if (!strncmp(str, "force", 5))
- edac_report = EDAC_REPORTING_FORCE;
-
- return 0;
-}
-
-static int edac_report_get(char *buffer, const struct kernel_param *kp)
-{
- int ret = 0;
-
- switch (edac_report) {
- case EDAC_REPORTING_ENABLED:
- ret = sprintf(buffer, "on");
- break;
- case EDAC_REPORTING_DISABLED:
- ret = sprintf(buffer, "off");
- break;
- case EDAC_REPORTING_FORCE:
- ret = sprintf(buffer, "force");
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static const struct kernel_param_ops edac_report_ops = {
- .set = edac_report_set,
- .get = edac_report_get,
-};
-
-module_param_cb(edac_report, &edac_report_ops, &edac_report, 0644);
-
unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
unsigned int len)
{
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index b3135b208f9a..5860ca41185c 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1815,7 +1815,7 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
struct mem_ctl_info *mci;
i7_dev = get_i7core_dev(mce->socketid);
- if (!i7_dev)
+ if (!i7_dev || (mce->kflags & MCE_HANDLED_CEC))
return NOTIFY_DONE;
mci = i7_dev->mci;
@@ -1834,7 +1834,8 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
i7core_check_error(mci, mce);
/* Advise mcelog that the errors were handled */
- return NOTIFY_STOP;
+ mce->kflags |= MCE_HANDLED_EDAC;
+ return NOTIFY_OK;
}
static struct notifier_block i7_mce_dec = {
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 8874b7722b2f..2b5401db56ad 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -10,15 +10,8 @@ static struct amd_decoder_ops fam_ops;
static u8 xec_mask = 0xf;
-static bool report_gart_errors;
static void (*decode_dram_ecc)(int node_id, struct mce *m);
-void amd_report_gart_errors(bool v)
-{
- report_gart_errors = v;
-}
-EXPORT_SYMBOL_GPL(amd_report_gart_errors);
-
void amd_register_ecc_decoder(void (*f)(int, struct mce *))
{
decode_dram_ecc = f;
@@ -1030,20 +1023,6 @@ static inline void amd_decode_err_code(u16 ec)
pr_cont("\n");
}
-/*
- * Filter out unwanted MCE signatures here.
- */
-static bool ignore_mce(struct mce *m)
-{
- /*
- * NB GART TLB error reporting is disabled by default.
- */
- if (m->bank == 4 && XEC(m->status, 0x1f) == 0x5 && !report_gart_errors)
- return true;
-
- return false;
-}
-
static const char *decode_error_status(struct mce *m)
{
if (m->status & MCI_STATUS_UC) {
@@ -1067,8 +1046,8 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
unsigned int fam = x86_family(m->cpuid);
int ecc;
- if (ignore_mce(m))
- return NOTIFY_STOP;
+ if (m->kflags & MCE_HANDLED_CEC)
+ return NOTIFY_DONE;
pr_emerg(HW_ERR "%s\n", decode_error_status(m));
@@ -1170,7 +1149,8 @@ amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
err_code:
amd_decode_err_code(m->status & 0xffff);
- return NOTIFY_STOP;
+ m->kflags |= MCE_HANDLED_EDAC;
+ return NOTIFY_OK;
}
static struct notifier_block amd_mce_dec_nb = {
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 4e9c5e596c6c..4811b18d9606 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -7,7 +7,6 @@
#include <asm/mce.h>
#define EC(x) ((x) & 0xffff)
-#define XEC(x, mask) (((x) >> 16) & mask)
#define LOW_SYNDROME(x) (((x) >> 15) & 0xff)
#define HIGH_SYNDROME(x) (((x) >> 24) & 0xff)
@@ -77,7 +76,6 @@ struct amd_decoder_ops {
bool (*mc2_mce)(u16, u8);
};
-void amd_report_gart_errors(bool);
void amd_register_ecc_decoder(void (*f)(int, struct mce *));
void amd_unregister_ecc_decoder(void (*f)(int, struct mce *));
diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c
index bc47328eb485..c1f2e6deb021 100644
--- a/drivers/edac/pnd2_edac.c
+++ b/drivers/edac/pnd2_edac.c
@@ -1396,11 +1396,8 @@ static int pnd2_mce_check_error(struct notifier_block *nb, unsigned long val, vo
struct dram_addr daddr;
char *type;
- if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
- return NOTIFY_DONE;
-
mci = pnd2_mci;
- if (!mci)
+ if (!mci || (mce->kflags & MCE_HANDLED_CEC))
return NOTIFY_DONE;
/*
@@ -1429,7 +1426,8 @@ static int pnd2_mce_check_error(struct notifier_block *nb, unsigned long val, vo
pnd2_mce_output_error(mci, mce, &daddr);
/* Advice mcelog that the error were handled */
- return NOTIFY_STOP;
+ mce->kflags |= MCE_HANDLED_EDAC;
+ return NOTIFY_OK;
}
static struct notifier_block pnd2_mce_dec = {
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 7d51c82be62b..d414698ca324 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -3134,7 +3134,7 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
struct mem_ctl_info *mci;
char *type;
- if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
+ if (mce->kflags & MCE_HANDLED_CEC)
return NOTIFY_DONE;
/*
@@ -3183,7 +3183,8 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
sbridge_mce_output_error(mci, mce);
/* Advice mcelog that the error were handled */
- return NOTIFY_STOP;
+ mce->kflags |= MCE_HANDLED_EDAC;
+ return NOTIFY_OK;
}
static struct notifier_block sbridge_mce_dec = {
@@ -3523,8 +3524,6 @@ static int __init sbridge_init(void)
if (rc >= 0) {
mce_register_decode_chain(&sbridge_mce_dec);
- if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
- sbridge_printk(KERN_WARNING, "Loading driver, error reporting disabled.\n");
return 0;
}
diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
index 46be1a77bd1d..6d8d6dc626bf 100644
--- a/drivers/edac/skx_common.c
+++ b/drivers/edac/skx_common.c
@@ -573,7 +573,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
struct mem_ctl_info *mci;
char *type;
- if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
+ if (mce->kflags & MCE_HANDLED_CEC)
return NOTIFY_DONE;
/* ignore unless this is memory related with an address */
@@ -615,6 +615,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
skx_mce_output_error(mci, mce, &res);
+ mce->kflags |= MCE_HANDLED_EDAC;
return NOTIFY_DONE;
}
diff --git a/drivers/eisa/Kconfig b/drivers/eisa/Kconfig
index ffc894b4d782..c8bbf90209f5 100644
--- a/drivers/eisa/Kconfig
+++ b/drivers/eisa/Kconfig
@@ -9,7 +9,7 @@ config HAVE_EISA
menuconfig EISA
bool "EISA support"
depends on HAVE_EISA
- ---help---
+ help
The Extended Industry Standard Architecture (EISA) bus was
developed as an open alternative to the IBM MicroChannel bus.
@@ -26,7 +26,7 @@ config EISA_VLB_PRIMING
bool "Vesa Local Bus priming"
depends on X86 && EISA
default n
- ---help---
+ help
Activate this option if your system contains a Vesa Local
Bus (VLB) card that identify itself as an EISA card (such as
the Adaptec AHA-284x).
@@ -37,7 +37,7 @@ config EISA_PCI_EISA
bool "Generic PCI/EISA bridge"
depends on !PARISC && PCI && EISA
default y
- ---help---
+ help
Activate this option if your system contains a PCI to EISA
bridge. If your system have both PCI and EISA slots, you
certainly need this option.
@@ -51,7 +51,7 @@ config EISA_VIRTUAL_ROOT
bool "EISA virtual root device"
depends on EISA && (ALPHA || X86)
default y
- ---help---
+ help
Activate this option if your system only have EISA bus
(no PCI slots). The Alpha Jensen is an example of such
a system.
@@ -62,7 +62,7 @@ config EISA_NAMES
bool "EISA device name database"
depends on EISA
default y
- ---help---
+ help
By default, the kernel contains a database of all known EISA
device names to make the information in sysfs comprehensible
to the user. This database increases size of the kernel
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 6b38f9e5d203..e6fc022bc87e 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -139,7 +139,7 @@ config EFI_BOOTLOADER_CONTROL
tristate "EFI Bootloader Control"
depends on EFI_VARS
default n
- ---help---
+ help
This module installs a reboot hook, such that if reboot() is
invoked with a string argument NNN, "NNN" is copied to the
"LoaderEntryOneShot" EFI variable, to be read by the
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index b876373f2297..3359ae2adf24 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -18,12 +18,12 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/efi.h>
#include <asm/mmu.h>
#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
#if defined(CONFIG_PTDUMP_DEBUGFS) && defined(CONFIG_ARM64)
#include <asm/ptdump.h>
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 9357d6b6e87c..7f1657b6c30d 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -54,7 +54,7 @@ struct mm_struct efi_mm = {
.mm_rb = RB_ROOT,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
- .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
+ MMAP_LOCK_INITIALIZER(efi_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
.mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
.cpu_bitmap = { [BITS_TO_LONGS(NR_CPUS)] = 0},
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index cce4a7436052..75daaf20374e 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -37,7 +37,9 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \
KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS))
GCOV_PROFILE := n
+# Sanitizer runtimes are unavailable and cannot be linked here.
KASAN_SANITIZE := n
+KCSAN_SANITIZE := n
UBSAN_SANITIZE := n
OBJECT_FILES_NON_STANDARD := y
diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 4cc0e630ab79..e6668a869913 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -7,7 +7,7 @@ menuconfig FSI
tristate "FSI support"
depends on OF
select CRC4
- ---help---
+ help
FSI - the FRU Support Interface - is a simple bus for low-level
access to POWER-based hardware.
@@ -16,7 +16,7 @@ if FSI
config FSI_NEW_DEV_NODE
bool "Create '/dev/fsi' directory for char devices"
default n
- ---help---
+ help
This option causes char devices created for FSI devices to be
located under a common /dev/fsi/ directory. Set to N unless your
userspace has been updated to handle the new location.
@@ -32,12 +32,12 @@ config FSI_MASTER_GPIO
tristate "GPIO-based FSI master"
depends on GPIOLIB
select CRC4
- ---help---
+ help
This option enables a FSI master driver using GPIO lines.
config FSI_MASTER_HUB
tristate "FSI hub master"
- ---help---
+ help
This option enables a FSI hub master driver. Hub is a type of FSI
master that is connected to the upstream master via a slave. Hubs
allow chaining of FSI links to an arbitrary depth. This allows for
@@ -48,7 +48,7 @@ config FSI_MASTER_AST_CF
depends on GPIOLIB
depends on GPIO_ASPEED
select GENERIC_ALLOCATOR
- ---help---
+ help
This option enables a FSI master using the AST2400 and AST2500 GPIO
lines driven by the internal ColdFire coprocessor. This requires
the corresponding machine specific ColdFire firmware to be available.
@@ -64,13 +64,13 @@ config FSI_MASTER_ASPEED
config FSI_SCOM
tristate "SCOM FSI client device driver"
- ---help---
+ help
This option enables an FSI based SCOM device driver.
config FSI_SBEFIFO
tristate "SBEFIFO FSI client device driver"
depends on OF_ADDRESS
- ---help---
+ help
This option enables an FSI based SBEFIFO device driver. The SBEFIFO is
a pipe-like FSI device for communicating with the self boot engine
(SBE) on POWER processors.
@@ -78,7 +78,7 @@ config FSI_SBEFIFO
config FSI_OCC
tristate "OCC SBEFIFO client device driver"
depends on FSI_SBEFIFO
- ---help---
+ help
This option enables an SBEFIFO based On-Chip Controller (OCC) device
driver. The OCC is a device embedded on a POWER processor that collects
and aggregates sensor data from the processor and system. The OCC can
diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig
index a0404ce155a6..bd12e3d57baa 100644
--- a/drivers/gnss/Kconfig
+++ b/drivers/gnss/Kconfig
@@ -5,7 +5,7 @@
menuconfig GNSS
tristate "GNSS receiver support"
- ---help---
+ help
Say Y here if you have a GNSS receiver (e.g. a GPS receiver).
To compile this driver as a module, choose M here: the module will
@@ -32,7 +32,7 @@ config GNSS_MTK_SERIAL
config GNSS_SIRF_SERIAL
tristate "SiRFstar GNSS receiver support"
depends on SERIAL_DEV_BUS
- ---help---
+ help
Say Y here if you have a SiRFstar-based GNSS receiver which uses a
serial interface.
@@ -45,7 +45,7 @@ config GNSS_UBX_SERIAL
tristate "u-blox GNSS receiver support"
depends on SERIAL_DEV_BUS
select GNSS_SERIAL
- ---help---
+ help
Say Y here if you have a u-blox GNSS receiver which uses a serial
interface.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bcacd9c74aa8..c6b5c65c8405 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1236,7 +1236,7 @@ config GPIO_TC3589X
config GPIO_TIMBERDALE
bool "Support for timberdale GPIO IP"
depends on MFD_TIMBERDALE
- ---help---
+ help
Add support for the GPIO IP in the timberdale FPGA.
config GPIO_TPS65086
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 3f2b695cf19e..ffe149aafc39 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -27,6 +27,7 @@
#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/kthread.h>
#include <linux/workqueue.h>
#include <kgd_kfd_interface.h>
#include <drm/ttm/ttm_execbuf_util.h>
@@ -186,7 +187,7 @@ uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *s
* disabled. The memory must be pinned and mapped to the hardware when
* this is called in hqd_load functions, so it should never fault in
* the first place. This resolves a circular lock dependency involving
- * four locks, including the DQM lock and mmap_sem.
+ * four locks, including the DQM lock and mmap_lock.
*/
#define read_user_wptr(mmptr, wptr, dst) \
({ \
@@ -195,10 +196,10 @@ uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *s
pagefault_disable(); \
if ((mmptr) == current->mm) { \
valid = !get_user((dst), (wptr)); \
- } else if (current->mm == NULL) { \
- use_mm(mmptr); \
+ } else if (current->flags & PF_KTHREAD) { \
+ kthread_use_mm(mmptr); \
valid = !get_user((dst), (wptr)); \
- unuse_mm(mmptr); \
+ kthread_unuse_mm(mmptr); \
} \
pagefault_enable(); \
} \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
index 6529caca88fe..35d4a5ab0228 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/fdtable.h>
#include <linux/uaccess.h>
-#include <linux/mmu_context.h>
#include <linux/firmware.h>
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
index 691c89705bcd..bf927f432506 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
@@ -19,7 +19,6 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <linux/mmu_context.h>
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
#include "gc/gc_10_1_0_offset.h"
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index 0b7e78748540..744366c7ee85 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -20,8 +20,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <linux/mmu_context.h>
-
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
#include "cikd.h"
@@ -237,7 +235,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data);
- /* read_user_ptr may take the mm->mmap_sem.
+ /* read_user_ptr may take the mm->mmap_lock.
* release srbm_mutex to avoid circular dependency between
* srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex.
*/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index ccd635b812b5..feab4cc6e836 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -20,8 +20,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <linux/mmu_context.h>
-
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
#include "gfx_v8_0.h"
@@ -224,7 +222,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data);
- /* read_user_ptr may take the mm->mmap_sem.
+ /* read_user_ptr may take the mm->mmap_lock.
* release srbm_mutex to avoid circular dependency between
* srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex.
*/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
index df841c2ac5e7..c7fd0c47b254 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -19,8 +19,6 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <linux/mmu_context.h>
-
#include "amdgpu.h"
#include "amdgpu_amdkfd.h"
#include "gc/gc_9_0_offset.h"
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 68e6e1bc8f3a..b91b5171270f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1393,9 +1393,9 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
* concurrently and the queues are actually stopped
*/
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
- down_write(&current->mm->mmap_sem);
+ mmap_write_lock(current->mm);
is_invalid_userptr = atomic_read(&mem->invalid);
- up_write(&current->mm->mmap_sem);
+ mmap_write_unlock(current->mm);
}
mutex_lock(&mem->lock);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index d7646cbce346..775e389c9a13 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -163,6 +163,9 @@ static ssize_t amdgpu_get_power_dpm_state(struct device *dev,
enum amd_pm_state_type pm;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -196,6 +199,9 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev,
enum amd_pm_state_type state;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (strncmp("battery", buf, strlen("battery")) == 0)
state = POWER_STATE_TYPE_BATTERY;
else if (strncmp("balanced", buf, strlen("balanced")) == 0)
@@ -297,6 +303,9 @@ static ssize_t amdgpu_get_power_dpm_force_performance_level(struct device *dev,
enum amd_dpm_forced_level level = 0xff;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -334,6 +343,9 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev,
enum amd_dpm_forced_level current_level = 0xff;
int ret = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (strncmp("low", buf, strlen("low")) == 0) {
level = AMD_DPM_FORCED_LEVEL_LOW;
} else if (strncmp("high", buf, strlen("high")) == 0) {
@@ -433,6 +445,9 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev,
struct pp_states_info data;
int i, buf_len, ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -472,6 +487,9 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev,
enum amd_pm_state_type pm = 0;
int i = 0, ret = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -508,6 +526,9 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = ddev->dev_private;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (adev->pp_force_state_enabled)
return amdgpu_get_pp_cur_state(dev, attr, buf);
else
@@ -525,6 +546,9 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
unsigned long idx;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (strlen(buf) == 1)
adev->pp_force_state_enabled = false;
else if (is_support_sw_smu(adev))
@@ -580,6 +604,9 @@ static ssize_t amdgpu_get_pp_table(struct device *dev,
char *table = NULL;
int size, ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -619,6 +646,9 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
struct amdgpu_device *adev = ddev->dev_private;
int ret = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -721,6 +751,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
const char delimiter[3] = {' ', '\n', '\0'};
uint32_t type;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (count > 127)
return -EINVAL;
@@ -810,6 +843,9 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -859,6 +895,9 @@ static ssize_t amdgpu_set_pp_features(struct device *dev,
uint64_t featuremask;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = kstrtou64(buf, 0, &featuremask);
if (ret)
return -EINVAL;
@@ -899,6 +938,9 @@ static ssize_t amdgpu_get_pp_features(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -955,6 +997,9 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1018,6 +1063,9 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
int ret;
uint32_t mask = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = amdgpu_read_mask(buf, count, &mask);
if (ret)
return ret;
@@ -1049,6 +1097,9 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1076,6 +1127,9 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
uint32_t mask = 0;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = amdgpu_read_mask(buf, count, &mask);
if (ret)
return ret;
@@ -1107,6 +1161,9 @@ static ssize_t amdgpu_get_pp_dpm_socclk(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1134,6 +1191,9 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev,
int ret;
uint32_t mask = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = amdgpu_read_mask(buf, count, &mask);
if (ret)
return ret;
@@ -1167,6 +1227,9 @@ static ssize_t amdgpu_get_pp_dpm_fclk(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1194,6 +1257,9 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev,
int ret;
uint32_t mask = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = amdgpu_read_mask(buf, count, &mask);
if (ret)
return ret;
@@ -1227,6 +1293,9 @@ static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1254,6 +1323,9 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev,
int ret;
uint32_t mask = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = amdgpu_read_mask(buf, count, &mask);
if (ret)
return ret;
@@ -1287,6 +1359,9 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1314,6 +1389,9 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
int ret;
uint32_t mask = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = amdgpu_read_mask(buf, count, &mask);
if (ret)
return ret;
@@ -1347,6 +1425,9 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev,
uint32_t value = 0;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1372,6 +1453,9 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev,
int ret;
long int value;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = kstrtol(buf, 0, &value);
if (ret)
@@ -1410,6 +1494,9 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev,
uint32_t value = 0;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1435,6 +1522,9 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
int ret;
long int value;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = kstrtol(buf, 0, &value);
if (ret)
@@ -1493,6 +1583,9 @@ static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,
ssize_t size;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(ddev->dev);
if (ret < 0)
return ret;
@@ -1528,6 +1621,9 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
long int profile_mode = 0;
const char delimiter[3] = {' ', '\n', '\0'};
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
tmp[0] = *(buf);
tmp[1] = '\0';
ret = kstrtol(tmp, 0, &profile_mode);
@@ -1587,6 +1683,9 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev,
struct amdgpu_device *adev = ddev->dev_private;
int r, value, size = sizeof(value);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(ddev->dev);
if (r < 0)
return r;
@@ -1620,6 +1719,9 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev,
struct amdgpu_device *adev = ddev->dev_private;
int r, value, size = sizeof(value);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(ddev->dev);
if (r < 0)
return r;
@@ -1658,6 +1760,9 @@ static ssize_t amdgpu_get_pcie_bw(struct device *dev,
uint64_t count0 = 0, count1 = 0;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (adev->flags & AMD_IS_APU)
return -ENODATA;
@@ -1694,6 +1799,9 @@ static ssize_t amdgpu_get_unique_id(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = ddev->dev_private;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (adev->unique_id)
return snprintf(buf, PAGE_SIZE, "%016llx\n", adev->unique_id);
@@ -1888,6 +1996,9 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
int channel = to_sensor_dev_attr(attr)->index;
int r, temp = 0, size = sizeof(temp);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (channel >= PP_TEMP_MAX)
return -EINVAL;
@@ -2019,6 +2130,9 @@ static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev,
u32 pwm_mode = 0;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(adev->ddev->dev);
if (ret < 0)
return ret;
@@ -2050,6 +2164,9 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev,
int err, ret;
int value;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = kstrtoint(buf, 10, &value);
if (err)
return err;
@@ -2099,6 +2216,9 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,
u32 value;
u32 pwm_mode;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = pm_runtime_get_sync(adev->ddev->dev);
if (err < 0)
return err;
@@ -2148,6 +2268,9 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev,
int err;
u32 speed = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = pm_runtime_get_sync(adev->ddev->dev);
if (err < 0)
return err;
@@ -2178,6 +2301,9 @@ static ssize_t amdgpu_hwmon_get_fan1_input(struct device *dev,
int err;
u32 speed = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = pm_runtime_get_sync(adev->ddev->dev);
if (err < 0)
return err;
@@ -2207,6 +2333,9 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev,
u32 size = sizeof(min_rpm);
int r;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2232,6 +2361,9 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,
u32 size = sizeof(max_rpm);
int r;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2256,6 +2388,9 @@ static ssize_t amdgpu_hwmon_get_fan1_target(struct device *dev,
int err;
u32 rpm = 0;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = pm_runtime_get_sync(adev->ddev->dev);
if (err < 0)
return err;
@@ -2285,6 +2420,9 @@ static ssize_t amdgpu_hwmon_set_fan1_target(struct device *dev,
u32 value;
u32 pwm_mode;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = pm_runtime_get_sync(adev->ddev->dev);
if (err < 0)
return err;
@@ -2331,6 +2469,9 @@ static ssize_t amdgpu_hwmon_get_fan1_enable(struct device *dev,
u32 pwm_mode = 0;
int ret;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
ret = pm_runtime_get_sync(adev->ddev->dev);
if (ret < 0)
return ret;
@@ -2363,6 +2504,9 @@ static ssize_t amdgpu_hwmon_set_fan1_enable(struct device *dev,
int value;
u32 pwm_mode;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
err = kstrtoint(buf, 10, &value);
if (err)
return err;
@@ -2403,6 +2547,9 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev,
u32 vddgfx;
int r, size = sizeof(vddgfx);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2435,6 +2582,9 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev,
u32 vddnb;
int r, size = sizeof(vddnb);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
/* only APUs have vddnb */
if (!(adev->flags & AMD_IS_APU))
return -EINVAL;
@@ -2472,6 +2622,9 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
int r, size = sizeof(u32);
unsigned uw;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2508,6 +2661,9 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
ssize_t size;
int r;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2537,6 +2693,9 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
ssize_t size;
int r;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2567,6 +2726,9 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,
int err;
u32 value;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
if (amdgpu_sriov_vf(adev))
return -EINVAL;
@@ -2605,6 +2767,9 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,
uint32_t sclk;
int r, size = sizeof(sclk);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -2637,6 +2802,9 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,
uint32_t mclk;
int r, size = sizeof(mclk);
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(adev->ddev->dev);
if (r < 0)
return r;
@@ -3497,6 +3665,9 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)
u32 flags = 0;
int r;
+ if (adev->in_gpu_reset)
+ return -EPERM;
+
r = pm_runtime_get_sync(dev->dev);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 9cbecd5ba814..e59c01a83dac 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -910,7 +910,7 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
goto out_free_ranges;
}
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = find_vma(mm, start);
if (unlikely(!vma || start < vma->vm_start)) {
r = -EFAULT;
@@ -921,15 +921,15 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
r = -EPERM;
goto out_unlock;
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
retry:
range->notifier_seq = mmu_interval_read_begin(&bo->notifier);
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
r = hmm_range_fault(range);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
if (unlikely(r)) {
/*
* FIXME: This timeout should encompass the retry from
@@ -954,7 +954,7 @@ retry:
return 0;
out_unlock:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
out_free_pfns:
kvfree(range->hmm_pfns);
out_free_ranges:
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index 15476fca8fa6..a9583b95fcc1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -901,7 +901,7 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, unsigned int pasid,
memset(&memory_exception_data, 0, sizeof(memory_exception_data));
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = find_vma(mm, address);
memory_exception_data.gpu_id = dev->id;
@@ -924,7 +924,7 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, unsigned int pasid,
memory_exception_data.failure.NoExecute = 0;
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
pr_debug("notpresent %d, noexecute %d, readonly %d\n",
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 bdba0bfd6df1..7ced9f87be97 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1356,7 +1356,7 @@ static int dm_late_init(void *handle)
unsigned int linear_lut[16];
int i;
struct dmcu *dmcu = NULL;
- bool ret = false;
+ bool ret;
if (!adev->dm.fw_dmcu)
return detect_mst_link_for_all_connectors(adev->ddev);
@@ -1377,13 +1377,10 @@ static int dm_late_init(void *handle)
*/
params.min_abm_backlight = 0x28F;
- /* todo will enable for navi10 */
- if (adev->asic_type <= CHIP_RAVEN) {
- ret = dmcu_load_iram(dmcu, params);
+ ret = dmcu_load_iram(dmcu, params);
- if (!ret)
- return -EINVAL;
- }
+ if (!ret)
+ return -EINVAL;
return detect_mst_link_for_all_connectors(adev->ddev);
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 45cfb7c45566..6f93a6ca4cf0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1016,9 +1016,17 @@ static void program_timing_sync(
}
}
- /* set first pipe with plane as master */
+ /* set first unblanked pipe as master */
for (j = 0; j < group_size; j++) {
- if (pipe_set[j]->plane_state) {
+ bool is_blanked;
+
+ if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
+ is_blanked =
+ pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
+ else
+ is_blanked =
+ pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
+ if (!is_blanked) {
if (j == 0)
break;
@@ -1039,9 +1047,17 @@ static void program_timing_sync(
status->timing_sync_info.master = false;
}
- /* remove any other pipes with plane as they have already been synced */
+ /* remove any other unblanked pipes as they have already been synced */
for (j = j + 1; j < group_size; j++) {
- if (pipe_set[j]->plane_state) {
+ bool is_blanked;
+
+ if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
+ is_blanked =
+ pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
+ else
+ is_blanked =
+ pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
+ if (!is_blanked) {
group_size--;
pipe_set[j] = pipe_set[group_size];
j--;
@@ -2522,6 +2538,12 @@ void dc_commit_updates_for_stream(struct dc *dc,
copy_stream_update_to_stream(dc, context, stream, stream_update);
+ if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
+ DC_ERROR("Mode validation failed for stream update!\n");
+ dc_release_state(context);
+ return;
+ }
+
commit_planes_for_stream(
dc,
srf_updates,
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index ae0361e225bb..aa76c2cea747 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1561,6 +1561,7 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev,
* events for SMCToHost interrupt.
*/
uint32_t ctxid = entry->src_data[0];
+ uint32_t data;
if (client_id == SOC15_IH_CLIENTID_THM) {
switch (src_id) {
@@ -1590,6 +1591,11 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev,
orderly_poweroff(true);
} else if (client_id == SOC15_IH_CLIENTID_MP1) {
if (src_id == 0xfe) {
+ /* ACK SMUToHost interrupt */
+ data = RREG32_SOC15(MP1, 0, mmMP1_SMN_IH_SW_INT_CTRL);
+ data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1);
+ WREG32_SOC15(MP1, 0, mmMP1_SMN_IH_SW_INT_CTRL, data);
+
switch (ctxid) {
case 0x3:
dev_dbg(adev->dev, "Switched to AC mode!\n");
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 7d39b858c9f1..3a3a511670c9 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -226,6 +226,7 @@ static void ast_set_vbios_color_reg(struct ast_private *ast,
case 3:
case 4:
color_index = TrueCModeIndex;
+ break;
default:
return;
}
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 04f876e985de..43271c21d3fc 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -62,7 +62,7 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
depends on OF
select DRM_KMS_HELPER
select DRM_PANEL
- ---help---
+ help
This is a driver for the display bridges of
GE B850v3 that convert dual channel LVDS
to DP++. This is used with the i.MX6 imx-ldb
@@ -89,7 +89,7 @@ config DRM_NXP_PTN3460
depends on OF
select DRM_KMS_HELPER
select DRM_PANEL
- ---help---
+ help
NXP PTN3460 eDP-LVDS bridge chip driver.
config DRM_PARADE_PS8622
@@ -98,7 +98,7 @@ config DRM_PARADE_PS8622
select DRM_PANEL
select DRM_KMS_HELPER
select BACKLIGHT_CLASS_DEVICE
- ---help---
+ help
Parade eDP-LVDS bridge chip driver.
config DRM_PARADE_PS8640
@@ -128,13 +128,13 @@ config DRM_SII902X
select REGMAP_I2C
select I2C_MUX
select SND_SOC_HDMI_CODEC if SND_SOC
- ---help---
+ help
Silicon Image sii902x bridge chip driver.
config DRM_SII9234
tristate "Silicon Image SII9234 HDMI/MHL bridge"
depends on OF
- ---help---
+ help
Say Y here if you want support for the MHL interface.
It is an I2C driver, that detects connection of MHL bridge
and starts encapsulation of HDMI signal.
@@ -150,7 +150,7 @@ config DRM_SIMPLE_BRIDGE
config DRM_THINE_THC63LVD1024
tristate "Thine THC63LVD1024 LVDS decoder bridge"
depends on OF
- ---help---
+ help
Thine THC63LVD1024 LVDS/parallel converter driver.
config DRM_TOSHIBA_TC358764
@@ -168,7 +168,7 @@ config DRM_TOSHIBA_TC358767
select DRM_KMS_HELPER
select REGMAP_I2C
select DRM_PANEL
- ---help---
+ help
Toshiba TC358767 eDP bridge chip driver.
config DRM_TOSHIBA_TC358768
@@ -185,7 +185,7 @@ config DRM_TI_TFP410
tristate "TI TFP410 DVI/HDMI bridge"
depends on OF
select DRM_KMS_HELPER
- ---help---
+ help
Texas Instruments TFP410 DVI/HDMI Transmitter driver
config DRM_TI_SN65DSI86
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b1099e1251a2..d877ddc6dc57 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -27,6 +27,7 @@
#include <drm/drm_print.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
+#include <drm/drm_sysfs.h>
#include <linux/uaccess.h>
@@ -523,6 +524,10 @@ int drm_connector_register(struct drm_connector *connector)
drm_mode_object_register(connector->dev, &connector->base);
connector->registration_state = DRM_CONNECTOR_REGISTERED;
+
+ /* Let userspace know we have a new connector */
+ drm_sysfs_hotplug_event(connector->dev);
+
goto unlock;
err_debugfs:
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 939f0032aab1..f0336c804639 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -291,9 +291,6 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
return PTR_ERR(connector->kdev);
}
- /* Let userspace know we have a new connector */
- drm_sysfs_hotplug_event(dev);
-
if (connector->ddc)
return sysfs_create_link(&connector->kdev->kobj,
&connector->ddc->dev.kobj, "ddc");
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 56197ae0b2f9..4391e242356d 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -37,6 +37,7 @@
#include <linux/pci.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
+#include <linux/pgtable.h>
#if defined(__ia64__)
#include <linux/efi.h>
@@ -44,7 +45,6 @@
#endif
#include <linux/mem_encrypt.h>
-#include <asm/pgtable.h>
#include <drm/drm_agpsupport.h>
#include <drm/drm_device.h>
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef302f517..701f3995f621 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -661,7 +661,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
struct etnaviv_gem_userptr *userptr = &etnaviv_obj->userptr;
int ret, pinned = 0, npages = etnaviv_obj->base.size >> PAGE_SHIFT;
- might_lock_read(&current->mm->mmap_sem);
+ might_lock_read(&current->mm->mmap_lock);
if (userptr->mm != current->mm)
return -EPERM;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 40d42dcff0b7..ed9e53c373a7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5206,6 +5206,9 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
unsigned int type)
{
+ if (encoder->type != INTEL_OUTPUT_DDI)
+ return;
+
switch (type) {
case DP_SDP_VSC:
intel_read_dp_vsc_sdp(encoder, crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c b/drivers/gpu/drm/i915/display/intel_global_state.c
index 212d4ee68205..7a19215ad844 100644
--- a/drivers/gpu/drm/i915/display/intel_global_state.c
+++ b/drivers/gpu/drm/i915/display/intel_global_state.c
@@ -10,6 +10,28 @@
#include "intel_display_types.h"
#include "intel_global_state.h"
+static void __intel_atomic_global_state_free(struct kref *kref)
+{
+ struct intel_global_state *obj_state =
+ container_of(kref, struct intel_global_state, ref);
+ struct intel_global_obj *obj = obj_state->obj;
+
+ obj->funcs->atomic_destroy_state(obj, obj_state);
+}
+
+static void intel_atomic_global_state_put(struct intel_global_state *obj_state)
+{
+ kref_put(&obj_state->ref, __intel_atomic_global_state_free);
+}
+
+static struct intel_global_state *
+intel_atomic_global_state_get(struct intel_global_state *obj_state)
+{
+ kref_get(&obj_state->ref);
+
+ return obj_state;
+}
+
void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv,
struct intel_global_obj *obj,
struct intel_global_state *state,
@@ -17,6 +39,10 @@ void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv,
{
memset(obj, 0, sizeof(*obj));
+ state->obj = obj;
+
+ kref_init(&state->ref);
+
obj->state = state;
obj->funcs = funcs;
list_add_tail(&obj->head, &dev_priv->global_obj_list);
@@ -28,7 +54,9 @@ void intel_atomic_global_obj_cleanup(struct drm_i915_private *dev_priv)
list_for_each_entry_safe(obj, next, &dev_priv->global_obj_list, head) {
list_del(&obj->head);
- obj->funcs->atomic_destroy_state(obj, obj->state);
+
+ drm_WARN_ON(&dev_priv->drm, kref_read(&obj->state->ref) != 1);
+ intel_atomic_global_state_put(obj->state);
}
}
@@ -97,10 +125,14 @@ intel_atomic_get_global_obj_state(struct intel_atomic_state *state,
if (!obj_state)
return ERR_PTR(-ENOMEM);
+ obj_state->obj = obj;
obj_state->changed = false;
+ kref_init(&obj_state->ref);
+
state->global_objs[index].state = obj_state;
- state->global_objs[index].old_state = obj->state;
+ state->global_objs[index].old_state =
+ intel_atomic_global_state_get(obj->state);
state->global_objs[index].new_state = obj_state;
state->global_objs[index].ptr = obj;
obj_state->state = state;
@@ -163,7 +195,9 @@ void intel_atomic_swap_global_state(struct intel_atomic_state *state)
new_obj_state->state = NULL;
state->global_objs[i].state = old_obj_state;
- obj->state = new_obj_state;
+
+ intel_atomic_global_state_put(obj->state);
+ obj->state = intel_atomic_global_state_get(new_obj_state);
}
}
@@ -172,10 +206,9 @@ void intel_atomic_clear_global_state(struct intel_atomic_state *state)
int i;
for (i = 0; i < state->num_global_objs; i++) {
- struct intel_global_obj *obj = state->global_objs[i].ptr;
+ intel_atomic_global_state_put(state->global_objs[i].old_state);
+ intel_atomic_global_state_put(state->global_objs[i].new_state);
- obj->funcs->atomic_destroy_state(obj,
- state->global_objs[i].state);
state->global_objs[i].ptr = NULL;
state->global_objs[i].state = NULL;
state->global_objs[i].old_state = NULL;
diff --git a/drivers/gpu/drm/i915/display/intel_global_state.h b/drivers/gpu/drm/i915/display/intel_global_state.h
index e6163a469029..1f16fa3073c9 100644
--- a/drivers/gpu/drm/i915/display/intel_global_state.h
+++ b/drivers/gpu/drm/i915/display/intel_global_state.h
@@ -6,6 +6,7 @@
#ifndef __INTEL_GLOBAL_STATE_H__
#define __INTEL_GLOBAL_STATE_H__
+#include <linux/kref.h>
#include <linux/list.h>
struct drm_i915_private;
@@ -54,7 +55,9 @@ struct intel_global_obj {
for_each_if(obj)
struct intel_global_state {
+ struct intel_global_obj *obj;
struct intel_atomic_state *state;
+ struct kref ref;
bool changed;
};
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 900ea8b7fc8f..30c229fcb404 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -230,7 +230,7 @@ static void intel_context_set_gem(struct intel_context *ce,
ce->timeline = intel_timeline_get(ctx->timeline);
if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
- intel_engine_has_semaphores(ce->engine))
+ intel_engine_has_timeslices(ce->engine))
__set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
}
@@ -1921,11 +1921,6 @@ get_engines(struct i915_gem_context *ctx,
}
user = u64_to_user_ptr(args->value);
- if (!access_ok(user, size)) {
- err = -EFAULT;
- goto err_free;
- }
-
if (put_user(0, &user->extensions)) {
err = -EFAULT;
goto err_free;
@@ -1969,7 +1964,7 @@ static int __apply_priority(struct intel_context *ce, void *arg)
{
struct i915_gem_context *ctx = arg;
- if (!intel_engine_has_semaphores(ce->engine))
+ if (!intel_engine_has_timeslices(ce->engine))
return 0;
if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 3ce185670ca4..db8eb1c6afe9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1988,6 +1988,38 @@ static const struct dma_fence_work_ops eb_parse_ops = {
.release = __eb_parse_release,
};
+static inline int
+__parser_mark_active(struct i915_vma *vma,
+ struct intel_timeline *tl,
+ struct dma_fence *fence)
+{
+ struct intel_gt_buffer_pool_node *node = vma->private;
+
+ return i915_active_ref(&node->active, tl, fence);
+}
+
+static int
+parser_mark_active(struct eb_parse_work *pw, struct intel_timeline *tl)
+{
+ int err;
+
+ mutex_lock(&tl->mutex);
+
+ err = __parser_mark_active(pw->shadow, tl, &pw->base.dma);
+ if (err)
+ goto unlock;
+
+ if (pw->trampoline) {
+ err = __parser_mark_active(pw->trampoline, tl, &pw->base.dma);
+ if (err)
+ goto unlock;
+ }
+
+unlock:
+ mutex_unlock(&tl->mutex);
+ return err;
+}
+
static int eb_parse_pipeline(struct i915_execbuffer *eb,
struct i915_vma *shadow,
struct i915_vma *trampoline)
@@ -2022,20 +2054,25 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
pw->shadow = shadow;
pw->trampoline = trampoline;
+ /* Mark active refs early for this worker, in case we get interrupted */
+ err = parser_mark_active(pw, eb->context->timeline);
+ if (err)
+ goto err_commit;
+
err = dma_resv_lock_interruptible(pw->batch->resv, NULL);
if (err)
- goto err_trampoline;
+ goto err_commit;
err = dma_resv_reserve_shared(pw->batch->resv, 1);
if (err)
- goto err_batch_unlock;
+ goto err_commit_unlock;
/* Wait for all writes (and relocs) into the batch to complete */
err = i915_sw_fence_await_reservation(&pw->base.chain,
pw->batch->resv, NULL, false,
0, I915_FENCE_GFP);
if (err < 0)
- goto err_batch_unlock;
+ goto err_commit_unlock;
/* Keep the batch alive and unwritten as we parse */
dma_resv_add_shared_fence(pw->batch->resv, &pw->base.dma);
@@ -2050,11 +2087,13 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
dma_fence_work_commit_imm(&pw->base);
return 0;
-err_batch_unlock:
+err_commit_unlock:
dma_resv_unlock(pw->batch->resv);
-err_trampoline:
- if (trampoline)
- i915_active_release(&trampoline->active);
+err_commit:
+ i915_sw_fence_set_error_once(&pw->base.chain, err);
+ dma_fence_work_commit_imm(&pw->base);
+ return err;
+
err_shadow:
i915_active_release(&shadow->active);
err_batch:
@@ -2100,6 +2139,7 @@ static int eb_parse(struct i915_execbuffer *eb)
goto err;
}
i915_gem_object_set_readonly(shadow->obj);
+ shadow->private = pool;
trampoline = NULL;
if (CMDPARSER_USES_GGTT(eb->i915)) {
@@ -2113,6 +2153,7 @@ static int eb_parse(struct i915_execbuffer *eb)
shadow = trampoline;
goto err_shadow;
}
+ shadow->private = pool;
eb->batch_flags |= I915_DISPATCH_SECURE;
}
@@ -2129,7 +2170,6 @@ static int eb_parse(struct i915_execbuffer *eb)
eb->trampoline = trampoline;
eb->batch_start_offset = 0;
- shadow->private = pool;
return 0;
err_trampoline:
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 70f5f82da288..fe45bd4d63a5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -93,7 +93,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- if (down_write_killable(&mm->mmap_sem)) {
+ if (mmap_write_lock_killable(mm)) {
addr = -EINTR;
goto err;
}
@@ -103,7 +103,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
else
addr = -ENOMEM;
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
if (IS_ERR_VALUE(addr))
goto err;
}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7eef3f43..7aff3514d97a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -39,7 +39,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
unsigned long last_pfn = 0; /* suppress gcc warning */
unsigned int max_segment = i915_sg_segment_size();
unsigned int sg_page_sizes;
- struct pagevec pvec;
gfp_t noreclaim;
int ret;
@@ -192,13 +191,17 @@ err_sg:
sg_mark_end(sg);
err_pages:
mapping_clear_unevictable(mapping);
- pagevec_init(&pvec);
- for_each_sgt_page(page, sgt_iter, st) {
- if (!pagevec_add(&pvec, page))
+ if (sg != st->sgl) {
+ struct pagevec pvec;
+
+ pagevec_init(&pvec);
+ for_each_sgt_page(page, sgt_iter, st) {
+ if (!pagevec_add(&pvec, page))
+ check_release_pagevec(&pvec);
+ }
+ if (pagevec_count(&pvec))
check_release_pagevec(&pvec);
}
- if (pagevec_count(&pvec))
- check_release_pagevec(&pvec);
sg_free_table(st);
kfree(st);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 33776b3f3fa5..c31a6744daee 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -200,10 +200,10 @@ i915_mmu_notifier_find(struct i915_mm_struct *mm)
if (IS_ERR(mn))
err = PTR_ERR(mn);
- down_write(&mm->mm->mmap_sem);
+ mmap_write_lock(mm->mm);
mutex_lock(&mm->i915->mm_lock);
if (mm->mn == NULL && !err) {
- /* Protected by mmap_sem (write-lock) */
+ /* Protected by mmap_lock (write-lock) */
err = __mmu_notifier_register(&mn->mn, mm->mm);
if (!err) {
/* Protected by mm_lock */
@@ -217,7 +217,7 @@ i915_mmu_notifier_find(struct i915_mm_struct *mm)
err = 0;
}
mutex_unlock(&mm->i915->mm_lock);
- up_write(&mm->mm->mmap_sem);
+ mmap_write_unlock(mm->mm);
if (mn && !IS_ERR(mn))
kfree(mn);
@@ -468,7 +468,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
if (mmget_not_zero(mm)) {
while (pinned < npages) {
if (!locked) {
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
locked = 1;
}
ret = pin_user_pages_remote
@@ -483,7 +483,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
pinned += ret;
}
if (locked)
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
}
}
@@ -522,8 +522,8 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj)
/* Spawn a worker so that we can acquire the
* user pages without holding our mutex. Access
- * to the user pages requires mmap_sem, and we have
- * a strict lock ordering of mmap_sem, struct_mutex -
+ * to the user pages requires mmap_lock, and we have
+ * a strict lock ordering of mmap_lock, struct_mutex -
* we already hold struct_mutex here and so cannot
* call gup without encountering a lock inversion.
*
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 74ddb49b2941..e4aece20bc80 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -97,8 +97,6 @@ int __intel_context_do_pin(struct intel_context *ce)
{
int err;
- GEM_BUG_ON(intel_context_is_closed(ce));
-
if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
err = intel_context_alloc_state(ce);
if (err)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index eee530453aa6..ad8a9df49f29 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -31,7 +31,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/mm.h>
-#include <linux/mmu_context.h>
+#include <linux/kthread.h>
#include <linux/sched/mm.h>
#include <linux/types.h>
#include <linux/list.h>
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 1d5ff88078bd..7d361623ff67 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -124,7 +124,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
*/
low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
- num_types = sizeof(vgpu_types) / sizeof(vgpu_types[0]);
+ num_types = ARRAY_SIZE(vgpu_types);
gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type),
GFP_KERNEL);
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 189b573d02be..372354d33f55 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -572,6 +572,9 @@ struct drm_i915_reg_descriptor {
#define REG32(_reg, ...) \
{ .addr = (_reg), __VA_ARGS__ }
+#define REG32_IDX(_reg, idx) \
+ { .addr = _reg(idx) }
+
/*
* Convenience macro for adding 64-bit registers.
*
@@ -669,6 +672,7 @@ static const struct drm_i915_reg_descriptor gen9_blt_regs[] = {
REG64_IDX(RING_TIMESTAMP, BSD_RING_BASE),
REG32(BCS_SWCTRL),
REG64_IDX(RING_TIMESTAMP, BLT_RING_BASE),
+ REG32_IDX(RING_CTX_TIMESTAMP, BLT_RING_BASE),
REG64_IDX(BCS_GPR, 0),
REG64_IDX(BCS_GPR, 1),
REG64_IDX(BCS_GPR, 2),
diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c
index 8e45ca3d2ede..55b97c3a3dde 100644
--- a/drivers/gpu/drm/i915/i915_ioc32.c
+++ b/drivers/gpu/drm/i915/i915_ioc32.c
@@ -47,20 +47,16 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct drm_i915_getparam32 req32;
- drm_i915_getparam_t __user *request;
+ struct drm_i915_getparam req;
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
- request = compat_alloc_user_space(sizeof(*request));
- if (!access_ok(request, sizeof(*request)) ||
- __put_user(req32.param, &request->param) ||
- __put_user((void __user *)(unsigned long)req32.value,
- &request->value))
- return -EFAULT;
+ req.param = req32.param;
+ req.value = compat_ptr(req32.value);
- return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
- (unsigned long)request);
+ return drm_ioctl_kernel(file, i915_getparam_ioctl, &req,
+ DRM_RENDER_ALLOW);
}
static drm_ioctl_compat_t *i915_compat_ioctls[] = {
diff --git a/drivers/gpu/drm/i915/i915_mm.c b/drivers/gpu/drm/i915/i915_mm.c
index b6376b25ef63..43039dc8c607 100644
--- a/drivers/gpu/drm/i915/i915_mm.c
+++ b/drivers/gpu/drm/i915/i915_mm.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/io-mapping.h>
-#include <asm/pgtable.h>
#include "i915_drv.h"
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index add00ec1f787..02559da61e6e 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -65,7 +65,7 @@ i915_param_named_unsafe(vbt_sdvo_panel_type, int, 0400,
"Override/Ignore selection of SDVO panel mode in the VBT "
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
-i915_param_named_unsafe(reset, int, 0600,
+i915_param_named_unsafe(reset, uint, 0600,
"Attempt GPU resets (0=disabled, 1=full gpu reset, 2=engine reset [default])");
i915_param_named_unsafe(vbt_firmware, charp, 0400,
@@ -173,7 +173,7 @@ i915_param_named(enable_gvt, bool, 0400,
#endif
#if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)
-i915_param_named_unsafe(fake_lmem_start, ulong, 0600,
+i915_param_named_unsafe(fake_lmem_start, ulong, 0400,
"Fake LMEM start offset (default: 0)");
#endif
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 45323732f099..4f21bfffbf0e 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -64,7 +64,7 @@ struct drm_printer;
param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \
param(int, edp_vswing, 0, 0400) \
param(unsigned int, reset, 3, 0600) \
- param(unsigned int, inject_probe_failure, 0, 0600) \
+ param(unsigned int, inject_probe_failure, 0, 0) \
param(int, fastboot, -1, 0600) \
param(int, enable_dpcd_backlight, -1, 0600) \
param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 75c60c2afb7e..25329b7600c9 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -3676,7 +3676,7 @@ static int read_properties_unlocked(struct i915_perf *perf,
* buffered data written by the GPU besides periodic OA metrics.
*
* Note we copy the properties from userspace outside of the i915 perf
- * mutex to avoid an awkward lockdep with mmap_sem.
+ * mutex to avoid an awkward lockdep with mmap_lock.
*
* Most of the implementation details are handled by
* i915_perf_open_ioctl_locked() after taking the &perf->lock
@@ -3896,9 +3896,6 @@ static struct i915_oa_reg *alloc_oa_regs(struct i915_perf *perf,
if (!n_regs)
return NULL;
- if (!access_ok(regs, n_regs * sizeof(u32) * 2))
- return ERR_PTR(-EFAULT);
-
/* No is_valid function means we're not allowing any register to be programmed. */
GEM_BUG_ON(!is_valid);
if (!is_valid)
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index ef25ce6e395e..e75c528ebbe0 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -25,10 +25,6 @@ static int copy_query_item(void *query_hdr, size_t query_sz,
query_sz))
return -EFAULT;
- if (!access_ok(u64_to_user_ptr(query_item->data_ptr),
- total_length))
- return -EFAULT;
-
return 0;
}
@@ -72,20 +68,20 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
topo.eu_offset = slice_length + subslice_length;
topo.eu_stride = sseu->eu_stride;
- if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr),
+ if (copy_to_user(u64_to_user_ptr(query_item->data_ptr),
&topo, sizeof(topo)))
return -EFAULT;
- if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr + sizeof(topo)),
+ if (copy_to_user(u64_to_user_ptr(query_item->data_ptr + sizeof(topo)),
&sseu->slice_mask, slice_length))
return -EFAULT;
- if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr +
+ if (copy_to_user(u64_to_user_ptr(query_item->data_ptr +
sizeof(topo) + slice_length),
sseu->subslice_mask, subslice_length))
return -EFAULT;
- if (__copy_to_user(u64_to_user_ptr(query_item->data_ptr +
+ if (copy_to_user(u64_to_user_ptr(query_item->data_ptr +
sizeof(topo) +
slice_length + subslice_length),
sseu->eu_mask, eu_length))
@@ -131,14 +127,14 @@ query_engine_info(struct drm_i915_private *i915,
info.engine.engine_instance = engine->uabi_instance;
info.capabilities = engine->uabi_capabilities;
- if (__copy_to_user(info_ptr, &info, sizeof(info)))
+ if (copy_to_user(info_ptr, &info, sizeof(info)))
return -EFAULT;
query.num_engines++;
info_ptr++;
}
- if (__copy_to_user(query_ptr, &query, sizeof(query)))
+ if (copy_to_user(query_ptr, &query, sizeof(query)))
return -EFAULT;
return len;
@@ -158,10 +154,6 @@ static int can_copy_perf_config_registers_or_number(u32 user_n_regs,
if (user_n_regs < kernel_n_regs)
return -EINVAL;
- if (!access_ok(u64_to_user_ptr(user_regs_ptr),
- 2 * sizeof(u32) * kernel_n_regs))
- return -EFAULT;
-
return 0;
}
@@ -170,6 +162,7 @@ static int copy_perf_config_registers_or_number(const struct i915_oa_reg *kernel
u64 user_regs_ptr,
u32 *user_n_regs)
{
+ u32 __user *p = u64_to_user_ptr(user_regs_ptr);
u32 r;
if (*user_n_regs == 0) {
@@ -179,25 +172,19 @@ static int copy_perf_config_registers_or_number(const struct i915_oa_reg *kernel
*user_n_regs = kernel_n_regs;
- for (r = 0; r < kernel_n_regs; r++) {
- u32 __user *user_reg_ptr =
- u64_to_user_ptr(user_regs_ptr + sizeof(u32) * r * 2);
- u32 __user *user_val_ptr =
- u64_to_user_ptr(user_regs_ptr + sizeof(u32) * r * 2 +
- sizeof(u32));
- int ret;
-
- ret = __put_user(i915_mmio_reg_offset(kernel_regs[r].addr),
- user_reg_ptr);
- if (ret)
- return -EFAULT;
+ if (!user_write_access_begin(p, 2 * sizeof(u32) * kernel_n_regs))
+ return -EFAULT;
- ret = __put_user(kernel_regs[r].value, user_val_ptr);
- if (ret)
- return -EFAULT;
+ for (r = 0; r < kernel_n_regs; r++, p += 2) {
+ unsafe_put_user(i915_mmio_reg_offset(kernel_regs[r].addr),
+ p, Efault);
+ unsafe_put_user(kernel_regs[r].value, p + 1, Efault);
}
-
+ user_write_access_end();
return 0;
+Efault:
+ user_write_access_end();
+ return -EFAULT;
}
static int query_perf_config_data(struct drm_i915_private *i915,
@@ -233,10 +220,7 @@ static int query_perf_config_data(struct drm_i915_private *i915,
return -EINVAL;
}
- if (!access_ok(user_query_config_ptr, total_size))
- return -EFAULT;
-
- if (__get_user(flags, &user_query_config_ptr->flags))
+ if (get_user(flags, &user_query_config_ptr->flags))
return -EFAULT;
if (flags != 0)
@@ -249,7 +233,7 @@ static int query_perf_config_data(struct drm_i915_private *i915,
BUILD_BUG_ON(sizeof(user_query_config_ptr->uuid) >= sizeof(uuid));
memset(&uuid, 0, sizeof(uuid));
- if (__copy_from_user(uuid, user_query_config_ptr->uuid,
+ if (copy_from_user(uuid, user_query_config_ptr->uuid,
sizeof(user_query_config_ptr->uuid)))
return -EFAULT;
@@ -263,7 +247,7 @@ static int query_perf_config_data(struct drm_i915_private *i915,
}
rcu_read_unlock();
} else {
- if (__get_user(config_id, &user_query_config_ptr->config))
+ if (get_user(config_id, &user_query_config_ptr->config))
return -EFAULT;
oa_config = i915_perf_get_oa_config(perf, config_id);
@@ -271,8 +255,7 @@ static int query_perf_config_data(struct drm_i915_private *i915,
if (!oa_config)
return -ENOENT;
- if (__copy_from_user(&user_config, user_config_ptr,
- sizeof(user_config))) {
+ if (copy_from_user(&user_config, user_config_ptr, sizeof(user_config))) {
ret = -EFAULT;
goto out;
}
@@ -318,8 +301,7 @@ static int query_perf_config_data(struct drm_i915_private *i915,
memcpy(user_config.uuid, oa_config->uuid, sizeof(user_config.uuid));
- if (__copy_to_user(user_config_ptr, &user_config,
- sizeof(user_config))) {
+ if (copy_to_user(user_config_ptr, &user_config, sizeof(user_config))) {
ret = -EFAULT;
goto out;
}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6c076a24eb82..7717581350bd 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -186,7 +186,7 @@ typedef struct {
#define INVALID_MMIO_REG _MMIO(0)
-static inline u32 i915_mmio_reg_offset(i915_reg_t reg)
+static __always_inline u32 i915_mmio_reg_offset(i915_reg_t reg)
{
return reg.reg;
}
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 526c1e9acbd5..def62100e666 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -121,8 +121,39 @@ static void i915_fence_release(struct dma_fence *fence)
i915_sw_fence_fini(&rq->submit);
i915_sw_fence_fini(&rq->semaphore);
- /* Keep one request on each engine for reserved use under mempressure */
- if (!cmpxchg(&rq->engine->request_pool, NULL, rq))
+ /*
+ * Keep one request on each engine for reserved use under mempressure
+ *
+ * We do not hold a reference to the engine here and so have to be
+ * very careful in what rq->engine we poke. The virtual engine is
+ * referenced via the rq->context and we released that ref during
+ * i915_request_retire(), ergo we must not dereference a virtual
+ * engine here. Not that we would want to, as the only consumer of
+ * the reserved engine->request_pool is the power management parking,
+ * which must-not-fail, and that is only run on the physical engines.
+ *
+ * Since the request must have been executed to be have completed,
+ * we know that it will have been processed by the HW and will
+ * not be unsubmitted again, so rq->engine and rq->execution_mask
+ * at this point is stable. rq->execution_mask will be a single
+ * bit if the last and _only_ engine it could execution on was a
+ * physical engine, if it's multiple bits then it started on and
+ * could still be on a virtual engine. Thus if the mask is not a
+ * power-of-two we assume that rq->engine may still be a virtual
+ * engine and so a dangling invalid pointer that we cannot dereference
+ *
+ * For example, consider the flow of a bonded request through a virtual
+ * engine. The request is created with a wide engine mask (all engines
+ * that we might execute on). On processing the bond, the request mask
+ * is reduced to one or more engines. If the request is subsequently
+ * bound to a single engine, it will then be constrained to only
+ * execute on that engine and never returned to the virtual engine
+ * after timeslicing away, see __unwind_incomplete_requests(). Thus we
+ * know that if the rq->execution_mask is a single bit, rq->engine
+ * can be a physical engine with the exact corresponding mask.
+ */
+ if (is_power_of_2(rq->execution_mask) &&
+ !cmpxchg(&rq->engine->request_pool, NULL, rq))
return;
kmem_cache_free(global.slab_requests, rq);
@@ -326,6 +357,53 @@ void i915_request_retire_upto(struct i915_request *rq)
} while (i915_request_retire(tmp) && tmp != rq);
}
+static struct i915_request * const *
+__engine_active(struct intel_engine_cs *engine)
+{
+ return READ_ONCE(engine->execlists.active);
+}
+
+static bool __request_in_flight(const struct i915_request *signal)
+{
+ struct i915_request * const *port, *rq;
+ bool inflight = false;
+
+ if (!i915_request_is_ready(signal))
+ return false;
+
+ /*
+ * Even if we have unwound the request, it may still be on
+ * the GPU (preempt-to-busy). If that request is inside an
+ * unpreemptible critical section, it will not be removed. Some
+ * GPU functions may even be stuck waiting for the paired request
+ * (__await_execution) to be submitted and cannot be preempted
+ * until the bond is executing.
+ *
+ * As we know that there are always preemption points between
+ * requests, we know that only the currently executing request
+ * may be still active even though we have cleared the flag.
+ * However, we can't rely on our tracking of ELSP[0] to known
+ * which request is currently active and so maybe stuck, as
+ * the tracking maybe an event behind. Instead assume that
+ * if the context is still inflight, then it is still active
+ * even if the active flag has been cleared.
+ */
+ if (!intel_context_inflight(signal->context))
+ return false;
+
+ rcu_read_lock();
+ for (port = __engine_active(signal->engine); (rq = *port); port++) {
+ if (rq->context == signal->context) {
+ inflight = i915_seqno_passed(rq->fence.seqno,
+ signal->fence.seqno);
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ return inflight;
+}
+
static int
__await_execution(struct i915_request *rq,
struct i915_request *signal,
@@ -356,7 +434,7 @@ __await_execution(struct i915_request *rq,
}
spin_lock_irq(&signal->lock);
- if (i915_request_is_active(signal)) {
+ if (i915_request_is_active(signal) || __request_in_flight(signal)) {
if (hook) {
hook(rq, &signal->fence);
i915_request_put(signal);
@@ -1022,37 +1100,91 @@ await_fence:
I915_FENCE_GFP);
}
+static bool intel_timeline_sync_has_start(struct intel_timeline *tl,
+ struct dma_fence *fence)
+{
+ return __intel_timeline_sync_is_later(tl,
+ fence->context,
+ fence->seqno - 1);
+}
+
+static int intel_timeline_sync_set_start(struct intel_timeline *tl,
+ const struct dma_fence *fence)
+{
+ return __intel_timeline_sync_set(tl, fence->context, fence->seqno - 1);
+}
+
static int
-i915_request_await_request(struct i915_request *to, struct i915_request *from)
+__i915_request_await_execution(struct i915_request *to,
+ struct i915_request *from,
+ void (*hook)(struct i915_request *rq,
+ struct dma_fence *signal))
{
- int ret;
+ int err;
- GEM_BUG_ON(to == from);
- GEM_BUG_ON(to->timeline == from->timeline);
+ GEM_BUG_ON(intel_context_is_barrier(from->context));
- if (i915_request_completed(from)) {
- i915_sw_fence_set_error_once(&to->submit, from->fence.error);
+ /* Submit both requests at the same time */
+ err = __await_execution(to, from, hook, I915_FENCE_GFP);
+ if (err)
+ return err;
+
+ /* Squash repeated depenendices to the same timelines */
+ if (intel_timeline_sync_has_start(i915_request_timeline(to),
+ &from->fence))
return 0;
+
+ /*
+ * Wait until the start of this request.
+ *
+ * The execution cb fires when we submit the request to HW. But in
+ * many cases this may be long before the request itself is ready to
+ * run (consider that we submit 2 requests for the same context, where
+ * the request of interest is behind an indefinite spinner). So we hook
+ * up to both to reduce our queues and keep the execution lag minimised
+ * in the worst case, though we hope that the await_start is elided.
+ */
+ err = i915_request_await_start(to, from);
+ if (err < 0)
+ return err;
+
+ /*
+ * Ensure both start together [after all semaphores in signal]
+ *
+ * Now that we are queued to the HW at roughly the same time (thanks
+ * to the execute cb) and are ready to run at roughly the same time
+ * (thanks to the await start), our signaler may still be indefinitely
+ * delayed by waiting on a semaphore from a remote engine. If our
+ * signaler depends on a semaphore, so indirectly do we, and we do not
+ * want to start our payload until our signaler also starts theirs.
+ * So we wait.
+ *
+ * However, there is also a second condition for which we need to wait
+ * for the precise start of the signaler. Consider that the signaler
+ * was submitted in a chain of requests following another context
+ * (with just an ordinary intra-engine fence dependency between the
+ * two). In this case the signaler is queued to HW, but not for
+ * immediate execution, and so we must wait until it reaches the
+ * active slot.
+ */
+ if (intel_engine_has_semaphores(to->engine) &&
+ !i915_request_has_initial_breadcrumb(to)) {
+ err = __emit_semaphore_wait(to, from, from->fence.seqno - 1);
+ if (err < 0)
+ return err;
}
+ /* Couple the dependency tree for PI on this exposed to->fence */
if (to->engine->schedule) {
- ret = i915_sched_node_add_dependency(&to->sched,
+ err = i915_sched_node_add_dependency(&to->sched,
&from->sched,
- I915_DEPENDENCY_EXTERNAL);
- if (ret < 0)
- return ret;
+ I915_DEPENDENCY_WEAK);
+ if (err < 0)
+ return err;
}
- if (to->engine == from->engine)
- ret = i915_sw_fence_await_sw_fence_gfp(&to->submit,
- &from->submit,
- I915_FENCE_GFP);
- else
- ret = emit_semaphore_wait(to, from, I915_FENCE_GFP);
- if (ret < 0)
- return ret;
-
- return 0;
+ return intel_timeline_sync_set_start(i915_request_timeline(to),
+ &from->fence);
}
static void mark_external(struct i915_request *rq)
@@ -1105,23 +1237,20 @@ i915_request_await_external(struct i915_request *rq, struct dma_fence *fence)
}
int
-i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
+i915_request_await_execution(struct i915_request *rq,
+ struct dma_fence *fence,
+ void (*hook)(struct i915_request *rq,
+ struct dma_fence *signal))
{
struct dma_fence **child = &fence;
unsigned int nchild = 1;
int ret;
- /*
- * Note that if the fence-array was created in signal-on-any mode,
- * we should *not* decompose it into its individual fences. However,
- * we don't currently store which mode the fence-array is operating
- * in. Fortunately, the only user of signal-on-any is private to
- * amdgpu and we should not see any incoming fence-array from
- * sync-file being in signal-on-any mode.
- */
if (dma_fence_is_array(fence)) {
struct dma_fence_array *array = to_dma_fence_array(fence);
+ /* XXX Error for signal-on-any fence arrays */
+
child = array->fences;
nchild = array->num_fences;
GEM_BUG_ON(!nchild);
@@ -1134,138 +1263,95 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
continue;
}
- /*
- * Requests on the same timeline are explicitly ordered, along
- * with their dependencies, by i915_request_add() which ensures
- * that requests are submitted in-order through each ring.
- */
if (fence->context == rq->fence.context)
continue;
- /* Squash repeated waits to the same timelines */
- if (fence->context &&
- intel_timeline_sync_is_later(i915_request_timeline(rq),
- fence))
- continue;
+ /*
+ * We don't squash repeated fence dependencies here as we
+ * want to run our callback in all cases.
+ */
if (dma_fence_is_i915(fence))
- ret = i915_request_await_request(rq, to_request(fence));
+ ret = __i915_request_await_execution(rq,
+ to_request(fence),
+ hook);
else
ret = i915_request_await_external(rq, fence);
if (ret < 0)
return ret;
-
- /* Record the latest fence used against each timeline */
- if (fence->context)
- intel_timeline_sync_set(i915_request_timeline(rq),
- fence);
} while (--nchild);
return 0;
}
-static bool intel_timeline_sync_has_start(struct intel_timeline *tl,
- struct dma_fence *fence)
-{
- return __intel_timeline_sync_is_later(tl,
- fence->context,
- fence->seqno - 1);
-}
-
-static int intel_timeline_sync_set_start(struct intel_timeline *tl,
- const struct dma_fence *fence)
+static int
+await_request_submit(struct i915_request *to, struct i915_request *from)
{
- return __intel_timeline_sync_set(tl, fence->context, fence->seqno - 1);
+ /*
+ * If we are waiting on a virtual engine, then it may be
+ * constrained to execute on a single engine *prior* to submission.
+ * When it is submitted, it will be first submitted to the virtual
+ * engine and then passed to the physical engine. We cannot allow
+ * the waiter to be submitted immediately to the physical engine
+ * as it may then bypass the virtual request.
+ */
+ if (to->engine == READ_ONCE(from->engine))
+ return i915_sw_fence_await_sw_fence_gfp(&to->submit,
+ &from->submit,
+ I915_FENCE_GFP);
+ else
+ return __i915_request_await_execution(to, from, NULL);
}
static int
-__i915_request_await_execution(struct i915_request *to,
- struct i915_request *from,
- void (*hook)(struct i915_request *rq,
- struct dma_fence *signal))
+i915_request_await_request(struct i915_request *to, struct i915_request *from)
{
- int err;
-
- GEM_BUG_ON(intel_context_is_barrier(from->context));
+ int ret;
- /* Submit both requests at the same time */
- err = __await_execution(to, from, hook, I915_FENCE_GFP);
- if (err)
- return err;
+ GEM_BUG_ON(to == from);
+ GEM_BUG_ON(to->timeline == from->timeline);
- /* Squash repeated depenendices to the same timelines */
- if (intel_timeline_sync_has_start(i915_request_timeline(to),
- &from->fence))
+ if (i915_request_completed(from)) {
+ i915_sw_fence_set_error_once(&to->submit, from->fence.error);
return 0;
-
- /*
- * Wait until the start of this request.
- *
- * The execution cb fires when we submit the request to HW. But in
- * many cases this may be long before the request itself is ready to
- * run (consider that we submit 2 requests for the same context, where
- * the request of interest is behind an indefinite spinner). So we hook
- * up to both to reduce our queues and keep the execution lag minimised
- * in the worst case, though we hope that the await_start is elided.
- */
- err = i915_request_await_start(to, from);
- if (err < 0)
- return err;
-
- /*
- * Ensure both start together [after all semaphores in signal]
- *
- * Now that we are queued to the HW at roughly the same time (thanks
- * to the execute cb) and are ready to run at roughly the same time
- * (thanks to the await start), our signaler may still be indefinitely
- * delayed by waiting on a semaphore from a remote engine. If our
- * signaler depends on a semaphore, so indirectly do we, and we do not
- * want to start our payload until our signaler also starts theirs.
- * So we wait.
- *
- * However, there is also a second condition for which we need to wait
- * for the precise start of the signaler. Consider that the signaler
- * was submitted in a chain of requests following another context
- * (with just an ordinary intra-engine fence dependency between the
- * two). In this case the signaler is queued to HW, but not for
- * immediate execution, and so we must wait until it reaches the
- * active slot.
- */
- if (intel_engine_has_semaphores(to->engine) &&
- !i915_request_has_initial_breadcrumb(to)) {
- err = __emit_semaphore_wait(to, from, from->fence.seqno - 1);
- if (err < 0)
- return err;
}
- /* Couple the dependency tree for PI on this exposed to->fence */
if (to->engine->schedule) {
- err = i915_sched_node_add_dependency(&to->sched,
+ ret = i915_sched_node_add_dependency(&to->sched,
&from->sched,
- I915_DEPENDENCY_WEAK);
- if (err < 0)
- return err;
+ I915_DEPENDENCY_EXTERNAL);
+ if (ret < 0)
+ return ret;
}
- return intel_timeline_sync_set_start(i915_request_timeline(to),
- &from->fence);
+ if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask)))
+ ret = await_request_submit(to, from);
+ else
+ ret = emit_semaphore_wait(to, from, I915_FENCE_GFP);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
int
-i915_request_await_execution(struct i915_request *rq,
- struct dma_fence *fence,
- void (*hook)(struct i915_request *rq,
- struct dma_fence *signal))
+i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
{
struct dma_fence **child = &fence;
unsigned int nchild = 1;
int ret;
+ /*
+ * Note that if the fence-array was created in signal-on-any mode,
+ * we should *not* decompose it into its individual fences. However,
+ * we don't currently store which mode the fence-array is operating
+ * in. Fortunately, the only user of signal-on-any is private to
+ * amdgpu and we should not see any incoming fence-array from
+ * sync-file being in signal-on-any mode.
+ */
if (dma_fence_is_array(fence)) {
struct dma_fence_array *array = to_dma_fence_array(fence);
- /* XXX Error for signal-on-any fence arrays */
-
child = array->fences;
nchild = array->num_fences;
GEM_BUG_ON(!nchild);
@@ -1278,22 +1364,31 @@ i915_request_await_execution(struct i915_request *rq,
continue;
}
+ /*
+ * Requests on the same timeline are explicitly ordered, along
+ * with their dependencies, by i915_request_add() which ensures
+ * that requests are submitted in-order through each ring.
+ */
if (fence->context == rq->fence.context)
continue;
- /*
- * We don't squash repeated fence dependencies here as we
- * want to run our callback in all cases.
- */
+ /* Squash repeated waits to the same timelines */
+ if (fence->context &&
+ intel_timeline_sync_is_later(i915_request_timeline(rq),
+ fence))
+ continue;
if (dma_fence_is_i915(fence))
- ret = __i915_request_await_execution(rq,
- to_request(fence),
- hook);
+ ret = i915_request_await_request(rq, to_request(fence));
else
ret = i915_request_await_external(rq, fence);
if (ret < 0)
return ret;
+
+ /* Record the latest fence used against each timeline */
+ if (fence->context)
+ intel_timeline_sync_set(i915_request_timeline(rq),
+ fence);
} while (--nchild);
return 0;
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index f4ea318781f0..cbb880b10c65 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -209,14 +209,6 @@ static void kick_submission(struct intel_engine_cs *engine,
if (!inflight)
goto unlock;
- ENGINE_TRACE(engine,
- "bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n",
- prio,
- rq->fence.context, rq->fence.seqno,
- inflight->fence.context, inflight->fence.seqno,
- inflight->sched.attr.priority);
- engine->execlists.queue_priority_hint = prio;
-
/*
* If we are already the currently executing context, don't
* bother evaluating if we should preempt ourselves.
@@ -224,6 +216,14 @@ static void kick_submission(struct intel_engine_cs *engine,
if (inflight->context == rq->context)
goto unlock;
+ ENGINE_TRACE(engine,
+ "bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n",
+ prio,
+ rq->fence.context, rq->fence.seqno,
+ inflight->fence.context, inflight->fence.seqno,
+ inflight->sched.attr.priority);
+
+ engine->execlists.queue_priority_hint = prio;
if (need_preempt(prio, rq_prio(inflight)))
tasklet_hi_schedule(&engine->execlists.tasklet);
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 1579cf0d828f..42f8aae28b31 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -65,6 +65,7 @@ msm-y := \
disp/dpu1/dpu_hw_lm.o \
disp/dpu1/dpu_hw_pingpong.o \
disp/dpu1/dpu_hw_sspp.o \
+ disp/dpu1/dpu_hw_dspp.o \
disp/dpu1/dpu_hw_top.o \
disp/dpu1/dpu_hw_util.o \
disp/dpu1/dpu_hw_vbif.o \
diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
index 1f83bc18d500..60f6472a3e58 100644
--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
@@ -401,6 +401,21 @@ static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu)
return state;
}
+static struct msm_gem_address_space *
+a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
+{
+ struct msm_mmu *mmu = msm_gpummu_new(&pdev->dev, gpu);
+ struct msm_gem_address_space *aspace;
+
+ aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
+ SZ_16M + 0xfff * SZ_64K);
+
+ if (IS_ERR(aspace) && !IS_ERR(mmu))
+ mmu->funcs->destroy(mmu);
+
+ return aspace;
+}
+
/* Register offset defines for A2XX - copy of A3XX */
static const unsigned int a2xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
@@ -429,6 +444,7 @@ static const struct adreno_gpu_funcs funcs = {
#endif
.gpu_state_get = a2xx_gpu_state_get,
.gpu_state_put = adreno_gpu_state_put,
+ .create_address_space = a2xx_create_address_space,
},
};
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index b67f88872726..0a5ea9f56cb8 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -441,6 +441,7 @@ static const struct adreno_gpu_funcs funcs = {
#endif
.gpu_state_get = a3xx_gpu_state_get,
.gpu_state_put = adreno_gpu_state_put,
+ .create_address_space = adreno_iommu_create_address_space,
},
};
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 253d8d85daad..b9b26b2bf9c5 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -66,19 +66,22 @@ static void a4xx_enable_hwcg(struct msm_gpu *gpu)
}
}
- for (i = 0; i < 4; i++) {
- gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i),
- 0x00000922);
- }
+ /* No CCU for A405 */
+ if (!adreno_is_a405(adreno_gpu)) {
+ for (i = 0; i < 4; i++) {
+ gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i),
+ 0x00000922);
+ }
- for (i = 0; i < 4; i++) {
- gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i),
- 0x00000000);
- }
+ for (i = 0; i < 4; i++) {
+ gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i),
+ 0x00000000);
+ }
- for (i = 0; i < 4; i++) {
- gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i),
- 0x00000001);
+ for (i = 0; i < 4; i++) {
+ gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i),
+ 0x00000001);
+ }
}
gpu_write(gpu, REG_A4XX_RBBM_CLOCK_MODE_GPC, 0x02222222);
@@ -137,7 +140,9 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
uint32_t *ptr, len;
int i, ret;
- if (adreno_is_a420(adreno_gpu)) {
+ if (adreno_is_a405(adreno_gpu)) {
+ gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
+ } else if (adreno_is_a420(adreno_gpu)) {
gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F);
gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
@@ -440,6 +445,52 @@ static const unsigned int a4xx_registers[] = {
~0 /* sentinel */
};
+static const unsigned int a405_registers[] = {
+ /* RBBM */
+ 0x0000, 0x0002, 0x0004, 0x0021, 0x0023, 0x0024, 0x0026, 0x0026,
+ 0x0028, 0x002B, 0x002E, 0x0034, 0x0037, 0x0044, 0x0047, 0x0066,
+ 0x0068, 0x0095, 0x009C, 0x0170, 0x0174, 0x01AF,
+ /* CP */
+ 0x0200, 0x0233, 0x0240, 0x0250, 0x04C0, 0x04DD, 0x0500, 0x050B,
+ 0x0578, 0x058F,
+ /* VSC */
+ 0x0C00, 0x0C03, 0x0C08, 0x0C41, 0x0C50, 0x0C51,
+ /* GRAS */
+ 0x0C80, 0x0C81, 0x0C88, 0x0C8F,
+ /* RB */
+ 0x0CC0, 0x0CC0, 0x0CC4, 0x0CD2,
+ /* PC */
+ 0x0D00, 0x0D0C, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
+ /* VFD */
+ 0x0E40, 0x0E4A,
+ /* VPC */
+ 0x0E60, 0x0E61, 0x0E63, 0x0E68,
+ /* UCHE */
+ 0x0E80, 0x0E84, 0x0E88, 0x0E95,
+ /* GRAS CTX 0 */
+ 0x2000, 0x2004, 0x2008, 0x2067, 0x2070, 0x2078, 0x207B, 0x216E,
+ /* PC CTX 0 */
+ 0x21C0, 0x21C6, 0x21D0, 0x21D0, 0x21D9, 0x21D9, 0x21E5, 0x21E7,
+ /* VFD CTX 0 */
+ 0x2200, 0x2204, 0x2208, 0x22A9,
+ /* GRAS CTX 1 */
+ 0x2400, 0x2404, 0x2408, 0x2467, 0x2470, 0x2478, 0x247B, 0x256E,
+ /* PC CTX 1 */
+ 0x25C0, 0x25C6, 0x25D0, 0x25D0, 0x25D9, 0x25D9, 0x25E5, 0x25E7,
+ /* VFD CTX 1 */
+ 0x2600, 0x2604, 0x2608, 0x26A9,
+ /* VBIF version 0x20050000*/
+ 0x3000, 0x3007, 0x302C, 0x302C, 0x3030, 0x3030, 0x3034, 0x3036,
+ 0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040, 0x3049, 0x3049,
+ 0x3058, 0x3058, 0x305B, 0x3061, 0x3064, 0x3068, 0x306C, 0x306D,
+ 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094, 0x3098, 0x3098,
+ 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8, 0x30D0, 0x30D0,
+ 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100, 0x3108, 0x3108,
+ 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120, 0x3124, 0x3125,
+ 0x3129, 0x3129, 0x340C, 0x340C, 0x3410, 0x3410,
+ ~0 /* sentinel */
+};
+
static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
{
struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -532,6 +583,7 @@ static const struct adreno_gpu_funcs funcs = {
#endif
.gpu_state_get = a4xx_gpu_state_get,
.gpu_state_put = adreno_gpu_state_put,
+ .create_address_space = adreno_iommu_create_address_space,
},
.get_timestamp = a4xx_get_timestamp,
};
@@ -563,13 +615,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
gpu->perfcntrs = NULL;
gpu->num_perfcntrs = 0;
- adreno_gpu->registers = a4xx_registers;
- adreno_gpu->reg_offsets = a4xx_register_offsets;
-
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
if (ret)
goto fail;
+ adreno_gpu->registers = adreno_is_a405(adreno_gpu) ? a405_registers :
+ a4xx_registers;
+ adreno_gpu->reg_offsets = a4xx_register_offsets;
+
/* if needed, allocate gmem: */
if (adreno_is_a4xx(adreno_gpu)) {
ret = adreno_gpu_ocmem_init(dev->dev, adreno_gpu,
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 724024a2243a..d95970a73fb4 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1404,6 +1404,10 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu)
{
u64 busy_cycles, busy_time;
+ /* Only read the gpu busy if the hardware is already active */
+ if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0)
+ return 0;
+
busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
@@ -1412,6 +1416,8 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu)
gpu->devfreq.busy_cycles = busy_cycles;
+ pm_runtime_put(&gpu->pdev->dev);
+
if (WARN_ON(busy_time > ~0LU))
return ~0LU;
@@ -1439,6 +1445,7 @@ static const struct adreno_gpu_funcs funcs = {
.gpu_busy = a5xx_gpu_busy,
.gpu_state_get = a5xx_gpu_state_get,
.gpu_state_put = a5xx_gpu_state_put,
+ .create_address_space = adreno_iommu_create_address_space,
},
.get_timestamp = a5xx_get_timestamp,
};
diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index ed78fee2a262..47840b73cdda 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1047,6 +1047,8 @@ enum a6xx_tex_type {
#define REG_A6XX_CP_MISC_CNTL 0x00000840
+#define REG_A6XX_CP_APRIV_CNTL 0x00000844
+
#define REG_A6XX_CP_ROQ_THRESHOLDS_1 0x000008c1
#define REG_A6XX_CP_ROQ_THRESHOLDS_2 0x000008c2
@@ -1764,6 +1766,8 @@ static inline uint32_t A6XX_CP_PROTECT_REG_MASK_LEN(uint32_t val)
#define REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL 0x00000010
+#define REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL 0x00000011
+
#define REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL 0x0000001f
#define REG_A6XX_RBBM_INT_CLEAR_CMD 0x00000037
@@ -2418,6 +2422,16 @@ static inline uint32_t A6XX_UCHE_CLIENT_PF_PERFSEL(uint32_t val)
#define REG_A6XX_TPL1_NC_MODE_CNTL 0x0000b604
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0 0x0000b608
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1 0x0000b609
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2 0x0000b60a
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3 0x0000b60b
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4 0x0000b60c
+
#define REG_A6XX_TPL1_PERFCTR_TP_SEL_0 0x0000b610
#define REG_A6XX_TPL1_PERFCTR_TP_SEL_1 0x0000b611
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index c4e71abbdd53..096be97ce9f9 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -2,14 +2,16 @@
/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */
#include <linux/clk.h>
-#include <linux/dma-mapping.h>
#include <linux/interconnect.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <soc/qcom/cmd-db.h>
+#include <drm/drm_gem.h>
#include "a6xx_gpu.h"
#include "a6xx_gmu.xml.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
static void a6xx_gmu_fault(struct a6xx_gmu *gmu)
{
@@ -127,8 +129,6 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
if (ret)
dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
- gmu->freq = gmu->gpu_freqs[index];
-
/*
* Eventually we will want to scale the path vote with the frequency but
* for now leave it at max so that the performance is nominal.
@@ -151,8 +151,21 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
break;
gmu->current_perf_index = perf_index;
+ gmu->freq = gmu->gpu_freqs[perf_index];
+
+ /*
+ * This can get called from devfreq while the hardware is idle. Don't
+ * bring up the power if it isn't already active
+ */
+ if (pm_runtime_get_if_in_use(gmu->dev) == 0)
+ return;
- __a6xx_gmu_set_freq(gmu, perf_index);
+ if (gmu->legacy)
+ __a6xx_gmu_set_freq(gmu, perf_index);
+ else
+ a6xx_hfi_set_freq(gmu, perf_index);
+
+ pm_runtime_put(gmu->dev);
}
unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
@@ -196,6 +209,12 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
u32 val;
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
+
+ /* Set the log wptr index
+ * note: downstream saves the value in poweroff and restores it here
+ */
+ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);
+
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
@@ -232,8 +251,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
switch (state) {
case GMU_OOB_GPU_SET:
- request = GMU_OOB_GPU_SET_REQUEST;
- ack = GMU_OOB_GPU_SET_ACK;
+ if (gmu->legacy) {
+ request = GMU_OOB_GPU_SET_REQUEST;
+ ack = GMU_OOB_GPU_SET_ACK;
+ } else {
+ request = GMU_OOB_GPU_SET_REQUEST_NEW;
+ ack = GMU_OOB_GPU_SET_ACK_NEW;
+ }
name = "GPU_SET";
break;
case GMU_OOB_BOOT_SLUMBER:
@@ -272,6 +296,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
/* Clear a pending OOB state in the GMU */
void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
{
+ if (!gmu->legacy) {
+ WARN_ON(state != GMU_OOB_GPU_SET);
+ gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
+ 1 << GMU_OOB_GPU_SET_CLEAR_NEW);
+ return;
+ }
+
switch (state) {
case GMU_OOB_GPU_SET:
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
@@ -294,6 +325,9 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu)
int ret;
u32 val;
+ if (!gmu->legacy)
+ return 0;
+
gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,
@@ -313,6 +347,9 @@ static void a6xx_sptprac_disable(struct a6xx_gmu *gmu)
u32 val;
int ret;
+ if (!gmu->legacy)
+ return;
+
/* Make sure retention is on */
gmu_rmw(gmu, REG_A6XX_GPU_CC_GX_GDSCR, 0, (1 << 11));
@@ -356,6 +393,11 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)
if (gmu->idle_level < GMU_IDLE_STATE_SPTP)
a6xx_sptprac_disable(gmu);
+ if (!gmu->legacy) {
+ ret = a6xx_hfi_send_prep_slumber(gmu);
+ goto out;
+ }
+
/* Tell the GMU to get ready to slumber */
gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 1);
@@ -371,6 +413,7 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)
}
}
+out:
/* Put fence into allow mode */
gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
return ret;
@@ -392,7 +435,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu)
return ret;
}
- ret = gmu_poll_timeout(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
+ ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
!val, 100, 10000);
if (ret) {
@@ -418,7 +461,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu)
gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1);
- ret = gmu_poll_timeout(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
+ ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
val, val & (1 << 16), 100, 10000);
if (ret)
DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n");
@@ -441,32 +484,48 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
struct platform_device *pdev = to_platform_device(gmu->dev);
void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
+ uint32_t pdc_address_offset;
if (!pdcptr || !seqptr)
goto err;
+ if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu))
+ pdc_address_offset = 0x30090;
+ else if (adreno_is_a650(adreno_gpu))
+ pdc_address_offset = 0x300a0;
+ else
+ pdc_address_offset = 0x30080;
+
/* Disable SDE clock gating */
- gmu_write(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
+ gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
/* Setup RSC PDC handshake for sleep and wakeup */
- gmu_write(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
- gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
- gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
- gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
- gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
- gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x80000000);
- gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
- gmu_write(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
- gmu_write(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
- gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
- gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x80000000);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
/* Load RSC sequencer uCode for sleep and wakeup */
- gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
- gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);
- gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);
- gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);
- gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
+ if (adreno_is_a650(adreno_gpu)) {
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xeaaae5a0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xe1a1ebab);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e0a581);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xecac82e2);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020edad);
+ } else {
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);
+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
+ }
/* Load PDC sequencer uCode for power up and power down sequence */
pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);
@@ -487,10 +546,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);
- if (adreno_is_a618(adreno_gpu))
- pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30090);
- else
- pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30080);
+ pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, pdc_address_offset);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7);
@@ -502,17 +558,12 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000);
- if (adreno_is_a618(adreno_gpu))
+ if (adreno_is_a618(adreno_gpu) || adreno_is_a650(adreno_gpu))
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2);
else
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);
-
-
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108);
- if (adreno_is_a618(adreno_gpu))
- pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30090);
- else
- pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30080);
+ pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, pdc_address_offset);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);
/* Setup GPU PDC */
@@ -542,6 +593,8 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)
{
/* Disable GMU WB/RB buffer */
gmu_write(gmu, REG_A6XX_GMU_SYS_BUS_CONFIG, 0x1);
+ gmu_write(gmu, REG_A6XX_GMU_ICACHE_CONFIG, 0x1);
+ gmu_write(gmu, REG_A6XX_GMU_DCACHE_CONFIG, 0x1);
gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0x9c40400);
@@ -571,14 +624,95 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)
A6XX_GMU_RPMH_CTRL_GFX_VOTE_ENABLE);
}
+struct block_header {
+ u32 addr;
+ u32 size;
+ u32 type;
+ u32 value;
+ u32 data[];
+};
+
+/* this should be a general kernel helper */
+static int in_range(u32 addr, u32 start, u32 size)
+{
+ return addr >= start && addr < start + size;
+}
+
+static bool fw_block_mem(struct a6xx_gmu_bo *bo, const struct block_header *blk)
+{
+ if (!in_range(blk->addr, bo->iova, bo->size))
+ return false;
+
+ memcpy(bo->virt + blk->addr - bo->iova, blk->data, blk->size);
+ return true;
+}
+
+static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)
+{
+ struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+ struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+ const struct firmware *fw_image = adreno_gpu->fw[ADRENO_FW_GMU];
+ const struct block_header *blk;
+ u32 reg_offset;
+
+ u32 itcm_base = 0x00000000;
+ u32 dtcm_base = 0x00040000;
+
+ if (adreno_is_a650(adreno_gpu))
+ dtcm_base = 0x10004000;
+
+ if (gmu->legacy) {
+ /* Sanity check the size of the firmware that was loaded */
+ if (fw_image->size > 0x8000) {
+ DRM_DEV_ERROR(gmu->dev,
+ "GMU firmware is bigger than the available region\n");
+ return -EINVAL;
+ }
+
+ gmu_write_bulk(gmu, REG_A6XX_GMU_CM3_ITCM_START,
+ (u32*) fw_image->data, fw_image->size);
+ return 0;
+ }
+
+
+ for (blk = (const struct block_header *) fw_image->data;
+ (const u8*) blk < fw_image->data + fw_image->size;
+ blk = (const struct block_header *) &blk->data[blk->size >> 2]) {
+ if (blk->size == 0)
+ continue;
+
+ if (in_range(blk->addr, itcm_base, SZ_16K)) {
+ reg_offset = (blk->addr - itcm_base) >> 2;
+ gmu_write_bulk(gmu,
+ REG_A6XX_GMU_CM3_ITCM_START + reg_offset,
+ blk->data, blk->size);
+ } else if (in_range(blk->addr, dtcm_base, SZ_16K)) {
+ reg_offset = (blk->addr - dtcm_base) >> 2;
+ gmu_write_bulk(gmu,
+ REG_A6XX_GMU_CM3_DTCM_START + reg_offset,
+ blk->data, blk->size);
+ } else if (!fw_block_mem(&gmu->icache, blk) &&
+ !fw_block_mem(&gmu->dcache, blk) &&
+ !fw_block_mem(&gmu->dummy, blk)) {
+ DRM_DEV_ERROR(gmu->dev,
+ "failed to match fw block (addr=%.8x size=%d data[0]=%.8x)\n",
+ blk->addr, blk->size, blk->data[0]);
+ }
+ }
+
+ return 0;
+}
+
static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
{
static bool rpmh_init;
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
- int i, ret;
+ int ret;
u32 chipid;
- u32 *image;
+
+ if (adreno_is_a650(adreno_gpu))
+ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1);
if (state == GMU_WARM_BOOT) {
ret = a6xx_rpmh_start(gmu);
@@ -589,13 +723,6 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
"GMU firmware is not loaded\n"))
return -ENOENT;
- /* Sanity check the size of the firmware that was loaded */
- if (adreno_gpu->fw[ADRENO_FW_GMU]->size > 0x8000) {
- DRM_DEV_ERROR(gmu->dev,
- "GMU firmware is bigger than the available region\n");
- return -EINVAL;
- }
-
/* Turn on register retention */
gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
@@ -609,18 +736,16 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
return ret;
}
- image = (u32 *) adreno_gpu->fw[ADRENO_FW_GMU]->data;
-
- for (i = 0; i < adreno_gpu->fw[ADRENO_FW_GMU]->size >> 2; i++)
- gmu_write(gmu, REG_A6XX_GMU_CM3_ITCM_START + i,
- image[i]);
+ ret = a6xx_gmu_fw_load(gmu);
+ if (ret)
+ return ret;
}
gmu_write(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, 0);
gmu_write(gmu, REG_A6XX_GMU_CM3_BOOT_CONFIG, 0x02);
/* Write the iova of the HFI table */
- gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi->iova);
+ gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi.iova);
gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_INFO, 1);
gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_RANGE_0,
@@ -633,6 +758,9 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
gmu_write(gmu, REG_A6XX_GMU_HFI_SFR_ADDR, chipid);
+ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG,
+ gmu->log.iova | (gmu->log.size / SZ_4K - 1));
+
/* Set up the lowest idle level on the GMU */
a6xx_gmu_power_config(gmu);
@@ -640,9 +768,11 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
if (ret)
return ret;
- ret = a6xx_gmu_gfx_rail_on(gmu);
- if (ret)
- return ret;
+ if (gmu->legacy) {
+ ret = a6xx_gmu_gfx_rail_on(gmu);
+ if (ret)
+ return ret;
+ }
/* Enable SPTP_PC if the CPU is responsible for it */
if (gmu->idle_level < GMU_IDLE_STATE_SPTP) {
@@ -683,13 +813,13 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
u32 val;
/* Make sure there are no outstanding RPMh votes */
- gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val,
+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val,
(val & 1), 100, 10000);
- gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS, val,
+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS, val,
(val & 1), 100, 10000);
- gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS, val,
+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS, val,
(val & 1), 100, 10000);
- gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val,
+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val,
(val & 1), 100, 1000);
}
@@ -744,6 +874,13 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
GMU_WARM_BOOT : GMU_COLD_BOOT;
+ /*
+ * Warm boot path does not work on newer GPUs
+ * Presumably this is because icache/dcache regions must be restored
+ */
+ if (!gmu->legacy)
+ status = GMU_COLD_BOOT;
+
ret = a6xx_gmu_fw_start(gmu, status);
if (ret)
goto out;
@@ -761,7 +898,10 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
enable_irq(gmu->hfi_irq);
/* Set the GPU to the current freq */
- __a6xx_gmu_set_freq(gmu, gmu->current_perf_index);
+ if (gmu->legacy)
+ __a6xx_gmu_set_freq(gmu, gmu->current_perf_index);
+ else
+ a6xx_hfi_set_freq(gmu, gmu->current_perf_index);
/*
* "enable" the GX power domain which won't actually do anything but it
@@ -919,34 +1059,75 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
return 0;
}
-static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo)
+static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu)
{
- if (IS_ERR_OR_NULL(bo))
- return;
-
- dma_free_wc(gmu->dev, bo->size, bo->virt, bo->iova);
- kfree(bo);
+ msm_gem_kernel_put(gmu->hfi.obj, gmu->aspace, false);
+ msm_gem_kernel_put(gmu->debug.obj, gmu->aspace, false);
+ msm_gem_kernel_put(gmu->icache.obj, gmu->aspace, false);
+ msm_gem_kernel_put(gmu->dcache.obj, gmu->aspace, false);
+ msm_gem_kernel_put(gmu->dummy.obj, gmu->aspace, false);
+ msm_gem_kernel_put(gmu->log.obj, gmu->aspace, false);
+
+ gmu->aspace->mmu->funcs->detach(gmu->aspace->mmu);
+ msm_gem_address_space_put(gmu->aspace);
}
-static struct a6xx_gmu_bo *a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu,
- size_t size)
+static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo,
+ size_t size, u64 iova)
{
- struct a6xx_gmu_bo *bo;
+ struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+ struct drm_device *dev = a6xx_gpu->base.base.dev;
+ uint32_t flags = MSM_BO_WC;
+ u64 range_start, range_end;
+ int ret;
- bo = kzalloc(sizeof(*bo), GFP_KERNEL);
- if (!bo)
- return ERR_PTR(-ENOMEM);
+ size = PAGE_ALIGN(size);
+ if (!iova) {
+ /* no fixed address - use GMU's uncached range */
+ range_start = 0x60000000 + PAGE_SIZE; /* skip dummy page */
+ range_end = 0x80000000;
+ } else {
+ /* range for fixed address */
+ range_start = iova;
+ range_end = iova + size;
+ /* use IOMMU_PRIV for icache/dcache */
+ flags |= MSM_BO_MAP_PRIV;
+ }
- bo->size = PAGE_ALIGN(size);
+ bo->obj = msm_gem_new(dev, size, flags);
+ if (IS_ERR(bo->obj))
+ return PTR_ERR(bo->obj);
- bo->virt = dma_alloc_wc(gmu->dev, bo->size, &bo->iova, GFP_KERNEL);
+ ret = msm_gem_get_and_pin_iova_range(bo->obj, gmu->aspace, &bo->iova,
+ range_start >> PAGE_SHIFT, range_end >> PAGE_SHIFT);
+ if (ret) {
+ drm_gem_object_put(bo->obj);
+ return ret;
+ }
+
+ bo->virt = msm_gem_get_vaddr(bo->obj);
+ bo->size = size;
+
+ return 0;
+}
+
+static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
+{
+ struct iommu_domain *domain;
+ struct msm_mmu *mmu;
- if (!bo->virt) {
- kfree(bo);
- return ERR_PTR(-ENOMEM);
+ domain = iommu_domain_alloc(&platform_bus_type);
+ if (!domain)
+ return -ENODEV;
+
+ mmu = msm_iommu_new(gmu->dev, domain);
+ gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x7fffffff);
+ if (IS_ERR(gmu->aspace)) {
+ iommu_domain_free(domain);
+ return PTR_ERR(gmu->aspace);
}
- return bo;
+ return 0;
}
/* Return the 'arc-level' for the given frequency */
@@ -1011,8 +1192,8 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
if (j == pri_count) {
DRM_DEV_ERROR(dev,
- "Level %u not found in in the RPMh list\n",
- level);
+ "Level %u not found in the RPMh list\n",
+ level);
DRM_DEV_ERROR(dev, "Available levels:\n");
for (j = 0; j < pri_count; j++)
DRM_DEV_ERROR(dev, " %u\n", pri[j]);
@@ -1190,6 +1371,7 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
{
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+ struct platform_device *pdev = to_platform_device(gmu->dev);
if (!gmu->initialized)
return;
@@ -1202,9 +1384,12 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
}
iounmap(gmu->mmio);
+ if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))
+ iounmap(gmu->rscc);
gmu->mmio = NULL;
+ gmu->rscc = NULL;
- a6xx_gmu_memory_free(gmu, gmu->hfi);
+ a6xx_gmu_memory_free(gmu);
free_irq(gmu->gmu_irq, gmu);
free_irq(gmu->hfi_irq, gmu);
@@ -1217,6 +1402,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
{
+ struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
struct platform_device *pdev = of_find_device_by_node(node);
int ret;
@@ -1226,15 +1412,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
gmu->dev = &pdev->dev;
- /* Pass force_dma false to require the DT to set the dma region */
- ret = of_dma_configure(gmu->dev, node, false);
- if (ret)
- return ret;
-
- /* Set the mask after the of_dma_configure() */
- ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(31));
- if (ret)
- return ret;
+ of_dma_configure(gmu->dev, node, true);
/* Fow now, don't do anything fancy until we get our feet under us */
gmu->idle_level = GMU_IDLE_STATE_ACTIVE;
@@ -1246,20 +1424,64 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
if (ret)
goto err_put_device;
+ ret = a6xx_gmu_memory_probe(gmu);
+ if (ret)
+ goto err_put_device;
+
+ /* Allocate memory for the GMU dummy page */
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, SZ_4K, 0x60000000);
+ if (ret)
+ goto err_memory;
+
+ if (adreno_is_a650(adreno_gpu)) {
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
+ SZ_16M - SZ_16K, 0x04000);
+ if (ret)
+ goto err_memory;
+ } else if (adreno_is_a640(adreno_gpu)) {
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
+ SZ_256K - SZ_16K, 0x04000);
+ if (ret)
+ goto err_memory;
+
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->dcache,
+ SZ_256K - SZ_16K, 0x44000);
+ if (ret)
+ goto err_memory;
+ } else {
+ /* HFI v1, has sptprac */
+ gmu->legacy = true;
+
+ /* Allocate memory for the GMU debug region */
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_16K, 0);
+ if (ret)
+ goto err_memory;
+ }
+
/* Allocate memory for for the HFI queues */
- gmu->hfi = a6xx_gmu_memory_alloc(gmu, SZ_16K);
- if (IS_ERR(gmu->hfi))
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->hfi, SZ_16K, 0);
+ if (ret)
goto err_memory;
- /* Allocate memory for the GMU debug region */
- gmu->debug = a6xx_gmu_memory_alloc(gmu, SZ_16K);
- if (IS_ERR(gmu->debug))
+ /* Allocate memory for the GMU log region */
+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->log, SZ_4K, 0);
+ if (ret)
goto err_memory;
/* Map the GMU registers */
gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
- if (IS_ERR(gmu->mmio))
+ if (IS_ERR(gmu->mmio)) {
+ ret = PTR_ERR(gmu->mmio);
goto err_memory;
+ }
+
+ if (adreno_is_a650(adreno_gpu)) {
+ gmu->rscc = a6xx_gmu_get_mmio(pdev, "rscc");
+ if (IS_ERR(gmu->rscc))
+ goto err_mmio;
+ } else {
+ gmu->rscc = gmu->mmio + 0x23000;
+ }
/* Get the HFI and GMU interrupts */
gmu->hfi_irq = a6xx_gmu_get_irq(gmu, pdev, "hfi", a6xx_hfi_irq);
@@ -1286,13 +1508,15 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
err_mmio:
iounmap(gmu->mmio);
+ if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))
+ iounmap(gmu->rscc);
free_irq(gmu->gmu_irq, gmu);
free_irq(gmu->hfi_irq, gmu);
-err_memory:
- a6xx_gmu_memory_free(gmu, gmu->hfi);
ret = -ENODEV;
+err_memory:
+ a6xx_gmu_memory_free(gmu);
err_put_device:
/* Drop reference taken in of_find_device_by_node */
put_device(gmu->dev);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 4af65a36d5ca..47df4745db50 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -10,9 +10,10 @@
#include "a6xx_hfi.h"
struct a6xx_gmu_bo {
+ struct drm_gem_object *obj;
void *virt;
size_t size;
- dma_addr_t iova;
+ u64 iova;
};
/*
@@ -43,7 +44,10 @@ struct a6xx_gmu_bo {
struct a6xx_gmu {
struct device *dev;
+ struct msm_gem_address_space *aspace;
+
void * __iomem mmio;
+ void * __iomem rscc;
int hfi_irq;
int gmu_irq;
@@ -52,8 +56,12 @@ struct a6xx_gmu {
int idle_level;
- struct a6xx_gmu_bo *hfi;
- struct a6xx_gmu_bo *debug;
+ struct a6xx_gmu_bo hfi;
+ struct a6xx_gmu_bo debug;
+ struct a6xx_gmu_bo icache;
+ struct a6xx_gmu_bo dcache;
+ struct a6xx_gmu_bo dummy;
+ struct a6xx_gmu_bo log;
int nr_clocks;
struct clk_bulk_data *clocks;
@@ -76,6 +84,7 @@ struct a6xx_gmu {
bool initialized;
bool hung;
+ bool legacy; /* a618 or a630 */
};
static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
@@ -88,6 +97,13 @@ static inline void gmu_write(struct a6xx_gmu *gmu, u32 offset, u32 value)
return msm_writel(value, gmu->mmio + (offset << 2));
}
+static inline void
+gmu_write_bulk(struct a6xx_gmu *gmu, u32 offset, const u32 *data, u32 size)
+{
+ memcpy_toio(gmu->mmio + (offset << 2), data, size);
+ wmb();
+}
+
static inline void gmu_rmw(struct a6xx_gmu *gmu, u32 reg, u32 mask, u32 or)
{
u32 val = gmu_read(gmu, reg);
@@ -111,6 +127,15 @@ static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi)
readl_poll_timeout((gmu)->mmio + ((addr) << 2), val, cond, \
interval, timeout)
+static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value)
+{
+ return msm_writel(value, gmu->rscc + (offset << 2));
+}
+
+#define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \
+ readl_poll_timeout((gmu)->rscc + ((addr) << 2), val, cond, \
+ interval, timeout)
+
/*
* These are the available OOB (out of band requests) to the GMU where "out of
* band" means that the CPU talks to the GMU directly and not through HFI.
@@ -156,10 +181,16 @@ enum a6xx_gmu_oob_state {
#define GMU_OOB_GPU_SET_ACK 24
#define GMU_OOB_GPU_SET_CLEAR 24
+#define GMU_OOB_GPU_SET_REQUEST_NEW 30
+#define GMU_OOB_GPU_SET_ACK_NEW 31
+#define GMU_OOB_GPU_SET_CLEAR_NEW 31
+
void a6xx_hfi_init(struct a6xx_gmu *gmu);
int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
void a6xx_hfi_stop(struct a6xx_gmu *gmu);
+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu);
+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index);
bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu);
bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
index 1cc1c135236b..176ae94d9fe6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
@@ -101,6 +101,10 @@ static inline uint32_t A6XX_HFI_IRQ_OOB_MASK(uint32_t val)
#define REG_A6XX_GMU_DCVS_RETURN 0x000023ff
+#define REG_A6XX_GMU_ICACHE_CONFIG 0x00004c00
+
+#define REG_A6XX_GMU_DCACHE_CONFIG 0x00004c01
+
#define REG_A6XX_GMU_SYS_BUS_CONFIG 0x00004c0f
#define REG_A6XX_GMU_CM3_SYSRESET 0x00005000
@@ -199,6 +203,12 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val)
#define REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE 0x000050ec
+#define REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF 0x000050f0
+
+#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG 0x00005100
+
+#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP 0x00005101
+
#define REG_A6XX_GMU_BOOT_KMD_LM_HANDSHAKE 0x000051f0
#define REG_A6XX_GMU_LLM_GLM_SLEEP_CTRL 0x00005157
@@ -330,8 +340,6 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val)
#define REG_A6XX_GMU_AO_SPARE_CNTL 0x00009316
-#define REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0 0x00008c04
-
#define REG_A6XX_GMU_RSCC_CONTROL_REQ 0x00009307
#define REG_A6XX_GMU_RSCC_CONTROL_ACK 0x00009308
@@ -344,39 +352,41 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val)
#define REG_A6XX_GPU_CC_GX_DOMAIN_MISC 0x00009d42
-#define REG_A6XX_RSCC_PDC_SEQ_START_ADDR 0x00008c08
+#define REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0 0x00000004
+
+#define REG_A6XX_RSCC_PDC_SEQ_START_ADDR 0x00000008
-#define REG_A6XX_RSCC_PDC_MATCH_VALUE_LO 0x00008c09
+#define REG_A6XX_RSCC_PDC_MATCH_VALUE_LO 0x00000009
-#define REG_A6XX_RSCC_PDC_MATCH_VALUE_HI 0x00008c0a
+#define REG_A6XX_RSCC_PDC_MATCH_VALUE_HI 0x0000000a
-#define REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0 0x00008c0b
+#define REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0 0x0000000b
-#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR 0x00008c0d
+#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR 0x0000000d
-#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA 0x00008c0e
+#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA 0x0000000e
-#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_L_DRV0 0x00008c82
+#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_L_DRV0 0x00000082
-#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_H_DRV0 0x00008c83
+#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_H_DRV0 0x00000083
-#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_EN_DRV0 0x00008c89
+#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_EN_DRV0 0x00000089
-#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_OUTPUT_DRV0 0x00008c8c
+#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_OUTPUT_DRV0 0x0000008c
-#define REG_A6XX_RSCC_OVERRIDE_START_ADDR 0x00008d00
+#define REG_A6XX_RSCC_OVERRIDE_START_ADDR 0x00000100
-#define REG_A6XX_RSCC_SEQ_BUSY_DRV0 0x00008d01
+#define REG_A6XX_RSCC_SEQ_BUSY_DRV0 0x00000101
-#define REG_A6XX_RSCC_SEQ_MEM_0_DRV0 0x00008d80
+#define REG_A6XX_RSCC_SEQ_MEM_0_DRV0 0x00000180
-#define REG_A6XX_RSCC_TCS0_DRV0_STATUS 0x00008f46
+#define REG_A6XX_RSCC_TCS0_DRV0_STATUS 0x00000346
-#define REG_A6XX_RSCC_TCS1_DRV0_STATUS 0x000090ae
+#define REG_A6XX_RSCC_TCS1_DRV0_STATUS 0x000003ee
-#define REG_A6XX_RSCC_TCS2_DRV0_STATUS 0x00009216
+#define REG_A6XX_RSCC_TCS2_DRV0_STATUS 0x00000496
-#define REG_A6XX_RSCC_TCS3_DRV0_STATUS 0x0000937e
+#define REG_A6XX_RSCC_TCS3_DRV0_STATUS 0x0000053e
#endif /* A6XX_GMU_XML */
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 68af24150de5..a1589e040c57 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -414,7 +414,17 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
a6xx_set_hwcg(gpu, true);
/* VBIF/GBIF start*/
- gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
+ if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu)) {
+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
+ gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3);
+ } else {
+ gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
+ }
+
if (adreno_is_a630(adreno_gpu))
gpu_write(gpu, REG_A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009);
@@ -429,25 +439,35 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_LO, 0xfffff000);
gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0001ffff);
- /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
- gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
- REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x00100000);
+ if (!adreno_is_a650(adreno_gpu)) {
+ /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
+ gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
+ REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x00100000);
- gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
- REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
- 0x00100000 + adreno_gpu->gmem - 1);
+ gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
+ REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
+ 0x00100000 + adreno_gpu->gmem - 1);
+ }
gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
- gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
+ if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu))
+ gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
+ else
+ gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
/* Setting the mem pool size */
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
/* Setting the primFifo thresholds default values */
- gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, (0x300 << 11));
+ if (adreno_is_a650(adreno_gpu))
+ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300000);
+ else if (adreno_is_a640(adreno_gpu))
+ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200000);
+ else
+ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, (0x300 << 11));
/* Set the AHB default slave response to "ERROR" */
gpu_write(gpu, REG_A6XX_CP_AHB_CNTL, 0x1);
@@ -471,6 +491,19 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1);
+ /* Set weights for bicubic filtering */
+ if (adreno_is_a650(adreno_gpu)) {
+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, 0);
+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1,
+ 0x3fe05ff4);
+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2,
+ 0x3fa0ebee);
+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3,
+ 0x3f5193ed);
+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4,
+ 0x3f0243f0);
+ }
+
/* Protect registers from the CP */
gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, 0x00000003);
@@ -508,6 +541,11 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
A6XX_PROTECT_RDONLY(0x980, 0x4));
gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0));
+ if (adreno_is_a650(adreno_gpu)) {
+ gpu_write(gpu, REG_A6XX_CP_APRIV_CNTL,
+ (1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1));
+ }
+
/* Enable interrupts */
gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK, A6XX_INT_MASK);
@@ -566,8 +604,10 @@ out:
*/
a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
- /* Take the GMU out of its special boot mode */
- a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
+ if (a6xx_gpu->gmu.legacy) {
+ /* Take the GMU out of its special boot mode */
+ a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
+ }
return ret;
}
@@ -810,6 +850,11 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
u64 busy_cycles, busy_time;
+
+ /* Only read the gpu busy if the hardware is already active */
+ if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0)
+ return 0;
+
busy_cycles = gmu_read64(&a6xx_gpu->gmu,
REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
@@ -819,6 +864,8 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
gpu->devfreq.busy_cycles = busy_cycles;
+ pm_runtime_put(a6xx_gpu->gmu.dev);
+
if (WARN_ON(busy_time > ~0LU))
return ~0LU;
@@ -846,6 +893,7 @@ static const struct adreno_gpu_funcs funcs = {
#if defined(CONFIG_DRM_MSM_GPU_STATE)
.gpu_state_get = a6xx_gpu_state_get,
.gpu_state_put = a6xx_gpu_state_put,
+ .create_address_space = adreno_iommu_create_address_space,
#endif
},
.get_timestamp = a6xx_get_timestamp,
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
index e450e0b97211..9921e632f1ca 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
@@ -17,10 +17,14 @@ static const char * const a6xx_hfi_msg_id[] = {
HFI_MSG_ID(HFI_H2F_MSG_BW_TABLE),
HFI_MSG_ID(HFI_H2F_MSG_PERF_TABLE),
HFI_MSG_ID(HFI_H2F_MSG_TEST),
+ HFI_MSG_ID(HFI_H2F_MSG_START),
+ HFI_MSG_ID(HFI_H2F_MSG_CORE_FW_START),
+ HFI_MSG_ID(HFI_H2F_MSG_GX_BW_PERF_VOTE),
+ HFI_MSG_ID(HFI_H2F_MSG_PREPARE_SLUMBER),
};
-static int a6xx_hfi_queue_read(struct a6xx_hfi_queue *queue, u32 *data,
- u32 dwords)
+static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu,
+ struct a6xx_hfi_queue *queue, u32 *data, u32 dwords)
{
struct a6xx_hfi_queue_header *header = queue->header;
u32 i, hdr, index = header->read_index;
@@ -48,6 +52,9 @@ static int a6xx_hfi_queue_read(struct a6xx_hfi_queue *queue, u32 *data,
index = (index + 1) % header->size;
}
+ if (!gmu->legacy)
+ index = ALIGN(index, 4) % header->size;
+
header->read_index = index;
return HFI_HEADER_SIZE(hdr);
}
@@ -73,6 +80,12 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu,
index = (index + 1) % header->size;
}
+ /* Cookify any non used data at the end of the write buffer */
+ if (!gmu->legacy) {
+ for (; index % 4; index = (index + 1) % header->size)
+ queue->data[index] = 0xfafafafa;
+ }
+
header->write_index = index;
spin_unlock(&queue->lock);
@@ -106,7 +119,7 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
struct a6xx_hfi_msg_response resp;
/* Get the next packet */
- ret = a6xx_hfi_queue_read(queue, (u32 *) &resp,
+ ret = a6xx_hfi_queue_read(gmu, queue, (u32 *) &resp,
sizeof(resp) >> 2);
/* If the queue is empty our response never made it */
@@ -176,8 +189,8 @@ static int a6xx_hfi_send_gmu_init(struct a6xx_gmu *gmu, int boot_state)
{
struct a6xx_hfi_msg_gmu_init_cmd msg = { 0 };
- msg.dbg_buffer_addr = (u32) gmu->debug->iova;
- msg.dbg_buffer_size = (u32) gmu->debug->size;
+ msg.dbg_buffer_addr = (u32) gmu->debug.iova;
+ msg.dbg_buffer_size = (u32) gmu->debug.size;
msg.boot_state = boot_state;
return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_INIT, &msg, sizeof(msg),
@@ -195,6 +208,28 @@ static int a6xx_hfi_get_fw_version(struct a6xx_gmu *gmu, u32 *version)
version, sizeof(*version));
}
+static int a6xx_hfi_send_perf_table_v1(struct a6xx_gmu *gmu)
+{
+ struct a6xx_hfi_msg_perf_table_v1 msg = { 0 };
+ int i;
+
+ msg.num_gpu_levels = gmu->nr_gpu_freqs;
+ msg.num_gmu_levels = gmu->nr_gmu_freqs;
+
+ for (i = 0; i < gmu->nr_gpu_freqs; i++) {
+ msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
+ msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
+ }
+
+ for (i = 0; i < gmu->nr_gmu_freqs; i++) {
+ msg.cx_votes[i].vote = gmu->cx_arc_votes[i];
+ msg.cx_votes[i].freq = gmu->gmu_freqs[i] / 1000;
+ }
+
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PERF_TABLE, &msg, sizeof(msg),
+ NULL, 0);
+}
+
static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
{
struct a6xx_hfi_msg_perf_table msg = { 0 };
@@ -205,6 +240,7 @@ static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
for (i = 0; i < gmu->nr_gpu_freqs; i++) {
msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
+ msg.gx_votes[i].acd = 0xffffffff;
msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
}
@@ -306,7 +342,45 @@ static int a6xx_hfi_send_test(struct a6xx_gmu *gmu)
NULL, 0);
}
-int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
+static int a6xx_hfi_send_start(struct a6xx_gmu *gmu)
+{
+ struct a6xx_hfi_msg_start msg = { 0 };
+
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_START, &msg, sizeof(msg),
+ NULL, 0);
+}
+
+static int a6xx_hfi_send_core_fw_start(struct a6xx_gmu *gmu)
+{
+ struct a6xx_hfi_msg_core_fw_start msg = { 0 };
+
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_CORE_FW_START, &msg,
+ sizeof(msg), NULL, 0);
+}
+
+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index)
+{
+ struct a6xx_hfi_gx_bw_perf_vote_cmd msg = { 0 };
+
+ msg.ack_type = 1; /* blocking */
+ msg.freq = index;
+ msg.bw = 0; /* TODO: bus scaling */
+
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_GX_BW_PERF_VOTE, &msg,
+ sizeof(msg), NULL, 0);
+}
+
+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu)
+{
+ struct a6xx_hfi_prep_slumber_cmd msg = { 0 };
+
+ /* TODO: should freq and bw fields be non-zero ? */
+
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PREPARE_SLUMBER, &msg,
+ sizeof(msg), NULL, 0);
+}
+
+static int a6xx_hfi_start_v1(struct a6xx_gmu *gmu, int boot_state)
{
int ret;
@@ -324,7 +398,7 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
* the GMU firmware
*/
- ret = a6xx_hfi_send_perf_table(gmu);
+ ret = a6xx_hfi_send_perf_table_v1(gmu);
if (ret)
return ret;
@@ -341,6 +415,37 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
return 0;
}
+int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
+{
+ int ret;
+
+ if (gmu->legacy)
+ return a6xx_hfi_start_v1(gmu, boot_state);
+
+
+ ret = a6xx_hfi_send_perf_table(gmu);
+ if (ret)
+ return ret;
+
+ ret = a6xx_hfi_send_bw_table(gmu);
+ if (ret)
+ return ret;
+
+ ret = a6xx_hfi_send_core_fw_start(gmu);
+ if (ret)
+ return ret;
+
+ /*
+ * Downstream driver sends this in its "a6xx_hw_init" equivalent,
+ * but seems to be no harm in sending it here
+ */
+ ret = a6xx_hfi_send_start(gmu);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
void a6xx_hfi_stop(struct a6xx_gmu *gmu)
{
int i;
@@ -385,7 +490,7 @@ static void a6xx_hfi_queue_init(struct a6xx_hfi_queue *queue,
void a6xx_hfi_init(struct a6xx_gmu *gmu)
{
- struct a6xx_gmu_bo *hfi = gmu->hfi;
+ struct a6xx_gmu_bo *hfi = &gmu->hfi;
struct a6xx_hfi_queue_table_header *table = hfi->virt;
struct a6xx_hfi_queue_header *headers = hfi->virt + sizeof(*table);
u64 offset;
@@ -415,5 +520,5 @@ void a6xx_hfi_init(struct a6xx_gmu *gmu)
/* GMU response queue */
offset += SZ_4K;
a6xx_hfi_queue_init(&gmu->queues[1], &headers[1], hfi->virt + offset,
- hfi->iova + offset, 4);
+ hfi->iova + offset, gmu->legacy ? 4 : 1);
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.h b/drivers/gpu/drm/msm/adreno/a6xx_hfi.h
index 60d1319fa44f..2bd670ca42d6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.h
@@ -51,7 +51,8 @@ struct a6xx_hfi_queue {
/* HFI message types */
#define HFI_MSG_CMD 0
-#define HFI_MSG_ACK 2
+#define HFI_MSG_ACK 1
+#define HFI_MSG_ACK_V1 2
#define HFI_F2H_MSG_ACK 126
@@ -94,7 +95,13 @@ struct perf_level {
u32 freq;
};
-struct a6xx_hfi_msg_perf_table {
+struct perf_gx_level {
+ u32 vote;
+ u32 acd;
+ u32 freq;
+};
+
+struct a6xx_hfi_msg_perf_table_v1 {
u32 header;
u32 num_gpu_levels;
u32 num_gmu_levels;
@@ -103,6 +110,15 @@ struct a6xx_hfi_msg_perf_table {
struct perf_level cx_votes[4];
};
+struct a6xx_hfi_msg_perf_table {
+ u32 header;
+ u32 num_gpu_levels;
+ u32 num_gmu_levels;
+
+ struct perf_gx_level gx_votes[16];
+ struct perf_level cx_votes[4];
+};
+
#define HFI_H2F_MSG_BW_TABLE 3
struct a6xx_hfi_msg_bw_table {
@@ -124,4 +140,34 @@ struct a6xx_hfi_msg_test {
u32 header;
};
+#define HFI_H2F_MSG_START 10
+
+struct a6xx_hfi_msg_start {
+ u32 header;
+};
+
+#define HFI_H2F_MSG_CORE_FW_START 14
+
+struct a6xx_hfi_msg_core_fw_start {
+ u32 header;
+ u32 handle;
+};
+
+#define HFI_H2F_MSG_GX_BW_PERF_VOTE 30
+
+struct a6xx_hfi_gx_bw_perf_vote_cmd {
+ u32 header;
+ u32 ack_type;
+ u32 freq;
+ u32 bw;
+};
+
+#define HFI_H2F_MSG_PREPARE_SLUMBER 33
+
+struct a6xx_hfi_prep_slumber_cmd {
+ u32 header;
+ u32 bw;
+ u32 freq;
+};
+
#endif
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index cb3a6e597d76..7732f03d9e3a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -93,6 +93,17 @@ static const struct adreno_info gpulist[] = {
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a3xx_gpu_init,
}, {
+ .rev = ADRENO_REV(4, 0, 5, ANY_ID),
+ .revn = 405,
+ .name = "A405",
+ .fw = {
+ [ADRENO_FW_PM4] = "a420_pm4.fw",
+ [ADRENO_FW_PFP] = "a420_pfp.fw",
+ },
+ .gmem = SZ_256K,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .init = a4xx_gpu_init,
+ }, {
.rev = ADRENO_REV(4, 2, 0, ANY_ID),
.revn = 420,
.name = "A420",
@@ -189,6 +200,30 @@ static const struct adreno_info gpulist[] = {
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a6xx_gpu_init,
.zapfw = "a630_zap.mdt",
+ }, {
+ .rev = ADRENO_REV(6, 4, 0, ANY_ID),
+ .revn = 640,
+ .name = "A640",
+ .fw = {
+ [ADRENO_FW_SQE] = "a630_sqe.fw",
+ [ADRENO_FW_GMU] = "a640_gmu.bin",
+ },
+ .gmem = SZ_1M,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .init = a6xx_gpu_init,
+ .zapfw = "a640_zap.mdt",
+ }, {
+ .rev = ADRENO_REV(6, 5, 0, ANY_ID),
+ .revn = 650,
+ .name = "A650",
+ .fw = {
+ [ADRENO_FW_SQE] = "a650_sqe.fw",
+ [ADRENO_FW_GMU] = "a650_gmu.bin",
+ },
+ .gmem = SZ_1M + SZ_128K,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .init = a6xx_gpu_init,
+ .zapfw = "a650_zap.mdt",
},
};
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 1d5c43c22269..89673c7ed473 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -185,6 +185,23 @@ int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)
return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
}
+struct msm_gem_address_space *
+adreno_iommu_create_address_space(struct msm_gpu *gpu,
+ struct platform_device *pdev)
+{
+ struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
+ struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
+ struct msm_gem_address_space *aspace;
+
+ aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
+ 0xfffffff);
+
+ if (IS_ERR(aspace) && !IS_ERR(mmu))
+ mmu->funcs->destroy(mmu);
+
+ return aspace;
+}
+
int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -197,7 +214,7 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
*value = adreno_gpu->gmem;
return 0;
case MSM_PARAM_GMEM_BASE:
- *value = 0x100000;
+ *value = !adreno_is_a650(adreno_gpu) ? 0x100000 : 0;
return 0;
case MSM_PARAM_CHIP_ID:
*value = adreno_gpu->rev.patchid |
@@ -459,7 +476,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
break;
/* fall-thru */
case MSM_SUBMIT_CMD_BUF:
- OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ?
+ OUT_PKT3(ring, adreno_is_a4xx(adreno_gpu) ?
CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2);
OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
OUT_RING(ring, submit->cmd[i].size);
@@ -988,12 +1005,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
- adreno_gpu_config.va_start = SZ_16M;
- adreno_gpu_config.va_end = 0xffffffff;
- /* maximum range of a2xx mmu */
- if (adreno_is_a2xx(adreno_gpu))
- adreno_gpu_config.va_end = SZ_16M + 0xfff * SZ_64K;
-
adreno_gpu_config.nr_rings = nr_rings;
adreno_get_pwrlevels(&pdev->dev, gpu);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 9ff4e550e7bd..2f5d2c3acc3a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -202,6 +202,11 @@ static inline bool adreno_is_a4xx(struct adreno_gpu *gpu)
return (gpu->revn >= 400) && (gpu->revn < 500);
}
+static inline int adreno_is_a405(struct adreno_gpu *gpu)
+{
+ return gpu->revn == 405;
+}
+
static inline int adreno_is_a420(struct adreno_gpu *gpu)
{
return gpu->revn == 420;
@@ -237,6 +242,16 @@ static inline int adreno_is_a630(struct adreno_gpu *gpu)
return gpu->revn == 630;
}
+static inline int adreno_is_a640(struct adreno_gpu *gpu)
+{
+ return gpu->revn == 640;
+}
+
+static inline int adreno_is_a650(struct adreno_gpu *gpu)
+{
+ return gpu->revn == 650;
+}
+
int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu,
const char *fwname);
@@ -273,6 +288,14 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
int adreno_gpu_state_put(struct msm_gpu_state *state);
/*
+ * Common helper function to initialize the default address space for arm-smmu
+ * attached targets
+ */
+struct msm_gem_address_space *
+adreno_iommu_create_address_space(struct msm_gpu *gpu,
+ struct platform_device *pdev);
+
+/*
* For a5xx and a6xx targets load the zap shader that is used to pull the GPU
* out of secure mode
*/
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 11f2bebe3869..7c230f719ad3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -36,22 +36,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
return to_dpu_kms(priv->kms);
}
-static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc)
-{
- struct drm_crtc *tmp_crtc;
-
- drm_for_each_crtc(tmp_crtc, crtc->dev) {
- if ((dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) &&
- tmp_crtc->enabled) {
- DPU_DEBUG("video interface connected crtc:%d\n",
- tmp_crtc->base.id);
- return true;
- }
- }
-
- return false;
-}
-
static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms,
struct drm_crtc *crtc,
struct drm_crtc_state *state,
@@ -94,7 +78,6 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
u32 bw, threshold;
u64 bw_sum_of_intfs = 0;
enum dpu_crtc_client_type curr_client_type;
- bool is_video_mode;
struct dpu_crtc_state *dpu_cstate;
struct drm_crtc *tmp_crtc;
struct dpu_kms *kms;
@@ -144,11 +127,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000);
DPU_DEBUG("calculated bandwidth=%uk\n", bw);
- is_video_mode = dpu_crtc_get_intf_mode(crtc) == INTF_MODE_VIDEO;
- threshold = (is_video_mode ||
- _dpu_core_video_mode_intf_connected(crtc)) ?
- kms->catalog->perf.max_bw_low :
- kms->catalog->perf.max_bw_high;
+ threshold = kms->catalog->perf.max_bw_high;
DPU_DEBUG("final threshold bw limit = %d\n", threshold);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 17448505a9b5..e15b42a780e0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -9,6 +9,7 @@
#include <linux/sort.h>
#include <linux/debugfs.h>
#include <linux/ktime.h>
+#include <linux/bits.h>
#include <drm/drm_crtc.h>
#include <drm/drm_flip_work.h>
@@ -20,6 +21,7 @@
#include "dpu_kms.h"
#include "dpu_hw_lm.h"
#include "dpu_hw_ctl.h"
+#include "dpu_hw_dspp.h"
#include "dpu_crtc.h"
#include "dpu_plane.h"
#include "dpu_encoder.h"
@@ -40,6 +42,9 @@
/* timeout in ms waiting for frame done */
#define DPU_CRTC_FRAME_DONE_TIMEOUT_MS 60
+#define CONVERT_S3_15(val) \
+ (((((u64)val) & ~BIT_ULL(63)) >> 17) & GENMASK_ULL(17, 0))
+
static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
{
struct msm_drm_private *priv = crtc->dev->dev_private;
@@ -88,11 +93,9 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
{
- struct dpu_crtc *dpu_crtc;
struct dpu_crtc_state *crtc_state;
int lm_idx, lm_horiz_position;
- dpu_crtc = to_dpu_crtc(crtc);
crtc_state = to_dpu_crtc_state(crtc->state);
lm_horiz_position = 0;
@@ -422,6 +425,74 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
drm_mode_debug_printmodeline(adj_mode);
}
+static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state,
+ struct dpu_hw_pcc_cfg *cfg)
+{
+ struct drm_color_ctm *ctm;
+
+ memset(cfg, 0, sizeof(struct dpu_hw_pcc_cfg));
+
+ ctm = (struct drm_color_ctm *)state->ctm->data;
+
+ if (!ctm)
+ return;
+
+ cfg->r.r = CONVERT_S3_15(ctm->matrix[0]);
+ cfg->g.r = CONVERT_S3_15(ctm->matrix[1]);
+ cfg->b.r = CONVERT_S3_15(ctm->matrix[2]);
+
+ cfg->r.g = CONVERT_S3_15(ctm->matrix[3]);
+ cfg->g.g = CONVERT_S3_15(ctm->matrix[4]);
+ cfg->b.g = CONVERT_S3_15(ctm->matrix[5]);
+
+ cfg->r.b = CONVERT_S3_15(ctm->matrix[6]);
+ cfg->g.b = CONVERT_S3_15(ctm->matrix[7]);
+ cfg->b.b = CONVERT_S3_15(ctm->matrix[8]);
+}
+
+static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
+{
+ struct drm_crtc_state *state = crtc->state;
+ struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+ struct dpu_crtc_mixer *mixer = cstate->mixers;
+ struct dpu_hw_pcc_cfg cfg;
+ struct dpu_hw_ctl *ctl;
+ struct dpu_hw_mixer *lm;
+ struct dpu_hw_dspp *dspp;
+ int i;
+
+
+ if (!state->color_mgmt_changed)
+ return;
+
+ for (i = 0; i < cstate->num_mixers; i++) {
+ ctl = mixer[i].lm_ctl;
+ lm = mixer[i].hw_lm;
+ dspp = mixer[i].hw_dspp;
+
+ if (!dspp || !dspp->ops.setup_pcc)
+ continue;
+
+ if (!state->ctm) {
+ dspp->ops.setup_pcc(dspp, NULL);
+ } else {
+ _dpu_crtc_get_pcc_coeff(state, &cfg);
+ dspp->ops.setup_pcc(dspp, &cfg);
+ }
+
+ mixer[i].flush_mask |= ctl->ops.get_bitmask_dspp(ctl,
+ mixer[i].hw_dspp->idx);
+
+ /* stage config flush mask */
+ ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
+
+ DPU_DEBUG("lm %d, ctl %d, flush mask 0x%x\n",
+ mixer[i].hw_lm->idx - DSPP_0,
+ ctl->idx - CTL_0,
+ mixer[i].flush_mask);
+ }
+}
+
static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
@@ -430,7 +501,6 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_encoder *encoder;
struct drm_device *dev;
unsigned long flags;
- struct dpu_crtc_smmu_state_data *smmu_state;
if (!crtc) {
DPU_ERROR("invalid crtc\n");
@@ -448,7 +518,6 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
dpu_crtc = to_dpu_crtc(crtc);
cstate = to_dpu_crtc_state(crtc->state);
dev = crtc->dev;
- smmu_state = &dpu_crtc->smmu_state;
_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
@@ -475,6 +544,8 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
_dpu_crtc_blend_setup(crtc);
+ _dpu_crtc_setup_cp_blocks(crtc);
+
/*
* PP_DONE irq is only used by command mode for now.
* It is better to request pending before FLUSH and START trigger
@@ -491,7 +562,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_device *dev;
struct drm_plane *plane;
struct msm_drm_private *priv;
- struct msm_drm_thread *event_thread;
unsigned long flags;
struct dpu_crtc_state *cstate;
@@ -513,8 +583,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
return;
}
- event_thread = &priv->event_thread[crtc->index];
-
if (dpu_crtc->event) {
DPU_DEBUG("already received dpu_crtc->event\n");
} else {
@@ -567,7 +635,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
static void dpu_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
- struct dpu_crtc *dpu_crtc;
struct dpu_crtc_state *cstate;
if (!crtc || !state) {
@@ -575,7 +642,6 @@ static void dpu_crtc_destroy_state(struct drm_crtc *crtc,
return;
}
- dpu_crtc = to_dpu_crtc(crtc);
cstate = to_dpu_crtc_state(state);
DPU_DEBUG("crtc%d\n", crtc->base.id);
@@ -662,11 +728,9 @@ static void dpu_crtc_reset(struct drm_crtc *crtc)
/**
* dpu_crtc_duplicate_state - state duplicate hook
* @crtc: Pointer to drm crtc structure
- * @Returns: Pointer to new drm_crtc_state structure
*/
static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc)
{
- struct dpu_crtc *dpu_crtc;
struct dpu_crtc_state *cstate, *old_cstate;
if (!crtc || !crtc->state) {
@@ -674,7 +738,6 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc)
return NULL;
}
- dpu_crtc = to_dpu_crtc(crtc);
old_cstate = to_dpu_crtc_state(crtc->state);
cstate = kmemdup(old_cstate, sizeof(*old_cstate), GFP_KERNEL);
if (!cstate) {
@@ -693,9 +756,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
{
struct dpu_crtc *dpu_crtc;
struct dpu_crtc_state *cstate;
- struct drm_display_mode *mode;
struct drm_encoder *encoder;
- struct msm_drm_private *priv;
unsigned long flags;
bool release_bandwidth = false;
@@ -705,8 +766,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
}
dpu_crtc = to_dpu_crtc(crtc);
cstate = to_dpu_crtc_state(crtc->state);
- mode = &cstate->base.adjusted_mode;
- priv = crtc->dev->dev_private;
DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
@@ -768,14 +827,12 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
{
struct dpu_crtc *dpu_crtc;
struct drm_encoder *encoder;
- struct msm_drm_private *priv;
bool request_bandwidth;
if (!crtc) {
DPU_ERROR("invalid crtc\n");
return;
}
- priv = crtc->dev->dev_private;
pm_runtime_get_sync(crtc->dev->dev);
@@ -1319,6 +1376,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
+ drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
+
/* save user friendly CRTC name for later */
snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 5174e86124cc..cec3474340e8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -73,12 +73,14 @@ struct dpu_crtc_smmu_state_data {
* struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
* @hw_lm: LM HW Driver context
* @lm_ctl: CTL Path HW driver context
+ * @lm_dspp: DSPP HW driver context
* @mixer_op_mode: mixer blending operation mode
* @flush_mask: mixer flush mask for ctl, mixer and pipe
*/
struct dpu_crtc_mixer {
struct dpu_hw_mixer *hw_lm;
struct dpu_hw_ctl *lm_ctl;
+ struct dpu_hw_dspp *hw_dspp;
u32 mixer_op_mode;
u32 flush_mask;
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index a1b79ee2bd9d..63976dcd2ac8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -20,6 +20,7 @@
#include "dpu_hw_catalog.h"
#include "dpu_hw_intf.h"
#include "dpu_hw_ctl.h"
+#include "dpu_hw_dspp.h"
#include "dpu_formats.h"
#include "dpu_encoder_phys.h"
#include "dpu_crtc.h"
@@ -536,6 +537,7 @@ static struct msm_display_topology dpu_encoder_get_topology(
* 1 LM, 1 INTF
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
*
+ * Adding color blocks only to primary interface
*/
if (intf_count == 2)
topology.num_lm = 2;
@@ -544,6 +546,9 @@ static struct msm_display_topology dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
+ if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI)
+ topology.num_dspp = topology.num_lm;
+
topology.num_enc = 0;
topology.num_intf = intf_count;
@@ -959,7 +964,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
- int num_lm, num_ctl, num_pp;
+ struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
+ int num_lm, num_ctl, num_pp, num_dspp;
int i, j;
if (!drm_enc) {
@@ -1008,6 +1014,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+ num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+ ARRAY_SIZE(hw_dspp));
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1020,6 +1029,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
+ cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
}
cstate->num_mixers = num_lm;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index c567917541e8..29d4fde3172b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -41,6 +41,8 @@
#define PINGPONG_SDM845_SPLIT_MASK \
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
+#define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
+
#define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
#define DEFAULT_DPU_LINE_WIDTH 2048
#define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
@@ -291,29 +293,30 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
},
};
-#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair) \
+#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
{ \
.name = _name, .id = _id, \
.base = _base, .len = 0x320, \
.features = _fmask, \
.sblk = _sblk, \
.pingpong = _pp, \
- .lm_pair_mask = (1 << _lmpair) \
+ .lm_pair_mask = (1 << _lmpair), \
+ .dspp = _dspp \
}
static const struct dpu_lm_cfg sdm845_lm[] = {
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_0, LM_1),
+ &sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_1, LM_0),
+ &sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_2, LM_5),
+ &sdm845_lm_sblk, PINGPONG_2, LM_5, 0),
LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_MAX, 0),
+ &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_MAX, 0),
+ &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_3, LM_2),
+ &sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
};
/* SC7180 */
@@ -328,11 +331,30 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
static const struct dpu_lm_cfg sc7180_lm[] = {
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
- &sc7180_lm_sblk, PINGPONG_0, LM_1),
+ &sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
- &sc7180_lm_sblk, PINGPONG_1, LM_0),
+ &sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
+};
+
+/*************************************************************
+ * DSPP sub blocks config
+ *************************************************************/
+static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = {
+ .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
+ .len = 0x90, .version = 0x10000},
};
+#define DSPP_BLK(_name, _id, _base) \
+ {\
+ .name = _name, .id = _id, \
+ .base = _base, .len = 0x1800, \
+ .features = DSPP_SC7180_MASK, \
+ .sblk = &sc7180_dspp_sblk \
+ }
+
+static const struct dpu_dspp_cfg sc7180_dspp[] = {
+ DSPP_BLK("dspp_0", DSPP_0, 0x54000),
+};
/*************************************************************
* PINGPONG sub blocks config
*************************************************************/
@@ -515,8 +537,8 @@ static const struct dpu_perf_cfg sdm845_perf_data = {
};
static const struct dpu_perf_cfg sc7180_perf_data = {
- .max_bw_low = 3900000,
- .max_bw_high = 5500000,
+ .max_bw_low = 6800000,
+ .max_bw_high = 6800000,
.min_core_ib = 2400000,
.min_llcc_ib = 800000,
.min_dram_ib = 800000,
@@ -587,6 +609,8 @@ static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
.sspp = sc7180_sspp,
.mixer_count = ARRAY_SIZE(sc7180_lm),
.mixer = sc7180_lm,
+ .dspp_count = ARRAY_SIZE(sc7180_dspp),
+ .dspp = sc7180_dspp,
.pingpong_count = ARRAY_SIZE(sc7180_pp),
.pingpong = sc7180_pp,
.intf_count = ARRAY_SIZE(sc7180_intf),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 09df7d87dd43..f7de43838c69 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -146,6 +146,17 @@ enum {
};
/**
+ * DSPP sub-blocks
+ * @DPU_DSPP_PCC Panel color correction block
+ * @DPU_DSPP_GC Gamma correction block
+ */
+enum {
+ DPU_DSPP_PCC = 0x1,
+ DPU_DSPP_GC,
+ DPU_DSPP_MAX
+};
+
+/**
* PINGPONG sub-blocks
* @DPU_PINGPONG_TE Tear check block
* @DPU_PINGPONG_TE2 Additional tear check block for split pipes
@@ -377,6 +388,16 @@ struct dpu_lm_sub_blks {
struct dpu_pp_blk gc;
};
+/**
+ * struct dpu_dspp_sub_blks: Information of DSPP block
+ * @gc : gamma correction block
+ * @pcc: pixel color correction block
+ */
+struct dpu_dspp_sub_blks {
+ struct dpu_pp_blk gc;
+ struct dpu_pp_blk pcc;
+};
+
struct dpu_pingpong_sub_blks {
struct dpu_pp_blk te;
struct dpu_pp_blk te2;
@@ -471,10 +492,24 @@ struct dpu_lm_cfg {
DPU_HW_BLK_INFO;
const struct dpu_lm_sub_blks *sblk;
u32 pingpong;
+ u32 dspp;
unsigned long lm_pair_mask;
};
/**
+ * struct dpu_dspp_cfg - information of DSPP blocks
+ * @id enum identifying this block
+ * @base register offset of this block
+ * @features bit mask identifying sub-blocks/features
+ * supported by this block
+ * @sblk sub-blocks information
+ */
+struct dpu_dspp_cfg {
+ DPU_HW_BLK_INFO;
+ const struct dpu_dspp_sub_blks *sblk;
+};
+
+/**
* struct dpu_pingpong_cfg - information of PING-PONG blocks
* @id enum identifying this block
* @base register offset of this block
@@ -688,6 +723,9 @@ struct dpu_mdss_cfg {
u32 ad_count;
+ u32 dspp_count;
+ const struct dpu_dspp_cfg *dspp;
+
/* Add additional block data structures here */
struct dpu_perf_cfg perf;
@@ -716,6 +754,7 @@ struct dpu_mdss_hw_cfg_handler {
#define BLK_PINGPONG(s) ((s)->pingpong)
#define BLK_INTF(s) ((s)->intf)
#define BLK_AD(s) ((s)->ad)
+#define BLK_DSPP(s) ((s)->dspp)
/**
* dpu_hw_catalog_init - dpu hardware catalog init API retrieves
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 831e5f7a9b7f..613ae8f0cfcd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -272,6 +272,31 @@ static int dpu_hw_ctl_active_get_bitmask_intf(struct dpu_hw_ctl *ctx,
return 0;
}
+static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
+ enum dpu_dspp dspp)
+{
+ uint32_t flushbits = 0;
+
+ switch (dspp) {
+ case DSPP_0:
+ flushbits = BIT(13);
+ break;
+ case DSPP_1:
+ flushbits = BIT(14);
+ break;
+ case DSPP_2:
+ flushbits = BIT(15);
+ break;
+ case DSPP_3:
+ flushbits = BIT(21);
+ break;
+ default:
+ return 0;
+ }
+
+ return flushbits;
+}
+
static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
@@ -548,6 +573,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
+ ops->get_bitmask_dspp = dpu_hw_ctl_get_bitmask_dspp;
};
static struct dpu_hw_blk_ops dpu_hw_ops;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 09e1263c72e2..ec579b470a80 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -139,6 +139,9 @@ struct dpu_hw_ctl_ops {
uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
enum dpu_lm blk);
+ uint32_t (*get_bitmask_dspp)(struct dpu_hw_ctl *ctx,
+ enum dpu_dspp blk);
+
/**
* Query the value of the intf flush mask
* No effect on hardware
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
new file mode 100644
index 000000000000..a7a24539921f
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_dspp.h"
+#include "dpu_kms.h"
+
+
+/* DSPP_PCC */
+#define PCC_EN BIT(0)
+#define PCC_DIS 0
+#define PCC_RED_R_OFF 0x10
+#define PCC_RED_G_OFF 0x1C
+#define PCC_RED_B_OFF 0x28
+#define PCC_GREEN_R_OFF 0x14
+#define PCC_GREEN_G_OFF 0x20
+#define PCC_GREEN_B_OFF 0x2C
+#define PCC_BLUE_R_OFF 0x18
+#define PCC_BLUE_G_OFF 0x24
+#define PCC_BLUE_B_OFF 0x30
+
+static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx,
+ struct dpu_hw_pcc_cfg *cfg)
+{
+
+ u32 base = ctx->cap->sblk->pcc.base;
+
+ if (!ctx || !base) {
+ DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base);
+ return;
+ }
+
+ if (!cfg) {
+ DRM_DEBUG_DRIVER("disable pcc feature\n");
+ DPU_REG_WRITE(&ctx->hw, base, PCC_DIS);
+ return;
+ }
+
+ DPU_REG_WRITE(&ctx->hw, base + PCC_RED_R_OFF, cfg->r.r);
+ DPU_REG_WRITE(&ctx->hw, base + PCC_RED_G_OFF, cfg->r.g);
+ DPU_REG_WRITE(&ctx->hw, base + PCC_RED_B_OFF, cfg->r.b);
+
+ DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_R_OFF, cfg->g.r);
+ DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_G_OFF, cfg->g.g);
+ DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_B_OFF, cfg->g.b);
+
+ DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_R_OFF, cfg->b.r);
+ DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_G_OFF, cfg->b.g);
+ DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_B_OFF, cfg->b.b);
+
+ DPU_REG_WRITE(&ctx->hw, base, PCC_EN);
+}
+
+static void _setup_dspp_ops(struct dpu_hw_dspp *c,
+ unsigned long features)
+{
+ if (test_bit(DPU_DSPP_PCC, &features) &&
+ IS_SC7180_TARGET(c->hw.hwversion))
+ c->ops.setup_pcc = dpu_setup_dspp_pcc;
+}
+
+static const struct dpu_dspp_cfg *_dspp_offset(enum dpu_dspp dspp,
+ const struct dpu_mdss_cfg *m,
+ void __iomem *addr,
+ struct dpu_hw_blk_reg_map *b)
+{
+ int i;
+
+ if (!m || !addr || !b)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < m->dspp_count; i++) {
+ if (dspp == m->dspp[i].id) {
+ b->base_off = addr;
+ b->blk_off = m->dspp[i].base;
+ b->length = m->dspp[i].len;
+ b->hwversion = m->hwversion;
+ b->log_mask = DPU_DBG_MASK_DSPP;
+ return &m->dspp[i];
+ }
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+static struct dpu_hw_blk_ops dpu_hw_ops;
+
+struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
+ void __iomem *addr,
+ const struct dpu_mdss_cfg *m)
+{
+ struct dpu_hw_dspp *c;
+ const struct dpu_dspp_cfg *cfg;
+
+ if (!addr || !m)
+ return ERR_PTR(-EINVAL);
+
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
+ if (!c)
+ return ERR_PTR(-ENOMEM);
+
+ cfg = _dspp_offset(idx, m, addr, &c->hw);
+ if (IS_ERR_OR_NULL(cfg)) {
+ kfree(c);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* Assign ops */
+ c->idx = idx;
+ c->cap = cfg;
+ _setup_dspp_ops(c, c->cap->features);
+
+ dpu_hw_blk_init(&c->base, DPU_HW_BLK_DSPP, idx, &dpu_hw_ops);
+
+ return c;
+}
+
+void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
+{
+ if (dspp)
+ dpu_hw_blk_destroy(&dspp->base);
+
+ kfree(dspp);
+}
+
+
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h
new file mode 100644
index 000000000000..7fa189cfcb06
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_DSPP_H
+#define _DPU_HW_DSPP_H
+
+#include "dpu_hw_blk.h"
+
+struct dpu_hw_dspp;
+
+/**
+ * struct dpu_hw_pcc_coeff - PCC coefficient structure for each color
+ * component.
+ * @r: red coefficient.
+ * @g: green coefficient.
+ * @b: blue coefficient.
+ */
+
+struct dpu_hw_pcc_coeff {
+ __u32 r;
+ __u32 g;
+ __u32 b;
+};
+
+/**
+ * struct dpu_hw_pcc - pcc feature structure
+ * @r: red coefficients.
+ * @g: green coefficients.
+ * @b: blue coefficients.
+ */
+struct dpu_hw_pcc_cfg {
+ struct dpu_hw_pcc_coeff r;
+ struct dpu_hw_pcc_coeff g;
+ struct dpu_hw_pcc_coeff b;
+};
+
+/**
+ * struct dpu_hw_dspp_ops - interface to the dspp hardware driver functions
+ * Caller must call the init function to get the dspp context for each dspp
+ * Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_dspp_ops {
+ /**
+ * setup_pcc - setup dspp pcc
+ * @ctx: Pointer to dspp context
+ * @cfg: Pointer to configuration
+ */
+ void (*setup_pcc)(struct dpu_hw_dspp *ctx, struct dpu_hw_pcc_cfg *cfg);
+
+};
+
+/**
+ * struct dpu_hw_dspp - dspp description
+ * @base: Hardware block base structure
+ * @hw: Block hardware details
+ * @idx: DSPP index
+ * @cap: Pointer to layer_cfg
+ * @ops: Pointer to operations possible for this DSPP
+ */
+struct dpu_hw_dspp {
+ struct dpu_hw_blk base;
+ struct dpu_hw_blk_reg_map hw;
+
+ /* dspp */
+ int idx;
+ const struct dpu_dspp_cfg *cap;
+
+ /* Ops */
+ struct dpu_hw_dspp_ops ops;
+};
+
+/**
+ * dpu_hw_dspp - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw)
+{
+ return container_of(hw, struct dpu_hw_dspp, base);
+}
+
+/**
+ * dpu_hw_dspp_init - initializes the dspp hw driver object.
+ * should be called once before accessing every dspp.
+ * @idx: DSPP index for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * @Return: pointer to structure or ERR_PTR
+ */
+struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
+ void __iomem *addr, const struct dpu_mdss_cfg *m);
+
+/**
+ * dpu_hw_dspp_destroy(): Destroys DSPP driver context
+ * @dspp: Pointer to DSPP driver context
+ */
+void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp);
+
+#endif /*_DPU_HW_DSPP_H */
+
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 686882132bf6..402dc5832361 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -95,6 +95,7 @@ enum dpu_hw_blk_type {
DPU_HW_BLK_PINGPONG,
DPU_HW_BLK_INTF,
DPU_HW_BLK_WB,
+ DPU_HW_BLK_DSPP,
DPU_HW_BLK_MAX,
};
@@ -425,5 +426,6 @@ struct dpu_mdss_color {
#define DPU_DBG_MASK_TOP (1 << 7)
#define DPU_DBG_MASK_VBIF (1 << 8)
#define DPU_DBG_MASK_ROT (1 << 9)
+#define DPU_DBG_MASK_DSPP (1 << 10)
#endif /* _DPU_HW_MDSS_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ce19f1d39367..b8615d4fe8a3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -772,29 +772,21 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
{
struct iommu_domain *domain;
struct msm_gem_address_space *aspace;
- int ret;
+ struct msm_mmu *mmu;
domain = iommu_domain_alloc(&platform_bus_type);
if (!domain)
return 0;
- domain->geometry.aperture_start = 0x1000;
- domain->geometry.aperture_end = 0xffffffff;
+ mmu = msm_iommu_new(dpu_kms->dev->dev, domain);
+ aspace = msm_gem_address_space_create(mmu, "dpu1",
+ 0x1000, 0xfffffff);
- aspace = msm_gem_address_space_create(dpu_kms->dev->dev,
- domain, "dpu1");
if (IS_ERR(aspace)) {
- iommu_domain_free(domain);
+ mmu->funcs->destroy(mmu);
return PTR_ERR(aspace);
}
- ret = aspace->mmu->funcs->attach(aspace->mmu);
- if (ret) {
- DPU_ERROR("failed to attach iommu %d\n", ret);
- msm_gem_address_space_put(aspace);
- return ret;
- }
-
dpu_kms->base.aspace = aspace;
return 0;
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 9aba2910d83a..a3b122bfb676 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -158,6 +158,7 @@ struct dpu_global_state {
uint32_t mixer_to_enc_id[LM_MAX - LM_0];
uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
+ uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
};
struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 9b62451b01ee..9b2b5044e8e0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -9,6 +9,7 @@
#include "dpu_hw_ctl.h"
#include "dpu_hw_pingpong.h"
#include "dpu_hw_intf.h"
+#include "dpu_hw_dspp.h"
#include "dpu_encoder.h"
#include "dpu_trace.h"
@@ -174,6 +175,23 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->ctl_blks[ctl->id - CTL_0] = &hw->base;
}
+ for (i = 0; i < cat->dspp_count; i++) {
+ struct dpu_hw_dspp *hw;
+ const struct dpu_dspp_cfg *dspp = &cat->dspp[i];
+
+ if (dspp->id < DSPP_0 || dspp->id >= DSPP_MAX) {
+ DPU_ERROR("skip dspp %d with invalid id\n", dspp->id);
+ continue;
+ }
+ hw = dpu_hw_dspp_init(dspp->id, mmio, cat);
+ if (IS_ERR_OR_NULL(hw)) {
+ rc = PTR_ERR(hw);
+ DPU_ERROR("failed dspp object creation: err %d\n", rc);
+ goto fail;
+ }
+ rm->dspp_blks[dspp->id - DSPP_0] = &hw->base;
+ }
+
return 0;
fail:
@@ -222,12 +240,17 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx,
* if lm, and all other hardwired blocks connected to the lm (pp) is
* available and appropriate
* @pp_idx: output parameter, index of pingpong block attached to the layer
- * mixer in rm->pongpong_blks[].
+ * mixer in rm->pingpong_blks[].
+ * @dspp_idx: output parameter, index of dspp block attached to the layer
+ * mixer in rm->dspp_blks[].
+ * @reqs: input parameter, rm requirements for HW blocks needed in the
+ * datapath.
* @Return: true if lm matches all requirements, false otherwise
*/
static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id, int lm_idx, int *pp_idx)
+ uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
+ struct dpu_rm_requirements *reqs)
{
const struct dpu_lm_cfg *lm_cfg;
int idx;
@@ -251,6 +274,23 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
return false;
}
*pp_idx = idx;
+
+ if (!reqs->topology.num_dspp)
+ return true;
+
+ idx = lm_cfg->dspp - DSPP_0;
+ if (idx < 0 || idx >= ARRAY_SIZE(rm->dspp_blks)) {
+ DPU_ERROR("failed to get dspp on lm %d\n", lm_cfg->dspp);
+ return false;
+ }
+
+ if (reserved_by_other(global_state->dspp_to_enc_id, idx, enc_id)) {
+ DPU_DEBUG("lm %d dspp %d already reserved\n", lm_cfg->id,
+ lm_cfg->dspp);
+ return false;
+ }
+ *dspp_idx = idx;
+
return true;
}
@@ -262,6 +302,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
{
int lm_idx[MAX_BLOCKS];
int pp_idx[MAX_BLOCKS];
+ int dspp_idx[MAX_BLOCKS] = {0};
int i, j, lm_count = 0;
if (!reqs->topology.num_lm) {
@@ -279,7 +320,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
lm_idx[lm_count] = i;
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
- enc_id, i, &pp_idx[lm_count])) {
+ enc_id, i, &pp_idx[lm_count],
+ &dspp_idx[lm_count], reqs)) {
continue;
}
@@ -299,7 +341,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
if (!_dpu_rm_check_lm_and_get_connected_blks(rm,
global_state, enc_id, j,
- &pp_idx[lm_count])) {
+ &pp_idx[lm_count], &dspp_idx[lm_count],
+ reqs)) {
continue;
}
@@ -316,6 +359,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
for (i = 0; i < lm_count; i++) {
global_state->mixer_to_enc_id[lm_idx[i]] = enc_id;
global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id;
+ global_state->dspp_to_enc_id[dspp_idx[i]] =
+ reqs->topology.num_dspp ? enc_id : 0;
trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
pp_idx[i] + PINGPONG_0);
@@ -560,6 +605,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
hw_to_enc_id = global_state->intf_to_enc_id;
max_blks = ARRAY_SIZE(rm->intf_blks);
break;
+ case DPU_HW_BLK_DSPP:
+ hw_blks = rm->dspp_blks;
+ hw_to_enc_id = global_state->dspp_to_enc_id;
+ max_blks = ARRAY_SIZE(rm->dspp_blks);
+ break;
default:
DPU_ERROR("blk type %d not managed by rm\n", type);
return 0;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 6d2b04f306f0..08726bb1063a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -19,6 +19,7 @@ struct dpu_global_state;
* @mixer_blks: array of layer mixer hardware resources
* @ctl_blks: array of ctl hardware resources
* @intf_blks: array of intf hardware resources
+ * @dspp_blks: array of dspp hardware resources
* @lm_max_width: cached layer mixer maximum width
* @rm_lock: resource manager mutex
*/
@@ -27,6 +28,7 @@ struct dpu_rm {
struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0];
+ struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
uint32_t lm_max_width;
};
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index dda05436f716..08897184b1d9 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -510,18 +510,20 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
mdelay(16);
if (config->iommu) {
- aspace = msm_gem_address_space_create(&pdev->dev,
- config->iommu, "mdp4");
+ struct msm_mmu *mmu = msm_iommu_new(&pdev->dev,
+ config->iommu);
+
+ aspace = msm_gem_address_space_create(mmu,
+ "mdp4", 0x1000, 0xffffffff);
+
if (IS_ERR(aspace)) {
+ if (!IS_ERR(mmu))
+ mmu->funcs->destroy(mmu);
ret = PTR_ERR(aspace);
goto fail;
}
kms->aspace = aspace;
-
- ret = aspace->mmu->funcs->attach(aspace->mmu);
- if (ret)
- goto fail;
} else {
DRM_DEV_INFO(dev->dev, "no iommu, fallback to phys "
"contig buffers for scanout\n");
@@ -569,10 +571,6 @@ static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev)
/* TODO: Chips that aren't apq8064 have a 200 Mhz max_clk */
config.max_clk = 266667000;
config.iommu = iommu_domain_alloc(&platform_bus_type);
- if (config.iommu) {
- config.iommu->geometry.aperture_start = 0x1000;
- config.iommu->geometry.aperture_end = 0xffffffff;
- }
return &config;
}
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
index e3c4c250238b..25a13a2a57a9 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
@@ -342,6 +342,81 @@ static const struct mdp5_cfg_hw msm8x16_config = {
.max_clk = 320000000,
};
+static const struct mdp5_cfg_hw msm8x36_config = {
+ .name = "msm8x36",
+ .mdp = {
+ .count = 1,
+ .base = { 0x0 },
+ .caps = MDP_CAP_SMP |
+ 0,
+ },
+ .smp = {
+ .mmb_count = 8,
+ .mmb_size = 10240,
+ .clients = {
+ [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+ [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+ },
+ },
+ .ctl = {
+ .count = 3,
+ .base = { 0x01000, 0x01200, 0x01400 },
+ .flush_hw_mask = 0x4003ffff,
+ },
+ .pipe_vig = {
+ .count = 1,
+ .base = { 0x04000 },
+ .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+ MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
+ MDP_PIPE_CAP_DECIMATION,
+ },
+ .pipe_rgb = {
+ .count = 2,
+ .base = { 0x14000, 0x16000 },
+ .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+ MDP_PIPE_CAP_DECIMATION,
+ },
+ .pipe_dma = {
+ .count = 1,
+ .base = { 0x24000 },
+ .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
+ },
+ .lm = {
+ .count = 2,
+ .base = { 0x44000, 0x47000 },
+ .instances = {
+ { .id = 0, .pp = 0, .dspp = 0,
+ .caps = MDP_LM_CAP_DISPLAY, },
+ { .id = 1, .pp = -1, .dspp = -1,
+ .caps = MDP_LM_CAP_WB, },
+ },
+ .nb_stages = 8,
+ .max_width = 2560,
+ .max_height = 0xFFFF,
+ },
+ .pp = {
+ .count = 1,
+ .base = { 0x70000 },
+ },
+ .ad = {
+ .count = 1,
+ .base = { 0x78000 },
+ },
+ .dspp = {
+ .count = 1,
+ .base = { 0x54000 },
+ },
+ .intf = {
+ .base = { 0x00000, 0x6a800, 0x6b000 },
+ .connect = {
+ [0] = INTF_DISABLED,
+ [1] = INTF_DSI,
+ [2] = INTF_DSI,
+ },
+ },
+ .max_clk = 366670000,
+};
+
static const struct mdp5_cfg_hw msm8x94_config = {
.name = "msm8x94",
.mdp = {
@@ -840,6 +915,7 @@ static const struct mdp5_cfg_handler cfg_handlers_v1[] = {
{ .revision = 2, .config = { .hw = &msm8x74v2_config } },
{ .revision = 3, .config = { .hw = &apq8084_config } },
{ .revision = 6, .config = { .hw = &msm8x16_config } },
+ { .revision = 8, .config = { .hw = &msm8x36_config } },
{ .revision = 9, .config = { .hw = &msm8x94_config } },
{ .revision = 7, .config = { .hw = &msm8x96_config } },
{ .revision = 11, .config = { .hw = &msm8x76_config } },
@@ -941,10 +1017,6 @@ static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev)
static struct mdp5_cfg_platform config = {};
config.iommu = iommu_domain_alloc(&platform_bus_type);
- if (config.iommu) {
- config.iommu->geometry.aperture_start = 0x1000;
- config.iommu->geometry.aperture_end = 0xffffffff;
- }
return &config;
}
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 998bef1190a3..b5fed67c4651 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -959,7 +959,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
if (!ctl)
return -EINVAL;
- /* don't support LM cursors when we we have source split enabled */
+ /* don't support LM cursors when we have source split enabled */
if (mdp5_cstate->pipeline.r_mixer)
return -EINVAL;
@@ -1030,7 +1030,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
return -EINVAL;
}
- /* don't support LM cursors when we we have source split enabled */
+ /* don't support LM cursors when we have source split enabled */
if (mdp5_cstate->pipeline.r_mixer)
return -EINVAL;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index c902c6503675..19ec48695ffb 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -624,25 +624,25 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
mdelay(16);
if (config->platform.iommu) {
+ struct msm_mmu *mmu;
+
iommu_dev = &pdev->dev;
if (!dev_iommu_fwspec_get(iommu_dev))
iommu_dev = iommu_dev->parent;
- aspace = msm_gem_address_space_create(iommu_dev,
- config->platform.iommu, "mdp5");
+ mmu = msm_iommu_new(iommu_dev, config->platform.iommu);
+
+ aspace = msm_gem_address_space_create(mmu, "mdp5",
+ 0x1000, 0xffffffff);
+
if (IS_ERR(aspace)) {
+ if (!IS_ERR(mmu))
+ mmu->funcs->destroy(mmu);
ret = PTR_ERR(aspace);
goto fail;
}
kms->aspace = aspace;
-
- ret = aspace->mmu->funcs->attach(aspace->mmu);
- if (ret) {
- DRM_DEV_ERROR(&pdev->dev, "failed to attach iommu: %d\n",
- ret);
- goto fail;
- }
} else {
DRM_DEV_INFO(&pdev->dev,
"no iommu, fallback to phys contig buffers for scanout\n");
@@ -935,7 +935,8 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
return 0;
fail:
- mdp5_destroy(pdev);
+ if (mdp5_kms)
+ mdp5_destroy(pdev);
return ret;
}
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 29295dee2a2e..f6ce40bf3699 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -37,9 +37,10 @@
* - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
* GEM object's debug name
* - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
+ * - 1.6.0 - Syncobj support
*/
#define MSM_VERSION_MAJOR 1
-#define MSM_VERSION_MINOR 5
+#define MSM_VERSION_MINOR 6
#define MSM_VERSION_PATCHLEVEL 0
static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -1002,7 +1003,8 @@ static struct drm_driver msm_driver = {
.driver_features = DRIVER_GEM |
DRIVER_RENDER |
DRIVER_ATOMIC |
- DRIVER_MODESET,
+ DRIVER_MODESET |
+ DRIVER_SYNCOBJ,
.open = msm_open,
.postclose = msm_postclose,
.lastclose = drm_fb_helper_lastclose,
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 194d900a460e..e2d6a6056418 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -105,6 +105,7 @@ struct msm_display_topology {
u32 num_lm;
u32 num_enc;
u32 num_intf;
+ u32 num_dspp;
};
/**
@@ -236,7 +237,8 @@ int msm_crtc_enable_vblank(struct drm_crtc *crtc);
void msm_crtc_disable_vblank(struct drm_crtc *crtc);
int msm_gem_init_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, int npages);
+ struct msm_gem_vma *vma, int npages,
+ u64 range_start, u64 range_end);
void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma);
void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
@@ -250,12 +252,8 @@ void msm_gem_close_vma(struct msm_gem_address_space *aspace,
void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
struct msm_gem_address_space *
-msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
- const char *name);
-
-struct msm_gem_address_space *
-msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
- const char *name, uint64_t va_start, uint64_t va_end);
+msm_gem_address_space_create(struct msm_mmu *mmu, const char *name,
+ u64 va_start, u64 size);
int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);
@@ -276,6 +274,9 @@ vm_fault_t msm_gem_fault(struct vm_fault *vmf);
uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
int msm_gem_get_iova(struct drm_gem_object *obj,
struct msm_gem_address_space *aspace, uint64_t *iova);
+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
+ struct msm_gem_address_space *aspace, uint64_t *iova,
+ u64 range_start, u64 range_end);
int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
struct msm_gem_address_space *aspace, uint64_t *iova);
uint64_t msm_gem_iova(struct drm_gem_object *obj,
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79fbc9d6..6277fde13df9 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -389,7 +389,8 @@ put_iova(struct drm_gem_object *obj)
}
static int msm_gem_get_iova_locked(struct drm_gem_object *obj,
- struct msm_gem_address_space *aspace, uint64_t *iova)
+ struct msm_gem_address_space *aspace, uint64_t *iova,
+ u64 range_start, u64 range_end)
{
struct msm_gem_object *msm_obj = to_msm_bo(obj);
struct msm_gem_vma *vma;
@@ -404,7 +405,8 @@ static int msm_gem_get_iova_locked(struct drm_gem_object *obj,
if (IS_ERR(vma))
return PTR_ERR(vma);
- ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT);
+ ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT,
+ range_start, range_end);
if (ret) {
del_vma(vma);
return ret;
@@ -426,6 +428,9 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
if (!(msm_obj->flags & MSM_BO_GPU_READONLY))
prot |= IOMMU_WRITE;
+ if (msm_obj->flags & MSM_BO_MAP_PRIV)
+ prot |= IOMMU_PRIV;
+
WARN_ON(!mutex_is_locked(&msm_obj->lock));
if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED))
@@ -443,9 +448,13 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
msm_obj->sgt, obj->size >> PAGE_SHIFT);
}
-/* get iova and pin it. Should have a matching put */
-int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
- struct msm_gem_address_space *aspace, uint64_t *iova)
+/*
+ * get iova and pin it. Should have a matching put
+ * limits iova to specified range (in pages)
+ */
+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
+ struct msm_gem_address_space *aspace, uint64_t *iova,
+ u64 range_start, u64 range_end)
{
struct msm_gem_object *msm_obj = to_msm_bo(obj);
u64 local;
@@ -453,7 +462,8 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
mutex_lock(&msm_obj->lock);
- ret = msm_gem_get_iova_locked(obj, aspace, &local);
+ ret = msm_gem_get_iova_locked(obj, aspace, &local,
+ range_start, range_end);
if (!ret)
ret = msm_gem_pin_iova(obj, aspace);
@@ -465,6 +475,13 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
return ret;
}
+/* get iova and pin it. Should have a matching put */
+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
+ struct msm_gem_address_space *aspace, uint64_t *iova)
+{
+ return msm_gem_get_and_pin_iova_range(obj, aspace, iova, 0, U64_MAX);
+}
+
/*
* Get an iova but don't pin it. Doesn't need a put because iovas are currently
* valid for the life of the object
@@ -476,7 +493,7 @@ int msm_gem_get_iova(struct drm_gem_object *obj,
int ret;
mutex_lock(&msm_obj->lock);
- ret = msm_gem_get_iova_locked(obj, aspace, iova);
+ ret = msm_gem_get_iova_locked(obj, aspace, iova, 0, U64_MAX);
mutex_unlock(&msm_obj->lock);
return ret;
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 30584eaf8cc8..972490b14ba5 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -13,6 +13,7 @@
/* Additional internal-use only BO flags: */
#define MSM_BO_STOLEN 0x10000000 /* try to use stolen/splash memory */
+#define MSM_BO_MAP_PRIV 0x20000000 /* use IOMMU_PRIV when mapping */
struct msm_gem_address_space {
const char *name;
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 385d4965a8d0..6630aa817505 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -8,7 +8,9 @@
#include <linux/sync_file.h>
#include <linux/uaccess.h>
+#include <drm/drm_drv.h>
#include <drm/drm_file.h>
+#include <drm/drm_syncobj.h>
#include "msm_drv.h"
#include "msm_gpu.h"
@@ -391,6 +393,186 @@ static void submit_cleanup(struct msm_gem_submit *submit)
}
}
+
+struct msm_submit_post_dep {
+ struct drm_syncobj *syncobj;
+ uint64_t point;
+ struct dma_fence_chain *chain;
+};
+
+static struct drm_syncobj **msm_wait_deps(struct drm_device *dev,
+ struct drm_file *file,
+ uint64_t in_syncobjs_addr,
+ uint32_t nr_in_syncobjs,
+ size_t syncobj_stride,
+ struct msm_ringbuffer *ring)
+{
+ struct drm_syncobj **syncobjs = NULL;
+ struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
+ int ret = 0;
+ uint32_t i, j;
+
+ syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs),
+ GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+ if (!syncobjs)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < nr_in_syncobjs; ++i) {
+ uint64_t address = in_syncobjs_addr + i * syncobj_stride;
+ struct dma_fence *fence;
+
+ if (copy_from_user(&syncobj_desc,
+ u64_to_user_ptr(address),
+ min(syncobj_stride, sizeof(syncobj_desc)))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (syncobj_desc.point &&
+ !drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) {
+ ret = -EINVAL;
+ break;
+ }
+
+ ret = drm_syncobj_find_fence(file, syncobj_desc.handle,
+ syncobj_desc.point, 0, &fence);
+ if (ret)
+ break;
+
+ if (!dma_fence_match_context(fence, ring->fctx->context))
+ ret = dma_fence_wait(fence, true);
+
+ dma_fence_put(fence);
+ if (ret)
+ break;
+
+ if (syncobj_desc.flags & MSM_SUBMIT_SYNCOBJ_RESET) {
+ syncobjs[i] =
+ drm_syncobj_find(file, syncobj_desc.handle);
+ if (!syncobjs[i]) {
+ ret = -EINVAL;
+ break;
+ }
+ }
+ }
+
+ if (ret) {
+ for (j = 0; j <= i; ++j) {
+ if (syncobjs[j])
+ drm_syncobj_put(syncobjs[j]);
+ }
+ kfree(syncobjs);
+ return ERR_PTR(ret);
+ }
+ return syncobjs;
+}
+
+static void msm_reset_syncobjs(struct drm_syncobj **syncobjs,
+ uint32_t nr_syncobjs)
+{
+ uint32_t i;
+
+ for (i = 0; syncobjs && i < nr_syncobjs; ++i) {
+ if (syncobjs[i])
+ drm_syncobj_replace_fence(syncobjs[i], NULL);
+ }
+}
+
+static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
+ struct drm_file *file,
+ uint64_t syncobjs_addr,
+ uint32_t nr_syncobjs,
+ size_t syncobj_stride)
+{
+ struct msm_submit_post_dep *post_deps;
+ struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
+ int ret = 0;
+ uint32_t i, j;
+
+ post_deps = kmalloc_array(nr_syncobjs, sizeof(*post_deps),
+ GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+ if (!post_deps)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < nr_syncobjs; ++i) {
+ uint64_t address = syncobjs_addr + i * syncobj_stride;
+
+ if (copy_from_user(&syncobj_desc,
+ u64_to_user_ptr(address),
+ min(syncobj_stride, sizeof(syncobj_desc)))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ post_deps[i].point = syncobj_desc.point;
+ post_deps[i].chain = NULL;
+
+ if (syncobj_desc.flags) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (syncobj_desc.point) {
+ if (!drm_core_check_feature(dev,
+ DRIVER_SYNCOBJ_TIMELINE)) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ post_deps[i].chain =
+ kmalloc(sizeof(*post_deps[i].chain),
+ GFP_KERNEL);
+ if (!post_deps[i].chain) {
+ ret = -ENOMEM;
+ break;
+ }
+ }
+
+ post_deps[i].syncobj =
+ drm_syncobj_find(file, syncobj_desc.handle);
+ if (!post_deps[i].syncobj) {
+ ret = -EINVAL;
+ break;
+ }
+ }
+
+ if (ret) {
+ for (j = 0; j <= i; ++j) {
+ kfree(post_deps[j].chain);
+ if (post_deps[j].syncobj)
+ drm_syncobj_put(post_deps[j].syncobj);
+ }
+
+ kfree(post_deps);
+ return ERR_PTR(ret);
+ }
+
+ return post_deps;
+}
+
+static void msm_process_post_deps(struct msm_submit_post_dep *post_deps,
+ uint32_t count, struct dma_fence *fence)
+{
+ uint32_t i;
+
+ for (i = 0; post_deps && i < count; ++i) {
+ if (post_deps[i].chain) {
+ drm_syncobj_add_point(post_deps[i].syncobj,
+ post_deps[i].chain,
+ fence, post_deps[i].point);
+ post_deps[i].chain = NULL;
+ } else {
+ drm_syncobj_replace_fence(post_deps[i].syncobj,
+ fence);
+ }
+ }
+}
+
int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -403,6 +585,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct sync_file *sync_file = NULL;
struct msm_gpu_submitqueue *queue;
struct msm_ringbuffer *ring;
+ struct msm_submit_post_dep *post_deps = NULL;
+ struct drm_syncobj **syncobjs_to_reset = NULL;
int out_fence_fd = -1;
struct pid *pid = get_pid(task_pid(current));
bool has_ww_ticket = false;
@@ -411,6 +595,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
if (!gpu)
return -ENXIO;
+ if (args->pad)
+ return -EINVAL;
+
/* for now, we just have 3d pipe.. eventually this would need to
* be more clever to dispatch to appropriate gpu module:
*/
@@ -458,9 +645,29 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
return ret;
}
+ if (args->flags & MSM_SUBMIT_SYNCOBJ_IN) {
+ syncobjs_to_reset = msm_wait_deps(dev, file,
+ args->in_syncobjs,
+ args->nr_in_syncobjs,
+ args->syncobj_stride, ring);
+ if (IS_ERR(syncobjs_to_reset))
+ return PTR_ERR(syncobjs_to_reset);
+ }
+
+ if (args->flags & MSM_SUBMIT_SYNCOBJ_OUT) {
+ post_deps = msm_parse_post_deps(dev, file,
+ args->out_syncobjs,
+ args->nr_out_syncobjs,
+ args->syncobj_stride);
+ if (IS_ERR(post_deps)) {
+ ret = PTR_ERR(post_deps);
+ goto out_post_unlock;
+ }
+ }
+
ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
- return ret;
+ goto out_post_unlock;
if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
@@ -587,6 +794,11 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
args->fence_fd = out_fence_fd;
}
+ msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
+ msm_process_post_deps(post_deps, args->nr_out_syncobjs,
+ submit->fence);
+
+
out:
submit_cleanup(submit);
if (has_ww_ticket)
@@ -597,5 +809,23 @@ out_unlock:
if (ret && (out_fence_fd >= 0))
put_unused_fd(out_fence_fd);
mutex_unlock(&dev->struct_mutex);
+
+out_post_unlock:
+ if (!IS_ERR_OR_NULL(post_deps)) {
+ for (i = 0; i < args->nr_out_syncobjs; ++i) {
+ kfree(post_deps[i].chain);
+ drm_syncobj_put(post_deps[i].syncobj);
+ }
+ kfree(post_deps);
+ }
+
+ if (!IS_ERR_OR_NULL(syncobjs_to_reset)) {
+ for (i = 0; i < args->nr_in_syncobjs; ++i) {
+ if (syncobjs_to_reset[i])
+ drm_syncobj_put(syncobjs_to_reset[i]);
+ }
+ kfree(syncobjs_to_reset);
+ }
+
return ret;
}
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index 1af5354bcd46..5f6a11211b64 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -103,7 +103,8 @@ void msm_gem_close_vma(struct msm_gem_address_space *aspace,
/* Initialize a new vma and allocate an iova for it */
int msm_gem_init_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, int npages)
+ struct msm_gem_vma *vma, int npages,
+ u64 range_start, u64 range_end)
{
int ret;
@@ -111,7 +112,8 @@ int msm_gem_init_vma(struct msm_gem_address_space *aspace,
return -EBUSY;
spin_lock(&aspace->lock);
- ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages);
+ ret = drm_mm_insert_node_in_range(&aspace->mm, &vma->node, npages, 0,
+ 0, range_start, range_end, 0);
spin_unlock(&aspace->lock);
if (ret)
@@ -125,37 +127,14 @@ int msm_gem_init_vma(struct msm_gem_address_space *aspace,
return 0;
}
-
struct msm_gem_address_space *
-msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
- const char *name)
+msm_gem_address_space_create(struct msm_mmu *mmu, const char *name,
+ u64 va_start, u64 size)
{
struct msm_gem_address_space *aspace;
- u64 size = domain->geometry.aperture_end -
- domain->geometry.aperture_start;
-
- aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
- if (!aspace)
- return ERR_PTR(-ENOMEM);
-
- spin_lock_init(&aspace->lock);
- aspace->name = name;
- aspace->mmu = msm_iommu_new(dev, domain);
-
- drm_mm_init(&aspace->mm, (domain->geometry.aperture_start >> PAGE_SHIFT),
- size >> PAGE_SHIFT);
- kref_init(&aspace->kref);
-
- return aspace;
-}
-
-struct msm_gem_address_space *
-msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
- const char *name, uint64_t va_start, uint64_t va_end)
-{
- struct msm_gem_address_space *aspace;
- u64 size = va_end - va_start;
+ if (IS_ERR(mmu))
+ return ERR_CAST(mmu);
aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
if (!aspace)
@@ -163,10 +142,9 @@ msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
spin_lock_init(&aspace->lock);
aspace->name = name;
- aspace->mmu = msm_gpummu_new(dev, gpu);
+ aspace->mmu = mmu;
- drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT),
- size >> PAGE_SHIFT);
+ drm_mm_init(&aspace->mm, va_start >> PAGE_SHIFT, size >> PAGE_SHIFT);
kref_init(&aspace->kref);
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 615c5cda5389..a22d30622306 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -821,51 +821,6 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
return 0;
}
-static struct msm_gem_address_space *
-msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
- uint64_t va_start, uint64_t va_end)
-{
- struct msm_gem_address_space *aspace;
- int ret;
-
- /*
- * Setup IOMMU.. eventually we will (I think) do this once per context
- * and have separate page tables per context. For now, to keep things
- * simple and to get something working, just use a single address space:
- */
- if (!adreno_is_a2xx(to_adreno_gpu(gpu))) {
- struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
- if (!iommu)
- return NULL;
-
- iommu->geometry.aperture_start = va_start;
- iommu->geometry.aperture_end = va_end;
-
- DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name);
-
- aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu");
- if (IS_ERR(aspace))
- iommu_domain_free(iommu);
- } else {
- aspace = msm_gem_address_space_create_a2xx(&pdev->dev, gpu, "gpu",
- va_start, va_end);
- }
-
- if (IS_ERR(aspace)) {
- DRM_DEV_ERROR(gpu->dev->dev, "failed to init mmu: %ld\n",
- PTR_ERR(aspace));
- return ERR_CAST(aspace);
- }
-
- ret = aspace->mmu->funcs->attach(aspace->mmu);
- if (ret) {
- msm_gem_address_space_put(aspace);
- return ERR_PTR(ret);
- }
-
- return aspace;
-}
-
int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
const char *name, struct msm_gpu_config *config)
@@ -938,8 +893,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
msm_devfreq_init(gpu);
- gpu->aspace = msm_gpu_create_address_space(gpu, pdev,
- config->va_start, config->va_end);
+
+ gpu->aspace = gpu->funcs->create_address_space(gpu, pdev);
if (gpu->aspace == NULL)
DRM_DEV_INFO(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 6ccae4ba905c..429cb40f7931 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -21,8 +21,6 @@ struct msm_gpu_state;
struct msm_gpu_config {
const char *ioname;
- uint64_t va_start;
- uint64_t va_end;
unsigned int nr_rings;
};
@@ -64,6 +62,8 @@ struct msm_gpu_funcs {
int (*gpu_state_put)(struct msm_gpu_state *state);
unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq);
+ struct msm_gem_address_space *(*create_address_space)
+ (struct msm_gpu *gpu, struct platform_device *pdev);
};
struct msm_gpu {
diff --git a/drivers/gpu/drm/msm/msm_gpummu.c b/drivers/gpu/drm/msm/msm_gpummu.c
index 34980d8eb7ad..310a31b05faa 100644
--- a/drivers/gpu/drm/msm/msm_gpummu.c
+++ b/drivers/gpu/drm/msm/msm_gpummu.c
@@ -21,17 +21,12 @@ struct msm_gpummu {
#define GPUMMU_PAGE_SIZE SZ_4K
#define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE)
-static int msm_gpummu_attach(struct msm_mmu *mmu)
-{
- return 0;
-}
-
static void msm_gpummu_detach(struct msm_mmu *mmu)
{
}
static int msm_gpummu_map(struct msm_mmu *mmu, uint64_t iova,
- struct sg_table *sgt, unsigned len, int prot)
+ struct sg_table *sgt, size_t len, int prot)
{
struct msm_gpummu *gpummu = to_msm_gpummu(mmu);
unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
@@ -59,7 +54,7 @@ static int msm_gpummu_map(struct msm_mmu *mmu, uint64_t iova,
return 0;
}
-static int msm_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
+static int msm_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
{
struct msm_gpummu *gpummu = to_msm_gpummu(mmu);
unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
@@ -85,7 +80,6 @@ static void msm_gpummu_destroy(struct msm_mmu *mmu)
}
static const struct msm_mmu_funcs funcs = {
- .attach = msm_gpummu_attach,
.detach = msm_gpummu_detach,
.map = msm_gpummu_map,
.unmap = msm_gpummu_unmap,
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe5998e..3a381a9674c9 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -23,13 +23,6 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
return 0;
}
-static int msm_iommu_attach(struct msm_mmu *mmu)
-{
- struct msm_iommu *iommu = to_msm_iommu(mmu);
-
- return iommu_attach_device(iommu->domain, mmu->dev);
-}
-
static void msm_iommu_detach(struct msm_mmu *mmu)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
@@ -38,7 +31,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu)
}
static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
- struct sg_table *sgt, unsigned len, int prot)
+ struct sg_table *sgt, size_t len, int prot)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
@@ -49,7 +42,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
return (ret == len) ? 0 : -EINVAL;
}
-static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
+static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
@@ -66,7 +59,6 @@ static void msm_iommu_destroy(struct msm_mmu *mmu)
}
static const struct msm_mmu_funcs funcs = {
- .attach = msm_iommu_attach,
.detach = msm_iommu_detach,
.map = msm_iommu_map,
.unmap = msm_iommu_unmap,
@@ -76,6 +68,10 @@ static const struct msm_mmu_funcs funcs = {
struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
{
struct msm_iommu *iommu;
+ int ret;
+
+ if (!domain)
+ return ERR_PTR(-ENODEV);
iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
@@ -85,5 +81,11 @@ struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
msm_mmu_init(&iommu->base, dev, &funcs);
iommu_set_fault_handler(domain, msm_fault_handler, iommu);
+ ret = iommu_attach_device(iommu->domain, dev);
+ if (ret) {
+ kfree(iommu);
+ return ERR_PTR(ret);
+ }
+
return &iommu->base;
}
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index 67a623f14319..3a534ee59bf6 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -10,11 +10,10 @@
#include <linux/iommu.h>
struct msm_mmu_funcs {
- int (*attach)(struct msm_mmu *mmu);
void (*detach)(struct msm_mmu *mmu);
int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
- unsigned len, int prot);
- int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len);
+ size_t len, int prot);
+ int (*unmap)(struct msm_mmu *mmu, uint64_t iova, size_t len);
void (*destroy)(struct msm_mmu *mmu);
};
diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c
index 732f65df5c4f..fea30e7aa9e8 100644
--- a/drivers/gpu/drm/msm/msm_rd.c
+++ b/drivers/gpu/drm/msm/msm_rd.c
@@ -29,8 +29,6 @@
* or shader programs (if not emitted inline in cmdstream).
*/
-#ifdef CONFIG_DEBUG_FS
-
#include <linux/circ_buf.h>
#include <linux/debugfs.h>
#include <linux/kfifo.h>
@@ -47,6 +45,8 @@ bool rd_full = false;
MODULE_PARM_DESC(rd_full, "If true, $debugfs/.../rd will snapshot all buffer contents");
module_param_named(rd_full, rd_full, bool, 0600);
+#ifdef CONFIG_DEBUG_FS
+
enum rd_sect_type {
RD_NONE,
RD_TEST, /* ascii text */
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 7622490d8602..d472942102f5 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -277,7 +277,7 @@ nv50_outp_release(struct nouveau_encoder *nv_encoder)
}
static int
-nv50_outp_acquire(struct nouveau_encoder *nv_encoder)
+nv50_outp_acquire(struct nouveau_encoder *nv_encoder, bool hda)
{
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nv50_disp *disp = nv50_disp(drm->dev);
@@ -289,6 +289,7 @@ nv50_outp_acquire(struct nouveau_encoder *nv_encoder)
.base.method = NV50_DISP_MTHD_V1_ACQUIRE,
.base.hasht = nv_encoder->dcb->hasht,
.base.hashm = nv_encoder->dcb->hashm,
+ .info.hda = hda,
};
int ret;
@@ -393,7 +394,7 @@ nv50_dac_enable(struct drm_encoder *encoder)
struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state);
struct nv50_core *core = nv50_disp(encoder->dev)->core;
- nv50_outp_acquire(nv_encoder);
+ nv50_outp_acquire(nv_encoder, false);
core->func->dac->ctrl(core, nv_encoder->or, 1 << nv_crtc->index, asyh);
asyh->or.depth = 0;
@@ -510,7 +511,7 @@ nv50_audio_component_get_eld(struct device *kdev, int port, int dev_id,
if (!nv_connector || !nv_crtc || nv_encoder->or != port ||
nv_crtc->index != dev_id)
continue;
- *enabled = drm_detect_monitor_audio(nv_connector->edid);
+ *enabled = nv_encoder->audio;
if (*enabled) {
ret = drm_eld_size(nv_connector->base.eld);
memcpy(buf, nv_connector->base.eld,
@@ -600,6 +601,7 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
(0x0100 << nv_crtc->index),
};
+ nv_encoder->audio = false;
nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
nv50_audio_component_eld_notify(drm->audio.component, nv_encoder->or,
@@ -636,6 +638,7 @@ nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
nvif_mthd(&disp->disp->object, 0, &args,
sizeof(args.base) + drm_eld_size(args.data));
+ nv_encoder->audio = true;
nv50_audio_component_eld_notify(drm->audio.component, nv_encoder->or,
nv_crtc->index);
@@ -966,7 +969,7 @@ nv50_msto_enable(struct drm_encoder *encoder)
DRM_DEBUG_KMS("Failed to allocate VCPI\n");
if (!mstm->links++)
- nv50_outp_acquire(mstm->outp);
+ nv50_outp_acquire(mstm->outp, false /*XXX: MST audio.*/);
if (mstm->outp->link & 1)
proto = 0x8;
@@ -1560,12 +1563,18 @@ nv50_sor_enable(struct drm_encoder *encoder)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_connector *nv_connector;
struct nvbios *bios = &drm->vbios;
+ bool hda = false;
u8 proto = 0xf;
u8 depth = 0x0;
nv_connector = nouveau_encoder_connector_get(nv_encoder);
nv_encoder->crtc = encoder->crtc;
- nv50_outp_acquire(nv_encoder);
+
+ if ((disp->disp->object.oclass == GT214_DISP ||
+ disp->disp->object.oclass >= GF110_DISP) &&
+ drm_detect_monitor_audio(nv_connector->edid))
+ hda = true;
+ nv50_outp_acquire(nv_encoder, hda);
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_TMDS:
@@ -1775,7 +1784,7 @@ nv50_pior_enable(struct drm_encoder *encoder)
u8 owner = 1 << nv_crtc->index;
u8 proto;
- nv50_outp_acquire(nv_encoder);
+ nv50_outp_acquire(nv_encoder, false);
switch (asyh->or.bpc) {
case 10: asyh->or.depth = 0x6; break;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index e25ead56052c..99b9b681736d 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -192,6 +192,8 @@ nv50_wndw_atomic_check_release(struct nv50_wndw *wndw,
wndw->func->release(wndw, asyw, asyh);
asyw->ntfy.handle = 0;
asyw->sema.handle = 0;
+ asyw->xlut.handle = 0;
+ memset(asyw->image.handle, 0x00, sizeof(asyw->image.handle));
}
static int
@@ -519,7 +521,8 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state)
return PTR_ERR(ctxdma);
}
- asyw->image.handle[0] = ctxdma->object.handle;
+ if (asyw->visible)
+ asyw->image.handle[0] = ctxdma->object.handle;
}
asyw->state.fence = dma_resv_get_excl_rcu(nvbo->bo.base.resv);
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl5070.h b/drivers/gpu/drm/nouveau/include/nvif/cl5070.h
index 38bf4f38e869..53800fb46582 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/cl5070.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/cl5070.h
@@ -46,7 +46,8 @@ struct nv50_disp_acquire_v0 {
__u8 version;
__u8 or;
__u8 link;
- __u8 pad03[5];
+ __u8 hda;
+ __u8 pad04[4];
};
struct nv50_disp_dac_load_v0 {
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index de51733b0476..a72c412ac8b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -52,6 +52,7 @@ struct nouveau_encoder {
* actually programmed on the hw, not the proposed crtc */
struct drm_crtc *crtc;
u32 ctrl;
+ bool audio;
struct drm_display_mode mode;
int last_dpms;
diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c
index 22f054f7ee3e..ba9f9359c30e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_svm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_svm.c
@@ -175,10 +175,10 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
*/
mm = get_task_mm(current);
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
if (!cli->svm.svmm) {
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return -EINVAL;
}
@@ -205,7 +205,7 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
*/
args->result = 0;
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
return 0;
@@ -355,7 +355,7 @@ nouveau_svmm_init(struct drm_device *dev, void *data,
if (ret)
goto out_free;
- down_write(&current->mm->mmap_sem);
+ mmap_write_lock(current->mm);
svmm->notifier.ops = &nouveau_mn_ops;
ret = __mmu_notifier_register(&svmm->notifier, current->mm);
if (ret)
@@ -364,12 +364,12 @@ nouveau_svmm_init(struct drm_device *dev, void *data,
cli->svm.svmm = svmm;
cli->svm.cli = cli;
- up_write(&current->mm->mmap_sem);
+ mmap_write_unlock(current->mm);
mutex_unlock(&cli->mutex);
return 0;
out_mm_unlock:
- up_write(&current->mm->mmap_sem);
+ mmap_write_unlock(current->mm);
out_free:
mutex_unlock(&cli->mutex);
kfree(svmm);
@@ -571,9 +571,9 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm,
return -EBUSY;
range.notifier_seq = mmu_interval_read_begin(range.notifier);
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
ret = hmm_range_fault(&range);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
if (ret) {
/*
* FIXME: the input PFN_REQ flags are destroyed on
@@ -705,18 +705,18 @@ nouveau_svm_fault(struct nvif_notify *notify)
/* Intersect fault window with the CPU VMA, cancelling
* the fault if the address is invalid.
*/
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = find_vma_intersection(mm, start, limit);
if (!vma) {
SVMM_ERR(svmm, "wndw %016llx-%016llx", start, limit);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
nouveau_svm_fault_cancel_fault(svm, buffer->fault[fi]);
continue;
}
start = max_t(u64, start, vma->vm_start);
limit = min_t(u64, limit, vma->vm_end);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
SVMM_DBG(svmm, "wndw %016llx-%016llx", start, limit);
if (buffer->fault[fi]->addr != start) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
index 571687ba85b8..cf075311cdd2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
@@ -39,6 +39,7 @@ nvkm-y += nvkm/engine/disp/sorgf119.o
nvkm-y += nvkm/engine/disp/sorgk104.o
nvkm-y += nvkm/engine/disp/sorgm107.o
nvkm-y += nvkm/engine/disp/sorgm200.o
+nvkm-y += nvkm/engine/disp/sorgp100.o
nvkm-y += nvkm/engine/disp/sorgv100.o
nvkm-y += nvkm/engine/disp/sortu102.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c
index fd6216684f6d..8471de3f3b61 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c
@@ -36,7 +36,7 @@ gp100_disp = {
.super = gf119_disp_super,
.root = &gp100_disp_root_oclass,
.head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
- .sor = { .cnt = gf119_sor_cnt, .new = gm200_sor_new },
+ .sor = { .cnt = gf119_sor_cnt, .new = gp100_sor_new },
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c
index 3468ddec1270..a3779c5046ea 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c
@@ -63,7 +63,7 @@ gp102_disp = {
.super = gf119_disp_super,
.root = &gp102_disp_root_oclass,
.head = { .cnt = gf119_head_cnt, .new = gf119_head_new },
- .sor = { .cnt = gf119_sor_cnt, .new = gm200_sor_new },
+ .sor = { .cnt = gf119_sor_cnt, .new = gp100_sor_new },
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
index 9b16a08eb4d9..bf6d41fb0c9f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c
@@ -27,10 +27,10 @@ void
gm200_hdmi_scdc(struct nvkm_ior *ior, int head, u8 scdc)
{
struct nvkm_device *device = ior->disp->engine.subdev.device;
- const u32 hoff = head * 0x800;
+ const u32 soff = nv50_ior_base(ior);
const u32 ctrl = scdc & 0x3;
- nvkm_mask(device, 0x61c5bc + hoff, 0x00000003, ctrl);
+ nvkm_mask(device, 0x61c5bc + soff, 0x00000003, ctrl);
ior->tmds.high_speed = !!(scdc & 0x2);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index c1d7a36e4d3c..1a200a9ba4e4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -201,6 +201,7 @@ int gf119_sor_new(struct nvkm_disp *, int);
int gk104_sor_new(struct nvkm_disp *, int);
int gm107_sor_new(struct nvkm_disp *, int);
int gm200_sor_new(struct nvkm_disp *, int);
+int gp100_sor_new(struct nvkm_disp *, int);
int gv100_sor_cnt(struct nvkm_disp *, unsigned long *);
int gv100_sor_new(struct nvkm_disp *, int);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index c62030c96fba..dcf08249374a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -111,8 +111,44 @@ nvkm_outp_acquire_ior(struct nvkm_outp *outp, u8 user, struct nvkm_ior *ior)
return 0;
}
+static inline int
+nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
+ u8 user, bool hda)
+{
+ struct nvkm_ior *ior;
+
+ /* First preference is to reuse the OR that is currently armed
+ * on HW, if any, in order to prevent unnecessary switching.
+ */
+ list_for_each_entry(ior, &outp->disp->ior, head) {
+ if (!ior->identity && !!ior->func->hda.hpd == hda &&
+ !ior->asy.outp && ior->arm.outp == outp)
+ return nvkm_outp_acquire_ior(outp, user, ior);
+ }
+
+ /* Failing that, a completely unused OR is the next best thing. */
+ list_for_each_entry(ior, &outp->disp->ior, head) {
+ if (!ior->identity && !!ior->func->hda.hpd == hda &&
+ !ior->asy.outp && ior->type == type && !ior->arm.outp &&
+ (ior->func->route.set || ior->id == __ffs(outp->info.or)))
+ return nvkm_outp_acquire_ior(outp, user, ior);
+ }
+
+ /* Last resort is to assign an OR that's already active on HW,
+ * but will be released during the next modeset.
+ */
+ list_for_each_entry(ior, &outp->disp->ior, head) {
+ if (!ior->identity && !!ior->func->hda.hpd == hda &&
+ !ior->asy.outp && ior->type == type &&
+ (ior->func->route.set || ior->id == __ffs(outp->info.or)))
+ return nvkm_outp_acquire_ior(outp, user, ior);
+ }
+
+ return -ENOSPC;
+}
+
int
-nvkm_outp_acquire(struct nvkm_outp *outp, u8 user)
+nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
{
struct nvkm_ior *ior = outp->ior;
enum nvkm_ior_proto proto;
@@ -137,32 +173,25 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user)
return nvkm_outp_acquire_ior(outp, user, ior);
}
- /* First preference is to reuse the OR that is currently armed
- * on HW, if any, in order to prevent unnecessary switching.
+ /* If we don't need HDA, first try to acquire an OR that doesn't
+ * support it to leave free the ones that do.
*/
- list_for_each_entry(ior, &outp->disp->ior, head) {
- if (!ior->identity && !ior->asy.outp && ior->arm.outp == outp)
- return nvkm_outp_acquire_ior(outp, user, ior);
- }
+ if (!hda) {
+ if (!nvkm_outp_acquire_hda(outp, type, user, false))
+ return 0;
- /* Failing that, a completely unused OR is the next best thing. */
- list_for_each_entry(ior, &outp->disp->ior, head) {
- if (!ior->identity &&
- !ior->asy.outp && ior->type == type && !ior->arm.outp &&
- (ior->func->route.set || ior->id == __ffs(outp->info.or)))
- return nvkm_outp_acquire_ior(outp, user, ior);
+ /* Use a HDA-supporting SOR anyway. */
+ return nvkm_outp_acquire_hda(outp, type, user, true);
}
- /* Last resort is to assign an OR that's already active on HW,
- * but will be released during the next modeset.
- */
- list_for_each_entry(ior, &outp->disp->ior, head) {
- if (!ior->identity && !ior->asy.outp && ior->type == type &&
- (ior->func->route.set || ior->id == __ffs(outp->info.or)))
- return nvkm_outp_acquire_ior(outp, user, ior);
- }
+ /* We want HDA, try to acquire an OR that supports it. */
+ if (!nvkm_outp_acquire_hda(outp, type, user, true))
+ return 0;
- return -ENOSPC;
+ /* There weren't any free ORs that support HDA, grab one that
+ * doesn't and at least allow display to work still.
+ */
+ return nvkm_outp_acquire_hda(outp, type, user, false);
}
void
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index 721b068b87ef..ee028d30cfe7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -32,7 +32,7 @@ int nvkm_outp_new(struct nvkm_disp *, int index, struct dcb_output *,
void nvkm_outp_del(struct nvkm_outp **);
void nvkm_outp_init(struct nvkm_outp *);
void nvkm_outp_fini(struct nvkm_outp *);
-int nvkm_outp_acquire(struct nvkm_outp *, u8 user);
+int nvkm_outp_acquire(struct nvkm_outp *, u8 user, bool hda);
void nvkm_outp_release(struct nvkm_outp *, u8 user);
void nvkm_outp_route(struct nvkm_disp *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
index a7672ef17d3b..fb5de44e4b8d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
@@ -99,7 +99,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
} *args = data;
int ret = -ENOSYS;
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
- ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER);
+ ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, args->v0.hda);
if (ret == 0) {
args->v0.or = outp->ior->id;
args->v0.link = outp->ior->asy.link;
@@ -119,7 +119,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
if (args->v0.data & 0xfff00000)
return -EINVAL;
- ret = nvkm_outp_acquire(outp, NVKM_OUTP_PRIV);
+ ret = nvkm_outp_acquire(outp, NVKM_OUTP_PRIV, false);
if (ret)
return ret;
ret = outp->ior->func->sense(outp->ior, args->v0.data);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
index cf2075db742a..4dd7f382968e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
@@ -89,7 +89,7 @@ gm200_sor_route_get(struct nvkm_outp *outp, int *link)
}
static const struct nvkm_ior_func
-gm200_sor = {
+gm200_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -119,8 +119,42 @@ gm200_sor = {
},
};
+static const struct nvkm_ior_func
+gm200_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gf119_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gk104_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+ },
+};
+
int
gm200_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda;
+
+ if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+ hda = nvkm_rd32(device, 0x101034);
+
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&gm200_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&gm200_sor, disp, SOR, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c
new file mode 100644
index 000000000000..c54f88317a07
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2020 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "ior.h"
+
+static const struct nvkm_ior_func
+gp100_sor_hda = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gf119_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gk104_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+ },
+ .hda = {
+ .hpd = gf119_hda_hpd,
+ .eld = gf119_hda_eld,
+ .device_entry = gf119_hda_device_entry,
+ },
+};
+
+static const struct nvkm_ior_func
+gp100_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gf119_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gk104_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+ },
+};
+
+int
+gp100_sor_new(struct nvkm_disp *disp, int id)
+{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda;
+
+ if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+ hda = nvkm_rd32(device, 0x10ebb0) >> 8;
+
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&gp100_sor_hda, disp, SOR, id);
+ return nvkm_ior_new_(&gp100_sor, disp, SOR, id);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
index d11a0dff10c6..4441187e8ec9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
@@ -78,7 +78,7 @@ gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
}
static const struct nvkm_ior_func
-gv100_sor = {
+gv100_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -107,9 +107,42 @@ gv100_sor = {
},
};
+static const struct nvkm_ior_func
+gv100_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gv100_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gv100_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+ },
+};
+
int
gv100_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda;
+
+ if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+ hda = nvkm_rd32(device, 0x118fb0) >> 8;
+
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&gv100_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&gv100_sor, disp, SOR, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
index fa6d74251237..59865a934c4b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
@@ -62,7 +62,7 @@ tu102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
}
static const struct nvkm_ior_func
-tu102_sor = {
+tu102_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -92,8 +92,38 @@ tu102_sor = {
},
};
+static const struct nvkm_ior_func
+tu102_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gv100_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gv100_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = tu102_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = tu102_sor_dp_vcpi,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+ },
+};
+
int
tu102_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda = nvkm_rd32(device, 0x08a15c);
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&tu102_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&tu102_sor, disp, SOR, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
index ec330d791d15..e56880f3e3bd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
@@ -352,7 +352,7 @@ gk20a_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
static const struct gf100_gr_fwif
gk20a_gr_fwif[] = {
- { -1, gk20a_gr_load, &gk20a_gr },
+ { 0, gk20a_gr_load, &gk20a_gr },
{}
};
diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig
index 72ae79c0c9b4..2658c521b702 100644
--- a/drivers/gpu/drm/omapdrm/dss/Kconfig
+++ b/drivers/gpu/drm/omapdrm/dss/Kconfig
@@ -71,7 +71,7 @@ config OMAP4_DSS_HDMI_CEC
depends on OMAP4_DSS_HDMI
select CEC_CORE
default y
- ---help---
+ help
When selected the HDMI transmitter will support the CEC feature.
config OMAP5_DSS_HDMI
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 0d0ab8e0ff3b..cc31d187042e 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -196,12 +196,12 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm,
&p->validated);
if (need_mmap_lock)
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
if (need_mmap_lock)
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 068c3e5da173..3c8f570a20ee 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -342,17 +342,17 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
}
if (args->flags & RADEON_GEM_USERPTR_VALIDATE) {
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
r = radeon_bo_reserve(bo, true);
if (r) {
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
goto release_object;
}
radeon_ttm_placement_from_domain(bo, RADEON_GEM_DOMAIN_GTT);
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
radeon_bo_unreserve(bo);
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
if (r)
goto release_object;
}
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 7ad3f06c127e..00ca35f07ba5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -148,7 +148,7 @@
#define SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE 3
#define SUN4I_HDMI_DDC_CLK_REG 0x528
-#define SUN4I_HDMI_DDC_CLK_M(m) (((m) & 0x7) << 3)
+#define SUN4I_HDMI_DDC_CLK_M(m) (((m) & 0xf) << 3)
#define SUN4I_HDMI_DDC_CLK_N(n) ((n) & 0x7)
#define SUN4I_HDMI_DDC_LINE_CTRL_REG 0x540
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
index 2ff780114106..12430b9d4e93 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
@@ -33,7 +33,7 @@ static unsigned long sun4i_ddc_calc_divider(unsigned long rate,
unsigned long best_rate = 0;
u8 best_m = 0, best_n = 0, _m, _n;
- for (_m = 0; _m < 8; _m++) {
+ for (_m = 0; _m < 16; _m++) {
for (_n = 0; _n < 8; _n++) {
unsigned long tmp_rate;
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 0ad30b112982..a43aa7275f12 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -58,7 +58,7 @@ static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
goto out_clear;
/*
- * If possible, avoid waiting for GPU with mmap_sem
+ * If possible, avoid waiting for GPU with mmap_lock
* held. We only do this if the fault allows retry and this
* is the first attempt.
*/
@@ -68,7 +68,7 @@ static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
goto out_unlock;
ttm_bo_get(bo);
- up_read(&vmf->vma->vm_mm->mmap_sem);
+ mmap_read_unlock(vmf->vma->vm_mm);
(void) dma_fence_wait(bo->moving, true);
dma_resv_unlock(bo->base.resv);
ttm_bo_put(bo);
@@ -131,20 +131,20 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
{
/*
* Work around locking order reversal in fault / nopfn
- * between mmap_sem and bo_reserve: Perform a trylock operation
+ * between mmap_lock and bo_reserve: Perform a trylock operation
* for reserve, and if it fails, retry the fault after waiting
* for the buffer to become unreserved.
*/
if (unlikely(!dma_resv_trylock(bo->base.resv))) {
/*
* If the fault allows retry and this is the first
- * fault attempt, we try to release the mmap_sem
+ * fault attempt, we try to release the mmap_lock
* before waiting
*/
if (fault_flag_allow_retry_first(vmf->flags)) {
if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
ttm_bo_get(bo);
- up_read(&vmf->vma->vm_mm->mmap_sem);
+ mmap_read_unlock(vmf->vma->vm_mm);
if (!dma_resv_lock_interruptible(bo->base.resv,
NULL))
dma_resv_unlock(bo->base.resv);
diff --git a/drivers/greybus/Kconfig b/drivers/greybus/Kconfig
index aeea082f1418..78ba3c3083d5 100644
--- a/drivers/greybus/Kconfig
+++ b/drivers/greybus/Kconfig
@@ -2,7 +2,7 @@
menuconfig GREYBUS
tristate "Greybus support"
depends on SYSFS
- ---help---
+ help
This option enables the Greybus driver core. Greybus is a
hardware protocol that was designed to provide Unipro with a
sane application layer. It was originally designed for the
@@ -20,7 +20,7 @@ if GREYBUS
config GREYBUS_ES2
tristate "Greybus ES3 USB host controller"
depends on USB
- ---help---
+ help
Select this option if you have a Toshiba ES3 USB device that
acts as a Greybus "host controller". This device is a bridge
from a USB device to a Unipro network.
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 443c5cbbde04..45e87dc59d4e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -9,7 +9,7 @@ config HID
tristate "HID bus support"
depends on INPUT
default y
- ---help---
+ help
A human interface device (HID) is a type of computer device that
interacts directly with and takes input from humans. The term "HID"
most commonly used to refer to the USB-HID specification, but other
@@ -31,7 +31,7 @@ config HID_BATTERY_STRENGTH
depends on HID
select POWER_SUPPLY
default n
- ---help---
+ help
This option adds support of reporting battery strength (for HID devices
that support this feature) through power_supply class so that userspace
tools, such as upower, can display it.
@@ -39,7 +39,7 @@ config HID_BATTERY_STRENGTH
config HIDRAW
bool "/dev/hidraw raw HID device support"
depends on HID
- ---help---
+ help
Say Y here if you want to support HID devices (from the USB
specification standpoint) that aren't strictly user interface
devices, like monitor controls and Uninterruptible Power Supplies.
@@ -59,7 +59,7 @@ config UHID
tristate "User-space I/O driver support for HID subsystem"
depends on HID
default n
- ---help---
+ help
Say Y here if you want to provide HID I/O Drivers from user-space.
This allows to write I/O drivers in user-space and feed the data from
the device into the kernel. The kernel parses the HID reports, loads the
@@ -80,7 +80,7 @@ config HID_GENERIC
tristate "Generic HID driver"
depends on HID
default HID
- ---help---
+ help
Support for generic devices on the HID bus. This includes most
keyboards and mice, joysticks, tablets and digitizers.
@@ -96,13 +96,13 @@ config HID_A4TECH
tristate "A4 tech mice"
depends on HID
default !EXPERT
- ---help---
+ help
Support for A4 tech X5 and WOP-35 / Trust 450L mice.
config HID_ACCUTOUCH
tristate "Accutouch touch device"
depends on USB_HID
- ---help---
+ help
This selects a driver for the Accutouch 2216 touch controller.
The driver works around a problem in the reported device capabilities
@@ -114,14 +114,14 @@ config HID_ACCUTOUCH
config HID_ACRUX
tristate "ACRUX game controller support"
depends on HID
- ---help---
+ help
Say Y here if you want to enable support for ACRUX game controllers.
config HID_ACRUX_FF
bool "ACRUX force feedback support"
depends on HID_ACRUX
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you want to enable force feedback support for ACRUX
game controllers.
@@ -129,7 +129,7 @@ config HID_APPLE
tristate "Apple {i,Power,Mac}Books"
depends on HID
default !EXPERT
- ---help---
+ help
Support for some Apple devices which less or more break
HID specification.
@@ -139,7 +139,7 @@ config HID_APPLE
config HID_APPLEIR
tristate "Apple infrared receiver"
depends on (USB_HID)
- ---help---
+ help
Support for Apple infrared remote control. All the Apple computers from
2005 onwards include such a port, except the unibody Macbook (2009),
and Mac Pros. This receiver is also used in the Apple TV set-top box
@@ -153,7 +153,7 @@ config HID_ASUS
depends on LEDS_CLASS
depends on ASUS_WMI || ASUS_WMI=n
select POWER_SUPPLY
- ---help---
+ help
Support for Asus notebook built-in keyboard and touchpad via i2c, and
the Asus Republic of Gamers laptop keyboard special keys.
@@ -166,21 +166,21 @@ config HID_ASUS
config HID_AUREAL
tristate "Aureal"
depends on HID
- ---help---
+ help
Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes.
config HID_BELKIN
tristate "Belkin Flip KVM and Wireless keyboard"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Belkin Flip KVM and Wireless keyboard.
config HID_BETOP_FF
tristate "Betop Production Inc. force feedback support"
depends on USB_HID
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you want to enable force feedback support for devices by
BETOP Production Ltd.
Currently the following devices are known to be supported:
@@ -202,20 +202,20 @@ config HID_CHERRY
tristate "Cherry Cymotion keyboard"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Cherry Cymotion keyboard.
config HID_CHICONY
tristate "Chicony devices"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Chicony Tactical pad and special keys on Chicony keyboards.
config HID_CORSAIR
tristate "Corsair devices"
depends on HID && USB && LEDS_CLASS
- ---help---
+ help
Support for Corsair devices that are not fully compliant with the
HID standard.
@@ -247,7 +247,7 @@ config HID_PRODIKEYS
tristate "Prodikeys PC-MIDI Keyboard support"
depends on HID && SND
select SND_RAWMIDI
- ---help---
+ help
Support for Prodikeys PC-MIDI Keyboard device support.
Say Y here to enable support for this device.
- Prodikeys PC-MIDI keyboard.
@@ -261,14 +261,14 @@ config HID_PRODIKEYS
config HID_CMEDIA
tristate "CMedia CM6533 HID audio jack controls"
depends on HID
- ---help---
+ help
Support for CMedia CM6533 HID audio jack controls.
config HID_CP2112
tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support"
depends on USB_HID && HIDRAW && I2C && GPIOLIB
select GPIOLIB_IRQCHIP
- ---help---
+ help
Support for Silicon Labs CP2112 HID USB to SMBus Master Bridge.
This is a HID device driver which registers as an i2c adapter
and gpiochip to expose these functions of the CP2112. The
@@ -287,13 +287,13 @@ config HID_CYPRESS
tristate "Cypress mouse and barcode readers"
depends on HID
default !EXPERT
- ---help---
+ help
Support for cypress mouse and barcode readers.
config HID_DRAGONRISE
tristate "DragonRise Inc. game controller"
depends on HID
- ---help---
+ help
Say Y here if you have DragonRise Inc. game controllers.
These might be branded as:
- Tesun USB-703
@@ -305,7 +305,7 @@ config DRAGONRISE_FF
bool "DragonRise Inc. force feedback"
depends on HID_DRAGONRISE
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you want to enable force feedback support for DragonRise Inc.
game controllers.
@@ -313,7 +313,7 @@ config HID_EMS_FF
tristate "EMS Production Inc. force feedback support"
depends on HID
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you want to enable force feedback support for devices by
EMS Production Ltd.
Currently the following devices are known to be supported:
@@ -322,7 +322,7 @@ config HID_EMS_FF
config HID_ELAN
tristate "ELAN USB Touchpad Support"
depends on LEDS_CLASS && USB_HID
- ---help---
+ help
Say Y to enable support for the USB ELAN touchpad
Currently the following devices are known to be supported:
- HP Pavilion X2 10-p0XX.
@@ -330,7 +330,7 @@ config HID_ELAN
config HID_ELECOM
tristate "ELECOM HID devices"
depends on HID
- ---help---
+ help
Support for ELECOM devices:
- BM084 Bluetooth Mouse
- EX-G Trackballs (M-XT3DRBK, M-XT3URBK)
@@ -340,7 +340,7 @@ config HID_ELECOM
config HID_ELO
tristate "ELO USB 4000/4500 touchscreen"
depends on USB_HID
- ---help---
+ help
Support for the ELO USB 4000/4500 touchscreens. Note that this is for
different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO.
@@ -348,19 +348,19 @@ config HID_EZKEY
tristate "Ezkey BTC 8193 keyboard"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Ezkey BTC 8193 keyboard.
config HID_GEMBIRD
tristate "Gembird Joypad"
depends on HID
- ---help---
+ help
Support for Gembird JPD-DualForce 2.
config HID_GFRM
tristate "Google Fiber TV Box remote control support"
depends on HID
- ---help---
+ help
Support for Google Fiber TV Box remote controls
config HID_GLORIOUS
@@ -373,7 +373,7 @@ config HID_GLORIOUS
config HID_HOLTEK
tristate "Holtek HID devices"
depends on USB_HID
- ---help---
+ help
Support for Holtek based devices:
- Holtek On Line Grip based game controller
- Trust GXT 18 Gaming Keyboard
@@ -387,20 +387,20 @@ config HOLTEK_FF
bool "Holtek On Line Grip force feedback support"
depends on HID_HOLTEK
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a Holtek On Line Grip based game controller
and want to have force feedback support for it.
config HID_GOOGLE_HAMMER
tristate "Google Hammer Keyboard"
depends on USB_HID && LEDS_CLASS && CROS_EC
- ---help---
+ help
Say Y here if you have a Google Hammer device.
config HID_GT683R
tristate "MSI GT68xR LED support"
depends on LEDS_CLASS && USB_HID
- ---help---
+ help
Say Y here if you want to enable support for the three MSI GT68xR LEDs
This driver support following modes:
@@ -414,7 +414,7 @@ config HID_GT683R
config HID_KEYTOUCH
tristate "Keytouch HID devices"
depends on HID
- ---help---
+ help
Support for Keytouch HID devices not fully compliant with
the specification. Currently supported:
- Keytouch IEC 60945
@@ -422,7 +422,7 @@ config HID_KEYTOUCH
config HID_KYE
tristate "KYE/Genius devices"
depends on HID
- ---help---
+ help
Support for KYE/Genius devices not fully compliant with HID standard:
- Ergo Mouse
- EasyPen i405X tablet
@@ -432,13 +432,13 @@ config HID_KYE
config HID_UCLOGIC
tristate "UC-Logic"
depends on USB_HID
- ---help---
+ help
Support for UC-Logic and Huion tablets.
config HID_WALTOP
tristate "Waltop"
depends on HID
- ---help---
+ help
Support for Waltop tablets.
config HID_VIEWSONIC
@@ -450,13 +450,13 @@ config HID_VIEWSONIC
config HID_GYRATION
tristate "Gyration remote control"
depends on HID
- ---help---
+ help
Support for Gyration remote control.
config HID_ICADE
tristate "ION iCade arcade controller"
depends on HID
- ---help---
+ help
Support for the ION iCade arcade controller to work as a joystick.
To compile this driver as a module, choose M here: the
@@ -466,13 +466,13 @@ config HID_ITE
tristate "ITE devices"
depends on HID
default !EXPERT
- ---help---
+ help
Support for ITE devices not fully compliant with HID standard.
config HID_JABRA
tristate "Jabra USB HID Driver"
depends on HID
- ---help---
+ help
Support for Jabra USB HID devices.
Prevents mapping of vendor defined HID usages to input events. Without
@@ -483,27 +483,27 @@ config HID_JABRA
config HID_TWINHAN
tristate "Twinhan IR remote control"
depends on HID
- ---help---
+ help
Support for Twinhan IR remote control.
config HID_KENSINGTON
tristate "Kensington Slimblade Trackball"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Kensington Slimblade Trackball.
config HID_LCPOWER
tristate "LC-Power"
depends on HID
- ---help---
+ help
Support for LC-Power RC1000MCE RF remote control.
config HID_LED
tristate "Simple RGB LED support"
depends on HID
depends on LEDS_CLASS
- ---help---
+ help
Support for simple RGB LED devices. Currently supported are:
- Riso Kagaku Webmail Notifier
- Dream Cheeky Webmail Notifier and Friends Alert
@@ -519,7 +519,7 @@ config HID_LENOVO
depends on HID
select NEW_LEDS
select LEDS_CLASS
- ---help---
+ help
Support for IBM/Lenovo devices that are not fully compliant with HID standard.
Say Y if you want support for horizontal scrolling of the IBM/Lenovo
@@ -535,7 +535,7 @@ config HID_LOGITECH
depends on HID
depends on LEDS_CLASS
default !EXPERT
- ---help---
+ help
Support for Logitech devices that are not fully compliant with HID standard.
config HID_LOGITECH_DJ
@@ -544,7 +544,7 @@ config HID_LOGITECH_DJ
depends on HIDRAW
depends on HID_LOGITECH
select HID_LOGITECH_HIDPP
- ---help---
+ help
Say Y if you want support for Logitech receivers and devices.
Logitech receivers are capable of pairing multiple Logitech compliant
devices to the same receiver. Without this driver it will be handled by
@@ -555,7 +555,7 @@ config HID_LOGITECH_HIDPP
tristate "Logitech HID++ devices support"
depends on HID_LOGITECH
select POWER_SUPPLY
- ---help---
+ help
Support for Logitech devices relyingon the HID++ Logitech specification
Say Y if you want support for Logitech devices relying on the HID++
@@ -621,7 +621,7 @@ config LOGIWHEELS_FF
config HID_MAGICMOUSE
tristate "Apple Magic Mouse/Trackpad multi-touch support"
depends on HID
- ---help---
+ help
Support for the Apple Magic Mouse/Trackpad multi-touch.
Say Y here if you want support for the multi-touch features of the
@@ -630,7 +630,7 @@ config HID_MAGICMOUSE
config HID_MALTRON
tristate "Maltron L90 keyboard"
depends on HID
- ---help---
+ help
Adds support for the volume up, volume down, mute, and play/pause buttons
of the Maltron L90 keyboard.
@@ -638,7 +638,7 @@ config HID_MAYFLASH
tristate "Mayflash game controller adapter force feedback"
depends on HID
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have HJZ Mayflash PS3 game controller adapters
and want to enable force feedback support.
@@ -646,7 +646,7 @@ config HID_REDRAGON
tristate "Redragon keyboards"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Redragon keyboards that need fix-ups to work properly.
config HID_MICROSOFT
@@ -654,20 +654,20 @@ config HID_MICROSOFT
depends on HID
default !EXPERT
select INPUT_FF_MEMLESS
- ---help---
+ help
Support for Microsoft devices that are not fully compliant with HID standard.
config HID_MONTEREY
tristate "Monterey Genius KB29E keyboard"
depends on HID
default !EXPERT
- ---help---
+ help
Support for Monterey Genius KB29E.
config HID_MULTITOUCH
tristate "HID Multitouch panels"
depends on HID
- ---help---
+ help
Generic support for HID multitouch panels.
Say Y here if you have one of the following devices:
@@ -712,20 +712,20 @@ config HID_MULTITOUCH
config HID_NTI
tristate "NTI keyboard adapters"
- ---help---
+ help
Support for the "extra" Sun keyboard keys on keyboards attached
through Network Technologies USB-SUN keyboard adapters.
config HID_NTRIG
tristate "N-Trig touch screen"
depends on USB_HID
- ---help---
+ help
Support for N-Trig touch screen.
config HID_ORTEK
tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad"
depends on HID
- ---help---
+ help
There are certain devices which have LogicalMaximum wrong in the keyboard
usage page of their report descriptor. The most prevailing ones so far
are manufactured by Ortek, thus the name of the driver. Currently
@@ -738,7 +738,7 @@ config HID_ORTEK
config HID_PANTHERLORD
tristate "Pantherlord/GreenAsia game controller"
depends on HID
- ---help---
+ help
Say Y here if you have a PantherLord/GreenAsia based game controller
or adapter.
@@ -746,14 +746,14 @@ config PANTHERLORD_FF
bool "Pantherlord force feedback support"
depends on HID_PANTHERLORD
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a PantherLord/GreenAsia based game controller
or adapter and want to enable force feedback support for it.
config HID_PENMOUNT
tristate "Penmount touch device"
depends on USB_HID
- ---help---
+ help
This selects a driver for the PenMount 6000 touch controller.
The driver works around a problem in the report descript allowing
@@ -764,13 +764,13 @@ config HID_PENMOUNT
config HID_PETALYNX
tristate "Petalynx Maxter remote control"
depends on HID
- ---help---
+ help
Support for Petalynx Maxter remote control.
config HID_PICOLCD
tristate "PicoLCD (graphic version)"
depends on HID
- ---help---
+ help
This provides support for Minibox PicoLCD devices, currently
only the graphical ones are supported.
@@ -796,7 +796,7 @@ config HID_PICOLCD_FB
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
- ---help---
+ help
Provide access to PicoLCD's 256x64 monochrome display via a
framebuffer device.
@@ -805,7 +805,7 @@ config HID_PICOLCD_BACKLIGHT
default !EXPERT
depends on HID_PICOLCD
depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y
- ---help---
+ help
Provide access to PicoLCD's backlight control via backlight
class.
@@ -814,7 +814,7 @@ config HID_PICOLCD_LCD
default !EXPERT
depends on HID_PICOLCD
depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y
- ---help---
+ help
Provide access to PicoLCD's LCD contrast via lcd class.
config HID_PICOLCD_LEDS
@@ -822,7 +822,7 @@ config HID_PICOLCD_LEDS
default !EXPERT
depends on HID_PICOLCD
depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y
- ---help---
+ help
Provide access to PicoLCD's GPO pins via leds class.
config HID_PICOLCD_CIR
@@ -830,13 +830,13 @@ config HID_PICOLCD_CIR
default !EXPERT
depends on HID_PICOLCD
depends on HID_PICOLCD=RC_CORE || RC_CORE=y
- ---help---
+ help
Provide access to PicoLCD's CIR interface via remote control (LIRC).
config HID_PLANTRONICS
tristate "Plantronics USB HID Driver"
depends on HID
- ---help---
+ help
Provides HID support for Plantronics USB audio devices.
Correctly maps vendor unique volume up/down HID usages to
KEY_VOLUMEUP and KEY_VOLUMEDOWN events and prevents core mapping
@@ -847,21 +847,21 @@ config HID_PLANTRONICS
config HID_PRIMAX
tristate "Primax non-fully HID-compliant devices"
depends on HID
- ---help---
+ help
Support for Primax devices that are not fully compliant with the
HID standard.
config HID_RETRODE
tristate "Retrode 2 USB adapter for vintage video games"
depends on USB_HID
- ---help---
+ help
Support for
* Retrode 2 cartridge and controller adapter
config HID_ROCCAT
tristate "Roccat device support"
depends on USB_HID
- ---help---
+ help
Support for Roccat devices.
Say Y here if you have a Roccat mouse or keyboard and want
support for its special functionalities.
@@ -869,7 +869,7 @@ config HID_ROCCAT
config HID_SAITEK
tristate "Saitek (Mad Catz) non-fully HID-compliant devices"
depends on HID
- ---help---
+ help
Support for Saitek devices that are not fully compliant with the
HID standard.
@@ -881,7 +881,7 @@ config HID_SAITEK
config HID_SAMSUNG
tristate "Samsung InfraRed remote control or keyboards"
depends on HID
- ---help---
+ help
Support for Samsung InfraRed remote control or keyboards.
config HID_SONY
@@ -890,7 +890,7 @@ config HID_SONY
depends on NEW_LEDS
depends on LEDS_CLASS
select POWER_SUPPLY
- ---help---
+ help
Support for
* Sony PS3 6-axis controllers
@@ -903,21 +903,21 @@ config SONY_FF
bool "Sony PS2/3/4 accessories force feedback support"
depends on HID_SONY
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a Sony PS2/3/4 accessory and want to enable
force feedback support for it.
config HID_SPEEDLINK
tristate "Speedlink VAD Cezanne mouse support"
depends on HID
- ---help---
+ help
Support for Speedlink Vicious and Divine Cezanne mouse.
config HID_STEAM
tristate "Steam Controller support"
depends on HID
select POWER_SUPPLY
- ---help---
+ help
Say Y here if you have a Steam Controller if you want to use it
without running the Steam Client. It supports both the wired and
the wireless adaptor.
@@ -925,13 +925,13 @@ config HID_STEAM
config HID_STEELSERIES
tristate "Steelseries SRW-S1 steering wheel support"
depends on HID
- ---help---
+ help
Support for Steelseries SRW-S1 steering wheel
config HID_SUNPLUS
tristate "Sunplus wireless desktop"
depends on HID
- ---help---
+ help
Support for Sunplus wireless desktop.
config HID_RMI
@@ -942,7 +942,7 @@ config HID_RMI
select RMI4_F11
select RMI4_F12
select RMI4_F30
- ---help---
+ help
Support for Synaptics RMI4 touchpads.
Say Y here if you have a Synaptics RMI4 touchpads over i2c-hid or usbhid
and want support for its special functionalities.
@@ -950,7 +950,7 @@ config HID_RMI
config HID_GREENASIA
tristate "GreenAsia (Product ID 0x12) game controller support"
depends on HID
- ---help---
+ help
Say Y here if you have a GreenAsia (Product ID 0x12) based game
controller or adapter.
@@ -958,7 +958,7 @@ config GREENASIA_FF
bool "GreenAsia (Product ID 0x12) force feedback support"
depends on HID_GREENASIA
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
(like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
and want to enable force feedback support for it.
@@ -966,13 +966,13 @@ config GREENASIA_FF
config HID_HYPERV_MOUSE
tristate "Microsoft Hyper-V mouse driver"
depends on HYPERV
- ---help---
+ help
Select this option to enable the Hyper-V mouse driver.
config HID_SMARTJOYPLUS
tristate "SmartJoy PLUS PS2/USB adapter support"
depends on HID
- ---help---
+ help
Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box,
Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro.
@@ -983,20 +983,20 @@ config SMARTJOYPLUS_FF
bool "SmartJoy PLUS PS2/USB adapter force feedback support"
depends on HID_SMARTJOYPLUS
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to
enable force feedback support for it.
config HID_TIVO
tristate "TiVo Slide Bluetooth remote control support"
depends on HID
- ---help---
+ help
Say Y if you have a TiVo Slide Bluetooth remote control.
config HID_TOPSEED
tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
depends on HID
- ---help---
+ help
Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
CLLRCMCE remote control.
@@ -1005,7 +1005,7 @@ config HID_THINGM
depends on HID
depends on LEDS_CLASS
select HID_LED
- ---help---
+ help
Support for the ThingM blink(1) USB RGB LED. This driver has been
merged into the generic hid led driver. Config symbol HID_THINGM
just selects HID_LED and will be removed soon.
@@ -1013,7 +1013,7 @@ config HID_THINGM
config HID_THRUSTMASTER
tristate "ThrustMaster devices support"
depends on HID
- ---help---
+ help
Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
a THRUSTMASTER Ferrari GT Rumble Wheel.
@@ -1021,7 +1021,7 @@ config THRUSTMASTER_FF
bool "ThrustMaster devices force feedback support"
depends on HID_THRUSTMASTER
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3,
a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT
Rumble Force or Force Feedback Wheel.
@@ -1029,7 +1029,7 @@ config THRUSTMASTER_FF
config HID_UDRAW_PS3
tristate "THQ PS3 uDraw tablet"
depends on HID
- ---help---
+ help
Say Y here if you want to use the THQ uDraw gaming tablet for
the PS3.
@@ -1069,7 +1069,7 @@ config HID_WIIMOTE
depends on LEDS_CLASS
select POWER_SUPPLY
select INPUT_FF_MEMLESS
- ---help---
+ help
Support for Nintendo Wii and Wii U Bluetooth peripherals. Supported
devices are the Wii Remote and its extension devices, but also devices
based on the Wii Remote like the Wii U Pro Controller or the
@@ -1091,7 +1091,7 @@ config HID_WIIMOTE
config HID_XINMO
tristate "Xin-Mo non-fully compliant devices"
depends on HID
- ---help---
+ help
Support for Xin-Mo devices that are not fully compliant with the HID
standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
if you have a Xin-Mo Dual Arcade controller.
@@ -1099,21 +1099,21 @@ config HID_XINMO
config HID_ZEROPLUS
tristate "Zeroplus based game controller support"
depends on HID
- ---help---
+ help
Say Y here if you have a Zeroplus based game controller.
config ZEROPLUS_FF
bool "Zeroplus based game controller force feedback support"
depends on HID_ZEROPLUS
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a Zeroplus based game controller and want
to have force feedback support for it.
config HID_ZYDACRON
tristate "Zydacron remote control support"
depends on HID
- ---help---
+ help
Support for Zydacron remote control.
config HID_SENSOR_HUB
@@ -1121,7 +1121,7 @@ config HID_SENSOR_HUB
depends on HID && HAS_IOMEM
select MFD_CORE
default n
- ---help---
+ help
Support for HID Sensor framework. This creates a MFD instance
for a sensor hub and identifies all the sensors connected to it.
Each sensor is registered as a MFD cell, so that sensor specific
@@ -1134,7 +1134,7 @@ config HID_SENSOR_CUSTOM_SENSOR
tristate "HID Sensors hub custom sensor support"
depends on HID_SENSOR_HUB
default n
- ---help---
+ help
HID Sensor hub specification allows definition of some custom and
generic sensors. Unlike other HID sensors, they can't be exported
via Linux IIO because of custom fields. This is up to the manufacturer
@@ -1148,7 +1148,7 @@ config HID_SENSOR_CUSTOM_SENSOR
config HID_ALPS
tristate "Alps HID device support"
depends on HID
- ---help---
+ help
Support for Alps I2C HID touchpads and StickPointer.
Say Y here if you have a Alps touchpads over i2c-hid or usbhid
and want support for its special functionalities.
@@ -1157,7 +1157,7 @@ config HID_MCP2221
tristate "Microchip MCP2221 HID USB-to-I2C/SMbus host support"
depends on USB_HID && I2C
depends on GPIOLIB
- ---help---
+ help
Provides I2C and SMBUS host adapter functionality over USB-HID
through MCP2221 device.
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index b2ad319a74b9..6f1fe7248d81 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -387,8 +387,7 @@ static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size)
input_report_abs(hdata->input,
ABS_MT_PRESSURE, z);
} else {
- input_mt_report_slot_state(hdata->input,
- MT_TOOL_FINGER, 0);
+ input_mt_report_slot_inactive(hdata->input);
}
}
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 35c8c174a0ce..3f94b4954225 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -899,7 +899,7 @@ static void mt_release_pending_palms(struct mt_device *td,
clear_bit(slotnum, app->pending_palm_slots);
input_mt_slot(input, slotnum);
- input_mt_report_slot_state(input, MT_TOOL_PALM, false);
+ input_mt_report_slot_inactive(input);
need_sync = true;
}
@@ -1643,9 +1643,7 @@ static void mt_release_contacts(struct hid_device *hid)
if (mt) {
for (i = 0; i < mt->num_slots; i++) {
input_mt_slot(input_dev, i);
- input_mt_report_slot_state(input_dev,
- MT_TOOL_FINGER,
- false);
+ input_mt_report_slot_inactive(input_dev);
}
input_mt_sync_frame(input_dev);
input_sync(input_dev);
diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
index 0e2ae47f38a7..c4e5dfeab2bd 100644
--- a/drivers/hid/i2c-hid/Kconfig
+++ b/drivers/hid/i2c-hid/Kconfig
@@ -7,7 +7,7 @@ config I2C_HID
default n
depends on I2C && INPUT
select HID
- ---help---
+ help
Say Y here if you use a keyboard, a touchpad, a touchscreen, or any
other HID based devices which is connected to your computer via I2C.
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index b5f3a3c4149e..dcf3a235870f 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -7,7 +7,7 @@ config USB_HID
default y
depends on USB && INPUT
select HID
- ---help---
+ help
Say Y here if you want to connect USB keyboards,
mice, joysticks, graphic tablets, or any other HID based devices
to your computer via USB, as well as Uninterruptible Power Supply
@@ -51,7 +51,7 @@ menu "USB HID Boot Protocol drivers"
config USB_KBD
tristate "USB HIDBP Keyboard (simple Boot) support"
depends on USB && INPUT
- ---help---
+ help
Say Y here only if you are absolutely sure that you don't want
to use the generic HID driver for your USB keyboard and prefer
to use the keyboard in its limited Boot Protocol mode instead.
@@ -67,7 +67,7 @@ config USB_KBD
config USB_MOUSE
tristate "USB HIDBP Mouse (simple Boot) support"
depends on USB && INPUT
- ---help---
+ help
Say Y here only if you are absolutely sure that you don't want
to use the generic HID driver for your USB mouse and prefer
to use the mouse in its limited Boot Protocol mode instead.
diff --git a/drivers/hsi/Kconfig b/drivers/hsi/Kconfig
index bcddb06ef038..42da4c235508 100644
--- a/drivers/hsi/Kconfig
+++ b/drivers/hsi/Kconfig
@@ -4,7 +4,7 @@
#
menuconfig HSI
tristate "HSI support"
- ---help---
+ help
The "High speed synchronous Serial Interface" is
synchronous serial interface used mainly to connect
application engines and cellular modems.
diff --git a/drivers/hsi/clients/Kconfig b/drivers/hsi/clients/Kconfig
index 3c423a27f0ae..80f60cb28c98 100644
--- a/drivers/hsi/clients/Kconfig
+++ b/drivers/hsi/clients/Kconfig
@@ -35,7 +35,7 @@ config SSI_PROTOCOL
config HSI_CHAR
tristate "HSI/SSI character driver"
depends on HSI
- ---help---
+ help
If you say Y here, you will enable the HSI/SSI character driver.
This driver provides a simple character device interface for
serial communication with the cellular modem over HSI/SSI bus.
diff --git a/drivers/hsi/controllers/Kconfig b/drivers/hsi/controllers/Kconfig
index 3ad4a5a9ab05..03ca5b558824 100644
--- a/drivers/hsi/controllers/Kconfig
+++ b/drivers/hsi/controllers/Kconfig
@@ -8,7 +8,7 @@ config OMAP_SSI
tristate "OMAP SSI hardware driver"
depends on HSI && OF && ARM && COMMON_CLK
depends on ARCH_OMAP3 || COMPILE_TEST
- ---help---
+ help
SSI is a legacy version of HSI. It is usually used to connect
an application engine with a cellular modem.
If you say Y here, you will enable the OMAP SSI hardware driver.
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
index 9915578533bb..8f12995ec133 100644
--- a/drivers/hwmon/k10temp.c
+++ b/drivers/hwmon/k10temp.c
@@ -632,6 +632,7 @@ static const struct pci_device_id k10temp_id_table[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
{ PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
{}
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 1474e57ecafc..ef39c83aaf33 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -9,7 +9,7 @@ config I2C
tristate "I2C support"
select RT_MUTEXES
select IRQ_DOMAIN
- ---help---
+ help
I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
many micro controller applications and developed by Philips. SMBus,
or System Management Bus is a subset of the I2C protocol. More
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2ddca08f8a76..735bf31a3fdf 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -475,8 +475,8 @@ config I2C_BCM_KONA
config I2C_BRCMSTB
tristate "BRCM Settop/DSL I2C controller"
- depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_63XX || \
- COMPILE_TEST
+ depends on ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC || \
+ ARCH_BCM_63XX || COMPILE_TEST
default y
help
If you say yes to this option, support will be included for the
@@ -526,22 +526,12 @@ config I2C_DAVINCI
config I2C_DESIGNWARE_CORE
tristate
-
-config I2C_DESIGNWARE_PLATFORM
- tristate "Synopsys DesignWare Platform"
- select I2C_DESIGNWARE_CORE
- depends on (ACPI && COMMON_CLK) || !ACPI
- help
- If you say yes to this option, support will be included for the
- Synopsys DesignWare I2C adapter.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-designware-platform.
+ select REGMAP
config I2C_DESIGNWARE_SLAVE
bool "Synopsys DesignWare Slave"
+ depends on I2C_DESIGNWARE_CORE
select I2C_SLAVE
- depends on I2C_DESIGNWARE_PLATFORM
help
If you say yes to this option, support will be included for the
Synopsys DesignWare I2C slave adapter.
@@ -549,20 +539,22 @@ config I2C_DESIGNWARE_SLAVE
This is not a standalone module, this module compiles together with
i2c-designware-core.
-config I2C_DESIGNWARE_PCI
- tristate "Synopsys DesignWare PCI"
- depends on PCI
+config I2C_DESIGNWARE_PLATFORM
+ tristate "Synopsys DesignWare Platform"
+ depends on (ACPI && COMMON_CLK) || !ACPI
select I2C_DESIGNWARE_CORE
+ select MFD_SYSCON if MIPS_BAIKAL_T1
help
If you say yes to this option, support will be included for the
- Synopsys DesignWare I2C adapter. Only master mode is supported.
+ Synopsys DesignWare I2C adapter.
This driver can also be built as a module. If so, the module
- will be called i2c-designware-pci.
+ will be called i2c-designware-platform.
config I2C_DESIGNWARE_BAYTRAIL
bool "Intel Baytrail I2C semaphore support"
depends on ACPI
+ depends on I2C_DESIGNWARE_PLATFORM
depends on (I2C_DESIGNWARE_PLATFORM=m && IOSF_MBI) || \
(I2C_DESIGNWARE_PLATFORM=y && IOSF_MBI=y)
help
@@ -572,6 +564,17 @@ config I2C_DESIGNWARE_BAYTRAIL
the platform firmware controlling it. You should say Y if running on
a BayTrail system using the AXP288.
+config I2C_DESIGNWARE_PCI
+ tristate "Synopsys DesignWare PCI"
+ depends on PCI
+ select I2C_DESIGNWARE_CORE
+ help
+ If you say yes to this option, support will be included for the
+ Synopsys DesignWare I2C adapter. Only master mode is supported.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-designware-pci.
+
config I2C_DIGICOLOR
tristate "Conexant Digicolor I2C driver"
depends on ARCH_DIGICOLOR || COMPILE_TEST
@@ -791,6 +794,15 @@ config I2C_NOMADIK
I2C interface from ST-Ericsson's Nomadik and Ux500 architectures,
as well as the STA2X11 PCIe I/O HUB.
+config I2C_NPCM7XX
+ tristate "Nuvoton I2C Controller"
+ depends on ARCH_NPCM7XX || COMPILE_TEST
+ help
+ If you say yes to this option, support will be included for the
+ Nuvoton I2C controller, which is available on the NPCM7xx BMC
+ controller.
+ Driver can also support slave mode (select I2C_SLAVE).
+
config I2C_OCORES
tristate "OpenCores I2C Controller"
help
@@ -885,6 +897,16 @@ config I2C_PXA_SLAVE
is necessary for systems where the PXA may be a target on the
I2C bus.
+config I2C_QCOM_CCI
+ tristate "Qualcomm Camera Control Interface"
+ depends on ARCH_QCOM || COMPILE_TEST
+ help
+ If you say yes to this option, support will be included for the
+ built-in camera control interface on the Qualcomm SoCs.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-qcom-cci.
+
config I2C_QCOM_GENI
tristate "Qualcomm Technologies Inc.'s GENI based I2C controller"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 25d60889713c..306d5dc3f417 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -48,16 +48,15 @@ obj-$(CONFIG_I2C_CADENCE) += i2c-cadence.o
obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus-gpio.o
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
-obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o
-i2c-designware-core-objs := i2c-designware-common.o i2c-designware-master.o
-ifeq ($(CONFIG_I2C_DESIGNWARE_SLAVE),y)
-i2c-designware-core-objs += i2c-designware-slave.o
-endif
-obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
-i2c-designware-platform-objs := i2c-designware-platdrv.o
+obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o
+i2c-designware-core-y := i2c-designware-common.o
+i2c-designware-core-y += i2c-designware-master.o
+i2c-designware-core-$(CONFIG_I2C_DESIGNWARE_SLAVE) += i2c-designware-slave.o
+obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
+i2c-designware-platform-y := i2c-designware-platdrv.o
i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o
-obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
-i2c-designware-pci-objs := i2c-designware-pcidrv.o
+obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o
+i2c-designware-pci-y := i2c-designware-pcidrv.o
obj-$(CONFIG_I2C_DIGICOLOR) += i2c-digicolor.o
obj-$(CONFIG_I2C_EFM32) += i2c-efm32.o
obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
@@ -81,6 +80,7 @@ obj-$(CONFIG_I2C_MT7621) += i2c-mt7621.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_MXS) += i2c-mxs.o
obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
+obj-$(CONFIG_I2C_NPCM7XX) += i2c-npcm7xx.o
obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
obj-$(CONFIG_I2C_OWL) += i2c-owl.o
@@ -91,6 +91,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
+obj-$(CONFIG_I2C_QCOM_CCI) += i2c-qcom-cci.o
obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c
index 16ddc26c00e6..7d62cbda6e06 100644
--- a/drivers/i2c/busses/i2c-altera.c
+++ b/drivers/i2c/busses/i2c-altera.c
@@ -69,7 +69,6 @@
* @fifo_size: size of the FIFO passed in.
* @isr_mask: cached copy of local ISR enables.
* @isr_status: cached copy of local ISR status.
- * @lock: spinlock for IRQ synchronization.
* @isr_mutex: mutex for IRQ thread.
*/
struct altr_i2c_dev {
@@ -86,18 +85,14 @@ struct altr_i2c_dev {
u32 fifo_size;
u32 isr_mask;
u32 isr_status;
- spinlock_t lock; /* IRQ synchronization */
struct mutex isr_mutex;
};
static void
altr_i2c_int_enable(struct altr_i2c_dev *idev, u32 mask, bool enable)
{
- unsigned long flags;
u32 int_en;
- spin_lock_irqsave(&idev->lock, flags);
-
int_en = readl(idev->base + ALTR_I2C_ISER);
if (enable)
idev->isr_mask = int_en | mask;
@@ -105,8 +100,6 @@ altr_i2c_int_enable(struct altr_i2c_dev *idev, u32 mask, bool enable)
idev->isr_mask = int_en & ~mask;
writel(idev->isr_mask, idev->base + ALTR_I2C_ISER);
-
- spin_unlock_irqrestore(&idev->lock, flags);
}
static void altr_i2c_int_clear(struct altr_i2c_dev *idev, u32 mask)
@@ -346,6 +339,7 @@ static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg)
time_left = wait_for_completion_timeout(&idev->msg_complete,
ALTR_I2C_XFER_TIMEOUT);
+ mutex_lock(&idev->isr_mutex);
altr_i2c_int_enable(idev, imask, false);
value = readl(idev->base + ALTR_I2C_STATUS) & ALTR_I2C_STAT_CORE;
@@ -358,6 +352,7 @@ static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg)
}
altr_i2c_core_disable(idev);
+ mutex_unlock(&idev->isr_mutex);
return idev->msg_err;
}
@@ -389,23 +384,19 @@ static const struct i2c_algorithm altr_i2c_algo = {
static int altr_i2c_probe(struct platform_device *pdev)
{
struct altr_i2c_dev *idev = NULL;
- struct resource *res;
int irq, ret;
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
if (!idev)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- idev->base = devm_ioremap_resource(&pdev->dev, res);
+ idev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(idev->base))
return PTR_ERR(idev->base);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "missing interrupt resource\n");
+ if (irq < 0)
return irq;
- }
idev->i2c_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(idev->i2c_clk)) {
@@ -415,7 +406,6 @@ static int altr_i2c_probe(struct platform_device *pdev)
idev->dev = &pdev->dev;
init_completion(&idev->msg_complete);
- spin_lock_init(&idev->lock);
mutex_init(&idev->isr_mutex);
ret = device_property_read_u32(idev->dev, "fifo-size",
@@ -453,7 +443,9 @@ static int altr_i2c_probe(struct platform_device *pdev)
return ret;
}
+ mutex_lock(&idev->isr_mutex);
altr_i2c_init(idev);
+ mutex_unlock(&idev->isr_mutex);
i2c_set_adapdata(&idev->adapter, idev);
strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c
index 3da1a8acecb5..e14edd236108 100644
--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -131,6 +131,7 @@ static struct at91_twi_pdata sama5d2_config = {
.has_dig_filtr = true,
.has_adv_dig_filtr = true,
.has_ana_filtr = true,
+ .has_clear_cmd = false, /* due to errata, CLEAR cmd is not working */
};
static struct at91_twi_pdata sam9x60_config = {
@@ -142,6 +143,7 @@ static struct at91_twi_pdata sam9x60_config = {
.has_dig_filtr = true,
.has_adv_dig_filtr = true,
.has_ana_filtr = true,
+ .has_clear_cmd = true,
};
static const struct of_device_id atmel_twi_dt_ids[] = {
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
index 37b96ac9dfae..363d540a8345 100644
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -480,7 +480,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
unsigned long time_left;
bool has_unre_flag = dev->pdata->has_unre_flag;
bool has_alt_cmd = dev->pdata->has_alt_cmd;
- struct i2c_bus_recovery_info *rinfo = &dev->rinfo;
/*
* WARNING: the TXCOMP bit in the Status Register is NOT a clear on
@@ -641,11 +640,12 @@ error:
AT91_TWI_THRCLR | AT91_TWI_LOCKCLR);
}
- if (rinfo->get_sda && !(rinfo->get_sda(&dev->adapter))) {
- dev_dbg(dev->dev,
- "SDA is down; clear bus using gpio\n");
- i2c_recover_bus(&dev->adapter);
- }
+ /*
+ * some faulty I2C slave devices might hold SDA down;
+ * we can send a bus clear command, hoping that the pins will be
+ * released
+ */
+ i2c_recover_bus(&dev->adapter);
return ret;
}
@@ -830,7 +830,7 @@ static void at91_unprepare_twi_recovery(struct i2c_adapter *adap)
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
}
-static int at91_init_twi_recovery_info(struct platform_device *pdev,
+static int at91_init_twi_recovery_gpio(struct platform_device *pdev,
struct at91_twi_dev *dev)
{
struct i2c_bus_recovery_info *rinfo = &dev->rinfo;
@@ -894,6 +894,41 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
return 0;
}
+static int at91_twi_recover_bus_cmd(struct i2c_adapter *adap)
+{
+ struct at91_twi_dev *dev = i2c_get_adapdata(adap);
+
+ dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR);
+ if (!(dev->transfer_status & AT91_TWI_SDA)) {
+ dev_dbg(dev->dev, "SDA is down; sending bus clear command\n");
+ if (dev->use_alt_cmd) {
+ unsigned int acr;
+
+ acr = at91_twi_read(dev, AT91_TWI_ACR);
+ acr &= ~AT91_TWI_ACR_DATAL_MASK;
+ at91_twi_write(dev, AT91_TWI_ACR, acr);
+ }
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_CLEAR);
+ }
+
+ return 0;
+}
+
+static int at91_init_twi_recovery_info(struct platform_device *pdev,
+ struct at91_twi_dev *dev)
+{
+ struct i2c_bus_recovery_info *rinfo = &dev->rinfo;
+ bool has_clear_cmd = dev->pdata->has_clear_cmd;
+
+ if (!has_clear_cmd)
+ return at91_init_twi_recovery_gpio(pdev, dev);
+
+ rinfo->recover_bus = at91_twi_recover_bus_cmd;
+ dev->adapter.bus_recovery_info = rinfo;
+
+ return 0;
+}
+
int at91_twi_probe_master(struct platform_device *pdev,
u32 phy_addr, struct at91_twi_dev *dev)
{
diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
index f57a6cab96b4..7e7b4955ca7f 100644
--- a/drivers/i2c/busses/i2c-at91.h
+++ b/drivers/i2c/busses/i2c-at91.h
@@ -36,6 +36,7 @@
#define AT91_TWI_SVDIS BIT(5) /* Slave Transfer Disable */
#define AT91_TWI_QUICK BIT(6) /* SMBus quick command */
#define AT91_TWI_SWRST BIT(7) /* Software Reset */
+#define AT91_TWI_CLEAR BIT(15) /* Bus clear command */
#define AT91_TWI_ACMEN BIT(16) /* Alternative Command Mode Enable */
#define AT91_TWI_ACMDIS BIT(17) /* Alternative Command Mode Disable */
#define AT91_TWI_THRCLR BIT(24) /* Transmit Holding Register Clear */
@@ -69,6 +70,8 @@
#define AT91_TWI_NACK BIT(8) /* Not Acknowledged */
#define AT91_TWI_EOSACC BIT(11) /* End Of Slave Access */
#define AT91_TWI_LOCK BIT(23) /* TWI Lock due to Frame Errors */
+#define AT91_TWI_SCL BIT(24) /* TWI SCL status */
+#define AT91_TWI_SDA BIT(25) /* TWI SDA status */
#define AT91_TWI_INT_MASK \
(AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK \
@@ -81,7 +84,8 @@
#define AT91_TWI_THR 0x0034 /* Transmit Holding Register */
#define AT91_TWI_ACR 0x0040 /* Alternative Command Register */
-#define AT91_TWI_ACR_DATAL(len) ((len) & 0xff)
+#define AT91_TWI_ACR_DATAL_MASK GENMASK(15, 0)
+#define AT91_TWI_ACR_DATAL(len) ((len) & AT91_TWI_ACR_DATAL_MASK)
#define AT91_TWI_ACR_DIR BIT(8)
#define AT91_TWI_FILTR 0x0044
@@ -118,6 +122,7 @@ struct at91_twi_pdata {
bool has_dig_filtr;
bool has_adv_dig_filtr;
bool has_ana_filtr;
+ bool has_clear_cmd;
struct at_dma_slave dma_slave;
};
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index be3681d08a8d..5294b73beca8 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -734,7 +734,6 @@ static int axxia_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct axxia_i2c_dev *idev = NULL;
- struct resource *res;
void __iomem *base;
int ret = 0;
@@ -742,16 +741,13 @@ static int axxia_i2c_probe(struct platform_device *pdev)
if (!idev)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&pdev->dev, res);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
idev->irq = platform_get_irq(pdev, 0);
- if (idev->irq < 0) {
- dev_err(&pdev->dev, "missing interrupt resource\n");
+ if (idev->irq < 0)
return idev->irq;
- }
idev->i2c_clk = devm_clk_get(&pdev->dev, "i2c");
if (IS_ERR(idev->i2c_clk)) {
diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
index d091a12596ad..8a3c98866fb7 100644
--- a/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -79,6 +79,7 @@
#define M_CMD_STATUS_RX_FIFO_FULL 0x6
#define M_CMD_PROTOCOL_SHIFT 9
#define M_CMD_PROTOCOL_MASK 0xf
+#define M_CMD_PROTOCOL_QUICK 0x0
#define M_CMD_PROTOCOL_BLK_WR 0x7
#define M_CMD_PROTOCOL_BLK_RD 0x8
#define M_CMD_PROTOCOL_PROCESS 0xa
@@ -768,7 +769,11 @@ static int bcm_iproc_i2c_xfer_internal(struct bcm_iproc_i2c_dev *iproc_i2c,
* number of bytes to read
*/
val = BIT(M_CMD_START_BUSY_SHIFT);
- if (msg->flags & I2C_M_RD) {
+
+ if (msg->len == 0) {
+ /* SMBUS QUICK Command (Read/Write) */
+ val |= (M_CMD_PROTOCOL_QUICK << M_CMD_PROTOCOL_SHIFT);
+ } else if (msg->flags & I2C_M_RD) {
u32 protocol;
iproc_i2c->rx_bytes = 0;
@@ -830,8 +835,7 @@ static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap)
{
u32 val;
- /* We do not support the SMBUS Quick command */
- val = I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+ val = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
if (adap->algo->reg_slave)
val |= I2C_FUNC_SLAVE;
diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c
index 572aebbb254e..ed5e1275ae46 100644
--- a/drivers/i2c/busses/i2c-bcm-kona.c
+++ b/drivers/i2c/busses/i2c-bcm-kona.c
@@ -750,7 +750,6 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
int rc = 0;
struct bcm_kona_i2c_dev *dev;
struct i2c_adapter *adap;
- struct resource *iomem;
/* Allocate memory for private data structure */
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -762,8 +761,7 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
init_completion(&dev->done);
/* Map hardware registers */
- iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev->base = devm_ioremap_resource(dev->device, iomem);
+ dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dev->base))
return -ENOMEM;
@@ -823,8 +821,7 @@ static int bcm_kona_i2c_probe(struct platform_device *pdev)
/* Get the interrupt number */
dev->irq = platform_get_irq(pdev, 0);
if (dev->irq < 0) {
- dev_err(dev->device, "no irq resource\n");
- rc = -ENODEV;
+ rc = dev->irq;
goto probe_disable_clk;
}
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
index 169a2836922d..d4e0a0f6732a 100644
--- a/drivers/i2c/busses/i2c-brcmstb.c
+++ b/drivers/i2c/busses/i2c-brcmstb.c
@@ -647,20 +647,22 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
int_name = NULL;
/* Get the interrupt number */
- dev->irq = platform_get_irq(pdev, 0);
+ dev->irq = platform_get_irq_optional(pdev, 0);
/* disable the bsc interrupt line */
brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);
/* register the ISR handler */
- rc = devm_request_irq(&pdev->dev, dev->irq, brcmstb_i2c_isr,
- IRQF_SHARED,
- int_name ? int_name : pdev->name,
- dev);
-
- if (rc) {
- dev_dbg(dev->device, "falling back to polling mode");
- dev->irq = -1;
+ if (dev->irq >= 0) {
+ rc = devm_request_irq(&pdev->dev, dev->irq, brcmstb_i2c_isr,
+ IRQF_SHARED,
+ int_name ? int_name : pdev->name,
+ dev);
+
+ if (rc) {
+ dev_dbg(dev->device, "falling back to polling mode");
+ dev->irq = -1;
+ }
}
if (of_property_read_u32(dev->device->of_node,
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index 89d58f7d2a25..4b72398af505 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -23,6 +23,7 @@
#define CDNS_I2C_ISR_OFFSET 0x10 /* IRQ Status Register, RW */
#define CDNS_I2C_XFER_SIZE_OFFSET 0x14 /* Transfer Size Register, RW */
#define CDNS_I2C_TIME_OUT_OFFSET 0x1C /* Time Out Register, RW */
+#define CDNS_I2C_IMR_OFFSET 0x20 /* IRQ Mask Register, RO */
#define CDNS_I2C_IER_OFFSET 0x24 /* IRQ Enable Register, WO */
#define CDNS_I2C_IDR_OFFSET 0x28 /* IRQ Disable Register, WO */
@@ -40,9 +41,17 @@
#define CDNS_I2C_CR_DIVB_SHIFT 8
#define CDNS_I2C_CR_DIVB_MASK (0x3f << CDNS_I2C_CR_DIVB_SHIFT)
+#define CDNS_I2C_CR_MASTER_EN_MASK (CDNS_I2C_CR_NEA | \
+ CDNS_I2C_CR_ACK_EN | \
+ CDNS_I2C_CR_MS)
+
+#define CDNS_I2C_CR_SLAVE_EN_MASK ~CDNS_I2C_CR_MASTER_EN_MASK
+
/* Status Register Bit mask definitions */
#define CDNS_I2C_SR_BA BIT(8)
+#define CDNS_I2C_SR_TXDV BIT(6)
#define CDNS_I2C_SR_RXDV BIT(5)
+#define CDNS_I2C_SR_RXRW BIT(3)
/*
* I2C Address Register Bit mask definitions
@@ -91,6 +100,14 @@
CDNS_I2C_IXR_DATA | \
CDNS_I2C_IXR_COMP)
+#define CDNS_I2C_IXR_SLAVE_INTR_MASK (CDNS_I2C_IXR_RX_UNF | \
+ CDNS_I2C_IXR_TX_OVF | \
+ CDNS_I2C_IXR_RX_OVF | \
+ CDNS_I2C_IXR_TO | \
+ CDNS_I2C_IXR_NACK | \
+ CDNS_I2C_IXR_DATA | \
+ CDNS_I2C_IXR_COMP)
+
#define CDNS_I2C_TIMEOUT msecs_to_jiffies(1000)
/* timeout for pm runtime autosuspend */
#define CNDS_I2C_PM_TIMEOUT 1000 /* ms */
@@ -114,6 +131,32 @@
#define cdns_i2c_readreg(offset) readl_relaxed(id->membase + offset)
#define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset)
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+/**
+ * enum cdns_i2c_mode - I2C Controller current operating mode
+ *
+ * @CDNS_I2C_MODE_SLAVE: I2C controller operating in slave mode
+ * @CDNS_I2C_MODE_MASTER: I2C Controller operating in master mode
+ */
+enum cdns_i2c_mode {
+ CDNS_I2C_MODE_SLAVE,
+ CDNS_I2C_MODE_MASTER,
+};
+
+/**
+ * enum cdns_i2c_slave_mode - Slave state when I2C is operating in slave mode
+ *
+ * @CDNS_I2C_SLAVE_STATE_IDLE: I2C slave idle
+ * @CDNS_I2C_SLAVE_STATE_SEND: I2C slave sending data to master
+ * @CDNS_I2C_SLAVE_STATE_RECV: I2C slave receiving data from master
+ */
+enum cdns_i2c_slave_state {
+ CDNS_I2C_SLAVE_STATE_IDLE,
+ CDNS_I2C_SLAVE_STATE_SEND,
+ CDNS_I2C_SLAVE_STATE_RECV,
+};
+#endif
+
/**
* struct cdns_i2c - I2C device private data structure
*
@@ -135,6 +178,10 @@
* @clk: Pointer to struct clk
* @clk_rate_change_nb: Notifier block for clock rate changes
* @quirks: flag for broken hold bit usage in r1p10
+ * @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register
+ * @slave: Registered slave instance.
+ * @dev_mode: I2C operating role(master/slave).
+ * @slave_state: I2C Slave state(idle/read/write).
*/
struct cdns_i2c {
struct device *dev;
@@ -155,6 +202,12 @@ struct cdns_i2c {
struct clk *clk;
struct notifier_block clk_rate_change_nb;
u32 quirks;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ u16 ctrl_reg_diva_divb;
+ struct i2c_client *slave;
+ enum cdns_i2c_mode dev_mode;
+ enum cdns_i2c_slave_state slave_state;
+#endif
};
struct cdns_platform_data {
@@ -183,17 +236,155 @@ static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround)
(id->curr_recv_count == CDNS_I2C_FIFO_DEPTH + 1));
}
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static void cdns_i2c_set_mode(enum cdns_i2c_mode mode, struct cdns_i2c *id)
+{
+ /* Disable all interrupts */
+ cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET);
+
+ /* Clear FIFO and transfer size */
+ cdns_i2c_writereg(CDNS_I2C_CR_CLR_FIFO, CDNS_I2C_CR_OFFSET);
+
+ /* Update device mode and state */
+ id->dev_mode = mode;
+ id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+
+ switch (mode) {
+ case CDNS_I2C_MODE_MASTER:
+ /* Enable i2c master */
+ cdns_i2c_writereg(id->ctrl_reg_diva_divb |
+ CDNS_I2C_CR_MASTER_EN_MASK,
+ CDNS_I2C_CR_OFFSET);
+ /*
+ * This delay is needed to give the IP some time to switch to
+ * the master mode. With lower values(like 110 us) i2cdetect
+ * will not detect any slave and without this delay, the IP will
+ * trigger a timeout interrupt.
+ */
+ usleep_range(115, 125);
+ break;
+ case CDNS_I2C_MODE_SLAVE:
+ /* Enable i2c slave */
+ cdns_i2c_writereg(id->ctrl_reg_diva_divb &
+ CDNS_I2C_CR_SLAVE_EN_MASK,
+ CDNS_I2C_CR_OFFSET);
+
+ /* Setting slave address */
+ cdns_i2c_writereg(id->slave->addr & CDNS_I2C_ADDR_MASK,
+ CDNS_I2C_ADDR_OFFSET);
+
+ /* Enable slave send/receive interrupts */
+ cdns_i2c_writereg(CDNS_I2C_IXR_SLAVE_INTR_MASK,
+ CDNS_I2C_IER_OFFSET);
+ break;
+ }
+}
+
+static void cdns_i2c_slave_rcv_data(struct cdns_i2c *id)
+{
+ u8 bytes;
+ unsigned char data;
+
+ /* Prepare backend for data reception */
+ if (id->slave_state == CDNS_I2C_SLAVE_STATE_IDLE) {
+ id->slave_state = CDNS_I2C_SLAVE_STATE_RECV;
+ i2c_slave_event(id->slave, I2C_SLAVE_WRITE_REQUESTED, NULL);
+ }
+
+ /* Fetch number of bytes to receive */
+ bytes = cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET);
+
+ /* Read data and send to backend */
+ while (bytes--) {
+ data = cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
+ i2c_slave_event(id->slave, I2C_SLAVE_WRITE_RECEIVED, &data);
+ }
+}
+
+static void cdns_i2c_slave_send_data(struct cdns_i2c *id)
+{
+ u8 data;
+
+ /* Prepare backend for data transmission */
+ if (id->slave_state == CDNS_I2C_SLAVE_STATE_IDLE) {
+ id->slave_state = CDNS_I2C_SLAVE_STATE_SEND;
+ i2c_slave_event(id->slave, I2C_SLAVE_READ_REQUESTED, &data);
+ } else {
+ i2c_slave_event(id->slave, I2C_SLAVE_READ_PROCESSED, &data);
+ }
+
+ /* Send data over bus */
+ cdns_i2c_writereg(data, CDNS_I2C_DATA_OFFSET);
+}
+
/**
- * cdns_i2c_isr - Interrupt handler for the I2C device
- * @irq: irq number for the I2C device
- * @ptr: void pointer to cdns_i2c structure
+ * cdns_i2c_slave_isr - Interrupt handler for the I2C device in slave role
+ * @ptr: Pointer to I2C device private data
+ *
+ * This function handles the data interrupt and transfer complete interrupt of
+ * the I2C device in slave role.
+ *
+ * Return: IRQ_HANDLED always
+ */
+static irqreturn_t cdns_i2c_slave_isr(void *ptr)
+{
+ struct cdns_i2c *id = ptr;
+ unsigned int isr_status, i2c_status;
+
+ /* Fetch the interrupt status */
+ isr_status = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET);
+ cdns_i2c_writereg(isr_status, CDNS_I2C_ISR_OFFSET);
+
+ /* Ignore masked interrupts */
+ isr_status &= ~cdns_i2c_readreg(CDNS_I2C_IMR_OFFSET);
+
+ /* Fetch transfer mode (send/receive) */
+ i2c_status = cdns_i2c_readreg(CDNS_I2C_SR_OFFSET);
+
+ /* Handle data send/receive */
+ if (i2c_status & CDNS_I2C_SR_RXRW) {
+ /* Send data to master */
+ if (isr_status & CDNS_I2C_IXR_DATA)
+ cdns_i2c_slave_send_data(id);
+
+ if (isr_status & CDNS_I2C_IXR_COMP) {
+ id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+ i2c_slave_event(id->slave, I2C_SLAVE_STOP, NULL);
+ }
+ } else {
+ /* Receive data from master */
+ if (isr_status & CDNS_I2C_IXR_DATA)
+ cdns_i2c_slave_rcv_data(id);
+
+ if (isr_status & CDNS_I2C_IXR_COMP) {
+ cdns_i2c_slave_rcv_data(id);
+ id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+ i2c_slave_event(id->slave, I2C_SLAVE_STOP, NULL);
+ }
+ }
+
+ /* Master indicated xfer stop or fifo underflow/overflow */
+ if (isr_status & (CDNS_I2C_IXR_NACK | CDNS_I2C_IXR_RX_OVF |
+ CDNS_I2C_IXR_RX_UNF | CDNS_I2C_IXR_TX_OVF)) {
+ id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+ i2c_slave_event(id->slave, I2C_SLAVE_STOP, NULL);
+ cdns_i2c_writereg(CDNS_I2C_CR_CLR_FIFO, CDNS_I2C_CR_OFFSET);
+ }
+
+ return IRQ_HANDLED;
+}
+#endif
+
+/**
+ * cdns_i2c_master_isr - Interrupt handler for the I2C device in master role
+ * @ptr: Pointer to I2C device private data
*
* This function handles the data interrupt, transfer complete interrupt and
- * the error interrupts of the I2C device.
+ * the error interrupts of the I2C device in master role.
*
* Return: IRQ_HANDLED always
*/
-static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
+static irqreturn_t cdns_i2c_master_isr(void *ptr)
{
unsigned int isr_status, avail_bytes, updatetx;
unsigned int bytes_to_send;
@@ -358,6 +549,27 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
}
/**
+ * cdns_i2c_isr - Interrupt handler for the I2C device
+ * @irq: irq number for the I2C device
+ * @ptr: void pointer to cdns_i2c structure
+ *
+ * This function passes the control to slave/master based on current role of
+ * i2c controller.
+ *
+ * Return: IRQ_HANDLED always
+ */
+static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
+{
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ struct cdns_i2c *id = ptr;
+
+ if (id->dev_mode == CDNS_I2C_MODE_SLAVE)
+ return cdns_i2c_slave_isr(ptr);
+#endif
+ return cdns_i2c_master_isr(ptr);
+}
+
+/**
* cdns_i2c_mrecv - Prepare and start a master receive operation
* @id: pointer to the i2c device structure
*/
@@ -577,10 +789,28 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
u32 reg;
struct cdns_i2c *id = adap->algo_data;
bool hold_quirk;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ bool change_role = false;
+#endif
ret = pm_runtime_get_sync(id->dev);
if (ret < 0)
return ret;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ /* Check i2c operating mode and switch if possible */
+ if (id->dev_mode == CDNS_I2C_MODE_SLAVE) {
+ if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE)
+ return -EAGAIN;
+
+ /* Set mode to master */
+ cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
+
+ /* Mark flag to change role once xfer is completed */
+ change_role = true;
+ }
+#endif
+
/* Check if the bus is free */
if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) {
ret = -EAGAIN;
@@ -639,7 +869,15 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
}
ret = num;
+
out:
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ /* Switch i2c mode to slave */
+ if (change_role)
+ cdns_i2c_set_mode(CDNS_I2C_MODE_SLAVE, id);
+#endif
+
pm_runtime_mark_last_busy(id->dev);
pm_runtime_put_autosuspend(id->dev);
return ret;
@@ -653,14 +891,67 @@ out:
*/
static u32 cdns_i2c_func(struct i2c_adapter *adap)
{
- return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
- (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
- I2C_FUNC_SMBUS_BLOCK_DATA;
+ u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
+ (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
+ I2C_FUNC_SMBUS_BLOCK_DATA;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ func |= I2C_FUNC_SLAVE;
+#endif
+
+ return func;
}
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static int cdns_reg_slave(struct i2c_client *slave)
+{
+ int ret;
+ struct cdns_i2c *id = container_of(slave->adapter, struct cdns_i2c,
+ adap);
+
+ if (id->slave)
+ return -EBUSY;
+
+ if (slave->flags & I2C_CLIENT_TEN)
+ return -EAFNOSUPPORT;
+
+ ret = pm_runtime_get_sync(id->dev);
+ if (ret < 0)
+ return ret;
+
+ /* Store slave information */
+ id->slave = slave;
+
+ /* Enable I2C slave */
+ cdns_i2c_set_mode(CDNS_I2C_MODE_SLAVE, id);
+
+ return 0;
+}
+
+static int cdns_unreg_slave(struct i2c_client *slave)
+{
+ struct cdns_i2c *id = container_of(slave->adapter, struct cdns_i2c,
+ adap);
+
+ pm_runtime_put(id->dev);
+
+ /* Remove slave information */
+ id->slave = NULL;
+
+ /* Enable I2C master */
+ cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
+
+ return 0;
+}
+#endif
+
static const struct i2c_algorithm cdns_i2c_algo = {
.master_xfer = cdns_i2c_master_xfer,
.functionality = cdns_i2c_func,
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ .reg_slave = cdns_reg_slave,
+ .unreg_slave = cdns_unreg_slave,
+#endif
};
/**
@@ -755,7 +1046,10 @@ static int cdns_i2c_setclk(unsigned long clk_in, struct cdns_i2c *id)
ctrl_reg |= ((div_a << CDNS_I2C_CR_DIVA_SHIFT) |
(div_b << CDNS_I2C_CR_DIVB_SHIFT));
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
-
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ id->ctrl_reg_diva_divb = ctrl_reg & (CDNS_I2C_CR_DIVA_MASK |
+ CDNS_I2C_CR_DIVB_MASK);
+#endif
return 0;
}
@@ -906,8 +1200,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
id->quirks = data->quirks;
}
- r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- id->membase = devm_ioremap_resource(&pdev->dev, r_mem);
+ id->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &r_mem);
if (IS_ERR(id->membase))
return PTR_ERR(id->membase);
@@ -949,8 +1242,12 @@ static int cdns_i2c_probe(struct platform_device *pdev)
if (ret || (id->i2c_clk > I2C_MAX_FAST_MODE_FREQ))
id->i2c_clk = I2C_MAX_STANDARD_MODE_FREQ;
- cdns_i2c_writereg(CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS,
- CDNS_I2C_CR_OFFSET);
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ /* Set initial mode to master */
+ id->dev_mode = CDNS_I2C_MODE_MASTER;
+ id->slave_state = CDNS_I2C_SLAVE_STATE_IDLE;
+#endif
+ cdns_i2c_writereg(CDNS_I2C_CR_MASTER_EN_MASK, CDNS_I2C_CR_OFFSET);
ret = cdns_i2c_setclk(id->input_clk, id);
if (ret) {
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
index 35e55feda763..f80d79e973cd 100644
--- a/drivers/i2c/busses/i2c-cht-wc.c
+++ b/drivers/i2c/busses/i2c-cht-wc.c
@@ -314,10 +314,8 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
int ret, reg, irq;
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "Error missing irq resource\n");
- return -EINVAL;
- }
+ if (irq < 0)
+ return irq;
adap = devm_kzalloc(&pdev->dev, sizeof(*adap), GFP_KERNEL);
if (!adap)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index e3ceb256a380..232a7679b69b 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -761,7 +761,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
{
struct davinci_i2c_dev *dev;
struct i2c_adapter *adap;
- struct resource *mem;
struct i2c_bus_recovery_info *rinfo;
int r, irq;
@@ -814,8 +813,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
if (IS_ERR(dev->clk))
return PTR_ERR(dev->clk);
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev->base = devm_ioremap_resource(&pdev->dev, mem);
+ dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dev->base)) {
return PTR_ERR(dev->base);
}
diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c
index c70c6fc09ee3..e3a8640db7da 100644
--- a/drivers/i2c/busses/i2c-designware-common.c
+++ b/drivers/i2c/busses/i2c-designware-common.c
@@ -8,17 +8,22 @@
* Copyright (C) 2007 MontaVista Software Inc.
* Copyright (C) 2009 Provigent Ltd.
*/
+#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
-#include <linux/export.h>
-#include <linux/errno.h>
+#include <linux/device.h>
#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/swab.h>
+#include <linux/types.h>
#include "i2c-designware-core.h"
@@ -53,69 +58,267 @@ static char *abort_sources[] = {
"incorrect slave-transmitter mode configuration",
};
-u32 dw_readl(struct dw_i2c_dev *dev, int offset)
+static int dw_reg_read(void *context, unsigned int reg, unsigned int *val)
{
- u32 value;
+ struct dw_i2c_dev *dev = context;
- if (dev->flags & ACCESS_16BIT)
- value = readw_relaxed(dev->base + offset) |
- (readw_relaxed(dev->base + offset + 2) << 16);
- else
- value = readl_relaxed(dev->base + offset);
+ *val = readl_relaxed(dev->base + reg);
- if (dev->flags & ACCESS_SWAP)
- return swab32(value);
- else
- return value;
+ return 0;
}
-void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
+static int dw_reg_write(void *context, unsigned int reg, unsigned int val)
{
- if (dev->flags & ACCESS_SWAP)
- b = swab32(b);
-
- if (dev->flags & ACCESS_16BIT) {
- writew_relaxed((u16)b, dev->base + offset);
- writew_relaxed((u16)(b >> 16), dev->base + offset + 2);
- } else {
- writel_relaxed(b, dev->base + offset);
- }
+ struct dw_i2c_dev *dev = context;
+
+ writel_relaxed(val, dev->base + reg);
+
+ return 0;
+}
+
+static int dw_reg_read_swab(void *context, unsigned int reg, unsigned int *val)
+{
+ struct dw_i2c_dev *dev = context;
+
+ *val = swab32(readl_relaxed(dev->base + reg));
+
+ return 0;
+}
+
+static int dw_reg_write_swab(void *context, unsigned int reg, unsigned int val)
+{
+ struct dw_i2c_dev *dev = context;
+
+ writel_relaxed(swab32(val), dev->base + reg);
+
+ return 0;
+}
+
+static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val)
+{
+ struct dw_i2c_dev *dev = context;
+
+ *val = readw_relaxed(dev->base + reg) |
+ (readw_relaxed(dev->base + reg + 2) << 16);
+
+ return 0;
+}
+
+static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val)
+{
+ struct dw_i2c_dev *dev = context;
+
+ writew_relaxed(val, dev->base + reg);
+ writew_relaxed(val >> 16, dev->base + reg + 2);
+
+ return 0;
}
/**
- * i2c_dw_set_reg_access() - Set register access flags
+ * i2c_dw_init_regmap() - Initialize registers map
* @dev: device private data
*
- * Autodetects needed register access mode and sets access flags accordingly.
- * This must be called before doing any other register access.
+ * Autodetects needed register access mode and creates the regmap with
+ * corresponding read/write callbacks. This must be called before doing any
+ * other register access.
*/
-int i2c_dw_set_reg_access(struct dw_i2c_dev *dev)
+int i2c_dw_init_regmap(struct dw_i2c_dev *dev)
{
+ struct regmap_config map_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .disable_locking = true,
+ .reg_read = dw_reg_read,
+ .reg_write = dw_reg_write,
+ .max_register = DW_IC_COMP_TYPE,
+ };
u32 reg;
int ret;
+ /*
+ * Skip detecting the registers map configuration if the regmap has
+ * already been provided by a higher code.
+ */
+ if (dev->map)
+ return 0;
+
ret = i2c_dw_acquire_lock(dev);
if (ret)
return ret;
- reg = dw_readl(dev, DW_IC_COMP_TYPE);
+ reg = readl(dev->base + DW_IC_COMP_TYPE);
i2c_dw_release_lock(dev);
if (reg == swab32(DW_IC_COMP_TYPE_VALUE)) {
- /* Configure register endianness access */
- dev->flags |= ACCESS_SWAP;
+ map_cfg.reg_read = dw_reg_read_swab;
+ map_cfg.reg_write = dw_reg_write_swab;
} else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
- /* Configure register access mode 16bit */
- dev->flags |= ACCESS_16BIT;
+ map_cfg.reg_read = dw_reg_read_word;
+ map_cfg.reg_write = dw_reg_write_word;
} else if (reg != DW_IC_COMP_TYPE_VALUE) {
dev_err(dev->dev,
"Unknown Synopsys component type: 0x%08x\n", reg);
return -ENODEV;
}
+ /*
+ * Note we'll check the return value of the regmap IO accessors only
+ * at the probe stage. The rest of the code won't do this because
+ * basically we have MMIO-based regmap so non of the read/write methods
+ * can fail.
+ */
+ dev->map = devm_regmap_init(dev->dev, NULL, dev, &map_cfg);
+ if (IS_ERR(dev->map)) {
+ dev_err(dev->dev, "Failed to init the registers map\n");
+ return PTR_ERR(dev->map);
+ }
+
return 0;
}
+static const u32 supported_speeds[] = {
+ I2C_MAX_HIGH_SPEED_MODE_FREQ,
+ I2C_MAX_FAST_MODE_PLUS_FREQ,
+ I2C_MAX_FAST_MODE_FREQ,
+ I2C_MAX_STANDARD_MODE_FREQ,
+};
+
+int i2c_dw_validate_speed(struct dw_i2c_dev *dev)
+{
+ struct i2c_timings *t = &dev->timings;
+ unsigned int i;
+
+ /*
+ * Only standard mode at 100kHz, fast mode at 400kHz,
+ * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
+ */
+ for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) {
+ if (t->bus_freq_hz == supported_speeds[i])
+ return 0;
+ }
+
+ dev_err(dev->dev,
+ "%d Hz is unsupported, only 100kHz, 400kHz, 1MHz and 3.4MHz are supported\n",
+ t->bus_freq_hz);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(i2c_dw_validate_speed);
+
+#ifdef CONFIG_ACPI
+
+#include <linux/dmi.h>
+
+/*
+ * The HCNT/LCNT information coming from ACPI should be the most accurate
+ * for given platform. However, some systems get it wrong. On such systems
+ * we get better results by calculating those based on the input clock.
+ */
+static const struct dmi_system_id i2c_dw_no_acpi_params[] = {
+ {
+ .ident = "Dell Inspiron 7348",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"),
+ },
+ },
+ {}
+};
+
+static void i2c_dw_acpi_params(struct device *device, char method[],
+ u16 *hcnt, u16 *lcnt, u32 *sda_hold)
+{
+ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+ acpi_handle handle = ACPI_HANDLE(device);
+ union acpi_object *obj;
+
+ if (dmi_check_system(i2c_dw_no_acpi_params))
+ return;
+
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
+ return;
+
+ obj = (union acpi_object *)buf.pointer;
+ if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) {
+ const union acpi_object *objs = obj->package.elements;
+
+ *hcnt = (u16)objs[0].integer.value;
+ *lcnt = (u16)objs[1].integer.value;
+ *sda_hold = (u32)objs[2].integer.value;
+ }
+
+ kfree(buf.pointer);
+}
+
+int i2c_dw_acpi_configure(struct device *device)
+{
+ struct dw_i2c_dev *dev = dev_get_drvdata(device);
+ struct i2c_timings *t = &dev->timings;
+ u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
+
+ /*
+ * Try to get SDA hold time and *CNT values from an ACPI method for
+ * selected speed modes.
+ */
+ i2c_dw_acpi_params(device, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht);
+ i2c_dw_acpi_params(device, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht);
+ i2c_dw_acpi_params(device, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
+ i2c_dw_acpi_params(device, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);
+
+ switch (t->bus_freq_hz) {
+ case I2C_MAX_STANDARD_MODE_FREQ:
+ dev->sda_hold_time = ss_ht;
+ break;
+ case I2C_MAX_FAST_MODE_PLUS_FREQ:
+ dev->sda_hold_time = fp_ht;
+ break;
+ case I2C_MAX_HIGH_SPEED_MODE_FREQ:
+ dev->sda_hold_time = hs_ht;
+ break;
+ case I2C_MAX_FAST_MODE_FREQ:
+ default:
+ dev->sda_hold_time = fs_ht;
+ break;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(i2c_dw_acpi_configure);
+
+void i2c_dw_acpi_adjust_bus_speed(struct device *device)
+{
+ struct dw_i2c_dev *dev = dev_get_drvdata(device);
+ struct i2c_timings *t = &dev->timings;
+ u32 acpi_speed;
+ int i;
+
+ acpi_speed = i2c_acpi_find_bus_speed(device);
+ /*
+ * Some DSTDs use a non standard speed, round down to the lowest
+ * standard speed.
+ */
+ for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) {
+ if (acpi_speed >= supported_speeds[i])
+ break;
+ }
+ acpi_speed = i < ARRAY_SIZE(supported_speeds) ? supported_speeds[i] : 0;
+
+ /*
+ * Find bus speed from the "clock-frequency" device property, ACPI
+ * or by using fast mode if neither is set.
+ */
+ if (acpi_speed && t->bus_freq_hz)
+ t->bus_freq_hz = min(t->bus_freq_hz, acpi_speed);
+ else if (acpi_speed || t->bus_freq_hz)
+ t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed);
+ else
+ t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
+}
+EXPORT_SYMBOL_GPL(i2c_dw_acpi_adjust_bus_speed);
+
+#endif /* CONFIG_ACPI */
+
u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
{
/*
@@ -181,11 +384,17 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
return ret;
/* Configure SDA Hold Time if required */
- reg = dw_readl(dev, DW_IC_COMP_VERSION);
+ ret = regmap_read(dev->map, DW_IC_COMP_VERSION, &reg);
+ if (ret)
+ goto err_release_lock;
+
if (reg >= DW_IC_SDA_HOLD_MIN_VERS) {
if (!dev->sda_hold_time) {
/* Keep previous hold time setting if no one set it */
- dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD);
+ ret = regmap_read(dev->map, DW_IC_SDA_HOLD,
+ &dev->sda_hold_time);
+ if (ret)
+ goto err_release_lock;
}
/*
@@ -209,14 +418,16 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
dev->sda_hold_time = 0;
}
+err_release_lock:
i2c_dw_release_lock(dev);
- return 0;
+ return ret;
}
void __i2c_dw_disable(struct dw_i2c_dev *dev)
{
int timeout = 100;
+ u32 status;
do {
__i2c_dw_disable_nowait(dev);
@@ -224,7 +435,8 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev)
* The enable status register may be unimplemented, but
* in that case this test reads zero and exits the loop.
*/
- if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == 0)
+ regmap_read(dev->map, DW_IC_ENABLE_STATUS, &status);
+ if ((status & 1) == 0)
return;
/*
@@ -303,22 +515,23 @@ void i2c_dw_release_lock(struct dw_i2c_dev *dev)
*/
int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev)
{
- int timeout = TIMEOUT;
+ u32 status;
+ int ret;
- while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) {
- if (timeout <= 0) {
- dev_warn(dev->dev, "timeout waiting for bus ready\n");
- i2c_recover_bus(&dev->adapter);
+ ret = regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status,
+ !(status & DW_IC_STATUS_ACTIVITY),
+ 1100, 20000);
+ if (ret) {
+ dev_warn(dev->dev, "timeout waiting for bus ready\n");
- if (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY)
- return -ETIMEDOUT;
- return 0;
- }
- timeout--;
- usleep_range(1000, 1100);
+ i2c_recover_bus(&dev->adapter);
+
+ regmap_read(dev->map, DW_IC_STATUS, &status);
+ if (!(status & DW_IC_STATUS_ACTIVITY))
+ ret = 0;
}
- return 0;
+ return ret;
}
int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
@@ -344,15 +557,19 @@ int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
return -EIO;
}
-void i2c_dw_set_fifo_size(struct dw_i2c_dev *dev)
+int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev)
{
u32 param, tx_fifo_depth, rx_fifo_depth;
+ int ret;
/*
* Try to detect the FIFO depth if not set by interface driver,
* the depth could be from 2 to 256 from HW spec.
*/
- param = dw_readl(dev, DW_IC_COMP_PARAM_1);
+ ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &param);
+ if (ret)
+ return ret;
+
tx_fifo_depth = ((param >> 16) & 0xff) + 1;
rx_fifo_depth = ((param >> 8) & 0xff) + 1;
if (!dev->tx_fifo_depth) {
@@ -364,6 +581,8 @@ void i2c_dw_set_fifo_size(struct dw_i2c_dev *dev)
dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth,
rx_fifo_depth);
}
+
+ return 0;
}
u32 i2c_dw_func(struct i2c_adapter *adap)
@@ -375,17 +594,19 @@ u32 i2c_dw_func(struct i2c_adapter *adap)
void i2c_dw_disable(struct dw_i2c_dev *dev)
{
+ u32 dummy;
+
/* Disable controller */
__i2c_dw_disable(dev);
/* Disable all interrupts */
- dw_writel(dev, 0, DW_IC_INTR_MASK);
- dw_readl(dev, DW_IC_CLR_INTR);
+ regmap_write(dev->map, DW_IC_INTR_MASK, 0);
+ regmap_read(dev->map, DW_IC_CLR_INTR, &dummy);
}
void i2c_dw_disable_int(struct dw_i2c_dev *dev)
{
- dw_writel(dev, 0, DW_IC_INTR_MASK);
+ regmap_write(dev->map, DW_IC_INTR_MASK, 0);
}
MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core");
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index b220ad64c38d..556673a1f61b 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -9,7 +9,14 @@
* Copyright (C) 2009 Provigent Ltd.
*/
+#include <linux/bits.h>
+#include <linux/compiler_types.h>
+#include <linux/completion.h>
+#include <linux/dev_printk.h>
+#include <linux/errno.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
I2C_FUNC_SMBUS_BYTE | \
@@ -120,8 +127,6 @@
#define STATUS_WRITE_IN_PROGRESS 0x1
#define STATUS_READ_IN_PROGRESS 0x2
-#define TIMEOUT 20 /* ms */
-
/*
* operation modes
*/
@@ -170,11 +175,17 @@
DW_IC_TX_ABRT_TXDATA_NOACK | \
DW_IC_TX_ABRT_GCALL_NOACK)
+struct clk;
+struct device;
+struct reset_control;
/**
* struct dw_i2c_dev - private i2c-designware data
* @dev: driver model device node
+ * @map: IO registers map
+ * @sysmap: System controller registers map
* @base: IO registers pointer
+ * @ext: Extended IO registers pointer
* @cmd_complete: tx completion indicator
* @clk: input reference clock
* @pclk: clock required to access the registers
@@ -224,6 +235,8 @@
*/
struct dw_i2c_dev {
struct device *dev;
+ struct regmap *map;
+ struct regmap *sysmap;
void __iomem *base;
void __iomem *ext;
struct completion cmd_complete;
@@ -232,7 +245,6 @@ struct dw_i2c_dev {
struct reset_control *rst;
struct i2c_client *slave;
u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev);
- struct dw_pci_controller *controller;
int cmd_err;
struct i2c_msg *msgs;
int msgs_num;
@@ -276,18 +288,14 @@ struct dw_i2c_dev {
bool suspended;
};
-#define ACCESS_SWAP 0x00000001
-#define ACCESS_16BIT 0x00000002
-#define ACCESS_INTR_MASK 0x00000004
-#define ACCESS_NO_IRQ_SUSPEND 0x00000008
+#define ACCESS_INTR_MASK 0x00000001
+#define ACCESS_NO_IRQ_SUSPEND 0x00000002
-#define MODEL_CHERRYTRAIL 0x00000100
-#define MODEL_MSCC_OCELOT 0x00000200
+#define MODEL_MSCC_OCELOT 0x00000100
+#define MODEL_BAIKAL_BT1 0x00000200
#define MODEL_MASK 0x00000f00
-u32 dw_readl(struct dw_i2c_dev *dev, int offset);
-void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
-int i2c_dw_set_reg_access(struct dw_i2c_dev *dev);
+int i2c_dw_init_regmap(struct dw_i2c_dev *dev);
u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset);
int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev);
@@ -297,32 +305,67 @@ int i2c_dw_acquire_lock(struct dw_i2c_dev *dev);
void i2c_dw_release_lock(struct dw_i2c_dev *dev);
int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev);
int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev);
-void i2c_dw_set_fifo_size(struct dw_i2c_dev *dev);
+int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev);
u32 i2c_dw_func(struct i2c_adapter *adap);
void i2c_dw_disable(struct dw_i2c_dev *dev);
void i2c_dw_disable_int(struct dw_i2c_dev *dev);
static inline void __i2c_dw_enable(struct dw_i2c_dev *dev)
{
- dw_writel(dev, 1, DW_IC_ENABLE);
+ regmap_write(dev->map, DW_IC_ENABLE, 1);
}
static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev)
{
- dw_writel(dev, 0, DW_IC_ENABLE);
+ regmap_write(dev->map, DW_IC_ENABLE, 0);
}
void __i2c_dw_disable(struct dw_i2c_dev *dev);
-extern int i2c_dw_probe(struct dw_i2c_dev *dev);
+extern void i2c_dw_configure_master(struct dw_i2c_dev *dev);
+extern int i2c_dw_probe_master(struct dw_i2c_dev *dev);
+
#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_SLAVE)
+extern void i2c_dw_configure_slave(struct dw_i2c_dev *dev);
extern int i2c_dw_probe_slave(struct dw_i2c_dev *dev);
#else
+static inline void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { }
static inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; }
#endif
+static inline int i2c_dw_probe(struct dw_i2c_dev *dev)
+{
+ switch (dev->mode) {
+ case DW_IC_SLAVE:
+ return i2c_dw_probe_slave(dev);
+ case DW_IC_MASTER:
+ return i2c_dw_probe_master(dev);
+ default:
+ dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode);
+ return -EINVAL;
+ }
+}
+
+static inline void i2c_dw_configure(struct dw_i2c_dev *dev)
+{
+ if (i2c_detect_slave_mode(dev->dev))
+ i2c_dw_configure_slave(dev);
+ else
+ i2c_dw_configure_master(dev);
+}
+
#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL)
extern int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev);
#else
static inline int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) { return 0; }
#endif
+
+int i2c_dw_validate_speed(struct dw_i2c_dev *dev);
+
+#if IS_ENABLED(CONFIG_ACPI)
+int i2c_dw_acpi_configure(struct device *device);
+void i2c_dw_acpi_adjust_bus_speed(struct device *device);
+#else
+static inline int i2c_dw_acpi_configure(struct device *device) { return -ENODEV; }
+static inline void i2c_dw_acpi_adjust_bus_speed(struct device *device) {}
+#endif
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 3a58eef20936..d6425ad6e6a3 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
#include "i2c-designware-core.h"
@@ -25,11 +26,11 @@
static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
{
/* Configure Tx/Rx FIFO threshold levels */
- dw_writel(dev, dev->tx_fifo_depth / 2, DW_IC_TX_TL);
- dw_writel(dev, 0, DW_IC_RX_TL);
+ regmap_write(dev->map, DW_IC_TX_TL, dev->tx_fifo_depth / 2);
+ regmap_write(dev->map, DW_IC_RX_TL, 0);
/* Configure the I2C master */
- dw_writel(dev, dev->master_cfg, DW_IC_CON);
+ regmap_write(dev->map, DW_IC_CON, dev->master_cfg);
}
static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
@@ -44,8 +45,11 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
ret = i2c_dw_acquire_lock(dev);
if (ret)
return ret;
- comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
+
+ ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &comp_param1);
i2c_dw_release_lock(dev);
+ if (ret)
+ return ret;
/* Set standard and fast speed dividers for high/low periods */
sda_falling_time = t->sda_fall_ns ?: 300; /* ns */
@@ -76,14 +80,27 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
*/
if (t->bus_freq_hz == 1000000) {
/*
- * Check are fast mode plus parameters available and use
- * fast mode if not.
+ * Check are Fast Mode Plus parameters available. Calculate
+ * SCL timing parameters for Fast Mode Plus if not set.
*/
if (dev->fp_hcnt && dev->fp_lcnt) {
dev->fs_hcnt = dev->fp_hcnt;
dev->fs_lcnt = dev->fp_lcnt;
- fp_str = " Plus";
+ } else {
+ ic_clk = i2c_dw_clk_rate(dev);
+ dev->fs_hcnt =
+ i2c_dw_scl_hcnt(ic_clk,
+ 260, /* tHIGH = 260 ns */
+ sda_falling_time,
+ 0, /* DW default */
+ 0); /* No offset */
+ dev->fs_lcnt =
+ i2c_dw_scl_lcnt(ic_clk,
+ 500, /* tLOW = 500 ns */
+ scl_falling_time,
+ 0); /* No offset */
}
+ fp_str = " Plus";
}
/*
* Calculate SCL timing parameters for fast mode if not set. They are
@@ -116,10 +133,22 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
dev->master_cfg |= DW_IC_CON_SPEED_FAST;
dev->hs_hcnt = 0;
dev->hs_lcnt = 0;
- } else if (dev->hs_hcnt && dev->hs_lcnt) {
- dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
- dev->hs_hcnt, dev->hs_lcnt);
+ } else if (!dev->hs_hcnt || !dev->hs_lcnt) {
+ ic_clk = i2c_dw_clk_rate(dev);
+ dev->hs_hcnt =
+ i2c_dw_scl_hcnt(ic_clk,
+ 160, /* tHIGH = 160 ns */
+ sda_falling_time,
+ 0, /* DW default */
+ 0); /* No offset */
+ dev->hs_lcnt =
+ i2c_dw_scl_lcnt(ic_clk,
+ 320, /* tLOW = 320 ns */
+ scl_falling_time,
+ 0); /* No offset */
}
+ dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
+ dev->hs_hcnt, dev->hs_lcnt);
}
ret = i2c_dw_set_sda_hold(dev);
@@ -162,22 +191,22 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
__i2c_dw_disable(dev);
/* Write standard speed timing parameters */
- dw_writel(dev, dev->ss_hcnt, DW_IC_SS_SCL_HCNT);
- dw_writel(dev, dev->ss_lcnt, DW_IC_SS_SCL_LCNT);
+ regmap_write(dev->map, DW_IC_SS_SCL_HCNT, dev->ss_hcnt);
+ regmap_write(dev->map, DW_IC_SS_SCL_LCNT, dev->ss_lcnt);
/* Write fast mode/fast mode plus timing parameters */
- dw_writel(dev, dev->fs_hcnt, DW_IC_FS_SCL_HCNT);
- dw_writel(dev, dev->fs_lcnt, DW_IC_FS_SCL_LCNT);
+ regmap_write(dev->map, DW_IC_FS_SCL_HCNT, dev->fs_hcnt);
+ regmap_write(dev->map, DW_IC_FS_SCL_LCNT, dev->fs_lcnt);
/* Write high speed timing parameters if supported */
if (dev->hs_hcnt && dev->hs_lcnt) {
- dw_writel(dev, dev->hs_hcnt, DW_IC_HS_SCL_HCNT);
- dw_writel(dev, dev->hs_lcnt, DW_IC_HS_SCL_LCNT);
+ regmap_write(dev->map, DW_IC_HS_SCL_HCNT, dev->hs_hcnt);
+ regmap_write(dev->map, DW_IC_HS_SCL_LCNT, dev->hs_lcnt);
}
/* Write SDA hold time if supported */
if (dev->sda_hold_time)
- dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
+ regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time);
i2c_dw_configure_fifo_master(dev);
i2c_dw_release_lock(dev);
@@ -188,15 +217,15 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
{
struct i2c_msg *msgs = dev->msgs;
- u32 ic_con, ic_tar = 0;
+ u32 ic_con = 0, ic_tar = 0;
+ u32 dummy;
/* Disable the adapter */
__i2c_dw_disable(dev);
/* If the slave address is ten bit address, enable 10BITADDR */
- ic_con = dw_readl(dev, DW_IC_CON);
if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) {
- ic_con |= DW_IC_CON_10BITADDR_MASTER;
+ ic_con = DW_IC_CON_10BITADDR_MASTER;
/*
* If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing
* mode has to be enabled via bit 12 of IC_TAR register.
@@ -204,17 +233,17 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
* detected from registers.
*/
ic_tar = DW_IC_TAR_10BITADDR_MASTER;
- } else {
- ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
}
- dw_writel(dev, ic_con, DW_IC_CON);
+ regmap_update_bits(dev->map, DW_IC_CON, DW_IC_CON_10BITADDR_MASTER,
+ ic_con);
/*
* Set the slave (target) address and enable 10-bit addressing mode
* if applicable.
*/
- dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR);
+ regmap_write(dev->map, DW_IC_TAR,
+ msgs[dev->msg_write_idx].addr | ic_tar);
/* Enforce disabled interrupts (due to HW issues) */
i2c_dw_disable_int(dev);
@@ -223,11 +252,11 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
__i2c_dw_enable(dev);
/* Dummy read to avoid the register getting stuck on Bay Trail */
- dw_readl(dev, DW_IC_ENABLE_STATUS);
+ regmap_read(dev->map, DW_IC_ENABLE_STATUS, &dummy);
/* Clear and enable interrupts */
- dw_readl(dev, DW_IC_CLR_INTR);
- dw_writel(dev, DW_IC_INTR_MASTER_MASK, DW_IC_INTR_MASK);
+ regmap_read(dev->map, DW_IC_CLR_INTR, &dummy);
+ regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK);
}
/*
@@ -246,6 +275,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
u32 buf_len = dev->tx_buf_len;
u8 *buf = dev->tx_buf;
bool need_restart = false;
+ unsigned int flr;
intr_mask = DW_IC_INTR_MASTER_MASK;
@@ -278,8 +308,11 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
need_restart = true;
}
- tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR);
- rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR);
+ regmap_read(dev->map, DW_IC_TXFLR, &flr);
+ tx_limit = dev->tx_fifo_depth - flr;
+
+ regmap_read(dev->map, DW_IC_RXFLR, &flr);
+ rx_limit = dev->rx_fifo_depth - flr;
while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
u32 cmd = 0;
@@ -312,11 +345,14 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
if (dev->rx_outstanding >= dev->rx_fifo_depth)
break;
- dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD);
+ regmap_write(dev->map, DW_IC_DATA_CMD,
+ cmd | 0x100);
rx_limit--;
dev->rx_outstanding++;
- } else
- dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD);
+ } else {
+ regmap_write(dev->map, DW_IC_DATA_CMD,
+ cmd | *buf++);
+ }
tx_limit--; buf_len--;
}
@@ -346,7 +382,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
if (dev->msg_err)
intr_mask = 0;
- dw_writel(dev, intr_mask, DW_IC_INTR_MASK);
+ regmap_write(dev->map, DW_IC_INTR_MASK, intr_mask);
}
static u8
@@ -371,10 +407,10 @@ static void
i2c_dw_read(struct dw_i2c_dev *dev)
{
struct i2c_msg *msgs = dev->msgs;
- int rx_valid;
+ unsigned int rx_valid;
for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) {
- u32 len;
+ u32 len, tmp;
u8 *buf;
if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD))
@@ -388,18 +424,18 @@ i2c_dw_read(struct dw_i2c_dev *dev)
buf = dev->rx_buf;
}
- rx_valid = dw_readl(dev, DW_IC_RXFLR);
+ regmap_read(dev->map, DW_IC_RXFLR, &rx_valid);
for (; len > 0 && rx_valid > 0; len--, rx_valid--) {
u32 flags = msgs[dev->msg_read_idx].flags;
- *buf = dw_readl(dev, DW_IC_DATA_CMD);
+ regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
/* Ensure length byte is a valid value */
if (flags & I2C_M_RECV_LEN &&
- *buf <= I2C_SMBUS_BLOCK_MAX && *buf > 0) {
- len = i2c_dw_recv_len(dev, *buf);
+ tmp <= I2C_SMBUS_BLOCK_MAX && tmp > 0) {
+ len = i2c_dw_recv_len(dev, tmp);
}
- buf++;
+ *buf++ = tmp;
dev->rx_outstanding--;
}
@@ -517,7 +553,7 @@ static const struct i2c_adapter_quirks i2c_dw_quirks = {
static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
{
- u32 stat;
+ u32 stat, dummy;
/*
* The IC_INTR_STAT register just indicates "enabled" interrupts.
@@ -525,47 +561,47 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
* in the IC_RAW_INTR_STAT register.
*
* That is,
- * stat = dw_readl(IC_INTR_STAT);
+ * stat = readl(IC_INTR_STAT);
* equals to,
- * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK);
+ * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK);
*
* The raw version might be useful for debugging purposes.
*/
- stat = dw_readl(dev, DW_IC_INTR_STAT);
+ regmap_read(dev->map, DW_IC_INTR_STAT, &stat);
/*
* Do not use the IC_CLR_INTR register to clear interrupts, or
* you'll miss some interrupts, triggered during the period from
- * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR).
+ * readl(IC_INTR_STAT) to readl(IC_CLR_INTR).
*
* Instead, use the separately-prepared IC_CLR_* registers.
*/
if (stat & DW_IC_INTR_RX_UNDER)
- dw_readl(dev, DW_IC_CLR_RX_UNDER);
+ regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &dummy);
if (stat & DW_IC_INTR_RX_OVER)
- dw_readl(dev, DW_IC_CLR_RX_OVER);
+ regmap_read(dev->map, DW_IC_CLR_RX_OVER, &dummy);
if (stat & DW_IC_INTR_TX_OVER)
- dw_readl(dev, DW_IC_CLR_TX_OVER);
+ regmap_read(dev->map, DW_IC_CLR_TX_OVER, &dummy);
if (stat & DW_IC_INTR_RD_REQ)
- dw_readl(dev, DW_IC_CLR_RD_REQ);
+ regmap_read(dev->map, DW_IC_CLR_RD_REQ, &dummy);
if (stat & DW_IC_INTR_TX_ABRT) {
/*
* The IC_TX_ABRT_SOURCE register is cleared whenever
* the IC_CLR_TX_ABRT is read. Preserve it beforehand.
*/
- dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE);
- dw_readl(dev, DW_IC_CLR_TX_ABRT);
+ regmap_read(dev->map, DW_IC_TX_ABRT_SOURCE, &dev->abort_source);
+ regmap_read(dev->map, DW_IC_CLR_TX_ABRT, &dummy);
}
if (stat & DW_IC_INTR_RX_DONE)
- dw_readl(dev, DW_IC_CLR_RX_DONE);
+ regmap_read(dev->map, DW_IC_CLR_RX_DONE, &dummy);
if (stat & DW_IC_INTR_ACTIVITY)
- dw_readl(dev, DW_IC_CLR_ACTIVITY);
+ regmap_read(dev->map, DW_IC_CLR_ACTIVITY, &dummy);
if (stat & DW_IC_INTR_STOP_DET)
- dw_readl(dev, DW_IC_CLR_STOP_DET);
+ regmap_read(dev->map, DW_IC_CLR_STOP_DET, &dummy);
if (stat & DW_IC_INTR_START_DET)
- dw_readl(dev, DW_IC_CLR_START_DET);
+ regmap_read(dev->map, DW_IC_CLR_START_DET, &dummy);
if (stat & DW_IC_INTR_GEN_CALL)
- dw_readl(dev, DW_IC_CLR_GEN_CALL);
+ regmap_read(dev->map, DW_IC_CLR_GEN_CALL, &dummy);
return stat;
}
@@ -587,7 +623,7 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
* Anytime TX_ABRT is set, the contents of the tx/rx
* buffers are flushed. Make sure to skip them.
*/
- dw_writel(dev, 0, DW_IC_INTR_MASK);
+ regmap_write(dev->map, DW_IC_INTR_MASK, 0);
goto tx_aborted;
}
@@ -608,9 +644,9 @@ tx_aborted:
complete(&dev->cmd_complete);
else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
/* Workaround to trigger pending interrupt */
- stat = dw_readl(dev, DW_IC_INTR_MASK);
+ regmap_read(dev->map, DW_IC_INTR_MASK, &stat);
i2c_dw_disable_int(dev);
- dw_writel(dev, stat, DW_IC_INTR_MASK);
+ regmap_write(dev->map, DW_IC_INTR_MASK, stat);
}
return 0;
@@ -621,8 +657,8 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
struct dw_i2c_dev *dev = dev_id;
u32 stat, enabled;
- enabled = dw_readl(dev, DW_IC_ENABLE);
- stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
+ regmap_read(dev->map, DW_IC_ENABLE, &enabled);
+ regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat);
dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat);
if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY))
return IRQ_NONE;
@@ -632,6 +668,30 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
return IRQ_HANDLED;
}
+void i2c_dw_configure_master(struct dw_i2c_dev *dev)
+{
+ struct i2c_timings *t = &dev->timings;
+
+ dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
+
+ dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
+ DW_IC_CON_RESTART_EN;
+
+ dev->mode = DW_IC_MASTER;
+
+ switch (t->bus_freq_hz) {
+ case I2C_MAX_STANDARD_MODE_FREQ:
+ dev->master_cfg |= DW_IC_CON_SPEED_STD;
+ break;
+ case I2C_MAX_HIGH_SPEED_MODE_FREQ:
+ dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
+ break;
+ default:
+ dev->master_cfg |= DW_IC_CON_SPEED_FAST;
+ }
+}
+EXPORT_SYMBOL_GPL(i2c_dw_configure_master);
+
static void i2c_dw_prepare_recovery(struct i2c_adapter *adap)
{
struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
@@ -678,7 +738,7 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev)
return 0;
}
-int i2c_dw_probe(struct dw_i2c_dev *dev)
+int i2c_dw_probe_master(struct dw_i2c_dev *dev)
{
struct i2c_adapter *adap = &dev->adapter;
unsigned long irq_flags;
@@ -690,7 +750,7 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
dev->disable = i2c_dw_disable;
dev->disable_int = i2c_dw_disable_int;
- ret = i2c_dw_set_reg_access(dev);
+ ret = i2c_dw_init_regmap(dev);
if (ret)
return ret;
@@ -698,7 +758,9 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
if (ret)
return ret;
- i2c_dw_set_fifo_size(dev);
+ ret = i2c_dw_set_fifo_size(dev);
+ if (ret)
+ return ret;
ret = dev->init(dev);
if (ret)
@@ -745,7 +807,7 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
return ret;
}
-EXPORT_SYMBOL_GPL(i2c_dw_probe);
+EXPORT_SYMBOL_GPL(i2c_dw_probe_master);
MODULE_DESCRIPTION("Synopsys DesignWare I2C bus master adapter");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 7a0b65b5b5b5..947c096f86e3 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -46,20 +46,12 @@ struct dw_scl_sda_cfg {
struct dw_pci_controller {
u32 bus_num;
- u32 bus_cfg;
- u32 tx_fifo_depth;
- u32 rx_fifo_depth;
- u32 clk_khz;
- u32 functionality;
u32 flags;
struct dw_scl_sda_cfg *scl_sda_cfg;
int (*setup)(struct pci_dev *pdev, struct dw_pci_controller *c);
+ u32 (*get_clk_rate_khz)(struct dw_i2c_dev *dev);
};
-#define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \
- DW_IC_CON_SLAVE_DISABLE | \
- DW_IC_CON_RESTART_EN)
-
/* Merrifield HCNT/LCNT/SDA hold time */
static struct dw_scl_sda_cfg mrfld_config = {
.ss_hcnt = 0x2f8,
@@ -86,12 +78,18 @@ static struct dw_scl_sda_cfg hsw_config = {
.sda_hold = 0x9,
};
+static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev)
+{
+ return 25000;
+}
+
static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
{
+ struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
+
switch (pdev->device) {
case 0x0817:
- c->bus_cfg &= ~DW_IC_CON_SPEED_MASK;
- c->bus_cfg |= DW_IC_CON_SPEED_STD;
+ dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
/* fall through */
case 0x0818:
case 0x0819:
@@ -125,57 +123,37 @@ static int mrfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
return -ENODEV;
}
+static u32 ehl_get_clk_rate_khz(struct dw_i2c_dev *dev)
+{
+ return 100000;
+}
+
static struct dw_pci_controller dw_pci_controllers[] = {
[medfield] = {
.bus_num = -1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .functionality = I2C_FUNC_10BIT_ADDR,
- .clk_khz = 25000,
.setup = mfld_setup,
+ .get_clk_rate_khz = mfld_get_clk_rate_khz,
},
[merrifield] = {
.bus_num = -1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 64,
- .rx_fifo_depth = 64,
- .functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &mrfld_config,
.setup = mrfld_setup,
},
[baytrail] = {
.bus_num = -1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &byt_config,
},
[haswell] = {
.bus_num = -1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .functionality = I2C_FUNC_10BIT_ADDR,
.scl_sda_cfg = &hsw_config,
},
[cherrytrail] = {
.bus_num = -1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .functionality = I2C_FUNC_10BIT_ADDR,
- .flags = MODEL_CHERRYTRAIL,
.scl_sda_cfg = &byt_config,
},
[elkhartlake] = {
.bus_num = -1,
- .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
- .tx_fifo_depth = 32,
- .rx_fifo_depth = 32,
- .functionality = I2C_FUNC_10BIT_ADDR,
- .clk_khz = 100000,
+ .get_clk_rate_khz = ehl_get_clk_rate_khz,
},
};
@@ -205,11 +183,6 @@ static int i2c_dw_pci_resume(struct device *dev)
static UNIVERSAL_DEV_PM_OPS(i2c_dw_pm_ops, i2c_dw_pci_suspend,
i2c_dw_pci_resume, NULL);
-static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
-{
- return dev->controller->clk_khz;
-}
-
static int i2c_dw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -250,14 +223,15 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
if (r < 0)
return r;
- dev->clk = NULL;
- dev->controller = controller;
- dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
+ dev->get_clk_rate_khz = controller->get_clk_rate_khz;
+ dev->timings.bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev;
dev->irq = pci_irq_vector(pdev, 0);
dev->flags |= controller->flags;
+ pci_set_drvdata(pdev, dev);
+
if (controller->setup) {
r = controller->setup(pdev, controller);
if (r) {
@@ -266,10 +240,19 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
}
}
- dev->functionality = controller->functionality |
- DW_IC_DEFAULT_FUNCTIONALITY;
+ i2c_dw_acpi_adjust_bus_speed(&pdev->dev);
+
+ if (has_acpi_companion(&pdev->dev))
+ i2c_dw_acpi_configure(&pdev->dev);
+
+ r = i2c_dw_validate_speed(dev);
+ if (r) {
+ pci_free_irq_vectors(pdev);
+ return r;
+ }
+
+ i2c_dw_configure(dev);
- dev->master_cfg = controller->bus_cfg;
if (controller->scl_sda_cfg) {
cfg = controller->scl_sda_cfg;
dev->ss_hcnt = cfg->ss_hcnt;
@@ -279,11 +262,6 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->sda_hold_time = cfg->sda_hold;
}
- pci_set_drvdata(pdev, dev);
-
- dev->tx_fifo_depth = controller->tx_fifo_depth;
- dev->rx_fifo_depth = controller->rx_fifo_depth;
-
adap = &dev->adapter;
adap->owner = THIS_MODULE;
adap->class = 0;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index c429d664f655..0de4e302fc6a 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -12,13 +12,13 @@
#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/delay.h>
-#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_data/i2c-designware.h>
@@ -26,6 +26,7 @@
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/sched.h>
#include <linux/slab.h>
@@ -39,91 +40,13 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
}
#ifdef CONFIG_ACPI
-/*
- * The HCNT/LCNT information coming from ACPI should be the most accurate
- * for given platform. However, some systems get it wrong. On such systems
- * we get better results by calculating those based on the input clock.
- */
-static const struct dmi_system_id dw_i2c_no_acpi_params[] = {
- {
- .ident = "Dell Inspiron 7348",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"),
- },
- },
- { }
-};
-
-static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
- u16 *hcnt, u16 *lcnt, u32 *sda_hold)
-{
- struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
- acpi_handle handle = ACPI_HANDLE(&pdev->dev);
- union acpi_object *obj;
-
- if (dmi_check_system(dw_i2c_no_acpi_params))
- return;
-
- if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
- return;
-
- obj = (union acpi_object *)buf.pointer;
- if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) {
- const union acpi_object *objs = obj->package.elements;
-
- *hcnt = (u16)objs[0].integer.value;
- *lcnt = (u16)objs[1].integer.value;
- *sda_hold = (u32)objs[2].integer.value;
- }
-
- kfree(buf.pointer);
-}
-
-static int dw_i2c_acpi_configure(struct platform_device *pdev)
-{
- struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
- struct i2c_timings *t = &dev->timings;
- u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
-
- dev->tx_fifo_depth = 32;
- dev->rx_fifo_depth = 32;
-
- /*
- * Try to get SDA hold time and *CNT values from an ACPI method for
- * selected speed modes.
- */
- dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht);
- dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht);
- dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
- dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);
-
- switch (t->bus_freq_hz) {
- case I2C_MAX_STANDARD_MODE_FREQ:
- dev->sda_hold_time = ss_ht;
- break;
- case I2C_MAX_FAST_MODE_PLUS_FREQ:
- dev->sda_hold_time = fp_ht;
- break;
- case I2C_MAX_HIGH_SPEED_MODE_FREQ:
- dev->sda_hold_time = hs_ht;
- break;
- case I2C_MAX_FAST_MODE_FREQ:
- default:
- dev->sda_hold_time = fs_ht;
- break;
- }
-
- return 0;
-}
-
static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT33C2", 0 },
{ "INT33C3", 0 },
{ "INT3432", 0 },
{ "INT3433", 0 },
{ "80860F41", ACCESS_NO_IRQ_SUSPEND },
- { "808622C1", ACCESS_NO_IRQ_SUSPEND | MODEL_CHERRYTRAIL },
+ { "808622C1", ACCESS_NO_IRQ_SUSPEND },
{ "AMD0010", ACCESS_INTR_MASK },
{ "AMDI0010", ACCESS_INTR_MASK },
{ "AMDI0510", 0 },
@@ -134,14 +57,66 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ }
};
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
-#else
-static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
-{
- return -ENODEV;
-}
#endif
#ifdef CONFIG_OF
+#define BT1_I2C_CTL 0x100
+#define BT1_I2C_CTL_ADDR_MASK GENMASK(7, 0)
+#define BT1_I2C_CTL_WR BIT(8)
+#define BT1_I2C_CTL_GO BIT(31)
+#define BT1_I2C_DI 0x104
+#define BT1_I2C_DO 0x108
+
+static int bt1_i2c_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct dw_i2c_dev *dev = context;
+ int ret;
+
+ /*
+ * Note these methods shouldn't ever fail because the system controller
+ * registers are memory mapped. We check the return value just in case.
+ */
+ ret = regmap_write(dev->sysmap, BT1_I2C_CTL,
+ BT1_I2C_CTL_GO | (reg & BT1_I2C_CTL_ADDR_MASK));
+ if (ret)
+ return ret;
+
+ return regmap_read(dev->sysmap, BT1_I2C_DO, val);
+}
+
+static int bt1_i2c_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct dw_i2c_dev *dev = context;
+ int ret;
+
+ ret = regmap_write(dev->sysmap, BT1_I2C_DI, val);
+ if (ret)
+ return ret;
+
+ return regmap_write(dev->sysmap, BT1_I2C_CTL,
+ BT1_I2C_CTL_GO | BT1_I2C_CTL_WR | (reg & BT1_I2C_CTL_ADDR_MASK));
+}
+
+static struct regmap_config bt1_i2c_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .fast_io = true,
+ .reg_read = bt1_i2c_read,
+ .reg_write = bt1_i2c_write,
+ .max_register = DW_IC_COMP_TYPE,
+};
+
+static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
+{
+ dev->sysmap = syscon_node_to_regmap(dev->dev->of_node->parent);
+ if (IS_ERR(dev->sysmap))
+ return PTR_ERR(dev->sysmap);
+
+ dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg);
+ return PTR_ERR_OR_ZERO(dev->map);
+}
+
#define MSCC_ICPU_CFG_TWI_DELAY 0x0
#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0)
#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4
@@ -157,12 +132,10 @@ static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
static int dw_i2c_of_configure(struct platform_device *pdev)
{
struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
- struct resource *mem;
switch (dev->flags & MODEL_MASK) {
case MODEL_MSCC_OCELOT:
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- dev->ext = devm_ioremap_resource(&pdev->dev, mem);
+ dev->ext = devm_platform_ioremap_resource(pdev, 1);
if (!IS_ERR(dev->ext))
dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
break;
@@ -176,48 +149,21 @@ static int dw_i2c_of_configure(struct platform_device *pdev)
static const struct of_device_id dw_i2c_of_match[] = {
{ .compatible = "snps,designware-i2c", },
{ .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
+ { .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 },
{},
};
MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
#else
-static inline int dw_i2c_of_configure(struct platform_device *pdev)
+static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
{
return -ENODEV;
}
-#endif
-
-static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
-{
- struct i2c_timings *t = &dev->timings;
-
- dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
-
- dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
- DW_IC_CON_RESTART_EN;
-
- dev->mode = DW_IC_MASTER;
-
- switch (t->bus_freq_hz) {
- case I2C_MAX_STANDARD_MODE_FREQ:
- dev->master_cfg |= DW_IC_CON_SPEED_STD;
- break;
- case I2C_MAX_HIGH_SPEED_MODE_FREQ:
- dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
- break;
- default:
- dev->master_cfg |= DW_IC_CON_SPEED_FAST;
- }
-}
-static void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
+static inline int dw_i2c_of_configure(struct platform_device *pdev)
{
- dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
-
- dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
- DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;
-
- dev->mode = DW_IC_SLAVE;
+ return -ENODEV;
}
+#endif
static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
{
@@ -227,12 +173,23 @@ static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
pm_runtime_put_noidle(dev->dev);
}
-static const u32 supported_speeds[] = {
- I2C_MAX_HIGH_SPEED_MODE_FREQ,
- I2C_MAX_FAST_MODE_PLUS_FREQ,
- I2C_MAX_FAST_MODE_FREQ,
- I2C_MAX_STANDARD_MODE_FREQ,
-};
+static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev->dev);
+ int ret;
+
+ switch (dev->flags & MODEL_MASK) {
+ case MODEL_BAIKAL_BT1:
+ ret = bt1_i2c_request_regs(dev);
+ break;
+ default:
+ dev->base = devm_platform_ioremap_resource(pdev, 0);
+ ret = PTR_ERR_OR_ZERO(dev->base);
+ break;
+ }
+
+ return ret;
+}
static int dw_i2c_plat_probe(struct platform_device *pdev)
{
@@ -240,9 +197,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
struct i2c_adapter *adap;
struct dw_i2c_dev *dev;
struct i2c_timings *t;
- u32 acpi_speed;
- struct resource *mem;
- int i, irq, ret;
+ int irq, ret;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
@@ -252,15 +207,15 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev->base = devm_ioremap_resource(&pdev->dev, mem);
- if (IS_ERR(dev->base))
- return PTR_ERR(dev->base);
-
+ dev->flags = (uintptr_t)device_get_match_data(&pdev->dev);
dev->dev = &pdev->dev;
dev->irq = irq;
platform_set_drvdata(pdev, dev);
+ ret = dw_i2c_plat_request_regs(dev);
+ if (ret)
+ return ret;
+
dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
if (IS_ERR(dev->rst))
return PTR_ERR(dev->rst);
@@ -273,60 +228,23 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
else
i2c_parse_fw_timings(&pdev->dev, t, false);
- acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
- /*
- * Some DSTDs use a non standard speed, round down to the lowest
- * standard speed.
- */
- for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) {
- if (acpi_speed >= supported_speeds[i])
- break;
- }
- acpi_speed = i < ARRAY_SIZE(supported_speeds) ? supported_speeds[i] : 0;
-
- /*
- * Find bus speed from the "clock-frequency" device property, ACPI
- * or by using fast mode if neither is set.
- */
- if (acpi_speed && t->bus_freq_hz)
- t->bus_freq_hz = min(t->bus_freq_hz, acpi_speed);
- else if (acpi_speed || t->bus_freq_hz)
- t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed);
- else
- t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
-
- dev->flags |= (uintptr_t)device_get_match_data(&pdev->dev);
+ i2c_dw_acpi_adjust_bus_speed(&pdev->dev);
if (pdev->dev.of_node)
dw_i2c_of_configure(pdev);
if (has_acpi_companion(&pdev->dev))
- dw_i2c_acpi_configure(pdev);
+ i2c_dw_acpi_configure(&pdev->dev);
- /*
- * Only standard mode at 100kHz, fast mode at 400kHz,
- * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
- */
- for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) {
- if (t->bus_freq_hz == supported_speeds[i])
- break;
- }
- if (i == ARRAY_SIZE(supported_speeds)) {
- dev_err(&pdev->dev,
- "%d Hz is unsupported, only 100kHz, 400kHz, 1MHz and 3.4MHz are supported\n",
- t->bus_freq_hz);
- ret = -EINVAL;
+ ret = i2c_dw_validate_speed(dev);
+ if (ret)
goto exit_reset;
- }
ret = i2c_dw_probe_lock_support(dev);
if (ret)
goto exit_reset;
- if (i2c_detect_slave_mode(&pdev->dev))
- i2c_dw_configure_slave(dev);
- else
- i2c_dw_configure_master(dev);
+ i2c_dw_configure(dev);
/* Optional interface clock */
dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
@@ -377,11 +295,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
- if (dev->mode == DW_IC_SLAVE)
- ret = i2c_dw_probe_slave(dev);
- else
- ret = i2c_dw_probe(dev);
-
+ ret = i2c_dw_probe(dev);
if (ret)
goto exit_probe;
diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c
index f5ecf76c0d02..44974b53a626 100644
--- a/drivers/i2c/busses/i2c-designware-slave.c
+++ b/drivers/i2c/busses/i2c-designware-slave.c
@@ -14,18 +14,19 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include "i2c-designware-core.h"
static void i2c_dw_configure_fifo_slave(struct dw_i2c_dev *dev)
{
/* Configure Tx/Rx FIFO threshold levels. */
- dw_writel(dev, 0, DW_IC_TX_TL);
- dw_writel(dev, 0, DW_IC_RX_TL);
+ regmap_write(dev->map, DW_IC_TX_TL, 0);
+ regmap_write(dev->map, DW_IC_RX_TL, 0);
/* Configure the I2C slave. */
- dw_writel(dev, dev->slave_cfg, DW_IC_CON);
- dw_writel(dev, DW_IC_INTR_SLAVE_MASK, DW_IC_INTR_MASK);
+ regmap_write(dev->map, DW_IC_CON, dev->slave_cfg);
+ regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_SLAVE_MASK);
}
/**
@@ -49,7 +50,7 @@ static int i2c_dw_init_slave(struct dw_i2c_dev *dev)
/* Write SDA hold time if supported */
if (dev->sda_hold_time)
- dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
+ regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time);
i2c_dw_configure_fifo_slave(dev);
i2c_dw_release_lock(dev);
@@ -72,7 +73,7 @@ static int i2c_dw_reg_slave(struct i2c_client *slave)
* the address to which the DW_apb_i2c responds.
*/
__i2c_dw_disable_nowait(dev);
- dw_writel(dev, slave->addr, DW_IC_SAR);
+ regmap_write(dev->map, DW_IC_SAR, slave->addr);
dev->slave = slave;
__i2c_dw_enable(dev);
@@ -103,7 +104,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave)
static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev)
{
- u32 stat;
+ u32 stat, dummy;
/*
* The IC_INTR_STAT register just indicates "enabled" interrupts.
@@ -111,39 +112,39 @@ static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev)
* in the IC_RAW_INTR_STAT register.
*
* That is,
- * stat = dw_readl(IC_INTR_STAT);
+ * stat = readl(IC_INTR_STAT);
* equals to,
- * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK);
+ * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK);
*
* The raw version might be useful for debugging purposes.
*/
- stat = dw_readl(dev, DW_IC_INTR_STAT);
+ regmap_read(dev->map, DW_IC_INTR_STAT, &stat);
/*
* Do not use the IC_CLR_INTR register to clear interrupts, or
* you'll miss some interrupts, triggered during the period from
- * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR).
+ * readl(IC_INTR_STAT) to readl(IC_CLR_INTR).
*
* Instead, use the separately-prepared IC_CLR_* registers.
*/
if (stat & DW_IC_INTR_TX_ABRT)
- dw_readl(dev, DW_IC_CLR_TX_ABRT);
+ regmap_read(dev->map, DW_IC_CLR_TX_ABRT, &dummy);
if (stat & DW_IC_INTR_RX_UNDER)
- dw_readl(dev, DW_IC_CLR_RX_UNDER);
+ regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &dummy);
if (stat & DW_IC_INTR_RX_OVER)
- dw_readl(dev, DW_IC_CLR_RX_OVER);
+ regmap_read(dev->map, DW_IC_CLR_RX_OVER, &dummy);
if (stat & DW_IC_INTR_TX_OVER)
- dw_readl(dev, DW_IC_CLR_TX_OVER);
+ regmap_read(dev->map, DW_IC_CLR_TX_OVER, &dummy);
if (stat & DW_IC_INTR_RX_DONE)
- dw_readl(dev, DW_IC_CLR_RX_DONE);
+ regmap_read(dev->map, DW_IC_CLR_RX_DONE, &dummy);
if (stat & DW_IC_INTR_ACTIVITY)
- dw_readl(dev, DW_IC_CLR_ACTIVITY);
+ regmap_read(dev->map, DW_IC_CLR_ACTIVITY, &dummy);
if (stat & DW_IC_INTR_STOP_DET)
- dw_readl(dev, DW_IC_CLR_STOP_DET);
+ regmap_read(dev->map, DW_IC_CLR_STOP_DET, &dummy);
if (stat & DW_IC_INTR_START_DET)
- dw_readl(dev, DW_IC_CLR_START_DET);
+ regmap_read(dev->map, DW_IC_CLR_START_DET, &dummy);
if (stat & DW_IC_INTR_GEN_CALL)
- dw_readl(dev, DW_IC_CLR_GEN_CALL);
+ regmap_read(dev->map, DW_IC_CLR_GEN_CALL, &dummy);
return stat;
}
@@ -155,14 +156,14 @@ static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev)
static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
{
- u32 raw_stat, stat, enabled;
- u8 val, slave_activity;
+ u32 raw_stat, stat, enabled, tmp;
+ u8 val = 0, slave_activity;
- stat = dw_readl(dev, DW_IC_INTR_STAT);
- enabled = dw_readl(dev, DW_IC_ENABLE);
- raw_stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
- slave_activity = ((dw_readl(dev, DW_IC_STATUS) &
- DW_IC_STATUS_SLAVE_ACTIVITY) >> 6);
+ regmap_read(dev->map, DW_IC_INTR_STAT, &stat);
+ regmap_read(dev->map, DW_IC_ENABLE, &enabled);
+ regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_stat);
+ regmap_read(dev->map, DW_IC_STATUS, &tmp);
+ slave_activity = ((tmp & DW_IC_STATUS_SLAVE_ACTIVITY) >> 6);
if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave)
return 0;
@@ -177,7 +178,8 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
if (stat & DW_IC_INTR_RD_REQ) {
if (slave_activity) {
if (stat & DW_IC_INTR_RX_FULL) {
- val = dw_readl(dev, DW_IC_DATA_CMD);
+ regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
+ val = tmp;
if (!i2c_slave_event(dev->slave,
I2C_SLAVE_WRITE_RECEIVED,
@@ -185,24 +187,24 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
dev_vdbg(dev->dev, "Byte %X acked!",
val);
}
- dw_readl(dev, DW_IC_CLR_RD_REQ);
+ regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp);
stat = i2c_dw_read_clear_intrbits_slave(dev);
} else {
- dw_readl(dev, DW_IC_CLR_RD_REQ);
- dw_readl(dev, DW_IC_CLR_RX_UNDER);
+ regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp);
+ regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &tmp);
stat = i2c_dw_read_clear_intrbits_slave(dev);
}
if (!i2c_slave_event(dev->slave,
I2C_SLAVE_READ_REQUESTED,
&val))
- dw_writel(dev, val, DW_IC_DATA_CMD);
+ regmap_write(dev->map, DW_IC_DATA_CMD, val);
}
}
if (stat & DW_IC_INTR_RX_DONE) {
if (!i2c_slave_event(dev->slave, I2C_SLAVE_READ_PROCESSED,
&val))
- dw_readl(dev, DW_IC_CLR_RX_DONE);
+ regmap_read(dev->map, DW_IC_CLR_RX_DONE, &tmp);
i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val);
stat = i2c_dw_read_clear_intrbits_slave(dev);
@@ -210,7 +212,8 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
}
if (stat & DW_IC_INTR_RX_FULL) {
- val = dw_readl(dev, DW_IC_DATA_CMD);
+ regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
+ val = tmp;
if (!i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED,
&val))
dev_vdbg(dev->dev, "Byte %X acked!", val);
@@ -241,6 +244,17 @@ static const struct i2c_algorithm i2c_dw_algo = {
.unreg_slave = i2c_dw_unreg_slave,
};
+void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
+{
+ dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
+
+ dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
+ DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;
+
+ dev->mode = DW_IC_SLAVE;
+}
+EXPORT_SYMBOL_GPL(i2c_dw_configure_slave);
+
int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
{
struct i2c_adapter *adap = &dev->adapter;
@@ -252,7 +266,7 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
dev->disable = i2c_dw_disable;
dev->disable_int = i2c_dw_disable_int;
- ret = i2c_dw_set_reg_access(dev);
+ ret = i2c_dw_init_regmap(dev);
if (ret)
return ret;
@@ -260,7 +274,9 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
if (ret)
return ret;
- i2c_dw_set_fifo_size(dev);
+ ret = i2c_dw_set_fifo_size(dev);
+ if (ret)
+ return ret;
ret = dev->init(dev);
if (ret)
diff --git a/drivers/i2c/busses/i2c-digicolor.c b/drivers/i2c/busses/i2c-digicolor.c
index 056a5c4f0833..332f00437479 100644
--- a/drivers/i2c/busses/i2c-digicolor.c
+++ b/drivers/i2c/busses/i2c-digicolor.c
@@ -290,7 +290,6 @@ static int dc_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct dc_i2c *i2c;
- struct resource *r;
int ret = 0, irq;
i2c = devm_kzalloc(&pdev->dev, sizeof(struct dc_i2c), GFP_KERNEL);
@@ -311,8 +310,7 @@ static int dc_i2c_probe(struct platform_device *pdev)
if (IS_ERR(i2c->clk))
return PTR_ERR(i2c->clk);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->regs = devm_ioremap_resource(&pdev->dev, r);
+ i2c->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);
diff --git a/drivers/i2c/busses/i2c-efm32.c b/drivers/i2c/busses/i2c-efm32.c
index 18cca8f56da8..838ce0947191 100644
--- a/drivers/i2c/busses/i2c-efm32.c
+++ b/drivers/i2c/busses/i2c-efm32.c
@@ -312,9 +312,6 @@ static int efm32_i2c_probe(struct platform_device *pdev)
int ret;
u32 clkdiv;
- if (!np)
- return -EINVAL;
-
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
@@ -352,7 +349,6 @@ static int efm32_i2c_probe(struct platform_device *pdev)
ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
- dev_err(&pdev->dev, "failed to get irq (%d)\n", ret);
if (!ret)
ret = -EINVAL;
return ret;
diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c
index 959d4912ec0d..1a319352e51b 100644
--- a/drivers/i2c/busses/i2c-emev2.c
+++ b/drivers/i2c/busses/i2c-emev2.c
@@ -361,15 +361,13 @@ static const struct i2c_algorithm em_i2c_algo = {
static int em_i2c_probe(struct platform_device *pdev)
{
struct em_i2c_device *priv;
- struct resource *r;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->base = devm_ioremap_resource(&pdev->dev, r);
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index 527030953ba1..6ce3ec03b595 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -736,7 +736,6 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct exynos5_i2c *i2c;
- struct resource *mem;
int ret;
i2c = devm_kzalloc(&pdev->dev, sizeof(struct exynos5_i2c), GFP_KERNEL);
@@ -762,8 +761,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
if (ret)
return ret;
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+ i2c->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->regs)) {
ret = PTR_ERR(i2c->regs);
goto err_clk;
@@ -879,6 +877,6 @@ static struct platform_driver exynos5_i2c_driver = {
module_platform_driver(exynos5_i2c_driver);
MODULE_DESCRIPTION("Exynos5 HS-I2C Bus driver");
-MODULE_AUTHOR("Naveen Krishna Chatradhi, <ch.naveen@samsung.com>");
-MODULE_AUTHOR("Taekgyun Ko, <taeggyun.ko@samsung.com>");
+MODULE_AUTHOR("Naveen Krishna Chatradhi <ch.naveen@samsung.com>");
+MODULE_AUTHOR("Taekgyun Ko <taeggyun.ko@samsung.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c
index 6610304b6dc6..ab15b1ec2ab3 100644
--- a/drivers/i2c/busses/i2c-hix5hd2.c
+++ b/drivers/i2c/busses/i2c-hix5hd2.c
@@ -388,7 +388,6 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct hix5hd2_i2c_priv *priv;
- struct resource *mem;
unsigned int freq;
int irq, ret;
@@ -409,8 +408,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
}
}
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(&pdev->dev, mem);
+ priv->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 4f333889489c..fea644921a76 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -1318,6 +1318,12 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
if (is_dell_system_with_lis3lv02d())
register_dell_lis3lv02d_i2c_device(priv);
+
+ /* Instantiate SPD EEPROMs unless the SMBus is multiplexed */
+#if IS_ENABLED(CONFIG_I2C_MUX_GPIO)
+ if (!priv->mux_drvdata)
+#endif
+ i2c_register_spd(&priv->adapter);
}
#else
static void __init input_apanel_init(void) {}
diff --git a/drivers/i2c/busses/i2c-icy.c b/drivers/i2c/busses/i2c-icy.c
index 271470f4d8a9..66c9923fc766 100644
--- a/drivers/i2c/busses/i2c-icy.c
+++ b/drivers/i2c/busses/i2c-icy.c
@@ -43,6 +43,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-pcf.h>
+#include <asm/amigahw.h>
#include <asm/amigaints.h>
#include <linux/zorro.h>
diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c
index 422097a31c95..98a89301ed2a 100644
--- a/drivers/i2c/busses/i2c-img-scb.c
+++ b/drivers/i2c/busses/i2c-img-scb.c
@@ -1330,7 +1330,6 @@ static int img_i2c_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct img_i2c *i2c;
- struct resource *res;
int irq, ret;
u32 val;
@@ -1338,16 +1337,13 @@ static int img_i2c_probe(struct platform_device *pdev)
if (!i2c)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->base = devm_ioremap_resource(&pdev->dev, res);
+ i2c->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->base))
return PTR_ERR(i2c->base);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "can't get irq number\n");
+ if (irq < 0)
return irq;
- }
i2c->sys_clk = devm_clk_get(&pdev->dev, "sys");
if (IS_ERR(i2c->sys_clk)) {
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index 94743ba581fe..9db6ccded5e9 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -551,10 +551,8 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
return PTR_ERR(lpi2c_imx->base);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "can't get irq number\n");
+ if (irq < 0)
return irq;
- }
lpi2c_imx->adapter.owner = THIS_MODULE;
lpi2c_imx->adapter.algo = &lpi2c_imx_algo;
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
index b426fc956938..ba831df6661e 100644
--- a/drivers/i2c/busses/i2c-jz4780.c
+++ b/drivers/i2c/busses/i2c-jz4780.c
@@ -763,7 +763,6 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
int ret = 0;
unsigned int clk_freq = 0;
unsigned short tmp;
- struct resource *r;
struct jz4780_i2c *i2c;
i2c = devm_kzalloc(&pdev->dev, sizeof(struct jz4780_i2c), GFP_KERNEL);
@@ -787,8 +786,7 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
init_completion(&i2c->trans_waitq);
spin_lock_init(&i2c->lock);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->iomem = devm_ioremap_resource(&pdev->dev, r);
+ i2c->iomem = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->iomem))
return PTR_ERR(i2c->iomem);
diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c
index 13b0c12e2dba..4e30c5267142 100644
--- a/drivers/i2c/busses/i2c-lpc2k.c
+++ b/drivers/i2c/busses/i2c-lpc2k.c
@@ -346,7 +346,6 @@ static const struct i2c_algorithm i2c_lpc2k_algorithm = {
static int i2c_lpc2k_probe(struct platform_device *pdev)
{
struct lpc2k_i2c *i2c;
- struct resource *res;
u32 bus_clk_rate;
u32 scl_high;
u32 clkrate;
@@ -356,16 +355,13 @@ static int i2c_lpc2k_probe(struct platform_device *pdev)
if (!i2c)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->base = devm_ioremap_resource(&pdev->dev, res);
+ i2c->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->base))
return PTR_ERR(i2c->base);
i2c->irq = platform_get_irq(pdev, 0);
- if (i2c->irq < 0) {
- dev_err(&pdev->dev, "can't get interrupt resource\n");
+ if (i2c->irq < 0)
return i2c->irq;
- }
init_waitqueue_head(&i2c->wait);
diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c
index 06b3bed78421..c5dec572fc48 100644
--- a/drivers/i2c/busses/i2c-meson.c
+++ b/drivers/i2c/busses/i2c-meson.c
@@ -397,7 +397,6 @@ static int meson_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct meson_i2c *i2c;
- struct resource *mem;
struct i2c_timings timings;
int irq, ret = 0;
@@ -422,16 +421,13 @@ static int meson_i2c_probe(struct platform_device *pdev)
return PTR_ERR(i2c->clk);
}
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+ i2c->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "can't find IRQ\n");
+ if (irq < 0)
return irq;
- }
ret = devm_request_irq(&pdev->dev, irq, meson_i2c_irq, 0, NULL, i2c);
if (ret < 0) {
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 0ca6c38a15eb..deef69e56906 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -40,12 +40,11 @@
#define I2C_SOFT_RST 0x0001
#define I2C_FIFO_ADDR_CLR 0x0001
#define I2C_DELAY_LEN 0x0002
-#define I2C_ST_START_CON 0x8001
-#define I2C_FS_START_CON 0x1800
#define I2C_TIME_CLR_VALUE 0x0000
#define I2C_TIME_DEFAULT_VALUE 0x0003
#define I2C_WRRD_TRANAC_VALUE 0x0002
#define I2C_RD_TRANAC_VALUE 0x0001
+#define I2C_SCL_MIS_COMP_VALUE 0x0000
#define I2C_DMA_CON_TX 0x0000
#define I2C_DMA_CON_RX 0x0001
@@ -55,10 +54,13 @@
#define I2C_DMA_HARD_RST 0x0002
#define I2C_DMA_4G_MODE 0x0001
-#define I2C_DEFAULT_CLK_DIV 5
#define MAX_SAMPLE_CNT_DIV 8
#define MAX_STEP_CNT_DIV 64
+#define MAX_CLOCK_DIV 256
#define MAX_HS_STEP_CNT_DIV 8
+#define I2C_STANDARD_MODE_BUFFER (1000 / 2)
+#define I2C_FAST_MODE_BUFFER (300 / 2)
+#define I2C_FAST_MODE_PLUS_BUFFER (20 / 2)
#define I2C_CONTROL_RS (0x1 << 1)
#define I2C_CONTROL_DMA_EN (0x1 << 2)
@@ -123,6 +125,12 @@ enum I2C_REGS_OFFSET {
OFFSET_TRANSFER_LEN_AUX,
OFFSET_CLOCK_DIV,
OFFSET_LTIMING,
+ OFFSET_SCL_HIGH_LOW_RATIO,
+ OFFSET_HS_SCL_HIGH_LOW_RATIO,
+ OFFSET_SCL_MIS_COMP_POINT,
+ OFFSET_STA_STO_AC_TIMING,
+ OFFSET_HS_STA_STO_AC_TIMING,
+ OFFSET_SDA_TIMING,
};
static const u16 mt_i2c_regs_v1[] = {
@@ -150,6 +158,12 @@ static const u16 mt_i2c_regs_v1[] = {
[OFFSET_DEBUGCTRL] = 0x68,
[OFFSET_TRANSFER_LEN_AUX] = 0x6c,
[OFFSET_CLOCK_DIV] = 0x70,
+ [OFFSET_SCL_HIGH_LOW_RATIO] = 0x74,
+ [OFFSET_HS_SCL_HIGH_LOW_RATIO] = 0x78,
+ [OFFSET_SCL_MIS_COMP_POINT] = 0x7C,
+ [OFFSET_STA_STO_AC_TIMING] = 0x80,
+ [OFFSET_HS_STA_STO_AC_TIMING] = 0x84,
+ [OFFSET_SDA_TIMING] = 0x88,
};
static const u16 mt_i2c_regs_v2[] = {
@@ -168,9 +182,11 @@ static const u16 mt_i2c_regs_v2[] = {
[OFFSET_HS] = 0x30,
[OFFSET_IO_CONFIG] = 0x34,
[OFFSET_FIFO_ADDR_CLR] = 0x38,
+ [OFFSET_SDA_TIMING] = 0x3c,
[OFFSET_TRANSFER_LEN_AUX] = 0x44,
[OFFSET_CLOCK_DIV] = 0x48,
[OFFSET_SOFTRESET] = 0x50,
+ [OFFSET_SCL_MIS_COMP_POINT] = 0x90,
[OFFSET_DEBUGSTAT] = 0xe0,
[OFFSET_DEBUGCTRL] = 0xe8,
[OFFSET_FIFO_STAT] = 0xf4,
@@ -191,6 +207,19 @@ struct mtk_i2c_compatible {
unsigned char ltiming_adjust: 1;
};
+struct mtk_i2c_ac_timing {
+ u16 htiming;
+ u16 ltiming;
+ u16 hs;
+ u16 ext;
+ u16 inter_clk_div;
+ u16 scl_hl_ratio;
+ u16 hs_scl_hl_ratio;
+ u16 sta_stop;
+ u16 hs_sta_stop;
+ u16 sda_timing;
+};
+
struct mtk_i2c {
struct i2c_adapter adap; /* i2c host adapter */
struct device *dev;
@@ -215,9 +244,46 @@ struct mtk_i2c {
u16 ltiming_reg;
unsigned char auto_restart;
bool ignore_restart_irq;
+ struct mtk_i2c_ac_timing ac_timing;
const struct mtk_i2c_compatible *dev_comp;
};
+/**
+ * struct i2c_spec_values:
+ * min_low_ns: min LOW period of the SCL clock
+ * min_su_sta_ns: min set-up time for a repeated START condition
+ * max_hd_dat_ns: max data hold time
+ * min_su_dat_ns: min data set-up time
+ */
+struct i2c_spec_values {
+ unsigned int min_low_ns;
+ unsigned int min_high_ns;
+ unsigned int min_su_sta_ns;
+ unsigned int max_hd_dat_ns;
+ unsigned int min_su_dat_ns;
+};
+
+static const struct i2c_spec_values standard_mode_spec = {
+ .min_low_ns = 4700 + I2C_STANDARD_MODE_BUFFER,
+ .min_su_sta_ns = 4700 + I2C_STANDARD_MODE_BUFFER,
+ .max_hd_dat_ns = 3450 - I2C_STANDARD_MODE_BUFFER,
+ .min_su_dat_ns = 250 + I2C_STANDARD_MODE_BUFFER,
+};
+
+static const struct i2c_spec_values fast_mode_spec = {
+ .min_low_ns = 1300 + I2C_FAST_MODE_BUFFER,
+ .min_su_sta_ns = 600 + I2C_FAST_MODE_BUFFER,
+ .max_hd_dat_ns = 900 - I2C_FAST_MODE_BUFFER,
+ .min_su_dat_ns = 100 + I2C_FAST_MODE_BUFFER,
+};
+
+static const struct i2c_spec_values fast_mode_plus_spec = {
+ .min_low_ns = 500 + I2C_FAST_MODE_PLUS_BUFFER,
+ .min_su_sta_ns = 260 + I2C_FAST_MODE_PLUS_BUFFER,
+ .max_hd_dat_ns = 400 - I2C_FAST_MODE_PLUS_BUFFER,
+ .min_su_dat_ns = 50 + I2C_FAST_MODE_PLUS_BUFFER,
+};
+
static const struct i2c_adapter_quirks mt6577_i2c_quirks = {
.flags = I2C_AQ_COMB_WRITE_THEN_READ,
.max_num_msgs = 1,
@@ -397,14 +463,38 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
if (i2c->dev_comp->dcm)
mtk_i2c_writew(i2c, I2C_DCM_DISABLE, OFFSET_DCM_EN);
- if (i2c->dev_comp->timing_adjust)
- mtk_i2c_writew(i2c, I2C_DEFAULT_CLK_DIV - 1, OFFSET_CLOCK_DIV);
-
mtk_i2c_writew(i2c, i2c->timing_reg, OFFSET_TIMING);
mtk_i2c_writew(i2c, i2c->high_speed_reg, OFFSET_HS);
if (i2c->dev_comp->ltiming_adjust)
mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING);
+ if (i2c->dev_comp->timing_adjust) {
+ mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF);
+ mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
+ OFFSET_CLOCK_DIV);
+ mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE,
+ OFFSET_SCL_MIS_COMP_POINT);
+ mtk_i2c_writew(i2c, i2c->ac_timing.sda_timing,
+ OFFSET_SDA_TIMING);
+
+ if (i2c->dev_comp->ltiming_adjust) {
+ mtk_i2c_writew(i2c, i2c->ac_timing.htiming,
+ OFFSET_TIMING);
+ mtk_i2c_writew(i2c, i2c->ac_timing.hs, OFFSET_HS);
+ mtk_i2c_writew(i2c, i2c->ac_timing.ltiming,
+ OFFSET_LTIMING);
+ } else {
+ mtk_i2c_writew(i2c, i2c->ac_timing.scl_hl_ratio,
+ OFFSET_SCL_HIGH_LOW_RATIO);
+ mtk_i2c_writew(i2c, i2c->ac_timing.hs_scl_hl_ratio,
+ OFFSET_HS_SCL_HIGH_LOW_RATIO);
+ mtk_i2c_writew(i2c, i2c->ac_timing.sta_stop,
+ OFFSET_STA_STO_AC_TIMING);
+ mtk_i2c_writew(i2c, i2c->ac_timing.hs_sta_stop,
+ OFFSET_HS_STA_STO_AC_TIMING);
+ }
+ }
+
/* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
if (i2c->have_pmic)
mtk_i2c_writew(i2c, I2C_CONTROL_WRAPPER, OFFSET_PATH_DIR);
@@ -422,6 +512,126 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
}
+static const struct i2c_spec_values *mtk_i2c_get_spec(unsigned int speed)
+{
+ if (speed <= I2C_MAX_STANDARD_MODE_FREQ)
+ return &standard_mode_spec;
+ else if (speed <= I2C_MAX_FAST_MODE_FREQ)
+ return &fast_mode_spec;
+ else
+ return &fast_mode_plus_spec;
+}
+
+static int mtk_i2c_max_step_cnt(unsigned int target_speed)
+{
+ if (target_speed > I2C_MAX_FAST_MODE_FREQ)
+ return MAX_HS_STEP_CNT_DIV;
+ else
+ return MAX_STEP_CNT_DIV;
+}
+
+/*
+ * Check and Calculate i2c ac-timing
+ *
+ * Hardware design:
+ * sample_ns = (1000000000 * (sample_cnt + 1)) / clk_src
+ * xxx_cnt_div = spec->min_xxx_ns / sample_ns
+ *
+ * Sample_ns is rounded down for xxx_cnt_div would be greater
+ * than the smallest spec.
+ * The sda_timing is chosen as the middle value between
+ * the largest and smallest.
+ */
+static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c,
+ unsigned int clk_src,
+ unsigned int check_speed,
+ unsigned int step_cnt,
+ unsigned int sample_cnt)
+{
+ const struct i2c_spec_values *spec;
+ unsigned int su_sta_cnt, low_cnt, high_cnt, max_step_cnt;
+ unsigned int sda_max, sda_min, clk_ns, max_sta_cnt = 0x3f;
+ unsigned int sample_ns = div_u64(1000000000ULL * (sample_cnt + 1),
+ clk_src);
+
+ if (!i2c->dev_comp->timing_adjust)
+ return 0;
+
+ if (i2c->dev_comp->ltiming_adjust)
+ max_sta_cnt = 0x100;
+
+ spec = mtk_i2c_get_spec(check_speed);
+
+ if (i2c->dev_comp->ltiming_adjust)
+ clk_ns = 1000000000 / clk_src;
+ else
+ clk_ns = sample_ns / 2;
+
+ su_sta_cnt = DIV_ROUND_UP(spec->min_su_sta_ns, clk_ns);
+ if (su_sta_cnt > max_sta_cnt)
+ return -1;
+
+ low_cnt = DIV_ROUND_UP(spec->min_low_ns, sample_ns);
+ max_step_cnt = mtk_i2c_max_step_cnt(check_speed);
+ if ((2 * step_cnt) > low_cnt && low_cnt < max_step_cnt) {
+ if (low_cnt > step_cnt) {
+ high_cnt = 2 * step_cnt - low_cnt;
+ } else {
+ high_cnt = step_cnt;
+ low_cnt = step_cnt;
+ }
+ } else {
+ return -2;
+ }
+
+ sda_max = spec->max_hd_dat_ns / sample_ns;
+ if (sda_max > low_cnt)
+ sda_max = 0;
+
+ sda_min = DIV_ROUND_UP(spec->min_su_dat_ns, sample_ns);
+ if (sda_min < low_cnt)
+ sda_min = 0;
+
+ if (sda_min > sda_max)
+ return -3;
+
+ if (check_speed > I2C_MAX_FAST_MODE_FREQ) {
+ if (i2c->dev_comp->ltiming_adjust) {
+ i2c->ac_timing.hs = I2C_TIME_DEFAULT_VALUE |
+ (sample_cnt << 12) | (high_cnt << 8);
+ i2c->ac_timing.ltiming &= ~GENMASK(15, 9);
+ i2c->ac_timing.ltiming |= (sample_cnt << 12) |
+ (low_cnt << 9);
+ i2c->ac_timing.ext &= ~GENMASK(7, 1);
+ i2c->ac_timing.ext |= (su_sta_cnt << 1) | (1 << 0);
+ } else {
+ i2c->ac_timing.hs_scl_hl_ratio = (1 << 12) |
+ (high_cnt << 6) | low_cnt;
+ i2c->ac_timing.hs_sta_stop = (su_sta_cnt << 8) |
+ su_sta_cnt;
+ }
+ i2c->ac_timing.sda_timing &= ~GENMASK(11, 6);
+ i2c->ac_timing.sda_timing |= (1 << 12) |
+ ((sda_max + sda_min) / 2) << 6;
+ } else {
+ if (i2c->dev_comp->ltiming_adjust) {
+ i2c->ac_timing.htiming = (sample_cnt << 8) | (high_cnt);
+ i2c->ac_timing.ltiming = (sample_cnt << 6) | (low_cnt);
+ i2c->ac_timing.ext = (su_sta_cnt << 8) | (1 << 0);
+ } else {
+ i2c->ac_timing.scl_hl_ratio = (1 << 12) |
+ (high_cnt << 6) | low_cnt;
+ i2c->ac_timing.sta_stop = (su_sta_cnt << 8) |
+ su_sta_cnt;
+ }
+
+ i2c->ac_timing.sda_timing = (1 << 12) |
+ (sda_max + sda_min) / 2;
+ }
+
+ return 0;
+}
+
/*
* Calculate i2c port speed
*
@@ -446,15 +656,12 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
unsigned int opt_div;
unsigned int best_mul;
unsigned int cnt_mul;
+ int ret = -EINVAL;
if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ)
target_speed = I2C_MAX_FAST_MODE_PLUS_FREQ;
- if (target_speed > I2C_MAX_FAST_MODE_FREQ)
- max_step_cnt = MAX_HS_STEP_CNT_DIV;
- else
- max_step_cnt = MAX_STEP_CNT_DIV;
-
+ max_step_cnt = mtk_i2c_max_step_cnt(target_speed);
base_step_cnt = max_step_cnt;
/* Find the best combination */
opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
@@ -473,6 +680,11 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
continue;
if (cnt_mul < best_mul) {
+ ret = mtk_i2c_check_ac_timing(i2c, clk_src,
+ target_speed, step_cnt - 1, sample_cnt - 1);
+ if (ret)
+ continue;
+
best_mul = cnt_mul;
base_sample_cnt = sample_cnt;
base_step_cnt = step_cnt;
@@ -481,6 +693,9 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
}
}
+ if (ret)
+ return -EINVAL;
+
sample_cnt = base_sample_cnt;
step_cnt = base_step_cnt;
@@ -506,47 +721,68 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
unsigned int l_step_cnt;
unsigned int l_sample_cnt;
unsigned int target_speed;
+ unsigned int clk_div;
+ unsigned int max_clk_div;
int ret;
- clk_src = parent_clk / i2c->clk_src_div;
target_speed = i2c->speed_hz;
+ parent_clk /= i2c->clk_src_div;
- if (target_speed > I2C_MAX_FAST_MODE_FREQ) {
- /* Set master code speed register */
- ret = mtk_i2c_calculate_speed(i2c, clk_src, I2C_MAX_FAST_MODE_FREQ,
- &l_step_cnt, &l_sample_cnt);
- if (ret < 0)
- return ret;
-
- i2c->timing_reg = (l_sample_cnt << 8) | l_step_cnt;
-
- /* Set the high speed mode register */
- ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
- &step_cnt, &sample_cnt);
- if (ret < 0)
- return ret;
-
- i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE |
- (sample_cnt << 12) | (step_cnt << 8);
+ if (i2c->dev_comp->timing_adjust)
+ max_clk_div = MAX_CLOCK_DIV;
+ else
+ max_clk_div = 1;
+
+ for (clk_div = 1; clk_div <= max_clk_div; clk_div++) {
+ clk_src = parent_clk / clk_div;
+
+ if (target_speed > I2C_MAX_FAST_MODE_FREQ) {
+ /* Set master code speed register */
+ ret = mtk_i2c_calculate_speed(i2c, clk_src,
+ I2C_MAX_FAST_MODE_FREQ,
+ &l_step_cnt,
+ &l_sample_cnt);
+ if (ret < 0)
+ continue;
+
+ i2c->timing_reg = (l_sample_cnt << 8) | l_step_cnt;
+
+ /* Set the high speed mode register */
+ ret = mtk_i2c_calculate_speed(i2c, clk_src,
+ target_speed, &step_cnt,
+ &sample_cnt);
+ if (ret < 0)
+ continue;
+
+ i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE |
+ (sample_cnt << 12) | (step_cnt << 8);
+
+ if (i2c->dev_comp->ltiming_adjust)
+ i2c->ltiming_reg =
+ (l_sample_cnt << 6) | l_step_cnt |
+ (sample_cnt << 12) | (step_cnt << 9);
+ } else {
+ ret = mtk_i2c_calculate_speed(i2c, clk_src,
+ target_speed, &l_step_cnt,
+ &l_sample_cnt);
+ if (ret < 0)
+ continue;
- if (i2c->dev_comp->ltiming_adjust)
- i2c->ltiming_reg = (l_sample_cnt << 6) | l_step_cnt |
- (sample_cnt << 12) | (step_cnt << 9);
- } else {
- ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
- &step_cnt, &sample_cnt);
- if (ret < 0)
- return ret;
+ i2c->timing_reg = (l_sample_cnt << 8) | l_step_cnt;
- i2c->timing_reg = (sample_cnt << 8) | step_cnt;
+ /* Disable the high speed transaction */
+ i2c->high_speed_reg = I2C_TIME_CLR_VALUE;
- /* Disable the high speed transaction */
- i2c->high_speed_reg = I2C_TIME_CLR_VALUE;
+ if (i2c->dev_comp->ltiming_adjust)
+ i2c->ltiming_reg =
+ (l_sample_cnt << 6) | l_step_cnt;
+ }
- if (i2c->dev_comp->ltiming_adjust)
- i2c->ltiming_reg = (sample_cnt << 6) | step_cnt;
+ break;
}
+ i2c->ac_timing.inter_clk_div = clk_div - 1;
+
return 0;
}
@@ -586,12 +822,6 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
mtk_i2c_writew(i2c, control_reg, OFFSET_CONTROL);
- /* set start condition */
- if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ)
- mtk_i2c_writew(i2c, I2C_ST_START_CON, OFFSET_EXT_CONF);
- else
- mtk_i2c_writew(i2c, I2C_FS_START_CON, OFFSET_EXT_CONF);
-
addr_reg = i2c_8bit_addr_from_msg(msgs);
mtk_i2c_writew(i2c, addr_reg, OFFSET_SLAVE_ADDR);
@@ -948,9 +1178,6 @@ static int mtk_i2c_probe(struct platform_device *pdev)
if (ret)
return -EINVAL;
- if (i2c->dev_comp->timing_adjust)
- i2c->clk_src_div *= I2C_DEFAULT_CLK_DIV;
-
if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
return -EINVAL;
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 9b8f1d8552ea..829b8c98ae51 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -877,7 +877,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
{
struct mv64xxx_i2c_data *drv_data;
struct mv64xxx_i2c_pdata *pdata = dev_get_platdata(&pd->dev);
- struct resource *r;
int rc;
if ((!pdata && !pd->dev.of_node))
@@ -888,8 +887,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
if (!drv_data)
return -ENOMEM;
- r = platform_get_resource(pd, IORESOURCE_MEM, 0);
- drv_data->reg_base = devm_ioremap_resource(&pd->dev, r);
+ drv_data->reg_base = devm_platform_ioremap_resource(pd, 0);
if (IS_ERR(drv_data->reg_base))
return PTR_ERR(drv_data->reg_base);
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
new file mode 100644
index 000000000000..75f07138a6fa
--- /dev/null
+++ b/drivers/i2c/busses/i2c-npcm7xx.c
@@ -0,0 +1,2342 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Nuvoton NPCM7xx I2C Controller driver
+ *
+ * Copyright (C) 2020 Nuvoton Technologies tali.perry@nuvoton.com
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+enum i2c_mode {
+ I2C_MASTER,
+ I2C_SLAVE,
+};
+
+/*
+ * External I2C Interface driver xfer indication values, which indicate status
+ * of the bus.
+ */
+enum i2c_state_ind {
+ I2C_NO_STATUS_IND = 0,
+ I2C_SLAVE_RCV_IND,
+ I2C_SLAVE_XMIT_IND,
+ I2C_SLAVE_XMIT_MISSING_DATA_IND,
+ I2C_SLAVE_RESTART_IND,
+ I2C_SLAVE_DONE_IND,
+ I2C_MASTER_DONE_IND,
+ I2C_NACK_IND,
+ I2C_BUS_ERR_IND,
+ I2C_WAKE_UP_IND,
+ I2C_BLOCK_BYTES_ERR_IND,
+ I2C_SLAVE_RCV_MISSING_DATA_IND,
+};
+
+/*
+ * Operation type values (used to define the operation currently running)
+ * module is interrupt driven, on each interrupt the current operation is
+ * checked to see if the module is currently reading or writing.
+ */
+enum i2c_oper {
+ I2C_NO_OPER = 0,
+ I2C_WRITE_OPER,
+ I2C_READ_OPER,
+};
+
+/* I2C Bank (module had 2 banks of registers) */
+enum i2c_bank {
+ I2C_BANK_0 = 0,
+ I2C_BANK_1,
+};
+
+/* Internal I2C states values (for the I2C module state machine). */
+enum i2c_state {
+ I2C_DISABLE = 0,
+ I2C_IDLE,
+ I2C_MASTER_START,
+ I2C_SLAVE_MATCH,
+ I2C_OPER_STARTED,
+ I2C_STOP_PENDING,
+};
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+/* Module supports setting multiple own slave addresses */
+enum i2c_addr {
+ I2C_SLAVE_ADDR1 = 0,
+ I2C_SLAVE_ADDR2,
+ I2C_SLAVE_ADDR3,
+ I2C_SLAVE_ADDR4,
+ I2C_SLAVE_ADDR5,
+ I2C_SLAVE_ADDR6,
+ I2C_SLAVE_ADDR7,
+ I2C_SLAVE_ADDR8,
+ I2C_SLAVE_ADDR9,
+ I2C_SLAVE_ADDR10,
+ I2C_GC_ADDR,
+ I2C_ARP_ADDR,
+};
+#endif
+
+/* init register and default value required to enable module */
+#define NPCM_I2CSEGCTL 0xE4
+#define NPCM_I2CSEGCTL_INIT_VAL 0x0333F000
+
+/* Common regs */
+#define NPCM_I2CSDA 0x00
+#define NPCM_I2CST 0x02
+#define NPCM_I2CCST 0x04
+#define NPCM_I2CCTL1 0x06
+#define NPCM_I2CADDR1 0x08
+#define NPCM_I2CCTL2 0x0A
+#define NPCM_I2CADDR2 0x0C
+#define NPCM_I2CCTL3 0x0E
+#define NPCM_I2CCST2 0x18
+#define NPCM_I2CCST3 0x19
+#define I2C_VER 0x1F
+
+/*BANK0 regs*/
+#define NPCM_I2CADDR3 0x10
+#define NPCM_I2CADDR7 0x11
+#define NPCM_I2CADDR4 0x12
+#define NPCM_I2CADDR8 0x13
+#define NPCM_I2CADDR5 0x14
+#define NPCM_I2CADDR9 0x15
+#define NPCM_I2CADDR6 0x16
+#define NPCM_I2CADDR10 0x17
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+/*
+ * npcm_i2caddr array:
+ * The module supports having multiple own slave addresses.
+ * Since the addr regs are sprinkled all over the address space,
+ * use this array to get the address or each register.
+ */
+#define I2C_NUM_OWN_ADDR 10
+static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = {
+ NPCM_I2CADDR1, NPCM_I2CADDR2, NPCM_I2CADDR3, NPCM_I2CADDR4,
+ NPCM_I2CADDR5, NPCM_I2CADDR6, NPCM_I2CADDR7, NPCM_I2CADDR8,
+ NPCM_I2CADDR9, NPCM_I2CADDR10,
+};
+#endif
+
+#define NPCM_I2CCTL4 0x1A
+#define NPCM_I2CCTL5 0x1B
+#define NPCM_I2CSCLLT 0x1C /* SCL Low Time */
+#define NPCM_I2CFIF_CTL 0x1D /* FIFO Control */
+#define NPCM_I2CSCLHT 0x1E /* SCL High Time */
+
+/* BANK 1 regs */
+#define NPCM_I2CFIF_CTS 0x10 /* Both FIFOs Control and Status */
+#define NPCM_I2CTXF_CTL 0x12 /* Tx-FIFO Control */
+#define NPCM_I2CT_OUT 0x14 /* Bus T.O. */
+#define NPCM_I2CPEC 0x16 /* PEC Data */
+#define NPCM_I2CTXF_STS 0x1A /* Tx-FIFO Status */
+#define NPCM_I2CRXF_STS 0x1C /* Rx-FIFO Status */
+#define NPCM_I2CRXF_CTL 0x1E /* Rx-FIFO Control */
+
+/* NPCM_I2CST reg fields */
+#define NPCM_I2CST_XMIT BIT(0)
+#define NPCM_I2CST_MASTER BIT(1)
+#define NPCM_I2CST_NMATCH BIT(2)
+#define NPCM_I2CST_STASTR BIT(3)
+#define NPCM_I2CST_NEGACK BIT(4)
+#define NPCM_I2CST_BER BIT(5)
+#define NPCM_I2CST_SDAST BIT(6)
+#define NPCM_I2CST_SLVSTP BIT(7)
+
+/* NPCM_I2CCST reg fields */
+#define NPCM_I2CCST_BUSY BIT(0)
+#define NPCM_I2CCST_BB BIT(1)
+#define NPCM_I2CCST_MATCH BIT(2)
+#define NPCM_I2CCST_GCMATCH BIT(3)
+#define NPCM_I2CCST_TSDA BIT(4)
+#define NPCM_I2CCST_TGSCL BIT(5)
+#define NPCM_I2CCST_MATCHAF BIT(6)
+#define NPCM_I2CCST_ARPMATCH BIT(7)
+
+/* NPCM_I2CCTL1 reg fields */
+#define NPCM_I2CCTL1_START BIT(0)
+#define NPCM_I2CCTL1_STOP BIT(1)
+#define NPCM_I2CCTL1_INTEN BIT(2)
+#define NPCM_I2CCTL1_EOBINTE BIT(3)
+#define NPCM_I2CCTL1_ACK BIT(4)
+#define NPCM_I2CCTL1_GCMEN BIT(5)
+#define NPCM_I2CCTL1_NMINTE BIT(6)
+#define NPCM_I2CCTL1_STASTRE BIT(7)
+
+/* RW1S fields (inside a RW reg): */
+#define NPCM_I2CCTL1_RWS \
+ (NPCM_I2CCTL1_START | NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK)
+
+/* npcm_i2caddr reg fields */
+#define NPCM_I2CADDR_A GENMASK(6, 0)
+#define NPCM_I2CADDR_SAEN BIT(7)
+
+/* NPCM_I2CCTL2 reg fields */
+#define I2CCTL2_ENABLE BIT(0)
+#define I2CCTL2_SCLFRQ6_0 GENMASK(7, 1)
+
+/* NPCM_I2CCTL3 reg fields */
+#define I2CCTL3_SCLFRQ8_7 GENMASK(1, 0)
+#define I2CCTL3_ARPMEN BIT(2)
+#define I2CCTL3_IDL_START BIT(3)
+#define I2CCTL3_400K_MODE BIT(4)
+#define I2CCTL3_BNK_SEL BIT(5)
+#define I2CCTL3_SDA_LVL BIT(6)
+#define I2CCTL3_SCL_LVL BIT(7)
+
+/* NPCM_I2CCST2 reg fields */
+#define NPCM_I2CCST2_MATCHA1F BIT(0)
+#define NPCM_I2CCST2_MATCHA2F BIT(1)
+#define NPCM_I2CCST2_MATCHA3F BIT(2)
+#define NPCM_I2CCST2_MATCHA4F BIT(3)
+#define NPCM_I2CCST2_MATCHA5F BIT(4)
+#define NPCM_I2CCST2_MATCHA6F BIT(5)
+#define NPCM_I2CCST2_MATCHA7F BIT(5)
+#define NPCM_I2CCST2_INTSTS BIT(7)
+
+/* NPCM_I2CCST3 reg fields */
+#define NPCM_I2CCST3_MATCHA8F BIT(0)
+#define NPCM_I2CCST3_MATCHA9F BIT(1)
+#define NPCM_I2CCST3_MATCHA10F BIT(2)
+#define NPCM_I2CCST3_EO_BUSY BIT(7)
+
+/* NPCM_I2CCTL4 reg fields */
+#define I2CCTL4_HLDT GENMASK(5, 0)
+#define I2CCTL4_LVL_WE BIT(7)
+
+/* NPCM_I2CCTL5 reg fields */
+#define I2CCTL5_DBNCT GENMASK(3, 0)
+
+/* NPCM_I2CFIF_CTS reg fields */
+#define NPCM_I2CFIF_CTS_RXF_TXE BIT(1)
+#define NPCM_I2CFIF_CTS_RFTE_IE BIT(3)
+#define NPCM_I2CFIF_CTS_CLR_FIFO BIT(6)
+#define NPCM_I2CFIF_CTS_SLVRSTR BIT(7)
+
+/* NPCM_I2CTXF_CTL reg fields */
+#define NPCM_I2CTXF_CTL_TX_THR GENMASK(4, 0)
+#define NPCM_I2CTXF_CTL_THR_TXIE BIT(6)
+
+/* NPCM_I2CT_OUT reg fields */
+#define NPCM_I2CT_OUT_TO_CKDIV GENMASK(5, 0)
+#define NPCM_I2CT_OUT_T_OUTIE BIT(6)
+#define NPCM_I2CT_OUT_T_OUTST BIT(7)
+
+/* NPCM_I2CTXF_STS reg fields */
+#define NPCM_I2CTXF_STS_TX_BYTES GENMASK(4, 0)
+#define NPCM_I2CTXF_STS_TX_THST BIT(6)
+
+/* NPCM_I2CRXF_STS reg fields */
+#define NPCM_I2CRXF_STS_RX_BYTES GENMASK(4, 0)
+#define NPCM_I2CRXF_STS_RX_THST BIT(6)
+
+/* NPCM_I2CFIF_CTL reg fields */
+#define NPCM_I2CFIF_CTL_FIFO_EN BIT(4)
+
+/* NPCM_I2CRXF_CTL reg fields */
+#define NPCM_I2CRXF_CTL_RX_THR GENMASK(4, 0)
+#define NPCM_I2CRXF_CTL_LAST_PEC BIT(5)
+#define NPCM_I2CRXF_CTL_THR_RXIE BIT(6)
+
+#define I2C_HW_FIFO_SIZE 16
+
+/* I2C_VER reg fields */
+#define I2C_VER_VERSION GENMASK(6, 0)
+#define I2C_VER_FIFO_EN BIT(7)
+
+/* stall/stuck timeout in us */
+#define DEFAULT_STALL_COUNT 25
+
+/* SCLFRQ field position */
+#define SCLFRQ_0_TO_6 GENMASK(6, 0)
+#define SCLFRQ_7_TO_8 GENMASK(8, 7)
+
+/* supported clk settings. values in Hz. */
+#define I2C_FREQ_MIN_HZ 10000
+#define I2C_FREQ_MAX_HZ I2C_MAX_FAST_MODE_PLUS_FREQ
+
+/* Status of one I2C module */
+struct npcm_i2c {
+ struct i2c_adapter adap;
+ struct device *dev;
+ unsigned char __iomem *reg;
+ spinlock_t lock; /* IRQ synchronization */
+ struct completion cmd_complete;
+ int cmd_err;
+ struct i2c_msg *msgs;
+ int msgs_num;
+ int num;
+ u32 apb_clk;
+ struct i2c_bus_recovery_info rinfo;
+ enum i2c_state state;
+ enum i2c_oper operation;
+ enum i2c_mode master_or_slave;
+ enum i2c_state_ind stop_ind;
+ u8 dest_addr;
+ u8 *rd_buf;
+ u16 rd_size;
+ u16 rd_ind;
+ u8 *wr_buf;
+ u16 wr_size;
+ u16 wr_ind;
+ bool fifo_use;
+ u16 PEC_mask; /* PEC bit mask per slave address */
+ bool PEC_use;
+ bool read_block_use;
+ unsigned long int_time_stamp;
+ unsigned long bus_freq; /* in Hz */
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ u8 own_slave_addr;
+ struct i2c_client *slave;
+ int slv_rd_size;
+ int slv_rd_ind;
+ int slv_wr_size;
+ int slv_wr_ind;
+ u8 slv_rd_buf[I2C_HW_FIFO_SIZE];
+ u8 slv_wr_buf[I2C_HW_FIFO_SIZE];
+#endif
+ struct dentry *debugfs; /* debugfs device directory */
+ u64 ber_cnt;
+ u64 rec_succ_cnt;
+ u64 rec_fail_cnt;
+ u64 nack_cnt;
+ u64 timeout_cnt;
+};
+
+static inline void npcm_i2c_select_bank(struct npcm_i2c *bus,
+ enum i2c_bank bank)
+{
+ u8 i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
+
+ if (bank == I2C_BANK_0)
+ i2cctl3 = i2cctl3 & ~I2CCTL3_BNK_SEL;
+ else
+ i2cctl3 = i2cctl3 | I2CCTL3_BNK_SEL;
+ iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
+}
+
+static void npcm_i2c_init_params(struct npcm_i2c *bus)
+{
+ bus->stop_ind = I2C_NO_STATUS_IND;
+ bus->rd_size = 0;
+ bus->wr_size = 0;
+ bus->rd_ind = 0;
+ bus->wr_ind = 0;
+ bus->read_block_use = false;
+ bus->int_time_stamp = 0;
+ bus->PEC_use = false;
+ bus->PEC_mask = 0;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (bus->slave)
+ bus->master_or_slave = I2C_SLAVE;
+#endif
+}
+
+static inline void npcm_i2c_wr_byte(struct npcm_i2c *bus, u8 data)
+{
+ iowrite8(data, bus->reg + NPCM_I2CSDA);
+}
+
+static inline u8 npcm_i2c_rd_byte(struct npcm_i2c *bus)
+{
+ return ioread8(bus->reg + NPCM_I2CSDA);
+}
+
+static int npcm_i2c_get_SCL(struct i2c_adapter *_adap)
+{
+ struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
+
+ return !!(I2CCTL3_SCL_LVL & ioread32(bus->reg + NPCM_I2CCTL3));
+}
+
+static int npcm_i2c_get_SDA(struct i2c_adapter *_adap)
+{
+ struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
+
+ return !!(I2CCTL3_SDA_LVL & ioread32(bus->reg + NPCM_I2CCTL3));
+}
+
+static inline u16 npcm_i2c_get_index(struct npcm_i2c *bus)
+{
+ if (bus->operation == I2C_READ_OPER)
+ return bus->rd_ind;
+ if (bus->operation == I2C_WRITE_OPER)
+ return bus->wr_ind;
+ return 0;
+}
+
+/* quick protocol (just address) */
+static inline bool npcm_i2c_is_quick(struct npcm_i2c *bus)
+{
+ return bus->wr_size == 0 && bus->rd_size == 0;
+}
+
+static void npcm_i2c_disable(struct npcm_i2c *bus)
+{
+ u8 i2cctl2;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ int i;
+
+ /* select bank 0 for I2C addresses */
+ npcm_i2c_select_bank(bus, I2C_BANK_0);
+
+ /* Slave addresses removal */
+ for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++)
+ iowrite8(0, bus->reg + npcm_i2caddr[i]);
+
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+#endif
+ /* Disable module */
+ i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
+ i2cctl2 = i2cctl2 & ~I2CCTL2_ENABLE;
+ iowrite8(i2cctl2, bus->reg + NPCM_I2CCTL2);
+
+ bus->state = I2C_DISABLE;
+}
+
+static void npcm_i2c_enable(struct npcm_i2c *bus)
+{
+ u8 i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
+
+ i2cctl2 = i2cctl2 | I2CCTL2_ENABLE;
+ iowrite8(i2cctl2, bus->reg + NPCM_I2CCTL2);
+ bus->state = I2C_IDLE;
+}
+
+/* enable\disable end of busy (EOB) interrupts */
+static inline void npcm_i2c_eob_int(struct npcm_i2c *bus, bool enable)
+{
+ u8 val;
+
+ /* Clear EO_BUSY pending bit: */
+ val = ioread8(bus->reg + NPCM_I2CCST3);
+ val = val | NPCM_I2CCST3_EO_BUSY;
+ iowrite8(val, bus->reg + NPCM_I2CCST3);
+
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val &= ~NPCM_I2CCTL1_RWS;
+ if (enable)
+ val |= NPCM_I2CCTL1_EOBINTE;
+ else
+ val &= ~NPCM_I2CCTL1_EOBINTE;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+}
+
+static inline bool npcm_i2c_tx_fifo_empty(struct npcm_i2c *bus)
+{
+ u8 tx_fifo_sts;
+
+ tx_fifo_sts = ioread8(bus->reg + NPCM_I2CTXF_STS);
+ /* check if TX FIFO is not empty */
+ if ((tx_fifo_sts & NPCM_I2CTXF_STS_TX_BYTES) == 0)
+ return false;
+
+ /* check if TX FIFO status bit is set: */
+ return !!FIELD_GET(NPCM_I2CTXF_STS_TX_THST, tx_fifo_sts);
+}
+
+static inline bool npcm_i2c_rx_fifo_full(struct npcm_i2c *bus)
+{
+ u8 rx_fifo_sts;
+
+ rx_fifo_sts = ioread8(bus->reg + NPCM_I2CRXF_STS);
+ /* check if RX FIFO is not empty: */
+ if ((rx_fifo_sts & NPCM_I2CRXF_STS_RX_BYTES) == 0)
+ return false;
+
+ /* check if rx fifo full status is set: */
+ return !!FIELD_GET(NPCM_I2CRXF_STS_RX_THST, rx_fifo_sts);
+}
+
+static inline void npcm_i2c_clear_fifo_int(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CFIF_CTS);
+ val = (val & NPCM_I2CFIF_CTS_SLVRSTR) | NPCM_I2CFIF_CTS_RXF_TXE;
+ iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
+}
+
+static inline void npcm_i2c_clear_tx_fifo(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CTXF_STS);
+ val = val | NPCM_I2CTXF_STS_TX_THST;
+ iowrite8(val, bus->reg + NPCM_I2CTXF_STS);
+}
+
+static inline void npcm_i2c_clear_rx_fifo(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CRXF_STS);
+ val = val | NPCM_I2CRXF_STS_RX_THST;
+ iowrite8(val, bus->reg + NPCM_I2CRXF_STS);
+}
+
+static void npcm_i2c_int_enable(struct npcm_i2c *bus, bool enable)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val &= ~NPCM_I2CCTL1_RWS;
+ if (enable)
+ val |= NPCM_I2CCTL1_INTEN;
+ else
+ val &= ~NPCM_I2CCTL1_INTEN;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+}
+
+static inline void npcm_i2c_master_start(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val &= ~(NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK);
+ val |= NPCM_I2CCTL1_START;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+}
+
+static inline void npcm_i2c_master_stop(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ /*
+ * override HW issue: I2C may fail to supply stop condition in Master
+ * Write operation.
+ * Need to delay at least 5 us from the last int, before issueing a stop
+ */
+ udelay(10); /* function called from interrupt, can't sleep */
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val &= ~(NPCM_I2CCTL1_START | NPCM_I2CCTL1_ACK);
+ val |= NPCM_I2CCTL1_STOP;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+
+ if (!bus->fifo_use)
+ return;
+
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+
+ if (bus->operation == I2C_READ_OPER)
+ npcm_i2c_clear_rx_fifo(bus);
+ else
+ npcm_i2c_clear_tx_fifo(bus);
+ npcm_i2c_clear_fifo_int(bus);
+ iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
+}
+
+static inline void npcm_i2c_stall_after_start(struct npcm_i2c *bus, bool stall)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val &= ~NPCM_I2CCTL1_RWS;
+ if (stall)
+ val |= NPCM_I2CCTL1_STASTRE;
+ else
+ val &= ~NPCM_I2CCTL1_STASTRE;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+}
+
+static inline void npcm_i2c_nack(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val &= ~(NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_START);
+ val |= NPCM_I2CCTL1_ACK;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+}
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static void npcm_i2c_slave_int_enable(struct npcm_i2c *bus, bool enable)
+{
+ u8 i2cctl1;
+
+ /* enable interrupt on slave match: */
+ i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
+ i2cctl1 &= ~NPCM_I2CCTL1_RWS;
+ if (enable)
+ i2cctl1 |= NPCM_I2CCTL1_NMINTE;
+ else
+ i2cctl1 &= ~NPCM_I2CCTL1_NMINTE;
+ iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
+}
+
+static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
+ u8 addr, bool enable)
+{
+ u8 i2cctl1;
+ u8 i2cctl3;
+ u8 sa_reg;
+
+ sa_reg = (addr & 0x7F) | FIELD_PREP(NPCM_I2CADDR_SAEN, enable);
+ if (addr_type == I2C_GC_ADDR) {
+ i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
+ if (enable)
+ i2cctl1 |= NPCM_I2CCTL1_GCMEN;
+ else
+ i2cctl1 &= ~NPCM_I2CCTL1_GCMEN;
+ iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
+ return 0;
+ }
+ if (addr_type == I2C_ARP_ADDR) {
+ i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
+ if (enable)
+ i2cctl3 |= I2CCTL3_ARPMEN;
+ else
+ i2cctl3 &= ~I2CCTL3_ARPMEN;
+ iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
+ return 0;
+ }
+ if (addr_type >= I2C_ARP_ADDR)
+ return -EFAULT;
+ /* select bank 0 for address 3 to 10 */
+ if (addr_type > I2C_SLAVE_ADDR2)
+ npcm_i2c_select_bank(bus, I2C_BANK_0);
+ /* Set and enable the address */
+ iowrite8(sa_reg, bus->reg + npcm_i2caddr[addr_type]);
+ npcm_i2c_slave_int_enable(bus, enable);
+ if (addr_type > I2C_SLAVE_ADDR2)
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+ return 0;
+}
+#endif
+
+static void npcm_i2c_reset(struct npcm_i2c *bus)
+{
+ /*
+ * Save I2CCTL1 relevant bits. It is being cleared when the module
+ * is disabled.
+ */
+ u8 i2cctl1;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ u8 addr;
+#endif
+
+ i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
+
+ npcm_i2c_disable(bus);
+ npcm_i2c_enable(bus);
+
+ /* Restore NPCM_I2CCTL1 Status */
+ i2cctl1 &= ~NPCM_I2CCTL1_RWS;
+ iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
+
+ /* Clear BB (BUS BUSY) bit */
+ iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
+ iowrite8(0xFF, bus->reg + NPCM_I2CST);
+
+ /* Clear EOB bit */
+ iowrite8(NPCM_I2CCST3_EO_BUSY, bus->reg + NPCM_I2CCST3);
+
+ /* Clear all fifo bits: */
+ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (bus->slave) {
+ addr = bus->slave->addr;
+ npcm_i2c_slave_enable(bus, I2C_SLAVE_ADDR1, addr, true);
+ }
+#endif
+
+ bus->state = I2C_IDLE;
+}
+
+static inline bool npcm_i2c_is_master(struct npcm_i2c *bus)
+{
+ return !!FIELD_GET(NPCM_I2CST_MASTER, ioread8(bus->reg + NPCM_I2CST));
+}
+
+static void npcm_i2c_callback(struct npcm_i2c *bus,
+ enum i2c_state_ind op_status, u16 info)
+{
+ struct i2c_msg *msgs;
+ int msgs_num;
+
+ msgs = bus->msgs;
+ msgs_num = bus->msgs_num;
+ /*
+ * check that transaction was not timed-out, and msgs still
+ * holds a valid value.
+ */
+ if (!msgs)
+ return;
+
+ if (completion_done(&bus->cmd_complete))
+ return;
+
+ switch (op_status) {
+ case I2C_MASTER_DONE_IND:
+ bus->cmd_err = bus->msgs_num;
+ fallthrough;
+ case I2C_BLOCK_BYTES_ERR_IND:
+ /* Master tx finished and all transmit bytes were sent */
+ if (bus->msgs) {
+ if (msgs[0].flags & I2C_M_RD)
+ msgs[0].len = info;
+ else if (msgs_num == 2 &&
+ msgs[1].flags & I2C_M_RD)
+ msgs[1].len = info;
+ }
+ if (completion_done(&bus->cmd_complete) == false)
+ complete(&bus->cmd_complete);
+ break;
+
+ case I2C_NACK_IND:
+ /* MASTER transmit got a NACK before tx all bytes */
+ bus->cmd_err = -ENXIO;
+ if (bus->master_or_slave == I2C_MASTER)
+ complete(&bus->cmd_complete);
+
+ break;
+ case I2C_BUS_ERR_IND:
+ /* Bus error */
+ bus->cmd_err = -EAGAIN;
+ if (bus->master_or_slave == I2C_MASTER)
+ complete(&bus->cmd_complete);
+
+ break;
+ case I2C_WAKE_UP_IND:
+ /* I2C wake up */
+ break;
+ default:
+ break;
+ }
+
+ bus->operation = I2C_NO_OPER;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (bus->slave)
+ bus->master_or_slave = I2C_SLAVE;
+#endif
+}
+
+static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus)
+{
+ if (bus->operation == I2C_WRITE_OPER)
+ return FIELD_GET(NPCM_I2CTXF_STS_TX_BYTES,
+ ioread8(bus->reg + NPCM_I2CTXF_STS));
+ if (bus->operation == I2C_READ_OPER)
+ return FIELD_GET(NPCM_I2CRXF_STS_RX_BYTES,
+ ioread8(bus->reg + NPCM_I2CRXF_STS));
+ return 0;
+}
+
+static void npcm_i2c_write_to_fifo_master(struct npcm_i2c *bus, u16 max_bytes)
+{
+ u8 size_free_fifo;
+
+ /*
+ * Fill the FIFO, while the FIFO is not full and there are more bytes
+ * to write
+ */
+ size_free_fifo = I2C_HW_FIFO_SIZE - npcm_i2c_fifo_usage(bus);
+ while (max_bytes-- && size_free_fifo) {
+ if (bus->wr_ind < bus->wr_size)
+ npcm_i2c_wr_byte(bus, bus->wr_buf[bus->wr_ind++]);
+ else
+ npcm_i2c_wr_byte(bus, 0xFF);
+ size_free_fifo = I2C_HW_FIFO_SIZE - npcm_i2c_fifo_usage(bus);
+ }
+}
+
+/*
+ * npcm_i2c_set_fifo:
+ * configure the FIFO before using it. If nread is -1 RX FIFO will not be
+ * configured. same for nwrite
+ */
+static void npcm_i2c_set_fifo(struct npcm_i2c *bus, int nread, int nwrite)
+{
+ u8 rxf_ctl = 0;
+
+ if (!bus->fifo_use)
+ return;
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+ npcm_i2c_clear_tx_fifo(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+
+ /* configure RX FIFO */
+ if (nread > 0) {
+ rxf_ctl = min_t(int, nread, I2C_HW_FIFO_SIZE);
+
+ /* set LAST bit. if LAST is set next FIFO packet is nacked */
+ if (nread <= I2C_HW_FIFO_SIZE)
+ rxf_ctl |= NPCM_I2CRXF_CTL_LAST_PEC;
+
+ /*
+ * if we are about to read the first byte in blk rd mode,
+ * don't NACK it. If slave returns zero size HW can't NACK
+ * it immidiattly, it will read extra byte and then NACK.
+ */
+ if (bus->rd_ind == 0 && bus->read_block_use) {
+ /* set fifo to read one byte, no last: */
+ rxf_ctl = 1;
+ }
+
+ /* set fifo size: */
+ iowrite8(rxf_ctl, bus->reg + NPCM_I2CRXF_CTL);
+ }
+
+ /* configure TX FIFO */
+ if (nwrite > 0) {
+ if (nwrite > I2C_HW_FIFO_SIZE)
+ /* data to send is more then FIFO size. */
+ iowrite8(I2C_HW_FIFO_SIZE, bus->reg + NPCM_I2CTXF_CTL);
+ else
+ iowrite8(nwrite, bus->reg + NPCM_I2CTXF_CTL);
+
+ npcm_i2c_clear_tx_fifo(bus);
+ }
+}
+
+static void npcm_i2c_read_fifo(struct npcm_i2c *bus, u8 bytes_in_fifo)
+{
+ u8 data;
+
+ while (bytes_in_fifo--) {
+ data = npcm_i2c_rd_byte(bus);
+ if (bus->rd_ind < bus->rd_size)
+ bus->rd_buf[bus->rd_ind++] = data;
+ }
+}
+
+static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ /* Clear NEGACK, STASTR and BER bits */
+ val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR;
+ iowrite8(val, bus->reg + NPCM_I2CST);
+}
+
+static void npcm_i2c_master_abort(struct npcm_i2c *bus)
+{
+ /* Only current master is allowed to issue a stop condition */
+ if (!npcm_i2c_is_master(bus))
+ return;
+
+ npcm_i2c_eob_int(bus, true);
+ npcm_i2c_master_stop(bus);
+ npcm_i2c_clear_master_status(bus);
+}
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type)
+{
+ u8 slave_add;
+
+ /* select bank 0 for address 3 to 10 */
+ if (addr_type > I2C_SLAVE_ADDR2)
+ npcm_i2c_select_bank(bus, I2C_BANK_0);
+
+ slave_add = ioread8(bus->reg + npcm_i2caddr[(int)addr_type]);
+
+ if (addr_type > I2C_SLAVE_ADDR2)
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+
+ return slave_add;
+}
+
+static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)
+{
+ int i;
+
+ /* Set the enable bit */
+ slave_add |= 0x80;
+ npcm_i2c_select_bank(bus, I2C_BANK_0);
+ for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++) {
+ if (ioread8(bus->reg + npcm_i2caddr[i]) == slave_add)
+ iowrite8(0, bus->reg + npcm_i2caddr[i]);
+ }
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+ return 0;
+}
+
+static void npcm_i2c_write_fifo_slave(struct npcm_i2c *bus, u16 max_bytes)
+{
+ /*
+ * Fill the FIFO, while the FIFO is not full and there are more bytes
+ * to write
+ */
+ npcm_i2c_clear_fifo_int(bus);
+ npcm_i2c_clear_tx_fifo(bus);
+ iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
+ while (max_bytes-- && I2C_HW_FIFO_SIZE != npcm_i2c_fifo_usage(bus)) {
+ if (bus->slv_wr_size <= 0)
+ break;
+ bus->slv_wr_ind = bus->slv_wr_ind % I2C_HW_FIFO_SIZE;
+ npcm_i2c_wr_byte(bus, bus->slv_wr_buf[bus->slv_wr_ind]);
+ bus->slv_wr_ind++;
+ bus->slv_wr_ind = bus->slv_wr_ind % I2C_HW_FIFO_SIZE;
+ bus->slv_wr_size--;
+ }
+}
+
+static void npcm_i2c_read_fifo_slave(struct npcm_i2c *bus, u8 bytes_in_fifo)
+{
+ u8 data;
+
+ if (!bus->slave)
+ return;
+
+ while (bytes_in_fifo--) {
+ data = npcm_i2c_rd_byte(bus);
+
+ bus->slv_rd_ind = bus->slv_rd_ind % I2C_HW_FIFO_SIZE;
+ bus->slv_rd_buf[bus->slv_rd_ind] = data;
+ bus->slv_rd_ind++;
+
+ /* 1st byte is length in block protocol: */
+ if (bus->slv_rd_ind == 1 && bus->read_block_use)
+ bus->slv_rd_size = data + bus->PEC_use + 1;
+ }
+}
+
+static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)
+{
+ int i;
+ u8 value;
+ int ind;
+ int ret = bus->slv_wr_ind;
+
+ /* fill a cyclic buffer */
+ for (i = 0; i < I2C_HW_FIFO_SIZE; i++) {
+ if (bus->slv_wr_size >= I2C_HW_FIFO_SIZE)
+ break;
+ i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
+ ind = (bus->slv_wr_ind + bus->slv_wr_size) % I2C_HW_FIFO_SIZE;
+ bus->slv_wr_buf[ind] = value;
+ bus->slv_wr_size++;
+ i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
+ }
+ return I2C_HW_FIFO_SIZE - ret;
+}
+
+static void npcm_i2c_slave_send_rd_buf(struct npcm_i2c *bus)
+{
+ int i;
+
+ for (i = 0; i < bus->slv_rd_ind; i++)
+ i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED,
+ &bus->slv_rd_buf[i]);
+ /*
+ * once we send bytes up, need to reset the counter of the wr buf
+ * got data from master (new offset in device), ignore wr fifo:
+ */
+ if (bus->slv_rd_ind) {
+ bus->slv_wr_size = 0;
+ bus->slv_wr_ind = 0;
+ }
+
+ bus->slv_rd_ind = 0;
+ bus->slv_rd_size = bus->adap.quirks->max_read_len;
+
+ npcm_i2c_clear_fifo_int(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+}
+
+static void npcm_i2c_slave_receive(struct npcm_i2c *bus, u16 nread,
+ u8 *read_data)
+{
+ bus->state = I2C_OPER_STARTED;
+ bus->operation = I2C_READ_OPER;
+ bus->slv_rd_size = nread;
+ bus->slv_rd_ind = 0;
+
+ iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
+ iowrite8(I2C_HW_FIFO_SIZE, bus->reg + NPCM_I2CRXF_CTL);
+ npcm_i2c_clear_tx_fifo(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+}
+
+static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite,
+ u8 *write_data)
+{
+ if (nwrite == 0)
+ return;
+
+ bus->state = I2C_OPER_STARTED;
+ bus->operation = I2C_WRITE_OPER;
+
+ /* get the next buffer */
+ npcm_i2c_slave_get_wr_buf(bus);
+ npcm_i2c_write_fifo_slave(bus, nwrite);
+}
+
+/*
+ * npcm_i2c_slave_wr_buf_sync:
+ * currently slave IF only supports single byte operations.
+ * in order to utilyze the npcm HW FIFO, the driver will ask for 16 bytes
+ * at a time, pack them in buffer, and then transmit them all together
+ * to the FIFO and onward to the bus.
+ * NACK on read will be once reached to bus->adap->quirks->max_read_len.
+ * sending a NACK wherever the backend requests for it is not supported.
+ * the next two functions allow reading to local buffer before writing it all
+ * to the HW FIFO.
+ */
+static void npcm_i2c_slave_wr_buf_sync(struct npcm_i2c *bus)
+{
+ int left_in_fifo;
+
+ left_in_fifo = FIELD_GET(NPCM_I2CTXF_STS_TX_BYTES,
+ ioread8(bus->reg + NPCM_I2CTXF_STS));
+
+ /* fifo already full: */
+ if (left_in_fifo >= I2C_HW_FIFO_SIZE ||
+ bus->slv_wr_size >= I2C_HW_FIFO_SIZE)
+ return;
+
+ /* update the wr fifo index back to the untransmitted bytes: */
+ bus->slv_wr_ind = bus->slv_wr_ind - left_in_fifo;
+ bus->slv_wr_size = bus->slv_wr_size + left_in_fifo;
+
+ if (bus->slv_wr_ind < 0)
+ bus->slv_wr_ind += I2C_HW_FIFO_SIZE;
+}
+
+static void npcm_i2c_slave_rd_wr(struct npcm_i2c *bus)
+{
+ if (NPCM_I2CST_XMIT & ioread8(bus->reg + NPCM_I2CST)) {
+ /*
+ * Slave got an address match with direction bit 1 so it should
+ * transmit data. Write till the master will NACK
+ */
+ bus->operation = I2C_WRITE_OPER;
+ npcm_i2c_slave_xmit(bus, bus->adap.quirks->max_write_len,
+ bus->slv_wr_buf);
+ } else {
+ /*
+ * Slave got an address match with direction bit 0 so it should
+ * receive data.
+ * this module does not support saying no to bytes.
+ * it will always ACK.
+ */
+ bus->operation = I2C_READ_OPER;
+ npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
+ bus->stop_ind = I2C_SLAVE_RCV_IND;
+ npcm_i2c_slave_send_rd_buf(bus);
+ npcm_i2c_slave_receive(bus, bus->adap.quirks->max_read_len,
+ bus->slv_rd_buf);
+ }
+}
+
+static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus)
+{
+ u8 val;
+ irqreturn_t ret = IRQ_NONE;
+ u8 i2cst = ioread8(bus->reg + NPCM_I2CST);
+
+ /* Slave: A NACK has occurred */
+ if (NPCM_I2CST_NEGACK & i2cst) {
+ bus->stop_ind = I2C_NACK_IND;
+ npcm_i2c_slave_wr_buf_sync(bus);
+ if (bus->fifo_use)
+ /* clear the FIFO */
+ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,
+ bus->reg + NPCM_I2CFIF_CTS);
+
+ /* In slave write, NACK is OK, otherwise it is a problem */
+ bus->stop_ind = I2C_NO_STATUS_IND;
+ bus->operation = I2C_NO_OPER;
+ bus->own_slave_addr = 0xFF;
+
+ /*
+ * Slave has to wait for STOP to decide this is the end
+ * of the transaction. tx is not yet considered as done
+ */
+ iowrite8(NPCM_I2CST_NEGACK, bus->reg + NPCM_I2CST);
+
+ ret = IRQ_HANDLED;
+ }
+
+ /* Slave mode: a Bus Error (BER) has been identified */
+ if (NPCM_I2CST_BER & i2cst) {
+ /*
+ * Check whether bus arbitration or Start or Stop during data
+ * xfer bus arbitration problem should not result in recovery
+ */
+ bus->stop_ind = I2C_BUS_ERR_IND;
+
+ /* wait for bus busy before clear fifo */
+ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
+
+ bus->state = I2C_IDLE;
+
+ /*
+ * in BER case we might get 2 interrupts: one for slave one for
+ * master ( for a channel which is master\slave switching)
+ */
+ if (completion_done(&bus->cmd_complete) == false) {
+ bus->cmd_err = -EIO;
+ complete(&bus->cmd_complete);
+ }
+ bus->own_slave_addr = 0xFF;
+ iowrite8(NPCM_I2CST_BER, bus->reg + NPCM_I2CST);
+ ret = IRQ_HANDLED;
+ }
+
+ /* A Slave Stop Condition has been identified */
+ if (NPCM_I2CST_SLVSTP & i2cst) {
+ u8 bytes_in_fifo = npcm_i2c_fifo_usage(bus);
+
+ bus->stop_ind = I2C_SLAVE_DONE_IND;
+
+ if (bus->operation == I2C_READ_OPER)
+ npcm_i2c_read_fifo_slave(bus, bytes_in_fifo);
+
+ /* if the buffer is empty nothing will be sent */
+ npcm_i2c_slave_send_rd_buf(bus);
+
+ /* Slave done transmitting or receiving */
+ bus->stop_ind = I2C_NO_STATUS_IND;
+
+ /*
+ * Note, just because we got here, it doesn't mean we through
+ * away the wr buffer.
+ * we keep it until the next received offset.
+ */
+ bus->operation = I2C_NO_OPER;
+ bus->own_slave_addr = 0xFF;
+ i2c_slave_event(bus->slave, I2C_SLAVE_STOP, 0);
+ iowrite8(NPCM_I2CST_SLVSTP, bus->reg + NPCM_I2CST);
+ if (bus->fifo_use) {
+ npcm_i2c_clear_fifo_int(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+ npcm_i2c_clear_tx_fifo(bus);
+
+ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,
+ bus->reg + NPCM_I2CFIF_CTS);
+ }
+ bus->state = I2C_IDLE;
+ ret = IRQ_HANDLED;
+ }
+
+ /* restart condition occurred and Rx-FIFO was not empty */
+ if (bus->fifo_use && FIELD_GET(NPCM_I2CFIF_CTS_SLVRSTR,
+ ioread8(bus->reg + NPCM_I2CFIF_CTS))) {
+ bus->stop_ind = I2C_SLAVE_RESTART_IND;
+ bus->master_or_slave = I2C_SLAVE;
+ if (bus->operation == I2C_READ_OPER)
+ npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
+ bus->operation = I2C_WRITE_OPER;
+ iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
+ val = NPCM_I2CFIF_CTS_CLR_FIFO | NPCM_I2CFIF_CTS_SLVRSTR |
+ NPCM_I2CFIF_CTS_RXF_TXE;
+ iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
+ npcm_i2c_slave_rd_wr(bus);
+ ret = IRQ_HANDLED;
+ }
+
+ /* A Slave Address Match has been identified */
+ if (NPCM_I2CST_NMATCH & i2cst) {
+ u8 info = 0;
+
+ /* Address match automatically implies slave mode */
+ bus->master_or_slave = I2C_SLAVE;
+ npcm_i2c_clear_fifo_int(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+ npcm_i2c_clear_tx_fifo(bus);
+ iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
+ iowrite8(I2C_HW_FIFO_SIZE, bus->reg + NPCM_I2CRXF_CTL);
+ if (NPCM_I2CST_XMIT & i2cst) {
+ bus->operation = I2C_WRITE_OPER;
+ } else {
+ i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_REQUESTED,
+ &info);
+ bus->operation = I2C_READ_OPER;
+ }
+ if (bus->own_slave_addr == 0xFF) {
+ /* Check which type of address match */
+ val = ioread8(bus->reg + NPCM_I2CCST);
+ if (NPCM_I2CCST_MATCH & val) {
+ u16 addr;
+ enum i2c_addr eaddr;
+ u8 i2ccst2;
+ u8 i2ccst3;
+
+ i2ccst3 = ioread8(bus->reg + NPCM_I2CCST3);
+ i2ccst2 = ioread8(bus->reg + NPCM_I2CCST2);
+
+ /*
+ * the i2c module can response to 10 own SA.
+ * check which one was addressed by the master.
+ * repond to the first one.
+ */
+ addr = ((i2ccst3 & 0x07) << 7) |
+ (i2ccst2 & 0x7F);
+ info = ffs(addr);
+ eaddr = (enum i2c_addr)info;
+ addr = npcm_i2c_get_slave_addr(bus, eaddr);
+ addr &= 0x7F;
+ bus->own_slave_addr = addr;
+ if (bus->PEC_mask & BIT(info))
+ bus->PEC_use = true;
+ else
+ bus->PEC_use = false;
+ } else {
+ if (NPCM_I2CCST_GCMATCH & val)
+ bus->own_slave_addr = 0;
+ if (NPCM_I2CCST_ARPMATCH & val)
+ bus->own_slave_addr = 0x61;
+ }
+ } else {
+ /*
+ * Slave match can happen in two options:
+ * 1. Start, SA, read (slave read without further ado)
+ * 2. Start, SA, read, data, restart, SA, read, ...
+ * (slave read in fragmented mode)
+ * 3. Start, SA, write, data, restart, SA, read, ..
+ * (regular write-read mode)
+ */
+ if ((bus->state == I2C_OPER_STARTED &&
+ bus->operation == I2C_READ_OPER &&
+ bus->stop_ind == I2C_SLAVE_XMIT_IND) ||
+ bus->stop_ind == I2C_SLAVE_RCV_IND) {
+ /* slave tx after slave rx w/o STOP */
+ bus->stop_ind = I2C_SLAVE_RESTART_IND;
+ }
+ }
+
+ if (NPCM_I2CST_XMIT & i2cst)
+ bus->stop_ind = I2C_SLAVE_XMIT_IND;
+ else
+ bus->stop_ind = I2C_SLAVE_RCV_IND;
+ bus->state = I2C_SLAVE_MATCH;
+ npcm_i2c_slave_rd_wr(bus);
+ iowrite8(NPCM_I2CST_NMATCH, bus->reg + NPCM_I2CST);
+ ret = IRQ_HANDLED;
+ }
+
+ /* Slave SDA status is set - tx or rx */
+ if ((NPCM_I2CST_SDAST & i2cst) ||
+ (bus->fifo_use &&
+ (npcm_i2c_tx_fifo_empty(bus) || npcm_i2c_rx_fifo_full(bus)))) {
+ npcm_i2c_slave_rd_wr(bus);
+ iowrite8(NPCM_I2CST_SDAST, bus->reg + NPCM_I2CST);
+ ret = IRQ_HANDLED;
+ } /* SDAST */
+
+ return ret;
+}
+
+static int npcm_i2c_reg_slave(struct i2c_client *client)
+{
+ unsigned long lock_flags;
+ struct npcm_i2c *bus = i2c_get_adapdata(client->adapter);
+
+ bus->slave = client;
+
+ if (!bus->slave)
+ return -EINVAL;
+
+ if (client->flags & I2C_CLIENT_TEN)
+ return -EAFNOSUPPORT;
+
+ spin_lock_irqsave(&bus->lock, lock_flags);
+
+ npcm_i2c_init_params(bus);
+ bus->slv_rd_size = 0;
+ bus->slv_wr_size = 0;
+ bus->slv_rd_ind = 0;
+ bus->slv_wr_ind = 0;
+ if (client->flags & I2C_CLIENT_PEC)
+ bus->PEC_use = true;
+
+ dev_info(bus->dev, "i2c%d register slave SA=0x%x, PEC=%d\n", bus->num,
+ client->addr, bus->PEC_use);
+
+ npcm_i2c_slave_enable(bus, I2C_SLAVE_ADDR1, client->addr, true);
+ npcm_i2c_clear_fifo_int(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+ npcm_i2c_clear_tx_fifo(bus);
+ npcm_i2c_slave_int_enable(bus, true);
+
+ spin_unlock_irqrestore(&bus->lock, lock_flags);
+ return 0;
+}
+
+static int npcm_i2c_unreg_slave(struct i2c_client *client)
+{
+ struct npcm_i2c *bus = client->adapter->algo_data;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bus->lock, lock_flags);
+ if (!bus->slave) {
+ spin_unlock_irqrestore(&bus->lock, lock_flags);
+ return -EINVAL;
+ }
+ npcm_i2c_slave_int_enable(bus, false);
+ npcm_i2c_remove_slave_addr(bus, client->addr);
+ bus->slave = NULL;
+ spin_unlock_irqrestore(&bus->lock, lock_flags);
+ return 0;
+}
+#endif /* CONFIG_I2C_SLAVE */
+
+static void npcm_i2c_master_fifo_read(struct npcm_i2c *bus)
+{
+ int rcount;
+ int fifo_bytes;
+ enum i2c_state_ind ind = I2C_MASTER_DONE_IND;
+
+ fifo_bytes = npcm_i2c_fifo_usage(bus);
+ rcount = bus->rd_size - bus->rd_ind;
+
+ /*
+ * In order not to change the RX_TRH during transaction (we found that
+ * this might be problematic if it takes too much time to read the FIFO)
+ * we read the data in the following way. If the number of bytes to
+ * read == FIFO Size + C (where C < FIFO Size)then first read C bytes
+ * and in the next int we read rest of the data.
+ */
+ if (rcount < (2 * I2C_HW_FIFO_SIZE) && rcount > I2C_HW_FIFO_SIZE)
+ fifo_bytes = rcount - I2C_HW_FIFO_SIZE;
+
+ if (rcount <= fifo_bytes) {
+ /* last bytes are about to be read - end of tx */
+ bus->state = I2C_STOP_PENDING;
+ bus->stop_ind = ind;
+ npcm_i2c_eob_int(bus, true);
+ /* Stop should be set before reading last byte. */
+ npcm_i2c_master_stop(bus);
+ npcm_i2c_read_fifo(bus, fifo_bytes);
+ } else {
+ npcm_i2c_read_fifo(bus, fifo_bytes);
+ rcount = bus->rd_size - bus->rd_ind;
+ npcm_i2c_set_fifo(bus, rcount, -1);
+ }
+}
+
+static void npcm_i2c_irq_master_handler_write(struct npcm_i2c *bus)
+{
+ u16 wcount;
+
+ if (bus->fifo_use)
+ npcm_i2c_clear_tx_fifo(bus); /* clear the TX fifo status bit */
+
+ /* Master write operation - last byte handling */
+ if (bus->wr_ind == bus->wr_size) {
+ if (bus->fifo_use && npcm_i2c_fifo_usage(bus) > 0)
+ /*
+ * No more bytes to send (to add to the FIFO),
+ * however the FIFO is not empty yet. It is
+ * still in the middle of tx. Currently there's nothing
+ * to do except for waiting to the end of the tx
+ * We will get an int when the FIFO will get empty.
+ */
+ return;
+
+ if (bus->rd_size == 0) {
+ /* all bytes have been written, in wr only operation */
+ npcm_i2c_eob_int(bus, true);
+ bus->state = I2C_STOP_PENDING;
+ bus->stop_ind = I2C_MASTER_DONE_IND;
+ npcm_i2c_master_stop(bus);
+ /* Clear SDA Status bit (by writing dummy byte) */
+ npcm_i2c_wr_byte(bus, 0xFF);
+
+ } else {
+ /* last write-byte written on previous int - restart */
+ npcm_i2c_set_fifo(bus, bus->rd_size, -1);
+ /* Generate repeated start upon next write to SDA */
+ npcm_i2c_master_start(bus);
+
+ /*
+ * Receiving one byte only - stall after successful
+ * completion of send address byte. If we NACK here, and
+ * slave doesn't ACK the address, we might
+ * unintentionally NACK the next multi-byte read.
+ */
+ if (bus->rd_size == 1)
+ npcm_i2c_stall_after_start(bus, true);
+
+ /* Next int will occur on read */
+ bus->operation = I2C_READ_OPER;
+ /* send the slave address in read direction */
+ npcm_i2c_wr_byte(bus, bus->dest_addr | 0x1);
+ }
+ } else {
+ /* write next byte not last byte and not slave address */
+ if (!bus->fifo_use || bus->wr_size == 1) {
+ npcm_i2c_wr_byte(bus, bus->wr_buf[bus->wr_ind++]);
+ } else {
+ wcount = bus->wr_size - bus->wr_ind;
+ npcm_i2c_set_fifo(bus, -1, wcount);
+ if (wcount)
+ npcm_i2c_write_to_fifo_master(bus, wcount);
+ }
+ }
+}
+
+static void npcm_i2c_irq_master_handler_read(struct npcm_i2c *bus)
+{
+ u16 block_extra_bytes_size;
+ u8 data;
+
+ /* added bytes to the packet: */
+ block_extra_bytes_size = bus->read_block_use + bus->PEC_use;
+
+ /*
+ * Perform master read, distinguishing between last byte and the rest of
+ * the bytes. The last byte should be read when the clock is stopped
+ */
+ if (bus->rd_ind == 0) { /* first byte handling: */
+ if (bus->read_block_use) {
+ /* first byte in block protocol is the size: */
+ data = npcm_i2c_rd_byte(bus);
+ data = clamp_val(data, 1, I2C_SMBUS_BLOCK_MAX);
+ bus->rd_size = data + block_extra_bytes_size;
+ bus->rd_buf[bus->rd_ind++] = data;
+
+ /* clear RX FIFO interrupt status: */
+ if (bus->fifo_use) {
+ data = ioread8(bus->reg + NPCM_I2CFIF_CTS);
+ data = data | NPCM_I2CFIF_CTS_RXF_TXE;
+ iowrite8(data, bus->reg + NPCM_I2CFIF_CTS);
+ }
+
+ npcm_i2c_set_fifo(bus, bus->rd_size - 1, -1);
+ npcm_i2c_stall_after_start(bus, false);
+ } else {
+ npcm_i2c_clear_tx_fifo(bus);
+ npcm_i2c_master_fifo_read(bus);
+ }
+ } else {
+ if (bus->rd_size == block_extra_bytes_size &&
+ bus->read_block_use) {
+ bus->state = I2C_STOP_PENDING;
+ bus->stop_ind = I2C_BLOCK_BYTES_ERR_IND;
+ bus->cmd_err = -EIO;
+ npcm_i2c_eob_int(bus, true);
+ npcm_i2c_master_stop(bus);
+ npcm_i2c_read_fifo(bus, npcm_i2c_fifo_usage(bus));
+ } else {
+ npcm_i2c_master_fifo_read(bus);
+ }
+ }
+}
+
+static void npcm_i2c_irq_handle_nmatch(struct npcm_i2c *bus)
+{
+ iowrite8(NPCM_I2CST_NMATCH, bus->reg + NPCM_I2CST);
+ npcm_i2c_nack(bus);
+ bus->stop_ind = I2C_BUS_ERR_IND;
+ npcm_i2c_callback(bus, bus->stop_ind, npcm_i2c_get_index(bus));
+}
+
+/* A NACK has occurred */
+static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus)
+{
+ u8 val;
+
+ if (bus->nack_cnt < ULLONG_MAX)
+ bus->nack_cnt++;
+
+ if (bus->fifo_use) {
+ /*
+ * if there are still untransmitted bytes in TX FIFO
+ * reduce them from wr_ind
+ */
+ if (bus->operation == I2C_WRITE_OPER)
+ bus->wr_ind -= npcm_i2c_fifo_usage(bus);
+
+ /* clear the FIFO */
+ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
+ }
+
+ /* In master write operation, got unexpected NACK */
+ bus->stop_ind = I2C_NACK_IND;
+ /* Only current master is allowed to issue Stop Condition */
+ if (npcm_i2c_is_master(bus)) {
+ /* stopping in the middle */
+ npcm_i2c_eob_int(bus, false);
+ npcm_i2c_master_stop(bus);
+
+ /*
+ * The bus is released from stall only after the SW clears
+ * NEGACK bit. Then a Stop condition is sent.
+ */
+ npcm_i2c_clear_master_status(bus);
+ readx_poll_timeout_atomic(ioread8, bus->reg + NPCM_I2CCST, val,
+ !(val & NPCM_I2CCST_BUSY), 10, 200);
+ }
+ bus->state = I2C_IDLE;
+
+ /*
+ * In Master mode, NACK should be cleared only after STOP.
+ * In such case, the bus is released from stall only after the
+ * software clears NACK bit. Then a Stop condition is sent.
+ */
+ npcm_i2c_callback(bus, bus->stop_ind, bus->wr_ind);
+}
+
+ /* Master mode: a Bus Error has been identified */
+static void npcm_i2c_irq_handle_ber(struct npcm_i2c *bus)
+{
+ if (bus->ber_cnt < ULLONG_MAX)
+ bus->ber_cnt++;
+ bus->stop_ind = I2C_BUS_ERR_IND;
+ if (npcm_i2c_is_master(bus)) {
+ npcm_i2c_master_abort(bus);
+ } else {
+ npcm_i2c_clear_master_status(bus);
+
+ /* Clear BB (BUS BUSY) bit */
+ iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
+
+ bus->cmd_err = -EAGAIN;
+ npcm_i2c_callback(bus, bus->stop_ind, npcm_i2c_get_index(bus));
+ }
+ bus->state = I2C_IDLE;
+}
+
+ /* EOB: a master End Of Busy (meaning STOP completed) */
+static void npcm_i2c_irq_handle_eob(struct npcm_i2c *bus)
+{
+ npcm_i2c_eob_int(bus, false);
+ bus->state = I2C_IDLE;
+ npcm_i2c_callback(bus, bus->stop_ind, bus->rd_ind);
+}
+
+/* Address sent and requested stall occurred (Master mode) */
+static void npcm_i2c_irq_handle_stall_after_start(struct npcm_i2c *bus)
+{
+ if (npcm_i2c_is_quick(bus)) {
+ bus->state = I2C_STOP_PENDING;
+ bus->stop_ind = I2C_MASTER_DONE_IND;
+ npcm_i2c_eob_int(bus, true);
+ npcm_i2c_master_stop(bus);
+ } else if ((bus->rd_size == 1) && !bus->read_block_use) {
+ /*
+ * Receiving one byte only - set NACK after ensuring
+ * slave ACKed the address byte.
+ */
+ npcm_i2c_nack(bus);
+ }
+
+ /* Reset stall-after-address-byte */
+ npcm_i2c_stall_after_start(bus, false);
+
+ /* Clear stall only after setting STOP */
+ iowrite8(NPCM_I2CST_STASTR, bus->reg + NPCM_I2CST);
+}
+
+/* SDA status is set - TX or RX, master */
+static void npcm_i2c_irq_handle_sda(struct npcm_i2c *bus, u8 i2cst)
+{
+ u8 fif_cts;
+
+ if (!npcm_i2c_is_master(bus))
+ return;
+
+ if (bus->state == I2C_IDLE) {
+ bus->stop_ind = I2C_WAKE_UP_IND;
+
+ if (npcm_i2c_is_quick(bus) || bus->read_block_use)
+ /*
+ * Need to stall after successful
+ * completion of sending address byte
+ */
+ npcm_i2c_stall_after_start(bus, true);
+ else
+ npcm_i2c_stall_after_start(bus, false);
+
+ /*
+ * Receiving one byte only - stall after successful completion
+ * of sending address byte If we NACK here, and slave doesn't
+ * ACK the address, we might unintentionally NACK the next
+ * multi-byte read
+ */
+ if (bus->wr_size == 0 && bus->rd_size == 1)
+ npcm_i2c_stall_after_start(bus, true);
+
+ /* Initiate I2C master tx */
+
+ /* select bank 1 for FIFO regs */
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+
+ fif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
+ fif_cts = fif_cts & ~NPCM_I2CFIF_CTS_SLVRSTR;
+
+ /* clear FIFO and relevant status bits. */
+ fif_cts = fif_cts | NPCM_I2CFIF_CTS_CLR_FIFO;
+ iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
+
+ /* re-enable */
+ fif_cts = fif_cts | NPCM_I2CFIF_CTS_RXF_TXE;
+ iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
+
+ /*
+ * Configure the FIFO threshold:
+ * according to the needed # of bytes to read.
+ * Note: due to HW limitation can't config the rx fifo before it
+ * got and ACK on the restart. LAST bit will not be reset unless
+ * RX completed. It will stay set on the next tx.
+ */
+ if (bus->wr_size)
+ npcm_i2c_set_fifo(bus, -1, bus->wr_size);
+ else
+ npcm_i2c_set_fifo(bus, bus->rd_size, -1);
+
+ bus->state = I2C_OPER_STARTED;
+
+ if (npcm_i2c_is_quick(bus) || bus->wr_size)
+ npcm_i2c_wr_byte(bus, bus->dest_addr);
+ else
+ npcm_i2c_wr_byte(bus, bus->dest_addr | BIT(0));
+ /* SDA interrupt, after start\restart */
+ } else {
+ if (NPCM_I2CST_XMIT & i2cst) {
+ bus->operation = I2C_WRITE_OPER;
+ npcm_i2c_irq_master_handler_write(bus);
+ } else {
+ bus->operation = I2C_READ_OPER;
+ npcm_i2c_irq_master_handler_read(bus);
+ }
+ }
+}
+
+static int npcm_i2c_int_master_handler(struct npcm_i2c *bus)
+{
+ u8 i2cst;
+ int ret = -EIO;
+
+ i2cst = ioread8(bus->reg + NPCM_I2CST);
+
+ if (FIELD_GET(NPCM_I2CST_NMATCH, i2cst)) {
+ npcm_i2c_irq_handle_nmatch(bus);
+ return 0;
+ }
+ /* A NACK has occurred */
+ if (FIELD_GET(NPCM_I2CST_NEGACK, i2cst)) {
+ npcm_i2c_irq_handle_nack(bus);
+ return 0;
+ }
+
+ /* Master mode: a Bus Error has been identified */
+ if (FIELD_GET(NPCM_I2CST_BER, i2cst)) {
+ npcm_i2c_irq_handle_ber(bus);
+ return 0;
+ }
+
+ /* EOB: a master End Of Busy (meaning STOP completed) */
+ if ((FIELD_GET(NPCM_I2CCTL1_EOBINTE,
+ ioread8(bus->reg + NPCM_I2CCTL1)) == 1) &&
+ (FIELD_GET(NPCM_I2CCST3_EO_BUSY,
+ ioread8(bus->reg + NPCM_I2CCST3)))) {
+ npcm_i2c_irq_handle_eob(bus);
+ return 0;
+ }
+
+ /* Address sent and requested stall occurred (Master mode) */
+ if (FIELD_GET(NPCM_I2CST_STASTR, i2cst)) {
+ npcm_i2c_irq_handle_stall_after_start(bus);
+ ret = 0;
+ }
+
+ /* SDA status is set - TX or RX, master */
+ if (FIELD_GET(NPCM_I2CST_SDAST, i2cst) ||
+ (bus->fifo_use &&
+ (npcm_i2c_tx_fifo_empty(bus) || npcm_i2c_rx_fifo_full(bus)))) {
+ npcm_i2c_irq_handle_sda(bus, i2cst);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/* recovery using TGCLK functionality of the module */
+static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap)
+{
+ u8 val;
+ u8 fif_cts;
+ bool done = false;
+ int status = -ENOTRECOVERABLE;
+ struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
+ /* Allow 3 bytes (27 toggles) to be read from the slave: */
+ int iter = 27;
+
+ if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1)) {
+ dev_dbg(bus->dev, "bus%d recovery skipped, bus not stuck",
+ bus->num);
+ npcm_i2c_reset(bus);
+ return status;
+ }
+
+ npcm_i2c_int_enable(bus, false);
+ npcm_i2c_disable(bus);
+ npcm_i2c_enable(bus);
+ iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
+ npcm_i2c_clear_tx_fifo(bus);
+ npcm_i2c_clear_rx_fifo(bus);
+ iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
+ iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
+ npcm_i2c_stall_after_start(bus, false);
+
+ /* select bank 1 for FIFO regs */
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+
+ /* clear FIFO and relevant status bits. */
+ fif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
+ fif_cts &= ~NPCM_I2CFIF_CTS_SLVRSTR;
+ fif_cts |= NPCM_I2CFIF_CTS_CLR_FIFO;
+ iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
+ npcm_i2c_set_fifo(bus, -1, 0);
+
+ /* Repeat the following sequence until SDA is released */
+ do {
+ /* Issue a single SCL toggle */
+ iowrite8(NPCM_I2CCST_TGSCL, bus->reg + NPCM_I2CCST);
+ usleep_range(20, 30);
+ /* If SDA line is inactive (high), stop */
+ if (npcm_i2c_get_SDA(_adap)) {
+ done = true;
+ status = 0;
+ }
+ } while (!done && iter--);
+
+ /* If SDA line is released: send start-addr-stop, to re-sync. */
+ if (npcm_i2c_get_SDA(_adap)) {
+ /* Send an address byte in write direction: */
+ npcm_i2c_wr_byte(bus, bus->dest_addr);
+ npcm_i2c_master_start(bus);
+ /* Wait until START condition is sent */
+ status = readx_poll_timeout(npcm_i2c_get_SCL, _adap, val, !val,
+ 20, 200);
+ /* If START condition was sent */
+ if (npcm_i2c_is_master(bus) > 0) {
+ usleep_range(20, 30);
+ npcm_i2c_master_stop(bus);
+ usleep_range(200, 500);
+ }
+ }
+ npcm_i2c_reset(bus);
+ npcm_i2c_int_enable(bus, true);
+
+ if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1))
+ status = 0;
+ else
+ status = -ENOTRECOVERABLE;
+ if (status) {
+ if (bus->rec_fail_cnt < ULLONG_MAX)
+ bus->rec_fail_cnt++;
+ } else {
+ if (bus->rec_succ_cnt < ULLONG_MAX)
+ bus->rec_succ_cnt++;
+ }
+ return status;
+}
+
+/* recovery using bit banging functionality of the module */
+static void npcm_i2c_recovery_init(struct i2c_adapter *_adap)
+{
+ struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
+ struct i2c_bus_recovery_info *rinfo = &bus->rinfo;
+
+ rinfo->recover_bus = npcm_i2c_recovery_tgclk;
+
+ /*
+ * npcm i2c HW allows direct reading of SCL and SDA.
+ * However, it does not support setting SCL and SDA directly.
+ * The recovery function can togle SCL when SDA is low (but not set)
+ * Getter functions used internally, and can be used externaly.
+ */
+ rinfo->get_scl = npcm_i2c_get_SCL;
+ rinfo->get_sda = npcm_i2c_get_SDA;
+ _adap->bus_recovery_info = rinfo;
+}
+
+/* SCLFRQ min/max field values */
+#define SCLFRQ_MIN 10
+#define SCLFRQ_MAX 511
+#define clk_coef(freq, mul) DIV_ROUND_UP((freq) * (mul), 1000000)
+
+/*
+ * npcm_i2c_init_clk: init HW timing parameters.
+ * NPCM7XX i2c module timing parameters are depenent on module core clk (APB)
+ * and bus frequency.
+ * 100kHz bus requires tSCL = 4 * SCLFRQ * tCLK. LT and HT are simetric.
+ * 400kHz bus requires assymetric HT and LT. A different equation is recomended
+ * by the HW designer, given core clock range (equations in comments below).
+ *
+ */
+static int npcm_i2c_init_clk(struct npcm_i2c *bus, u32 bus_freq_hz)
+{
+ u32 k1 = 0;
+ u32 k2 = 0;
+ u8 dbnct = 0;
+ u32 sclfrq = 0;
+ u8 hldt = 7;
+ u8 fast_mode = 0;
+ u32 src_clk_khz;
+ u32 bus_freq_khz;
+
+ src_clk_khz = bus->apb_clk / 1000;
+ bus_freq_khz = bus_freq_hz / 1000;
+ bus->bus_freq = bus_freq_hz;
+
+ /* 100KHz and below: */
+ if (bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ) {
+ sclfrq = src_clk_khz / (bus_freq_khz * 4);
+
+ if (sclfrq < SCLFRQ_MIN || sclfrq > SCLFRQ_MAX)
+ return -EDOM;
+
+ if (src_clk_khz >= 40000)
+ hldt = 17;
+ else if (src_clk_khz >= 12500)
+ hldt = 15;
+ else
+ hldt = 7;
+ }
+
+ /* 400KHz: */
+ else if (bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ) {
+ sclfrq = 0;
+ fast_mode = I2CCTL3_400K_MODE;
+
+ if (src_clk_khz < 7500)
+ /* 400KHZ cannot be supported for core clock < 7.5MHz */
+ return -EDOM;
+
+ else if (src_clk_khz >= 50000) {
+ k1 = 80;
+ k2 = 48;
+ hldt = 12;
+ dbnct = 7;
+ }
+
+ /* Master or Slave with frequency > 25MHz */
+ else if (src_clk_khz > 25000) {
+ hldt = clk_coef(src_clk_khz, 300) + 7;
+ k1 = clk_coef(src_clk_khz, 1600);
+ k2 = clk_coef(src_clk_khz, 900);
+ }
+ }
+
+ /* 1MHz: */
+ else if (bus_freq_hz <= I2C_MAX_FAST_MODE_PLUS_FREQ) {
+ sclfrq = 0;
+ fast_mode = I2CCTL3_400K_MODE;
+
+ /* 1MHZ cannot be supported for core clock < 24 MHz */
+ if (src_clk_khz < 24000)
+ return -EDOM;
+
+ k1 = clk_coef(src_clk_khz, 620);
+ k2 = clk_coef(src_clk_khz, 380);
+
+ /* Core clk > 40 MHz */
+ if (src_clk_khz > 40000) {
+ /*
+ * Set HLDT:
+ * SDA hold time: (HLDT-7) * T(CLK) >= 120
+ * HLDT = 120/T(CLK) + 7 = 120 * FREQ(CLK) + 7
+ */
+ hldt = clk_coef(src_clk_khz, 120) + 7;
+ } else {
+ hldt = 7;
+ dbnct = 2;
+ }
+ }
+
+ /* Frequency larger than 1 MHz is not supported */
+ else
+ return -EINVAL;
+
+ if (bus_freq_hz >= I2C_MAX_FAST_MODE_FREQ) {
+ k1 = round_up(k1, 2);
+ k2 = round_up(k2 + 1, 2);
+ if (k1 < SCLFRQ_MIN || k1 > SCLFRQ_MAX ||
+ k2 < SCLFRQ_MIN || k2 > SCLFRQ_MAX)
+ return -EDOM;
+ }
+
+ /* write sclfrq value. bits [6:0] are in I2CCTL2 reg */
+ iowrite8(FIELD_PREP(I2CCTL2_SCLFRQ6_0, sclfrq & 0x7F),
+ bus->reg + NPCM_I2CCTL2);
+
+ /* bits [8:7] are in I2CCTL3 reg */
+ iowrite8(fast_mode | FIELD_PREP(I2CCTL3_SCLFRQ8_7, (sclfrq >> 7) & 0x3),
+ bus->reg + NPCM_I2CCTL3);
+
+ /* Select Bank 0 to access NPCM_I2CCTL4/NPCM_I2CCTL5 */
+ npcm_i2c_select_bank(bus, I2C_BANK_0);
+
+ if (bus_freq_hz >= I2C_MAX_FAST_MODE_FREQ) {
+ /*
+ * Set SCL Low/High Time:
+ * k1 = 2 * SCLLT7-0 -> Low Time = k1 / 2
+ * k2 = 2 * SCLLT7-0 -> High Time = k2 / 2
+ */
+ iowrite8(k1 / 2, bus->reg + NPCM_I2CSCLLT);
+ iowrite8(k2 / 2, bus->reg + NPCM_I2CSCLHT);
+
+ iowrite8(dbnct, bus->reg + NPCM_I2CCTL5);
+ }
+
+ iowrite8(hldt, bus->reg + NPCM_I2CCTL4);
+
+ /* Return to Bank 1, and stay there by default: */
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+
+ return 0;
+}
+
+static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode,
+ u32 bus_freq_hz)
+{
+ u8 val;
+ int ret;
+
+ /* Check whether module already enabled or frequency is out of bounds */
+ if ((bus->state != I2C_DISABLE && bus->state != I2C_IDLE) ||
+ bus_freq_hz < I2C_FREQ_MIN_HZ || bus_freq_hz > I2C_FREQ_MAX_HZ)
+ return -EINVAL;
+
+ npcm_i2c_disable(bus);
+
+ /* Configure FIFO mode : */
+ if (FIELD_GET(I2C_VER_FIFO_EN, ioread8(bus->reg + I2C_VER))) {
+ bus->fifo_use = true;
+ npcm_i2c_select_bank(bus, I2C_BANK_0);
+ val = ioread8(bus->reg + NPCM_I2CFIF_CTL);
+ val |= NPCM_I2CFIF_CTL_FIFO_EN;
+ iowrite8(val, bus->reg + NPCM_I2CFIF_CTL);
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+ } else {
+ bus->fifo_use = false;
+ }
+
+ /* Configure I2C module clock frequency */
+ ret = npcm_i2c_init_clk(bus, bus_freq_hz);
+ if (ret) {
+ dev_err(bus->dev, "npcm_i2c_init_clk failed\n");
+ return ret;
+ }
+
+ /* Enable module (before configuring CTL1) */
+ npcm_i2c_enable(bus);
+ bus->state = I2C_IDLE;
+ val = ioread8(bus->reg + NPCM_I2CCTL1);
+ val = (val | NPCM_I2CCTL1_NMINTE) & ~NPCM_I2CCTL1_RWS;
+ iowrite8(val, bus->reg + NPCM_I2CCTL1);
+
+ npcm_i2c_int_enable(bus, true);
+
+ npcm_i2c_reset(bus);
+
+ return 0;
+}
+
+static int __npcm_i2c_init(struct npcm_i2c *bus, struct platform_device *pdev)
+{
+ u32 clk_freq_hz;
+ int ret;
+
+ /* Initialize the internal data structures */
+ bus->state = I2C_DISABLE;
+ bus->master_or_slave = I2C_SLAVE;
+ bus->int_time_stamp = 0;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ bus->slave = NULL;
+#endif
+
+ ret = device_property_read_u32(&pdev->dev, "clock-frequency",
+ &clk_freq_hz);
+ if (ret) {
+ dev_info(&pdev->dev, "Could not read clock-frequency property");
+ clk_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
+ }
+
+ ret = npcm_i2c_init_module(bus, I2C_MASTER, clk_freq_hz);
+ if (ret) {
+ dev_err(&pdev->dev, "npcm_i2c_init_module failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static irqreturn_t npcm_i2c_bus_irq(int irq, void *dev_id)
+{
+ struct npcm_i2c *bus = dev_id;
+
+ if (npcm_i2c_is_master(bus))
+ bus->master_or_slave = I2C_MASTER;
+
+ if (bus->master_or_slave == I2C_MASTER) {
+ bus->int_time_stamp = jiffies;
+ if (!npcm_i2c_int_master_handler(bus))
+ return IRQ_HANDLED;
+ }
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (bus->slave) {
+ bus->master_or_slave = I2C_SLAVE;
+ return npcm_i2c_int_slave_handler(bus);
+ }
+#endif
+ return IRQ_NONE;
+}
+
+static bool npcm_i2c_master_start_xmit(struct npcm_i2c *bus,
+ u8 slave_addr, u16 nwrite, u16 nread,
+ u8 *write_data, u8 *read_data,
+ bool use_PEC, bool use_read_block)
+{
+ if (bus->state != I2C_IDLE) {
+ bus->cmd_err = -EBUSY;
+ return false;
+ }
+ bus->dest_addr = slave_addr << 1;
+ bus->wr_buf = write_data;
+ bus->wr_size = nwrite;
+ bus->wr_ind = 0;
+ bus->rd_buf = read_data;
+ bus->rd_size = nread;
+ bus->rd_ind = 0;
+ bus->PEC_use = 0;
+
+ /* for tx PEC is appended to buffer from i2c IF. PEC flag is ignored */
+ if (nread)
+ bus->PEC_use = use_PEC;
+
+ bus->read_block_use = use_read_block;
+ if (nread && !nwrite)
+ bus->operation = I2C_READ_OPER;
+ else
+ bus->operation = I2C_WRITE_OPER;
+ if (bus->fifo_use) {
+ u8 i2cfif_cts;
+
+ npcm_i2c_select_bank(bus, I2C_BANK_1);
+ /* clear FIFO and relevant status bits. */
+ i2cfif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
+ i2cfif_cts &= ~NPCM_I2CFIF_CTS_SLVRSTR;
+ i2cfif_cts |= NPCM_I2CFIF_CTS_CLR_FIFO;
+ iowrite8(i2cfif_cts, bus->reg + NPCM_I2CFIF_CTS);
+ }
+
+ bus->state = I2C_IDLE;
+ npcm_i2c_stall_after_start(bus, true);
+ npcm_i2c_master_start(bus);
+ return true;
+}
+
+static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct npcm_i2c *bus = container_of(adap, struct npcm_i2c, adap);
+ struct i2c_msg *msg0, *msg1;
+ unsigned long time_left, flags;
+ u16 nwrite, nread;
+ u8 *write_data, *read_data;
+ u8 slave_addr;
+ int timeout;
+ int ret = 0;
+ bool read_block = false;
+ bool read_PEC = false;
+ u8 bus_busy;
+ unsigned long timeout_usec;
+
+ if (bus->state == I2C_DISABLE) {
+ dev_err(bus->dev, "I2C%d module is disabled", bus->num);
+ return -EINVAL;
+ }
+
+ msg0 = &msgs[0];
+ slave_addr = msg0->addr;
+ if (msg0->flags & I2C_M_RD) { /* read */
+ nwrite = 0;
+ write_data = NULL;
+ read_data = msg0->buf;
+ if (msg0->flags & I2C_M_RECV_LEN) {
+ nread = 1;
+ read_block = true;
+ if (msg0->flags & I2C_CLIENT_PEC)
+ read_PEC = true;
+ } else {
+ nread = msg0->len;
+ }
+ } else { /* write */
+ nwrite = msg0->len;
+ write_data = msg0->buf;
+ nread = 0;
+ read_data = NULL;
+ if (num == 2) {
+ msg1 = &msgs[1];
+ read_data = msg1->buf;
+ if (msg1->flags & I2C_M_RECV_LEN) {
+ nread = 1;
+ read_block = true;
+ if (msg1->flags & I2C_CLIENT_PEC)
+ read_PEC = true;
+ } else {
+ nread = msg1->len;
+ read_block = false;
+ }
+ }
+ }
+
+ /* Adaptive TimeOut: astimated time in usec + 100% margin */
+ timeout_usec = (2 * 10000 / bus->bus_freq) * (2 + nread + nwrite);
+ timeout = max(msecs_to_jiffies(35), usecs_to_jiffies(timeout_usec));
+ if (nwrite >= 32 * 1024 || nread >= 32 * 1024) {
+ dev_err(bus->dev, "i2c%d buffer too big\n", bus->num);
+ return -EINVAL;
+ }
+
+ time_left = jiffies + msecs_to_jiffies(DEFAULT_STALL_COUNT) + 1;
+ do {
+ /*
+ * we must clear slave address immediately when the bus is not
+ * busy, so we spinlock it, but we don't keep the lock for the
+ * entire while since it is too long.
+ */
+ spin_lock_irqsave(&bus->lock, flags);
+ bus_busy = ioread8(bus->reg + NPCM_I2CCST) & NPCM_I2CCST_BB;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (!bus_busy && bus->slave)
+ iowrite8((bus->slave->addr & 0x7F),
+ bus->reg + NPCM_I2CADDR1);
+#endif
+ spin_unlock_irqrestore(&bus->lock, flags);
+
+ } while (time_is_after_jiffies(time_left) && bus_busy);
+
+ if (bus_busy) {
+ iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
+ npcm_i2c_reset(bus);
+ i2c_recover_bus(adap);
+ return -EAGAIN;
+ }
+
+ npcm_i2c_init_params(bus);
+ bus->dest_addr = slave_addr;
+ bus->msgs = msgs;
+ bus->msgs_num = num;
+ bus->cmd_err = 0;
+ bus->read_block_use = read_block;
+
+ reinit_completion(&bus->cmd_complete);
+ if (!npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread,
+ write_data, read_data, read_PEC,
+ read_block))
+ ret = -EBUSY;
+
+ if (ret != -EBUSY) {
+ time_left = wait_for_completion_timeout(&bus->cmd_complete,
+ timeout);
+
+ if (time_left == 0) {
+ if (bus->timeout_cnt < ULLONG_MAX)
+ bus->timeout_cnt++;
+ if (bus->master_or_slave == I2C_MASTER) {
+ i2c_recover_bus(adap);
+ bus->cmd_err = -EIO;
+ bus->state = I2C_IDLE;
+ }
+ }
+ }
+ ret = bus->cmd_err;
+
+ /* if there was BER, check if need to recover the bus: */
+ if (bus->cmd_err == -EAGAIN)
+ ret = i2c_recover_bus(adap);
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ /* reenable slave if it was enabled */
+ if (bus->slave)
+ iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN,
+ bus->reg + NPCM_I2CADDR1);
+#endif
+ return bus->cmd_err;
+}
+
+static u32 npcm_i2c_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_EMUL |
+ I2C_FUNC_SMBUS_BLOCK_DATA |
+ I2C_FUNC_SMBUS_PEC |
+ I2C_FUNC_SLAVE;
+}
+
+static const struct i2c_adapter_quirks npcm_i2c_quirks = {
+ .max_read_len = 32768,
+ .max_write_len = 32768,
+ .flags = I2C_AQ_COMB_WRITE_THEN_READ,
+};
+
+static const struct i2c_algorithm npcm_i2c_algo = {
+ .master_xfer = npcm_i2c_master_xfer,
+ .functionality = npcm_i2c_functionality,
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ .reg_slave = npcm_i2c_reg_slave,
+ .unreg_slave = npcm_i2c_unreg_slave,
+#endif
+};
+
+/* i2c debugfs directory: used to keep health monitor of i2c devices */
+static struct dentry *npcm_i2c_debugfs_dir;
+
+static void npcm_i2c_init_debugfs(struct platform_device *pdev,
+ struct npcm_i2c *bus)
+{
+ struct dentry *d;
+
+ if (!npcm_i2c_debugfs_dir)
+ return;
+ d = debugfs_create_dir(dev_name(&pdev->dev), npcm_i2c_debugfs_dir);
+ if (IS_ERR_OR_NULL(d))
+ return;
+ debugfs_create_u64("ber_cnt", 0444, d, &bus->ber_cnt);
+ debugfs_create_u64("nack_cnt", 0444, d, &bus->nack_cnt);
+ debugfs_create_u64("rec_succ_cnt", 0444, d, &bus->rec_succ_cnt);
+ debugfs_create_u64("rec_fail_cnt", 0444, d, &bus->rec_fail_cnt);
+ debugfs_create_u64("timeout_cnt", 0444, d, &bus->timeout_cnt);
+
+ bus->debugfs = d;
+}
+
+static int npcm_i2c_probe_bus(struct platform_device *pdev)
+{
+ struct npcm_i2c *bus;
+ struct i2c_adapter *adap;
+ struct clk *i2c_clk;
+ static struct regmap *gcr_regmap;
+ static struct regmap *clk_regmap;
+ int irq;
+ int ret;
+
+ bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
+ if (!bus)
+ return -ENOMEM;
+
+ bus->dev = &pdev->dev;
+
+ bus->num = of_alias_get_id(pdev->dev.of_node, "i2c");
+ /* core clk must be acquired to calculate module timing settings */
+ i2c_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(i2c_clk))
+ return PTR_ERR(i2c_clk);
+ bus->apb_clk = clk_get_rate(i2c_clk);
+
+ gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
+ if (IS_ERR(gcr_regmap))
+ return PTR_ERR(gcr_regmap);
+ regmap_write(gcr_regmap, NPCM_I2CSEGCTL, NPCM_I2CSEGCTL_INIT_VAL);
+
+ clk_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-clk");
+ if (IS_ERR(clk_regmap))
+ return PTR_ERR(clk_regmap);
+
+ bus->reg = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(bus->reg))
+ return PTR_ERR(bus->reg);
+
+ spin_lock_init(&bus->lock);
+ init_completion(&bus->cmd_complete);
+
+ adap = &bus->adap;
+ adap->owner = THIS_MODULE;
+ adap->retries = 3;
+ adap->timeout = HZ;
+ adap->algo = &npcm_i2c_algo;
+ adap->quirks = &npcm_i2c_quirks;
+ adap->algo_data = bus;
+ adap->dev.parent = &pdev->dev;
+ adap->dev.of_node = pdev->dev.of_node;
+ adap->nr = pdev->id;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0,
+ dev_name(bus->dev), bus);
+ if (ret)
+ return ret;
+
+ ret = __npcm_i2c_init(bus, pdev);
+ if (ret)
+ return ret;
+
+ npcm_i2c_recovery_init(adap);
+
+ i2c_set_adapdata(adap, bus);
+
+ snprintf(bus->adap.name, sizeof(bus->adap.name), "npcm_i2c_%d",
+ bus->num);
+ ret = i2c_add_numbered_adapter(&bus->adap);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, bus);
+ npcm_i2c_init_debugfs(pdev, bus);
+ return 0;
+}
+
+static int npcm_i2c_remove_bus(struct platform_device *pdev)
+{
+ unsigned long lock_flags;
+ struct npcm_i2c *bus = platform_get_drvdata(pdev);
+
+ debugfs_remove_recursive(bus->debugfs);
+ spin_lock_irqsave(&bus->lock, lock_flags);
+ npcm_i2c_disable(bus);
+ spin_unlock_irqrestore(&bus->lock, lock_flags);
+ i2c_del_adapter(&bus->adap);
+ return 0;
+}
+
+static const struct of_device_id npcm_i2c_bus_of_table[] = {
+ { .compatible = "nuvoton,npcm750-i2c", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, npcm_i2c_bus_of_table);
+
+static struct platform_driver npcm_i2c_bus_driver = {
+ .probe = npcm_i2c_probe_bus,
+ .remove = npcm_i2c_remove_bus,
+ .driver = {
+ .name = "nuvoton-i2c",
+ .of_match_table = npcm_i2c_bus_of_table,
+ }
+};
+
+static int __init npcm_i2c_init(void)
+{
+ npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL);
+ platform_driver_register(&npcm_i2c_bus_driver);
+ return 0;
+}
+module_init(npcm_i2c_init);
+
+static void __exit npcm_i2c_exit(void)
+{
+ platform_driver_unregister(&npcm_i2c_bus_driver);
+ debugfs_remove_recursive(npcm_i2c_debugfs_dir);
+}
+module_exit(npcm_i2c_exit);
+
+MODULE_AUTHOR("Avi Fishman <avi.fishman@gmail.com>");
+MODULE_AUTHOR("Tali Perry <tali.perry@nuvoton.com>");
+MODULE_AUTHOR("Tyrone Ting <kfting@nuvoton.com>");
+MODULE_DESCRIPTION("Nuvoton I2C Bus Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c
index f5d25ce00f03..f480105000b8 100644
--- a/drivers/i2c/busses/i2c-nvidia-gpu.c
+++ b/drivers/i2c/busses/i2c-nvidia-gpu.c
@@ -277,10 +277,7 @@ static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq)
i2cd->gpu_ccgx_ucsi->irq = irq;
i2cd->gpu_ccgx_ucsi->properties = ccgx_props;
i2cd->ccgx_client = i2c_new_client_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi);
- if (IS_ERR(i2cd->ccgx_client))
- return PTR_ERR(i2cd->ccgx_client);
-
- return 0;
+ return PTR_ERR_OR_ZERO(i2cd->ccgx_client);
}
static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c
index 64bda83e65ac..0c227963c8d6 100644
--- a/drivers/i2c/busses/i2c-octeon-platdrv.c
+++ b/drivers/i2c/busses/i2c-octeon-platdrv.c
@@ -136,7 +136,6 @@ static int octeon_i2c_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
int irq, result = 0, hlc_irq = 0;
- struct resource *res_mem;
struct octeon_i2c *i2c;
bool cn78xx_style;
@@ -167,8 +166,7 @@ static int octeon_i2c_probe(struct platform_device *pdev)
i2c->roff.twsi_int = 0x10;
i2c->roff.sw_twsi_ext = 0x18;
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->twsi_base = devm_ioremap_resource(&pdev->dev, res_mem);
+ i2c->twsi_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->twsi_base)) {
result = PTR_ERR(i2c->twsi_base);
goto out;
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 71b4637c86b7..175c590b93b7 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1365,10 +1365,8 @@ omap_i2c_probe(struct platform_device *pdev)
u16 minor, major;
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no irq resource?\n");
+ if (irq < 0)
return irq;
- }
omap = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
if (!omap)
diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c
index 3ab8be62c581..672f1f239bd6 100644
--- a/drivers/i2c/busses/i2c-owl.c
+++ b/drivers/i2c/busses/i2c-owl.c
@@ -396,23 +396,19 @@ static int owl_i2c_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct owl_i2c_dev *i2c_dev;
- struct resource *res;
int ret, irq;
i2c_dev = devm_kzalloc(dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c_dev->base = devm_ioremap_resource(dev, res);
+ i2c_dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(dev, "failed to get IRQ number\n");
+ if (irq < 0)
return irq;
- }
if (of_property_read_u32(dev->of_node, "clock-frequency",
&i2c_dev->bus_freq))
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index 635dd697ac0b..546426a470cc 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -149,8 +149,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
if (!i2c)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ i2c->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(i2c->reg_base))
return PTR_ERR(i2c->reg_base);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 30ded6422e7b..69740a4ff1db 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -977,7 +977,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
}
if (dev->vendor == PCI_VENDOR_ID_AMD &&
- dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) {
+ (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS ||
+ dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) {
retval = piix4_setup_sb800(dev, id, 1);
}
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 686c06f31625..5d7207c10f1d 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -720,7 +720,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
alg_data->irq = platform_get_irq(pdev, 0);
if (alg_data->irq < 0) {
- dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n");
ret = alg_data->irq;
goto out_clock;
}
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index d565714c1f13..3e38e114948b 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -207,18 +207,18 @@ static u32 i2c_powermac_get_addr(struct i2c_adapter *adap,
struct pmac_i2c_bus *bus,
struct device_node *node)
{
- const __be32 *prop;
- int len;
+ u32 prop;
+ int ret;
/* First check for valid "reg" */
- prop = of_get_property(node, "reg", &len);
- if (prop && (len >= sizeof(int)))
- return (be32_to_cpup(prop) & 0xff) >> 1;
+ ret = of_property_read_u32(node, "reg", &prop);
+ if (ret == 0)
+ return (prop & 0xff) >> 1;
/* Then check old-style "i2c-address" */
- prop = of_get_property(node, "i2c-address", &len);
- if (prop && (len >= sizeof(int)))
- return (be32_to_cpup(prop) & 0xff) >> 1;
+ ret = of_property_read_u32(node, "i2c-address", &prop);
+ if (ret == 0)
+ return (prop & 0xff) >> 1;
/* Now handle some devices with missing "reg" properties */
if (of_node_name_eq(node, "cereal"))
@@ -315,7 +315,7 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap,
{
struct i2c_client *newdev;
struct device_node *node;
- bool found_onyx = 0;
+ bool found_onyx = false;
/*
* In some cases we end up with the via-pmu node itself, in this
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 466e4f681d7a..35ca2c02c9b9 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -16,25 +16,120 @@
* Dec 2004: Added support for PXA27x and slave device probing [Liam Girdwood]
* Feb 2005: Rework slave mode handling [RMK]
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
+#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/io.h>
#include <linux/platform_data/i2c-pxa.h>
+#include <linux/slab.h>
+
+/* I2C register field definitions */
+#define IBMR_SDAS (1 << 0)
+#define IBMR_SCLS (1 << 1)
+
+#define ICR_START (1 << 0) /* start bit */
+#define ICR_STOP (1 << 1) /* stop bit */
+#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */
+#define ICR_TB (1 << 3) /* transfer byte bit */
+#define ICR_MA (1 << 4) /* master abort */
+#define ICR_SCLE (1 << 5) /* master clock enable */
+#define ICR_IUE (1 << 6) /* unit enable */
+#define ICR_GCD (1 << 7) /* general call disable */
+#define ICR_ITEIE (1 << 8) /* enable tx interrupts */
+#define ICR_IRFIE (1 << 9) /* enable rx interrupts */
+#define ICR_BEIE (1 << 10) /* enable bus error ints */
+#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */
+#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */
+#define ICR_SADIE (1 << 13) /* slave address detected int enable */
+#define ICR_UR (1 << 14) /* unit reset */
+#define ICR_FM (1 << 15) /* fast mode */
+#define ICR_HS (1 << 16) /* High Speed mode */
+#define ICR_A3700_FM (1 << 16) /* fast mode for armada-3700 */
+#define ICR_A3700_HS (1 << 17) /* high speed mode for armada-3700 */
+#define ICR_GPIOEN (1 << 19) /* enable GPIO mode for SCL in HS */
+
+#define ISR_RWM (1 << 0) /* read/write mode */
+#define ISR_ACKNAK (1 << 1) /* ack/nak status */
+#define ISR_UB (1 << 2) /* unit busy */
+#define ISR_IBB (1 << 3) /* bus busy */
+#define ISR_SSD (1 << 4) /* slave stop detected */
+#define ISR_ALD (1 << 5) /* arbitration loss detected */
+#define ISR_ITE (1 << 6) /* tx buffer empty */
+#define ISR_IRF (1 << 7) /* rx buffer full */
+#define ISR_GCAD (1 << 8) /* general call address detected */
+#define ISR_SAD (1 << 9) /* slave address detected */
+#define ISR_BED (1 << 10) /* bus error no ACK/NAK */
+
+#define ILCR_SLV_SHIFT 0
+#define ILCR_SLV_MASK (0x1FF << ILCR_SLV_SHIFT)
+#define ILCR_FLV_SHIFT 9
+#define ILCR_FLV_MASK (0x1FF << ILCR_FLV_SHIFT)
+#define ILCR_HLVL_SHIFT 18
+#define ILCR_HLVL_MASK (0x1FF << ILCR_HLVL_SHIFT)
+#define ILCR_HLVH_SHIFT 27
+#define ILCR_HLVH_MASK (0x1F << ILCR_HLVH_SHIFT)
+
+#define IWCR_CNT_SHIFT 0
+#define IWCR_CNT_MASK (0x1F << IWCR_CNT_SHIFT)
+#define IWCR_HS_CNT1_SHIFT 5
+#define IWCR_HS_CNT1_MASK (0x1F << IWCR_HS_CNT1_SHIFT)
+#define IWCR_HS_CNT2_SHIFT 10
+#define IWCR_HS_CNT2_MASK (0x1F << IWCR_HS_CNT2_SHIFT)
+
+/* need a longer timeout if we're dealing with the fact we may well be
+ * looking at a multi-master environment
+ */
+#define DEF_TIMEOUT 32
+
+#define NO_SLAVE (-ENXIO)
+#define BUS_ERROR (-EREMOTEIO)
+#define XFER_NAKED (-ECONNREFUSED)
+#define I2C_RETRY (-2000) /* an error has occurred retry transmit */
+
+/* ICR initialize bit values
+ *
+ * 15 FM 0 (100 kHz operation)
+ * 14 UR 0 (No unit reset)
+ * 13 SADIE 0 (Disables the unit from interrupting on slave addresses
+ * matching its slave address)
+ * 12 ALDIE 0 (Disables the unit from interrupt when it loses arbitration
+ * in master mode)
+ * 11 SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode)
+ * 10 BEIE 1 (Enable interrupts from detected bus errors, no ACK sent)
+ * 9 IRFIE 1 (Enable interrupts from full buffer received)
+ * 8 ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty)
+ * 7 GCD 1 (Disables i2c unit response to general call messages as a slave)
+ * 6 IUE 0 (Disable unit until we change settings)
+ * 5 SCLE 1 (Enables the i2c clock output for master mode (drives SCL)
+ * 4 MA 0 (Only send stop with the ICR stop bit)
+ * 3 TB 0 (We are not transmitting a byte initially)
+ * 2 ACKNAK 0 (Send an ACK after the unit receives a byte)
+ * 1 STOP 0 (Do not send a STOP)
+ * 0 START 0 (Do not send a START)
+ */
+#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#include <asm/irq.h>
+/* I2C status register init values
+ *
+ * 10 BED 1 (Clear bus error detected)
+ * 9 SAD 1 (Clear slave address detected)
+ * 7 IRF 1 (Clear IDBR Receive Full)
+ * 6 ITE 1 (Clear IDBR Transmit Empty)
+ * 5 ALD 1 (Clear Arbitration Loss Detected)
+ * 4 SSD 1 (Clear Slave Stop Detected)
+ */
+#define I2C_ISR_INIT 0x7FF /* status register init */
struct pxa_reg_layout {
u32 ibmr;
@@ -56,12 +151,7 @@ enum pxa_i2c_types {
REGS_A3700,
};
-#define ICR_BUSMODE_FM (1 << 16) /* shifted fast mode for armada-3700 */
-#define ICR_BUSMODE_HS (1 << 17) /* shifted high speed mode for armada-3700 */
-
-/*
- * I2C registers definitions
- */
+/* I2C register layout definitions */
static struct pxa_reg_layout pxa_reg_layout[] = {
[REGS_PXA2XX] = {
.ibmr = 0x00,
@@ -69,6 +159,8 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.icr = 0x10,
.isr = 0x18,
.isar = 0x20,
+ .fm = ICR_FM,
+ .hs = ICR_HS,
},
[REGS_PXA3XX] = {
.ibmr = 0x00,
@@ -76,6 +168,8 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.icr = 0x08,
.isr = 0x0c,
.isar = 0x10,
+ .fm = ICR_FM,
+ .hs = ICR_HS,
},
[REGS_CE4100] = {
.ibmr = 0x14,
@@ -83,6 +177,8 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.icr = 0x00,
.isr = 0x04,
/* no isar register */
+ .fm = ICR_FM,
+ .hs = ICR_HS,
},
[REGS_PXA910] = {
.ibmr = 0x00,
@@ -92,6 +188,8 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.isar = 0x20,
.ilcr = 0x28,
.iwcr = 0x30,
+ .fm = ICR_FM,
+ .hs = ICR_HS,
},
[REGS_A3700] = {
.ibmr = 0x00,
@@ -99,11 +197,20 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.icr = 0x08,
.isr = 0x0c,
.isar = 0x10,
- .fm = ICR_BUSMODE_FM,
- .hs = ICR_BUSMODE_HS,
+ .fm = ICR_A3700_FM,
+ .hs = ICR_A3700_HS,
},
};
+static const struct of_device_id i2c_pxa_dt_ids[] = {
+ { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
+ { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
+ { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
+ { .compatible = "marvell,armada-3700-i2c", .data = (void *)REGS_A3700 },
+ {}
+};
+MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
+
static const struct platform_device_id i2c_pxa_id_table[] = {
{ "pxa2xx-i2c", REGS_PXA2XX },
{ "pxa3xx-pwri2c", REGS_PXA3XX },
@@ -114,58 +221,6 @@ static const struct platform_device_id i2c_pxa_id_table[] = {
};
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
-/*
- * I2C bit definitions
- */
-
-#define ICR_START (1 << 0) /* start bit */
-#define ICR_STOP (1 << 1) /* stop bit */
-#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */
-#define ICR_TB (1 << 3) /* transfer byte bit */
-#define ICR_MA (1 << 4) /* master abort */
-#define ICR_SCLE (1 << 5) /* master clock enable */
-#define ICR_IUE (1 << 6) /* unit enable */
-#define ICR_GCD (1 << 7) /* general call disable */
-#define ICR_ITEIE (1 << 8) /* enable tx interrupts */
-#define ICR_IRFIE (1 << 9) /* enable rx interrupts */
-#define ICR_BEIE (1 << 10) /* enable bus error ints */
-#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */
-#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */
-#define ICR_SADIE (1 << 13) /* slave address detected int enable */
-#define ICR_UR (1 << 14) /* unit reset */
-#define ICR_FM (1 << 15) /* fast mode */
-#define ICR_HS (1 << 16) /* High Speed mode */
-#define ICR_GPIOEN (1 << 19) /* enable GPIO mode for SCL in HS */
-
-#define ISR_RWM (1 << 0) /* read/write mode */
-#define ISR_ACKNAK (1 << 1) /* ack/nak status */
-#define ISR_UB (1 << 2) /* unit busy */
-#define ISR_IBB (1 << 3) /* bus busy */
-#define ISR_SSD (1 << 4) /* slave stop detected */
-#define ISR_ALD (1 << 5) /* arbitration loss detected */
-#define ISR_ITE (1 << 6) /* tx buffer empty */
-#define ISR_IRF (1 << 7) /* rx buffer full */
-#define ISR_GCAD (1 << 8) /* general call address detected */
-#define ISR_SAD (1 << 9) /* slave address detected */
-#define ISR_BED (1 << 10) /* bus error no ACK/NAK */
-
-/* bit field shift & mask */
-#define ILCR_SLV_SHIFT 0
-#define ILCR_SLV_MASK (0x1FF << ILCR_SLV_SHIFT)
-#define ILCR_FLV_SHIFT 9
-#define ILCR_FLV_MASK (0x1FF << ILCR_FLV_SHIFT)
-#define ILCR_HLVL_SHIFT 18
-#define ILCR_HLVL_MASK (0x1FF << ILCR_HLVL_SHIFT)
-#define ILCR_HLVH_SHIFT 27
-#define ILCR_HLVH_MASK (0x1F << ILCR_HLVH_SHIFT)
-
-#define IWCR_CNT_SHIFT 0
-#define IWCR_CNT_MASK (0x1F << IWCR_CNT_SHIFT)
-#define IWCR_HS_CNT1_SHIFT 5
-#define IWCR_HS_CNT1_MASK (0x1F << IWCR_HS_CNT1_SHIFT)
-#define IWCR_HS_CNT2_SHIFT 10
-#define IWCR_HS_CNT2_MASK (0x1F << IWCR_HS_CNT2_SHIFT)
-
struct pxa_i2c {
spinlock_t lock;
wait_queue_head_t wait;
@@ -207,6 +262,11 @@ struct pxa_i2c {
bool highmode_enter;
u32 fm_mask;
u32 hs_mask;
+
+ struct i2c_bus_recovery_info recovery;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pinctrl_default;
+ struct pinctrl_state *pinctrl_recovery;
};
#define _IBMR(i2c) ((i2c)->reg_ibmr)
@@ -234,13 +294,14 @@ struct bits {
static inline void
decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
{
- printk("%s %08x: ", prefix, val);
+ printk("%s %08x:", prefix, val);
while (num--) {
const char *str = val & bits->mask ? bits->set : bits->unset;
if (str)
- printk("%s ", str);
+ pr_cont(" %s", str);
bits++;
}
+ pr_cont("\n");
}
static const struct bits isr_bits[] = {
@@ -260,7 +321,6 @@ static const struct bits isr_bits[] = {
static void decode_ISR(unsigned int val)
{
decode_bits(KERN_DEBUG "ISR", isr_bits, ARRAY_SIZE(isr_bits), val);
- printk("\n");
}
static const struct bits icr_bits[] = {
@@ -285,7 +345,6 @@ static const struct bits icr_bits[] = {
static void decode_ICR(unsigned int val)
{
decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val);
- printk("\n");
}
#endif
@@ -311,11 +370,10 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
dev_err(dev, "IBMR: %08x IDBR: %08x ICR: %08x ISR: %08x\n",
readl(_IBMR(i2c)), readl(_IDBR(i2c)), readl(_ICR(i2c)),
readl(_ISR(i2c)));
- dev_dbg(dev, "log: ");
+ dev_err(dev, "log:");
for (i = 0; i < i2c->irqlogidx; i++)
- pr_debug("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
-
- pr_debug("\n");
+ pr_cont(" [%03x:%05x]", i2c->isrlog[i], i2c->icrlog[i]);
+ pr_cont("\n");
}
#else /* ifdef DEBUG */
@@ -330,7 +388,6 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
#endif /* ifdef DEBUG / else */
static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
-static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
{
@@ -346,7 +403,7 @@ static void i2c_pxa_abort(struct pxa_i2c *i2c)
return;
}
- while ((i > 0) && (readl(_IBMR(i2c)) & 0x1) == 0) {
+ while ((i > 0) && (readl(_IBMR(i2c)) & IBMR_SDAS) == 0) {
unsigned long icr = readl(_ICR(i2c));
icr &= ~ICR_START;
@@ -367,19 +424,26 @@ static void i2c_pxa_abort(struct pxa_i2c *i2c)
static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
{
int timeout = DEF_TIMEOUT;
+ u32 isr;
+
+ while (1) {
+ isr = readl(_ISR(i2c));
+ if (!(isr & (ISR_IBB | ISR_UB)))
+ return 0;
- while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
- if ((readl(_ISR(i2c)) & ISR_SAD) != 0)
+ if (isr & ISR_SAD)
timeout += 4;
+ if (!timeout--)
+ break;
+
msleep(2);
show_state(i2c);
}
- if (timeout < 0)
- show_state(i2c);
+ show_state(i2c);
- return timeout < 0 ? I2C_RETRY : 0;
+ return I2C_RETRY;
}
static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
@@ -401,7 +465,8 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
* quick check of the i2c lines themselves to ensure they've
* gone high...
*/
- if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 && readl(_IBMR(i2c)) == 3) {
+ if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 &&
+ readl(_IBMR(i2c)) == (IBMR_SCLS | IBMR_SDAS)) {
if (i2c_debug > 0)
dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
return 1;
@@ -501,13 +566,8 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
#define i2c_pxa_set_slave(i2c, err) do { } while (0)
#endif
-static void i2c_pxa_reset(struct pxa_i2c *i2c)
+static void i2c_pxa_do_reset(struct pxa_i2c *i2c)
{
- pr_debug("Resetting I2C Controller Unit\n");
-
- /* abort any transfer currently under way */
- i2c_pxa_abort(i2c);
-
/* reset according to 9.8 */
writel(ICR_UR, _ICR(i2c));
writel(I2C_ISR_INIT, _ISR(i2c));
@@ -526,12 +586,25 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
#endif
i2c_pxa_set_slave(i2c, 0);
+}
+static void i2c_pxa_enable(struct pxa_i2c *i2c)
+{
/* enable unit */
writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
udelay(100);
}
+static void i2c_pxa_reset(struct pxa_i2c *i2c)
+{
+ pr_debug("Resetting I2C Controller Unit\n");
+
+ /* abort any transfer currently under way */
+ i2c_pxa_abort(i2c);
+ i2c_pxa_do_reset(i2c);
+ i2c_pxa_enable(i2c);
+}
+
#ifdef CONFIG_I2C_PXA_SLAVE
/*
@@ -596,7 +669,7 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
timeout = 0x10000;
while (1) {
- if ((readl(_IBMR(i2c)) & 2) == 2)
+ if ((readl(_IBMR(i2c)) & IBMR_SCLS) == IBMR_SCLS)
break;
timeout--;
@@ -691,7 +764,7 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
timeout = 0x10000;
while (1) {
- if ((readl(_IBMR(i2c)) & 2) == 2)
+ if ((readl(_IBMR(i2c)) & IBMR_SCLS) == IBMR_SCLS)
break;
timeout--;
@@ -716,16 +789,6 @@ static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
* PXA I2C Master mode
*/
-static inline unsigned int i2c_pxa_addr_byte(struct i2c_msg *msg)
-{
- unsigned int addr = (msg->addr & 0x7f) << 1;
-
- if (msg->flags & I2C_M_RD)
- addr |= 1;
-
- return addr;
-}
-
static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
{
u32 icr;
@@ -733,8 +796,8 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
/*
* Step 1: target slave address into IDBR
*/
- writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
- i2c->req_slave_addr = i2c_pxa_addr_byte(i2c->msg);
+ i2c->req_slave_addr = i2c_8bit_addr_from_msg(i2c->msg);
+ writel(i2c->req_slave_addr, _IDBR(i2c));
/*
* Step 2: initiate the write.
@@ -747,42 +810,12 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
{
u32 icr;
- /*
- * Clear the STOP and ACK flags
- */
+ /* Clear the START, STOP, ACK, TB and MA flags */
icr = readl(_ICR(i2c));
- icr &= ~(ICR_STOP | ICR_ACKNAK);
+ icr &= ~(ICR_START | ICR_STOP | ICR_ACKNAK | ICR_TB | ICR_MA);
writel(icr, _ICR(i2c));
}
-static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
-{
- /* make timeout the same as for interrupt based functions */
- long timeout = 2 * DEF_TIMEOUT;
-
- /*
- * Wait for the bus to become free.
- */
- while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
- udelay(1000);
- show_state(i2c);
- }
-
- if (timeout < 0) {
- show_state(i2c);
- dev_err(&i2c->adap.dev,
- "i2c_pxa: timeout waiting for bus free\n");
- return I2C_RETRY;
- }
-
- /*
- * Set master mode.
- */
- writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
-
- return 0;
-}
-
/*
* PXA I2C send master code
* 1. Load master code to IDBR and send it.
@@ -811,140 +844,6 @@ static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
return (timeout == 0) ? I2C_RETRY : 0;
}
-static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
- struct i2c_msg *msg, int num)
-{
- unsigned long timeout = 500000; /* 5 seconds */
- int ret = 0;
-
- ret = i2c_pxa_pio_set_master(i2c);
- if (ret)
- goto out;
-
- i2c->msg = msg;
- i2c->msg_num = num;
- i2c->msg_idx = 0;
- i2c->msg_ptr = 0;
- i2c->irqlogidx = 0;
-
- i2c_pxa_start_message(i2c);
-
- while (i2c->msg_num > 0 && --timeout) {
- i2c_pxa_handler(0, i2c);
- udelay(10);
- }
-
- i2c_pxa_stop_message(i2c);
-
- /*
- * We place the return code in i2c->msg_idx.
- */
- ret = i2c->msg_idx;
-
-out:
- if (timeout == 0) {
- i2c_pxa_scream_blue_murder(i2c, "timeout");
- ret = I2C_RETRY;
- }
-
- return ret;
-}
-
-/*
- * We are protected by the adapter bus mutex.
- */
-static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
-{
- long timeout;
- int ret;
-
- /*
- * Wait for the bus to become free.
- */
- ret = i2c_pxa_wait_bus_not_busy(i2c);
- if (ret) {
- dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
- goto out;
- }
-
- /*
- * Set master mode.
- */
- ret = i2c_pxa_set_master(i2c);
- if (ret) {
- dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
- goto out;
- }
-
- if (i2c->high_mode) {
- ret = i2c_pxa_send_mastercode(i2c);
- if (ret) {
- dev_err(&i2c->adap.dev, "i2c_pxa_send_mastercode timeout\n");
- goto out;
- }
- }
-
- spin_lock_irq(&i2c->lock);
-
- i2c->msg = msg;
- i2c->msg_num = num;
- i2c->msg_idx = 0;
- i2c->msg_ptr = 0;
- i2c->irqlogidx = 0;
-
- i2c_pxa_start_message(i2c);
-
- spin_unlock_irq(&i2c->lock);
-
- /*
- * The rest of the processing occurs in the interrupt handler.
- */
- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
- i2c_pxa_stop_message(i2c);
-
- /*
- * We place the return code in i2c->msg_idx.
- */
- ret = i2c->msg_idx;
-
- if (!timeout && i2c->msg_num) {
- i2c_pxa_scream_blue_murder(i2c, "timeout");
- ret = I2C_RETRY;
- }
-
- out:
- return ret;
-}
-
-static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
- struct i2c_msg msgs[], int num)
-{
- struct pxa_i2c *i2c = adap->algo_data;
- int ret, i;
-
- /* If the I2C controller is disabled we need to reset it
- (probably due to a suspend/resume destroying state). We do
- this here as we can then avoid worrying about resuming the
- controller before its users. */
- if (!(readl(_ICR(i2c)) & ICR_IUE))
- i2c_pxa_reset(i2c);
-
- for (i = adap->retries; i >= 0; i--) {
- ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
- if (ret != I2C_RETRY)
- goto out;
-
- if (i2c_debug)
- dev_dbg(&adap->dev, "Retrying transmission\n");
- udelay(100);
- }
- i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
- ret = -EREMOTEIO;
- out:
- i2c_pxa_set_slave(i2c, ret);
- return ret;
-}
-
/*
* i2c_pxa_master_complete - complete the message and wake up.
*/
@@ -996,7 +895,7 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
*/
if (isr & ISR_ACKNAK) {
if (i2c->msg_ptr == 0 && i2c->msg_idx == 0)
- ret = I2C_RETRY;
+ ret = NO_SLAVE;
else
ret = XFER_NAKED;
}
@@ -1047,8 +946,8 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
/*
* Write the next address.
*/
- writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
- i2c->req_slave_addr = i2c_pxa_addr_byte(i2c->msg);
+ i2c->req_slave_addr = i2c_8bit_addr_from_msg(i2c->msg);
+ writel(i2c->req_slave_addr, _IDBR(i2c));
/*
* And trigger a repeated start, and send the byte.
@@ -1056,14 +955,8 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
icr &= ~ICR_ALDIE;
icr |= ICR_START | ICR_TB;
} else {
- if (i2c->msg->len == 0) {
- /*
- * Device probes have a message length of zero
- * and need the bus to be reset before it can
- * be used again.
- */
- i2c_pxa_reset(i2c);
- }
+ if (i2c->msg->len == 0)
+ icr |= ICR_MA;
i2c_pxa_master_complete(i2c, 0);
}
@@ -1151,28 +1044,108 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
return IRQ_HANDLED;
}
+/*
+ * We are protected by the adapter bus mutex.
+ */
+static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
+{
+ long timeout;
+ int ret;
+
+ /*
+ * Wait for the bus to become free.
+ */
+ ret = i2c_pxa_wait_bus_not_busy(i2c);
+ if (ret) {
+ dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
+ i2c_recover_bus(&i2c->adap);
+ goto out;
+ }
+
+ /*
+ * Set master mode.
+ */
+ ret = i2c_pxa_set_master(i2c);
+ if (ret) {
+ dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
+ goto out;
+ }
+
+ if (i2c->high_mode) {
+ ret = i2c_pxa_send_mastercode(i2c);
+ if (ret) {
+ dev_err(&i2c->adap.dev, "i2c_pxa_send_mastercode timeout\n");
+ goto out;
+ }
+ }
+
+ spin_lock_irq(&i2c->lock);
+
+ i2c->msg = msg;
+ i2c->msg_num = num;
+ i2c->msg_idx = 0;
+ i2c->msg_ptr = 0;
+ i2c->irqlogidx = 0;
+
+ i2c_pxa_start_message(i2c);
+
+ spin_unlock_irq(&i2c->lock);
+
+ /*
+ * The rest of the processing occurs in the interrupt handler.
+ */
+ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+ i2c_pxa_stop_message(i2c);
+
+ /*
+ * We place the return code in i2c->msg_idx.
+ */
+ ret = i2c->msg_idx;
+
+ if (!timeout && i2c->msg_num) {
+ i2c_pxa_scream_blue_murder(i2c, "timeout with active message");
+ i2c_recover_bus(&i2c->adap);
+ ret = I2C_RETRY;
+ }
-static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+ out:
+ return ret;
+}
+
+static int i2c_pxa_internal_xfer(struct pxa_i2c *i2c,
+ struct i2c_msg *msgs, int num,
+ int (*xfer)(struct pxa_i2c *,
+ struct i2c_msg *, int num))
{
- struct pxa_i2c *i2c = adap->algo_data;
int ret, i;
- for (i = adap->retries; i >= 0; i--) {
- ret = i2c_pxa_do_xfer(i2c, msgs, num);
- if (ret != I2C_RETRY)
+ for (i = 0; ; ) {
+ ret = xfer(i2c, msgs, num);
+ if (ret != I2C_RETRY && ret != NO_SLAVE)
goto out;
+ if (++i >= i2c->adap.retries)
+ break;
if (i2c_debug)
- dev_dbg(&adap->dev, "Retrying transmission\n");
+ dev_dbg(&i2c->adap.dev, "Retrying transmission\n");
udelay(100);
}
- i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
+ if (ret != NO_SLAVE)
+ i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
ret = -EREMOTEIO;
out:
i2c_pxa_set_slave(i2c, ret);
return ret;
}
+static int i2c_pxa_xfer(struct i2c_adapter *adap,
+ struct i2c_msg msgs[], int num)
+{
+ struct pxa_i2c *i2c = adap->algo_data;
+
+ return i2c_pxa_internal_xfer(i2c, msgs, num, i2c_pxa_do_xfer);
+}
+
static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
@@ -1188,6 +1161,87 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
#endif
};
+/* Non-interrupt mode support */
+static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
+{
+ /* make timeout the same as for interrupt based functions */
+ long timeout = 2 * DEF_TIMEOUT;
+
+ /*
+ * Wait for the bus to become free.
+ */
+ while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB))
+ udelay(1000);
+
+ if (timeout < 0) {
+ show_state(i2c);
+ dev_err(&i2c->adap.dev,
+ "i2c_pxa: timeout waiting for bus free (set_master)\n");
+ return I2C_RETRY;
+ }
+
+ /*
+ * Set master mode.
+ */
+ writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
+
+ return 0;
+}
+
+static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
+ struct i2c_msg *msg, int num)
+{
+ unsigned long timeout = 500000; /* 5 seconds */
+ int ret = 0;
+
+ ret = i2c_pxa_pio_set_master(i2c);
+ if (ret)
+ goto out;
+
+ i2c->msg = msg;
+ i2c->msg_num = num;
+ i2c->msg_idx = 0;
+ i2c->msg_ptr = 0;
+ i2c->irqlogidx = 0;
+
+ i2c_pxa_start_message(i2c);
+
+ while (i2c->msg_num > 0 && --timeout) {
+ i2c_pxa_handler(0, i2c);
+ udelay(10);
+ }
+
+ i2c_pxa_stop_message(i2c);
+
+ /*
+ * We place the return code in i2c->msg_idx.
+ */
+ ret = i2c->msg_idx;
+
+out:
+ if (timeout == 0) {
+ i2c_pxa_scream_blue_murder(i2c, "timeout (do_pio_xfer)");
+ ret = I2C_RETRY;
+ }
+
+ return ret;
+}
+
+static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
+ struct i2c_msg msgs[], int num)
+{
+ struct pxa_i2c *i2c = adap->algo_data;
+
+ /* If the I2C controller is disabled we need to reset it
+ (probably due to a suspend/resume destroying state). We do
+ this here as we can then avoid worrying about resuming the
+ controller before its users. */
+ if (!(readl(_ICR(i2c)) & ICR_IUE))
+ i2c_pxa_reset(i2c);
+
+ return i2c_pxa_internal_xfer(i2c, msgs, num, i2c_pxa_do_pio_xfer);
+}
+
static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
.master_xfer = i2c_pxa_pio_xfer,
.functionality = i2c_pxa_functionality,
@@ -1197,15 +1251,6 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
#endif
};
-static const struct of_device_id i2c_pxa_dt_ids[] = {
- { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
- { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
- { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
- { .compatible = "marvell,armada-3700-i2c", .data = (void *)REGS_A3700 },
- {}
-};
-MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
-
static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
enum pxa_i2c_types *i2c_types)
{
@@ -1249,6 +1294,131 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
return 0;
}
+static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap)
+{
+ struct pxa_i2c *i2c = adap->algo_data;
+ u32 ibmr = readl(_IBMR(i2c));
+
+ /*
+ * Program the GPIOs to reflect the current I2C bus state while
+ * we transition to recovery; this avoids glitching the bus.
+ */
+ gpiod_set_value(i2c->recovery.scl_gpiod, ibmr & IBMR_SCLS);
+ gpiod_set_value(i2c->recovery.sda_gpiod, ibmr & IBMR_SDAS);
+
+ WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery));
+}
+
+static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
+{
+ struct pxa_i2c *i2c = adap->algo_data;
+ u32 isr;
+
+ /*
+ * The bus should now be free. Clear up the I2C controller before
+ * handing control of the bus back to avoid the bus changing state.
+ */
+ isr = readl(_ISR(i2c));
+ if (isr & (ISR_UB | ISR_IBB)) {
+ dev_dbg(&i2c->adap.dev,
+ "recovery: resetting controller, ISR=0x%08x\n", isr);
+ i2c_pxa_do_reset(i2c);
+ }
+
+ WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default));
+
+ dev_dbg(&i2c->adap.dev, "recovery: IBMR 0x%08x ISR 0x%08x\n",
+ readl(_IBMR(i2c)), readl(_ISR(i2c)));
+
+ i2c_pxa_enable(i2c);
+}
+
+static int i2c_pxa_init_recovery(struct pxa_i2c *i2c)
+{
+ struct i2c_bus_recovery_info *bri = &i2c->recovery;
+ struct device *dev = i2c->adap.dev.parent;
+
+ /*
+ * When slave mode is enabled, we are not the only master on the bus.
+ * Bus recovery can only be performed when we are the master, which
+ * we can't be certain of. Therefore, when slave mode is enabled, do
+ * not configure bus recovery.
+ */
+ if (IS_ENABLED(CONFIG_I2C_PXA_SLAVE))
+ return 0;
+
+ i2c->pinctrl = devm_pinctrl_get(dev);
+ if (PTR_ERR(i2c->pinctrl) == -ENODEV)
+ i2c->pinctrl = NULL;
+ if (IS_ERR(i2c->pinctrl))
+ return PTR_ERR(i2c->pinctrl);
+
+ if (!i2c->pinctrl)
+ return 0;
+
+ i2c->pinctrl_default = pinctrl_lookup_state(i2c->pinctrl,
+ PINCTRL_STATE_DEFAULT);
+ i2c->pinctrl_recovery = pinctrl_lookup_state(i2c->pinctrl, "recovery");
+
+ if (IS_ERR(i2c->pinctrl_default) || IS_ERR(i2c->pinctrl_recovery)) {
+ dev_info(dev, "missing pinmux recovery information: %ld %ld\n",
+ PTR_ERR(i2c->pinctrl_default),
+ PTR_ERR(i2c->pinctrl_recovery));
+ return 0;
+ }
+
+ /*
+ * Claiming GPIOs can influence the pinmux state, and may glitch the
+ * I2C bus. Do this carefully.
+ */
+ bri->scl_gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
+ if (bri->scl_gpiod == ERR_PTR(-EPROBE_DEFER))
+ return -EPROBE_DEFER;
+ if (IS_ERR(bri->scl_gpiod)) {
+ dev_info(dev, "missing scl gpio recovery information: %pe\n",
+ bri->scl_gpiod);
+ return 0;
+ }
+
+ /*
+ * We have SCL. Pull SCL low and wait a bit so that SDA glitches
+ * have no effect.
+ */
+ gpiod_direction_output(bri->scl_gpiod, 0);
+ udelay(10);
+ bri->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_OUT_HIGH_OPEN_DRAIN);
+
+ /* Wait a bit in case of a SDA glitch, and then release SCL. */
+ udelay(10);
+ gpiod_direction_output(bri->scl_gpiod, 1);
+
+ if (bri->sda_gpiod == ERR_PTR(-EPROBE_DEFER))
+ return -EPROBE_DEFER;
+
+ if (IS_ERR(bri->sda_gpiod)) {
+ dev_info(dev, "missing sda gpio recovery information: %pe\n",
+ bri->sda_gpiod);
+ return 0;
+ }
+
+ bri->prepare_recovery = i2c_pxa_prepare_recovery;
+ bri->unprepare_recovery = i2c_pxa_unprepare_recovery;
+ bri->recover_bus = i2c_generic_scl_recovery;
+
+ i2c->adap.bus_recovery_info = bri;
+
+ /*
+ * Claiming GPIOs can change the pinmux state, which confuses the
+ * pinctrl since pinctrl's idea of the current setting is unaffected
+ * by the pinmux change caused by claiming the GPIO. Work around that
+ * by switching pinctrl to the GPIO state here. We do it this way to
+ * avoid glitching the I2C bus.
+ */
+ pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery);
+
+ return pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default);
+}
+
static int i2c_pxa_probe(struct platform_device *dev)
{
struct i2c_pxa_platform_data *plat = dev_get_platdata(&dev->dev);
@@ -1261,19 +1431,28 @@ static int i2c_pxa_probe(struct platform_device *dev)
if (!i2c)
return -ENOMEM;
+ /* Default adapter num to device id; i2c_pxa_probe_dt can override. */
+ i2c->adap.nr = dev->id;
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.retries = 5;
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = &dev->dev;
+#ifdef CONFIG_OF
+ i2c->adap.dev.of_node = dev->dev.of_node;
+#endif
+
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
i2c->reg_base = devm_ioremap_resource(&dev->dev, res);
if (IS_ERR(i2c->reg_base))
return PTR_ERR(i2c->reg_base);
irq = platform_get_irq(dev, 0);
- if (irq < 0) {
- dev_err(&dev->dev, "no irq resource: %d\n", irq);
+ if (irq < 0)
return irq;
- }
- /* Default adapter num to device id; i2c_pxa_probe_dt can override. */
- i2c->adap.nr = dev->id;
+ ret = i2c_pxa_init_recovery(i2c);
+ if (ret)
+ return ret;
ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
if (ret > 0)
@@ -1281,9 +1460,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
if (ret < 0)
return ret;
- i2c->adap.owner = THIS_MODULE;
- i2c->adap.retries = 5;
-
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
@@ -1299,8 +1475,8 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
- i2c->fm_mask = pxa_reg_layout[i2c_type].fm ? : ICR_FM;
- i2c->hs_mask = pxa_reg_layout[i2c_type].hs ? : ICR_HS;
+ i2c->fm_mask = pxa_reg_layout[i2c_type].fm;
+ i2c->hs_mask = pxa_reg_layout[i2c_type].hs;
if (i2c_type != REGS_CE4100)
i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
@@ -1349,12 +1525,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c_pxa_reset(i2c);
- i2c->adap.algo_data = i2c;
- i2c->adap.dev.parent = &dev->dev;
-#ifdef CONFIG_OF
- i2c->adap.dev.of_node = dev->dev.of_node;
-#endif
-
ret = i2c_add_numbered_adapter(&i2c->adap);
if (ret < 0)
goto ereqirq;
diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
new file mode 100644
index 000000000000..f13735beca58
--- /dev/null
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -0,0 +1,791 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+// Copyright (c) 2017-20 Linaro Limited.
+
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#define CCI_HW_VERSION 0x0
+#define CCI_RESET_CMD 0x004
+#define CCI_RESET_CMD_MASK 0x0f73f3f7
+#define CCI_RESET_CMD_M0_MASK 0x000003f1
+#define CCI_RESET_CMD_M1_MASK 0x0003f001
+#define CCI_QUEUE_START 0x008
+#define CCI_HALT_REQ 0x034
+#define CCI_HALT_REQ_I2C_M0_Q0Q1 BIT(0)
+#define CCI_HALT_REQ_I2C_M1_Q0Q1 BIT(1)
+
+#define CCI_I2C_Mm_SCL_CTL(m) (0x100 + 0x100 * (m))
+#define CCI_I2C_Mm_SDA_CTL_0(m) (0x104 + 0x100 * (m))
+#define CCI_I2C_Mm_SDA_CTL_1(m) (0x108 + 0x100 * (m))
+#define CCI_I2C_Mm_SDA_CTL_2(m) (0x10c + 0x100 * (m))
+#define CCI_I2C_Mm_MISC_CTL(m) (0x110 + 0x100 * (m))
+
+#define CCI_I2C_Mm_READ_DATA(m) (0x118 + 0x100 * (m))
+#define CCI_I2C_Mm_READ_BUF_LEVEL(m) (0x11c + 0x100 * (m))
+#define CCI_I2C_Mm_Qn_EXEC_WORD_CNT(m, n) (0x300 + 0x200 * (m) + 0x100 * (n))
+#define CCI_I2C_Mm_Qn_CUR_WORD_CNT(m, n) (0x304 + 0x200 * (m) + 0x100 * (n))
+#define CCI_I2C_Mm_Qn_CUR_CMD(m, n) (0x308 + 0x200 * (m) + 0x100 * (n))
+#define CCI_I2C_Mm_Qn_REPORT_STATUS(m, n) (0x30c + 0x200 * (m) + 0x100 * (n))
+#define CCI_I2C_Mm_Qn_LOAD_DATA(m, n) (0x310 + 0x200 * (m) + 0x100 * (n))
+
+#define CCI_IRQ_GLOBAL_CLEAR_CMD 0xc00
+#define CCI_IRQ_MASK_0 0xc04
+#define CCI_IRQ_MASK_0_I2C_M0_RD_DONE BIT(0)
+#define CCI_IRQ_MASK_0_I2C_M0_Q0_REPORT BIT(4)
+#define CCI_IRQ_MASK_0_I2C_M0_Q1_REPORT BIT(8)
+#define CCI_IRQ_MASK_0_I2C_M1_RD_DONE BIT(12)
+#define CCI_IRQ_MASK_0_I2C_M1_Q0_REPORT BIT(16)
+#define CCI_IRQ_MASK_0_I2C_M1_Q1_REPORT BIT(20)
+#define CCI_IRQ_MASK_0_RST_DONE_ACK BIT(24)
+#define CCI_IRQ_MASK_0_I2C_M0_Q0Q1_HALT_ACK BIT(25)
+#define CCI_IRQ_MASK_0_I2C_M1_Q0Q1_HALT_ACK BIT(26)
+#define CCI_IRQ_MASK_0_I2C_M0_ERROR 0x18000ee6
+#define CCI_IRQ_MASK_0_I2C_M1_ERROR 0x60ee6000
+#define CCI_IRQ_CLEAR_0 0xc08
+#define CCI_IRQ_STATUS_0 0xc0c
+#define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE BIT(0)
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT BIT(4)
+#define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT BIT(8)
+#define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE BIT(12)
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT BIT(16)
+#define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT BIT(20)
+#define CCI_IRQ_STATUS_0_RST_DONE_ACK BIT(24)
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK BIT(25)
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK BIT(26)
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR BIT(27)
+#define CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR BIT(28)
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR BIT(29)
+#define CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR BIT(30)
+#define CCI_IRQ_STATUS_0_I2C_M0_ERROR 0x18000ee6
+#define CCI_IRQ_STATUS_0_I2C_M1_ERROR 0x60ee6000
+
+#define CCI_TIMEOUT (msecs_to_jiffies(100))
+#define NUM_MASTERS 2
+#define NUM_QUEUES 2
+
+/* Max number of resources + 1 for a NULL terminator */
+#define CCI_RES_MAX 6
+
+#define CCI_I2C_SET_PARAM 1
+#define CCI_I2C_REPORT 8
+#define CCI_I2C_WRITE 9
+#define CCI_I2C_READ 10
+
+#define CCI_I2C_REPORT_IRQ_EN BIT(8)
+
+enum {
+ I2C_MODE_STANDARD,
+ I2C_MODE_FAST,
+ I2C_MODE_FAST_PLUS,
+};
+
+enum cci_i2c_queue_t {
+ QUEUE_0,
+ QUEUE_1
+};
+
+struct hw_params {
+ u16 thigh; /* HIGH period of the SCL clock in clock ticks */
+ u16 tlow; /* LOW period of the SCL clock */
+ u16 tsu_sto; /* set-up time for STOP condition */
+ u16 tsu_sta; /* set-up time for a repeated START condition */
+ u16 thd_dat; /* data hold time */
+ u16 thd_sta; /* hold time (repeated) START condition */
+ u16 tbuf; /* bus free time between a STOP and START condition */
+ u8 scl_stretch_en;
+ u16 trdhld;
+ u16 tsp; /* pulse width of spikes suppressed by the input filter */
+};
+
+struct cci;
+
+struct cci_master {
+ struct i2c_adapter adap;
+ u16 master;
+ u8 mode;
+ int status;
+ struct completion irq_complete;
+ struct cci *cci;
+};
+
+struct cci_data {
+ unsigned int num_masters;
+ struct i2c_adapter_quirks quirks;
+ u16 queue_size[NUM_QUEUES];
+ unsigned long cci_clk_rate;
+ struct hw_params params[3];
+};
+
+struct cci {
+ struct device *dev;
+ void __iomem *base;
+ unsigned int irq;
+ const struct cci_data *data;
+ struct clk_bulk_data *clocks;
+ int nclocks;
+ struct cci_master master[NUM_MASTERS];
+};
+
+static irqreturn_t cci_isr(int irq, void *dev)
+{
+ struct cci *cci = dev;
+ u32 val, reset = 0;
+ int ret = IRQ_NONE;
+
+ val = readl(cci->base + CCI_IRQ_STATUS_0);
+ writel(val, cci->base + CCI_IRQ_CLEAR_0);
+ writel(0x1, cci->base + CCI_IRQ_GLOBAL_CLEAR_CMD);
+
+ if (val & CCI_IRQ_STATUS_0_RST_DONE_ACK) {
+ complete(&cci->master[0].irq_complete);
+ if (cci->master[1].master)
+ complete(&cci->master[1].irq_complete);
+ ret = IRQ_HANDLED;
+ }
+
+ if (val & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE ||
+ val & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT ||
+ val & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT) {
+ cci->master[0].status = 0;
+ complete(&cci->master[0].irq_complete);
+ ret = IRQ_HANDLED;
+ }
+
+ if (val & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE ||
+ val & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT ||
+ val & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT) {
+ cci->master[1].status = 0;
+ complete(&cci->master[1].irq_complete);
+ ret = IRQ_HANDLED;
+ }
+
+ if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK)) {
+ reset = CCI_RESET_CMD_M0_MASK;
+ ret = IRQ_HANDLED;
+ }
+
+ if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK)) {
+ reset = CCI_RESET_CMD_M1_MASK;
+ ret = IRQ_HANDLED;
+ }
+
+ if (unlikely(reset))
+ writel(reset, cci->base + CCI_RESET_CMD);
+
+ if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M0_ERROR)) {
+ if (val & CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR ||
+ val & CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR)
+ cci->master[0].status = -ENXIO;
+ else
+ cci->master[0].status = -EIO;
+
+ writel(CCI_HALT_REQ_I2C_M0_Q0Q1, cci->base + CCI_HALT_REQ);
+ ret = IRQ_HANDLED;
+ }
+
+ if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M1_ERROR)) {
+ if (val & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR ||
+ val & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR)
+ cci->master[0].status = -ENXIO;
+ else
+ cci->master[0].status = -EIO;
+
+ writel(CCI_HALT_REQ_I2C_M1_Q0Q1, cci->base + CCI_HALT_REQ);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+static int cci_halt(struct cci *cci, u8 master_num)
+{
+ struct cci_master *master;
+ u32 val;
+
+ if (master_num >= cci->data->num_masters) {
+ dev_err(cci->dev, "Unsupported master idx (%u)\n", master_num);
+ return -EINVAL;
+ }
+
+ val = BIT(master_num);
+ master = &cci->master[master_num];
+
+ reinit_completion(&master->irq_complete);
+ writel(val, cci->base + CCI_HALT_REQ);
+
+ if (!wait_for_completion_timeout(&master->irq_complete, CCI_TIMEOUT)) {
+ dev_err(cci->dev, "CCI halt timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int cci_reset(struct cci *cci)
+{
+ /*
+ * we reset the whole controller, here and for implicity use
+ * master[0].xxx for waiting on it.
+ */
+ reinit_completion(&cci->master[0].irq_complete);
+ writel(CCI_RESET_CMD_MASK, cci->base + CCI_RESET_CMD);
+
+ if (!wait_for_completion_timeout(&cci->master[0].irq_complete,
+ CCI_TIMEOUT)) {
+ dev_err(cci->dev, "CCI reset timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int cci_init(struct cci *cci)
+{
+ u32 val = CCI_IRQ_MASK_0_I2C_M0_RD_DONE |
+ CCI_IRQ_MASK_0_I2C_M0_Q0_REPORT |
+ CCI_IRQ_MASK_0_I2C_M0_Q1_REPORT |
+ CCI_IRQ_MASK_0_I2C_M1_RD_DONE |
+ CCI_IRQ_MASK_0_I2C_M1_Q0_REPORT |
+ CCI_IRQ_MASK_0_I2C_M1_Q1_REPORT |
+ CCI_IRQ_MASK_0_RST_DONE_ACK |
+ CCI_IRQ_MASK_0_I2C_M0_Q0Q1_HALT_ACK |
+ CCI_IRQ_MASK_0_I2C_M1_Q0Q1_HALT_ACK |
+ CCI_IRQ_MASK_0_I2C_M0_ERROR |
+ CCI_IRQ_MASK_0_I2C_M1_ERROR;
+ int i;
+
+ writel(val, cci->base + CCI_IRQ_MASK_0);
+
+ for (i = 0; i < cci->data->num_masters; i++) {
+ int mode = cci->master[i].mode;
+ const struct hw_params *hw;
+
+ if (!cci->master[i].cci)
+ continue;
+
+ hw = &cci->data->params[mode];
+
+ val = hw->thigh << 16 | hw->tlow;
+ writel(val, cci->base + CCI_I2C_Mm_SCL_CTL(i));
+
+ val = hw->tsu_sto << 16 | hw->tsu_sta;
+ writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_0(i));
+
+ val = hw->thd_dat << 16 | hw->thd_sta;
+ writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_1(i));
+
+ val = hw->tbuf;
+ writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_2(i));
+
+ val = hw->scl_stretch_en << 8 | hw->trdhld << 4 | hw->tsp;
+ writel(val, cci->base + CCI_I2C_Mm_MISC_CTL(i));
+ }
+
+ return 0;
+}
+
+static int cci_run_queue(struct cci *cci, u8 master, u8 queue)
+{
+ u32 val;
+
+ val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue));
+ writel(val, cci->base + CCI_I2C_Mm_Qn_EXEC_WORD_CNT(master, queue));
+
+ reinit_completion(&cci->master[master].irq_complete);
+ val = BIT(master * 2 + queue);
+ writel(val, cci->base + CCI_QUEUE_START);
+
+ if (!wait_for_completion_timeout(&cci->master[master].irq_complete,
+ CCI_TIMEOUT)) {
+ dev_err(cci->dev, "master %d queue %d timeout\n",
+ master, queue);
+ cci_reset(cci);
+ cci_init(cci);
+ return -ETIMEDOUT;
+ }
+
+ return cci->master[master].status;
+}
+
+static int cci_validate_queue(struct cci *cci, u8 master, u8 queue)
+{
+ u32 val;
+
+ val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue));
+ if (val == cci->data->queue_size[queue])
+ return -EINVAL;
+
+ if (!val)
+ return 0;
+
+ val = CCI_I2C_REPORT | CCI_I2C_REPORT_IRQ_EN;
+ writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
+
+ return cci_run_queue(cci, master, queue);
+}
+
+static int cci_i2c_read(struct cci *cci, u16 master,
+ u16 addr, u8 *buf, u16 len)
+{
+ u32 val, words_read, words_exp;
+ u8 queue = QUEUE_1;
+ int i, index = 0, ret;
+ bool first = true;
+
+ /*
+ * Call validate queue to make sure queue is empty before starting.
+ * This is to avoid overflow / underflow of queue.
+ */
+ ret = cci_validate_queue(cci, master, queue);
+ if (ret < 0)
+ return ret;
+
+ val = CCI_I2C_SET_PARAM | (addr & 0x7f) << 4;
+ writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
+
+ val = CCI_I2C_READ | len << 4;
+ writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
+
+ ret = cci_run_queue(cci, master, queue);
+ if (ret < 0)
+ return ret;
+
+ words_read = readl(cci->base + CCI_I2C_Mm_READ_BUF_LEVEL(master));
+ words_exp = len / 4 + 1;
+ if (words_read != words_exp) {
+ dev_err(cci->dev, "words read = %d, words expected = %d\n",
+ words_read, words_exp);
+ return -EIO;
+ }
+
+ do {
+ val = readl(cci->base + CCI_I2C_Mm_READ_DATA(master));
+
+ for (i = 0; i < 4 && index < len; i++) {
+ if (first) {
+ /* The LS byte of this register represents the
+ * first byte read from the slave during a read
+ * access.
+ */
+ first = false;
+ continue;
+ }
+ buf[index++] = (val >> (i * 8)) & 0xff;
+ }
+ } while (--words_read);
+
+ return 0;
+}
+
+static int cci_i2c_write(struct cci *cci, u16 master,
+ u16 addr, u8 *buf, u16 len)
+{
+ u8 queue = QUEUE_0;
+ u8 load[12] = { 0 };
+ int i = 0, j, ret;
+ u32 val;
+
+ /*
+ * Call validate queue to make sure queue is empty before starting.
+ * This is to avoid overflow / underflow of queue.
+ */
+ ret = cci_validate_queue(cci, master, queue);
+ if (ret < 0)
+ return ret;
+
+ val = CCI_I2C_SET_PARAM | (addr & 0x7f) << 4;
+ writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
+
+ load[i++] = CCI_I2C_WRITE | len << 4;
+
+ for (j = 0; j < len; j++)
+ load[i++] = buf[j];
+
+ for (j = 0; j < i; j += 4) {
+ val = load[j];
+ val |= load[j + 1] << 8;
+ val |= load[j + 2] << 16;
+ val |= load[j + 3] << 24;
+ writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
+ }
+
+ val = CCI_I2C_REPORT | CCI_I2C_REPORT_IRQ_EN;
+ writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
+
+ return cci_run_queue(cci, master, queue);
+}
+
+static int cci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ struct cci_master *cci_master = i2c_get_adapdata(adap);
+ struct cci *cci = cci_master->cci;
+ int i, ret;
+
+ ret = pm_runtime_get_sync(cci->dev);
+ if (ret < 0)
+ goto err;
+
+ for (i = 0; i < num; i++) {
+ if (msgs[i].flags & I2C_M_RD)
+ ret = cci_i2c_read(cci, cci_master->master,
+ msgs[i].addr, msgs[i].buf,
+ msgs[i].len);
+ else
+ ret = cci_i2c_write(cci, cci_master->master,
+ msgs[i].addr, msgs[i].buf,
+ msgs[i].len);
+
+ if (ret < 0)
+ break;
+ }
+
+ if (!ret)
+ ret = num;
+
+err:
+ pm_runtime_mark_last_busy(cci->dev);
+ pm_runtime_put_autosuspend(cci->dev);
+
+ return ret;
+}
+
+static u32 cci_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm cci_algo = {
+ .master_xfer = cci_xfer,
+ .functionality = cci_func,
+};
+
+static int cci_enable_clocks(struct cci *cci)
+{
+ return clk_bulk_prepare_enable(cci->nclocks, cci->clocks);
+}
+
+static void cci_disable_clocks(struct cci *cci)
+{
+ clk_bulk_disable_unprepare(cci->nclocks, cci->clocks);
+}
+
+static int __maybe_unused cci_suspend_runtime(struct device *dev)
+{
+ struct cci *cci = dev_get_drvdata(dev);
+
+ cci_disable_clocks(cci);
+ return 0;
+}
+
+static int __maybe_unused cci_resume_runtime(struct device *dev)
+{
+ struct cci *cci = dev_get_drvdata(dev);
+ int ret;
+
+ ret = cci_enable_clocks(cci);
+ if (ret)
+ return ret;
+
+ cci_init(cci);
+ return 0;
+}
+
+static int __maybe_unused cci_suspend(struct device *dev)
+{
+ if (!pm_runtime_suspended(dev))
+ return cci_suspend_runtime(dev);
+
+ return 0;
+}
+
+static int __maybe_unused cci_resume(struct device *dev)
+{
+ cci_resume_runtime(dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_request_autosuspend(dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops qcom_cci_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(cci_suspend, cci_resume)
+ SET_RUNTIME_PM_OPS(cci_suspend_runtime, cci_resume_runtime, NULL)
+};
+
+static int cci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ unsigned long cci_clk_rate = 0;
+ struct device_node *child;
+ struct resource *r;
+ struct cci *cci;
+ int ret, i;
+ u32 val;
+
+ cci = devm_kzalloc(dev, sizeof(*cci), GFP_KERNEL);
+ if (!cci)
+ return -ENOMEM;
+
+ cci->dev = dev;
+ platform_set_drvdata(pdev, cci);
+ cci->data = device_get_match_data(dev);
+ if (!cci->data)
+ return -ENOENT;
+
+ for_each_available_child_of_node(dev->of_node, child) {
+ u32 idx;
+
+ ret = of_property_read_u32(child, "reg", &idx);
+ if (ret) {
+ dev_err(dev, "%pOF invalid 'reg' property", child);
+ continue;
+ }
+
+ if (idx >= cci->data->num_masters) {
+ dev_err(dev, "%pOF invalid 'reg' value: %u (max is %u)",
+ child, idx, cci->data->num_masters - 1);
+ continue;
+ }
+
+ cci->master[idx].adap.quirks = &cci->data->quirks;
+ cci->master[idx].adap.algo = &cci_algo;
+ cci->master[idx].adap.dev.parent = dev;
+ cci->master[idx].adap.dev.of_node = child;
+ cci->master[idx].master = idx;
+ cci->master[idx].cci = cci;
+
+ i2c_set_adapdata(&cci->master[idx].adap, &cci->master[idx]);
+ snprintf(cci->master[idx].adap.name,
+ sizeof(cci->master[idx].adap.name), "Qualcomm-CCI");
+
+ cci->master[idx].mode = I2C_MODE_STANDARD;
+ ret = of_property_read_u32(child, "clock-frequency", &val);
+ if (!ret) {
+ if (val == 400000)
+ cci->master[idx].mode = I2C_MODE_FAST;
+ else if (val == 1000000)
+ cci->master[idx].mode = I2C_MODE_FAST_PLUS;
+ }
+
+ init_completion(&cci->master[idx].irq_complete);
+ }
+
+ /* Memory */
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ cci->base = devm_ioremap_resource(dev, r);
+ if (IS_ERR(cci->base))
+ return PTR_ERR(cci->base);
+
+ /* Clocks */
+
+ ret = devm_clk_bulk_get_all(dev, &cci->clocks);
+ if (ret < 1) {
+ dev_err(dev, "failed to get clocks %d\n", ret);
+ return ret;
+ }
+ cci->nclocks = ret;
+
+ /* Retrieve CCI clock rate */
+ for (i = 0; i < cci->nclocks; i++) {
+ if (!strcmp(cci->clocks[i].id, "cci")) {
+ cci_clk_rate = clk_get_rate(cci->clocks[i].clk);
+ break;
+ }
+ }
+
+ if (cci_clk_rate != cci->data->cci_clk_rate) {
+ /* cci clock set by the bootloader or via assigned clock rate
+ * in DT.
+ */
+ dev_warn(dev, "Found %lu cci clk rate while %lu was expected\n",
+ cci_clk_rate, cci->data->cci_clk_rate);
+ }
+
+ ret = cci_enable_clocks(cci);
+ if (ret < 0)
+ return ret;
+
+ /* Interrupt */
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ goto disable_clocks;
+ cci->irq = ret;
+
+ ret = devm_request_irq(dev, cci->irq, cci_isr, 0, dev_name(dev), cci);
+ if (ret < 0) {
+ dev_err(dev, "request_irq failed, ret: %d\n", ret);
+ goto disable_clocks;
+ }
+
+ val = readl(cci->base + CCI_HW_VERSION);
+ dev_dbg(dev, "CCI HW version = 0x%08x", val);
+
+ ret = cci_reset(cci);
+ if (ret < 0)
+ goto error;
+
+ ret = cci_init(cci);
+ if (ret < 0)
+ goto error;
+
+ for (i = 0; i < cci->data->num_masters; i++) {
+ if (!cci->master[i].cci)
+ continue;
+
+ ret = i2c_add_adapter(&cci->master[i].adap);
+ if (ret < 0)
+ goto error_i2c;
+ }
+
+ pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ return 0;
+
+error_i2c:
+ for (; i >= 0; i--) {
+ if (cci->master[i].cci)
+ i2c_del_adapter(&cci->master[i].adap);
+ }
+error:
+ disable_irq(cci->irq);
+disable_clocks:
+ cci_disable_clocks(cci);
+
+ return ret;
+}
+
+static int cci_remove(struct platform_device *pdev)
+{
+ struct cci *cci = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < cci->data->num_masters; i++) {
+ if (cci->master[i].cci)
+ i2c_del_adapter(&cci->master[i].adap);
+ cci_halt(cci, i);
+ }
+
+ disable_irq(cci->irq);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+
+ return 0;
+}
+
+static const struct cci_data cci_v1_data = {
+ .num_masters = 1,
+ .queue_size = { 64, 16 },
+ .quirks = {
+ .max_write_len = 10,
+ .max_read_len = 12,
+ },
+ .cci_clk_rate = 19200000,
+ .params[I2C_MODE_STANDARD] = {
+ .thigh = 78,
+ .tlow = 114,
+ .tsu_sto = 28,
+ .tsu_sta = 28,
+ .thd_dat = 10,
+ .thd_sta = 77,
+ .tbuf = 118,
+ .scl_stretch_en = 0,
+ .trdhld = 6,
+ .tsp = 1
+ },
+ .params[I2C_MODE_FAST] = {
+ .thigh = 20,
+ .tlow = 28,
+ .tsu_sto = 21,
+ .tsu_sta = 21,
+ .thd_dat = 13,
+ .thd_sta = 18,
+ .tbuf = 32,
+ .scl_stretch_en = 0,
+ .trdhld = 6,
+ .tsp = 3
+ },
+};
+
+static const struct cci_data cci_v2_data = {
+ .num_masters = 2,
+ .queue_size = { 64, 16 },
+ .quirks = {
+ .max_write_len = 11,
+ .max_read_len = 12,
+ },
+ .cci_clk_rate = 37500000,
+ .params[I2C_MODE_STANDARD] = {
+ .thigh = 201,
+ .tlow = 174,
+ .tsu_sto = 204,
+ .tsu_sta = 231,
+ .thd_dat = 22,
+ .thd_sta = 162,
+ .tbuf = 227,
+ .scl_stretch_en = 0,
+ .trdhld = 6,
+ .tsp = 3
+ },
+ .params[I2C_MODE_FAST] = {
+ .thigh = 38,
+ .tlow = 56,
+ .tsu_sto = 40,
+ .tsu_sta = 40,
+ .thd_dat = 22,
+ .thd_sta = 35,
+ .tbuf = 62,
+ .scl_stretch_en = 0,
+ .trdhld = 6,
+ .tsp = 3
+ },
+ .params[I2C_MODE_FAST_PLUS] = {
+ .thigh = 16,
+ .tlow = 22,
+ .tsu_sto = 17,
+ .tsu_sta = 18,
+ .thd_dat = 16,
+ .thd_sta = 15,
+ .tbuf = 24,
+ .scl_stretch_en = 0,
+ .trdhld = 3,
+ .tsp = 3
+ },
+};
+
+static const struct of_device_id cci_dt_match[] = {
+ { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
+ { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
+ { .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
+ {}
+};
+MODULE_DEVICE_TABLE(of, cci_dt_match);
+
+static struct platform_driver qcom_cci_driver = {
+ .probe = cci_probe,
+ .remove = cci_remove,
+ .driver = {
+ .name = "i2c-qcom-cci",
+ .of_match_table = cci_dt_match,
+ .pm = &qcom_cci_pm,
+ },
+};
+
+module_platform_driver(qcom_cci_driver);
+
+MODULE_DESCRIPTION("Qualcomm Camera Control Interface driver");
+MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
+MODULE_AUTHOR("Loic Poulain <loic.poulain@linaro.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 748872a9b0fc..fbc04b60cfd1 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -956,10 +956,8 @@ static void qup_i2c_conf_v1(struct qup_i2c_dev *qup)
u32 qup_config = I2C_MINI_CORE | I2C_N_VAL;
u32 io_mode = QUP_REPACK_EN;
- blk->is_tx_blk_mode =
- blk->total_tx_len > qup->out_fifo_sz ? true : false;
- blk->is_rx_blk_mode =
- blk->total_rx_len > qup->in_fifo_sz ? true : false;
+ blk->is_tx_blk_mode = blk->total_tx_len > qup->out_fifo_sz;
+ blk->is_rx_blk_mode = blk->total_rx_len > qup->in_fifo_sz;
if (blk->is_tx_blk_mode) {
io_mode |= QUP_OUTPUT_BLK_MODE;
@@ -1528,9 +1526,9 @@ qup_i2c_determine_mode_v2(struct qup_i2c_dev *qup,
qup->use_dma = true;
} else {
qup->blk.is_tx_blk_mode = max_tx_len > qup->out_fifo_sz -
- QUP_MAX_TAGS_LEN ? true : false;
+ QUP_MAX_TAGS_LEN;
qup->blk.is_rx_blk_mode = max_rx_len > qup->in_fifo_sz -
- READ_RX_TAGS_LEN ? true : false;
+ READ_RX_TAGS_LEN;
}
return 0;
@@ -1660,7 +1658,6 @@ static int qup_i2c_probe(struct platform_device *pdev)
static const int blk_sizes[] = {4, 16, 32};
struct qup_i2c_dev *qup;
unsigned long one_bit_t;
- struct resource *res;
u32 io_mode, hw_ver, size;
int ret, fs_div, hs_div;
u32 src_clk_freq = DEFAULT_SRC_CLK;
@@ -1757,16 +1754,13 @@ nodma:
return -EINVAL;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- qup->base = devm_ioremap_resource(qup->dev, res);
+ qup->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(qup->base))
return PTR_ERR(qup->base);
qup->irq = platform_get_irq(pdev, 0);
- if (qup->irq < 0) {
- dev_err(qup->dev, "No IRQ defined\n");
+ if (qup->irq < 0)
return qup->irq;
- }
if (has_acpi_companion(qup->dev)) {
ret = device_property_read_u32(qup->dev,
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 3b5397aa4ca6..a45c4bf1ec01 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -938,9 +938,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
return PTR_ERR(priv->clk);
}
- priv->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- priv->io = devm_ioremap_resource(dev, priv->res);
+ priv->io = devm_platform_get_and_ioremap_resource(pdev, 0, &priv->res);
if (IS_ERR(priv->io))
return PTR_ERR(priv->io);
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 73272d4296bb..bc698240c4aa 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -1193,7 +1193,6 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *match;
struct rk3x_i2c *i2c;
- struct resource *mem;
int ret = 0;
int bus_nr;
u32 value;
@@ -1223,8 +1222,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->regs = devm_ioremap_resource(&pdev->dev, mem);
+ i2c->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);
@@ -1262,10 +1260,8 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
/* IRQ setup */
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "cannot find rk3x IRQ\n");
+ if (irq < 0)
return irq;
- }
ret = devm_request_irq(&pdev->dev, irq, rk3x_i2c_irq,
0, dev_name(&pdev->dev), i2c);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 5a5638e1daa1..3eafe0eb3e4c 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -435,8 +435,7 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* fall through to the write state, as we will need to
* send a byte as well
*/
- /* Fall through */
-
+ fallthrough;
case STATE_WRITE:
/*
* we are writing data to the device... check for the
@@ -1267,5 +1266,5 @@ static void __exit i2c_adap_s3c_exit(void)
module_exit(i2c_adap_s3c_exit);
MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index d83ca4028fa0..2cca1b21e26e 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -366,7 +366,6 @@ static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd)
static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
{
- unsigned char data;
int real_pos;
/* switch from TX (address) to RX (data) adds two interrupts */
@@ -387,13 +386,11 @@ static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
if (real_pos < 0)
i2c_op(pd, OP_RX_STOP);
else
- data = i2c_op(pd, OP_RX_STOP_DATA);
+ pd->msg->buf[real_pos] = i2c_op(pd, OP_RX_STOP_DATA);
} else if (real_pos >= 0) {
- data = i2c_op(pd, OP_RX);
+ pd->msg->buf[real_pos] = i2c_op(pd, OP_RX);
}
- if (real_pos >= 0)
- pd->msg->buf[real_pos] = data;
done:
pd->pos++;
return pd->pos == (pd->msg->len + 2);
diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c
index a459e00c6851..d7f72ec331e8 100644
--- a/drivers/i2c/busses/i2c-sirf.c
+++ b/drivers/i2c/busses/i2c-sirf.c
@@ -271,7 +271,6 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
{
struct sirfsoc_i2c *siic;
struct i2c_adapter *adap;
- struct resource *mem_res;
struct clk *clk;
int bitrate;
int ctrl_speed;
@@ -309,8 +308,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
adap = &siic->adapter;
adap->class = I2C_CLASS_DEPRECATED;
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- siic->base = devm_ioremap_resource(&pdev->dev, mem_res);
+ siic->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(siic->base)) {
err = PTR_ERR(siic->base);
goto out;
diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c
index 123a42bfe3b1..19cda6742423 100644
--- a/drivers/i2c/busses/i2c-sprd.c
+++ b/drivers/i2c/busses/i2c-sprd.c
@@ -492,10 +492,8 @@ static int sprd_i2c_probe(struct platform_device *pdev)
return PTR_ERR(i2c_dev->base);
i2c_dev->irq = platform_get_irq(pdev, 0);
- if (i2c_dev->irq < 0) {
- dev_err(&pdev->dev, "failed to get irq resource\n");
+ if (i2c_dev->irq < 0)
return i2c_dev->irq;
- }
i2c_set_adapdata(&i2c_dev->adap, i2c_dev);
init_completion(&i2c_dev->complete);
diff --git a/drivers/i2c/busses/i2c-stm32.c b/drivers/i2c/busses/i2c-stm32.c
index 1da347e6a358..3f69a3bb6119 100644
--- a/drivers/i2c/busses/i2c-stm32.c
+++ b/drivers/i2c/busses/i2c-stm32.c
@@ -25,8 +25,9 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
/* Request and configure I2C TX dma channel */
dma->chan_tx = dma_request_chan(dev, "tx");
if (IS_ERR(dma->chan_tx)) {
- dev_dbg(dev, "can't request DMA tx channel\n");
ret = PTR_ERR(dma->chan_tx);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "can't request DMA tx channel\n");
goto fail_al;
}
@@ -44,8 +45,10 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev,
/* Request and configure I2C RX dma channel */
dma->chan_rx = dma_request_chan(dev, "rx");
if (IS_ERR(dma->chan_rx)) {
- dev_err(dev, "can't request DMA rx channel\n");
ret = PTR_ERR(dma->chan_rx);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "can't request DMA rx channel\n");
+
goto fail_tx;
}
@@ -73,7 +76,8 @@ fail_tx:
dma_release_channel(dma->chan_tx);
fail_al:
devm_kfree(dev, dma);
- dev_info(dev, "can't use DMA\n");
+ if (ret != -EPROBE_DEFER)
+ dev_info(dev, "can't use DMA\n");
return ERR_PTR(ret);
}
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
index d6a69dfcac3f..48e269284369 100644
--- a/drivers/i2c/busses/i2c-stm32f4.c
+++ b/drivers/i2c/busses/i2c-stm32f4.c
@@ -797,8 +797,10 @@ static int stm32f4_i2c_probe(struct platform_device *pdev)
rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(rst)) {
- dev_err(&pdev->dev, "Error: Missing controller reset\n");
ret = PTR_ERR(rst);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Error: Missing reset ctrl\n");
+
goto clk_free;
}
reset_control_assert(rst);
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 330ffed011e0..bff3479fe122 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -189,8 +189,6 @@ struct stm32f7_i2c_regs {
/**
* struct stm32f7_i2c_spec - private i2c specification timing
* @rate: I2C bus speed (Hz)
- * @rate_min: 80% of I2C bus speed (Hz)
- * @rate_max: 100% of I2C bus speed (Hz)
* @fall_max: Max fall time of both SDA and SCL signals (ns)
* @rise_max: Max rise time of both SDA and SCL signals (ns)
* @hddat_min: Min data hold time (ns)
@@ -201,8 +199,6 @@ struct stm32f7_i2c_regs {
*/
struct stm32f7_i2c_spec {
u32 rate;
- u32 rate_min;
- u32 rate_max;
u32 fall_max;
u32 rise_max;
u32 hddat_min;
@@ -214,7 +210,6 @@ struct stm32f7_i2c_spec {
/**
* struct stm32f7_i2c_setup - private I2C timing setup parameters
- * @speed: I2C speed mode (standard, Fast Plus)
* @speed_freq: I2C speed frequency (Hz)
* @clock_src: I2C clock source frequency (Hz)
* @rise_time: Rise time (ns)
@@ -224,7 +219,6 @@ struct stm32f7_i2c_spec {
* @fmp_clr_offset: Fast Mode Plus clear register offset from set register
*/
struct stm32f7_i2c_setup {
- enum stm32_i2c_speed speed;
u32 speed_freq;
u32 clock_src;
u32 rise_time;
@@ -287,7 +281,7 @@ struct stm32f7_i2c_msg {
* @base: virtual memory area
* @complete: completion of I2C message
* @clk: hw i2c clock
- * @speed: I2C clock frequency of the controller. Standard, Fast or Fast+
+ * @bus_rate: I2C clock frequency of the controller
* @msg: Pointer to data to be written
* @msg_num: number of I2C messages to be executed
* @msg_id: message identifiant
@@ -314,7 +308,7 @@ struct stm32f7_i2c_dev {
void __iomem *base;
struct completion complete;
struct clk *clk;
- int speed;
+ unsigned int bus_rate;
struct i2c_msg *msg;
unsigned int msg_num;
unsigned int msg_id;
@@ -342,11 +336,9 @@ struct stm32f7_i2c_dev {
* Table10. Characteristics of the SDA and SCL bus lines for Standard, Fast,
* and Fast-mode Plus I2C-bus devices
*/
-static struct stm32f7_i2c_spec i2c_specs[] = {
- [STM32_I2C_SPEED_STANDARD] = {
+static struct stm32f7_i2c_spec stm32f7_i2c_specs[] = {
+ {
.rate = I2C_MAX_STANDARD_MODE_FREQ,
- .rate_min = I2C_MAX_STANDARD_MODE_FREQ * 8 / 10, /* 80% */
- .rate_max = I2C_MAX_STANDARD_MODE_FREQ,
.fall_max = 300,
.rise_max = 1000,
.hddat_min = 0,
@@ -355,10 +347,8 @@ static struct stm32f7_i2c_spec i2c_specs[] = {
.l_min = 4700,
.h_min = 4000,
},
- [STM32_I2C_SPEED_FAST] = {
+ {
.rate = I2C_MAX_FAST_MODE_FREQ,
- .rate_min = I2C_MAX_FAST_MODE_FREQ * 8 / 10, /* 80% */
- .rate_max = I2C_MAX_FAST_MODE_FREQ,
.fall_max = 300,
.rise_max = 300,
.hddat_min = 0,
@@ -367,10 +357,8 @@ static struct stm32f7_i2c_spec i2c_specs[] = {
.l_min = 1300,
.h_min = 600,
},
- [STM32_I2C_SPEED_FAST_PLUS] = {
+ {
.rate = I2C_MAX_FAST_MODE_PLUS_FREQ,
- .rate_min = I2C_MAX_FAST_MODE_PLUS_FREQ * 8 / 10, /* 80% */
- .rate_max = I2C_MAX_FAST_MODE_PLUS_FREQ,
.fall_max = 100,
.rise_max = 120,
.hddat_min = 0,
@@ -411,10 +399,23 @@ static void stm32f7_i2c_disable_irq(struct stm32f7_i2c_dev *i2c_dev, u32 mask)
stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, mask);
}
+static struct stm32f7_i2c_spec *stm32f7_get_specs(u32 rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(stm32f7_i2c_specs); i++)
+ if (rate <= stm32f7_i2c_specs[i].rate)
+ return &stm32f7_i2c_specs[i];
+
+ return ERR_PTR(-EINVAL);
+}
+
+#define RATE_MIN(rate) ((rate) * 8 / 10)
static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
struct stm32f7_i2c_setup *setup,
struct stm32f7_i2c_timings *output)
{
+ struct stm32f7_i2c_spec *specs;
u32 p_prev = STM32F7_PRESC_MAX;
u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
setup->clock_src);
@@ -432,18 +433,19 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
u16 p, l, a, h;
int ret = 0;
- if (setup->speed >= STM32_I2C_SPEED_END) {
- dev_err(i2c_dev->dev, "speed out of bound {%d/%d}\n",
- setup->speed, STM32_I2C_SPEED_END - 1);
+ specs = stm32f7_get_specs(setup->speed_freq);
+ if (specs == ERR_PTR(-EINVAL)) {
+ dev_err(i2c_dev->dev, "speed out of bound {%d}\n",
+ setup->speed_freq);
return -EINVAL;
}
- if ((setup->rise_time > i2c_specs[setup->speed].rise_max) ||
- (setup->fall_time > i2c_specs[setup->speed].fall_max)) {
+ if ((setup->rise_time > specs->rise_max) ||
+ (setup->fall_time > specs->fall_max)) {
dev_err(i2c_dev->dev,
"timings out of bound Rise{%d>%d}/Fall{%d>%d}\n",
- setup->rise_time, i2c_specs[setup->speed].rise_max,
- setup->fall_time, i2c_specs[setup->speed].fall_max);
+ setup->rise_time, specs->rise_max,
+ setup->fall_time, specs->fall_max);
return -EINVAL;
}
@@ -454,12 +456,6 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
return -EINVAL;
}
- if (setup->speed_freq > i2c_specs[setup->speed].rate) {
- dev_err(i2c_dev->dev, "ERROR: Freq {%d/%d}\n",
- setup->speed_freq, i2c_specs[setup->speed].rate);
- return -EINVAL;
- }
-
/* Analog and Digital Filters */
af_delay_min =
(setup->analog_filter ?
@@ -469,13 +465,13 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
STM32F7_I2C_ANALOG_FILTER_DELAY_MAX : 0);
dnf_delay = setup->dnf * i2cclk;
- sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time -
+ sdadel_min = specs->hddat_min + setup->fall_time -
af_delay_min - (setup->dnf + 3) * i2cclk;
- sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time -
+ sdadel_max = specs->vddat_max - setup->rise_time -
af_delay_max - (setup->dnf + 4) * i2cclk;
- scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min;
+ scldel_min = setup->rise_time + specs->sudat_min;
if (sdadel_min < 0)
sdadel_min = 0;
@@ -530,8 +526,8 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
tsync = af_delay_min + dnf_delay + (2 * i2cclk);
s = NULL;
- clk_max = NSEC_PER_SEC / i2c_specs[setup->speed].rate_min;
- clk_min = NSEC_PER_SEC / i2c_specs[setup->speed].rate_max;
+ clk_max = NSEC_PER_SEC / RATE_MIN(setup->speed_freq);
+ clk_min = NSEC_PER_SEC / setup->speed_freq;
/*
* Among Prescaler possibilities discovered above figures out SCL Low
@@ -549,7 +545,7 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
for (l = 0; l < STM32F7_SCLL_MAX; l++) {
u32 tscl_l = (l + 1) * prescaler + tsync;
- if ((tscl_l < i2c_specs[setup->speed].l_min) ||
+ if ((tscl_l < specs->l_min) ||
(i2cclk >=
((tscl_l - af_delay_min - dnf_delay) / 4))) {
continue;
@@ -561,7 +557,7 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
setup->rise_time + setup->fall_time;
if ((tscl >= clk_min) && (tscl <= clk_max) &&
- (tscl_h >= i2c_specs[setup->speed].h_min) &&
+ (tscl_h >= specs->h_min) &&
(i2cclk < tscl_h)) {
int clk_error = tscl - i2cbus;
@@ -607,6 +603,17 @@ exit:
return ret;
}
+static u32 stm32f7_get_lower_rate(u32 rate)
+{
+ int i = ARRAY_SIZE(stm32f7_i2c_specs);
+
+ while (--i)
+ if (stm32f7_i2c_specs[i].rate < rate)
+ break;
+
+ return stm32f7_i2c_specs[i].rate;
+}
+
static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
struct stm32f7_i2c_setup *setup)
{
@@ -619,18 +626,15 @@ static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
i2c_parse_fw_timings(i2c_dev->dev, t, false);
- if (t->bus_freq_hz >= I2C_MAX_FAST_MODE_PLUS_FREQ)
- i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS;
- else if (t->bus_freq_hz >= I2C_MAX_FAST_MODE_FREQ)
- i2c_dev->speed = STM32_I2C_SPEED_FAST;
- else
- i2c_dev->speed = STM32_I2C_SPEED_STANDARD;
+ if (t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) {
+ dev_err(i2c_dev->dev, "Invalid bus speed (%i>%i)\n",
+ t->bus_freq_hz, I2C_MAX_FAST_MODE_PLUS_FREQ);
+ return -EINVAL;
+ }
+ setup->speed_freq = t->bus_freq_hz;
i2c_dev->setup.rise_time = t->scl_rise_ns;
i2c_dev->setup.fall_time = t->scl_fall_ns;
-
- setup->speed = i2c_dev->speed;
- setup->speed_freq = i2c_specs[setup->speed].rate;
setup->clock_src = clk_get_rate(i2c_dev->clk);
if (!setup->clock_src) {
@@ -644,17 +648,13 @@ static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
if (ret) {
dev_err(i2c_dev->dev,
"failed to compute I2C timings.\n");
- if (i2c_dev->speed > STM32_I2C_SPEED_STANDARD) {
- i2c_dev->speed--;
- setup->speed = i2c_dev->speed;
- setup->speed_freq =
- i2c_specs[setup->speed].rate;
- dev_warn(i2c_dev->dev,
- "downgrade I2C Speed Freq to (%i)\n",
- i2c_specs[setup->speed].rate);
- } else {
+ if (setup->speed_freq <= I2C_MAX_STANDARD_MODE_FREQ)
break;
- }
+ setup->speed_freq =
+ stm32f7_get_lower_rate(setup->speed_freq);
+ dev_warn(i2c_dev->dev,
+ "downgrade I2C Speed Freq to (%i)\n",
+ setup->speed_freq);
}
} while (ret);
@@ -663,13 +663,15 @@ static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
return ret;
}
- dev_dbg(i2c_dev->dev, "I2C Speed(%i), Freq(%i), Clk Source(%i)\n",
- setup->speed, setup->speed_freq, setup->clock_src);
+ dev_dbg(i2c_dev->dev, "I2C Speed(%i), Clk Source(%i)\n",
+ setup->speed_freq, setup->clock_src);
dev_dbg(i2c_dev->dev, "I2C Rise(%i) and Fall(%i) Time\n",
setup->rise_time, setup->fall_time);
dev_dbg(i2c_dev->dev, "I2C Analog Filter(%s), DNF(%i)\n",
(setup->analog_filter ? "On" : "Off"), setup->dnf);
+ i2c_dev->bus_rate = setup->speed_freq;
+
return 0;
}
@@ -1462,7 +1464,8 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
/* NACK received */
if (status & STM32F7_I2C_ISR_NACKF) {
- dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__);
+ dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
+ __func__, f7_msg->addr);
writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
f7_msg->result = -ENXIO;
}
@@ -1866,7 +1869,7 @@ static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev,
{
int ret;
- if (i2c_dev->speed != STM32_I2C_SPEED_FAST_PLUS ||
+ if (i2c_dev->bus_rate <= I2C_MAX_FAST_MODE_FREQ ||
IS_ERR_OR_NULL(i2c_dev->regmap))
/* Optional */
return 0;
@@ -1940,8 +1943,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
if (!i2c_dev)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
+ i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base);
phy_addr = (dma_addr_t)res->start;
@@ -1967,7 +1969,8 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c_dev->clk)) {
- dev_err(&pdev->dev, "Error: Missing controller clock\n");
+ if (PTR_ERR(i2c_dev->clk) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Failed to get controller clock\n");
return PTR_ERR(i2c_dev->clk);
}
@@ -1979,8 +1982,10 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
rst = devm_reset_control_get(&pdev->dev, NULL);
if (IS_ERR(rst)) {
- dev_err(&pdev->dev, "Error: Missing controller reset\n");
ret = PTR_ERR(rst);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Error: Missing reset ctrl\n");
+
goto clk_free;
}
reset_control_assert(rst);
@@ -2020,7 +2025,8 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
if (ret)
goto clk_free;
- if (i2c_dev->speed == STM32_I2C_SPEED_FAST_PLUS) {
+ /* Setup Fast mode plus if necessary */
+ if (i2c_dev->bus_rate > I2C_MAX_FAST_MODE_FREQ) {
ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev);
if (ret)
goto clk_free;
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c
index ba6b60caa45e..64d739baf480 100644
--- a/drivers/i2c/busses/i2c-stu300.c
+++ b/drivers/i2c/busses/i2c-stu300.c
@@ -860,7 +860,6 @@ static int stu300_probe(struct platform_device *pdev)
{
struct stu300_dev *dev;
struct i2c_adapter *adap;
- struct resource *res;
int bus_nr;
int ret = 0;
@@ -876,8 +875,7 @@ static int stu300_probe(struct platform_device *pdev)
}
dev->pdev = pdev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev->virtbase = devm_ioremap_resource(&pdev->dev, res);
+ dev->virtbase = devm_platform_ioremap_resource(pdev, 0);
dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
"base %p\n", bus_nr, dev->virtbase);
if (IS_ERR(dev->virtbase))
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index e5293f0b3318..2f6f6468214d 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -187,7 +187,6 @@ static int p2wi_probe(struct platform_device *pdev)
struct device_node *childnp;
unsigned long parent_clk_freq;
u32 clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
- struct resource *r;
struct p2wi *p2wi;
u32 slave_addr;
int clk_div;
@@ -231,17 +230,14 @@ static int p2wi_probe(struct platform_device *pdev)
p2wi->slave_addr = slave_addr;
}
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- p2wi->regs = devm_ioremap_resource(dev, r);
+ p2wi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(p2wi->regs))
return PTR_ERR(p2wi->regs);
strlcpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name));
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(dev, "failed to retrieve irq: %d\n", irq);
+ if (irq < 0)
return irq;
- }
p2wi->clk = devm_clk_get(dev, NULL);
if (IS_ERR(p2wi->clk)) {
diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c
index 9099d0a67ace..c9a3dba6a75d 100644
--- a/drivers/i2c/busses/i2c-synquacer.c
+++ b/drivers/i2c/busses/i2c-synquacer.c
@@ -536,7 +536,6 @@ static const struct i2c_adapter synquacer_i2c_ops = {
static int synquacer_i2c_probe(struct platform_device *pdev)
{
struct synquacer_i2c *i2c;
- struct resource *r;
u32 bus_speed;
int ret;
@@ -574,16 +573,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
return -EINVAL;
}
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->base = devm_ioremap_resource(&pdev->dev, r);
+ i2c->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->base))
return PTR_ERR(i2c->base);
i2c->irq = platform_get_irq(pdev, 0);
- if (i2c->irq < 0) {
- dev_err(&pdev->dev, "no IRQ resource found\n");
+ if (i2c->irq < 0)
return -ENODEV;
- }
ret = devm_request_irq(&pdev->dev, i2c->irq, synquacer_i2c_isr,
0, dev_name(&pdev->dev), i2c);
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 4c4d17ddc96b..15772964a05f 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -6,6 +6,7 @@
* Author: Colin Cross <ccross@android.com>
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
@@ -29,16 +30,17 @@
#define BYTES_PER_FIFO_WORD 4
#define I2C_CNFG 0x000
-#define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12
+#define I2C_CNFG_DEBOUNCE_CNT GENMASK(14, 12)
#define I2C_CNFG_PACKET_MODE_EN BIT(10)
#define I2C_CNFG_NEW_MASTER_FSM BIT(11)
#define I2C_CNFG_MULTI_MASTER_MODE BIT(17)
-#define I2C_STATUS 0x01C
+#define I2C_STATUS 0x01c
#define I2C_SL_CNFG 0x020
#define I2C_SL_CNFG_NACK BIT(1)
#define I2C_SL_CNFG_NEWSL BIT(2)
#define I2C_SL_ADDR1 0x02c
#define I2C_SL_ADDR2 0x030
+#define I2C_TLOW_SEXT 0x034
#define I2C_TX_FIFO 0x050
#define I2C_RX_FIFO 0x054
#define I2C_PACKET_TRANSFER_STATUS 0x058
@@ -48,10 +50,8 @@
#define I2C_FIFO_CONTROL_TX_TRIG(x) (((x) - 1) << 5)
#define I2C_FIFO_CONTROL_RX_TRIG(x) (((x) - 1) << 2)
#define I2C_FIFO_STATUS 0x060
-#define I2C_FIFO_STATUS_TX_MASK 0xF0
-#define I2C_FIFO_STATUS_TX_SHIFT 4
-#define I2C_FIFO_STATUS_RX_MASK 0x0F
-#define I2C_FIFO_STATUS_RX_SHIFT 0
+#define I2C_FIFO_STATUS_TX GENMASK(7, 4)
+#define I2C_FIFO_STATUS_RX GENMASK(3, 0)
#define I2C_INT_MASK 0x064
#define I2C_INT_STATUS 0x068
#define I2C_INT_BUS_CLR_DONE BIT(11)
@@ -61,7 +61,8 @@
#define I2C_INT_TX_FIFO_DATA_REQ BIT(1)
#define I2C_INT_RX_FIFO_DATA_REQ BIT(0)
#define I2C_CLK_DIVISOR 0x06c
-#define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT 16
+#define I2C_CLK_DIVISOR_STD_FAST_MODE GENMASK(31, 16)
+#define I2C_CLK_DIVISOR_HSMODE GENMASK(15, 0)
#define DVC_CTRL_REG1 0x000
#define DVC_CTRL_REG1_INTR_EN BIT(10)
@@ -77,10 +78,11 @@
#define I2C_ERR_UNKNOWN_INTERRUPT BIT(2)
#define I2C_ERR_RX_BUFFER_OVERFLOW BIT(3)
-#define PACKET_HEADER0_HEADER_SIZE_SHIFT 28
-#define PACKET_HEADER0_PACKET_ID_SHIFT 16
-#define PACKET_HEADER0_CONT_ID_SHIFT 12
-#define PACKET_HEADER0_PROTOCOL_I2C BIT(4)
+#define PACKET_HEADER0_HEADER_SIZE GENMASK(29, 28)
+#define PACKET_HEADER0_PACKET_ID GENMASK(23, 16)
+#define PACKET_HEADER0_CONT_ID GENMASK(15, 12)
+#define PACKET_HEADER0_PROTOCOL GENMASK(7, 4)
+#define PACKET_HEADER0_PROTOCOL_I2C 1
#define I2C_HEADER_CONT_ON_NAK BIT(21)
#define I2C_HEADER_READ BIT(19)
@@ -91,21 +93,35 @@
#define I2C_HEADER_SLAVE_ADDR_SHIFT 1
#define I2C_BUS_CLEAR_CNFG 0x084
-#define I2C_BC_SCLK_THRESHOLD 9
-#define I2C_BC_SCLK_THRESHOLD_SHIFT 16
+#define I2C_BC_SCLK_THRESHOLD GENMASK(23, 16)
#define I2C_BC_STOP_COND BIT(2)
#define I2C_BC_TERMINATE BIT(1)
#define I2C_BC_ENABLE BIT(0)
#define I2C_BUS_CLEAR_STATUS 0x088
#define I2C_BC_STATUS BIT(0)
-#define I2C_CONFIG_LOAD 0x08C
+#define I2C_CONFIG_LOAD 0x08c
#define I2C_MSTR_CONFIG_LOAD BIT(0)
#define I2C_CLKEN_OVERRIDE 0x090
#define I2C_MST_CORE_CLKEN_OVR BIT(0)
-#define I2C_CONFIG_LOAD_TIMEOUT 1000000
+#define I2C_INTERFACE_TIMING_0 0x094
+#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8)
+#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0)
+#define I2C_INTERFACE_TIMING_1 0x098
+#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24)
+#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
+#define I2C_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
+#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
+
+#define I2C_HS_INTERFACE_TIMING_0 0x09c
+#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8)
+#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0)
+#define I2C_HS_INTERFACE_TIMING_1 0x0a0
+#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
+#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
+#define I2C_HS_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
#define I2C_MST_FIFO_CONTROL 0x0b4
#define I2C_MST_FIFO_CONTROL_RX_FLUSH BIT(0)
@@ -114,14 +130,11 @@
#define I2C_MST_FIFO_CONTROL_TX_TRIG(x) (((x) - 1) << 16)
#define I2C_MST_FIFO_STATUS 0x0b8
-#define I2C_MST_FIFO_STATUS_RX_MASK 0xff
-#define I2C_MST_FIFO_STATUS_RX_SHIFT 0
-#define I2C_MST_FIFO_STATUS_TX_MASK 0xff0000
-#define I2C_MST_FIFO_STATUS_TX_SHIFT 16
+#define I2C_MST_FIFO_STATUS_TX GENMASK(23, 16)
+#define I2C_MST_FIFO_STATUS_RX GENMASK(7, 0)
-#define I2C_INTERFACE_TIMING_0 0x94
-#define I2C_THIGH_SHIFT 8
-#define I2C_INTERFACE_TIMING_1 0x98
+/* configuration load timeout in microseconds */
+#define I2C_CONFIG_LOAD_TIMEOUT 1000000
/* Packet header size in bytes */
#define I2C_PACKET_HEADER_SIZE 12
@@ -230,6 +243,7 @@ struct tegra_i2c_hw_feature {
* @cont_id: I2C controller ID, used for packet header
* @irq: IRQ number of transfer complete interrupt
* @is_dvc: identifies the DVC I2C controller, has a different register layout
+ * @is_vi: identifies the VI I2C controller, has a different register layout
* @msg_complete: transfer completion notifier
* @msg_err: error code for completed message
* @msg_buf: pointer to current message data
@@ -253,12 +267,14 @@ struct tegra_i2c_dev {
struct i2c_adapter adapter;
struct clk *div_clk;
struct clk *fast_clk;
+ struct clk *slow_clk;
struct reset_control *rst;
void __iomem *base;
phys_addr_t base_phys;
int cont_id;
int irq;
int is_dvc;
+ bool is_vi;
struct completion msg_complete;
int msg_err;
u8 *msg_buf;
@@ -297,6 +313,8 @@ static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,
{
if (i2c_dev->is_dvc)
reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
+ else if (i2c_dev->is_vi)
+ reg = 0xc00 + (reg << 2);
return reg;
}
@@ -495,12 +513,10 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
if (i2c_dev->hw->has_mst_fifo) {
val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
- rx_fifo_avail = (val & I2C_MST_FIFO_STATUS_RX_MASK) >>
- I2C_MST_FIFO_STATUS_RX_SHIFT;
+ rx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_RX, val);
} else {
val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
- rx_fifo_avail = (val & I2C_FIFO_STATUS_RX_MASK) >>
- I2C_FIFO_STATUS_RX_SHIFT;
+ rx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_RX, val);
}
/* Rounds down to not include partial word at the end of buf */
@@ -551,12 +567,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
if (i2c_dev->hw->has_mst_fifo) {
val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
- tx_fifo_avail = (val & I2C_MST_FIFO_STATUS_TX_MASK) >>
- I2C_MST_FIFO_STATUS_TX_SHIFT;
+ tx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_TX, val);
} else {
val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
- tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >>
- I2C_FIFO_STATUS_TX_SHIFT;
+ tx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_TX, val);
}
/* Rounds down to not include partial word at the end of buf */
@@ -650,6 +664,14 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
}
}
+ if (i2c_dev->slow_clk) {
+ ret = clk_enable(i2c_dev->slow_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable slow clock: %d\n", ret);
+ return ret;
+ }
+ }
+
ret = clk_enable(i2c_dev->div_clk);
if (ret < 0) {
dev_err(i2c_dev->dev,
@@ -666,6 +688,10 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
clk_disable(i2c_dev->div_clk);
+
+ if (i2c_dev->slow_clk)
+ clk_disable(i2c_dev->slow_clk);
+
if (!i2c_dev->hw->has_single_clk_source)
clk_disable(i2c_dev->fast_clk);
@@ -703,6 +729,35 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
return 0;
}
+static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
+{
+ u32 value;
+
+ value = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, 2) |
+ FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, 4);
+ i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_0);
+
+ value = FIELD_PREP(I2C_INTERFACE_TIMING_TBUF, 4) |
+ FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STO, 7) |
+ FIELD_PREP(I2C_INTERFACE_TIMING_THD_STA, 4) |
+ FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STA, 4);
+ i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_1);
+
+ value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, 3) |
+ FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, 8);
+ i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_0);
+
+ value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STO, 11) |
+ FIELD_PREP(I2C_HS_INTERFACE_TIMING_THD_STA, 11) |
+ FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STA, 11);
+ i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_1);
+
+ value = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND;
+ i2c_writel(i2c_dev, value, I2C_BUS_CLEAR_CNFG);
+
+ i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
+}
+
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
{
u32 val;
@@ -719,7 +774,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
tegra_dvc_init(i2c_dev);
val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
- (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
+ FIELD_PREP(I2C_CNFG_DEBOUNCE_CNT, 2);
if (i2c_dev->hw->has_multi_master_mode)
val |= I2C_CNFG_MULTI_MASTER_MODE;
@@ -727,10 +782,14 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
i2c_writel(i2c_dev, val, I2C_CNFG);
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
+ if (i2c_dev->is_vi)
+ tegra_i2c_vi_init(i2c_dev);
+
/* Make sure clock divisor programmed correctly */
- clk_divisor = i2c_dev->hw->clk_divisor_hs_mode;
- clk_divisor |= i2c_dev->clk_divisor_non_hs_mode <<
- I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
+ clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
+ i2c_dev->hw->clk_divisor_hs_mode) |
+ FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE,
+ i2c_dev->clk_divisor_non_hs_mode);
i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
if (i2c_dev->bus_clk_rate > I2C_MAX_STANDARD_MODE_FREQ &&
@@ -745,7 +804,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
}
if (i2c_dev->hw->has_interface_timing_reg) {
- val = (thigh << I2C_THIGH_SHIFT) | tlow;
+ val = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) |
+ FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow);
i2c_writel(i2c_dev, val, I2C_INTERFACE_TIMING_0);
}
@@ -768,7 +828,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
}
}
- if (!i2c_dev->is_dvc) {
+ if (!i2c_dev->is_dvc && !i2c_dev->is_vi) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
@@ -996,14 +1056,13 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
do {
u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
- if (status) {
+ if (status)
tegra_i2c_isr(i2c_dev->irq, i2c_dev);
- if (completion_done(complete)) {
- s64 delta = ktime_ms_delta(ktimeout, ktime);
+ if (completion_done(complete)) {
+ s64 delta = ktime_ms_delta(ktimeout, ktime);
- return msecs_to_jiffies(delta) ?: 1;
- }
+ return msecs_to_jiffies(delta) ?: 1;
}
ktime = ktime_get();
@@ -1030,14 +1089,18 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
disable_irq(i2c_dev->irq);
/*
- * There is a chance that completion may happen after IRQ
- * synchronization, which is done by disable_irq().
+ * Under some rare circumstances (like running KASAN +
+ * NFS root) CPU, which handles interrupt, may stuck in
+ * uninterruptible state for a significant time. In this
+ * case we will get timeout if I2C transfer is running on
+ * a sibling CPU, despite of IRQ being raised.
+ *
+ * In order to handle this rare condition, the IRQ status
+ * needs to be checked after timeout.
*/
- if (ret == 0 && completion_done(complete)) {
- dev_warn(i2c_dev->dev,
- "completion done after timeout\n");
- ret = 1;
- }
+ if (ret == 0)
+ ret = tegra_i2c_poll_completion_timeout(i2c_dev,
+ complete, 0);
}
return ret;
@@ -1051,8 +1114,8 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
u32 reg;
reinit_completion(&i2c_dev->msg_complete);
- reg = (I2C_BC_SCLK_THRESHOLD << I2C_BC_SCLK_THRESHOLD_SHIFT) |
- I2C_BC_STOP_COND | I2C_BC_TERMINATE;
+ reg = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
+ I2C_BC_TERMINATE;
i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
if (i2c_dev->hw->has_config_load_reg) {
err = tegra_i2c_wait_for_config_load(i2c_dev);
@@ -1145,10 +1208,11 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
}
}
- packet_header = (0 << PACKET_HEADER0_HEADER_SIZE_SHIFT) |
- PACKET_HEADER0_PROTOCOL_I2C |
- (i2c_dev->cont_id << PACKET_HEADER0_CONT_ID_SHIFT) |
- (1 << PACKET_HEADER0_PACKET_ID_SHIFT);
+ packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
+ FIELD_PREP(PACKET_HEADER0_PROTOCOL,
+ PACKET_HEADER0_PROTOCOL_I2C) |
+ FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
+ FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
if (dma && !i2c_dev->msg_read)
*buffer++ = packet_header;
else
@@ -1216,6 +1280,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
time_left = tegra_i2c_wait_completion_timeout(
i2c_dev, &i2c_dev->dma_complete, xfer_time);
+ /*
+ * Synchronize DMA first, since dmaengine_terminate_sync()
+ * performs synchronization after the transfer's termination
+ * and we want to get a completion if transfer succeeded.
+ */
+ dmaengine_synchronize(i2c_dev->msg_read ?
+ i2c_dev->rx_dma_chan :
+ i2c_dev->tx_dma_chan);
+
dmaengine_terminate_sync(i2c_dev->msg_read ?
i2c_dev->rx_dma_chan :
i2c_dev->tx_dma_chan);
@@ -1544,6 +1617,7 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
static const struct of_device_id tegra_i2c_of_match[] = {
{ .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, },
{ .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, },
+ { .compatible = "nvidia,tegra210-i2c-vi", .data = &tegra210_i2c_hw, },
{ .compatible = "nvidia,tegra210-i2c", .data = &tegra210_i2c_hw, },
{ .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, },
{ .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
@@ -1556,6 +1630,7 @@ MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
static int tegra_i2c_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct tegra_i2c_dev *i2c_dev;
struct resource *res;
struct clk *div_clk;
@@ -1611,6 +1686,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->hw = of_device_get_match_data(&pdev->dev);
i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
"nvidia,tegra20-i2c-dvc");
+ i2c_dev->is_vi = of_device_is_compatible(dev->of_node,
+ "nvidia,tegra210-i2c-vi");
i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
i2c_dev->dma_buf_size = i2c_dev->adapter.quirks->max_write_len +
I2C_PACKET_HEADER_SIZE;
@@ -1626,6 +1703,17 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->fast_clk = fast_clk;
}
+ if (i2c_dev->is_vi) {
+ i2c_dev->slow_clk = devm_clk_get(dev, "slow");
+ if (IS_ERR(i2c_dev->slow_clk)) {
+ if (PTR_ERR(i2c_dev->slow_clk) != -EPROBE_DEFER)
+ dev_err(dev, "failed to get slow clock: %ld\n",
+ PTR_ERR(i2c_dev->slow_clk));
+
+ return PTR_ERR(i2c_dev->slow_clk);
+ }
+ }
+
platform_set_drvdata(pdev, i2c_dev);
if (!i2c_dev->hw->has_single_clk_source) {
@@ -1636,6 +1724,14 @@ static int tegra_i2c_probe(struct platform_device *pdev)
}
}
+ if (i2c_dev->slow_clk) {
+ ret = clk_prepare(i2c_dev->slow_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to prepare slow clock: %d\n", ret);
+ goto unprepare_fast_clk;
+ }
+ }
+
if (i2c_dev->bus_clk_rate > I2C_MAX_FAST_MODE_FREQ &&
i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_PLUS_FREQ)
i2c_dev->clk_divisor_non_hs_mode =
@@ -1651,7 +1747,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
ret = clk_prepare(i2c_dev->div_clk);
if (ret < 0) {
dev_err(i2c_dev->dev, "Clock prepare failed %d\n", ret);
- goto unprepare_fast_clk;
+ goto unprepare_slow_clk;
}
pm_runtime_irq_safe(&pdev->dev);
@@ -1694,8 +1790,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
- ret = devm_request_irq(&pdev->dev, i2c_dev->irq,
- tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev);
+ ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
+ IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
goto release_dma;
@@ -1738,6 +1834,10 @@ disable_rpm:
unprepare_div_clk:
clk_unprepare(i2c_dev->div_clk);
+unprepare_slow_clk:
+ if (i2c_dev->is_vi)
+ clk_unprepare(i2c_dev->slow_clk);
+
unprepare_fast_clk:
if (!i2c_dev->hw->has_single_clk_source)
clk_unprepare(i2c_dev->fast_clk);
@@ -1759,6 +1859,10 @@ static int tegra_i2c_remove(struct platform_device *pdev)
tegra_i2c_runtime_suspend(&pdev->dev);
clk_unprepare(i2c_dev->div_clk);
+
+ if (i2c_dev->slow_clk)
+ clk_unprepare(i2c_dev->slow_clk);
+
if (!i2c_dev->hw->has_single_clk_source)
clk_unprepare(i2c_dev->fast_clk);
@@ -1769,15 +1873,14 @@ static int tegra_i2c_remove(struct platform_device *pdev)
static int __maybe_unused tegra_i2c_suspend(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
- int err;
+ int err = 0;
i2c_mark_adapter_suspended(&i2c_dev->adapter);
- err = pm_runtime_force_suspend(dev);
- if (err < 0)
- return err;
+ if (!pm_runtime_status_suspended(dev))
+ err = tegra_i2c_runtime_suspend(dev);
- return 0;
+ return err;
}
static int __maybe_unused tegra_i2c_resume(struct device *dev)
@@ -1785,6 +1888,10 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev)
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
int err;
+ /*
+ * We need to ensure that clocks are enabled so that registers can be
+ * restored in tegra_i2c_init().
+ */
err = tegra_i2c_runtime_resume(dev);
if (err)
return err;
@@ -1793,13 +1900,16 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev)
if (err)
return err;
- err = tegra_i2c_runtime_suspend(dev);
- if (err)
- return err;
-
- err = pm_runtime_force_resume(dev);
- if (err < 0)
- return err;
+ /*
+ * In case we are runtime suspended, disable clocks again so that we
+ * don't unbalance the clock reference counts during the next runtime
+ * resume transition.
+ */
+ if (pm_runtime_status_suspended(dev)) {
+ err = tegra_i2c_runtime_suspend(dev);
+ if (err)
+ return err;
+ }
i2c_mark_adapter_resumed(&i2c_dev->adapter);
diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c
index 2b258d54d68c..cb4666c54a23 100644
--- a/drivers/i2c/busses/i2c-uniphier-f.c
+++ b/drivers/i2c/busses/i2c-uniphier-f.c
@@ -529,10 +529,8 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
return PTR_ERR(priv->membase);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(dev, "failed to get IRQ number\n");
+ if (irq < 0)
return irq;
- }
if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
bus_speed = I2C_MAX_STANDARD_MODE_FREQ;
diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c
index 668b1fa2b0ef..ee00a44bf4c7 100644
--- a/drivers/i2c/busses/i2c-uniphier.c
+++ b/drivers/i2c/busses/i2c-uniphier.c
@@ -324,10 +324,8 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
return PTR_ERR(priv->membase);
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(dev, "failed to get IRQ number\n");
+ if (irq < 0)
return irq;
- }
if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
bus_speed = I2C_MAX_STANDARD_MODE_FREQ;
diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c
index 391c878a7cdc..f2241cedf5d3 100644
--- a/drivers/i2c/busses/i2c-xlp9xx.c
+++ b/drivers/i2c/busses/i2c-xlp9xx.c
@@ -506,23 +506,19 @@ static int xlp9xx_i2c_smbus_setup(struct xlp9xx_i2c_dev *priv,
static int xlp9xx_i2c_probe(struct platform_device *pdev)
{
struct xlp9xx_i2c_dev *priv;
- struct resource *res;
int err = 0;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->base = devm_ioremap_resource(&pdev->dev, res);
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
priv->irq = platform_get_irq(pdev, 0);
- if (priv->irq <= 0) {
- dev_err(&pdev->dev, "invalid irq!\n");
+ if (priv->irq <= 0)
return priv->irq;
- }
/* SMBAlert irq */
priv->alert_data.irq = platform_get_irq(pdev, 1);
if (priv->alert_data.irq <= 0)
diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c
index 282f161a8b08..126d1393e548 100644
--- a/drivers/i2c/busses/i2c-xlr.c
+++ b/drivers/i2c/busses/i2c-xlr.c
@@ -362,7 +362,6 @@ static int xlr_i2c_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct xlr_i2c_private *priv;
- struct resource *res;
struct clk *clk;
unsigned long clk_rate;
unsigned long clk_div;
@@ -380,8 +379,7 @@ static int xlr_i2c_probe(struct platform_device *pdev)
else
priv->cfg = &xlr_i2c_config_default;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->iobase = devm_ioremap_resource(&pdev->dev, res);
+ priv->iobase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->iobase))
return PTR_ERR(priv->iobase);
diff --git a/drivers/i2c/busses/i2c-zx2967.c b/drivers/i2c/busses/i2c-zx2967.c
index 5f3318559b8d..8db9519695a6 100644
--- a/drivers/i2c/busses/i2c-zx2967.c
+++ b/drivers/i2c/busses/i2c-zx2967.c
@@ -502,7 +502,6 @@ static int zx2967_i2c_probe(struct platform_device *pdev)
{
struct zx2967_i2c *i2c;
void __iomem *reg_base;
- struct resource *res;
struct clk *clk;
int ret;
@@ -510,8 +509,7 @@ static int zx2967_i2c_probe(struct platform_device *pdev)
if (!i2c)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- reg_base = devm_ioremap_resource(&pdev->dev, res);
+ reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg_base))
return PTR_ERR(reg_base);
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index c8f42f2037cb..2ade99b105b9 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -468,16 +468,12 @@ struct notifier_block i2c_acpi_notifier = {
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
struct i2c_board_info *info)
{
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct i2c_acpi_lookup lookup;
struct i2c_adapter *adapter;
- struct acpi_device *adev;
LIST_HEAD(resource_list);
int ret;
- adev = ACPI_COMPANION(dev);
- if (!adev)
- return ERR_PTR(-EINVAL);
-
memset(&lookup, 0, sizeof(lookup));
lookup.info = info;
lookup.device_handle = acpi_device_handle(adev);
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 1f1442dfcad7..d1f278f73011 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1598,6 +1598,18 @@ void i2c_del_adapter(struct i2c_adapter *adap)
}
EXPORT_SYMBOL(i2c_del_adapter);
+static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p,
+ u32 def_val, bool use_def)
+{
+ int ret;
+
+ ret = device_property_read_u32(dev, prop_name, cur_val_p);
+ if (ret && use_def)
+ *cur_val_p = def_val;
+
+ dev_dbg(dev, "%s: %u\n", prop_name, *cur_val_p);
+}
+
/**
* i2c_parse_fw_timings - get I2C related timing parameters from firmware
* @dev: The device to scan for I2C timing properties
@@ -1616,49 +1628,28 @@ EXPORT_SYMBOL(i2c_del_adapter);
*/
void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults)
{
- int ret;
-
- ret = device_property_read_u32(dev, "clock-frequency", &t->bus_freq_hz);
- if (ret && use_defaults)
- t->bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
-
- ret = device_property_read_u32(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns);
- if (ret && use_defaults) {
- if (t->bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ)
- t->scl_rise_ns = 1000;
- else if (t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ)
- t->scl_rise_ns = 300;
- else
- t->scl_rise_ns = 120;
- }
-
- ret = device_property_read_u32(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns);
- if (ret && use_defaults) {
- if (t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ)
- t->scl_fall_ns = 300;
- else
- t->scl_fall_ns = 120;
- }
-
- ret = device_property_read_u32(dev, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns);
- if (ret && use_defaults)
- t->scl_int_delay_ns = 0;
+ bool u = use_defaults;
+ u32 d;
- ret = device_property_read_u32(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns);
- if (ret && use_defaults)
- t->sda_fall_ns = t->scl_fall_ns;
+ i2c_parse_timing(dev, "clock-frequency", &t->bus_freq_hz,
+ I2C_MAX_STANDARD_MODE_FREQ, u);
- ret = device_property_read_u32(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns);
- if (ret && use_defaults)
- t->sda_hold_ns = 0;
+ d = t->bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ ? 1000 :
+ t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ ? 300 : 120;
+ i2c_parse_timing(dev, "i2c-scl-rising-time-ns", &t->scl_rise_ns, d, u);
- ret = device_property_read_u32(dev, "i2c-digital-filter-width-ns", &t->digital_filter_width_ns);
- if (ret && use_defaults)
- t->digital_filter_width_ns = 0;
+ d = t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ ? 300 : 120;
+ i2c_parse_timing(dev, "i2c-scl-falling-time-ns", &t->scl_fall_ns, d, u);
- ret = device_property_read_u32(dev, "i2c-analog-filter-cutoff-frequency", &t->analog_filter_cutoff_freq_hz);
- if (ret && use_defaults)
- t->analog_filter_cutoff_freq_hz = 0;
+ i2c_parse_timing(dev, "i2c-scl-internal-delay-ns",
+ &t->scl_int_delay_ns, 0, u);
+ i2c_parse_timing(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns,
+ t->scl_fall_ns, u);
+ i2c_parse_timing(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns, 0, u);
+ i2c_parse_timing(dev, "i2c-digital-filter-width-ns",
+ &t->digital_filter_width_ns, 0, u);
+ i2c_parse_timing(dev, "i2c-analog-filter-cutoff-frequency",
+ &t->analog_filter_cutoff_freq_hz, 0, u);
}
EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);
@@ -2195,7 +2186,6 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
const unsigned short *address_list;
struct i2c_client *temp_client;
int i, err = 0;
- int adap_id = i2c_adapter_id(adapter);
address_list = driver->address_list;
if (!driver->detect || !address_list)
@@ -2223,7 +2213,7 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
dev_dbg(&adapter->dev,
"found normal entry for adapter %d, addr 0x%02x\n",
- adap_id, address_list[i]);
+ i2c_adapter_id(adapter), address_list[i]);
temp_client->addr = address_list[i];
err = i2c_detect_address(temp_client, driver);
if (unlikely(err))
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
index 517d98be68d2..94ff1693b391 100644
--- a/drivers/i2c/i2c-core.h
+++ b/drivers/i2c/i2c-core.h
@@ -23,9 +23,9 @@ int i2c_dev_irq_from_resources(const struct resource *resources,
unsigned int num_resources);
/*
- * We only allow atomic transfers for very late communication, e.g. to send
- * the powerdown command to a PMIC. Atomic transfers are a corner case and not
- * for generic use!
+ * We only allow atomic transfers for very late communication, e.g. to access a
+ * PMIC when powering down. Atomic transfers are a corner case and not for
+ * generic use!
*/
static inline bool i2c_in_atomic_xfer_mode(void)
{
diff --git a/drivers/i2c/i2c-slave-eeprom.c b/drivers/i2c/i2c-slave-eeprom.c
index cb415b10642f..593f2fd39d17 100644
--- a/drivers/i2c/i2c-slave-eeprom.c
+++ b/drivers/i2c/i2c-slave-eeprom.c
@@ -5,10 +5,9 @@
* Copyright (C) 2014 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
* Copyright (C) 2014 by Renesas Electronics Corporation
*
- * Because most IP blocks can only detect one I2C slave address anyhow, this
- * driver does not support simulating EEPROM types which take more than one
- * address. It is prepared to simulate bigger EEPROMs with an internal 16 bit
- * pointer, yet implementation is deferred until the need actually arises.
+ * Because most slave IP cores can only detect one I2C slave address anyhow,
+ * this driver does not support simulating EEPROM types which take more than
+ * one address.
*/
/*
@@ -18,6 +17,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -40,7 +40,7 @@ struct eeprom_data {
#define I2C_SLAVE_BYTELEN GENMASK(15, 0)
#define I2C_SLAVE_FLAG_ADDR16 BIT(16)
#define I2C_SLAVE_FLAG_RO BIT(17)
-#define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | (_len))
+#define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | ((_len) - 1))
static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
enum i2c_slave_event event, u8 *val)
@@ -120,24 +120,47 @@ static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kob
return count;
}
+static int i2c_slave_init_eeprom_data(struct eeprom_data *eeprom, struct i2c_client *client,
+ unsigned int size)
+{
+ const struct firmware *fw;
+ const char *eeprom_data;
+ int ret = device_property_read_string(&client->dev, "firmware-name", &eeprom_data);
+
+ if (!ret) {
+ ret = request_firmware_into_buf(&fw, eeprom_data, &client->dev,
+ eeprom->buffer, size);
+ if (ret)
+ return ret;
+ release_firmware(fw);
+ } else {
+ /* An empty eeprom typically has all bits set to 1 */
+ memset(eeprom->buffer, 0xff, size);
+ }
+ return 0;
+}
+
static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct eeprom_data *eeprom;
int ret;
- unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data);
+ unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data) + 1;
unsigned int flag_addr16 = FIELD_GET(I2C_SLAVE_FLAG_ADDR16, id->driver_data);
eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL);
if (!eeprom)
return -ENOMEM;
- eeprom->idx_write_cnt = 0;
eeprom->num_address_bytes = flag_addr16 ? 2 : 1;
eeprom->address_mask = size - 1;
eeprom->read_only = FIELD_GET(I2C_SLAVE_FLAG_RO, id->driver_data);
spin_lock_init(&eeprom->buffer_lock);
i2c_set_clientdata(client, eeprom);
+ ret = i2c_slave_init_eeprom_data(eeprom, client, size);
+ if (ret)
+ return ret;
+
sysfs_bin_attr_init(&eeprom->bin);
eeprom->bin.attr.name = "slave-eeprom";
eeprom->bin.attr.mode = S_IRUSR | S_IWUSR;
@@ -175,6 +198,8 @@ static const struct i2c_device_id i2c_slave_eeprom_id[] = {
{ "slave-24c32ro", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
{ "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) },
{ "slave-24c64ro", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
+ { "slave-24c512", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16) },
+ { "slave-24c512ro", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id);
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index 809bcf8387d0..dc0108287ccf 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -3,10 +3,11 @@
* i2c-smbus.c - SMBus extensions to the I2C protocol
*
* Copyright (C) 2008 David Brownell
- * Copyright (C) 2010 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2010-2019 Jean Delvare <jdelvare@suse.de>
*/
#include <linux/device.h>
+#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/interrupt.h>
@@ -196,6 +197,107 @@ EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert);
module_i2c_driver(smbalert_driver);
+/*
+ * SPD is not part of SMBus but we include it here for convenience as the
+ * target systems are the same.
+ * Restrictions to automatic SPD instantiation:
+ * - Only works if all filled slots have the same memory type
+ * - Only works for DDR2, DDR3 and DDR4 for now
+ * - Only works on systems with 1 to 4 memory slots
+ */
+#if IS_ENABLED(CONFIG_DMI)
+void i2c_register_spd(struct i2c_adapter *adap)
+{
+ int n, slot_count = 0, dimm_count = 0;
+ u16 handle;
+ u8 common_mem_type = 0x0, mem_type;
+ u64 mem_size;
+ const char *name;
+
+ while ((handle = dmi_memdev_handle(slot_count)) != 0xffff) {
+ slot_count++;
+
+ /* Skip empty slots */
+ mem_size = dmi_memdev_size(handle);
+ if (!mem_size)
+ continue;
+
+ /* Skip undefined memory type */
+ mem_type = dmi_memdev_type(handle);
+ if (mem_type <= 0x02) /* Invalid, Other, Unknown */
+ continue;
+
+ if (!common_mem_type) {
+ /* First filled slot */
+ common_mem_type = mem_type;
+ } else {
+ /* Check that all filled slots have the same type */
+ if (mem_type != common_mem_type) {
+ dev_warn(&adap->dev,
+ "Different memory types mixed, not instantiating SPD\n");
+ return;
+ }
+ }
+ dimm_count++;
+ }
+
+ /* No useful DMI data, bail out */
+ if (!dimm_count)
+ return;
+
+ dev_info(&adap->dev, "%d/%d memory slots populated (from DMI)\n",
+ dimm_count, slot_count);
+
+ if (slot_count > 4) {
+ dev_warn(&adap->dev,
+ "Systems with more than 4 memory slots not supported yet, not instantiating SPD\n");
+ return;
+ }
+
+ switch (common_mem_type) {
+ case 0x13: /* DDR2 */
+ case 0x18: /* DDR3 */
+ case 0x1C: /* LPDDR2 */
+ case 0x1D: /* LPDDR3 */
+ name = "spd";
+ break;
+ case 0x1A: /* DDR4 */
+ case 0x1E: /* LPDDR4 */
+ name = "ee1004";
+ break;
+ default:
+ dev_info(&adap->dev,
+ "Memory type 0x%02x not supported yet, not instantiating SPD\n",
+ common_mem_type);
+ return;
+ }
+
+ /*
+ * We don't know in which slots the memory modules are. We could
+ * try to guess from the slot names, but that would be rather complex
+ * and unreliable, so better probe all possible addresses until we
+ * have found all memory modules.
+ */
+ for (n = 0; n < slot_count && dimm_count; n++) {
+ struct i2c_board_info info;
+ unsigned short addr_list[2];
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, name, I2C_NAME_SIZE);
+ addr_list[0] = 0x50 + n;
+ addr_list[1] = I2C_CLIENT_END;
+
+ if (!IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL))) {
+ dev_info(&adap->dev,
+ "Successfully instantiated SPD at 0x%hx\n",
+ addr_list[0]);
+ dimm_count--;
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(i2c_register_spd);
+#endif
+
MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
MODULE_DESCRIPTION("SMBus protocol extensions support");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index a0d926ae3f86..4ad665757dd8 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -1,10 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* I2C multiplexer
*
* Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
* Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
*
- * This module supports the PCA954x and PCA954x series of I2C multiplexer/switch
+ * This module supports the PCA954x and PCA984x series of I2C multiplexer/switch
* chips made by NXP Semiconductors.
* This includes the:
* PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547,
@@ -29,10 +30,6 @@
* i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
* and
* pca9540.c from Jean Delvare <jdelvare@suse.de>.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/device.h>
@@ -43,10 +40,8 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
#include <linux/pm.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <dt-bindings/mux/mux.h>
@@ -198,7 +193,6 @@ static const struct i2c_device_id pca954x_id[] = {
};
MODULE_DEVICE_TABLE(i2c, pca954x_id);
-#ifdef CONFIG_OF
static const struct of_device_id pca954x_of_match[] = {
{ .compatible = "nxp,pca9540", .data = &chips[pca_9540] },
{ .compatible = "nxp,pca9542", .data = &chips[pca_9542] },
@@ -215,7 +209,6 @@ static const struct of_device_id pca954x_of_match[] = {
{}
};
MODULE_DEVICE_TABLE(of, pca954x_of_match);
-#endif
/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
for this as they will try to lock adapter a second time */
@@ -327,21 +320,18 @@ static DEVICE_ATTR_RW(idle_state);
static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
{
struct pca954x *data = dev_id;
- unsigned int child_irq;
- int ret, i, handled = 0;
+ unsigned long pending;
+ int ret, i;
ret = i2c_smbus_read_byte(data->client);
if (ret < 0)
return IRQ_NONE;
- for (i = 0; i < data->chip->nchans; i++) {
- if (ret & BIT(PCA954X_IRQ_OFFSET + i)) {
- child_irq = irq_linear_revmap(data->irq, i);
- handle_nested_irq(child_irq);
- handled++;
- }
- }
- return handled ? IRQ_HANDLED : IRQ_NONE;
+ 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));
+
+ return IRQ_RETVAL(pending);
}
static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
@@ -390,11 +380,8 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc)
static void pca954x_cleanup(struct i2c_mux_core *muxc)
{
struct pca954x *data = i2c_mux_priv(muxc);
- struct i2c_client *client = data->client;
int c, irq;
- device_remove_file(&client->dev, &dev_attr_idle_state);
-
if (data->irq) {
for (c = 0; c < data->chip->nchans; c++) {
irq = irq_find_mapping(data->irq, c);
@@ -429,7 +416,6 @@ static int pca954x_probe(struct i2c_client *client,
{
struct i2c_adapter *adap = client->adapter;
struct device *dev = &client->dev;
- struct device_node *np = dev->of_node;
struct gpio_desc *gpio;
struct i2c_mux_core *muxc;
struct pca954x *data;
@@ -459,7 +445,7 @@ static int pca954x_probe(struct i2c_client *client,
udelay(1);
}
- data->chip = of_device_get_match_data(dev);
+ data->chip = device_get_match_data(dev);
if (!data->chip)
data->chip = &chips[id->driver_data];
@@ -481,8 +467,8 @@ static int pca954x_probe(struct i2c_client *client,
}
data->idle_state = MUX_IDLE_AS_IS;
- if (of_property_read_u32(np, "idle-state", &data->idle_state)) {
- if (np && of_property_read_bool(np, "i2c-mux-idle-disconnect"))
+ if (device_property_read_u32(dev, "idle-state", &data->idle_state)) {
+ if (device_property_read_bool(dev, "i2c-mux-idle-disconnect"))
data->idle_state = MUX_IDLE_DISCONNECT;
}
@@ -539,6 +525,8 @@ static int pca954x_remove(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+ device_remove_file(&client->dev, &dev_attr_idle_state);
+
pca954x_cleanup(muxc);
return 0;
}
@@ -565,7 +553,7 @@ static struct i2c_driver pca954x_driver = {
.driver = {
.name = "pca954x",
.pm = &pca954x_pm,
- .of_match_table = of_match_ptr(pca954x_of_match),
+ .of_match_table = pca954x_of_match,
},
.probe = pca954x_probe,
.remove = pca954x_remove,
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 593f149c2910..973ed4b684ce 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -12,7 +12,7 @@ menuconfig IDE
depends on HAVE_IDE
depends on BLOCK
select BLK_SCSI_REQUEST
- ---help---
+ help
If you say Y here, your kernel will be able to manage ATA/(E)IDE and
ATAPI units. The most common cases are IDE hard drives and ATAPI
CD-ROM drives.
@@ -49,7 +49,7 @@ config IDE_LEGACY
config BLK_DEV_IDE_SATA
bool "Support for SATA (deprecated; conflicts with libata SATA driver)"
default n
- ---help---
+ help
There are two drivers for Serial ATA controllers.
The main driver, "libata", uses the SCSI subsystem
@@ -121,7 +121,7 @@ config BLK_DEV_IDECD
depends on BLK_DEV
select IDE_ATAPI
select CDROM
- ---help---
+ help
If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is
a newer protocol used by IDE CD-ROM and TAPE drives, similar to the
SCSI protocol. Most new CD-ROM drives use ATAPI, including the
@@ -172,7 +172,7 @@ config BLK_DEV_IDETAPE
config BLK_DEV_IDEACPI
bool "IDE ACPI support"
depends on ACPI
- ---help---
+ help
Implement ACPI support for generic IDE devices. On modern
machines ACPI support is required to properly handle ACPI S3 states.
@@ -232,7 +232,7 @@ config BLK_DEV_CMD640
tristate "CMD640 chipset bugfix/support"
depends on X86
select IDE_TIMINGS
- ---help---
+ help
The CMD-Technologies CMD640 IDE chip is used on many common 486 and
Pentium motherboards, usually in combination with a "Neptune" or
"SiS" chipset. Unfortunately, it has a number of rather nasty
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 3728f6325501..dae8d27e772d 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -325,7 +325,7 @@ config MAX5821
config MCP4725
tristate "MCP4725/6 DAC driver"
depends on I2C
- ---help---
+ help
Say Y here if you want to build a driver for the Microchip
MCP 4725/6 12-bit digital-to-analog converter (DAC) with I2C
interface.
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 477418b37786..a83f9eb86bfe 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -8,7 +8,7 @@ menuconfig INFINIBAND
depends on !ALPHA
select IRQ_POLL
select DIMLIB
- ---help---
+ help
Core support for InfiniBand (IB). Make sure to also select
any protocols you wish to use as well as drivers for your
InfiniBand hardware.
@@ -18,7 +18,7 @@ if INFINIBAND
config INFINIBAND_USER_MAD
tristate "InfiniBand userspace MAD support"
depends on INFINIBAND
- ---help---
+ help
Userspace InfiniBand Management Datagram (MAD) support. This
is the kernel side of the userspace MAD support, which allows
userspace processes to send and receive MADs. You will also
@@ -28,7 +28,7 @@ config INFINIBAND_USER_MAD
config INFINIBAND_USER_ACCESS
tristate "InfiniBand userspace access (verbs and CM)"
depends on MMU
- ---help---
+ help
Userspace InfiniBand access support. This enables the
kernel side of userspace verbs and the userspace
communication manager (CM). This allows userspace processes
@@ -40,7 +40,7 @@ config INFINIBAND_USER_ACCESS
config INFINIBAND_EXP_LEGACY_VERBS_NEW_UAPI
bool "Allow experimental legacy verbs in new ioctl uAPI (EXPERIMENTAL)"
depends on INFINIBAND_USER_ACCESS
- ---help---
+ help
IOCTL based uAPI support for Infiniband is enabled by default for
new verbs only. This allows userspace to invoke the IOCTL based uAPI
for current legacy verbs too.
@@ -57,7 +57,7 @@ config INFINIBAND_ON_DEMAND_PAGING
select MMU_NOTIFIER
select INTERVAL_TREE
default y
- ---help---
+ help
On demand paging support for the InfiniBand subsystem.
Together with driver support this allows registration of
memory regions without pinning their pages, fetching the
@@ -67,7 +67,7 @@ config INFINIBAND_ADDR_TRANS
bool "RDMA/CM"
depends on INFINIBAND
default y
- ---help---
+ help
Support for RDMA communication manager (CM).
This allows for a generic connection abstraction over RDMA.
@@ -75,7 +75,7 @@ config INFINIBAND_ADDR_TRANS_CONFIGFS
bool
depends on INFINIBAND_ADDR_TRANS && CONFIGFS_FS && !(INFINIBAND=y && CONFIGFS_FS=m)
default y
- ---help---
+ help
ConfigFS support for RDMA communication manager (CM).
This allows the user to config the default GID type that the CM
uses for each device, when initiaing new connections.
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
index 3b1e627d9a8d..ccd28405451c 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -429,7 +429,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt,
ALIGN(bcnt, PAGE_SIZE) / PAGE_SIZE,
PAGE_SIZE / sizeof(struct page *));
- down_read(&owning_mm->mmap_sem);
+ mmap_read_lock(owning_mm);
/*
* Note: this might result in redundent page getting. We can
* avoid this by checking dma_list to be 0 before calling
@@ -440,7 +440,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt,
npages = get_user_pages_remote(owning_process, owning_mm,
user_virt, gup_num_pages,
flags, local_page_list, NULL, NULL);
- up_read(&owning_mm->mmap_sem);
+ mmap_read_unlock(owning_mm);
if (npages < 0) {
if (npages != -EAGAIN)
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 47794c85e9af..69e4755cc04b 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -835,12 +835,12 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
return;
/*
- * The umap_lock is nested under mmap_sem since it used within
+ * The umap_lock is nested under mmap_lock since it used within
* the vma_ops callbacks, so we have to clean the list one mm
* at a time to get the lock ordering right. Typically there
* will only be one mm, so no big deal.
*/
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
if (!mmget_still_valid(mm))
goto skip_mm;
mutex_lock(&ufile->umap_lock);
@@ -862,7 +862,7 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
}
mutex_unlock(&ufile->umap_lock);
skip_mm:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
}
}
diff --git a/drivers/infiniband/hw/bnxt_re/Kconfig b/drivers/infiniband/hw/bnxt_re/Kconfig
index b83f1cc38c52..0feac5132ce1 100644
--- a/drivers/infiniband/hw/bnxt_re/Kconfig
+++ b/drivers/infiniband/hw/bnxt_re/Kconfig
@@ -5,7 +5,7 @@ config INFINIBAND_BNXT_RE
depends on ETHERNET && NETDEVICES && PCI && INET && DCB
select NET_VENDOR_BROADCOM
select BNXT
- ---help---
+ help
This driver supports Broadcom NetXtreme-E 10/25/40/50 gigabit
RoCE HCAs. To compile this driver as a module, choose M here:
the module will be called bnxt_re.
diff --git a/drivers/infiniband/hw/cxgb4/Kconfig b/drivers/infiniband/hw/cxgb4/Kconfig
index b49e8d4c3854..9e2b2c348afd 100644
--- a/drivers/infiniband/hw/cxgb4/Kconfig
+++ b/drivers/infiniband/hw/cxgb4/Kconfig
@@ -5,7 +5,7 @@ config INFINIBAND_CXGB4
depends on INFINIBAND_ADDR_TRANS
select CHELSIO_LIB
select GENERIC_ALLOCATOR
- ---help---
+ help
This is an iWARP/RDMA driver for the Chelsio T4 and T5
1GbE, 10GbE adapters and T5 40GbE adapter.
diff --git a/drivers/infiniband/hw/hfi1/Kconfig b/drivers/infiniband/hw/hfi1/Kconfig
index 0653f4f7b26c..519866b30a13 100644
--- a/drivers/infiniband/hw/hfi1/Kconfig
+++ b/drivers/infiniband/hw/hfi1/Kconfig
@@ -5,19 +5,19 @@ config INFINIBAND_HFI1
select MMU_NOTIFIER
select CRC32
select I2C_ALGOBIT
- ---help---
+ help
This is a low-level driver for Intel OPA Gen1 adapter.
config HFI1_DEBUG_SDMA_ORDER
bool "HFI1 SDMA Order debug"
depends on INFINIBAND_HFI1
default n
- ---help---
+ help
This is a debug flag to test for out of order
sdma completions for unit testing
config SDMA_VERBOSITY
bool "Config SDMA Verbosity"
depends on INFINIBAND_HFI1
default n
- ---help---
+ help
This is a configuration flag to enable verbose
SDMA debug
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c
index 14d2a90964c3..24ca17b77b72 100644
--- a/drivers/infiniband/hw/hfi1/mmu_rb.c
+++ b/drivers/infiniband/hw/hfi1/mmu_rb.c
@@ -333,7 +333,7 @@ static void do_remove(struct mmu_rb_handler *handler,
/*
* Work queue function to remove all nodes that have been queued up to
- * be removed. The key feature is that mm->mmap_sem is not being held
+ * be removed. The key feature is that mm->mmap_lock is not being held
* and the remove callback can sleep while taking it, if needed.
*/
static void handle_remove(struct work_struct *work)
diff --git a/drivers/infiniband/hw/hns/Kconfig b/drivers/infiniband/hw/hns/Kconfig
index 4921c1e40ccd..18d10ebf900b 100644
--- a/drivers/infiniband/hw/hns/Kconfig
+++ b/drivers/infiniband/hw/hns/Kconfig
@@ -4,7 +4,7 @@ config INFINIBAND_HNS
depends on NET_VENDOR_HISILICON
depends on ARM64 || (COMPILE_TEST && 64BIT)
depends on (HNS_DSAF && HNS_ENET) || HNS3
- ---help---
+ help
This is a RoCE/RDMA driver for the Hisilicon RoCE engine. The engine
is used in Hisilicon Hip06 and more further ICT SoC based on
platform device.
@@ -15,7 +15,7 @@ config INFINIBAND_HNS_HIP06
bool "Hisilicon Hip06 Family RoCE support"
depends on INFINIBAND_HNS && HNS && HNS_DSAF && HNS_ENET
depends on INFINIBAND_HNS=m || (HNS_DSAF=y && HNS_ENET=y)
- ---help---
+ help
RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip06 and
Hip07 SoC. These RoCE engines are platform devices.
@@ -26,7 +26,7 @@ config INFINIBAND_HNS_HIP08
bool "Hisilicon Hip08 Family RoCE support"
depends on INFINIBAND_HNS && PCI && HNS3
depends on INFINIBAND_HNS=m || HNS3=y
- ---help---
+ help
RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip08 SoC.
The RoCE engine is a PCI device.
diff --git a/drivers/infiniband/hw/i40iw/Kconfig b/drivers/infiniband/hw/i40iw/Kconfig
index e4b45f4cd8f8..7476f3b14c39 100644
--- a/drivers/infiniband/hw/i40iw/Kconfig
+++ b/drivers/infiniband/hw/i40iw/Kconfig
@@ -5,5 +5,5 @@ config INFINIBAND_I40IW
depends on IPV6 || !IPV6
depends on PCI
select GENERIC_ALLOCATOR
- ---help---
+ help
Intel(R) Ethernet X722 iWARP Driver
diff --git a/drivers/infiniband/hw/mlx4/Kconfig b/drivers/infiniband/hw/mlx4/Kconfig
index cc7c42fe6499..f30ce9dd080a 100644
--- a/drivers/infiniband/hw/mlx4/Kconfig
+++ b/drivers/infiniband/hw/mlx4/Kconfig
@@ -4,7 +4,7 @@ config MLX4_INFINIBAND
depends on NETDEVICES && ETHERNET && PCI && INET
select NET_VENDOR_MELLANOX
select MLX4_CORE
- ---help---
+ help
This driver provides low-level InfiniBand support for
Mellanox ConnectX PCI Express host channel adapters (HCAs).
This is required to use InfiniBand protocols such as
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index e2fb71b23c80..7e0b205c05eb 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -380,7 +380,7 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start,
unsigned long untagged_start = untagged_addr(start);
struct vm_area_struct *vma;
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
/*
* FIXME: Ideally this would iterate over all the vmas that
* cover the memory, but for now it requires a single vma to
@@ -395,7 +395,7 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start,
access_flags |= IB_ACCESS_LOCAL_WRITE;
}
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
}
return ib_umem_get(device, start, length, access_flags);
diff --git a/drivers/infiniband/hw/mlx5/Kconfig b/drivers/infiniband/hw/mlx5/Kconfig
index ea248def4556..ef1ff42eaec5 100644
--- a/drivers/infiniband/hw/mlx5/Kconfig
+++ b/drivers/infiniband/hw/mlx5/Kconfig
@@ -2,7 +2,7 @@
config MLX5_INFINIBAND
tristate "Mellanox 5th generation network adapters (ConnectX series) support"
depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE
- ---help---
+ help
This driver provides low-level InfiniBand support for
Mellanox Connect-IB PCI Express host channel adapters (HCAs).
This is required to use InfiniBand protocols such as
diff --git a/drivers/infiniband/hw/mthca/Kconfig b/drivers/infiniband/hw/mthca/Kconfig
index 66ff527f5928..faa7381f7d63 100644
--- a/drivers/infiniband/hw/mthca/Kconfig
+++ b/drivers/infiniband/hw/mthca/Kconfig
@@ -2,7 +2,7 @@
config INFINIBAND_MTHCA
tristate "Mellanox HCA support"
depends on PCI
- ---help---
+ help
This is a low-level driver for Mellanox InfiniHost host
channel adapters (HCAs), including the MT23108 PCI-X HCA
("Tavor") and the MT25208 PCI Express HCA ("Arbel").
@@ -11,7 +11,7 @@ config INFINIBAND_MTHCA_DEBUG
bool "Verbose debugging output" if EXPERT
depends on INFINIBAND_MTHCA
default y
- ---help---
+ help
This option causes debugging code to be compiled into the
mthca driver. The output can be turned on via the
debug_level module parameter (which can also be set after
diff --git a/drivers/infiniband/hw/ocrdma/Kconfig b/drivers/infiniband/hw/ocrdma/Kconfig
index dd4ec388208c..54bd70bc4d1a 100644
--- a/drivers/infiniband/hw/ocrdma/Kconfig
+++ b/drivers/infiniband/hw/ocrdma/Kconfig
@@ -4,6 +4,6 @@ config INFINIBAND_OCRDMA
depends on ETHERNET && NETDEVICES && PCI && INET && (IPV6 || IPV6=n)
select NET_VENDOR_EMULEX
select BE2NET
- ---help---
+ help
This driver provides low-level InfiniBand over Ethernet
support for Emulex One Connect host channel adapters (HCAs).
diff --git a/drivers/infiniband/hw/qedr/Kconfig b/drivers/infiniband/hw/qedr/Kconfig
index 9c30325e1414..9e31d13b03c3 100644
--- a/drivers/infiniband/hw/qedr/Kconfig
+++ b/drivers/infiniband/hw/qedr/Kconfig
@@ -6,6 +6,6 @@ config INFINIBAND_QEDR
select QED_LL2
select QED_OOO
select QED_RDMA
- ---help---
+ help
This driver provides low-level InfiniBand over Ethernet
support for QLogic QED host channel adapters (HCAs).
diff --git a/drivers/infiniband/hw/qib/Kconfig b/drivers/infiniband/hw/qib/Kconfig
index 376d19f29346..6c4895777042 100644
--- a/drivers/infiniband/hw/qib/Kconfig
+++ b/drivers/infiniband/hw/qib/Kconfig
@@ -3,7 +3,7 @@ config INFINIBAND_QIB
tristate "Intel PCIe HCA support"
depends on 64BIT && INFINIBAND_RDMAVT
depends on PCI
- ---help---
+ help
This is a low-level driver for Intel PCIe QLE InfiniBand host
channel adapters. This driver does not support the Intel
HyperTransport card (model QHT7140).
@@ -12,6 +12,6 @@ config INFINIBAND_QIB_DCA
bool "QIB DCA support"
depends on INFINIBAND_QIB && DCA && SMP && !(INFINIBAND_QIB=y && DCA=m)
default y
- ---help---
+ help
Setting this enables DCA support on some Intel chip sets
with the iba7322 HCA.
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c
index b0144229cf3b..ff87a67dd7b7 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -40,10 +40,10 @@
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/jiffies.h>
-#include <asm/pgtable.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/uio.h>
+#include <linux/pgtable.h>
#include <rdma/ib.h>
diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c
index 342e3172ca40..4c24e83f3175 100644
--- a/drivers/infiniband/hw/qib/qib_user_pages.c
+++ b/drivers/infiniband/hw/qib/qib_user_pages.c
@@ -106,18 +106,18 @@ int qib_get_user_pages(unsigned long start_page, size_t num_pages,
goto bail;
}
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
for (got = 0; got < num_pages; got += ret) {
ret = pin_user_pages(start_page + got * PAGE_SIZE,
num_pages - got,
FOLL_LONGTERM | FOLL_WRITE | FOLL_FORCE,
p + got, NULL);
if (ret < 0) {
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
goto bail_release;
}
}
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
return 0;
bail_release:
diff --git a/drivers/infiniband/hw/usnic/Kconfig b/drivers/infiniband/hw/usnic/Kconfig
index c0847d9e2539..9019599c173b 100644
--- a/drivers/infiniband/hw/usnic/Kconfig
+++ b/drivers/infiniband/hw/usnic/Kconfig
@@ -6,6 +6,6 @@ config INFINIBAND_USNIC
select ENIC
select NET_VENDOR_CISCO
select PCI_IOV
- ---help---
+ help
This is a low-level driver for Cisco's Virtual Interface
Cards (VICs), including the VIC 1240 and 1280 cards.
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
index bd9f944b68fc..760b254ba42d 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -123,7 +123,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
npages = PAGE_ALIGN(size + (addr & ~PAGE_MASK)) >> PAGE_SHIFT;
uiomr->owning_mm = mm = current->mm;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
locked = atomic64_add_return(npages, &current->mm->pinned_vm);
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
@@ -187,7 +187,7 @@ out:
} else
mmgrab(uiomr->owning_mm);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
free_page((unsigned long) page_list);
return ret;
}
diff --git a/drivers/infiniband/hw/vmw_pvrdma/Kconfig b/drivers/infiniband/hw/vmw_pvrdma/Kconfig
index b99c9f0fc06a..a11e892e5e77 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/Kconfig
+++ b/drivers/infiniband/hw/vmw_pvrdma/Kconfig
@@ -2,7 +2,7 @@
config INFINIBAND_VMWARE_PVRDMA
tristate "VMware Paravirtualized RDMA Driver"
depends on NETDEVICES && ETHERNET && PCI && INET && VMXNET3
- ---help---
+ help
This driver provides low-level support for VMware Paravirtual
RDMA adapter. It interacts with the VMXNet3 driver to provide
Ethernet capabilities.
diff --git a/drivers/infiniband/sw/rdmavt/Kconfig b/drivers/infiniband/sw/rdmavt/Kconfig
index 1f2759c72108..9ef5f5ce1ff6 100644
--- a/drivers/infiniband/sw/rdmavt/Kconfig
+++ b/drivers/infiniband/sw/rdmavt/Kconfig
@@ -4,5 +4,5 @@ config INFINIBAND_RDMAVT
depends on X86_64 && ARCH_DMA_ADDR_T_64BIT
depends on PCI
select DMA_VIRT_OPS
- ---help---
+ help
This is a common software verbs provider for RDMA networks.
diff --git a/drivers/infiniband/sw/rdmavt/mmap.c b/drivers/infiniband/sw/rdmavt/mmap.c
index 37853aa3bcf7..f5d0e33cf3d7 100644
--- a/drivers/infiniband/sw/rdmavt/mmap.c
+++ b/drivers/infiniband/sw/rdmavt/mmap.c
@@ -48,7 +48,6 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
-#include <asm/pgtable.h>
#include <rdma/uverbs_ioctl.h>
#include "mmap.h"
diff --git a/drivers/infiniband/sw/rxe/Kconfig b/drivers/infiniband/sw/rxe/Kconfig
index d9bcfe740588..a0c6c7dfc181 100644
--- a/drivers/infiniband/sw/rxe/Kconfig
+++ b/drivers/infiniband/sw/rxe/Kconfig
@@ -6,7 +6,7 @@ config RDMA_RXE
select NET_UDP_TUNNEL
select CRYPTO_CRC32
select DMA_VIRT_OPS
- ---help---
+ help
This driver implements the InfiniBand RDMA transport over
the Linux network stack. It enables a system with a
standard Ethernet adapter to interoperate with a RoCE
diff --git a/drivers/infiniband/sw/rxe/rxe_mmap.c b/drivers/infiniband/sw/rxe/rxe_mmap.c
index 6a413d73b95d..7887f623f62c 100644
--- a/drivers/infiniband/sw/rxe/rxe_mmap.c
+++ b/drivers/infiniband/sw/rxe/rxe_mmap.c
@@ -35,7 +35,6 @@
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/errno.h>
-#include <asm/pgtable.h>
#include <rdma/uverbs_ioctl.h>
#include "rxe.h"
diff --git a/drivers/infiniband/sw/siw/siw_mem.c b/drivers/infiniband/sw/siw/siw_mem.c
index 87117781d637..34a910cf0edb 100644
--- a/drivers/infiniband/sw/siw/siw_mem.c
+++ b/drivers/infiniband/sw/siw/siw_mem.c
@@ -394,7 +394,7 @@ struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable)
if (!writable)
foll_flags |= FOLL_FORCE;
- down_read(&mm_s->mmap_sem);
+ mmap_read_lock(mm_s);
mlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
@@ -438,7 +438,7 @@ struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable)
num_pages -= got;
}
out_sem_up:
- up_read(&mm_s->mmap_sem);
+ mmap_read_unlock(mm_s);
if (rv > 0)
return umem;
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig
index 7af68604af77..254e31a90a66 100644
--- a/drivers/infiniband/ulp/ipoib/Kconfig
+++ b/drivers/infiniband/ulp/ipoib/Kconfig
@@ -2,7 +2,7 @@
config INFINIBAND_IPOIB
tristate "IP-over-InfiniBand"
depends on NETDEVICES && INET && (IPV6 || IPV6=n)
- ---help---
+ help
Support for the IP-over-InfiniBand protocol (IPoIB). This
transports IP packets over InfiniBand so you can use your IB
device as a fancy NIC.
@@ -13,7 +13,7 @@ config INFINIBAND_IPOIB_CM
bool "IP-over-InfiniBand Connected Mode support"
depends on INFINIBAND_IPOIB
default n
- ---help---
+ help
This option enables support for IPoIB connected mode. After
enabling this option, you need to switch to connected mode
through /sys/class/net/ibXXX/mode to actually create
@@ -28,7 +28,7 @@ config INFINIBAND_IPOIB_DEBUG
bool "IP-over-InfiniBand debugging" if EXPERT
depends on INFINIBAND_IPOIB
default y
- ---help---
+ help
This option causes debugging code to be compiled into the
IPoIB driver. The output can be turned on via the
debug_level and mcast_debug_level module parameters (which
@@ -42,7 +42,7 @@ config INFINIBAND_IPOIB_DEBUG
config INFINIBAND_IPOIB_DEBUG_DATA
bool "IP-over-InfiniBand data path debugging"
depends on INFINIBAND_IPOIB_DEBUG
- ---help---
+ help
This option compiles debugging code into the data path
of the IPoIB driver. The output can be turned on via the
data_debug_level module parameter; however, even with output
diff --git a/drivers/infiniband/ulp/iser/Kconfig b/drivers/infiniband/ulp/iser/Kconfig
index 1d29dffeaff9..3016a0c9a9f0 100644
--- a/drivers/infiniband/ulp/iser/Kconfig
+++ b/drivers/infiniband/ulp/iser/Kconfig
@@ -3,7 +3,7 @@ config INFINIBAND_ISER
tristate "iSCSI Extensions for RDMA (iSER)"
depends on SCSI && INET && INFINIBAND_ADDR_TRANS
select SCSI_ISCSI_ATTRS
- ---help---
+ help
Support for the iSCSI Extensions for RDMA (iSER) Protocol
over InfiniBand. This allows you to access storage devices
that speak iSCSI over iSER over InfiniBand.
diff --git a/drivers/infiniband/ulp/isert/Kconfig b/drivers/infiniband/ulp/isert/Kconfig
index 1a3f5ca8354c..798147adbef1 100644
--- a/drivers/infiniband/ulp/isert/Kconfig
+++ b/drivers/infiniband/ulp/isert/Kconfig
@@ -2,5 +2,5 @@
config INFINIBAND_ISERT
tristate "iSCSI Extensions for RDMA (iSER) target support"
depends on INET && INFINIBAND_ADDR_TRANS && TARGET_CORE && ISCSI_TARGET
- ---help---
+ help
Support for iSCSI Extensions for RDMA (iSER) Target on Infiniband fabrics.
diff --git a/drivers/infiniband/ulp/opa_vnic/Kconfig b/drivers/infiniband/ulp/opa_vnic/Kconfig
index a1f266b9c0b2..e84248587187 100644
--- a/drivers/infiniband/ulp/opa_vnic/Kconfig
+++ b/drivers/infiniband/ulp/opa_vnic/Kconfig
@@ -2,7 +2,7 @@
config INFINIBAND_OPA_VNIC
tristate "Intel OPA VNIC support"
depends on X86_64 && INFINIBAND
- ---help---
+ help
This is Omni-Path (OPA) Virtual Network Interface Controller (VNIC)
driver for Ethernet over Omni-Path feature. It implements the HW
independent VNIC functionality. It interfaces with Linux stack for
diff --git a/drivers/infiniband/ulp/srp/Kconfig b/drivers/infiniband/ulp/srp/Kconfig
index 6f5e7b3a3864..67cd63d1399c 100644
--- a/drivers/infiniband/ulp/srp/Kconfig
+++ b/drivers/infiniband/ulp/srp/Kconfig
@@ -3,7 +3,7 @@ config INFINIBAND_SRP
tristate "InfiniBand SCSI RDMA Protocol"
depends on SCSI && INFINIBAND_ADDR_TRANS
select SCSI_SRP_ATTRS
- ---help---
+ help
Support for the SCSI RDMA Protocol over InfiniBand. This
allows you to access storage devices that speak SRP over
InfiniBand.
diff --git a/drivers/infiniband/ulp/srpt/Kconfig b/drivers/infiniband/ulp/srpt/Kconfig
index ce7567cea9f6..4b5d9b792cfa 100644
--- a/drivers/infiniband/ulp/srpt/Kconfig
+++ b/drivers/infiniband/ulp/srpt/Kconfig
@@ -2,7 +2,7 @@
config INFINIBAND_SRPT
tristate "InfiniBand SCSI RDMA Protocol target support"
depends on INFINIBAND && INFINIBAND_ADDR_TRANS && TARGET_CORE
- ---help---
+ help
Support for the SCSI RDMA Protocol (SRP) Target driver. The
SRP protocol is a protocol that allows an initiator to access
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 0d57e51b8ba1..e494295d1c7b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -282,7 +282,8 @@ static void evdev_pass_values(struct evdev_client *client,
spin_unlock(&client->buffer_lock);
if (wakeup)
- wake_up_interruptible(&evdev->wait);
+ wake_up_interruptible_poll(&evdev->wait,
+ EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM);
}
/*
@@ -429,7 +430,7 @@ static void evdev_hangup(struct evdev *evdev)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
spin_unlock(&evdev->client_lock);
- wake_up_interruptible(&evdev->wait);
+ wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR);
}
static int evdev_release(struct inode *inode, struct file *file)
@@ -945,7 +946,7 @@ static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,
client->revoked = true;
evdev_ungrab(evdev, client);
input_flush_device(&evdev->handle, file);
- wake_up_interruptible(&evdev->wait);
+ wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR);
return 0;
}
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
index 24acb3b07fed..4761795cb49f 100644
--- a/drivers/input/gameport/Kconfig
+++ b/drivers/input/gameport/Kconfig
@@ -4,7 +4,7 @@
#
config GAMEPORT
tristate "Gameport support"
- ---help---
+ help
Gameport support is for the standard 15-pin PC gameport. If you
have a joystick, gamepad, gameport card, a soundcard with a gameport
or anything else that uses the gameport, say Y or M here and also to
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 940b744639c7..eb031b7a4866 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -18,7 +18,7 @@ if INPUT_JOYSTICK
config JOYSTICK_ANALOG
tristate "Classic PC analog joysticks and gamepads"
select GAMEPORT
- ---help---
+ help
Say Y here if you have a joystick that connects to the PC
gameport. In addition to the usual PC analog joystick, this driver
supports many extensions, including joysticks with throttle control,
@@ -45,6 +45,7 @@ config JOYSTICK_A3D
config JOYSTICK_ADI
tristate "Logitech ADI digital joysticks and gamepads"
select GAMEPORT
+ depends on ADI!=m # avoid module name conflict
help
Say Y here if you have a Logitech controller using the ADI
protocol over the PC gameport.
@@ -224,7 +225,7 @@ config JOYSTICK_GAMECON
tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads"
depends on PARPORT
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you have a Nintendo Entertainment System gamepad,
Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad,
Sony PlayStation gamepad or a Multisystem -- Atari, Amiga,
@@ -297,13 +298,13 @@ config JOYSTICK_XPAD_FF
bool "X-Box gamepad rumble support"
depends on JOYSTICK_XPAD && INPUT
select INPUT_FF_MEMLESS
- ---help---
+ help
Say Y here if you want to take advantage of xbox 360 rumble features.
config JOYSTICK_XPAD_LEDS
bool "LED Support for Xbox360 controller 'BigX' LED"
depends on JOYSTICK_XPAD && (LEDS_CLASS=y || LEDS_CLASS=JOYSTICK_XPAD)
- ---help---
+ help
This option enables support for the LED which surrounds the Big X on
XBox 360 controller.
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 28de965a08d5..793ecbbda32c 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -701,7 +701,7 @@ config KEYBOARD_SPEAR
Say Y here if you want to use the SPEAR keyboard.
To compile this driver as a module, choose M here: the
- module will be called spear-keboard.
+ module will be called spear-keyboard.
config KEYBOARD_TC3589X
tristate "TC3589X Keypad support"
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 7e3eae54c192..6ec28265771d 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -24,6 +24,7 @@
#include <linux/libps2.h>
#include <linux/mutex.h>
#include <linux/dmi.h>
+#include <linux/property.h>
#define DRIVER_DESC "AT and PS/2 keyboard driver"
@@ -63,6 +64,11 @@ static bool atkbd_terminal;
module_param_named(terminal, atkbd_terminal, bool, 0);
MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
+#define MAX_FUNCTION_ROW_KEYS 24
+
+#define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF)
+#define KEYCODE(keymap) (keymap & 0xFFFF)
+
/*
* Scancode to keycode tables. These are just the default setting, and
* are loadable via a userland utility.
@@ -230,6 +236,9 @@ struct atkbd {
/* Serializes reconnect(), attr->set() and event work */
struct mutex mutex;
+
+ u32 function_row_physmap[MAX_FUNCTION_ROW_KEYS];
+ int num_function_row_keys;
};
/*
@@ -283,6 +292,7 @@ static struct device_attribute atkbd_attr_##_name = \
__ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
ATKBD_DEFINE_RO_ATTR(err_count);
+ATKBD_DEFINE_RO_ATTR(function_row_physmap);
static struct attribute *atkbd_attributes[] = {
&atkbd_attr_extra.attr,
@@ -292,11 +302,42 @@ static struct attribute *atkbd_attributes[] = {
&atkbd_attr_softrepeat.attr,
&atkbd_attr_softraw.attr,
&atkbd_attr_err_count.attr,
+ &atkbd_attr_function_row_physmap.attr,
NULL
};
+static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf)
+{
+ ssize_t size = 0;
+ int i;
+
+ if (!atkbd->num_function_row_keys)
+ return 0;
+
+ for (i = 0; i < atkbd->num_function_row_keys; i++)
+ size += scnprintf(buf + size, PAGE_SIZE - size, "%02X ",
+ atkbd->function_row_physmap[i]);
+ size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
+ return size;
+}
+
+static umode_t atkbd_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int i)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct serio *serio = to_serio_port(dev);
+ struct atkbd *atkbd = serio_get_drvdata(serio);
+
+ if (attr == &atkbd_attr_function_row_physmap.attr &&
+ !atkbd->num_function_row_keys)
+ return 0;
+
+ return attr->mode;
+}
+
static struct attribute_group atkbd_attribute_group = {
.attrs = atkbd_attributes,
+ .is_visible = atkbd_attr_is_visible,
};
static const unsigned int xl_table[] = {
@@ -994,6 +1035,39 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
return code;
}
+static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
+{
+ struct device *dev = &atkbd->ps2dev.serio->dev;
+ int i, n;
+ u32 *ptr;
+ u16 scancode, keycode;
+
+ /* Parse "linux,keymap" property */
+ n = device_property_count_u32(dev, "linux,keymap");
+ if (n <= 0 || n > ATKBD_KEYMAP_SIZE)
+ return -ENXIO;
+
+ ptr = kcalloc(n, sizeof(u32), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ if (device_property_read_u32_array(dev, "linux,keymap", ptr, n)) {
+ dev_err(dev, "problem parsing FW keymap property\n");
+ kfree(ptr);
+ return -EINVAL;
+ }
+
+ memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
+ for (i = 0; i < n; i++) {
+ scancode = SCANCODE(ptr[i]);
+ keycode = KEYCODE(ptr[i]);
+ atkbd->keycode[scancode] = keycode;
+ }
+
+ kfree(ptr);
+ return 0;
+}
+
/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
@@ -1001,13 +1075,16 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
static void atkbd_set_keycode_table(struct atkbd *atkbd)
{
+ struct device *dev = &atkbd->ps2dev.serio->dev;
unsigned int scancode;
int i, j;
memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
- if (atkbd->translated) {
+ if (!atkbd_get_keymap_from_fwnode(atkbd)) {
+ dev_dbg(dev, "Using FW keymap\n");
+ } else if (atkbd->translated) {
for (i = 0; i < 128; i++) {
scancode = atkbd_unxlate_table[i];
atkbd->keycode[i] = atkbd_set2_keycode[scancode];
@@ -1121,6 +1198,22 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
}
}
+static void atkbd_parse_fwnode_data(struct serio *serio)
+{
+ struct atkbd *atkbd = serio_get_drvdata(serio);
+ struct device *dev = &serio->dev;
+ int n;
+
+ /* Parse "function-row-physmap" property */
+ n = device_property_count_u32(dev, "function-row-physmap");
+ if (n > 0 && n <= MAX_FUNCTION_ROW_KEYS &&
+ !device_property_read_u32_array(dev, "function-row-physmap",
+ atkbd->function_row_physmap, n)) {
+ atkbd->num_function_row_keys = n;
+ dev_dbg(dev, "FW reported %d function-row key locations\n", n);
+ }
+}
+
/*
* atkbd_connect() is called when the serio module finds an interface
* that isn't handled yet by an appropriate device driver. We check if
@@ -1184,6 +1277,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
atkbd->id = 0xab00;
}
+ atkbd_parse_fwnode_data(serio);
+
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c
index 9f809aeb785c..d18839f1f4f6 100644
--- a/drivers/input/keyboard/imx_sc_key.c
+++ b/drivers/input/keyboard/imx_sc_key.c
@@ -99,6 +99,15 @@ static void imx_sc_check_for_events(struct work_struct *work)
msecs_to_jiffies(REPEAT_INTERVAL));
}
+static void imx_sc_key_action(void *data)
+{
+ struct imx_key_drv_data *priv = data;
+
+ imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
+ imx_scu_irq_unregister_notifier(&priv->key_notifier);
+ cancel_delayed_work_sync(&priv->check_work);
+}
+
static int imx_sc_key_probe(struct platform_device *pdev)
{
struct imx_key_drv_data *priv;
@@ -149,27 +158,16 @@ static int imx_sc_key_probe(struct platform_device *pdev)
return error;
}
+ error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, &priv);
+ if (error)
+ return error;
+
priv->key_notifier.notifier_call = imx_sc_key_notify;
error = imx_scu_irq_register_notifier(&priv->key_notifier);
- if (error) {
- imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON,
- false);
+ if (error)
dev_err(&pdev->dev, "failed to register scu notifier\n");
- return error;
- }
-
- return 0;
-}
-
-static int imx_sc_key_remove(struct platform_device *pdev)
-{
- struct imx_key_drv_data *priv = platform_get_drvdata(pdev);
-
- imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
- imx_scu_irq_unregister_notifier(&priv->key_notifier);
- cancel_delayed_work_sync(&priv->check_work);
- return 0;
+ return error;
}
static const struct of_device_id imx_sc_key_ids[] = {
@@ -184,7 +182,6 @@ static struct platform_driver imx_sc_key_driver = {
.of_match_table = imx_sc_key_ids,
},
.probe = imx_sc_key_probe,
- .remove = imx_sc_key_remove,
};
module_platform_driver(imx_sc_key_driver);
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 21758767ccf0..9b0f9665dcb0 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -374,5 +374,5 @@ static void __exit tca6416_keypad_exit(void)
module_exit(tca6416_keypad_exit);
MODULE_AUTHOR("Sriramakrishnan <srk@ti.com>");
-MODULE_DESCRIPTION("Keypad driver over tca6146 IO expander");
+MODULE_DESCRIPTION("Keypad driver over tca6416 IO expander");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7e2e658d551c..362e8a01980c 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -117,16 +117,6 @@ config INPUT_E3X0_BUTTON
To compile this driver as a module, choose M here: the
module will be called e3x0_button.
-config INPUT_MSM_VIBRATOR
- tristate "Qualcomm MSM vibrator driver"
- select INPUT_FF_MEMLESS
- help
- Support for the vibrator that is found on various Qualcomm MSM
- SOCs.
-
- To compile this driver as a module, choose M here: the module
- will be called msm_vibrator.
-
config INPUT_PCSPKR
tristate "PC Speaker support"
depends on PCSPKR_PLATFORM
@@ -265,17 +255,6 @@ config INPUT_APANEL
To compile this driver as a module, choose M here: the module will
be called apanel.
-config INPUT_GP2A
- tristate "Sharp GP2AP002A00F I2C Proximity/Opto sensor driver"
- depends on I2C
- depends on GPIOLIB || COMPILE_TEST
- help
- Say Y here if you have a Sharp GP2AP002A00F proximity/als combo-chip
- hooked to an I2C bus.
-
- To compile this driver as a module, choose M here: the
- module will be called gp2ap002a00f.
-
config INPUT_GPIO_BEEPER
tristate "Generic GPIO Beeper support"
depends on GPIOLIB || COMPILE_TEST
@@ -739,6 +718,17 @@ config INPUT_IMS_PCU
To compile this driver as a module, choose M here: the module will be
called ims_pcu.
+config INPUT_IQS269A
+ tristate "Azoteq IQS269A capacitive touch controller"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say Y to enable support for the Azoteq IQS269A capacitive
+ touch controller.
+
+ To compile this driver as a module, choose M here: the
+ module will be called iqs269a.
+
config INPUT_CMA3000
tristate "VTI CMA3000 Tri-axis accelerometer"
help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 8fd187f314bd..a48e5f2d859d 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -33,13 +33,13 @@ obj-$(CONFIG_INPUT_E3X0_BUTTON) += e3x0-button.o
obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o
obj-$(CONFIG_INPUT_DRV2665_HAPTICS) += drv2665.o
obj-$(CONFIG_INPUT_DRV2667_HAPTICS) += drv2667.o
-obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o
obj-$(CONFIG_INPUT_GPIO_BEEPER) += gpio-beeper.o
obj-$(CONFIG_INPUT_GPIO_DECODER) += gpio_decoder.o
obj-$(CONFIG_INPUT_GPIO_VIBRA) += gpio-vibra.o
obj-$(CONFIG_INPUT_HISI_POWERKEY) += hisi_powerkey.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o
+obj-$(CONFIG_INPUT_IQS269A) += iqs269a.o
obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
@@ -50,7 +50,6 @@ obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
obj-$(CONFIG_INPUT_MMA8450) += mma8450.o
-obj-$(CONFIG_INPUT_MSM_VIBRATOR) += msm-vibrator.o
obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON) += palmas-pwrbutton.o
obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c
deleted file mode 100644
index 90abda8eea67..000000000000
--- a/drivers/input/misc/gp2ap002a00f.c
+++ /dev/null
@@ -1,281 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2011 Sony Ericsson Mobile Communications Inc.
- *
- * Author: Courtney Cavin <courtney.cavin@sonyericsson.com>
- * Prepared for up-stream by: Oskar Andero <oskar.andero@sonyericsson.com>
- */
-
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/input/gp2ap002a00f.h>
-
-struct gp2a_data {
- struct input_dev *input;
- const struct gp2a_platform_data *pdata;
- struct i2c_client *i2c_client;
-};
-
-enum gp2a_addr {
- GP2A_ADDR_PROX = 0x0,
- GP2A_ADDR_GAIN = 0x1,
- GP2A_ADDR_HYS = 0x2,
- GP2A_ADDR_CYCLE = 0x3,
- GP2A_ADDR_OPMOD = 0x4,
- GP2A_ADDR_CON = 0x6
-};
-
-enum gp2a_controls {
- /* Software Shutdown control: 0 = shutdown, 1 = normal operation */
- GP2A_CTRL_SSD = 0x01
-};
-
-static int gp2a_report(struct gp2a_data *dt)
-{
- int vo = gpio_get_value(dt->pdata->vout_gpio);
-
- input_report_switch(dt->input, SW_FRONT_PROXIMITY, !vo);
- input_sync(dt->input);
-
- return 0;
-}
-
-static irqreturn_t gp2a_irq(int irq, void *handle)
-{
- struct gp2a_data *dt = handle;
-
- gp2a_report(dt);
-
- return IRQ_HANDLED;
-}
-
-static int gp2a_enable(struct gp2a_data *dt)
-{
- return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
- GP2A_CTRL_SSD);
-}
-
-static int gp2a_disable(struct gp2a_data *dt)
-{
- return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
- 0x00);
-}
-
-static int gp2a_device_open(struct input_dev *dev)
-{
- struct gp2a_data *dt = input_get_drvdata(dev);
- int error;
-
- error = gp2a_enable(dt);
- if (error < 0) {
- dev_err(&dt->i2c_client->dev,
- "unable to activate, err %d\n", error);
- return error;
- }
-
- gp2a_report(dt);
-
- return 0;
-}
-
-static void gp2a_device_close(struct input_dev *dev)
-{
- struct gp2a_data *dt = input_get_drvdata(dev);
- int error;
-
- error = gp2a_disable(dt);
- if (error < 0)
- dev_err(&dt->i2c_client->dev,
- "unable to deactivate, err %d\n", error);
-}
-
-static int gp2a_initialize(struct gp2a_data *dt)
-{
- int error;
-
- error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_GAIN,
- 0x08);
- if (error < 0)
- return error;
-
- error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_HYS,
- 0xc2);
- if (error < 0)
- return error;
-
- error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_CYCLE,
- 0x04);
- if (error < 0)
- return error;
-
- error = gp2a_disable(dt);
-
- return error;
-}
-
-static int gp2a_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- const struct gp2a_platform_data *pdata = dev_get_platdata(&client->dev);
- struct gp2a_data *dt;
- int error;
-
- if (!pdata)
- return -EINVAL;
-
- if (pdata->hw_setup) {
- error = pdata->hw_setup(client);
- if (error < 0)
- return error;
- }
-
- error = gpio_request_one(pdata->vout_gpio, GPIOF_IN, GP2A_I2C_NAME);
- if (error)
- goto err_hw_shutdown;
-
- dt = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
- if (!dt) {
- error = -ENOMEM;
- goto err_free_gpio;
- }
-
- dt->pdata = pdata;
- dt->i2c_client = client;
-
- error = gp2a_initialize(dt);
- if (error < 0)
- goto err_free_mem;
-
- dt->input = input_allocate_device();
- if (!dt->input) {
- error = -ENOMEM;
- goto err_free_mem;
- }
-
- input_set_drvdata(dt->input, dt);
-
- dt->input->open = gp2a_device_open;
- dt->input->close = gp2a_device_close;
- dt->input->name = GP2A_I2C_NAME;
- dt->input->id.bustype = BUS_I2C;
- dt->input->dev.parent = &client->dev;
-
- input_set_capability(dt->input, EV_SW, SW_FRONT_PROXIMITY);
-
- error = request_threaded_irq(client->irq, NULL, gp2a_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
- GP2A_I2C_NAME, dt);
- if (error) {
- dev_err(&client->dev, "irq request failed\n");
- goto err_free_input_dev;
- }
-
- error = input_register_device(dt->input);
- if (error) {
- dev_err(&client->dev, "device registration failed\n");
- goto err_free_irq;
- }
-
- device_init_wakeup(&client->dev, pdata->wakeup);
- i2c_set_clientdata(client, dt);
-
- return 0;
-
-err_free_irq:
- free_irq(client->irq, dt);
-err_free_input_dev:
- input_free_device(dt->input);
-err_free_mem:
- kfree(dt);
-err_free_gpio:
- gpio_free(pdata->vout_gpio);
-err_hw_shutdown:
- if (pdata->hw_shutdown)
- pdata->hw_shutdown(client);
- return error;
-}
-
-static int gp2a_remove(struct i2c_client *client)
-{
- struct gp2a_data *dt = i2c_get_clientdata(client);
- const struct gp2a_platform_data *pdata = dt->pdata;
-
- free_irq(client->irq, dt);
-
- input_unregister_device(dt->input);
- kfree(dt);
-
- gpio_free(pdata->vout_gpio);
-
- if (pdata->hw_shutdown)
- pdata->hw_shutdown(client);
-
- return 0;
-}
-
-static int __maybe_unused gp2a_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct gp2a_data *dt = i2c_get_clientdata(client);
- int retval = 0;
-
- if (device_may_wakeup(&client->dev)) {
- enable_irq_wake(client->irq);
- } else {
- mutex_lock(&dt->input->mutex);
- if (dt->input->users)
- retval = gp2a_disable(dt);
- mutex_unlock(&dt->input->mutex);
- }
-
- return retval;
-}
-
-static int __maybe_unused gp2a_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct gp2a_data *dt = i2c_get_clientdata(client);
- int retval = 0;
-
- if (device_may_wakeup(&client->dev)) {
- disable_irq_wake(client->irq);
- } else {
- mutex_lock(&dt->input->mutex);
- if (dt->input->users)
- retval = gp2a_enable(dt);
- mutex_unlock(&dt->input->mutex);
- }
-
- return retval;
-}
-
-static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume);
-
-static const struct i2c_device_id gp2a_i2c_id[] = {
- { GP2A_I2C_NAME, 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, gp2a_i2c_id);
-
-static struct i2c_driver gp2a_i2c_driver = {
- .driver = {
- .name = GP2A_I2C_NAME,
- .pm = &gp2a_pm,
- },
- .probe = gp2a_probe,
- .remove = gp2a_remove,
- .id_table = gp2a_i2c_id,
-};
-
-module_i2c_driver(gp2a_i2c_driver);
-
-MODULE_AUTHOR("Courtney Cavin <courtney.cavin@sonyericsson.com>");
-MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
new file mode 100644
index 000000000000..6699eb160a0f
--- /dev/null
+++ b/drivers/input/misc/iqs269a.c
@@ -0,0 +1,1833 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS269A Capacitive Touch Controller
+ *
+ * Copyright (C) 2020 Jeff LaBundy <jeff@labundy.com>
+ *
+ * This driver registers up to 3 input devices: one representing capacitive or
+ * inductive keys as well as Hall-effect switches, and one for each of the two
+ * axial sliders presented by the device.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define IQS269_VER_INFO 0x00
+#define IQS269_VER_INFO_PROD_NUM 0x4F
+
+#define IQS269_SYS_FLAGS 0x02
+#define IQS269_SYS_FLAGS_SHOW_RESET BIT(15)
+#define IQS269_SYS_FLAGS_PWR_MODE_MASK GENMASK(12, 11)
+#define IQS269_SYS_FLAGS_PWR_MODE_SHIFT 11
+#define IQS269_SYS_FLAGS_IN_ATI BIT(10)
+
+#define IQS269_CHx_COUNTS 0x08
+
+#define IQS269_SLIDER_X 0x30
+
+#define IQS269_CAL_DATA_A 0x35
+#define IQS269_CAL_DATA_A_HALL_BIN_L_MASK GENMASK(15, 12)
+#define IQS269_CAL_DATA_A_HALL_BIN_L_SHIFT 12
+#define IQS269_CAL_DATA_A_HALL_BIN_R_MASK GENMASK(11, 8)
+#define IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT 8
+
+#define IQS269_SYS_SETTINGS 0x80
+#define IQS269_SYS_SETTINGS_CLK_DIV BIT(15)
+#define IQS269_SYS_SETTINGS_ULP_AUTO BIT(14)
+#define IQS269_SYS_SETTINGS_DIS_AUTO BIT(13)
+#define IQS269_SYS_SETTINGS_PWR_MODE_MASK GENMASK(12, 11)
+#define IQS269_SYS_SETTINGS_PWR_MODE_SHIFT 11
+#define IQS269_SYS_SETTINGS_PWR_MODE_MAX 3
+#define IQS269_SYS_SETTINGS_ULP_UPDATE_MASK GENMASK(10, 8)
+#define IQS269_SYS_SETTINGS_ULP_UPDATE_SHIFT 8
+#define IQS269_SYS_SETTINGS_ULP_UPDATE_MAX 7
+#define IQS269_SYS_SETTINGS_RESEED_OFFSET BIT(6)
+#define IQS269_SYS_SETTINGS_EVENT_MODE BIT(5)
+#define IQS269_SYS_SETTINGS_EVENT_MODE_LP BIT(4)
+#define IQS269_SYS_SETTINGS_REDO_ATI BIT(2)
+#define IQS269_SYS_SETTINGS_ACK_RESET BIT(0)
+
+#define IQS269_FILT_STR_LP_LTA_MASK GENMASK(7, 6)
+#define IQS269_FILT_STR_LP_LTA_SHIFT 6
+#define IQS269_FILT_STR_LP_CNT_MASK GENMASK(5, 4)
+#define IQS269_FILT_STR_LP_CNT_SHIFT 4
+#define IQS269_FILT_STR_NP_LTA_MASK GENMASK(3, 2)
+#define IQS269_FILT_STR_NP_LTA_SHIFT 2
+#define IQS269_FILT_STR_NP_CNT_MASK GENMASK(1, 0)
+#define IQS269_FILT_STR_MAX 3
+
+#define IQS269_EVENT_MASK_SYS BIT(6)
+#define IQS269_EVENT_MASK_DEEP BIT(2)
+#define IQS269_EVENT_MASK_TOUCH BIT(1)
+#define IQS269_EVENT_MASK_PROX BIT(0)
+
+#define IQS269_RATE_NP_MS_MAX 255
+#define IQS269_RATE_LP_MS_MAX 255
+#define IQS269_RATE_ULP_MS_MAX 4080
+#define IQS269_TIMEOUT_PWR_MS_MAX 130560
+#define IQS269_TIMEOUT_LTA_MS_MAX 130560
+
+#define IQS269_MISC_A_ATI_BAND_DISABLE BIT(15)
+#define IQS269_MISC_A_ATI_LP_ONLY BIT(14)
+#define IQS269_MISC_A_ATI_BAND_TIGHTEN BIT(13)
+#define IQS269_MISC_A_FILT_DISABLE BIT(12)
+#define IQS269_MISC_A_GPIO3_SELECT_MASK GENMASK(10, 8)
+#define IQS269_MISC_A_GPIO3_SELECT_SHIFT 8
+#define IQS269_MISC_A_DUAL_DIR BIT(6)
+#define IQS269_MISC_A_TX_FREQ_MASK GENMASK(5, 4)
+#define IQS269_MISC_A_TX_FREQ_SHIFT 4
+#define IQS269_MISC_A_TX_FREQ_MAX 3
+#define IQS269_MISC_A_GLOBAL_CAP_SIZE BIT(0)
+
+#define IQS269_MISC_B_RESEED_UI_SEL_MASK GENMASK(7, 6)
+#define IQS269_MISC_B_RESEED_UI_SEL_SHIFT 6
+#define IQS269_MISC_B_RESEED_UI_SEL_MAX 3
+#define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4)
+#define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0)
+
+#define IQS269_CHx_SETTINGS 0x8C
+
+#define IQS269_CHx_ENG_A_MEAS_CAP_SIZE BIT(15)
+#define IQS269_CHx_ENG_A_RX_GND_INACTIVE BIT(13)
+#define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE BIT(12)
+#define IQS269_CHx_ENG_A_ATI_MODE_MASK GENMASK(9, 8)
+#define IQS269_CHx_ENG_A_ATI_MODE_SHIFT 8
+#define IQS269_CHx_ENG_A_ATI_MODE_MAX 3
+#define IQS269_CHx_ENG_A_INV_LOGIC BIT(7)
+#define IQS269_CHx_ENG_A_PROJ_BIAS_MASK GENMASK(6, 5)
+#define IQS269_CHx_ENG_A_PROJ_BIAS_SHIFT 5
+#define IQS269_CHx_ENG_A_PROJ_BIAS_MAX 3
+#define IQS269_CHx_ENG_A_SENSE_MODE_MASK GENMASK(3, 0)
+#define IQS269_CHx_ENG_A_SENSE_MODE_MAX 15
+
+#define IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE BIT(13)
+#define IQS269_CHx_ENG_B_SENSE_FREQ_MASK GENMASK(10, 9)
+#define IQS269_CHx_ENG_B_SENSE_FREQ_SHIFT 9
+#define IQS269_CHx_ENG_B_SENSE_FREQ_MAX 3
+#define IQS269_CHx_ENG_B_STATIC_ENABLE BIT(8)
+#define IQS269_CHx_ENG_B_ATI_BASE_MASK GENMASK(7, 6)
+#define IQS269_CHx_ENG_B_ATI_BASE_75 0x00
+#define IQS269_CHx_ENG_B_ATI_BASE_100 0x40
+#define IQS269_CHx_ENG_B_ATI_BASE_150 0x80
+#define IQS269_CHx_ENG_B_ATI_BASE_200 0xC0
+#define IQS269_CHx_ENG_B_ATI_TARGET_MASK GENMASK(5, 0)
+#define IQS269_CHx_ENG_B_ATI_TARGET_MAX 2016
+
+#define IQS269_CHx_WEIGHT_MAX 255
+#define IQS269_CHx_THRESH_MAX 255
+#define IQS269_CHx_HYST_DEEP_MASK GENMASK(7, 4)
+#define IQS269_CHx_HYST_DEEP_SHIFT 4
+#define IQS269_CHx_HYST_TOUCH_MASK GENMASK(3, 0)
+#define IQS269_CHx_HYST_MAX 15
+
+#define IQS269_CHx_HALL_INACTIVE 6
+#define IQS269_CHx_HALL_ACTIVE 7
+
+#define IQS269_HALL_PAD_R BIT(0)
+#define IQS269_HALL_PAD_L BIT(1)
+#define IQS269_HALL_PAD_INV BIT(6)
+
+#define IQS269_HALL_UI 0xF5
+#define IQS269_HALL_UI_ENABLE BIT(15)
+
+#define IQS269_MAX_REG 0xFF
+
+#define IQS269_NUM_CH 8
+#define IQS269_NUM_SL 2
+
+#define IQS269_ATI_POLL_SLEEP_US (iqs269->delay_mult * 10000)
+#define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000)
+#define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150)
+
+#define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US
+#define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US
+
+#define iqs269_irq_wait() usleep_range(100, 150)
+
+enum iqs269_local_cap_size {
+ IQS269_LOCAL_CAP_SIZE_0,
+ IQS269_LOCAL_CAP_SIZE_GLOBAL_ONLY,
+ IQS269_LOCAL_CAP_SIZE_GLOBAL_0pF5,
+};
+
+enum iqs269_st_offs {
+ IQS269_ST_OFFS_PROX,
+ IQS269_ST_OFFS_DIR,
+ IQS269_ST_OFFS_TOUCH,
+ IQS269_ST_OFFS_DEEP,
+};
+
+enum iqs269_th_offs {
+ IQS269_TH_OFFS_PROX,
+ IQS269_TH_OFFS_TOUCH,
+ IQS269_TH_OFFS_DEEP,
+};
+
+enum iqs269_event_id {
+ IQS269_EVENT_PROX_DN,
+ IQS269_EVENT_PROX_UP,
+ IQS269_EVENT_TOUCH_DN,
+ IQS269_EVENT_TOUCH_UP,
+ IQS269_EVENT_DEEP_DN,
+ IQS269_EVENT_DEEP_UP,
+};
+
+struct iqs269_switch_desc {
+ unsigned int code;
+ bool enabled;
+};
+
+struct iqs269_event_desc {
+ const char *name;
+ enum iqs269_st_offs st_offs;
+ enum iqs269_th_offs th_offs;
+ bool dir_up;
+ u8 mask;
+};
+
+static const struct iqs269_event_desc iqs269_events[] = {
+ [IQS269_EVENT_PROX_DN] = {
+ .name = "event-prox",
+ .st_offs = IQS269_ST_OFFS_PROX,
+ .th_offs = IQS269_TH_OFFS_PROX,
+ .mask = IQS269_EVENT_MASK_PROX,
+ },
+ [IQS269_EVENT_PROX_UP] = {
+ .name = "event-prox-alt",
+ .st_offs = IQS269_ST_OFFS_PROX,
+ .th_offs = IQS269_TH_OFFS_PROX,
+ .dir_up = true,
+ .mask = IQS269_EVENT_MASK_PROX,
+ },
+ [IQS269_EVENT_TOUCH_DN] = {
+ .name = "event-touch",
+ .st_offs = IQS269_ST_OFFS_TOUCH,
+ .th_offs = IQS269_TH_OFFS_TOUCH,
+ .mask = IQS269_EVENT_MASK_TOUCH,
+ },
+ [IQS269_EVENT_TOUCH_UP] = {
+ .name = "event-touch-alt",
+ .st_offs = IQS269_ST_OFFS_TOUCH,
+ .th_offs = IQS269_TH_OFFS_TOUCH,
+ .dir_up = true,
+ .mask = IQS269_EVENT_MASK_TOUCH,
+ },
+ [IQS269_EVENT_DEEP_DN] = {
+ .name = "event-deep",
+ .st_offs = IQS269_ST_OFFS_DEEP,
+ .th_offs = IQS269_TH_OFFS_DEEP,
+ .mask = IQS269_EVENT_MASK_DEEP,
+ },
+ [IQS269_EVENT_DEEP_UP] = {
+ .name = "event-deep-alt",
+ .st_offs = IQS269_ST_OFFS_DEEP,
+ .th_offs = IQS269_TH_OFFS_DEEP,
+ .dir_up = true,
+ .mask = IQS269_EVENT_MASK_DEEP,
+ },
+};
+
+struct iqs269_ver_info {
+ u8 prod_num;
+ u8 sw_num;
+ u8 hw_num;
+ u8 padding;
+} __packed;
+
+struct iqs269_sys_reg {
+ __be16 general;
+ u8 active;
+ u8 filter;
+ u8 reseed;
+ u8 event_mask;
+ u8 rate_np;
+ u8 rate_lp;
+ u8 rate_ulp;
+ u8 timeout_pwr;
+ u8 timeout_rdy;
+ u8 timeout_lta;
+ __be16 misc_a;
+ __be16 misc_b;
+ u8 blocking;
+ u8 padding;
+ u8 slider_select[IQS269_NUM_SL];
+ u8 timeout_tap;
+ u8 timeout_swipe;
+ u8 thresh_swipe;
+ u8 redo_ati;
+} __packed;
+
+struct iqs269_ch_reg {
+ u8 rx_enable;
+ u8 tx_enable;
+ __be16 engine_a;
+ __be16 engine_b;
+ __be16 ati_comp;
+ u8 thresh[3];
+ u8 hyst;
+ u8 assoc_select;
+ u8 assoc_weight;
+} __packed;
+
+struct iqs269_flags {
+ __be16 system;
+ u8 gesture;
+ u8 padding;
+ u8 states[4];
+} __packed;
+
+struct iqs269_private {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct mutex lock;
+ struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)];
+ struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
+ struct iqs269_sys_reg sys_reg;
+ struct input_dev *keypad;
+ struct input_dev *slider[IQS269_NUM_SL];
+ unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
+ unsigned int suspend_mode;
+ unsigned int delay_mult;
+ unsigned int ch_num;
+ bool hall_enable;
+ bool ati_current;
+};
+
+static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int mode)
+{
+ u16 engine_a;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ if (mode > IQS269_CHx_ENG_A_ATI_MODE_MAX)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+
+ engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
+
+ engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK;
+ engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
+
+ iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+
+ return 0;
+}
+
+static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int *mode)
+{
+ u16 engine_a;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+ engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
+ mutex_unlock(&iqs269->lock);
+
+ engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK;
+ *mode = (engine_a >> IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
+
+ return 0;
+}
+
+static int iqs269_ati_base_set(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int base)
+{
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ switch (base) {
+ case 75:
+ base = IQS269_CHx_ENG_B_ATI_BASE_75;
+ break;
+
+ case 100:
+ base = IQS269_CHx_ENG_B_ATI_BASE_100;
+ break;
+
+ case 150:
+ base = IQS269_CHx_ENG_B_ATI_BASE_150;
+ break;
+
+ case 200:
+ base = IQS269_CHx_ENG_B_ATI_BASE_200;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ mutex_lock(&iqs269->lock);
+
+ engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+
+ engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK;
+ engine_b |= base;
+
+ iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+
+ return 0;
+}
+
+static int iqs269_ati_base_get(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int *base)
+{
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+ engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+ mutex_unlock(&iqs269->lock);
+
+ switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) {
+ case IQS269_CHx_ENG_B_ATI_BASE_75:
+ *base = 75;
+ return 0;
+
+ case IQS269_CHx_ENG_B_ATI_BASE_100:
+ *base = 100;
+ return 0;
+
+ case IQS269_CHx_ENG_B_ATI_BASE_150:
+ *base = 150;
+ return 0;
+
+ case IQS269_CHx_ENG_B_ATI_BASE_200:
+ *base = 200;
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int iqs269_ati_target_set(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int target)
+{
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ if (target > IQS269_CHx_ENG_B_ATI_TARGET_MAX)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+
+ engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+
+ engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK;
+ engine_b |= target / 32;
+
+ iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+
+ return 0;
+}
+
+static int iqs269_ati_target_get(struct iqs269_private *iqs269,
+ unsigned int ch_num, unsigned int *target)
+{
+ u16 engine_b;
+
+ if (ch_num >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+ engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+ mutex_unlock(&iqs269->lock);
+
+ *target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32;
+
+ return 0;
+}
+
+static int iqs269_parse_mask(const struct fwnode_handle *fwnode,
+ const char *propname, u8 *mask)
+{
+ unsigned int val[IQS269_NUM_CH];
+ int count, error, i;
+
+ count = fwnode_property_count_u32(fwnode, propname);
+ if (count < 0)
+ return 0;
+
+ if (count > IQS269_NUM_CH)
+ return -EINVAL;
+
+ error = fwnode_property_read_u32_array(fwnode, propname, val, count);
+ if (error)
+ return error;
+
+ *mask = 0;
+
+ for (i = 0; i < count; i++) {
+ if (val[i] >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ *mask |= BIT(val[i]);
+ }
+
+ return 0;
+}
+
+static int iqs269_parse_chan(struct iqs269_private *iqs269,
+ const struct fwnode_handle *ch_node)
+{
+ struct i2c_client *client = iqs269->client;
+ struct fwnode_handle *ev_node;
+ struct iqs269_ch_reg *ch_reg;
+ u16 engine_a, engine_b;
+ unsigned int reg, val;
+ int error, i;
+
+ error = fwnode_property_read_u32(ch_node, "reg", &reg);
+ if (error) {
+ dev_err(&client->dev, "Failed to read channel number: %d\n",
+ error);
+ return error;
+ } else if (reg >= IQS269_NUM_CH) {
+ dev_err(&client->dev, "Invalid channel number: %u\n", reg);
+ return -EINVAL;
+ }
+
+ iqs269->sys_reg.active |= BIT(reg);
+ if (!fwnode_property_present(ch_node, "azoteq,reseed-disable"))
+ iqs269->sys_reg.reseed |= BIT(reg);
+
+ if (fwnode_property_present(ch_node, "azoteq,blocking-enable"))
+ iqs269->sys_reg.blocking |= BIT(reg);
+
+ if (fwnode_property_present(ch_node, "azoteq,slider0-select"))
+ iqs269->sys_reg.slider_select[0] |= BIT(reg);
+
+ if (fwnode_property_present(ch_node, "azoteq,slider1-select"))
+ iqs269->sys_reg.slider_select[1] |= BIT(reg);
+
+ ch_reg = &iqs269->ch_reg[reg];
+
+ error = regmap_raw_read(iqs269->regmap,
+ IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2,
+ ch_reg, sizeof(*ch_reg));
+ if (error)
+ return error;
+
+ error = iqs269_parse_mask(ch_node, "azoteq,rx-enable",
+ &ch_reg->rx_enable);
+ if (error) {
+ dev_err(&client->dev, "Invalid channel %u RX enable mask: %d\n",
+ reg, error);
+ return error;
+ }
+
+ error = iqs269_parse_mask(ch_node, "azoteq,tx-enable",
+ &ch_reg->tx_enable);
+ if (error) {
+ dev_err(&client->dev, "Invalid channel %u TX enable mask: %d\n",
+ reg, error);
+ return error;
+ }
+
+ engine_a = be16_to_cpu(ch_reg->engine_a);
+ engine_b = be16_to_cpu(ch_reg->engine_b);
+
+ engine_a |= IQS269_CHx_ENG_A_MEAS_CAP_SIZE;
+ if (fwnode_property_present(ch_node, "azoteq,meas-cap-decrease"))
+ engine_a &= ~IQS269_CHx_ENG_A_MEAS_CAP_SIZE;
+
+ engine_a |= IQS269_CHx_ENG_A_RX_GND_INACTIVE;
+ if (fwnode_property_present(ch_node, "azoteq,rx-float-inactive"))
+ engine_a &= ~IQS269_CHx_ENG_A_RX_GND_INACTIVE;
+
+ engine_a &= ~IQS269_CHx_ENG_A_LOCAL_CAP_SIZE;
+ engine_b &= ~IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE;
+ if (!fwnode_property_read_u32(ch_node, "azoteq,local-cap-size", &val)) {
+ switch (val) {
+ case IQS269_LOCAL_CAP_SIZE_0:
+ break;
+
+ case IQS269_LOCAL_CAP_SIZE_GLOBAL_0pF5:
+ engine_a |= IQS269_CHx_ENG_A_LOCAL_CAP_SIZE;
+
+ /* fall through */
+
+ case IQS269_LOCAL_CAP_SIZE_GLOBAL_ONLY:
+ engine_b |= IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE;
+ break;
+
+ default:
+ dev_err(&client->dev,
+ "Invalid channel %u local cap. size: %u\n", reg,
+ val);
+ return -EINVAL;
+ }
+ }
+
+ engine_a &= ~IQS269_CHx_ENG_A_INV_LOGIC;
+ if (fwnode_property_present(ch_node, "azoteq,invert-enable"))
+ engine_a |= IQS269_CHx_ENG_A_INV_LOGIC;
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,proj-bias", &val)) {
+ if (val > IQS269_CHx_ENG_A_PROJ_BIAS_MAX) {
+ dev_err(&client->dev,
+ "Invalid channel %u bias current: %u\n", reg,
+ val);
+ return -EINVAL;
+ }
+
+ engine_a &= ~IQS269_CHx_ENG_A_PROJ_BIAS_MASK;
+ engine_a |= (val << IQS269_CHx_ENG_A_PROJ_BIAS_SHIFT);
+ }
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,sense-mode", &val)) {
+ if (val > IQS269_CHx_ENG_A_SENSE_MODE_MAX) {
+ dev_err(&client->dev,
+ "Invalid channel %u sensing mode: %u\n", reg,
+ val);
+ return -EINVAL;
+ }
+
+ engine_a &= ~IQS269_CHx_ENG_A_SENSE_MODE_MASK;
+ engine_a |= val;
+ }
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,sense-freq", &val)) {
+ if (val > IQS269_CHx_ENG_B_SENSE_FREQ_MAX) {
+ dev_err(&client->dev,
+ "Invalid channel %u sensing frequency: %u\n",
+ reg, val);
+ return -EINVAL;
+ }
+
+ engine_b &= ~IQS269_CHx_ENG_B_SENSE_FREQ_MASK;
+ engine_b |= (val << IQS269_CHx_ENG_B_SENSE_FREQ_SHIFT);
+ }
+
+ engine_b &= ~IQS269_CHx_ENG_B_STATIC_ENABLE;
+ if (fwnode_property_present(ch_node, "azoteq,static-enable"))
+ engine_b |= IQS269_CHx_ENG_B_STATIC_ENABLE;
+
+ ch_reg->engine_a = cpu_to_be16(engine_a);
+ ch_reg->engine_b = cpu_to_be16(engine_b);
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,ati-mode", &val)) {
+ error = iqs269_ati_mode_set(iqs269, reg, val);
+ if (error) {
+ dev_err(&client->dev,
+ "Invalid channel %u ATI mode: %u\n", reg, val);
+ return error;
+ }
+ }
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,ati-base", &val)) {
+ error = iqs269_ati_base_set(iqs269, reg, val);
+ if (error) {
+ dev_err(&client->dev,
+ "Invalid channel %u ATI base: %u\n", reg, val);
+ return error;
+ }
+ }
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,ati-target", &val)) {
+ error = iqs269_ati_target_set(iqs269, reg, val);
+ if (error) {
+ dev_err(&client->dev,
+ "Invalid channel %u ATI target: %u\n", reg,
+ val);
+ return error;
+ }
+ }
+
+ error = iqs269_parse_mask(ch_node, "azoteq,assoc-select",
+ &ch_reg->assoc_select);
+ if (error) {
+ dev_err(&client->dev, "Invalid channel %u association: %d\n",
+ reg, error);
+ return error;
+ }
+
+ if (!fwnode_property_read_u32(ch_node, "azoteq,assoc-weight", &val)) {
+ if (val > IQS269_CHx_WEIGHT_MAX) {
+ dev_err(&client->dev,
+ "Invalid channel %u associated weight: %u\n",
+ reg, val);
+ return -EINVAL;
+ }
+
+ ch_reg->assoc_weight = val;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+ ev_node = fwnode_get_named_child_node(ch_node,
+ iqs269_events[i].name);
+ if (!ev_node)
+ continue;
+
+ if (!fwnode_property_read_u32(ev_node, "azoteq,thresh", &val)) {
+ if (val > IQS269_CHx_THRESH_MAX) {
+ dev_err(&client->dev,
+ "Invalid channel %u threshold: %u\n",
+ reg, val);
+ return -EINVAL;
+ }
+
+ ch_reg->thresh[iqs269_events[i].th_offs] = val;
+ }
+
+ if (!fwnode_property_read_u32(ev_node, "azoteq,hyst", &val)) {
+ u8 *hyst = &ch_reg->hyst;
+
+ if (val > IQS269_CHx_HYST_MAX) {
+ dev_err(&client->dev,
+ "Invalid channel %u hysteresis: %u\n",
+ reg, val);
+ return -EINVAL;
+ }
+
+ if (i == IQS269_EVENT_DEEP_DN ||
+ i == IQS269_EVENT_DEEP_UP) {
+ *hyst &= ~IQS269_CHx_HYST_DEEP_MASK;
+ *hyst |= (val << IQS269_CHx_HYST_DEEP_SHIFT);
+ } else if (i == IQS269_EVENT_TOUCH_DN ||
+ i == IQS269_EVENT_TOUCH_UP) {
+ *hyst &= ~IQS269_CHx_HYST_TOUCH_MASK;
+ *hyst |= val;
+ }
+ }
+
+ if (fwnode_property_read_u32(ev_node, "linux,code", &val))
+ continue;
+
+ switch (reg) {
+ case IQS269_CHx_HALL_ACTIVE:
+ if (iqs269->hall_enable) {
+ iqs269->switches[i].code = val;
+ iqs269->switches[i].enabled = true;
+ }
+
+ /* fall through */
+
+ case IQS269_CHx_HALL_INACTIVE:
+ if (iqs269->hall_enable)
+ break;
+
+ /* fall through */
+
+ default:
+ iqs269->keycode[i * IQS269_NUM_CH + reg] = val;
+ }
+
+ iqs269->sys_reg.event_mask &= ~iqs269_events[i].mask;
+ }
+
+ return 0;
+}
+
+static int iqs269_parse_prop(struct iqs269_private *iqs269)
+{
+ struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
+ struct i2c_client *client = iqs269->client;
+ struct fwnode_handle *ch_node;
+ u16 general, misc_a, misc_b;
+ unsigned int val;
+ int error;
+
+ iqs269->hall_enable = device_property_present(&client->dev,
+ "azoteq,hall-enable");
+
+ if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
+ &val)) {
+ if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
+ dev_err(&client->dev, "Invalid suspend mode: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ iqs269->suspend_mode = val;
+ }
+
+ error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
+ sizeof(*sys_reg));
+ if (error)
+ return error;
+
+ if (!device_property_read_u32(&client->dev, "azoteq,filt-str-lp-lta",
+ &val)) {
+ if (val > IQS269_FILT_STR_MAX) {
+ dev_err(&client->dev, "Invalid filter strength: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ sys_reg->filter &= ~IQS269_FILT_STR_LP_LTA_MASK;
+ sys_reg->filter |= (val << IQS269_FILT_STR_LP_LTA_SHIFT);
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,filt-str-lp-cnt",
+ &val)) {
+ if (val > IQS269_FILT_STR_MAX) {
+ dev_err(&client->dev, "Invalid filter strength: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ sys_reg->filter &= ~IQS269_FILT_STR_LP_CNT_MASK;
+ sys_reg->filter |= (val << IQS269_FILT_STR_LP_CNT_SHIFT);
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,filt-str-np-lta",
+ &val)) {
+ if (val > IQS269_FILT_STR_MAX) {
+ dev_err(&client->dev, "Invalid filter strength: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ sys_reg->filter &= ~IQS269_FILT_STR_NP_LTA_MASK;
+ sys_reg->filter |= (val << IQS269_FILT_STR_NP_LTA_SHIFT);
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,filt-str-np-cnt",
+ &val)) {
+ if (val > IQS269_FILT_STR_MAX) {
+ dev_err(&client->dev, "Invalid filter strength: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ sys_reg->filter &= ~IQS269_FILT_STR_NP_CNT_MASK;
+ sys_reg->filter |= val;
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,rate-np-ms",
+ &val)) {
+ if (val > IQS269_RATE_NP_MS_MAX) {
+ dev_err(&client->dev, "Invalid report rate: %u\n", val);
+ return -EINVAL;
+ }
+
+ sys_reg->rate_np = val;
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,rate-lp-ms",
+ &val)) {
+ if (val > IQS269_RATE_LP_MS_MAX) {
+ dev_err(&client->dev, "Invalid report rate: %u\n", val);
+ return -EINVAL;
+ }
+
+ sys_reg->rate_lp = val;
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,rate-ulp-ms",
+ &val)) {
+ if (val > IQS269_RATE_ULP_MS_MAX) {
+ dev_err(&client->dev, "Invalid report rate: %u\n", val);
+ return -EINVAL;
+ }
+
+ sys_reg->rate_ulp = val / 16;
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,timeout-pwr-ms",
+ &val)) {
+ if (val > IQS269_TIMEOUT_PWR_MS_MAX) {
+ dev_err(&client->dev, "Invalid timeout: %u\n", val);
+ return -EINVAL;
+ }
+
+ sys_reg->timeout_pwr = val / 512;
+ }
+
+ if (!device_property_read_u32(&client->dev, "azoteq,timeout-lta-ms",
+ &val)) {
+ if (val > IQS269_TIMEOUT_LTA_MS_MAX) {
+ dev_err(&client->dev, "Invalid timeout: %u\n", val);
+ return -EINVAL;
+ }
+
+ sys_reg->timeout_lta = val / 512;
+ }
+
+ misc_a = be16_to_cpu(sys_reg->misc_a);
+ misc_b = be16_to_cpu(sys_reg->misc_b);
+
+ misc_a &= ~IQS269_MISC_A_ATI_BAND_DISABLE;
+ if (device_property_present(&client->dev, "azoteq,ati-band-disable"))
+ misc_a |= IQS269_MISC_A_ATI_BAND_DISABLE;
+
+ misc_a &= ~IQS269_MISC_A_ATI_LP_ONLY;
+ if (device_property_present(&client->dev, "azoteq,ati-lp-only"))
+ misc_a |= IQS269_MISC_A_ATI_LP_ONLY;
+
+ misc_a &= ~IQS269_MISC_A_ATI_BAND_TIGHTEN;
+ if (device_property_present(&client->dev, "azoteq,ati-band-tighten"))
+ misc_a |= IQS269_MISC_A_ATI_BAND_TIGHTEN;
+
+ misc_a &= ~IQS269_MISC_A_FILT_DISABLE;
+ if (device_property_present(&client->dev, "azoteq,filt-disable"))
+ misc_a |= IQS269_MISC_A_FILT_DISABLE;
+
+ if (!device_property_read_u32(&client->dev, "azoteq,gpio3-select",
+ &val)) {
+ if (val >= IQS269_NUM_CH) {
+ dev_err(&client->dev, "Invalid GPIO3 selection: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ misc_a &= ~IQS269_MISC_A_GPIO3_SELECT_MASK;
+ misc_a |= (val << IQS269_MISC_A_GPIO3_SELECT_SHIFT);
+ }
+
+ misc_a &= ~IQS269_MISC_A_DUAL_DIR;
+ if (device_property_present(&client->dev, "azoteq,dual-direction"))
+ misc_a |= IQS269_MISC_A_DUAL_DIR;
+
+ if (!device_property_read_u32(&client->dev, "azoteq,tx-freq", &val)) {
+ if (val > IQS269_MISC_A_TX_FREQ_MAX) {
+ dev_err(&client->dev,
+ "Invalid excitation frequency: %u\n", val);
+ return -EINVAL;
+ }
+
+ misc_a &= ~IQS269_MISC_A_TX_FREQ_MASK;
+ misc_a |= (val << IQS269_MISC_A_TX_FREQ_SHIFT);
+ }
+
+ misc_a &= ~IQS269_MISC_A_GLOBAL_CAP_SIZE;
+ if (device_property_present(&client->dev, "azoteq,global-cap-increase"))
+ misc_a |= IQS269_MISC_A_GLOBAL_CAP_SIZE;
+
+ if (!device_property_read_u32(&client->dev, "azoteq,reseed-select",
+ &val)) {
+ if (val > IQS269_MISC_B_RESEED_UI_SEL_MAX) {
+ dev_err(&client->dev, "Invalid reseed selection: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ misc_b &= ~IQS269_MISC_B_RESEED_UI_SEL_MASK;
+ misc_b |= (val << IQS269_MISC_B_RESEED_UI_SEL_SHIFT);
+ }
+
+ misc_b &= ~IQS269_MISC_B_TRACKING_UI_ENABLE;
+ if (device_property_present(&client->dev, "azoteq,tracking-enable"))
+ misc_b |= IQS269_MISC_B_TRACKING_UI_ENABLE;
+
+ if (!device_property_read_u32(&client->dev, "azoteq,filt-str-slider",
+ &val)) {
+ if (val > IQS269_FILT_STR_MAX) {
+ dev_err(&client->dev, "Invalid filter strength: %u\n",
+ val);
+ return -EINVAL;
+ }
+
+ misc_b &= ~IQS269_MISC_B_FILT_STR_SLIDER;
+ misc_b |= val;
+ }
+
+ sys_reg->misc_a = cpu_to_be16(misc_a);
+ sys_reg->misc_b = cpu_to_be16(misc_b);
+
+ sys_reg->active = 0;
+ sys_reg->reseed = 0;
+
+ sys_reg->blocking = 0;
+
+ sys_reg->slider_select[0] = 0;
+ sys_reg->slider_select[1] = 0;
+
+ sys_reg->event_mask = ~((u8)IQS269_EVENT_MASK_SYS);
+
+ device_for_each_child_node(&client->dev, ch_node) {
+ error = iqs269_parse_chan(iqs269, ch_node);
+ if (error) {
+ fwnode_handle_put(ch_node);
+ return error;
+ }
+ }
+
+ /*
+ * Volunteer all active channels to participate in ATI when REDO-ATI is
+ * manually triggered.
+ */
+ sys_reg->redo_ati = sys_reg->active;
+
+ general = be16_to_cpu(sys_reg->general);
+
+ if (device_property_present(&client->dev, "azoteq,clk-div")) {
+ general |= IQS269_SYS_SETTINGS_CLK_DIV;
+ iqs269->delay_mult = 4;
+ } else {
+ general &= ~IQS269_SYS_SETTINGS_CLK_DIV;
+ iqs269->delay_mult = 1;
+ }
+
+ /*
+ * Configure the device to automatically switch between normal and low-
+ * power modes as a function of sensing activity. Ultra-low-power mode,
+ * if enabled, is reserved for suspend.
+ */
+ general &= ~IQS269_SYS_SETTINGS_ULP_AUTO;
+ general &= ~IQS269_SYS_SETTINGS_DIS_AUTO;
+ general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK;
+
+ if (!device_property_read_u32(&client->dev, "azoteq,ulp-update",
+ &val)) {
+ if (val > IQS269_SYS_SETTINGS_ULP_UPDATE_MAX) {
+ dev_err(&client->dev, "Invalid update rate: %u\n", val);
+ return -EINVAL;
+ }
+
+ general &= ~IQS269_SYS_SETTINGS_ULP_UPDATE_MASK;
+ general |= (val << IQS269_SYS_SETTINGS_ULP_UPDATE_SHIFT);
+ }
+
+ general &= ~IQS269_SYS_SETTINGS_RESEED_OFFSET;
+ if (device_property_present(&client->dev, "azoteq,reseed-offset"))
+ general |= IQS269_SYS_SETTINGS_RESEED_OFFSET;
+
+ general |= IQS269_SYS_SETTINGS_EVENT_MODE;
+
+ /*
+ * As per the datasheet, enable streaming during normal-power mode if
+ * either slider is in use. In that case, the device returns to event
+ * mode during low-power mode.
+ */
+ if (sys_reg->slider_select[0] || sys_reg->slider_select[1])
+ general |= IQS269_SYS_SETTINGS_EVENT_MODE_LP;
+
+ general |= IQS269_SYS_SETTINGS_REDO_ATI;
+ general |= IQS269_SYS_SETTINGS_ACK_RESET;
+
+ sys_reg->general = cpu_to_be16(general);
+
+ return 0;
+}
+
+static int iqs269_dev_init(struct iqs269_private *iqs269)
+{
+ struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
+ struct iqs269_ch_reg *ch_reg;
+ unsigned int val;
+ int error, i;
+
+ mutex_lock(&iqs269->lock);
+
+ error = regmap_update_bits(iqs269->regmap, IQS269_HALL_UI,
+ IQS269_HALL_UI_ENABLE,
+ iqs269->hall_enable ? ~0 : 0);
+ if (error)
+ goto err_mutex;
+
+ for (i = 0; i < IQS269_NUM_CH; i++) {
+ if (!(sys_reg->active & BIT(i)))
+ continue;
+
+ ch_reg = &iqs269->ch_reg[i];
+
+ error = regmap_raw_write(iqs269->regmap,
+ IQS269_CHx_SETTINGS + i *
+ sizeof(*ch_reg) / 2, ch_reg,
+ sizeof(*ch_reg));
+ if (error)
+ goto err_mutex;
+ }
+
+ /*
+ * The REDO-ATI and ATI channel selection fields must be written in the
+ * same block write, so every field between registers 0x80 through 0x8B
+ * (inclusive) must be written as well.
+ */
+ error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
+ sizeof(*sys_reg));
+ if (error)
+ goto err_mutex;
+
+ error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+ !(val & IQS269_SYS_FLAGS_IN_ATI),
+ IQS269_ATI_POLL_SLEEP_US,
+ IQS269_ATI_POLL_TIMEOUT_US);
+ if (error)
+ goto err_mutex;
+
+ msleep(IQS269_ATI_STABLE_DELAY_MS);
+ iqs269->ati_current = true;
+
+err_mutex:
+ mutex_unlock(&iqs269->lock);
+
+ return error;
+}
+
+static int iqs269_input_init(struct iqs269_private *iqs269)
+{
+ struct i2c_client *client = iqs269->client;
+ struct iqs269_flags flags;
+ unsigned int sw_code, keycode;
+ int error, i, j;
+ u8 dir_mask, state;
+
+ iqs269->keypad = devm_input_allocate_device(&client->dev);
+ if (!iqs269->keypad)
+ return -ENOMEM;
+
+ iqs269->keypad->keycodemax = ARRAY_SIZE(iqs269->keycode);
+ iqs269->keypad->keycode = iqs269->keycode;
+ iqs269->keypad->keycodesize = sizeof(*iqs269->keycode);
+
+ iqs269->keypad->name = "iqs269a_keypad";
+ iqs269->keypad->id.bustype = BUS_I2C;
+
+ if (iqs269->hall_enable) {
+ error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS,
+ &flags, sizeof(flags));
+ if (error) {
+ dev_err(&client->dev,
+ "Failed to read initial status: %d\n", error);
+ return error;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+ dir_mask = flags.states[IQS269_ST_OFFS_DIR];
+ if (!iqs269_events[i].dir_up)
+ dir_mask = ~dir_mask;
+
+ state = flags.states[iqs269_events[i].st_offs] & dir_mask;
+
+ sw_code = iqs269->switches[i].code;
+
+ for (j = 0; j < IQS269_NUM_CH; j++) {
+ keycode = iqs269->keycode[i * IQS269_NUM_CH + j];
+
+ /*
+ * Hall-effect sensing repurposes a pair of dedicated
+ * channels, only one of which reports events.
+ */
+ switch (j) {
+ case IQS269_CHx_HALL_ACTIVE:
+ if (iqs269->hall_enable &&
+ iqs269->switches[i].enabled) {
+ input_set_capability(iqs269->keypad,
+ EV_SW, sw_code);
+ input_report_switch(iqs269->keypad,
+ sw_code,
+ state & BIT(j));
+ }
+
+ /* fall through */
+
+ case IQS269_CHx_HALL_INACTIVE:
+ if (iqs269->hall_enable)
+ continue;
+
+ /* fall through */
+
+ default:
+ if (keycode != KEY_RESERVED)
+ input_set_capability(iqs269->keypad,
+ EV_KEY, keycode);
+ }
+ }
+ }
+
+ input_sync(iqs269->keypad);
+
+ error = input_register_device(iqs269->keypad);
+ if (error) {
+ dev_err(&client->dev, "Failed to register keypad: %d\n", error);
+ return error;
+ }
+
+ for (i = 0; i < IQS269_NUM_SL; i++) {
+ if (!iqs269->sys_reg.slider_select[i])
+ continue;
+
+ iqs269->slider[i] = devm_input_allocate_device(&client->dev);
+ if (!iqs269->slider[i])
+ return -ENOMEM;
+
+ iqs269->slider[i]->name = i ? "iqs269a_slider_1"
+ : "iqs269a_slider_0";
+ iqs269->slider[i]->id.bustype = BUS_I2C;
+
+ input_set_capability(iqs269->slider[i], EV_KEY, BTN_TOUCH);
+ input_set_abs_params(iqs269->slider[i], ABS_X, 0, 255, 0, 0);
+
+ error = input_register_device(iqs269->slider[i]);
+ if (error) {
+ dev_err(&client->dev,
+ "Failed to register slider %d: %d\n", i, error);
+ return error;
+ }
+ }
+
+ return 0;
+}
+
+static int iqs269_report(struct iqs269_private *iqs269)
+{
+ struct i2c_client *client = iqs269->client;
+ struct iqs269_flags flags;
+ unsigned int sw_code, keycode;
+ int error, i, j;
+ u8 slider_x[IQS269_NUM_SL];
+ u8 dir_mask, state;
+
+ error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS, &flags,
+ sizeof(flags));
+ if (error) {
+ dev_err(&client->dev, "Failed to read device status: %d\n",
+ error);
+ return error;
+ }
+
+ /*
+ * The device resets itself if its own watchdog bites, which can happen
+ * in the event of an I2C communication error. In this case, the device
+ * asserts a SHOW_RESET interrupt and all registers must be restored.
+ */
+ if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_SHOW_RESET) {
+ dev_err(&client->dev, "Unexpected device reset\n");
+
+ error = iqs269_dev_init(iqs269);
+ if (error)
+ dev_err(&client->dev,
+ "Failed to re-initialize device: %d\n", error);
+
+ return error;
+ }
+
+ error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x,
+ sizeof(slider_x));
+ if (error) {
+ dev_err(&client->dev, "Failed to read slider position: %d\n",
+ error);
+ return error;
+ }
+
+ for (i = 0; i < IQS269_NUM_SL; i++) {
+ if (!iqs269->sys_reg.slider_select[i])
+ continue;
+
+ /*
+ * Report BTN_TOUCH if any channel that participates in the
+ * slider is in a state of touch.
+ */
+ if (flags.states[IQS269_ST_OFFS_TOUCH] &
+ iqs269->sys_reg.slider_select[i]) {
+ input_report_key(iqs269->slider[i], BTN_TOUCH, 1);
+ input_report_abs(iqs269->slider[i], ABS_X, slider_x[i]);
+ } else {
+ input_report_key(iqs269->slider[i], BTN_TOUCH, 0);
+ }
+
+ input_sync(iqs269->slider[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+ dir_mask = flags.states[IQS269_ST_OFFS_DIR];
+ if (!iqs269_events[i].dir_up)
+ dir_mask = ~dir_mask;
+
+ state = flags.states[iqs269_events[i].st_offs] & dir_mask;
+
+ sw_code = iqs269->switches[i].code;
+
+ for (j = 0; j < IQS269_NUM_CH; j++) {
+ keycode = iqs269->keycode[i * IQS269_NUM_CH + j];
+
+ switch (j) {
+ case IQS269_CHx_HALL_ACTIVE:
+ if (iqs269->hall_enable &&
+ iqs269->switches[i].enabled)
+ input_report_switch(iqs269->keypad,
+ sw_code,
+ state & BIT(j));
+
+ /* fall through */
+
+ case IQS269_CHx_HALL_INACTIVE:
+ if (iqs269->hall_enable)
+ continue;
+
+ /* fall through */
+
+ default:
+ input_report_key(iqs269->keypad, keycode,
+ state & BIT(j));
+ }
+ }
+ }
+
+ input_sync(iqs269->keypad);
+
+ return 0;
+}
+
+static irqreturn_t iqs269_irq(int irq, void *context)
+{
+ struct iqs269_private *iqs269 = context;
+
+ if (iqs269_report(iqs269))
+ return IRQ_NONE;
+
+ /*
+ * The device does not deassert its interrupt (RDY) pin until shortly
+ * after receiving an I2C stop condition; the following delay ensures
+ * the interrupt handler does not return before this time.
+ */
+ iqs269_irq_wait();
+
+ return IRQ_HANDLED;
+}
+
+static ssize_t counts_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+ __le16 counts;
+ int error;
+
+ if (!iqs269->ati_current || iqs269->hall_enable)
+ return -EPERM;
+
+ /*
+ * Unsolicited I2C communication prompts the device to assert its RDY
+ * pin, so disable the interrupt line until the operation is finished
+ * and RDY has been deasserted.
+ */
+ disable_irq(client->irq);
+
+ error = regmap_raw_read(iqs269->regmap,
+ IQS269_CHx_COUNTS + iqs269->ch_num * 2,
+ &counts, sizeof(counts));
+
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+ if (error)
+ return error;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", le16_to_cpu(counts));
+}
+
+static ssize_t hall_bin_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+ unsigned int val;
+ int error;
+
+ disable_irq(client->irq);
+
+ error = regmap_read(iqs269->regmap, IQS269_CAL_DATA_A, &val);
+
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+ if (error)
+ return error;
+
+ switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
+ iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
+ case IQS269_HALL_PAD_R:
+ val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK;
+ val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT;
+ break;
+
+ case IQS269_HALL_PAD_L:
+ val &= IQS269_CAL_DATA_A_HALL_BIN_L_MASK;
+ val >>= IQS269_CAL_DATA_A_HALL_BIN_L_SHIFT;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t hall_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->hall_enable);
+}
+
+static ssize_t hall_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ mutex_lock(&iqs269->lock);
+
+ iqs269->hall_enable = val;
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+
+ return count;
+}
+
+static ssize_t ch_number_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ch_num);
+}
+
+static ssize_t ch_number_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ if (val >= IQS269_NUM_CH)
+ return -EINVAL;
+
+ iqs269->ch_num = val;
+
+ return count;
+}
+
+static ssize_t rx_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ iqs269->ch_reg[iqs269->ch_num].rx_enable);
+}
+
+static ssize_t rx_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ if (val > 0xFF)
+ return -EINVAL;
+
+ mutex_lock(&iqs269->lock);
+
+ iqs269->ch_reg[iqs269->ch_num].rx_enable = val;
+ iqs269->ati_current = false;
+
+ mutex_unlock(&iqs269->lock);
+
+ return count;
+}
+
+static ssize_t ati_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = iqs269_ati_mode_get(iqs269, iqs269->ch_num, &val);
+ if (error)
+ return error;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t ati_mode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ error = iqs269_ati_mode_set(iqs269, iqs269->ch_num, val);
+ if (error)
+ return error;
+
+ return count;
+}
+
+static ssize_t ati_base_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = iqs269_ati_base_get(iqs269, iqs269->ch_num, &val);
+ if (error)
+ return error;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t ati_base_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ error = iqs269_ati_base_set(iqs269, iqs269->ch_num, val);
+ if (error)
+ return error;
+
+ return count;
+}
+
+static ssize_t ati_target_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = iqs269_ati_target_get(iqs269, iqs269->ch_num, &val);
+ if (error)
+ return error;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t ati_target_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ error = iqs269_ati_target_set(iqs269, iqs269->ch_num, val);
+ if (error)
+ return error;
+
+ return count;
+}
+
+static ssize_t ati_trigger_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ati_current);
+}
+
+static ssize_t ati_trigger_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 10, &val);
+ if (error)
+ return error;
+
+ if (!val)
+ return count;
+
+ disable_irq(client->irq);
+
+ error = iqs269_dev_init(iqs269);
+
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+ if (error)
+ return error;
+
+ return count;
+}
+
+static DEVICE_ATTR_RO(counts);
+static DEVICE_ATTR_RO(hall_bin);
+static DEVICE_ATTR_RW(hall_enable);
+static DEVICE_ATTR_RW(ch_number);
+static DEVICE_ATTR_RW(rx_enable);
+static DEVICE_ATTR_RW(ati_mode);
+static DEVICE_ATTR_RW(ati_base);
+static DEVICE_ATTR_RW(ati_target);
+static DEVICE_ATTR_RW(ati_trigger);
+
+static struct attribute *iqs269_attrs[] = {
+ &dev_attr_counts.attr,
+ &dev_attr_hall_bin.attr,
+ &dev_attr_hall_enable.attr,
+ &dev_attr_ch_number.attr,
+ &dev_attr_rx_enable.attr,
+ &dev_attr_ati_mode.attr,
+ &dev_attr_ati_base.attr,
+ &dev_attr_ati_target.attr,
+ &dev_attr_ati_trigger.attr,
+ NULL,
+};
+
+static const struct attribute_group iqs269_attr_group = {
+ .attrs = iqs269_attrs,
+};
+
+static const struct regmap_config iqs269_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = IQS269_MAX_REG,
+};
+
+static int iqs269_probe(struct i2c_client *client)
+{
+ struct iqs269_ver_info ver_info;
+ struct iqs269_private *iqs269;
+ int error;
+
+ iqs269 = devm_kzalloc(&client->dev, sizeof(*iqs269), GFP_KERNEL);
+ if (!iqs269)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, iqs269);
+ iqs269->client = client;
+
+ iqs269->regmap = devm_regmap_init_i2c(client, &iqs269_regmap_config);
+ if (IS_ERR(iqs269->regmap)) {
+ error = PTR_ERR(iqs269->regmap);
+ dev_err(&client->dev, "Failed to initialize register map: %d\n",
+ error);
+ return error;
+ }
+
+ mutex_init(&iqs269->lock);
+
+ error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info,
+ sizeof(ver_info));
+ if (error)
+ return error;
+
+ if (ver_info.prod_num != IQS269_VER_INFO_PROD_NUM) {
+ dev_err(&client->dev, "Unrecognized product number: 0x%02X\n",
+ ver_info.prod_num);
+ return -EINVAL;
+ }
+
+ error = iqs269_parse_prop(iqs269);
+ if (error)
+ return error;
+
+ error = iqs269_dev_init(iqs269);
+ if (error) {
+ dev_err(&client->dev, "Failed to initialize device: %d\n",
+ error);
+ return error;
+ }
+
+ error = iqs269_input_init(iqs269);
+ if (error)
+ return error;
+
+ error = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, iqs269_irq, IRQF_ONESHOT,
+ client->name, iqs269);
+ if (error) {
+ dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
+ return error;
+ }
+
+ error = devm_device_add_group(&client->dev, &iqs269_attr_group);
+ if (error)
+ dev_err(&client->dev, "Failed to add attributes: %d\n", error);
+
+ return error;
+}
+
+static int __maybe_unused iqs269_suspend(struct device *dev)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+ unsigned int val;
+ int error;
+
+ if (!iqs269->suspend_mode)
+ return 0;
+
+ disable_irq(client->irq);
+
+ /*
+ * Automatic power mode switching must be disabled before the device is
+ * forced into any particular power mode. In this case, the device will
+ * transition into normal-power mode.
+ */
+ error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+ IQS269_SYS_SETTINGS_DIS_AUTO, ~0);
+ if (error)
+ goto err_irq;
+
+ /*
+ * The following check ensures the device has completed its transition
+ * into normal-power mode before a manual mode switch is performed.
+ */
+ error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+ !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
+ IQS269_PWR_MODE_POLL_SLEEP_US,
+ IQS269_PWR_MODE_POLL_TIMEOUT_US);
+ if (error)
+ goto err_irq;
+
+ error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+ IQS269_SYS_SETTINGS_PWR_MODE_MASK,
+ iqs269->suspend_mode <<
+ IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
+ if (error)
+ goto err_irq;
+
+ /*
+ * This last check ensures the device has completed its transition into
+ * the desired power mode to prevent any spurious interrupts from being
+ * triggered after iqs269_suspend has already returned.
+ */
+ error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+ (val & IQS269_SYS_FLAGS_PWR_MODE_MASK)
+ == (iqs269->suspend_mode <<
+ IQS269_SYS_FLAGS_PWR_MODE_SHIFT),
+ IQS269_PWR_MODE_POLL_SLEEP_US,
+ IQS269_PWR_MODE_POLL_TIMEOUT_US);
+
+err_irq:
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+ return error;
+}
+
+static int __maybe_unused iqs269_resume(struct device *dev)
+{
+ struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+ struct i2c_client *client = iqs269->client;
+ unsigned int val;
+ int error;
+
+ if (!iqs269->suspend_mode)
+ return 0;
+
+ disable_irq(client->irq);
+
+ error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+ IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0);
+ if (error)
+ goto err_irq;
+
+ /*
+ * This check ensures the device has returned to normal-power mode
+ * before automatic power mode switching is re-enabled.
+ */
+ error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+ !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
+ IQS269_PWR_MODE_POLL_SLEEP_US,
+ IQS269_PWR_MODE_POLL_TIMEOUT_US);
+ if (error)
+ goto err_irq;
+
+ error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+ IQS269_SYS_SETTINGS_DIS_AUTO, 0);
+ if (error)
+ goto err_irq;
+
+ /*
+ * This step reports any events that may have been "swallowed" as a
+ * result of polling PWR_MODE (which automatically acknowledges any
+ * pending interrupts).
+ */
+ error = iqs269_report(iqs269);
+
+err_irq:
+ iqs269_irq_wait();
+ enable_irq(client->irq);
+
+ return error;
+}
+
+static SIMPLE_DEV_PM_OPS(iqs269_pm, iqs269_suspend, iqs269_resume);
+
+static const struct of_device_id iqs269_of_match[] = {
+ { .compatible = "azoteq,iqs269a" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, iqs269_of_match);
+
+static struct i2c_driver iqs269_i2c_driver = {
+ .driver = {
+ .name = "iqs269a",
+ .of_match_table = iqs269_of_match,
+ .pm = &iqs269_pm,
+ },
+ .probe_new = iqs269_probe,
+};
+module_i2c_driver(iqs269_i2c_driver);
+
+MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
+MODULE_DESCRIPTION("Azoteq IQS269A Capacitive Touch Controller");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/msm-vibrator.c b/drivers/input/misc/msm-vibrator.c
deleted file mode 100644
index b60f1aaee705..000000000000
--- a/drivers/input/misc/msm-vibrator.c
+++ /dev/null
@@ -1,281 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Qualcomm MSM vibrator driver
- *
- * Copyright (c) 2018 Brian Masney <masneyb@onstation.org>
- *
- * Based on qcom,pwm-vibrator.c from:
- * Copyright (c) 2018 Jonathan Marek <jonathan@marek.ca>
- *
- * Based on msm_pwm_vibrator.c from downstream Android sources:
- * Copyright (C) 2009-2014 LGE, Inc.
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/gpio/consumer.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-
-#define REG_CMD_RCGR 0x00
-#define REG_CFG_RCGR 0x04
-#define REG_M 0x08
-#define REG_N 0x0C
-#define REG_D 0x10
-#define REG_CBCR 0x24
-#define MMSS_CC_M_DEFAULT 1
-
-struct msm_vibrator {
- struct input_dev *input;
- struct mutex mutex;
- struct work_struct worker;
- void __iomem *base;
- struct regulator *vcc;
- struct clk *clk;
- struct gpio_desc *enable_gpio;
- u16 magnitude;
- bool enabled;
-};
-
-static void msm_vibrator_write(struct msm_vibrator *vibrator, int offset,
- u32 value)
-{
- writel(value, vibrator->base + offset);
-}
-
-static int msm_vibrator_start(struct msm_vibrator *vibrator)
-{
- int d_reg_val, ret = 0;
-
- mutex_lock(&vibrator->mutex);
-
- if (!vibrator->enabled) {
- ret = clk_set_rate(vibrator->clk, 24000);
- if (ret) {
- dev_err(&vibrator->input->dev,
- "Failed to set clock rate: %d\n", ret);
- goto unlock;
- }
-
- ret = clk_prepare_enable(vibrator->clk);
- if (ret) {
- dev_err(&vibrator->input->dev,
- "Failed to enable clock: %d\n", ret);
- goto unlock;
- }
-
- ret = regulator_enable(vibrator->vcc);
- if (ret) {
- dev_err(&vibrator->input->dev,
- "Failed to enable regulator: %d\n", ret);
- clk_disable(vibrator->clk);
- goto unlock;
- }
-
- gpiod_set_value_cansleep(vibrator->enable_gpio, 1);
-
- vibrator->enabled = true;
- }
-
- d_reg_val = 127 - ((126 * vibrator->magnitude) / 0xffff);
- msm_vibrator_write(vibrator, REG_CFG_RCGR,
- (2 << 12) | /* dual edge mode */
- (0 << 8) | /* cxo */
- (7 << 0));
- msm_vibrator_write(vibrator, REG_M, 1);
- msm_vibrator_write(vibrator, REG_N, 128);
- msm_vibrator_write(vibrator, REG_D, d_reg_val);
- msm_vibrator_write(vibrator, REG_CMD_RCGR, 1);
- msm_vibrator_write(vibrator, REG_CBCR, 1);
-
-unlock:
- mutex_unlock(&vibrator->mutex);
-
- return ret;
-}
-
-static void msm_vibrator_stop(struct msm_vibrator *vibrator)
-{
- mutex_lock(&vibrator->mutex);
-
- if (vibrator->enabled) {
- gpiod_set_value_cansleep(vibrator->enable_gpio, 0);
- regulator_disable(vibrator->vcc);
- clk_disable(vibrator->clk);
- vibrator->enabled = false;
- }
-
- mutex_unlock(&vibrator->mutex);
-}
-
-static void msm_vibrator_worker(struct work_struct *work)
-{
- struct msm_vibrator *vibrator = container_of(work,
- struct msm_vibrator,
- worker);
-
- if (vibrator->magnitude)
- msm_vibrator_start(vibrator);
- else
- msm_vibrator_stop(vibrator);
-}
-
-static int msm_vibrator_play_effect(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct msm_vibrator *vibrator = input_get_drvdata(dev);
-
- mutex_lock(&vibrator->mutex);
-
- if (effect->u.rumble.strong_magnitude > 0)
- vibrator->magnitude = effect->u.rumble.strong_magnitude;
- else
- vibrator->magnitude = effect->u.rumble.weak_magnitude;
-
- mutex_unlock(&vibrator->mutex);
-
- schedule_work(&vibrator->worker);
-
- return 0;
-}
-
-static void msm_vibrator_close(struct input_dev *input)
-{
- struct msm_vibrator *vibrator = input_get_drvdata(input);
-
- cancel_work_sync(&vibrator->worker);
- msm_vibrator_stop(vibrator);
-}
-
-static int msm_vibrator_probe(struct platform_device *pdev)
-{
- struct msm_vibrator *vibrator;
- struct resource *res;
- int ret;
-
- vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
- if (!vibrator)
- return -ENOMEM;
-
- vibrator->input = devm_input_allocate_device(&pdev->dev);
- if (!vibrator->input)
- return -ENOMEM;
-
- vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
- if (IS_ERR(vibrator->vcc)) {
- if (PTR_ERR(vibrator->vcc) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "Failed to get regulator: %ld\n",
- PTR_ERR(vibrator->vcc));
- return PTR_ERR(vibrator->vcc);
- }
-
- vibrator->enable_gpio = devm_gpiod_get(&pdev->dev, "enable",
- GPIOD_OUT_LOW);
- if (IS_ERR(vibrator->enable_gpio)) {
- if (PTR_ERR(vibrator->enable_gpio) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "Failed to get enable gpio: %ld\n",
- PTR_ERR(vibrator->enable_gpio));
- return PTR_ERR(vibrator->enable_gpio);
- }
-
- vibrator->clk = devm_clk_get(&pdev->dev, "pwm");
- if (IS_ERR(vibrator->clk)) {
- if (PTR_ERR(vibrator->clk) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "Failed to lookup pwm clock: %ld\n",
- PTR_ERR(vibrator->clk));
- return PTR_ERR(vibrator->clk);
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Failed to get platform resource\n");
- return -ENODEV;
- }
-
- vibrator->base = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!vibrator->base) {
- dev_err(&pdev->dev, "Failed to iomap resource.\n");
- return -ENOMEM;
- }
-
- vibrator->enabled = false;
- mutex_init(&vibrator->mutex);
- INIT_WORK(&vibrator->worker, msm_vibrator_worker);
-
- vibrator->input->name = "msm-vibrator";
- vibrator->input->id.bustype = BUS_HOST;
- vibrator->input->close = msm_vibrator_close;
-
- input_set_drvdata(vibrator->input, vibrator);
- input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
-
- ret = input_ff_create_memless(vibrator->input, NULL,
- msm_vibrator_play_effect);
- if (ret) {
- dev_err(&pdev->dev, "Failed to create ff memless: %d", ret);
- return ret;
- }
-
- ret = input_register_device(vibrator->input);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register input device: %d", ret);
- return ret;
- }
-
- platform_set_drvdata(pdev, vibrator);
-
- return 0;
-}
-
-static int __maybe_unused msm_vibrator_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
-
- cancel_work_sync(&vibrator->worker);
-
- if (vibrator->enabled)
- msm_vibrator_stop(vibrator);
-
- return 0;
-}
-
-static int __maybe_unused msm_vibrator_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
-
- if (vibrator->enabled)
- msm_vibrator_start(vibrator);
-
- return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(msm_vibrator_pm_ops, msm_vibrator_suspend,
- msm_vibrator_resume);
-
-static const struct of_device_id msm_vibrator_of_match[] = {
- { .compatible = "qcom,msm8226-vibrator" },
- { .compatible = "qcom,msm8974-vibrator" },
- {},
-};
-MODULE_DEVICE_TABLE(of, msm_vibrator_of_match);
-
-static struct platform_driver msm_vibrator_driver = {
- .probe = msm_vibrator_probe,
- .driver = {
- .name = "msm-vibrator",
- .pm = &msm_vibrator_pm_ops,
- .of_match_table = of_match_ptr(msm_vibrator_of_match),
- },
-};
-module_platform_driver(msm_vibrator_driver);
-
-MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
-MODULE_DESCRIPTION("Qualcomm MSM vibrator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 24bc5c5d876f..a1bba722b234 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -146,7 +146,7 @@ static void xenkbd_handle_mt_event(struct xenkbd_info *info,
break;
case XENKBD_MT_EV_UP:
- input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(info->mtouch);
break;
case XENKBD_MT_EV_SYN:
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 8719da540383..3f9354baac4b 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -938,7 +938,7 @@ static void elan_report_contact(struct elan_tp_data *data,
input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
} else {
input_mt_slot(input, contact_num);
- input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(input);
}
}
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index 373a1646019e..0754744b9ce5 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -223,7 +223,7 @@ config SERIO_AMS_DELTA
tristate "Amstrad Delta (E3) mailboard support"
depends on MACH_AMS_DELTA
default y
- ---help---
+ help
Say Y here if you have an E3 and want to use its mailboard,
or any standard AT keyboard connected to the mailboard port.
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 7e048b557462..7b08ff8ddf35 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -945,6 +945,7 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
}
i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
sizeof(i8042_kbd_firmware_id));
+ i8042_kbd_fwnode = dev_fwnode(&dev->dev);
/* Keyboard ports are always supposed to be wakeup-enabled */
device_set_wakeup_enable(&dev->dev, true);
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 20ff2bed3917..0dddf273afd9 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -21,6 +21,7 @@
#include <linux/i8042.h>
#include <linux/slab.h>
#include <linux/suspend.h>
+#include <linux/property.h>
#include <asm/io.h>
@@ -124,6 +125,7 @@ MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive da
static bool i8042_bypass_aux_irq_test;
static char i8042_kbd_firmware_id[128];
static char i8042_aux_firmware_id[128];
+static struct fwnode_handle *i8042_kbd_fwnode;
#include "i8042.h"
@@ -1335,6 +1337,7 @@ static int __init i8042_create_kbd_port(void)
strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
strlcpy(serio->firmware_id, i8042_kbd_firmware_id,
sizeof(serio->firmware_id));
+ set_primary_fwnode(&serio->dev, i8042_kbd_fwnode);
port->serio = serio;
port->irq = I8042_KBD_IRQ;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c071f7c407b6..35c867b2d9a7 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -201,6 +201,18 @@ config TOUCHSCREEN_CHIPONE_ICN8505
To compile this driver as a module, choose M here: the
module will be called chipone_icn8505.
+config TOUCHSCREEN_CY8CTMA140
+ tristate "cy8ctma140 touchscreen"
+ depends on I2C
+ help
+ Say Y here if you have a Cypress CY8CTMA140 capacitive
+ touchscreen also just known as "TMA140"
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cy8ctma140.
+
config TOUCHSCREEN_CY8CTMG110
tristate "cy8ctmg110 touchscreen"
depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 94c6162409b3..30d1e1b42492 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21029) += bu21029_ts.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8505) += chipone_icn8505.o
+obj-$(CONFIG_TOUCHSCREEN_CY8CTMA140) += cy8ctma140.o
obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o cyttsp_i2c_common.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ae60442efda0..a2189739e30f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -822,8 +822,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
* have happened.
*/
if (status & MXT_T9_RELEASE) {
- input_mt_report_slot_state(input_dev,
- MT_TOOL_FINGER, 0);
+ input_mt_report_slot_inactive(input_dev);
mxt_input_sync(data);
}
@@ -839,7 +838,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
} else {
/* Touch no longer active, close out slot */
- input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+ input_mt_report_slot_inactive(input_dev);
}
data->update_input = true;
@@ -947,7 +946,7 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message)
dev_dbg(dev, "[%u] release\n", id);
/* close out slot */
- input_mt_report_slot_state(input_dev, 0, 0);
+ input_mt_report_slot_inactive(input_dev);
}
data->update_input = true;
diff --git a/drivers/input/touchscreen/cy8ctma140.c b/drivers/input/touchscreen/cy8ctma140.c
new file mode 100644
index 000000000000..a9be29139cbf
--- /dev/null
+++ b/drivers/input/touchscreen/cy8ctma140.c
@@ -0,0 +1,353 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for Cypress CY8CTMA140 (TMA140) touchscreen
+ * (C) 2020 Linus Walleij <linus.walleij@linaro.org>
+ * (C) 2007 Cypress
+ * (C) 2007 Google, Inc.
+ *
+ * Inspired by the tma140_skomer.c driver in the Samsung GT-S7710 code
+ * drop. The GT-S7710 is codenamed "Skomer", the code also indicates
+ * that the same touchscreen was used in a product called "Lucas".
+ *
+ * The code drop for GT-S7710 also contains a firmware downloader and
+ * 15 (!) versions of the firmware drop from Cypress. But here we assume
+ * the firmware got downloaded to the touchscreen flash successfully and
+ * just use it to read the fingers. The shipped vendor driver does the
+ * same.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+
+#define CY8CTMA140_NAME "cy8ctma140"
+
+#define CY8CTMA140_MAX_FINGERS 4
+
+#define CY8CTMA140_GET_FINGERS 0x00
+#define CY8CTMA140_GET_FW_INFO 0x19
+
+/* This message also fits some bytes for touchkeys, if used */
+#define CY8CTMA140_PACKET_SIZE 31
+
+#define CY8CTMA140_INVALID_BUFFER_BIT 5
+
+struct cy8ctma140 {
+ struct input_dev *input;
+ struct touchscreen_properties props;
+ struct device *dev;
+ struct i2c_client *client;
+ struct regulator_bulk_data regulators[2];
+ u8 prev_fingers;
+ u8 prev_f1id;
+ u8 prev_f2id;
+};
+
+static void cy8ctma140_report(struct cy8ctma140 *ts, u8 *data, int n_fingers)
+{
+ static const u8 contact_offsets[] = { 0x03, 0x09, 0x10, 0x16 };
+ u8 *buf;
+ u16 x, y;
+ u8 w;
+ u8 id;
+ int slot;
+ int i;
+
+ for (i = 0; i < n_fingers; i++) {
+ buf = &data[contact_offsets[i]];
+
+ /*
+ * Odd contacts have contact ID in the lower nibble of
+ * the preceding byte, whereas even contacts have it in
+ * the upper nibble of the following byte.
+ */
+ id = i % 2 ? buf[-1] & 0x0f : buf[5] >> 4;
+ slot = input_mt_get_slot_by_key(ts->input, id);
+ if (slot < 0)
+ continue;
+
+ x = get_unaligned_be16(buf);
+ y = get_unaligned_be16(buf + 2);
+ w = buf[4];
+
+ dev_dbg(ts->dev, "finger %d: ID %02x (%d, %d) w: %d\n",
+ slot, id, x, y, w);
+
+ input_mt_slot(ts->input, slot);
+ input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
+ touchscreen_report_pos(ts->input, &ts->props, x, y, true);
+ input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, w);
+ }
+
+ input_mt_sync_frame(ts->input);
+ input_sync(ts->input);
+}
+
+static irqreturn_t cy8ctma140_irq_thread(int irq, void *d)
+{
+ struct cy8ctma140 *ts = d;
+ u8 cmdbuf[] = { CY8CTMA140_GET_FINGERS };
+ u8 buf[CY8CTMA140_PACKET_SIZE];
+ struct i2c_msg msg[] = {
+ {
+ .addr = ts->client->addr,
+ .flags = 0,
+ .len = sizeof(cmdbuf),
+ .buf = cmdbuf,
+ }, {
+ .addr = ts->client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(buf),
+ .buf = buf,
+ },
+ };
+ u8 n_fingers;
+ int ret;
+
+ ret = i2c_transfer(ts->client->adapter, msg, ARRAY_SIZE(msg));
+ if (ret != ARRAY_SIZE(msg)) {
+ if (ret < 0)
+ dev_err(ts->dev, "error reading message: %d\n", ret);
+ else
+ dev_err(ts->dev, "wrong number of messages\n");
+ goto out;
+ }
+
+ if (buf[1] & BIT(CY8CTMA140_INVALID_BUFFER_BIT)) {
+ dev_dbg(ts->dev, "invalid event\n");
+ goto out;
+ }
+
+ n_fingers = buf[2] & 0x0f;
+ if (n_fingers > CY8CTMA140_MAX_FINGERS) {
+ dev_err(ts->dev, "unexpected number of fingers: %d\n",
+ n_fingers);
+ goto out;
+ }
+
+ cy8ctma140_report(ts, buf, n_fingers);
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int cy8ctma140_init(struct cy8ctma140 *ts)
+{
+ u8 addr[1];
+ u8 buf[5];
+ int ret;
+
+ addr[0] = CY8CTMA140_GET_FW_INFO;
+ ret = i2c_master_send(ts->client, addr, 1);
+ if (ret < 0) {
+ dev_err(ts->dev, "error sending FW info message\n");
+ return ret;
+ }
+ ret = i2c_master_recv(ts->client, buf, 5);
+ if (ret < 0) {
+ dev_err(ts->dev, "error receiving FW info message\n");
+ return ret;
+ }
+ if (ret != 5) {
+ dev_err(ts->dev, "got only %d bytes\n", ret);
+ return -EIO;
+ }
+
+ dev_dbg(ts->dev, "vendor %c%c, HW ID %.2d, FW ver %.4d\n",
+ buf[0], buf[1], buf[3], buf[4]);
+
+ return 0;
+}
+
+static int cy8ctma140_power_up(struct cy8ctma140 *ts)
+{
+ int error;
+
+ error = regulator_bulk_enable(ARRAY_SIZE(ts->regulators),
+ ts->regulators);
+ if (error) {
+ dev_err(ts->dev, "failed to enable regulators\n");
+ return error;
+ }
+
+ msleep(250);
+
+ return 0;
+}
+
+static void cy8ctma140_power_down(struct cy8ctma140 *ts)
+{
+ regulator_bulk_disable(ARRAY_SIZE(ts->regulators),
+ ts->regulators);
+}
+
+/* Called from the registered devm action */
+static void cy8ctma140_power_off_action(void *d)
+{
+ struct cy8ctma140 *ts = d;
+
+ cy8ctma140_power_down(ts);
+}
+
+static int cy8ctma140_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct cy8ctma140 *ts;
+ struct input_dev *input;
+ struct device *dev = &client->dev;
+ int error;
+
+ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ input = devm_input_allocate_device(dev);
+ if (!input)
+ return -ENOMEM;
+
+ ts->dev = dev;
+ ts->client = client;
+ ts->input = input;
+
+ input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
+ input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
+ /* One byte for width 0..255 so this is the limit */
+ input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ /*
+ * This sets up event max/min capabilities and fuzz.
+ * Some DT properties are compulsory so we do not need
+ * to provide defaults for X/Y max or pressure max.
+ *
+ * We just initialize a very simple MT touchscreen here,
+ * some devices use the capability of this touchscreen to
+ * provide touchkeys, and in that case this needs to be
+ * extended to handle touchkey input.
+ *
+ * The firmware takes care of finger tracking and dropping
+ * invalid ranges.
+ */
+ touchscreen_parse_properties(input, true, &ts->props);
+ input_abs_set_fuzz(input, ABS_MT_POSITION_X, 0);
+ input_abs_set_fuzz(input, ABS_MT_POSITION_Y, 0);
+
+ error = input_mt_init_slots(input, CY8CTMA140_MAX_FINGERS,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+ if (error)
+ return error;
+
+ input->name = CY8CTMA140_NAME;
+ input->id.bustype = BUS_I2C;
+ input_set_drvdata(input, ts);
+
+ /*
+ * VCPIN is the analog voltage supply
+ * VDD is the digital voltage supply
+ * since the voltage range of VDD overlaps that of VCPIN,
+ * many designs to just supply both with a single voltage
+ * source of ~3.3 V.
+ */
+ ts->regulators[0].supply = "vcpin";
+ ts->regulators[1].supply = "vdd";
+ error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->regulators),
+ ts->regulators);
+ if (error) {
+ if (error != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get regulators %d\n",
+ error);
+ return error;
+ }
+
+ error = cy8ctma140_power_up(ts);
+ if (error)
+ return error;
+
+ error = devm_add_action_or_reset(dev, cy8ctma140_power_off_action, ts);
+ if (error) {
+ dev_err(dev, "failed to install power off handler\n");
+ return error;
+ }
+
+ error = devm_request_threaded_irq(dev, client->irq,
+ NULL, cy8ctma140_irq_thread,
+ IRQF_ONESHOT, CY8CTMA140_NAME, ts);
+ if (error) {
+ dev_err(dev, "irq %d busy? error %d\n", client->irq, error);
+ return error;
+ }
+
+ error = cy8ctma140_init(ts);
+ if (error)
+ return error;
+
+ error = input_register_device(input);
+ if (error)
+ return error;
+
+ i2c_set_clientdata(client, ts);
+
+ return 0;
+}
+
+static int __maybe_unused cy8ctma140_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cy8ctma140 *ts = i2c_get_clientdata(client);
+
+ if (!device_may_wakeup(&client->dev))
+ cy8ctma140_power_down(ts);
+
+ return 0;
+}
+
+static int __maybe_unused cy8ctma140_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cy8ctma140 *ts = i2c_get_clientdata(client);
+ int error;
+
+ if (!device_may_wakeup(&client->dev)) {
+ error = cy8ctma140_power_up(ts);
+ if (error)
+ return error;
+ }
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(cy8ctma140_pm, cy8ctma140_suspend, cy8ctma140_resume);
+
+static const struct i2c_device_id cy8ctma140_idtable[] = {
+ { CY8CTMA140_NAME, 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, cy8ctma140_idtable);
+
+static const struct of_device_id cy8ctma140_of_match[] = {
+ { .compatible = "cypress,cy8ctma140", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cy8ctma140_of_match);
+
+static struct i2c_driver cy8ctma140_driver = {
+ .driver = {
+ .name = CY8CTMA140_NAME,
+ .pm = &cy8ctma140_pm,
+ .of_match_table = cy8ctma140_of_match,
+ },
+ .id_table = cy8ctma140_idtable,
+ .probe = cy8ctma140_probe,
+};
+module_i2c_driver(cy8ctma140_driver);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("CY8CTMA140 TouchScreen Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c
index 6bcffc930384..02a73d9a4def 100644
--- a/drivers/input/touchscreen/cyttsp4_core.c
+++ b/drivers/input/touchscreen/cyttsp4_core.c
@@ -744,8 +744,7 @@ static void cyttsp4_report_slot_liftoff(struct cyttsp4_mt_data *md,
for (t = 0; t < max_slots; t++) {
input_mt_slot(md->input, t);
- input_mt_report_slot_state(md->input,
- MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(md->input);
}
}
@@ -845,7 +844,7 @@ static void cyttsp4_final_sync(struct input_dev *input, int max_slots, int *ids)
if (ids[t])
continue;
input_mt_slot(input, t);
- input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(input);
}
input_sync(input);
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 3f5d463dbeed..697aa2c158f7 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -340,7 +340,7 @@ static void cyttsp_report_tchdata(struct cyttsp *ts)
continue;
input_mt_slot(input, i);
- input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(input);
}
input_sync(input);
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index d2587724c52a..3a4f18d3450d 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -38,6 +38,9 @@
#define WORK_REGISTER_NUM_X 0x33
#define WORK_REGISTER_NUM_Y 0x34
+#define PMOD_REGISTER_ACTIVE 0x00
+#define PMOD_REGISTER_HIBERNATE 0x03
+
#define M09_REGISTER_THRESHOLD 0x80
#define M09_REGISTER_GAIN 0x92
#define M09_REGISTER_OFFSET 0x93
@@ -53,6 +56,7 @@
#define WORK_REGISTER_OPMODE 0x3c
#define FACTORY_REGISTER_OPMODE 0x01
+#define PMOD_REGISTER_OPMODE 0xa5
#define TOUCH_EVENT_DOWN 0x00
#define TOUCH_EVENT_UP 0x01
@@ -65,6 +69,12 @@
#define EDT_RAW_DATA_RETRIES 100
#define EDT_RAW_DATA_DELAY 1000 /* usec */
+enum edt_pmode {
+ EDT_PMODE_NOT_SUPPORTED,
+ EDT_PMODE_HIBERNATE,
+ EDT_PMODE_POWEROFF,
+};
+
enum edt_ver {
EDT_M06,
EDT_M09,
@@ -103,6 +113,7 @@ struct edt_ft5x06_ts_data {
struct mutex mutex;
bool factory_mode;
+ enum edt_pmode suspend_mode;
int threshold;
int gain;
int offset;
@@ -527,6 +538,29 @@ static const struct attribute_group edt_ft5x06_attr_group = {
.attrs = edt_ft5x06_attrs,
};
+static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata)
+{
+ struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
+ tsdata->threshold);
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
+ tsdata->gain);
+ if (reg_addr->reg_offset != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
+ tsdata->offset);
+ if (reg_addr->reg_offset_x != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x,
+ tsdata->offset_x);
+ if (reg_addr->reg_offset_y != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y,
+ tsdata->offset_y);
+ if (reg_addr->reg_report_rate != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
+ tsdata->report_rate);
+
+}
+
#ifdef CONFIG_DEBUG_FS
static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
{
@@ -592,7 +626,6 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
{
struct i2c_client *client = tsdata->client;
int retries = EDT_SWITCH_MODE_RETRIES;
- struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
int ret;
int error;
@@ -624,24 +657,7 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
kfree(tsdata->raw_buffer);
tsdata->raw_buffer = NULL;
- /* restore parameters */
- edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
- tsdata->threshold);
- edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
- tsdata->gain);
- if (reg_addr->reg_offset != NO_REGISTER)
- edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
- tsdata->offset);
- if (reg_addr->reg_offset_x != NO_REGISTER)
- edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x,
- tsdata->offset_x);
- if (reg_addr->reg_offset_y != NO_REGISTER)
- edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y,
- tsdata->offset_y);
- if (reg_addr->reg_report_rate != NO_REGISTER)
- edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
- tsdata->report_rate);
-
+ edt_ft5x06_restore_reg_parameters(tsdata);
enable_irq(client->irq);
return 0;
@@ -762,9 +778,8 @@ static const struct file_operations debugfs_raw_data_fops = {
.read = edt_ft5x06_debugfs_raw_data_read,
};
-static void
-edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
- const char *debugfs_name)
+static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
+ const char *debugfs_name)
{
tsdata->debug_dir = debugfs_create_dir(debugfs_name, NULL);
@@ -777,8 +792,7 @@ edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
tsdata->debug_dir, tsdata, &debugfs_raw_data_fops);
}
-static void
-edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
+static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
debugfs_remove_recursive(tsdata->debug_dir);
kfree(tsdata->raw_buffer);
@@ -786,14 +800,17 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
#else
-static inline void
-edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
- const char *debugfs_name)
+static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
+{
+ return -ENOSYS;
+}
+
+static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
+ const char *debugfs_name)
{
}
-static inline void
-edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
+static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
}
@@ -938,19 +955,25 @@ static void edt_ft5x06_ts_get_defaults(struct device *dev,
error = device_property_read_u32(dev, "offset", &val);
if (!error) {
- edt_ft5x06_register_write(tsdata, reg_addr->reg_offset, val);
+ if (reg_addr->reg_offset != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata,
+ reg_addr->reg_offset, val);
tsdata->offset = val;
}
error = device_property_read_u32(dev, "offset-x", &val);
if (!error) {
- edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x, val);
+ if (reg_addr->reg_offset_x != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata,
+ reg_addr->reg_offset_x, val);
tsdata->offset_x = val;
}
error = device_property_read_u32(dev, "offset-y", &val);
if (!error) {
- edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y, val);
+ if (reg_addr->reg_offset_y != NO_REGISTER)
+ edt_ft5x06_register_write(tsdata,
+ reg_addr->reg_offset_y, val);
tsdata->offset_y = val;
}
}
@@ -1114,6 +1137,19 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
return error;
}
+ /*
+ * Check which sleep modes we can support. Power-off requieres the
+ * reset-pin to ensure correct power-down/power-up behaviour. Start with
+ * the EDT_PMODE_POWEROFF test since this is the deepest possible sleep
+ * mode.
+ */
+ if (tsdata->reset_gpio)
+ tsdata->suspend_mode = EDT_PMODE_POWEROFF;
+ else if (tsdata->wake_gpio)
+ tsdata->suspend_mode = EDT_PMODE_HIBERNATE;
+ else
+ tsdata->suspend_mode = EDT_PMODE_NOT_SUPPORTED;
+
if (tsdata->wake_gpio) {
usleep_range(5000, 6000);
gpiod_set_value_cansleep(tsdata->wake_gpio, 1);
@@ -1227,6 +1263,102 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client)
return 0;
}
+static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+ struct gpio_desc *reset_gpio = tsdata->reset_gpio;
+ int ret;
+
+ if (device_may_wakeup(dev))
+ return 0;
+
+ if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED)
+ return 0;
+
+ /* Enter hibernate mode. */
+ ret = edt_ft5x06_register_write(tsdata, PMOD_REGISTER_OPMODE,
+ PMOD_REGISTER_HIBERNATE);
+ if (ret)
+ dev_warn(dev, "Failed to set hibernate mode\n");
+
+ if (tsdata->suspend_mode == EDT_PMODE_HIBERNATE)
+ return 0;
+
+ /*
+ * Power-off according the datasheet. Cut the power may leaf the irq
+ * line in an undefined state depending on the host pull resistor
+ * settings. Disable the irq to avoid adjusting each host till the
+ * device is back in a full functional state.
+ */
+ disable_irq(tsdata->client->irq);
+
+ gpiod_set_value_cansleep(reset_gpio, 1);
+ usleep_range(1000, 2000);
+
+ ret = regulator_disable(tsdata->vcc);
+ if (ret)
+ dev_warn(dev, "Failed to disable vcc\n");
+
+ return 0;
+}
+
+static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+ int ret = 0;
+
+ if (device_may_wakeup(dev))
+ return 0;
+
+ if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED)
+ return 0;
+
+ if (tsdata->suspend_mode == EDT_PMODE_POWEROFF) {
+ struct gpio_desc *reset_gpio = tsdata->reset_gpio;
+
+ /*
+ * We can't check if the regulator is a dummy or a real
+ * regulator. So we need to specify the 5ms reset time (T_rst)
+ * here instead of the 100us T_rtp time. We also need to wait
+ * 300ms in case it was a real supply and the power was cutted
+ * of. Toggle the reset pin is also a way to exit the hibernate
+ * mode.
+ */
+ gpiod_set_value_cansleep(reset_gpio, 1);
+ usleep_range(5000, 6000);
+
+ ret = regulator_enable(tsdata->vcc);
+ if (ret) {
+ dev_err(dev, "Failed to enable vcc\n");
+ return ret;
+ }
+
+ usleep_range(1000, 2000);
+ gpiod_set_value_cansleep(reset_gpio, 0);
+ msleep(300);
+
+ edt_ft5x06_restore_reg_parameters(tsdata);
+ enable_irq(tsdata->client->irq);
+
+ if (tsdata->factory_mode)
+ ret = edt_ft5x06_factory_mode(tsdata);
+ } else {
+ struct gpio_desc *wake_gpio = tsdata->wake_gpio;
+
+ gpiod_set_value_cansleep(wake_gpio, 0);
+ usleep_range(5000, 6000);
+ gpiod_set_value_cansleep(wake_gpio, 1);
+ }
+
+
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
+ edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
+
static const struct edt_i2c_chip_data edt_ft5x06_data = {
.max_support_points = 5,
};
@@ -1265,6 +1397,8 @@ static struct i2c_driver edt_ft5x06_ts_driver = {
.driver = {
.name = "edt_ft5x06",
.of_match_table = edt_ft5x06_of_match,
+ .pm = &edt_ft5x06_ts_pm_ops,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.id_table = edt_ft5x06_ts_id,
.probe = edt_ft5x06_ts_probe,
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 2289f9638116..233cb1085bbd 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
@@ -89,6 +90,7 @@
/* FW read command, 0x53 0x?? 0x0, 0x01 */
#define E_ELAN_INFO_FW_VER 0x00
#define E_ELAN_INFO_BC_VER 0x10
+#define E_ELAN_INFO_REK 0xE0
#define E_ELAN_INFO_TEST_VER 0xE0
#define E_ELAN_INFO_FW_ID 0xF0
#define E_INFO_OSR 0xD6
@@ -136,6 +138,7 @@ struct elants_data {
unsigned int y_res;
unsigned int x_max;
unsigned int y_max;
+ struct touchscreen_properties prop;
enum elants_state state;
enum elants_iap_mode iap_mode;
@@ -189,7 +192,8 @@ static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)
static int elants_i2c_execute_command(struct i2c_client *client,
const u8 *cmd, size_t cmd_size,
- u8 *resp, size_t resp_size)
+ u8 *resp, size_t resp_size,
+ int retries, const char *cmd_name)
{
struct i2c_msg msgs[2];
int ret;
@@ -209,30 +213,55 @@ static int elants_i2c_execute_command(struct i2c_client *client,
break;
default:
- dev_err(&client->dev, "%s: invalid command %*ph\n",
- __func__, (int)cmd_size, cmd);
+ dev_err(&client->dev, "(%s): invalid command: %*ph\n",
+ cmd_name, (int)cmd_size, cmd);
return -EINVAL;
}
- msgs[0].addr = client->addr;
- msgs[0].flags = client->flags & I2C_M_TEN;
- msgs[0].len = cmd_size;
- msgs[0].buf = (u8 *)cmd;
+ for (;;) {
+ msgs[0].addr = client->addr;
+ msgs[0].flags = client->flags & I2C_M_TEN;
+ msgs[0].len = cmd_size;
+ msgs[0].buf = (u8 *)cmd;
+
+ msgs[1].addr = client->addr;
+ msgs[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
+ msgs[1].flags |= I2C_M_RD;
+ msgs[1].len = resp_size;
+ msgs[1].buf = resp;
+
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0) {
+ if (--retries > 0) {
+ dev_dbg(&client->dev,
+ "(%s) I2C transfer failed: %pe (retrying)\n",
+ cmd_name, ERR_PTR(ret));
+ continue;
+ }
- msgs[1].addr = client->addr;
- msgs[1].flags = client->flags & I2C_M_TEN;
- msgs[1].flags |= I2C_M_RD;
- msgs[1].len = resp_size;
- msgs[1].buf = resp;
+ dev_err(&client->dev,
+ "(%s) I2C transfer failed: %pe\n",
+ cmd_name, ERR_PTR(ret));
+ return ret;
+ }
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret < 0)
- return ret;
+ if (ret != ARRAY_SIZE(msgs) ||
+ resp[FW_HDR_TYPE] != expected_response) {
+ if (--retries > 0) {
+ dev_dbg(&client->dev,
+ "(%s) unexpected response: %*ph (retrying)\n",
+ cmd_name, ret, resp);
+ continue;
+ }
- if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
- return -EIO;
+ dev_err(&client->dev,
+ "(%s) unexpected response: %*ph\n",
+ cmd_name, ret, resp);
+ return -EIO;
+ }
- return 0;
+ return 0;
+ }
}
static int elants_i2c_calibrate(struct elants_data *ts)
@@ -305,27 +334,21 @@ static u16 elants_i2c_parse_version(u8 *buf)
static int elants_i2c_query_hw_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- int error, retry_cnt;
+ int retry_cnt = MAX_RETRIES;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
+ int error;
- for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
+ while (retry_cnt--) {
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (!error) {
- ts->hw_version = elants_i2c_parse_version(resp);
- if (ts->hw_version != 0xffff)
- return 0;
- }
-
- dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
- }
+ resp, sizeof(resp), 1,
+ "read fw id");
+ if (error)
+ return error;
- if (error) {
- dev_err(&client->dev,
- "Failed to read fw id: %d\n", error);
- return error;
+ ts->hw_version = elants_i2c_parse_version(resp);
+ if (ts->hw_version != 0xffff)
+ return 0;
}
dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
@@ -336,26 +359,27 @@ static int elants_i2c_query_hw_version(struct elants_data *ts)
static int elants_i2c_query_fw_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- int error, retry_cnt;
+ int retry_cnt = MAX_RETRIES;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
+ int error;
- for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
+ while (retry_cnt--) {
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (!error) {
- ts->fw_version = elants_i2c_parse_version(resp);
- if (ts->fw_version != 0x0000 &&
- ts->fw_version != 0xffff)
- return 0;
- }
+ resp, sizeof(resp), 1,
+ "read fw version");
+ if (error)
+ return error;
+
+ ts->fw_version = elants_i2c_parse_version(resp);
+ if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
+ return 0;
- dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
+ dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
+ (int)sizeof(resp), resp);
}
- dev_err(&client->dev,
- "Failed to read fw version or fw version is invalid\n");
+ dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);
return -EINVAL;
}
@@ -363,30 +387,24 @@ static int elants_i2c_query_fw_version(struct elants_data *ts)
static int elants_i2c_query_test_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- int error, retry_cnt;
+ int error;
u16 version;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
- for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
- error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (!error) {
- version = elants_i2c_parse_version(resp);
- ts->test_version = version >> 8;
- ts->solution_version = version & 0xff;
-
- return 0;
- }
-
- dev_dbg(&client->dev,
- "read test version error rc=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
+ error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+ resp, sizeof(resp), MAX_RETRIES,
+ "read test version");
+ if (error) {
+ dev_err(&client->dev, "Failed to read test version\n");
+ return error;
}
- dev_err(&client->dev, "Failed to read test version\n");
+ version = elants_i2c_parse_version(resp);
+ ts->test_version = version >> 8;
+ ts->solution_version = version & 0xff;
- return -EINVAL;
+ return 0;
}
static int elants_i2c_query_bc_version(struct elants_data *ts)
@@ -398,13 +416,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
int error;
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev,
- "read BC version error=%d, buf=%*phC\n",
- error, (int)sizeof(resp), resp);
+ resp, sizeof(resp), 1,
+ "read BC version");
+ if (error)
return error;
- }
version = elants_i2c_parse_version(resp);
ts->bc_version = version >> 8;
@@ -436,12 +451,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
error = elants_i2c_execute_command(client,
get_resolution_cmd,
sizeof(get_resolution_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get resolution command failed: %d\n",
- error);
+ resp, sizeof(resp), 1,
+ "get resolution");
+ if (error)
return error;
- }
rows = resp[2] + resp[6] + resp[10];
cols = resp[3] + resp[7] + resp[11];
@@ -449,36 +462,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
/* Process mm_to_pixel information */
error = elants_i2c_execute_command(client,
get_osr_cmd, sizeof(get_osr_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get osr command failed: %d\n",
- error);
+ resp, sizeof(resp), 1, "get osr");
+ if (error)
return error;
- }
osr = resp[3];
error = elants_i2c_execute_command(client,
get_physical_scan_cmd,
sizeof(get_physical_scan_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get physical scan command failed: %d\n",
- error);
+ resp, sizeof(resp), 1,
+ "get physical scan");
+ if (error)
return error;
- }
phy_x = get_unaligned_be16(&resp[2]);
error = elants_i2c_execute_command(client,
get_physical_drive_cmd,
sizeof(get_physical_drive_cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "get physical drive command failed: %d\n",
- error);
+ resp, sizeof(resp), 1,
+ "get physical drive");
+ if (error)
return error;
- }
phy_y = get_unaligned_be16(&resp[2]);
@@ -633,11 +639,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,
/* Compare TS Remark ID and FW Remark ID */
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
- resp, sizeof(resp));
- if (error) {
- dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
+ resp, sizeof(resp),
+ 1, "read Remark ID");
+ if (error)
return error;
- }
ts_remark_id = get_unaligned_be16(&resp[3]);
@@ -875,8 +880,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
input_mt_slot(input, i);
input_mt_report_slot_state(input, tool_type, true);
- input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
+ touchscreen_report_pos(input, &ts->prop, x, y, true);
input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w);
@@ -1017,7 +1021,7 @@ out:
*/
static ssize_t calibrate_store(struct device *dev,
struct device_attribute *attr,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct elants_data *ts = i2c_get_clientdata(client);
@@ -1063,8 +1067,28 @@ static ssize_t show_iap_mode(struct device *dev,
"Normal" : "Recovery");
}
+static ssize_t show_calibration_count(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_REK, 0x00, 0x01 };
+ u8 resp[HEADER_SIZE];
+ u16 rek_count;
+ int error;
+
+ error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+ resp, sizeof(resp), 1,
+ "read ReK status");
+ if (error)
+ return sprintf(buf, "%d\n", error);
+
+ rek_count = get_unaligned_be16(&resp[2]);
+ return sprintf(buf, "0x%04x\n", rek_count);
+}
+
static DEVICE_ATTR_WO(calibrate);
static DEVICE_ATTR(iap_mode, S_IRUGO, show_iap_mode, NULL);
+static DEVICE_ATTR(calibration_count, S_IRUGO, show_calibration_count, NULL);
static DEVICE_ATTR(update_fw, S_IWUSR, NULL, write_update_fw);
struct elants_version_attribute {
@@ -1120,6 +1144,7 @@ static struct attribute *elants_attributes[] = {
&dev_attr_calibrate.attr,
&dev_attr_update_fw.attr,
&dev_attr_iap_mode.attr,
+ &dev_attr_calibration_count.attr,
&elants_ver_attr_fw_version.dattr.attr,
&elants_ver_attr_hw_version.dattr.attr,
@@ -1290,25 +1315,7 @@ static int elants_i2c_probe(struct i2c_client *client,
ts->input->name = "Elan Touchscreen";
ts->input->id.bustype = BUS_I2C;
- __set_bit(BTN_TOUCH, ts->input->keybit);
- __set_bit(EV_ABS, ts->input->evbit);
- __set_bit(EV_KEY, ts->input->evbit);
-
- /* Single touch input params setup */
- input_set_abs_params(ts->input, ABS_X, 0, ts->x_max, 0, 0);
- input_set_abs_params(ts->input, ABS_Y, 0, ts->y_max, 0, 0);
- input_set_abs_params(ts->input, ABS_PRESSURE, 0, 255, 0, 0);
- input_abs_set_res(ts->input, ABS_X, ts->x_res);
- input_abs_set_res(ts->input, ABS_Y, ts->y_res);
-
/* Multitouch input params setup */
- error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
- INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
- if (error) {
- dev_err(&client->dev,
- "failed to initialize MT slots: %d\n", error);
- return error;
- }
input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0);
input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
@@ -1320,6 +1327,16 @@ static int elants_i2c_probe(struct i2c_client *client,
input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);
+ touchscreen_parse_properties(ts->input, true, &ts->prop);
+
+ error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+ if (error) {
+ dev_err(&client->dev,
+ "failed to initialize MT slots: %d\n", error);
+ return error;
+ }
+
error = input_register_device(ts->input);
if (error) {
dev_err(&client->dev,
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 247c3aaba2d8..f67efdd040b2 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -391,7 +391,7 @@ static void mip4_clear_input(struct mip4_ts *ts)
/* Screen */
for (i = 0; i < MIP4_MAX_FINGERS; i++) {
input_mt_slot(ts->input, i);
- input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, 0);
+ input_mt_report_slot_inactive(ts->input);
}
/* Keys */
@@ -534,7 +534,7 @@ static void mip4_report_touch(struct mip4_ts *ts, u8 *packet)
} else {
/* Release event */
input_mt_slot(ts->input, id);
- input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, 0);
+ input_mt_report_slot_inactive(ts->input);
}
input_mt_sync_frame(ts->input);
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 2ef1adaed9af..1f96657310b7 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -54,6 +54,7 @@
enum mms_type {
TYPE_MMS114 = 114,
TYPE_MMS152 = 152,
+ TYPE_MMS345L = 345,
};
struct mms114_data {
@@ -250,6 +251,15 @@ static int mms114_get_version(struct mms114_data *data)
int error;
switch (data->type) {
+ case TYPE_MMS345L:
+ error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
+ if (error)
+ return error;
+
+ dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n",
+ buf[0], buf[1], buf[2]);
+ break;
+
case TYPE_MMS152:
error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
if (error)
@@ -287,8 +297,8 @@ static int mms114_setup_regs(struct mms114_data *data)
if (error < 0)
return error;
- /* MMS152 has no configuration or power on registers */
- if (data->type == TYPE_MMS152)
+ /* Only MMS114 has configuration and power on registers */
+ if (data->type != TYPE_MMS114)
return 0;
error = mms114_set_active(data, true);
@@ -547,7 +557,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
/* Release all touch */
for (id = 0; id < MMS114_MAX_TOUCH; id++) {
input_mt_slot(input_dev, id);
- input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(input_dev);
}
input_mt_report_pointer_emulation(input_dev, true);
@@ -597,6 +607,9 @@ static const struct of_device_id mms114_dt_match[] = {
}, {
.compatible = "melfas,mms152",
.data = (void *)TYPE_MMS152,
+ }, {
+ .compatible = "melfas,mms345l",
+ .data = (void *)TYPE_MMS345L,
},
{ }
};
diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c
index 0e2e08f3f433..ef6aaed217cf 100644
--- a/drivers/input/touchscreen/raspberrypi-ts.c
+++ b/drivers/input/touchscreen/raspberrypi-ts.c
@@ -100,7 +100,7 @@ static void rpi_ts_poll(struct input_dev *input)
released_ids = ts->known_ids & ~modified_ids;
for_each_set_bit(i, &released_ids, RPI_TS_MAX_SUPPORTED_POINTS) {
input_mt_slot(input, i);
- input_mt_report_slot_state(input, MT_TOOL_FINGER, 0);
+ input_mt_report_slot_inactive(input);
modified_ids &= ~(BIT(i));
}
ts->known_ids = modified_ids;
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index b6f95f20f924..b54cc64e4ea6 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -198,7 +198,7 @@ static void stmfts_report_contact_release(struct stmfts_data *sdata,
u8 slot_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
input_mt_slot(sdata->input, slot_id);
- input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(sdata->input);
input_sync(sdata->input);
}
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index ece2a579a9b0..e5f998744501 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -544,6 +544,24 @@ void icc_set_tag(struct icc_path *path, u32 tag)
EXPORT_SYMBOL_GPL(icc_set_tag);
/**
+ * icc_get_name() - Get name of the icc path
+ * @path: reference to the path returned by icc_get()
+ *
+ * This function is used by an interconnect consumer to get the name of the icc
+ * path.
+ *
+ * Returns a valid pointer on success, or NULL otherwise.
+ */
+const char *icc_get_name(struct icc_path *path)
+{
+ if (!path)
+ return NULL;
+
+ return path->name;
+}
+EXPORT_SYMBOL_GPL(icc_get_name);
+
+/**
* icc_set_bw() - set bandwidth constraints on an interconnect path
* @path: reference to the path returned by icc_get()
* @avg_bw: average bandwidth in kilobytes per second
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 2ab07ce17abb..b510f67dfa49 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -15,7 +15,7 @@ menuconfig IOMMU_SUPPORT
bool "IOMMU Hardware Support"
depends on MMU
default y
- ---help---
+ help
Say Y here if you want to compile device drivers for IO Memory
Management Units into the kernel. These devices usually allow to
remap DMA requests and/or remap interrupts from other devices on the
@@ -144,7 +144,7 @@ config AMD_IOMMU
select IOMMU_IOVA
select IOMMU_DMA
depends on X86_64 && PCI && ACPI
- ---help---
+ help
With this option you can enable support for AMD IOMMU hardware in
your system. An IOMMU is a hardware component which provides
remapping of DMA memory accesses from devices. With an AMD IOMMU you
@@ -159,7 +159,7 @@ config AMD_IOMMU_V2
tristate "AMD IOMMU Version 2 driver"
depends on AMD_IOMMU
select MMU_NOTIFIER
- ---help---
+ help
This option enables support for the AMD IOMMUv2 features of the IOMMU
hardware. Select this option if you want to use devices that support
the PCI PRI and PASID interface.
@@ -167,7 +167,7 @@ config AMD_IOMMU_V2
config AMD_IOMMU_DEBUGFS
bool "Enable AMD IOMMU internals in DebugFS"
depends on AMD_IOMMU && IOMMU_DEBUGFS
- ---help---
+ help
!!!WARNING!!! !!!WARNING!!! !!!WARNING!!! !!!WARNING!!!
DO NOT ENABLE THIS OPTION UNLESS YOU REALLY, -REALLY- KNOW WHAT YOU ARE DOING!!!
@@ -233,7 +233,7 @@ config INTEL_IOMMU_DEFAULT_ON
config INTEL_IOMMU_BROKEN_GFX_WA
bool "Workaround broken graphics drivers (going away soon)"
depends on INTEL_IOMMU && BROKEN && X86
- ---help---
+ help
Current Graphics drivers tend to use physical address
for DMA and avoid using DMA APIs. Setting this config
option permits the IOMMU driver to set a unity map for
@@ -244,7 +244,7 @@ config INTEL_IOMMU_BROKEN_GFX_WA
config INTEL_IOMMU_FLOPPY_WA
def_bool y
depends on INTEL_IOMMU && X86
- ---help---
+ help
Floppy disk drivers are known to bypass DMA API calls
thereby failing to work when IOMMU is enabled. This
workaround will setup a 1:1 mapping for the first
@@ -266,7 +266,7 @@ config IRQ_REMAP
bool "Support for Interrupt Remapping"
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI
select DMAR_TABLE
- ---help---
+ help
Supports Interrupt remapping for IO-APIC and MSI devices.
To use x2apic mode in the CPU's which support x2APIC enhancements or
to support platforms with CPU's having > 8 bit APIC ID, say Y.
@@ -277,14 +277,14 @@ config OMAP_IOMMU
depends on ARM && MMU || (COMPILE_TEST && (ARM || ARM64 || IA64 || SPARC))
depends on ARCH_OMAP2PLUS || COMPILE_TEST
select IOMMU_API
- ---help---
+ help
The OMAP3 media platform drivers depend on iommu support,
if you need them say Y here.
config OMAP_IOMMU_DEBUG
bool "Export OMAP IOMMU internals in DebugFS"
depends on OMAP_IOMMU && DEBUG_FS
- ---help---
+ help
Select this to see extensive information about
the internal state of OMAP IOMMU in debugfs.
@@ -303,6 +303,15 @@ config ROCKCHIP_IOMMU
Say Y here if you are using a Rockchip SoC that includes an IOMMU
device.
+config SUN50I_IOMMU
+ bool "Allwinner H6 IOMMU Support"
+ depends on ARCH_SUNXI || COMPILE_TEST
+ select ARM_DMA_USE_IOMMU
+ select IOMMU_API
+ select IOMMU_DMA
+ help
+ Support for the IOMMU introduced in the Allwinner H6 SoCs.
+
config TEGRA_IOMMU_GART
bool "Tegra GART IOMMU Support"
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 9f33fdb3bb05..342190196dfb 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,24 +11,25 @@ obj-$(CONFIG_IOASID) += ioasid.o
obj-$(CONFIG_IOMMU_IOVA) += iova.o
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
-obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
-obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
-obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
+obj-$(CONFIG_AMD_IOMMU) += amd/iommu.o amd/init.o amd/quirks.o
+obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd/debugfs.o
+obj-$(CONFIG_AMD_IOMMU_V2) += amd/iommu_v2.o
obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
-obj-$(CONFIG_DMAR_TABLE) += dmar.o
-obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
-obj-$(CONFIG_INTEL_IOMMU) += intel-trace.o
-obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += intel-iommu-debugfs.o
-obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
+obj-$(CONFIG_DMAR_TABLE) += intel/dmar.o
+obj-$(CONFIG_INTEL_IOMMU) += intel/iommu.o intel/pasid.o
+obj-$(CONFIG_INTEL_IOMMU) += intel/trace.o
+obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += intel/debugfs.o
+obj-$(CONFIG_INTEL_IOMMU_SVM) += intel/svm.o
obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
-obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
+obj-$(CONFIG_IRQ_REMAP) += intel/irq_remapping.o irq_remapping.o
obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o
obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
+obj-$(CONFIG_SUN50I_IOMMU) += sun50i-iommu.o
obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd/amd_iommu.h
index 92c2ba6468a0..f892992c8744 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -4,8 +4,10 @@
* Author: Joerg Roedel <jroedel@suse.de>
*/
-#ifndef _ASM_X86_AMD_IOMMU_PROTO_H
-#define _ASM_X86_AMD_IOMMU_PROTO_H
+#ifndef AMD_IOMMU_H
+#define AMD_IOMMU_H
+
+#include <linux/iommu.h>
#include "amd_iommu_types.h"
@@ -92,5 +94,15 @@ static inline void *iommu_phys_to_virt(unsigned long paddr)
}
extern bool translation_pre_enabled(struct amd_iommu *iommu);
-extern struct iommu_dev_data *get_dev_data(struct device *dev);
-#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
+extern bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
+ struct device *dev);
+extern int __init add_special_device(u8 type, u8 id, u16 *devid,
+ bool cmd_line);
+
+#ifdef CONFIG_DMI
+void amd_iommu_apply_ivrs_quirks(void);
+#else
+static void amd_iommu_apply_ivrs_quirks(void) { }
+#endif
+
+#endif
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 7a8fdec138bd..30a5d412255a 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -395,10 +395,10 @@
#define PD_IOMMUV2_MASK (1UL << 3) /* domain has gcr3 table */
extern bool amd_iommu_dump;
-#define DUMP_printk(format, arg...) \
- do { \
- if (amd_iommu_dump) \
- printk(KERN_INFO "AMD-Vi: " format, ## arg); \
+#define DUMP_printk(format, arg...) \
+ do { \
+ if (amd_iommu_dump) \
+ pr_info("AMD-Vi: " format, ## arg); \
} while(0);
/* global flag if IOMMUs cache non-present entries */
@@ -645,7 +645,6 @@ struct iommu_dev_data {
struct pci_dev *pdev;
u16 devid; /* PCI Device ID */
bool iommu_v2; /* Device can make use of IOMMUv2 */
- bool passthrough; /* Device is identity mapped */
struct {
bool enabled;
int qdep;
diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd/debugfs.c
index c6a5c737ef09..545372fcc72f 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd/debugfs.c
@@ -8,10 +8,9 @@
*/
#include <linux/debugfs.h>
-#include <linux/iommu.h>
#include <linux/pci.h>
-#include "amd_iommu_proto.h"
-#include "amd_iommu_types.h"
+
+#include "amd_iommu.h"
static struct dentry *amd_iommu_debugfs;
static DEFINE_MUTEX(amd_iommu_debugfs_lock);
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd/init.c
index 5b81fd16f5fa..6ebd4825e320 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd/init.c
@@ -18,7 +18,6 @@
#include <linux/msi.h>
#include <linux/amd-iommu.h>
#include <linux/export.h>
-#include <linux/iommu.h>
#include <linux/kmemleak.h>
#include <linux/mem_encrypt.h>
#include <asm/pci-direct.h>
@@ -32,10 +31,9 @@
#include <asm/irq_remapping.h>
#include <linux/crash_dump.h>
+
#include "amd_iommu.h"
-#include "amd_iommu_proto.h"
-#include "amd_iommu_types.h"
-#include "irq_remapping.h"
+#include "../irq_remapping.h"
/*
* definitions for the ACPI scanning code
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd/iommu.c
index 2883ac389abb..74cca1757172 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -22,7 +22,6 @@
#include <linux/dma-direct.h>
#include <linux/dma-iommu.h>
#include <linux/iommu-helper.h>
-#include <linux/iommu.h>
#include <linux/delay.h>
#include <linux/amd-iommu.h>
#include <linux/notifier.h>
@@ -43,9 +42,8 @@
#include <asm/gart.h>
#include <asm/dma.h>
-#include "amd_iommu_proto.h"
-#include "amd_iommu_types.h"
-#include "irq_remapping.h"
+#include "amd_iommu.h"
+#include "../irq_remapping.h"
#define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
@@ -71,6 +69,8 @@
*/
#define AMD_IOMMU_PGSIZES ((~0xFFFUL) & ~(2ULL << 38))
+#define DEFAULT_PGTABLE_LEVEL PAGE_MODE_3_LEVEL
+
static DEFINE_SPINLOCK(pd_bitmap_lock);
/* List of all available dev_data structures */
@@ -99,7 +99,6 @@ struct iommu_cmd {
struct kmem_cache *amd_iommu_irq_cache;
static void update_domain(struct protection_domain *domain);
-static int protection_domain_init(struct protection_domain *domain);
static void detach_device(struct device *dev);
static void update_and_flush_device_table(struct protection_domain *domain,
struct domain_pgtable *pgtable);
@@ -280,12 +279,6 @@ static struct iommu_dev_data *find_dev_data(u16 devid)
return dev_data;
}
-struct iommu_dev_data *get_dev_data(struct device *dev)
-{
- return dev->archdata.iommu;
-}
-EXPORT_SYMBOL(get_dev_data);
-
/*
* Find or create an IOMMU group for a acpihid device.
*/
@@ -314,16 +307,15 @@ static struct iommu_group *acpihid_device_group(struct device *dev)
static bool pci_iommuv2_capable(struct pci_dev *pdev)
{
static const int caps[] = {
- PCI_EXT_CAP_ID_ATS,
PCI_EXT_CAP_ID_PRI,
PCI_EXT_CAP_ID_PASID,
};
int i, pos;
- if (pci_ats_disabled())
+ if (!pci_ats_supported(pdev))
return false;
- for (i = 0; i < 3; ++i) {
+ for (i = 0; i < 2; ++i) {
pos = pci_find_ext_capability(pdev, caps[i]);
if (pos == 0)
return false;
@@ -336,7 +328,7 @@ static bool pdev_pri_erratum(struct pci_dev *pdev, u32 erratum)
{
struct iommu_dev_data *dev_data;
- dev_data = get_dev_data(&pdev->dev);
+ dev_data = dev_iommu_priv_get(&pdev->dev);
return dev_data->errata & (1 << erratum) ? true : false;
}
@@ -349,7 +341,7 @@ static bool check_device(struct device *dev)
{
int devid;
- if (!dev || !dev->dma_mask)
+ if (!dev)
return false;
devid = get_device_id(dev);
@@ -366,32 +358,18 @@ static bool check_device(struct device *dev)
return true;
}
-static void init_iommu_group(struct device *dev)
-{
- struct iommu_group *group;
-
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return;
-
- iommu_group_put(group);
-}
-
static int iommu_init_device(struct device *dev)
{
struct iommu_dev_data *dev_data;
- struct amd_iommu *iommu;
int devid;
- if (dev->archdata.iommu)
+ if (dev_iommu_priv_get(dev))
return 0;
devid = get_device_id(dev);
if (devid < 0)
return devid;
- iommu = amd_iommu_rlookup_table[devid];
-
dev_data = find_dev_data(devid);
if (!dev_data)
return -ENOMEM;
@@ -412,9 +390,7 @@ static int iommu_init_device(struct device *dev)
dev_data->iommu_v2 = iommu->is_iommu_v2;
}
- dev->archdata.iommu = dev_data;
-
- iommu_device_link(&iommu->iommu, dev);
+ dev_iommu_priv_set(dev, dev_data);
return 0;
}
@@ -433,31 +409,18 @@ static void iommu_ignore_device(struct device *dev)
setup_aliases(dev);
}
-static void iommu_uninit_device(struct device *dev)
+static void amd_iommu_uninit_device(struct device *dev)
{
struct iommu_dev_data *dev_data;
- struct amd_iommu *iommu;
- int devid;
- devid = get_device_id(dev);
- if (devid < 0)
- return;
-
- iommu = amd_iommu_rlookup_table[devid];
-
- dev_data = search_dev_data(devid);
+ dev_data = dev_iommu_priv_get(dev);
if (!dev_data)
return;
if (dev_data->domain)
detach_device(dev);
- iommu_device_unlink(&iommu->iommu, dev);
-
- iommu_group_remove_device(dev);
-
- /* Remove dma-ops */
- dev->dma_ops = NULL;
+ dev_iommu_priv_set(dev, NULL);
/*
* We keep dev_data around for unplugged devices and reuse it when the
@@ -521,7 +484,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
devid & 0xff);
if (pdev)
- dev_data = get_dev_data(&pdev->dev);
+ dev_data = dev_iommu_priv_get(&pdev->dev);
if (dev_data && __ratelimit(&dev_data->rs)) {
pci_err(pdev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n",
@@ -1418,20 +1381,19 @@ static struct page *free_sub_pt(unsigned long root, int mode,
return freelist;
}
-static void free_pagetable(struct protection_domain *domain)
+static void free_pagetable(struct domain_pgtable *pgtable)
{
- struct domain_pgtable pgtable;
struct page *freelist = NULL;
unsigned long root;
- amd_iommu_domain_get_pgtable(domain, &pgtable);
- atomic64_set(&domain->pt_root, 0);
+ if (pgtable->mode == PAGE_MODE_NONE)
+ return;
- BUG_ON(pgtable.mode < PAGE_MODE_NONE ||
- pgtable.mode > PAGE_MODE_6_LEVEL);
+ BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
+ pgtable->mode > PAGE_MODE_6_LEVEL);
- root = (unsigned long)pgtable.root;
- freelist = free_sub_pt(root, pgtable.mode, freelist);
+ root = (unsigned long)pgtable->root;
+ freelist = free_sub_pt(root, pgtable->mode, freelist);
free_page_list(freelist);
}
@@ -1844,70 +1806,6 @@ static void free_gcr3_table(struct protection_domain *domain)
free_page((unsigned long)domain->gcr3_tbl);
}
-/*
- * Free a domain, only used if something went wrong in the
- * allocation path and we need to free an already allocated page table
- */
-static void dma_ops_domain_free(struct protection_domain *domain)
-{
- if (!domain)
- return;
-
- iommu_put_dma_cookie(&domain->domain);
-
- free_pagetable(domain);
-
- if (domain->id)
- domain_id_free(domain->id);
-
- kfree(domain);
-}
-
-/*
- * Allocates a new protection domain usable for the dma_ops functions.
- * It also initializes the page table and the address allocator data
- * structures required for the dma_ops interface
- */
-static struct protection_domain *dma_ops_domain_alloc(void)
-{
- struct protection_domain *domain;
- u64 *pt_root, root;
-
- domain = kzalloc(sizeof(struct protection_domain), GFP_KERNEL);
- if (!domain)
- return NULL;
-
- if (protection_domain_init(domain))
- goto free_domain;
-
- pt_root = (void *)get_zeroed_page(GFP_KERNEL);
- if (!pt_root)
- goto free_domain;
-
- root = amd_iommu_domain_encode_pgtable(pt_root, PAGE_MODE_3_LEVEL);
- atomic64_set(&domain->pt_root, root);
- domain->flags = PD_DMA_OPS_MASK;
-
- if (iommu_get_dma_cookie(&domain->domain) == -ENOMEM)
- goto free_domain;
-
- return domain;
-
-free_domain:
- dma_ops_domain_free(domain);
-
- return NULL;
-}
-
-/*
- * little helper function to check whether a given protection domain is a
- * dma_ops domain
- */
-static bool dma_ops_domain(struct protection_domain *domain)
-{
- return domain->flags & PD_DMA_OPS_MASK;
-}
-
static void set_dte_entry(u16 devid, struct protection_domain *domain,
struct domain_pgtable *pgtable,
bool ats, bool ppr)
@@ -2119,14 +2017,14 @@ out_err:
static int attach_device(struct device *dev,
struct protection_domain *domain)
{
- struct pci_dev *pdev;
struct iommu_dev_data *dev_data;
+ struct pci_dev *pdev;
unsigned long flags;
int ret;
spin_lock_irqsave(&domain->lock, flags);
- dev_data = get_dev_data(dev);
+ dev_data = dev_iommu_priv_get(dev);
spin_lock(&dev_data->lock);
@@ -2139,8 +2037,10 @@ static int attach_device(struct device *dev,
pdev = to_pci_dev(dev);
if (domain->flags & PD_IOMMUV2_MASK) {
+ struct iommu_domain *def_domain = iommu_get_dma_domain(dev);
+
ret = -EINVAL;
- if (!dev_data->passthrough)
+ if (def_domain->type != IOMMU_DOMAIN_IDENTITY)
goto out;
if (dev_data->iommu_v2) {
@@ -2188,7 +2088,7 @@ static void detach_device(struct device *dev)
struct iommu_dev_data *dev_data;
unsigned long flags;
- dev_data = get_dev_data(dev);
+ dev_data = dev_iommu_priv_get(dev);
domain = dev_data->domain;
spin_lock_irqsave(&domain->lock, flags);
@@ -2222,68 +2122,60 @@ out:
spin_unlock_irqrestore(&domain->lock, flags);
}
-static int amd_iommu_add_device(struct device *dev)
+static struct iommu_device *amd_iommu_probe_device(struct device *dev)
{
- struct iommu_dev_data *dev_data;
- struct iommu_domain *domain;
+ struct iommu_device *iommu_dev;
struct amd_iommu *iommu;
int ret, devid;
- if (!check_device(dev) || get_dev_data(dev))
- return 0;
+ if (!check_device(dev))
+ return ERR_PTR(-ENODEV);
devid = get_device_id(dev);
if (devid < 0)
- return devid;
+ return ERR_PTR(devid);
iommu = amd_iommu_rlookup_table[devid];
+ if (dev_iommu_priv_get(dev))
+ return &iommu->iommu;
+
ret = iommu_init_device(dev);
if (ret) {
if (ret != -ENOTSUPP)
dev_err(dev, "Failed to initialize - trying to proceed anyway\n");
-
+ iommu_dev = ERR_PTR(ret);
iommu_ignore_device(dev);
- dev->dma_ops = NULL;
- goto out;
+ } else {
+ iommu_dev = &iommu->iommu;
}
- init_iommu_group(dev);
- dev_data = get_dev_data(dev);
+ iommu_completion_wait(iommu);
- BUG_ON(!dev_data);
+ return iommu_dev;
+}
- if (dev_data->iommu_v2)
- iommu_request_dm_for_dev(dev);
+static void amd_iommu_probe_finalize(struct device *dev)
+{
+ struct iommu_domain *domain;
/* Domains are initialized for this device - have a look what we ended up with */
domain = iommu_get_domain_for_dev(dev);
- if (domain->type == IOMMU_DOMAIN_IDENTITY)
- dev_data->passthrough = true;
- else if (domain->type == IOMMU_DOMAIN_DMA)
+ if (domain->type == IOMMU_DOMAIN_DMA)
iommu_setup_dma_ops(dev, IOVA_START_PFN << PAGE_SHIFT, 0);
-
-out:
- iommu_completion_wait(iommu);
-
- return 0;
}
-static void amd_iommu_remove_device(struct device *dev)
+static void amd_iommu_release_device(struct device *dev)
{
+ int devid = get_device_id(dev);
struct amd_iommu *iommu;
- int devid;
if (!check_device(dev))
return;
- devid = get_device_id(dev);
- if (devid < 0)
- return;
-
iommu = amd_iommu_rlookup_table[devid];
- iommu_uninit_device(dev);
+ amd_iommu_uninit_device(dev);
iommu_completion_wait(iommu);
}
@@ -2418,27 +2310,46 @@ static void cleanup_domain(struct protection_domain *domain)
static void protection_domain_free(struct protection_domain *domain)
{
+ struct domain_pgtable pgtable;
+
if (!domain)
return;
if (domain->id)
domain_id_free(domain->id);
+ amd_iommu_domain_get_pgtable(domain, &pgtable);
+ atomic64_set(&domain->pt_root, 0);
+ free_pagetable(&pgtable);
+
kfree(domain);
}
-static int protection_domain_init(struct protection_domain *domain)
+static int protection_domain_init(struct protection_domain *domain, int mode)
{
+ u64 *pt_root = NULL, root;
+
+ BUG_ON(mode < PAGE_MODE_NONE || mode > PAGE_MODE_6_LEVEL);
+
spin_lock_init(&domain->lock);
domain->id = domain_id_alloc();
if (!domain->id)
return -ENOMEM;
INIT_LIST_HEAD(&domain->dev_list);
+ if (mode != PAGE_MODE_NONE) {
+ pt_root = (void *)get_zeroed_page(GFP_KERNEL);
+ if (!pt_root)
+ return -ENOMEM;
+ }
+
+ root = amd_iommu_domain_encode_pgtable(pt_root, mode);
+ atomic64_set(&domain->pt_root, root);
+
return 0;
}
-static struct protection_domain *protection_domain_alloc(void)
+static struct protection_domain *protection_domain_alloc(int mode)
{
struct protection_domain *domain;
@@ -2446,7 +2357,7 @@ static struct protection_domain *protection_domain_alloc(void)
if (!domain)
return NULL;
- if (protection_domain_init(domain))
+ if (protection_domain_init(domain, mode))
goto out_err;
return domain;
@@ -2459,54 +2370,35 @@ out_err:
static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
{
- struct protection_domain *pdomain;
- u64 *pt_root, root;
+ struct protection_domain *domain;
+ int mode = DEFAULT_PGTABLE_LEVEL;
- switch (type) {
- case IOMMU_DOMAIN_UNMANAGED:
- pdomain = protection_domain_alloc();
- if (!pdomain)
- return NULL;
+ if (type == IOMMU_DOMAIN_IDENTITY)
+ mode = PAGE_MODE_NONE;
- pt_root = (void *)get_zeroed_page(GFP_KERNEL);
- if (!pt_root) {
- protection_domain_free(pdomain);
- return NULL;
- }
+ domain = protection_domain_alloc(mode);
+ if (!domain)
+ return NULL;
- root = amd_iommu_domain_encode_pgtable(pt_root, PAGE_MODE_3_LEVEL);
- atomic64_set(&pdomain->pt_root, root);
+ domain->domain.geometry.aperture_start = 0;
+ domain->domain.geometry.aperture_end = ~0ULL;
+ domain->domain.geometry.force_aperture = true;
- pdomain->domain.geometry.aperture_start = 0;
- pdomain->domain.geometry.aperture_end = ~0ULL;
- pdomain->domain.geometry.force_aperture = true;
+ if (type == IOMMU_DOMAIN_DMA &&
+ iommu_get_dma_cookie(&domain->domain) == -ENOMEM)
+ goto free_domain;
- break;
- case IOMMU_DOMAIN_DMA:
- pdomain = dma_ops_domain_alloc();
- if (!pdomain) {
- pr_err("Failed to allocate\n");
- return NULL;
- }
- break;
- case IOMMU_DOMAIN_IDENTITY:
- pdomain = protection_domain_alloc();
- if (!pdomain)
- return NULL;
+ return &domain->domain;
- atomic64_set(&pdomain->pt_root, PAGE_MODE_NONE);
- break;
- default:
- return NULL;
- }
+free_domain:
+ protection_domain_free(domain);
- return &pdomain->domain;
+ return NULL;
}
static void amd_iommu_domain_free(struct iommu_domain *dom)
{
struct protection_domain *domain;
- struct domain_pgtable pgtable;
domain = to_pdomain(dom);
@@ -2518,29 +2410,19 @@ static void amd_iommu_domain_free(struct iommu_domain *dom)
if (!dom)
return;
- switch (dom->type) {
- case IOMMU_DOMAIN_DMA:
- /* Now release the domain */
- dma_ops_domain_free(domain);
- break;
- default:
- amd_iommu_domain_get_pgtable(domain, &pgtable);
-
- if (pgtable.mode != PAGE_MODE_NONE)
- free_pagetable(domain);
+ if (dom->type == IOMMU_DOMAIN_DMA)
+ iommu_put_dma_cookie(&domain->domain);
- if (domain->flags & PD_IOMMUV2_MASK)
- free_gcr3_table(domain);
+ if (domain->flags & PD_IOMMUV2_MASK)
+ free_gcr3_table(domain);
- protection_domain_free(domain);
- break;
- }
+ protection_domain_free(domain);
}
static void amd_iommu_detach_device(struct iommu_domain *dom,
struct device *dev)
{
- struct iommu_dev_data *dev_data = dev->archdata.iommu;
+ struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
struct amd_iommu *iommu;
int devid;
@@ -2578,7 +2460,7 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
if (!check_device(dev))
return -EINVAL;
- dev_data = dev->archdata.iommu;
+ dev_data = dev_iommu_priv_get(dev);
dev_data->defer_attach = false;
iommu = amd_iommu_rlookup_table[dev_data->devid];
@@ -2734,12 +2616,14 @@ static void amd_iommu_get_resv_regions(struct device *dev,
list_add_tail(&region->list, head);
}
-static bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
- struct device *dev)
+bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
+ struct device *dev)
{
- struct iommu_dev_data *dev_data = dev->archdata.iommu;
+ struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
+
return dev_data->defer_attach;
}
+EXPORT_SYMBOL_GPL(amd_iommu_is_attach_deferred);
static void amd_iommu_flush_iotlb_all(struct iommu_domain *domain)
{
@@ -2758,6 +2642,20 @@ static void amd_iommu_iotlb_sync(struct iommu_domain *domain,
amd_iommu_flush_iotlb_all(domain);
}
+static int amd_iommu_def_domain_type(struct device *dev)
+{
+ struct iommu_dev_data *dev_data;
+
+ dev_data = dev_iommu_priv_get(dev);
+ if (!dev_data)
+ return 0;
+
+ if (dev_data->iommu_v2)
+ return IOMMU_DOMAIN_IDENTITY;
+
+ return 0;
+}
+
const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
@@ -2767,8 +2665,9 @@ const struct iommu_ops amd_iommu_ops = {
.map = amd_iommu_map,
.unmap = amd_iommu_unmap,
.iova_to_phys = amd_iommu_iova_to_phys,
- .add_device = amd_iommu_add_device,
- .remove_device = amd_iommu_remove_device,
+ .probe_device = amd_iommu_probe_device,
+ .release_device = amd_iommu_release_device,
+ .probe_finalize = amd_iommu_probe_finalize,
.device_group = amd_iommu_device_group,
.domain_get_attr = amd_iommu_domain_get_attr,
.get_resv_regions = amd_iommu_get_resv_regions,
@@ -2777,6 +2676,7 @@ const struct iommu_ops amd_iommu_ops = {
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
.flush_iotlb_all = amd_iommu_flush_iotlb_all,
.iotlb_sync = amd_iommu_iotlb_sync,
+ .def_domain_type = amd_iommu_def_domain_type,
};
/*****************************************************************************
@@ -2807,7 +2707,6 @@ void amd_iommu_domain_direct_map(struct iommu_domain *dom)
struct protection_domain *domain = to_pdomain(dom);
struct domain_pgtable pgtable;
unsigned long flags;
- u64 pt_root;
spin_lock_irqsave(&domain->lock, flags);
@@ -2815,18 +2714,13 @@ void amd_iommu_domain_direct_map(struct iommu_domain *dom)
amd_iommu_domain_get_pgtable(domain, &pgtable);
/* Update data structure */
- pt_root = amd_iommu_domain_encode_pgtable(NULL, PAGE_MODE_NONE);
- atomic64_set(&domain->pt_root, pt_root);
+ atomic64_set(&domain->pt_root, 0);
/* Make changes visible to IOMMUs */
update_domain(domain);
- /* Restore old pgtable in domain->ptroot to free page-table */
- pt_root = amd_iommu_domain_encode_pgtable(pgtable.root, pgtable.mode);
- atomic64_set(&domain->pt_root, pt_root);
-
/* Page-table is not visible to IOMMU anymore, so free it */
- free_pagetable(domain);
+ free_pagetable(&pgtable);
spin_unlock_irqrestore(&domain->lock, flags);
}
@@ -3085,7 +2979,7 @@ int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid,
struct amd_iommu *iommu;
struct iommu_cmd cmd;
- dev_data = get_dev_data(&pdev->dev);
+ dev_data = dev_iommu_priv_get(&pdev->dev);
iommu = amd_iommu_rlookup_table[dev_data->devid];
build_complete_ppr(&cmd, dev_data->devid, pasid, status,
@@ -3098,23 +2992,27 @@ EXPORT_SYMBOL(amd_iommu_complete_ppr);
struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev)
{
struct protection_domain *pdomain;
- struct iommu_domain *io_domain;
+ struct iommu_dev_data *dev_data;
struct device *dev = &pdev->dev;
+ struct iommu_domain *io_domain;
if (!check_device(dev))
return NULL;
- pdomain = get_dev_data(dev)->domain;
- if (pdomain == NULL && get_dev_data(dev)->defer_attach) {
- get_dev_data(dev)->defer_attach = false;
- io_domain = iommu_get_domain_for_dev(dev);
+ dev_data = dev_iommu_priv_get(&pdev->dev);
+ pdomain = dev_data->domain;
+ io_domain = iommu_get_domain_for_dev(dev);
+
+ if (pdomain == NULL && dev_data->defer_attach) {
+ dev_data->defer_attach = false;
pdomain = to_pdomain(io_domain);
attach_device(dev, pdomain);
}
+
if (pdomain == NULL)
return NULL;
- if (!dma_ops_domain(pdomain))
+ if (io_domain->type != IOMMU_DOMAIN_DMA)
return NULL;
/* Only return IOMMUv2 domains */
@@ -3132,7 +3030,7 @@ void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum)
if (!amd_iommu_v2_supported())
return;
- dev_data = get_dev_data(&pdev->dev);
+ dev_data = dev_iommu_priv_get(&pdev->dev);
dev_data->errata |= (1 << erratum);
}
EXPORT_SYMBOL(amd_iommu_enable_device_erratum);
@@ -3151,11 +3049,8 @@ int amd_iommu_device_info(struct pci_dev *pdev,
memset(info, 0, sizeof(*info));
- if (!pci_ats_disabled()) {
- pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS);
- if (pos)
- info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP;
- }
+ if (pci_ats_supported(pdev))
+ info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (pos)
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd/iommu_v2.c
index d6d85debd01b..e4b025c5637c 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd/iommu_v2.c
@@ -13,13 +13,11 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sched/mm.h>
-#include <linux/iommu.h>
#include <linux/wait.h>
#include <linux/pci.h>
#include <linux/gfp.h>
-#include "amd_iommu_types.h"
-#include "amd_iommu_proto.h"
+#include "amd_iommu.h"
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Joerg Roedel <jroedel@suse.de>");
@@ -487,7 +485,7 @@ static void do_fault(struct work_struct *work)
flags |= FAULT_FLAG_WRITE;
flags |= FAULT_FLAG_REMOTE;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = find_extend_vma(mm, address);
if (!vma || address < vma->vm_start)
/* failed to get a vma in the right range */
@@ -499,7 +497,7 @@ static void do_fault(struct work_struct *work)
ret = handle_mm_fault(vma, address, flags);
out:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
if (ret & VM_FAULT_ERROR)
/* failed to service fault */
@@ -517,13 +515,12 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
struct amd_iommu_fault *iommu_fault;
struct pasid_state *pasid_state;
struct device_state *dev_state;
+ struct pci_dev *pdev = NULL;
unsigned long flags;
struct fault *fault;
bool finish;
u16 tag, devid;
int ret;
- struct iommu_dev_data *dev_data;
- struct pci_dev *pdev = NULL;
iommu_fault = data;
tag = iommu_fault->tag & 0x1ff;
@@ -534,12 +531,11 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
devid & 0xff);
if (!pdev)
return -ENODEV;
- dev_data = get_dev_data(&pdev->dev);
- /* In kdump kernel pci dev is not initialized yet -> send INVALID */
ret = NOTIFY_DONE;
- if (translation_pre_enabled(amd_iommu_rlookup_table[devid])
- && dev_data->defer_attach) {
+
+ /* In kdump kernel pci dev is not initialized yet -> send INVALID */
+ if (amd_iommu_is_attach_deferred(NULL, &pdev->dev)) {
amd_iommu_complete_ppr(pdev, iommu_fault->pasid,
PPR_INVALID, tag);
goto out;
diff --git a/drivers/iommu/amd_iommu_quirks.c b/drivers/iommu/amd/quirks.c
index 5120ce4fdce3..5120ce4fdce3 100644
--- a/drivers/iommu/amd_iommu_quirks.c
+++ b/drivers/iommu/amd/quirks.c
diff --git a/drivers/iommu/amd_iommu.h b/drivers/iommu/amd_iommu.h
deleted file mode 100644
index 12d540d9b59b..000000000000
--- a/drivers/iommu/amd_iommu.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef AMD_IOMMU_H
-#define AMD_IOMMU_H
-
-int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line);
-
-#ifdef CONFIG_DMI
-void amd_iommu_apply_ivrs_quirks(void);
-#else
-static void amd_iommu_apply_ivrs_quirks(void) { }
-#endif
-
-#endif
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index 74d97a886e93..c75b9d957b70 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -150,6 +150,8 @@ static const struct arm_smmu_impl arm_mmu500_impl = {
struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
{
+ const struct device_node *np = smmu->dev->of_node;
+
/*
* We will inevitably have to combine model-specific implementation
* quirks with platform-specific integration quirks, but everything
@@ -166,11 +168,11 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
break;
}
- if (of_property_read_bool(smmu->dev->of_node,
- "calxeda,smmu-secure-config-access"))
+ if (of_property_read_bool(np, "calxeda,smmu-secure-config-access"))
smmu->impl = &calxeda_impl;
- if (of_device_is_compatible(smmu->dev->of_node, "qcom,sdm845-smmu-500"))
+ if (of_device_is_compatible(np, "qcom,sdm845-smmu-500") ||
+ of_device_is_compatible(np, "qcom,sc7180-smmu-500"))
return qcom_smmu_impl_init(smmu);
return smmu;
diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index 24c071c1d8b0..cf01d0215a39 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -3,6 +3,7 @@
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
+#include <linux/of_device.h>
#include <linux/qcom_scm.h>
#include "arm-smmu.h"
@@ -11,12 +12,29 @@ struct qcom_smmu {
struct arm_smmu_device smmu;
};
+static const struct of_device_id qcom_smmu_client_of_match[] = {
+ { .compatible = "qcom,adreno" },
+ { .compatible = "qcom,mdp4" },
+ { .compatible = "qcom,mdss" },
+ { .compatible = "qcom,sc7180-mdss" },
+ { .compatible = "qcom,sc7180-mss-pil" },
+ { .compatible = "qcom,sdm845-mdss" },
+ { .compatible = "qcom,sdm845-mss-pil" },
+ { }
+};
+
+static int qcom_smmu_def_domain_type(struct device *dev)
+{
+ const struct of_device_id *match =
+ of_match_device(qcom_smmu_client_of_match, dev);
+
+ return match ? IOMMU_DOMAIN_IDENTITY : 0;
+}
+
static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
{
int ret;
- arm_mmu500_reset(smmu);
-
/*
* To address performance degradation in non-real time clients,
* such as USB and UFS, turn off wait-for-safe on sdm845 based boards,
@@ -30,8 +48,21 @@ static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
return ret;
}
+static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
+{
+ const struct device_node *np = smmu->dev->of_node;
+
+ arm_mmu500_reset(smmu);
+
+ if (of_device_is_compatible(np, "qcom,sdm845-smmu-500"))
+ return qcom_sdm845_smmu500_reset(smmu);
+
+ return 0;
+}
+
static const struct arm_smmu_impl qcom_smmu_impl = {
- .reset = qcom_sdm845_smmu500_reset,
+ .def_domain_type = qcom_smmu_def_domain_type,
+ .reset = qcom_smmu500_reset,
};
struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 82508730feb7..f578677a5c41 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -171,6 +171,8 @@
#define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8
#define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc
+#define ARM_SMMU_REG_SZ 0xe00
+
/* Common MSI config fields */
#define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2)
#define MSI_CFG2_SH GENMASK(5, 4)
@@ -628,6 +630,7 @@ struct arm_smmu_strtab_cfg {
struct arm_smmu_device {
struct device *dev;
void __iomem *base;
+ void __iomem *page1;
#define ARM_SMMU_FEAT_2_LVL_STRTAB (1 << 0)
#define ARM_SMMU_FEAT_2_LVL_CDTAB (1 << 1)
@@ -664,7 +667,6 @@ struct arm_smmu_device {
#define ARM_SMMU_MAX_ASIDS (1 << 16)
unsigned int asid_bits;
- DECLARE_BITMAP(asid_map, ARM_SMMU_MAX_ASIDS);
#define ARM_SMMU_MAX_VMIDS (1 << 16)
unsigned int vmid_bits;
@@ -724,6 +726,8 @@ struct arm_smmu_option_prop {
const char *prop;
};
+static DEFINE_XARRAY_ALLOC1(asid_xa);
+
static struct arm_smmu_option_prop arm_smmu_options[] = {
{ ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" },
{ ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"},
@@ -733,9 +737,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset,
struct arm_smmu_device *smmu)
{
- if ((offset > SZ_64K) &&
- (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY))
- offset -= SZ_64K;
+ if (offset > SZ_64K)
+ return smmu->page1 + offset - SZ_64K;
return smmu->base + offset;
}
@@ -1763,6 +1766,14 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain)
cdcfg->cdtab = NULL;
}
+static void arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd)
+{
+ if (!cd->asid)
+ return;
+
+ xa_erase(&asid_xa, cd->asid);
+}
+
/* Stream table manipulation functions */
static void
arm_smmu_write_strtab_l1_desc(__le64 *dst, struct arm_smmu_strtab_l1_desc *desc)
@@ -2448,10 +2459,9 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
- if (cfg->cdcfg.cdtab) {
+ if (cfg->cdcfg.cdtab)
arm_smmu_free_cd_tables(smmu_domain);
- arm_smmu_bitmap_free(smmu->asid_map, cfg->cd.asid);
- }
+ arm_smmu_free_asid(&cfg->cd);
} else {
struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
if (cfg->vmid)
@@ -2466,14 +2476,15 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
struct io_pgtable_cfg *pgtbl_cfg)
{
int ret;
- int asid;
+ u32 asid;
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
- asid = arm_smmu_bitmap_alloc(smmu->asid_map, smmu->asid_bits);
- if (asid < 0)
- return asid;
+ ret = xa_alloc(&asid_xa, &asid, &cfg->cd,
+ XA_LIMIT(1, (1 << smmu->asid_bits) - 1), GFP_KERNEL);
+ if (ret)
+ return ret;
cfg->s1cdmax = master->ssid_bits;
@@ -2506,7 +2517,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
out_free_cd_tables:
arm_smmu_free_cd_tables(smmu_domain);
out_free_asid:
- arm_smmu_bitmap_free(smmu->asid_map, asid);
+ arm_smmu_free_asid(&cfg->cd);
return ret;
}
@@ -2652,26 +2663,20 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
}
}
-#ifdef CONFIG_PCI_ATS
static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
{
- struct pci_dev *pdev;
+ struct device *dev = master->dev;
struct arm_smmu_device *smmu = master->smmu;
- struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- if (!(smmu->features & ARM_SMMU_FEAT_ATS) || !dev_is_pci(master->dev) ||
- !(fwspec->flags & IOMMU_FWSPEC_PCI_RC_ATS) || pci_ats_disabled())
+ if (!(smmu->features & ARM_SMMU_FEAT_ATS))
return false;
- pdev = to_pci_dev(master->dev);
- return !pdev->untrusted && pdev->ats_cap;
-}
-#else
-static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
-{
- return false;
+ if (!(fwspec->flags & IOMMU_FWSPEC_PCI_RC_ATS))
+ return false;
+
+ return dev_is_pci(dev) && pci_ats_supported(to_pci_dev(dev));
}
-#endif
static void arm_smmu_enable_ats(struct arm_smmu_master *master)
{
@@ -2914,27 +2919,26 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
static struct iommu_ops arm_smmu_ops;
-static int arm_smmu_add_device(struct device *dev)
+static struct iommu_device *arm_smmu_probe_device(struct device *dev)
{
int i, ret;
struct arm_smmu_device *smmu;
struct arm_smmu_master *master;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct iommu_group *group;
if (!fwspec || fwspec->ops != &arm_smmu_ops)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
if (WARN_ON_ONCE(dev_iommu_priv_get(dev)))
- return -EBUSY;
+ return ERR_PTR(-EBUSY);
smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
if (!smmu)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
master = kzalloc(sizeof(*master), GFP_KERNEL);
if (!master)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
master->dev = dev;
master->smmu = smmu;
@@ -2975,43 +2979,24 @@ static int arm_smmu_add_device(struct device *dev)
master->ssid_bits = min_t(u8, master->ssid_bits,
CTXDESC_LINEAR_CDMAX);
- ret = iommu_device_link(&smmu->iommu, dev);
- if (ret)
- goto err_disable_pasid;
-
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group)) {
- ret = PTR_ERR(group);
- goto err_unlink;
- }
+ return &smmu->iommu;
- iommu_group_put(group);
- return 0;
-
-err_unlink:
- iommu_device_unlink(&smmu->iommu, dev);
-err_disable_pasid:
- arm_smmu_disable_pasid(master);
err_free_master:
kfree(master);
dev_iommu_priv_set(dev, NULL);
- return ret;
+ return ERR_PTR(ret);
}
-static void arm_smmu_remove_device(struct device *dev)
+static void arm_smmu_release_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct arm_smmu_master *master;
- struct arm_smmu_device *smmu;
if (!fwspec || fwspec->ops != &arm_smmu_ops)
return;
master = dev_iommu_priv_get(dev);
- smmu = master->smmu;
arm_smmu_detach_dev(master);
- iommu_group_remove_device(dev);
- iommu_device_unlink(&smmu->iommu, dev);
arm_smmu_disable_pasid(master);
kfree(master);
iommu_fwspec_free(dev);
@@ -3138,8 +3123,8 @@ static struct iommu_ops arm_smmu_ops = {
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
- .add_device = arm_smmu_add_device,
- .remove_device = arm_smmu_remove_device,
+ .probe_device = arm_smmu_probe_device,
+ .release_device = arm_smmu_release_device,
.device_group = arm_smmu_device_group,
.domain_get_attr = arm_smmu_domain_get_attr,
.domain_set_attr = arm_smmu_domain_set_attr,
@@ -4021,6 +4006,18 @@ err_reset_pci_ops: __maybe_unused;
return err;
}
+static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start,
+ resource_size_t size)
+{
+ struct resource res = {
+ .flags = IORESOURCE_MEM,
+ .start = start,
+ .end = start + size - 1,
+ };
+
+ return devm_ioremap_resource(dev, &res);
+}
+
static int arm_smmu_device_probe(struct platform_device *pdev)
{
int irq, ret;
@@ -4056,10 +4053,23 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
}
ioaddr = res->start;
- smmu->base = devm_ioremap_resource(dev, res);
+ /*
+ * Don't map the IMPLEMENTATION DEFINED regions, since they may contain
+ * the PMCG registers which are reserved by the PMU driver.
+ */
+ smmu->base = arm_smmu_ioremap(dev, ioaddr, ARM_SMMU_REG_SZ);
if (IS_ERR(smmu->base))
return PTR_ERR(smmu->base);
+ if (arm_smmu_resource_size(smmu) > SZ_64K) {
+ smmu->page1 = arm_smmu_ioremap(dev, ioaddr + SZ_64K,
+ ARM_SMMU_REG_SZ);
+ if (IS_ERR(smmu->page1))
+ return PTR_ERR(smmu->page1);
+ } else {
+ smmu->page1 = smmu->base;
+ }
+
/* Interrupt lines */
irq = platform_get_irq_byname_optional(pdev, "combined");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a6a5796e9c41..243bc4cb2705 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -220,7 +220,7 @@ static int arm_smmu_register_legacy_master(struct device *dev,
* With the legacy DT binding in play, we have no guarantees about
* probe order, but then we're also not doing default domains, so we can
* delay setting bus ops until we're sure every possible SMMU is ready,
- * and that way ensure that no add_device() calls get missed.
+ * and that way ensure that no probe_device() calls get missed.
*/
static int arm_smmu_legacy_bus_init(void)
{
@@ -1062,7 +1062,6 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
struct arm_smmu_device *smmu = cfg->smmu;
struct arm_smmu_smr *smrs = smmu->smrs;
- struct iommu_group *group;
int i, idx, ret;
mutex_lock(&smmu->stream_map_mutex);
@@ -1090,18 +1089,9 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
cfg->smendx[i] = (s16)idx;
}
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group)) {
- ret = PTR_ERR(group);
- goto out_err;
- }
- iommu_group_put(group);
-
/* It worked! Now, poke the actual hardware */
- for_each_cfg_sme(cfg, fwspec, i, idx) {
+ for_each_cfg_sme(cfg, fwspec, i, idx)
arm_smmu_write_sme(smmu, idx);
- smmu->s2crs[idx].group = group;
- }
mutex_unlock(&smmu->stream_map_mutex);
return 0;
@@ -1172,7 +1162,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
/*
* FIXME: The arch/arm DMA API code tries to attach devices to its own
- * domains between of_xlate() and add_device() - we have no way to cope
+ * domains between of_xlate() and probe_device() - we have no way to cope
* with that, so until ARM gets converted to rely on groups and default
* domains, just say no (but more politely than by dereferencing NULL).
* This should be at least a WARN_ON once that's sorted.
@@ -1382,7 +1372,7 @@ struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
return dev ? dev_get_drvdata(dev) : NULL;
}
-static int arm_smmu_add_device(struct device *dev)
+static struct iommu_device *arm_smmu_probe_device(struct device *dev)
{
struct arm_smmu_device *smmu = NULL;
struct arm_smmu_master_cfg *cfg;
@@ -1403,7 +1393,7 @@ static int arm_smmu_add_device(struct device *dev)
} else if (fwspec && fwspec->ops == &arm_smmu_ops) {
smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
} else {
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
}
ret = -EINVAL;
@@ -1444,21 +1434,19 @@ static int arm_smmu_add_device(struct device *dev)
if (ret)
goto out_cfg_free;
- iommu_device_link(&smmu->iommu, dev);
-
device_link_add(dev, smmu->dev,
DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
- return 0;
+ return &smmu->iommu;
out_cfg_free:
kfree(cfg);
out_free:
iommu_fwspec_free(dev);
- return ret;
+ return ERR_PTR(ret);
}
-static void arm_smmu_remove_device(struct device *dev)
+static void arm_smmu_release_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct arm_smmu_master_cfg *cfg;
@@ -1475,13 +1463,11 @@ static void arm_smmu_remove_device(struct device *dev)
if (ret < 0)
return;
- iommu_device_unlink(&smmu->iommu, dev);
arm_smmu_master_free_smes(cfg, fwspec);
arm_smmu_rpm_put(smmu);
dev_iommu_priv_set(dev, NULL);
- iommu_group_remove_device(dev);
kfree(cfg);
iommu_fwspec_free(dev);
}
@@ -1512,6 +1498,11 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
else
group = generic_device_group(dev);
+ /* Remember group for faster lookups */
+ if (!IS_ERR(group))
+ for_each_cfg_sme(cfg, fwspec, i, idx)
+ smmu->s2crs[idx].group = group;
+
return group;
}
@@ -1618,6 +1609,17 @@ static void arm_smmu_get_resv_regions(struct device *dev,
iommu_dma_get_resv_regions(dev, head);
}
+static int arm_smmu_def_domain_type(struct device *dev)
+{
+ struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+ const struct arm_smmu_impl *impl = cfg->smmu->impl;
+
+ if (impl && impl->def_domain_type)
+ return impl->def_domain_type(dev);
+
+ return 0;
+}
+
static struct iommu_ops arm_smmu_ops = {
.capable = arm_smmu_capable,
.domain_alloc = arm_smmu_domain_alloc,
@@ -1628,14 +1630,15 @@ static struct iommu_ops arm_smmu_ops = {
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
- .add_device = arm_smmu_add_device,
- .remove_device = arm_smmu_remove_device,
+ .probe_device = arm_smmu_probe_device,
+ .release_device = arm_smmu_release_device,
.device_group = arm_smmu_device_group,
.domain_get_attr = arm_smmu_domain_get_attr,
.domain_set_attr = arm_smmu_domain_set_attr,
.of_xlate = arm_smmu_of_xlate,
.get_resv_regions = arm_smmu_get_resv_regions,
.put_resv_regions = generic_iommu_put_resv_regions,
+ .def_domain_type = arm_smmu_def_domain_type,
.pgsize_bitmap = -1UL, /* Restricted during device attach */
};
@@ -2253,7 +2256,7 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
return -ENODEV;
if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS))
- dev_err(&pdev->dev, "removing device with active domains!\n");
+ dev_notice(&pdev->dev, "disabling translation\n");
arm_smmu_bus_init(NULL);
iommu_device_unregister(&smmu->iommu);
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 8d1cd54d82a6..d172c024be61 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -386,6 +386,7 @@ struct arm_smmu_impl {
int (*init_context)(struct arm_smmu_domain *smmu_domain);
void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
int status);
+ int (*def_domain_type)(struct device *dev);
};
static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 186ff5cc975c..60c8a56e4a3f 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1235,19 +1235,13 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
return phys;
}
-static int exynos_iommu_add_device(struct device *dev)
+static struct iommu_device *exynos_iommu_probe_device(struct device *dev)
{
struct exynos_iommu_owner *owner = dev->archdata.iommu;
struct sysmmu_drvdata *data;
- struct iommu_group *group;
if (!has_sysmmu(dev))
- return -ENODEV;
-
- group = iommu_group_get_for_dev(dev);
-
- if (IS_ERR(group))
- return PTR_ERR(group);
+ return ERR_PTR(-ENODEV);
list_for_each_entry(data, &owner->controllers, owner_node) {
/*
@@ -1259,12 +1253,15 @@ static int exynos_iommu_add_device(struct device *dev)
DL_FLAG_STATELESS |
DL_FLAG_PM_RUNTIME);
}
- iommu_group_put(group);
- return 0;
+ /* There is always at least one entry, see exynos_iommu_of_xlate() */
+ data = list_first_entry(&owner->controllers,
+ struct sysmmu_drvdata, owner_node);
+
+ return &data->iommu;
}
-static void exynos_iommu_remove_device(struct device *dev)
+static void exynos_iommu_release_device(struct device *dev)
{
struct exynos_iommu_owner *owner = dev->archdata.iommu;
struct sysmmu_drvdata *data;
@@ -1282,7 +1279,6 @@ static void exynos_iommu_remove_device(struct device *dev)
iommu_group_put(group);
}
}
- iommu_group_remove_device(dev);
list_for_each_entry(data, &owner->controllers, owner_node)
device_link_del(data->link);
@@ -1331,8 +1327,8 @@ static const struct iommu_ops exynos_iommu_ops = {
.unmap = exynos_iommu_unmap,
.iova_to_phys = exynos_iommu_iova_to_phys,
.device_group = generic_device_group,
- .add_device = exynos_iommu_add_device,
- .remove_device = exynos_iommu_remove_device,
+ .probe_device = exynos_iommu_probe_device,
+ .release_device = exynos_iommu_release_device,
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
.of_xlate = exynos_iommu_of_xlate,
};
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 06828e2698d5..928d37771ece 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -1016,25 +1016,13 @@ static struct iommu_group *fsl_pamu_device_group(struct device *dev)
return group;
}
-static int fsl_pamu_add_device(struct device *dev)
+static struct iommu_device *fsl_pamu_probe_device(struct device *dev)
{
- struct iommu_group *group;
-
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
-
- iommu_device_link(&pamu_iommu, dev);
-
- return 0;
+ return &pamu_iommu;
}
-static void fsl_pamu_remove_device(struct device *dev)
+static void fsl_pamu_release_device(struct device *dev)
{
- iommu_device_unlink(&pamu_iommu, dev);
- iommu_group_remove_device(dev);
}
static const struct iommu_ops fsl_pamu_ops = {
@@ -1048,8 +1036,8 @@ static const struct iommu_ops fsl_pamu_ops = {
.iova_to_phys = fsl_pamu_iova_to_phys,
.domain_set_attr = fsl_pamu_set_domain_attr,
.domain_get_attr = fsl_pamu_get_domain_attr,
- .add_device = fsl_pamu_add_device,
- .remove_device = fsl_pamu_remove_device,
+ .probe_device = fsl_pamu_probe_device,
+ .release_device = fsl_pamu_release_device,
.device_group = fsl_pamu_device_group,
};
diff --git a/drivers/iommu/hyperv-iommu.c b/drivers/iommu/hyperv-iommu.c
index a386b83e0e34..3c0c67a99c7b 100644
--- a/drivers/iommu/hyperv-iommu.c
+++ b/drivers/iommu/hyperv-iommu.c
@@ -131,7 +131,7 @@ static int hyperv_irq_remapping_activate(struct irq_domain *domain,
return 0;
}
-static struct irq_domain_ops hyperv_ir_domain_ops = {
+static const struct irq_domain_ops hyperv_ir_domain_ops = {
.alloc = hyperv_irq_remapping_alloc,
.free = hyperv_irq_remapping_free,
.activate = hyperv_irq_remapping_activate,
diff --git a/drivers/iommu/intel-iommu-debugfs.c b/drivers/iommu/intel/debugfs.c
index 3eb1fe240fb0..cf1ebb98e418 100644
--- a/drivers/iommu/intel-iommu-debugfs.c
+++ b/drivers/iommu/intel/debugfs.c
@@ -372,6 +372,66 @@ static int domain_translation_struct_show(struct seq_file *m, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
+static void invalidation_queue_entry_show(struct seq_file *m,
+ struct intel_iommu *iommu)
+{
+ int index, shift = qi_shift(iommu);
+ struct qi_desc *desc;
+ int offset;
+
+ if (ecap_smts(iommu->ecap))
+ seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tqw2\t\t\tqw3\t\t\tstatus\n");
+ else
+ seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tstatus\n");
+
+ for (index = 0; index < QI_LENGTH; index++) {
+ offset = index << shift;
+ desc = iommu->qi->desc + offset;
+ if (ecap_smts(iommu->ecap))
+ seq_printf(m, "%5d\t%016llx\t%016llx\t%016llx\t%016llx\t%016x\n",
+ index, desc->qw0, desc->qw1,
+ desc->qw2, desc->qw3,
+ iommu->qi->desc_status[index]);
+ else
+ seq_printf(m, "%5d\t%016llx\t%016llx\t%016x\n",
+ index, desc->qw0, desc->qw1,
+ iommu->qi->desc_status[index]);
+ }
+}
+
+static int invalidation_queue_show(struct seq_file *m, void *unused)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu;
+ unsigned long flags;
+ struct q_inval *qi;
+ int shift;
+
+ rcu_read_lock();
+ for_each_active_iommu(iommu, drhd) {
+ qi = iommu->qi;
+ shift = qi_shift(iommu);
+
+ if (!qi || !ecap_qis(iommu->ecap))
+ continue;
+
+ seq_printf(m, "Invalidation queue on IOMMU: %s\n", iommu->name);
+
+ raw_spin_lock_irqsave(&qi->q_lock, flags);
+ seq_printf(m, " Base: 0x%llx\tHead: %lld\tTail: %lld\n",
+ (u64)virt_to_phys(qi->desc),
+ dmar_readq(iommu->reg + DMAR_IQH_REG) >> shift,
+ dmar_readq(iommu->reg + DMAR_IQT_REG) >> shift);
+ invalidation_queue_entry_show(m, iommu);
+ raw_spin_unlock_irqrestore(&qi->q_lock, flags);
+ seq_putc(m, '\n');
+ }
+ rcu_read_unlock();
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(invalidation_queue);
+
#ifdef CONFIG_IRQ_REMAP
static void ir_tbl_remap_entry_show(struct seq_file *m,
struct intel_iommu *iommu)
@@ -490,6 +550,8 @@ void __init intel_iommu_debugfs_init(void)
debugfs_create_file("domain_translation_struct", 0444,
intel_iommu_debug, NULL,
&domain_translation_struct_fops);
+ debugfs_create_file("invalidation_queue", 0444, intel_iommu_debug,
+ NULL, &invalidation_queue_fops);
#ifdef CONFIG_IRQ_REMAP
debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
NULL, &ir_translation_struct_fops);
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/intel/dmar.c
index f77dae7ba7d4..cc46dff98fa0 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -32,7 +32,7 @@
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>
-#include "irq_remapping.h"
+#include "../irq_remapping.h"
typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
struct dmar_res_callback {
@@ -963,6 +963,7 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr)
warn_invalid_dmar(phys_addr, " returns all ones");
goto unmap;
}
+ iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG);
/* the registers might be more than one page */
map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
@@ -1156,12 +1157,11 @@ static inline void reclaim_free_desc(struct q_inval *qi)
}
}
-static int qi_check_fault(struct intel_iommu *iommu, int index)
+static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
{
u32 fault;
int head, tail;
struct q_inval *qi = iommu->qi;
- int wait_index = (index + 1) % QI_LENGTH;
int shift = qi_shift(iommu);
if (qi->desc_status[wait_index] == QI_ABORT)
@@ -1224,17 +1224,21 @@ static int qi_check_fault(struct intel_iommu *iommu, int index)
}
/*
- * Submit the queued invalidation descriptor to the remapping
- * hardware unit and wait for its completion.
+ * Function to submit invalidation descriptors of all types to the queued
+ * invalidation interface(QI). Multiple descriptors can be submitted at a
+ * time, a wait descriptor will be appended to each submission to ensure
+ * hardware has completed the invalidation before return. Wait descriptors
+ * can be part of the submission but it will not be polled for completion.
*/
-int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
+int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,
+ unsigned int count, unsigned long options)
{
- int rc;
struct q_inval *qi = iommu->qi;
- int offset, shift, length;
struct qi_desc wait_desc;
int wait_index, index;
unsigned long flags;
+ int offset, shift;
+ int rc, i;
if (!qi)
return 0;
@@ -1243,32 +1247,41 @@ restart:
rc = 0;
raw_spin_lock_irqsave(&qi->q_lock, flags);
- while (qi->free_cnt < 3) {
+ /*
+ * Check if we have enough empty slots in the queue to submit,
+ * the calculation is based on:
+ * # of desc + 1 wait desc + 1 space between head and tail
+ */
+ while (qi->free_cnt < count + 2) {
raw_spin_unlock_irqrestore(&qi->q_lock, flags);
cpu_relax();
raw_spin_lock_irqsave(&qi->q_lock, flags);
}
index = qi->free_head;
- wait_index = (index + 1) % QI_LENGTH;
+ wait_index = (index + count) % QI_LENGTH;
shift = qi_shift(iommu);
- length = 1 << shift;
- qi->desc_status[index] = qi->desc_status[wait_index] = QI_IN_USE;
+ for (i = 0; i < count; i++) {
+ offset = ((index + i) % QI_LENGTH) << shift;
+ memcpy(qi->desc + offset, &desc[i], 1 << shift);
+ qi->desc_status[(index + i) % QI_LENGTH] = QI_IN_USE;
+ }
+ qi->desc_status[wait_index] = QI_IN_USE;
- offset = index << shift;
- memcpy(qi->desc + offset, desc, length);
wait_desc.qw0 = QI_IWD_STATUS_DATA(QI_DONE) |
QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
+ if (options & QI_OPT_WAIT_DRAIN)
+ wait_desc.qw0 |= QI_IWD_PRQ_DRAIN;
wait_desc.qw1 = virt_to_phys(&qi->desc_status[wait_index]);
wait_desc.qw2 = 0;
wait_desc.qw3 = 0;
offset = wait_index << shift;
- memcpy(qi->desc + offset, &wait_desc, length);
+ memcpy(qi->desc + offset, &wait_desc, 1 << shift);
- qi->free_head = (qi->free_head + 2) % QI_LENGTH;
- qi->free_cnt -= 2;
+ qi->free_head = (qi->free_head + count + 1) % QI_LENGTH;
+ qi->free_cnt -= count + 1;
/*
* update the HW tail register indicating the presence of
@@ -1284,7 +1297,7 @@ restart:
* a deadlock where the interrupt context can wait indefinitely
* for free slots in the queue.
*/
- rc = qi_check_fault(iommu, index);
+ rc = qi_check_fault(iommu, index, wait_index);
if (rc)
break;
@@ -1293,7 +1306,8 @@ restart:
raw_spin_lock(&qi->q_lock);
}
- qi->desc_status[index] = QI_DONE;
+ for (i = 0; i < count; i++)
+ qi->desc_status[(index + i) % QI_LENGTH] = QI_DONE;
reclaim_free_desc(qi);
raw_spin_unlock_irqrestore(&qi->q_lock, flags);
@@ -1317,7 +1331,7 @@ void qi_global_iec(struct intel_iommu *iommu)
desc.qw3 = 0;
/* should never fail */
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
}
void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
@@ -1331,7 +1345,7 @@ void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
}
void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
@@ -1355,7 +1369,7 @@ void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
}
void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
@@ -1377,7 +1391,7 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
}
/* PASID-based IOTLB invalidation */
@@ -1418,7 +1432,46 @@ void qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr,
QI_EIOTLB_AM(mask);
}
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
+}
+
+/* PASID-based device IOTLB Invalidate */
+void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+ u32 pasid, u16 qdep, u64 addr,
+ unsigned int size_order, u64 granu)
+{
+ unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size_order - 1);
+ struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0};
+
+ desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
+ QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE |
+ QI_DEV_IOTLB_PFSID(pfsid);
+ desc.qw1 = QI_DEV_EIOTLB_GLOB(granu);
+
+ /*
+ * If S bit is 0, we only flush a single page. If S bit is set,
+ * The least significant zero bit indicates the invalidation address
+ * range. VT-d spec 6.5.2.6.
+ * e.g. address bit 12[0] indicates 8KB, 13[0] indicates 16KB.
+ * size order = 0 is PAGE_SIZE 4KB
+ * Max Invs Pending (MIP) is set to 0 for now until we have DIT in
+ * ECAP.
+ */
+ desc.qw1 |= addr & ~mask;
+ if (size_order)
+ desc.qw1 |= QI_DEV_EIOTLB_SIZE;
+
+ qi_submit_sync(iommu, &desc, 1, 0);
+}
+
+void qi_flush_pasid_cache(struct intel_iommu *iommu, u16 did,
+ u64 granu, int pasid)
+{
+ struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0};
+
+ desc.qw0 = QI_PC_PASID(pasid) | QI_PC_DID(did) |
+ QI_PC_GRAN(granu) | QI_PC_TYPE;
+ qi_submit_sync(iommu, &desc, 1, 0);
}
/*
diff --git a/drivers/iommu/intel-pasid.h b/drivers/iommu/intel/intel-pasid.h
index 92de6df24ccb..c5318d40e0fa 100644
--- a/drivers/iommu/intel-pasid.h
+++ b/drivers/iommu/intel/intel-pasid.h
@@ -15,6 +15,7 @@
#define PASID_MAX 0x100000
#define PASID_PTE_MASK 0x3F
#define PASID_PTE_PRESENT 1
+#define PASID_PTE_FPD 2
#define PDE_PFN_MASK PAGE_MASK
#define PASID_PDE_SHIFT 6
#define MAX_NR_PASID_BITS 20
@@ -23,6 +24,16 @@
#define is_pasid_enabled(entry) (((entry)->lo >> 3) & 0x1)
#define get_pasid_dir_size(entry) (1 << ((((entry)->lo >> 9) & 0x7) + 7))
+/* Virtual command interface for enlightened pasid management. */
+#define VCMD_CMD_ALLOC 0x1
+#define VCMD_CMD_FREE 0x2
+#define VCMD_VRSP_IP 0x1
+#define VCMD_VRSP_SC(e) (((e) >> 1) & 0x3)
+#define VCMD_VRSP_SC_SUCCESS 0
+#define VCMD_VRSP_SC_NO_PASID_AVAIL 1
+#define VCMD_VRSP_SC_INVALID_PASID 1
+#define VCMD_VRSP_RESULT_PASID(e) (((e) >> 8) & 0xfffff)
+#define VCMD_CMD_OPERAND(e) ((e) << 8)
/*
* Domain ID reserved for pasid entries programmed for first-level
* only and pass-through transfer modes.
@@ -36,6 +47,7 @@
* to vmalloc or even module mappings.
*/
#define PASID_FLAG_SUPERVISOR_MODE BIT(0)
+#define PASID_FLAG_NESTED BIT(1)
/*
* The PASID_FLAG_FL5LP flag Indicates using 5-level paging for first-
@@ -51,6 +63,11 @@ struct pasid_entry {
u64 val[8];
};
+#define PASID_ENTRY_PGTT_FL_ONLY (1)
+#define PASID_ENTRY_PGTT_SL_ONLY (2)
+#define PASID_ENTRY_PGTT_NESTED (3)
+#define PASID_ENTRY_PGTT_PT (4)
+
/* The representative of a PASID table */
struct pasid_table {
void *table; /* pasid table pointer */
@@ -99,7 +116,13 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
struct dmar_domain *domain,
struct device *dev, int pasid);
+int intel_pasid_setup_nested(struct intel_iommu *iommu,
+ struct device *dev, pgd_t *pgd, int pasid,
+ struct iommu_gpasid_bind_data_vtd *pasid_data,
+ struct dmar_domain *domain, int addr_width);
void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
- struct device *dev, int pasid);
-
+ struct device *dev, int pasid,
+ bool fault_ignore);
+int vcmd_alloc_pasid(struct intel_iommu *iommu, unsigned int *pasid);
+void vcmd_free_pasid(struct intel_iommu *iommu, unsigned int pasid);
#endif /* __INTEL_PASID_H */
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel/iommu.c
index 0182cff2c7ac..9129663a7406 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -47,7 +47,7 @@
#include <asm/iommu.h>
#include <trace/events/intel_iommu.h>
-#include "irq_remapping.h"
+#include "../irq_remapping.h"
#include "intel-pasid.h"
#define ROOT_SIZE VTD_PAGE_SIZE
@@ -296,31 +296,6 @@ static inline void context_clear_entry(struct context_entry *context)
static struct dmar_domain *si_domain;
static int hw_pass_through = 1;
-/* si_domain contains mulitple devices */
-#define DOMAIN_FLAG_STATIC_IDENTITY BIT(0)
-
-/*
- * This is a DMA domain allocated through the iommu domain allocation
- * interface. But one or more devices belonging to this domain have
- * been chosen to use a private domain. We should avoid to use the
- * map/unmap/iova_to_phys APIs on it.
- */
-#define DOMAIN_FLAG_LOSE_CHILDREN BIT(1)
-
-/*
- * When VT-d works in the scalable mode, it allows DMA translation to
- * happen through either first level or second level page table. This
- * bit marks that the DMA translation for the domain goes through the
- * first level page table, otherwise, it goes through the second level.
- */
-#define DOMAIN_FLAG_USE_FIRST_LEVEL BIT(2)
-
-/*
- * Domain represents a virtual machine which demands iommu nested
- * translation mode support.
- */
-#define DOMAIN_FLAG_NESTING_MODE BIT(3)
-
#define for_each_domain_iommu(idx, domain) \
for (idx = 0; idx < g_num_of_iommus; idx++) \
if (domain->iommu_refcnt[idx])
@@ -355,11 +330,6 @@ static void domain_exit(struct dmar_domain *domain);
static void domain_remove_dev_info(struct dmar_domain *domain);
static void dmar_remove_one_dev_info(struct device *dev);
static void __dmar_remove_one_dev_info(struct device_domain_info *info);
-static void domain_context_clear(struct intel_iommu *iommu,
- struct device *dev);
-static int domain_detach_iommu(struct dmar_domain *domain,
- struct intel_iommu *iommu);
-static bool device_is_rmrr_locked(struct device *dev);
static int intel_iommu_attach_device(struct iommu_domain *domain,
struct device *dev);
static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -395,6 +365,21 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
+struct device_domain_info *get_domain_info(struct device *dev)
+{
+ struct device_domain_info *info;
+
+ if (!dev)
+ return NULL;
+
+ info = dev->archdata.iommu;
+ if (unlikely(info == DUMMY_DEVICE_DOMAIN_INFO ||
+ info == DEFER_DEVICE_DOMAIN_INFO))
+ return NULL;
+
+ return info;
+}
+
DEFINE_SPINLOCK(device_domain_lock);
static LIST_HEAD(device_domain_list);
@@ -446,12 +431,6 @@ static void init_translation_status(struct intel_iommu *iommu)
iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
}
-/* Convert generic 'struct iommu_domain to private struct dmar_domain */
-static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
-{
- return container_of(dom, struct dmar_domain, domain);
-}
-
static int __init intel_iommu_setup(char *str)
{
if (!str)
@@ -480,8 +459,7 @@ static int __init intel_iommu_setup(char *str)
pr_info("Intel-IOMMU: scalable mode supported\n");
intel_iommu_sm = 1;
} else if (!strncmp(str, "tboot_noforce", 13)) {
- printk(KERN_INFO
- "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
+ pr_info("Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
intel_iommu_tboot_noforce = 1;
} else if (!strncmp(str, "nobounce", 8)) {
pr_info("Intel-IOMMU: No bounce buffer. This could expose security risks of DMA attacks\n");
@@ -1454,8 +1432,7 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
!pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
info->pri_enabled = 1;
#endif
- if (!pdev->untrusted && info->ats_supported &&
- pci_ats_page_aligned(pdev) &&
+ if (info->ats_supported && pci_ats_page_aligned(pdev) &&
!pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
info->ats_enabled = 1;
domain_update_iotlb(info->domain);
@@ -1763,6 +1740,9 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
if (ecap_prs(iommu->ecap))
intel_svm_finish_prq(iommu);
}
+ if (ecap_vcs(iommu->ecap) && vccap_pasid(iommu->vccap))
+ ioasid_unregister_allocator(&iommu->pasid_allocator);
+
#endif
}
@@ -1911,11 +1891,6 @@ static int dmar_init_reserved_ranges(void)
return 0;
}
-static void domain_reserve_special_ranges(struct dmar_domain *domain)
-{
- copy_reserved_iova(&reserved_iova_list, &domain->iovad);
-}
-
static inline int guestwidth_to_adjustwidth(int gaw)
{
int agaw;
@@ -1930,65 +1905,6 @@ static inline int guestwidth_to_adjustwidth(int gaw)
return agaw;
}
-static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
- int guest_width)
-{
- int adjust_width, agaw;
- unsigned long sagaw;
- int ret;
-
- init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
-
- if (!intel_iommu_strict) {
- ret = init_iova_flush_queue(&domain->iovad,
- iommu_flush_iova, iova_entry_free);
- if (ret)
- pr_info("iova flush queue initialization failed\n");
- }
-
- domain_reserve_special_ranges(domain);
-
- /* calculate AGAW */
- if (guest_width > cap_mgaw(iommu->cap))
- guest_width = cap_mgaw(iommu->cap);
- domain->gaw = guest_width;
- adjust_width = guestwidth_to_adjustwidth(guest_width);
- agaw = width_to_agaw(adjust_width);
- sagaw = cap_sagaw(iommu->cap);
- if (!test_bit(agaw, &sagaw)) {
- /* hardware doesn't support it, choose a bigger one */
- pr_debug("Hardware doesn't support agaw %d\n", agaw);
- agaw = find_next_bit(&sagaw, 5, agaw);
- if (agaw >= 5)
- return -ENODEV;
- }
- domain->agaw = agaw;
-
- if (ecap_coherent(iommu->ecap))
- domain->iommu_coherency = 1;
- else
- domain->iommu_coherency = 0;
-
- if (ecap_sc_support(iommu->ecap))
- domain->iommu_snooping = 1;
- else
- domain->iommu_snooping = 0;
-
- if (intel_iommu_superpage)
- domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
- else
- domain->iommu_superpage = 0;
-
- domain->nid = iommu->node;
-
- /* always allocate the top pgd */
- domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
- if (!domain->pgd)
- return -ENOMEM;
- __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
- return 0;
-}
-
static void domain_exit(struct dmar_domain *domain)
{
@@ -1996,7 +1912,8 @@ static void domain_exit(struct dmar_domain *domain)
domain_remove_dev_info(domain);
/* destroy iovas */
- put_iova_domain(&domain->iovad);
+ if (domain->domain.type == IOMMU_DOMAIN_DMA)
+ put_iova_domain(&domain->iovad);
if (domain->pgd) {
struct page *freelist;
@@ -2518,11 +2435,8 @@ struct dmar_domain *find_domain(struct device *dev)
if (unlikely(attach_deferred(dev) || iommu_dummy(dev)))
return NULL;
- if (dev_is_pci(dev))
- dev = &pci_real_dma_dev(to_pci_dev(dev))->dev;
-
/* No lock here, assumes no domain exit in normal case */
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (likely(info))
return info->domain;
@@ -2545,7 +2459,7 @@ dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
struct device_domain_info *info;
list_for_each_entry(info, &device_domain_list, global)
- if (info->iommu->segment == segment && info->bus == bus &&
+ if (info->segment == segment && info->bus == bus &&
info->devfn == devfn)
return info;
@@ -2582,6 +2496,12 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
flags);
}
+static bool dev_is_real_dma_subdevice(struct device *dev)
+{
+ return dev && dev_is_pci(dev) &&
+ pci_real_dma_dev(to_pci_dev(dev)) != to_pci_dev(dev);
+}
+
static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
int bus, int devfn,
struct device *dev,
@@ -2596,8 +2516,18 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
if (!info)
return NULL;
- info->bus = bus;
- info->devfn = devfn;
+ if (!dev_is_real_dma_subdevice(dev)) {
+ info->bus = bus;
+ info->devfn = devfn;
+ info->segment = iommu->segment;
+ } else {
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ info->bus = pdev->bus->number;
+ info->devfn = pdev->devfn;
+ info->segment = pci_domain_nr(pdev->bus);
+ }
+
info->ats_supported = info->pasid_supported = info->pri_supported = 0;
info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
info->ats_qdep = 0;
@@ -2611,10 +2541,8 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
if (dev && dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(info->dev);
- if (!pdev->untrusted &&
- !pci_ats_disabled() &&
- ecap_dev_iotlb_support(iommu->ecap) &&
- pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
+ if (ecap_dev_iotlb_support(iommu->ecap) &&
+ pci_ats_supported(pdev) &&
dmar_find_matched_atsr_unit(pdev))
info->ats_supported = 1;
@@ -2637,7 +2565,8 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
if (!found) {
struct device_domain_info *info2;
- info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
+ info2 = dmar_search_domain_by_dev_info(info->segment, info->bus,
+ info->devfn);
if (info2) {
found = info2->domain;
info2->dev = dev;
@@ -2704,108 +2633,10 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
return domain;
}
-static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
-{
- *(u16 *)opaque = alias;
- return 0;
-}
-
-static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
-{
- struct device_domain_info *info;
- struct dmar_domain *domain = NULL;
- struct intel_iommu *iommu;
- u16 dma_alias;
- unsigned long flags;
- u8 bus, devfn;
-
- iommu = device_to_iommu(dev, &bus, &devfn);
- if (!iommu)
- return NULL;
-
- if (dev_is_pci(dev)) {
- struct pci_dev *pdev = to_pci_dev(dev);
-
- pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
-
- spin_lock_irqsave(&device_domain_lock, flags);
- info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
- PCI_BUS_NUM(dma_alias),
- dma_alias & 0xff);
- if (info) {
- iommu = info->iommu;
- domain = info->domain;
- }
- spin_unlock_irqrestore(&device_domain_lock, flags);
-
- /* DMA alias already has a domain, use it */
- if (info)
- goto out;
- }
-
- /* Allocate and initialize new domain for the device */
- domain = alloc_domain(0);
- if (!domain)
- return NULL;
- if (domain_init(domain, iommu, gaw)) {
- domain_exit(domain);
- return NULL;
- }
-
-out:
- return domain;
-}
-
-static struct dmar_domain *set_domain_for_dev(struct device *dev,
- struct dmar_domain *domain)
-{
- struct intel_iommu *iommu;
- struct dmar_domain *tmp;
- u16 req_id, dma_alias;
- u8 bus, devfn;
-
- iommu = device_to_iommu(dev, &bus, &devfn);
- if (!iommu)
- return NULL;
-
- req_id = ((u16)bus << 8) | devfn;
-
- if (dev_is_pci(dev)) {
- struct pci_dev *pdev = to_pci_dev(dev);
-
- pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
-
- /* register PCI DMA alias device */
- if (req_id != dma_alias) {
- tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
- dma_alias & 0xff, NULL, domain);
-
- if (!tmp || tmp != domain)
- return tmp;
- }
- }
-
- tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
- if (!tmp || tmp != domain)
- return tmp;
-
- return domain;
-}
-
static int iommu_domain_identity_map(struct dmar_domain *domain,
- unsigned long long start,
- unsigned long long end)
+ unsigned long first_vpfn,
+ unsigned long last_vpfn)
{
- unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
- unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
-
- if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
- dma_to_mm_pfn(last_vpfn))) {
- pr_err("Reserving iova failed\n");
- return -ENOMEM;
- }
-
- pr_debug("Mapping reserved region %llx-%llx\n", start, end);
/*
* RMRR range might have overlap with physical memory range,
* clear it first
@@ -2817,45 +2648,6 @@ static int iommu_domain_identity_map(struct dmar_domain *domain,
DMA_PTE_READ|DMA_PTE_WRITE);
}
-static int domain_prepare_identity_map(struct device *dev,
- struct dmar_domain *domain,
- unsigned long long start,
- unsigned long long end)
-{
- /* For _hardware_ passthrough, don't bother. But for software
- passthrough, we do it anyway -- it may indicate a memory
- range which is reserved in E820, so which didn't get set
- up to start with in si_domain */
- if (domain == si_domain && hw_pass_through) {
- dev_warn(dev, "Ignoring identity map for HW passthrough [0x%Lx - 0x%Lx]\n",
- start, end);
- return 0;
- }
-
- dev_info(dev, "Setting identity map [0x%Lx - 0x%Lx]\n", start, end);
-
- if (end < start) {
- WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- return -EIO;
- }
-
- if (end >> agaw_to_width(domain->agaw)) {
- WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
- "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- agaw_to_width(domain->agaw),
- dmi_get_system_info(DMI_BIOS_VENDOR),
- dmi_get_system_info(DMI_BIOS_VERSION),
- dmi_get_system_info(DMI_PRODUCT_VERSION));
- return -EIO;
- }
-
- return iommu_domain_identity_map(domain, start, end);
-}
-
static int md_domain_init(struct dmar_domain *domain, int guest_width);
static int __init si_domain_init(int hw)
@@ -2882,7 +2674,8 @@ static int __init si_domain_init(int hw)
for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
ret = iommu_domain_identity_map(si_domain,
- PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
+ mm_to_dma_pfn(start_pfn),
+ mm_to_dma_pfn(end_pfn));
if (ret)
return ret;
}
@@ -2911,17 +2704,6 @@ static int __init si_domain_init(int hw)
return 0;
}
-static int identity_mapping(struct device *dev)
-{
- struct device_domain_info *info;
-
- info = dev->archdata.iommu;
- if (info)
- return (info->domain == si_domain);
-
- return 0;
-}
-
static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
{
struct dmar_domain *ndomain;
@@ -3048,31 +2830,6 @@ static int device_def_domain_type(struct device *dev)
if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
return IOMMU_DOMAIN_IDENTITY;
-
- /*
- * We want to start off with all devices in the 1:1 domain, and
- * take them out later if we find they can't access all of memory.
- *
- * However, we can't do this for PCI devices behind bridges,
- * because all PCI devices behind the same bridge will end up
- * with the same source-id on their transactions.
- *
- * Practically speaking, we can't change things around for these
- * devices at run-time, because we can't be sure there'll be no
- * DMA transactions in flight for any of their siblings.
- *
- * So PCI devices (unless they're on the root bus) as well as
- * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
- * the 1:1 domain, just in _case_ one of their siblings turns out
- * not to be able to map all of memory.
- */
- if (!pci_is_pcie(pdev)) {
- if (!pci_is_root_bus(pdev->bus))
- return IOMMU_DOMAIN_DMA;
- if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
- return IOMMU_DOMAIN_DMA;
- } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
- return IOMMU_DOMAIN_DMA;
}
return 0;
@@ -3297,6 +3054,85 @@ out_unmap:
return ret;
}
+#ifdef CONFIG_INTEL_IOMMU_SVM
+static ioasid_t intel_vcmd_ioasid_alloc(ioasid_t min, ioasid_t max, void *data)
+{
+ struct intel_iommu *iommu = data;
+ ioasid_t ioasid;
+
+ if (!iommu)
+ return INVALID_IOASID;
+ /*
+ * VT-d virtual command interface always uses the full 20 bit
+ * PASID range. Host can partition guest PASID range based on
+ * policies but it is out of guest's control.
+ */
+ if (min < PASID_MIN || max > intel_pasid_max_id)
+ return INVALID_IOASID;
+
+ if (vcmd_alloc_pasid(iommu, &ioasid))
+ return INVALID_IOASID;
+
+ return ioasid;
+}
+
+static void intel_vcmd_ioasid_free(ioasid_t ioasid, void *data)
+{
+ struct intel_iommu *iommu = data;
+
+ if (!iommu)
+ return;
+ /*
+ * Sanity check the ioasid owner is done at upper layer, e.g. VFIO
+ * We can only free the PASID when all the devices are unbound.
+ */
+ if (ioasid_find(NULL, ioasid, NULL)) {
+ pr_alert("Cannot free active IOASID %d\n", ioasid);
+ return;
+ }
+ vcmd_free_pasid(iommu, ioasid);
+}
+
+static void register_pasid_allocator(struct intel_iommu *iommu)
+{
+ /*
+ * If we are running in the host, no need for custom allocator
+ * in that PASIDs are allocated from the host system-wide.
+ */
+ if (!cap_caching_mode(iommu->cap))
+ return;
+
+ if (!sm_supported(iommu)) {
+ pr_warn("VT-d Scalable Mode not enabled, no PASID allocation\n");
+ return;
+ }
+
+ /*
+ * Register a custom PASID allocator if we are running in a guest,
+ * guest PASID must be obtained via virtual command interface.
+ * There can be multiple vIOMMUs in each guest but only one allocator
+ * is active. All vIOMMU allocators will eventually be calling the same
+ * host allocator.
+ */
+ if (!ecap_vcs(iommu->ecap) || !vccap_pasid(iommu->vccap))
+ return;
+
+ pr_info("Register custom PASID allocator\n");
+ iommu->pasid_allocator.alloc = intel_vcmd_ioasid_alloc;
+ iommu->pasid_allocator.free = intel_vcmd_ioasid_free;
+ iommu->pasid_allocator.pdata = (void *)iommu;
+ if (ioasid_register_allocator(&iommu->pasid_allocator)) {
+ pr_warn("Custom PASID allocator failed, scalable mode disabled\n");
+ /*
+ * Disable scalable mode on this IOMMU if there
+ * is no custom allocator. Mixing SM capable vIOMMU
+ * and non-SM vIOMMU are not supported.
+ */
+ intel_iommu_sm = 0;
+ }
+}
+#endif
+
static int __init init_dmars(void)
{
struct dmar_drhd_unit *drhd;
@@ -3414,6 +3250,9 @@ static int __init init_dmars(void)
*/
for_each_active_iommu(iommu, drhd) {
iommu_flush_write_buffer(iommu);
+#ifdef CONFIG_INTEL_IOMMU_SVM
+ register_pasid_allocator(iommu);
+#endif
iommu_set_root_entry(iommu);
iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
@@ -3531,100 +3370,6 @@ static unsigned long intel_alloc_iova(struct device *dev,
return iova_pfn;
}
-static struct dmar_domain *get_private_domain_for_dev(struct device *dev)
-{
- struct dmar_domain *domain, *tmp;
- struct dmar_rmrr_unit *rmrr;
- struct device *i_dev;
- int i, ret;
-
- /* Device shouldn't be attached by any domains. */
- domain = find_domain(dev);
- if (domain)
- return NULL;
-
- domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
- if (!domain)
- goto out;
-
- /* We have a new domain - setup possible RMRRs for the device */
- rcu_read_lock();
- for_each_rmrr_units(rmrr) {
- for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
- i, i_dev) {
- if (i_dev != dev)
- continue;
-
- ret = domain_prepare_identity_map(dev, domain,
- rmrr->base_address,
- rmrr->end_address);
- if (ret)
- dev_err(dev, "Mapping reserved region failed\n");
- }
- }
- rcu_read_unlock();
-
- tmp = set_domain_for_dev(dev, domain);
- if (!tmp || domain != tmp) {
- domain_exit(domain);
- domain = tmp;
- }
-
-out:
- if (!domain)
- dev_err(dev, "Allocating domain failed\n");
- else
- domain->domain.type = IOMMU_DOMAIN_DMA;
-
- return domain;
-}
-
-/* Check if the dev needs to go through non-identity map and unmap process.*/
-static bool iommu_need_mapping(struct device *dev)
-{
- int ret;
-
- if (iommu_dummy(dev))
- return false;
-
- if (unlikely(attach_deferred(dev)))
- do_deferred_attach(dev);
-
- ret = identity_mapping(dev);
- if (ret) {
- u64 dma_mask = *dev->dma_mask;
-
- if (dev->coherent_dma_mask && dev->coherent_dma_mask < dma_mask)
- dma_mask = dev->coherent_dma_mask;
-
- if (dma_mask >= dma_direct_get_required_mask(dev))
- return false;
-
- /*
- * 32 bit DMA is removed from si_domain and fall back to
- * non-identity mapping.
- */
- dmar_remove_one_dev_info(dev);
- ret = iommu_request_dma_domain_for_dev(dev);
- if (ret) {
- struct iommu_domain *domain;
- struct dmar_domain *dmar_domain;
-
- domain = iommu_get_domain_for_dev(dev);
- if (domain) {
- dmar_domain = to_dmar_domain(domain);
- dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
- }
- dmar_remove_one_dev_info(dev);
- get_private_domain_for_dev(dev);
- }
-
- dev_info(dev, "32bit DMA uses non-identity mapping\n");
- }
-
- return true;
-}
-
static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
size_t size, int dir, u64 dma_mask)
{
@@ -3638,6 +3383,9 @@ static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
BUG_ON(dir == DMA_NONE);
+ if (unlikely(attach_deferred(dev)))
+ do_deferred_attach(dev);
+
domain = find_domain(dev);
if (!domain)
return DMA_MAPPING_ERROR;
@@ -3689,20 +3437,15 @@ static dma_addr_t intel_map_page(struct device *dev, struct page *page,
enum dma_data_direction dir,
unsigned long attrs)
{
- if (iommu_need_mapping(dev))
- return __intel_map_single(dev, page_to_phys(page) + offset,
- size, dir, *dev->dma_mask);
- return dma_direct_map_page(dev, page, offset, size, dir, attrs);
+ return __intel_map_single(dev, page_to_phys(page) + offset,
+ size, dir, *dev->dma_mask);
}
static dma_addr_t intel_map_resource(struct device *dev, phys_addr_t phys_addr,
size_t size, enum dma_data_direction dir,
unsigned long attrs)
{
- if (iommu_need_mapping(dev))
- return __intel_map_single(dev, phys_addr, size, dir,
- *dev->dma_mask);
- return dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
+ return __intel_map_single(dev, phys_addr, size, dir, *dev->dma_mask);
}
static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
@@ -3753,17 +3496,13 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
size_t size, enum dma_data_direction dir,
unsigned long attrs)
{
- if (iommu_need_mapping(dev))
- intel_unmap(dev, dev_addr, size);
- else
- dma_direct_unmap_page(dev, dev_addr, size, dir, attrs);
+ intel_unmap(dev, dev_addr, size);
}
static void intel_unmap_resource(struct device *dev, dma_addr_t dev_addr,
size_t size, enum dma_data_direction dir, unsigned long attrs)
{
- if (iommu_need_mapping(dev))
- intel_unmap(dev, dev_addr, size);
+ intel_unmap(dev, dev_addr, size);
}
static void *intel_alloc_coherent(struct device *dev, size_t size,
@@ -3773,8 +3512,8 @@ static void *intel_alloc_coherent(struct device *dev, size_t size,
struct page *page = NULL;
int order;
- if (!iommu_need_mapping(dev))
- return dma_direct_alloc(dev, size, dma_handle, flags, attrs);
+ if (unlikely(attach_deferred(dev)))
+ do_deferred_attach(dev);
size = PAGE_ALIGN(size);
order = get_order(size);
@@ -3809,9 +3548,6 @@ static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
int order;
struct page *page = virt_to_page(vaddr);
- if (!iommu_need_mapping(dev))
- return dma_direct_free(dev, size, vaddr, dma_handle, attrs);
-
size = PAGE_ALIGN(size);
order = get_order(size);
@@ -3829,9 +3565,6 @@ static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
struct scatterlist *sg;
int i;
- if (!iommu_need_mapping(dev))
- return dma_direct_unmap_sg(dev, sglist, nelems, dir, attrs);
-
for_each_sg(sglist, sg, nelems, i) {
nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
}
@@ -3855,8 +3588,9 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
struct intel_iommu *iommu;
BUG_ON(dir == DMA_NONE);
- if (!iommu_need_mapping(dev))
- return dma_direct_map_sg(dev, sglist, nelems, dir, attrs);
+
+ if (unlikely(attach_deferred(dev)))
+ do_deferred_attach(dev);
domain = find_domain(dev);
if (!domain)
@@ -3903,8 +3637,6 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
static u64 intel_get_required_mask(struct device *dev)
{
- if (!iommu_need_mapping(dev))
- return dma_direct_get_required_mask(dev);
return DMA_BIT_MASK(32);
}
@@ -4813,58 +4545,37 @@ static int intel_iommu_memory_notifier(struct notifier_block *nb,
unsigned long val, void *v)
{
struct memory_notify *mhp = v;
- unsigned long long start, end;
- unsigned long start_vpfn, last_vpfn;
+ unsigned long start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
+ unsigned long last_vpfn = mm_to_dma_pfn(mhp->start_pfn +
+ mhp->nr_pages - 1);
switch (val) {
case MEM_GOING_ONLINE:
- start = mhp->start_pfn << PAGE_SHIFT;
- end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
- if (iommu_domain_identity_map(si_domain, start, end)) {
- pr_warn("Failed to build identity map for [%llx-%llx]\n",
- start, end);
+ if (iommu_domain_identity_map(si_domain,
+ start_vpfn, last_vpfn)) {
+ pr_warn("Failed to build identity map for [%lx-%lx]\n",
+ start_vpfn, last_vpfn);
return NOTIFY_BAD;
}
break;
case MEM_OFFLINE:
case MEM_CANCEL_ONLINE:
- start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
- last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
- while (start_vpfn <= last_vpfn) {
- struct iova *iova;
+ {
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu;
struct page *freelist;
- iova = find_iova(&si_domain->iovad, start_vpfn);
- if (iova == NULL) {
- pr_debug("Failed get IOVA for PFN %lx\n",
- start_vpfn);
- break;
- }
-
- iova = split_and_remove_iova(&si_domain->iovad, iova,
- start_vpfn, last_vpfn);
- if (iova == NULL) {
- pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
- start_vpfn, last_vpfn);
- return NOTIFY_BAD;
- }
-
- freelist = domain_unmap(si_domain, iova->pfn_lo,
- iova->pfn_hi);
+ freelist = domain_unmap(si_domain,
+ start_vpfn, last_vpfn);
rcu_read_lock();
for_each_active_iommu(iommu, drhd)
iommu_flush_iotlb_psi(iommu, si_domain,
- iova->pfn_lo, iova_size(iova),
+ start_vpfn, mhp->nr_pages,
!freelist, 0);
rcu_read_unlock();
dma_free_pagelist(freelist);
-
- start_vpfn = iova->pfn_hi + 1;
- free_iova_mem(iova);
}
break;
}
@@ -4892,8 +4603,9 @@ static void free_all_cpu_cached_iovas(unsigned int cpu)
for (did = 0; did < cap_ndoms(iommu->cap); did++) {
domain = get_iommu_domain(iommu, (u16)did);
- if (!domain)
+ if (!domain || domain->domain.type != IOMMU_DOMAIN_DMA)
continue;
+
free_cpu_cached_iovas(cpu, &domain->iovad);
}
}
@@ -5186,18 +4898,6 @@ int __init intel_iommu_init(void)
}
up_write(&dmar_global_lock);
-#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
- /*
- * If the system has no untrusted device or the user has decided
- * to disable the bounce page mechanisms, we don't need swiotlb.
- * Mark this and the pre-allocated bounce pages will be released
- * later.
- */
- if (!has_untrusted_dev() || intel_no_bounce)
- swiotlb = 0;
-#endif
- dma_ops = &intel_dma_ops;
-
init_iommu_pm_ops();
down_read(&dmar_global_lock);
@@ -5283,10 +4983,11 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
if (info->dev) {
if (dev_is_pci(info->dev) && sm_supported(iommu))
intel_pasid_tear_down_entry(iommu, info->dev,
- PASID_RID2PASID);
+ PASID_RID2PASID, false);
iommu_disable_dev_iotlb(info);
- domain_context_clear(iommu, info->dev);
+ if (!dev_is_real_dma_subdevice(info->dev))
+ domain_context_clear(iommu, info->dev);
intel_pasid_free_table(info->dev);
}
@@ -5296,12 +4997,6 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
domain_detach_iommu(domain, iommu);
spin_unlock_irqrestore(&iommu->lock, flags);
- /* free the private domain */
- if (domain->flags & DOMAIN_FLAG_LOSE_CHILDREN &&
- !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
- list_empty(&domain->devices))
- domain_exit(info->domain);
-
free_devinfo_mem(info);
}
@@ -5311,9 +5006,8 @@ static void dmar_remove_one_dev_info(struct device *dev)
unsigned long flags;
spin_lock_irqsave(&device_domain_lock, flags);
- info = dev->archdata.iommu;
- if (info && info != DEFER_DEVICE_DOMAIN_INFO
- && info != DUMMY_DEVICE_DOMAIN_INFO)
+ info = get_domain_info(dev);
+ if (info)
__dmar_remove_one_dev_info(info);
spin_unlock_irqrestore(&device_domain_lock, flags);
}
@@ -5322,9 +5016,6 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
{
int adjust_width;
- init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
- domain_reserve_special_ranges(domain);
-
/* calculate AGAW */
domain->gaw = guest_width;
adjust_width = guestwidth_to_adjustwidth(guest_width);
@@ -5343,11 +5034,21 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
return 0;
}
+static void intel_init_iova_domain(struct dmar_domain *dmar_domain)
+{
+ init_iova_domain(&dmar_domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
+ copy_reserved_iova(&reserved_iova_list, &dmar_domain->iovad);
+
+ if (!intel_iommu_strict &&
+ init_iova_flush_queue(&dmar_domain->iovad,
+ iommu_flush_iova, iova_entry_free))
+ pr_info("iova flush queue initialization failed\n");
+}
+
static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
{
struct dmar_domain *dmar_domain;
struct iommu_domain *domain;
- int ret;
switch (type) {
case IOMMU_DOMAIN_DMA:
@@ -5364,13 +5065,8 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
return NULL;
}
- if (!intel_iommu_strict && type == IOMMU_DOMAIN_DMA) {
- ret = init_iova_flush_queue(&dmar_domain->iovad,
- iommu_flush_iova,
- iova_entry_free);
- if (ret)
- pr_info("iova flush queue initialization failed\n");
- }
+ if (type == IOMMU_DOMAIN_DMA)
+ intel_init_iova_domain(dmar_domain);
domain_update_iommu_cap(dmar_domain);
@@ -5403,7 +5099,7 @@ static void intel_iommu_domain_free(struct iommu_domain *domain)
static inline bool
is_aux_domain(struct device *dev, struct iommu_domain *domain)
{
- struct device_domain_info *info = dev->archdata.iommu;
+ struct device_domain_info *info = get_domain_info(dev);
return info && info->auxd_enabled &&
domain->type == IOMMU_DOMAIN_UNMANAGED;
@@ -5412,7 +5108,7 @@ is_aux_domain(struct device *dev, struct iommu_domain *domain)
static void auxiliary_link_device(struct dmar_domain *domain,
struct device *dev)
{
- struct device_domain_info *info = dev->archdata.iommu;
+ struct device_domain_info *info = get_domain_info(dev);
assert_spin_locked(&device_domain_lock);
if (WARN_ON(!info))
@@ -5425,7 +5121,7 @@ static void auxiliary_link_device(struct dmar_domain *domain,
static void auxiliary_unlink_device(struct dmar_domain *domain,
struct device *dev)
{
- struct device_domain_info *info = dev->archdata.iommu;
+ struct device_domain_info *info = get_domain_info(dev);
assert_spin_locked(&device_domain_lock);
if (WARN_ON(!info))
@@ -5513,13 +5209,13 @@ static void aux_domain_remove_dev(struct dmar_domain *domain,
return;
spin_lock_irqsave(&device_domain_lock, flags);
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
iommu = info->iommu;
auxiliary_unlink_device(domain, dev);
spin_lock(&iommu->lock);
- intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid);
+ intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid, false);
domain_detach_iommu(domain, iommu);
spin_unlock(&iommu->lock);
@@ -5626,6 +5322,176 @@ static void intel_iommu_aux_detach_device(struct iommu_domain *domain,
aux_domain_remove_dev(to_dmar_domain(domain), dev);
}
+/*
+ * 2D array for converting and sanitizing IOMMU generic TLB granularity to
+ * VT-d granularity. Invalidation is typically included in the unmap operation
+ * as a result of DMA or VFIO unmap. However, for assigned devices guest
+ * owns the first level page tables. Invalidations of translation caches in the
+ * guest are trapped and passed down to the host.
+ *
+ * vIOMMU in the guest will only expose first level page tables, therefore
+ * we do not support IOTLB granularity for request without PASID (second level).
+ *
+ * For example, to find the VT-d granularity encoding for IOTLB
+ * type and page selective granularity within PASID:
+ * X: indexed by iommu cache type
+ * Y: indexed by enum iommu_inv_granularity
+ * [IOMMU_CACHE_INV_TYPE_IOTLB][IOMMU_INV_GRANU_ADDR]
+ */
+
+static const int
+inv_type_granu_table[IOMMU_CACHE_INV_TYPE_NR][IOMMU_INV_GRANU_NR] = {
+ /*
+ * PASID based IOTLB invalidation: PASID selective (per PASID),
+ * page selective (address granularity)
+ */
+ {-EINVAL, QI_GRAN_NONG_PASID, QI_GRAN_PSI_PASID},
+ /* PASID based dev TLBs */
+ {-EINVAL, -EINVAL, QI_DEV_IOTLB_GRAN_PASID_SEL},
+ /* PASID cache */
+ {-EINVAL, -EINVAL, -EINVAL}
+};
+
+static inline int to_vtd_granularity(int type, int granu)
+{
+ return inv_type_granu_table[type][granu];
+}
+
+static inline u64 to_vtd_size(u64 granu_size, u64 nr_granules)
+{
+ u64 nr_pages = (granu_size * nr_granules) >> VTD_PAGE_SHIFT;
+
+ /* VT-d size is encoded as 2^size of 4K pages, 0 for 4k, 9 for 2MB, etc.
+ * IOMMU cache invalidate API passes granu_size in bytes, and number of
+ * granu size in contiguous memory.
+ */
+ return order_base_2(nr_pages);
+}
+
+#ifdef CONFIG_INTEL_IOMMU_SVM
+static int
+intel_iommu_sva_invalidate(struct iommu_domain *domain, struct device *dev,
+ struct iommu_cache_invalidate_info *inv_info)
+{
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ struct device_domain_info *info;
+ struct intel_iommu *iommu;
+ unsigned long flags;
+ int cache_type;
+ u8 bus, devfn;
+ u16 did, sid;
+ int ret = 0;
+ u64 size = 0;
+
+ if (!inv_info || !dmar_domain ||
+ inv_info->version != IOMMU_CACHE_INVALIDATE_INFO_VERSION_1)
+ return -EINVAL;
+
+ if (!dev || !dev_is_pci(dev))
+ return -ENODEV;
+
+ iommu = device_to_iommu(dev, &bus, &devfn);
+ if (!iommu)
+ return -ENODEV;
+
+ if (!(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE))
+ return -EINVAL;
+
+ spin_lock_irqsave(&device_domain_lock, flags);
+ spin_lock(&iommu->lock);
+ info = get_domain_info(dev);
+ if (!info) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+ did = dmar_domain->iommu_did[iommu->seq_id];
+ sid = PCI_DEVID(bus, devfn);
+
+ /* Size is only valid in address selective invalidation */
+ if (inv_info->granularity != IOMMU_INV_GRANU_PASID)
+ size = to_vtd_size(inv_info->addr_info.granule_size,
+ inv_info->addr_info.nb_granules);
+
+ for_each_set_bit(cache_type,
+ (unsigned long *)&inv_info->cache,
+ IOMMU_CACHE_INV_TYPE_NR) {
+ int granu = 0;
+ u64 pasid = 0;
+
+ granu = to_vtd_granularity(cache_type, inv_info->granularity);
+ if (granu == -EINVAL) {
+ pr_err_ratelimited("Invalid cache type and granu combination %d/%d\n",
+ cache_type, inv_info->granularity);
+ break;
+ }
+
+ /*
+ * PASID is stored in different locations based on the
+ * granularity.
+ */
+ if (inv_info->granularity == IOMMU_INV_GRANU_PASID &&
+ (inv_info->pasid_info.flags & IOMMU_INV_PASID_FLAGS_PASID))
+ pasid = inv_info->pasid_info.pasid;
+ else if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
+ (inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_PASID))
+ pasid = inv_info->addr_info.pasid;
+
+ switch (BIT(cache_type)) {
+ case IOMMU_CACHE_INV_TYPE_IOTLB:
+ if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
+ size &&
+ (inv_info->addr_info.addr & ((BIT(VTD_PAGE_SHIFT + size)) - 1))) {
+ pr_err_ratelimited("Address out of range, 0x%llx, size order %llu\n",
+ inv_info->addr_info.addr, size);
+ ret = -ERANGE;
+ goto out_unlock;
+ }
+
+ /*
+ * If granu is PASID-selective, address is ignored.
+ * We use npages = -1 to indicate that.
+ */
+ qi_flush_piotlb(iommu, did, pasid,
+ mm_to_dma_pfn(inv_info->addr_info.addr),
+ (granu == QI_GRAN_NONG_PASID) ? -1 : 1 << size,
+ inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_LEAF);
+
+ /*
+ * Always flush device IOTLB if ATS is enabled. vIOMMU
+ * in the guest may assume IOTLB flush is inclusive,
+ * which is more efficient.
+ */
+ if (info->ats_enabled)
+ qi_flush_dev_iotlb_pasid(iommu, sid,
+ info->pfsid, pasid,
+ info->ats_qdep,
+ inv_info->addr_info.addr,
+ size, granu);
+ break;
+ case IOMMU_CACHE_INV_TYPE_DEV_IOTLB:
+ if (info->ats_enabled)
+ qi_flush_dev_iotlb_pasid(iommu, sid,
+ info->pfsid, pasid,
+ info->ats_qdep,
+ inv_info->addr_info.addr,
+ size, granu);
+ else
+ pr_warn_ratelimited("Passdown device IOTLB flush w/o ATS!\n");
+ break;
+ default:
+ dev_err_ratelimited(dev, "Unsupported IOMMU invalidation type %d\n",
+ cache_type);
+ ret = -EINVAL;
+ }
+ }
+out_unlock:
+ spin_unlock(&iommu->lock);
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+
+ return ret;
+}
+#endif
+
static int intel_iommu_map(struct iommu_domain *domain,
unsigned long iova, phys_addr_t hpa,
size_t size, int iommu_prot, gfp_t gfp)
@@ -5781,78 +5647,22 @@ static bool intel_iommu_capable(enum iommu_cap cap)
return false;
}
-static int intel_iommu_add_device(struct device *dev)
+static struct iommu_device *intel_iommu_probe_device(struct device *dev)
{
- struct dmar_domain *dmar_domain;
- struct iommu_domain *domain;
struct intel_iommu *iommu;
- struct iommu_group *group;
u8 bus, devfn;
- int ret;
iommu = device_to_iommu(dev, &bus, &devfn);
if (!iommu)
- return -ENODEV;
-
- iommu_device_link(&iommu->iommu, dev);
+ return ERR_PTR(-ENODEV);
if (translation_pre_enabled(iommu))
dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
- group = iommu_group_get_for_dev(dev);
-
- if (IS_ERR(group)) {
- ret = PTR_ERR(group);
- goto unlink;
- }
-
- iommu_group_put(group);
-
- domain = iommu_get_domain_for_dev(dev);
- dmar_domain = to_dmar_domain(domain);
- if (domain->type == IOMMU_DOMAIN_DMA) {
- if (device_def_domain_type(dev) == IOMMU_DOMAIN_IDENTITY) {
- ret = iommu_request_dm_for_dev(dev);
- if (ret) {
- dmar_remove_one_dev_info(dev);
- dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
- domain_add_dev_info(si_domain, dev);
- dev_info(dev,
- "Device uses a private identity domain.\n");
- }
- }
- } else {
- if (device_def_domain_type(dev) == IOMMU_DOMAIN_DMA) {
- ret = iommu_request_dma_domain_for_dev(dev);
- if (ret) {
- dmar_remove_one_dev_info(dev);
- dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
- if (!get_private_domain_for_dev(dev)) {
- dev_warn(dev,
- "Failed to get a private domain.\n");
- ret = -ENOMEM;
- goto unlink;
- }
-
- dev_info(dev,
- "Device uses a private dma domain.\n");
- }
- }
- }
-
- if (device_needs_bounce(dev)) {
- dev_info(dev, "Use Intel IOMMU bounce page dma_ops\n");
- set_dma_ops(dev, &bounce_dma_ops);
- }
-
- return 0;
-
-unlink:
- iommu_device_unlink(&iommu->iommu, dev);
- return ret;
+ return &iommu->iommu;
}
-static void intel_iommu_remove_device(struct device *dev)
+static void intel_iommu_release_device(struct device *dev)
{
struct intel_iommu *iommu;
u8 bus, devfn;
@@ -5863,11 +5673,19 @@ static void intel_iommu_remove_device(struct device *dev)
dmar_remove_one_dev_info(dev);
- iommu_group_remove_device(dev);
+ set_dma_ops(dev, NULL);
+}
- iommu_device_unlink(&iommu->iommu, dev);
+static void intel_iommu_probe_finalize(struct device *dev)
+{
+ struct iommu_domain *domain;
+ domain = iommu_get_domain_for_dev(dev);
if (device_needs_bounce(dev))
+ set_dma_ops(dev, &bounce_dma_ops);
+ else if (domain && domain->type == IOMMU_DOMAIN_DMA)
+ set_dma_ops(dev, &intel_dma_ops);
+ else
set_dma_ops(dev, NULL);
}
@@ -5945,7 +5763,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
spin_lock(&iommu->lock);
ret = -EINVAL;
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (!info || !info->pasid_supported)
goto out;
@@ -6041,7 +5859,7 @@ static int intel_iommu_enable_auxd(struct device *dev)
return -ENODEV;
spin_lock_irqsave(&device_domain_lock, flags);
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
info->auxd_enabled = 1;
spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -6054,7 +5872,7 @@ static int intel_iommu_disable_auxd(struct device *dev)
unsigned long flags;
spin_lock_irqsave(&device_domain_lock, flags);
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (!WARN_ON(!info))
info->auxd_enabled = 0;
spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -6107,6 +5925,14 @@ intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
return !!siov_find_pci_dvsec(to_pci_dev(dev));
}
+ if (feat == IOMMU_DEV_FEAT_SVA) {
+ struct device_domain_info *info = get_domain_info(dev);
+
+ return info && (info->iommu->flags & VTD_FLAG_SVM_CAPABLE) &&
+ info->pasid_supported && info->pri_supported &&
+ info->ats_supported;
+ }
+
return false;
}
@@ -6116,6 +5942,16 @@ intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
if (feat == IOMMU_DEV_FEAT_AUX)
return intel_iommu_enable_auxd(dev);
+ if (feat == IOMMU_DEV_FEAT_SVA) {
+ struct device_domain_info *info = get_domain_info(dev);
+
+ if (!info)
+ return -EINVAL;
+
+ if (info->iommu->flags & VTD_FLAG_SVM_CAPABLE)
+ return 0;
+ }
+
return -ENODEV;
}
@@ -6131,7 +5967,7 @@ intel_iommu_dev_disable_feat(struct device *dev, enum iommu_dev_features feat)
static bool
intel_iommu_dev_feat_enabled(struct device *dev, enum iommu_dev_features feat)
{
- struct device_domain_info *info = dev->archdata.iommu;
+ struct device_domain_info *info = get_domain_info(dev);
if (feat == IOMMU_DEV_FEAT_AUX)
return scalable_mode_support() && info && info->auxd_enabled;
@@ -6198,8 +6034,9 @@ const struct iommu_ops intel_iommu_ops = {
.map = intel_iommu_map,
.unmap = intel_iommu_unmap,
.iova_to_phys = intel_iommu_iova_to_phys,
- .add_device = intel_iommu_add_device,
- .remove_device = intel_iommu_remove_device,
+ .probe_device = intel_iommu_probe_device,
+ .probe_finalize = intel_iommu_probe_finalize,
+ .release_device = intel_iommu_release_device,
.get_resv_regions = intel_iommu_get_resv_regions,
.put_resv_regions = generic_iommu_put_resv_regions,
.apply_resv_region = intel_iommu_apply_resv_region,
@@ -6209,7 +6046,16 @@ const struct iommu_ops intel_iommu_ops = {
.dev_enable_feat = intel_iommu_dev_enable_feat,
.dev_disable_feat = intel_iommu_dev_disable_feat,
.is_attach_deferred = intel_iommu_is_attach_deferred,
+ .def_domain_type = device_def_domain_type,
.pgsize_bitmap = INTEL_IOMMU_PGSIZES,
+#ifdef CONFIG_INTEL_IOMMU_SVM
+ .cache_invalidate = intel_iommu_sva_invalidate,
+ .sva_bind_gpasid = intel_svm_bind_gpasid,
+ .sva_unbind_gpasid = intel_svm_unbind_gpasid,
+ .sva_bind = intel_svm_bind,
+ .sva_unbind = intel_svm_unbind,
+ .sva_get_pasid = intel_svm_get_pasid,
+#endif
};
static void quirk_iommu_igfx(struct pci_dev *dev)
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel/irq_remapping.c
index 81e43c1df7ec..7f8769800815 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel/irq_remapping.c
@@ -21,7 +21,7 @@
#include <asm/pci-direct.h>
#include <asm/msidef.h>
-#include "irq_remapping.h"
+#include "../irq_remapping.h"
enum irq_mode {
IRQ_REMAPPING,
@@ -151,7 +151,7 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
desc.qw2 = 0;
desc.qw3 = 0;
- return qi_submit_sync(&desc, iommu);
+ return qi_submit_sync(iommu, &desc, 1, 0);
}
static int modify_irte(struct irq_2_iommu *irq_iommu,
diff --git a/drivers/iommu/intel-pasid.c b/drivers/iommu/intel/pasid.c
index 22b30f10b396..c81f0f17c6ba 100644
--- a/drivers/iommu/intel-pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -27,6 +27,63 @@
static DEFINE_SPINLOCK(pasid_lock);
u32 intel_pasid_max_id = PASID_MAX;
+int vcmd_alloc_pasid(struct intel_iommu *iommu, unsigned int *pasid)
+{
+ unsigned long flags;
+ u8 status_code;
+ int ret = 0;
+ u64 res;
+
+ raw_spin_lock_irqsave(&iommu->register_lock, flags);
+ dmar_writeq(iommu->reg + DMAR_VCMD_REG, VCMD_CMD_ALLOC);
+ IOMMU_WAIT_OP(iommu, DMAR_VCRSP_REG, dmar_readq,
+ !(res & VCMD_VRSP_IP), res);
+ raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
+
+ status_code = VCMD_VRSP_SC(res);
+ switch (status_code) {
+ case VCMD_VRSP_SC_SUCCESS:
+ *pasid = VCMD_VRSP_RESULT_PASID(res);
+ break;
+ case VCMD_VRSP_SC_NO_PASID_AVAIL:
+ pr_info("IOMMU: %s: No PASID available\n", iommu->name);
+ ret = -ENOSPC;
+ break;
+ default:
+ ret = -ENODEV;
+ pr_warn("IOMMU: %s: Unexpected error code %d\n",
+ iommu->name, status_code);
+ }
+
+ return ret;
+}
+
+void vcmd_free_pasid(struct intel_iommu *iommu, unsigned int pasid)
+{
+ unsigned long flags;
+ u8 status_code;
+ u64 res;
+
+ raw_spin_lock_irqsave(&iommu->register_lock, flags);
+ dmar_writeq(iommu->reg + DMAR_VCMD_REG,
+ VCMD_CMD_OPERAND(pasid) | VCMD_CMD_FREE);
+ IOMMU_WAIT_OP(iommu, DMAR_VCRSP_REG, dmar_readq,
+ !(res & VCMD_VRSP_IP), res);
+ raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
+
+ status_code = VCMD_VRSP_SC(res);
+ switch (status_code) {
+ case VCMD_VRSP_SC_SUCCESS:
+ break;
+ case VCMD_VRSP_SC_INVALID_PASID:
+ pr_info("IOMMU: %s: Invalid PASID\n", iommu->name);
+ break;
+ default:
+ pr_warn("IOMMU: %s: Unexpected error code %d\n",
+ iommu->name, status_code);
+ }
+}
+
/*
* Per device pasid table management:
*/
@@ -94,7 +151,7 @@ int intel_pasid_alloc_table(struct device *dev)
int size;
might_sleep();
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table))
return -EINVAL;
@@ -141,7 +198,7 @@ void intel_pasid_free_table(struct device *dev)
struct pasid_entry *table;
int i, max_pde;
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (!info || !dev_is_pci(dev) || !info->pasid_table)
return;
@@ -167,7 +224,7 @@ struct pasid_table *intel_pasid_get_table(struct device *dev)
{
struct device_domain_info *info;
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (!info)
return NULL;
@@ -178,7 +235,7 @@ int intel_pasid_get_dev_max_id(struct device *dev)
{
struct device_domain_info *info;
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (!info || !info->pasid_table)
return 0;
@@ -199,7 +256,7 @@ struct pasid_entry *intel_pasid_get_entry(struct device *dev, int pasid)
return NULL;
dir = pasid_table->table;
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
dir_index = pasid >> PASID_PDE_SHIFT;
index = pasid & PASID_PTE_MASK;
@@ -235,7 +292,20 @@ static inline void pasid_clear_entry(struct pasid_entry *pe)
WRITE_ONCE(pe->val[7], 0);
}
-static void intel_pasid_clear_entry(struct device *dev, int pasid)
+static inline void pasid_clear_entry_with_fpd(struct pasid_entry *pe)
+{
+ WRITE_ONCE(pe->val[0], PASID_PTE_FPD);
+ WRITE_ONCE(pe->val[1], 0);
+ WRITE_ONCE(pe->val[2], 0);
+ WRITE_ONCE(pe->val[3], 0);
+ WRITE_ONCE(pe->val[4], 0);
+ WRITE_ONCE(pe->val[5], 0);
+ WRITE_ONCE(pe->val[6], 0);
+ WRITE_ONCE(pe->val[7], 0);
+}
+
+static void
+intel_pasid_clear_entry(struct device *dev, int pasid, bool fault_ignore)
{
struct pasid_entry *pe;
@@ -243,7 +313,10 @@ static void intel_pasid_clear_entry(struct device *dev, int pasid)
if (WARN_ON(!pe))
return;
- pasid_clear_entry(pe);
+ if (fault_ignore && pasid_pte_is_present(pe))
+ pasid_clear_entry_with_fpd(pe);
+ else
+ pasid_clear_entry(pe);
}
static inline void pasid_set_bits(u64 *ptr, u64 mask, u64 bits)
@@ -359,18 +432,29 @@ pasid_set_flpm(struct pasid_entry *pe, u64 value)
pasid_set_bits(&pe->val[2], GENMASK_ULL(3, 2), value << 2);
}
+/*
+ * Setup the Extended Access Flag Enable (EAFE) field (Bit 135)
+ * of a scalable mode PASID entry.
+ */
+static inline void
+pasid_set_eafe(struct pasid_entry *pe)
+{
+ pasid_set_bits(&pe->val[2], 1 << 7, 1 << 7);
+}
+
static void
pasid_cache_invalidation_with_pasid(struct intel_iommu *iommu,
u16 did, int pasid)
{
struct qi_desc desc;
- desc.qw0 = QI_PC_DID(did) | QI_PC_PASID_SEL | QI_PC_PASID(pasid);
+ desc.qw0 = QI_PC_DID(did) | QI_PC_GRAN(QI_PC_PASID_SEL) |
+ QI_PC_PASID(pasid) | QI_PC_TYPE;
desc.qw1 = 0;
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
}
static void
@@ -384,7 +468,7 @@ iotlb_invalidation_with_pasid(struct intel_iommu *iommu, u16 did, u32 pasid)
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, iommu);
+ qi_submit_sync(iommu, &desc, 1, 0);
}
static void
@@ -394,7 +478,7 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu,
struct device_domain_info *info;
u16 sid, qdep, pfsid;
- info = dev->archdata.iommu;
+ info = get_domain_info(dev);
if (!info || !info->ats_enabled)
return;
@@ -405,8 +489,8 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu,
qi_flush_dev_iotlb(iommu, sid, pfsid, qdep, 0, 64 - VTD_PAGE_SHIFT);
}
-void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
- struct device *dev, int pasid)
+void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
+ int pasid, bool fault_ignore)
{
struct pasid_entry *pte;
u16 did;
@@ -416,7 +500,7 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
return;
did = pasid_get_domain_id(pte);
- intel_pasid_clear_entry(dev, pasid);
+ intel_pasid_clear_entry(dev, pasid, fault_ignore);
if (!ecap_coherent(iommu->ecap))
clflush_cache_range(pte, sizeof(*pte));
@@ -492,7 +576,7 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
/* Setup Present and PASID Granular Transfer Type: */
- pasid_set_translation_type(pte, 1);
+ pasid_set_translation_type(pte, PASID_ENTRY_PGTT_FL_ONLY);
pasid_set_present(pte);
pasid_flush_caches(iommu, pte, pasid, did);
@@ -500,6 +584,25 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
}
/*
+ * Skip top levels of page tables for iommu which has less agaw
+ * than default. Unnecessary for PT mode.
+ */
+static inline int iommu_skip_agaw(struct dmar_domain *domain,
+ struct intel_iommu *iommu,
+ struct dma_pte **pgd)
+{
+ int agaw;
+
+ for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
+ *pgd = phys_to_virt(dma_pte_addr(*pgd));
+ if (!dma_pte_present(*pgd))
+ return -EINVAL;
+ }
+
+ return agaw;
+}
+
+/*
* Set up the scalable mode pasid entry for second only translation type.
*/
int intel_pasid_setup_second_level(struct intel_iommu *iommu,
@@ -522,17 +625,11 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
return -EINVAL;
}
- /*
- * Skip top levels of page tables for iommu which has less agaw
- * than default. Unnecessary for PT mode.
- */
pgd = domain->pgd;
- for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
- pgd = phys_to_virt(dma_pte_addr(pgd));
- if (!dma_pte_present(pgd)) {
- dev_err(dev, "Invalid domain page table\n");
- return -EINVAL;
- }
+ agaw = iommu_skip_agaw(domain, iommu, &pgd);
+ if (agaw < 0) {
+ dev_err(dev, "Invalid domain page table\n");
+ return -EINVAL;
}
pgd_val = virt_to_phys(pgd);
@@ -548,7 +645,7 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
pasid_set_domain_id(pte, did);
pasid_set_slptr(pte, pgd_val);
pasid_set_address_width(pte, agaw);
- pasid_set_translation_type(pte, 2);
+ pasid_set_translation_type(pte, PASID_ENTRY_PGTT_SL_ONLY);
pasid_set_fault_enable(pte);
pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
@@ -582,7 +679,7 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
pasid_clear_entry(pte);
pasid_set_domain_id(pte, did);
pasid_set_address_width(pte, iommu->agaw);
- pasid_set_translation_type(pte, 4);
+ pasid_set_translation_type(pte, PASID_ENTRY_PGTT_PT);
pasid_set_fault_enable(pte);
pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
@@ -596,3 +693,161 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
return 0;
}
+
+static int
+intel_pasid_setup_bind_data(struct intel_iommu *iommu, struct pasid_entry *pte,
+ struct iommu_gpasid_bind_data_vtd *pasid_data)
+{
+ /*
+ * Not all guest PASID table entry fields are passed down during bind,
+ * here we only set up the ones that are dependent on guest settings.
+ * Execution related bits such as NXE, SMEP are not supported.
+ * Other fields, such as snoop related, are set based on host needs
+ * regardless of guest settings.
+ */
+ if (pasid_data->flags & IOMMU_SVA_VTD_GPASID_SRE) {
+ if (!ecap_srs(iommu->ecap)) {
+ pr_err_ratelimited("No supervisor request support on %s\n",
+ iommu->name);
+ return -EINVAL;
+ }
+ pasid_set_sre(pte);
+ }
+
+ if (pasid_data->flags & IOMMU_SVA_VTD_GPASID_EAFE) {
+ if (!ecap_eafs(iommu->ecap)) {
+ pr_err_ratelimited("No extended access flag support on %s\n",
+ iommu->name);
+ return -EINVAL;
+ }
+ pasid_set_eafe(pte);
+ }
+
+ /*
+ * Memory type is only applicable to devices inside processor coherent
+ * domain. Will add MTS support once coherent devices are available.
+ */
+ if (pasid_data->flags & IOMMU_SVA_VTD_GPASID_MTS_MASK) {
+ pr_warn_ratelimited("No memory type support %s\n",
+ iommu->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * intel_pasid_setup_nested() - Set up PASID entry for nested translation.
+ * This could be used for guest shared virtual address. In this case, the
+ * first level page tables are used for GVA-GPA translation in the guest,
+ * second level page tables are used for GPA-HPA translation.
+ *
+ * @iommu: IOMMU which the device belong to
+ * @dev: Device to be set up for translation
+ * @gpgd: FLPTPTR: First Level Page translation pointer in GPA
+ * @pasid: PASID to be programmed in the device PASID table
+ * @pasid_data: Additional PASID info from the guest bind request
+ * @domain: Domain info for setting up second level page tables
+ * @addr_width: Address width of the first level (guest)
+ */
+int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
+ pgd_t *gpgd, int pasid,
+ struct iommu_gpasid_bind_data_vtd *pasid_data,
+ struct dmar_domain *domain, int addr_width)
+{
+ struct pasid_entry *pte;
+ struct dma_pte *pgd;
+ int ret = 0;
+ u64 pgd_val;
+ int agaw;
+ u16 did;
+
+ if (!ecap_nest(iommu->ecap)) {
+ pr_err_ratelimited("IOMMU: %s: No nested translation support\n",
+ iommu->name);
+ return -EINVAL;
+ }
+
+ if (!(domain->flags & DOMAIN_FLAG_NESTING_MODE)) {
+ pr_err_ratelimited("Domain is not in nesting mode, %x\n",
+ domain->flags);
+ return -EINVAL;
+ }
+
+ pte = intel_pasid_get_entry(dev, pasid);
+ if (WARN_ON(!pte))
+ return -EINVAL;
+
+ /*
+ * Caller must ensure PASID entry is not in use, i.e. not bind the
+ * same PASID to the same device twice.
+ */
+ if (pasid_pte_is_present(pte))
+ return -EBUSY;
+
+ pasid_clear_entry(pte);
+
+ /* Sanity checking performed by caller to make sure address
+ * width matching in two dimensions:
+ * 1. CPU vs. IOMMU
+ * 2. Guest vs. Host.
+ */
+ switch (addr_width) {
+#ifdef CONFIG_X86
+ case ADDR_WIDTH_5LEVEL:
+ if (!cpu_feature_enabled(X86_FEATURE_LA57) ||
+ !cap_5lp_support(iommu->cap)) {
+ dev_err_ratelimited(dev,
+ "5-level paging not supported\n");
+ return -EINVAL;
+ }
+
+ pasid_set_flpm(pte, 1);
+ break;
+#endif
+ case ADDR_WIDTH_4LEVEL:
+ pasid_set_flpm(pte, 0);
+ break;
+ default:
+ dev_err_ratelimited(dev, "Invalid guest address width %d\n",
+ addr_width);
+ return -EINVAL;
+ }
+
+ /* First level PGD is in GPA, must be supported by the second level */
+ if ((uintptr_t)gpgd > domain->max_addr) {
+ dev_err_ratelimited(dev,
+ "Guest PGD %lx not supported, max %llx\n",
+ (uintptr_t)gpgd, domain->max_addr);
+ return -EINVAL;
+ }
+ pasid_set_flptr(pte, (uintptr_t)gpgd);
+
+ ret = intel_pasid_setup_bind_data(iommu, pte, pasid_data);
+ if (ret)
+ return ret;
+
+ /* Setup the second level based on the given domain */
+ pgd = domain->pgd;
+
+ agaw = iommu_skip_agaw(domain, iommu, &pgd);
+ if (agaw < 0) {
+ dev_err_ratelimited(dev, "Invalid domain page table\n");
+ return -EINVAL;
+ }
+ pgd_val = virt_to_phys(pgd);
+ pasid_set_slptr(pte, pgd_val);
+ pasid_set_fault_enable(pte);
+
+ did = domain->iommu_did[iommu->seq_id];
+ pasid_set_domain_id(pte, did);
+
+ pasid_set_address_width(pte, agaw);
+ pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
+
+ pasid_set_translation_type(pte, PASID_ENTRY_PGTT_NESTED);
+ pasid_set_present(pte);
+ pasid_flush_caches(iommu, pte, pasid, did);
+
+ return ret;
+}
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel/svm.c
index 2998418f0a38..6c87c807a0ab 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -23,6 +23,7 @@
#include "intel-pasid.h"
static irqreturn_t prq_event_thread(int irq, void *d);
+static void intel_svm_drain_prq(struct device *dev, int pasid);
#define PRQ_ORDER 0
@@ -66,6 +67,8 @@ int intel_svm_enable_prq(struct intel_iommu *iommu)
dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
dmar_writeq(iommu->reg + DMAR_PQA_REG, virt_to_phys(iommu->prq) | PRQ_ORDER);
+ init_completion(&iommu->prq_complete);
+
return 0;
}
@@ -138,7 +141,7 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d
}
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, svm->iommu);
+ qi_submit_sync(svm->iommu, &desc, 1, 0);
if (sdev->dev_iotlb) {
desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) |
@@ -162,7 +165,7 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d
}
desc.qw2 = 0;
desc.qw3 = 0;
- qi_submit_sync(&desc, svm->iommu);
+ qi_submit_sync(svm->iommu, &desc, 1, 0);
}
}
@@ -206,10 +209,9 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
* *has* to handle gracefully without affecting other processes.
*/
rcu_read_lock();
- list_for_each_entry_rcu(sdev, &svm->devs, list) {
- intel_pasid_tear_down_entry(svm->iommu, sdev->dev, svm->pasid);
- intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
- }
+ list_for_each_entry_rcu(sdev, &svm->devs, list)
+ intel_pasid_tear_down_entry(svm->iommu, sdev->dev,
+ svm->pasid, true);
rcu_read_unlock();
}
@@ -226,13 +228,212 @@ static LIST_HEAD(global_svm_list);
list_for_each_entry((sdev), &(svm)->devs, list) \
if ((d) != (sdev)->dev) {} else
-int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops)
+int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev,
+ struct iommu_gpasid_bind_data *data)
+{
+ struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
+ struct dmar_domain *dmar_domain;
+ struct intel_svm_dev *sdev;
+ struct intel_svm *svm;
+ int ret = 0;
+
+ if (WARN_ON(!iommu) || !data)
+ return -EINVAL;
+
+ if (data->version != IOMMU_GPASID_BIND_VERSION_1 ||
+ data->format != IOMMU_PASID_FORMAT_INTEL_VTD)
+ return -EINVAL;
+
+ if (!dev_is_pci(dev))
+ return -ENOTSUPP;
+
+ /* VT-d supports devices with full 20 bit PASIDs only */
+ if (pci_max_pasids(to_pci_dev(dev)) != PASID_MAX)
+ return -EINVAL;
+
+ /*
+ * We only check host PASID range, we have no knowledge to check
+ * guest PASID range.
+ */
+ if (data->hpasid <= 0 || data->hpasid >= PASID_MAX)
+ return -EINVAL;
+
+ dmar_domain = to_dmar_domain(domain);
+
+ mutex_lock(&pasid_mutex);
+ svm = ioasid_find(NULL, data->hpasid, NULL);
+ if (IS_ERR(svm)) {
+ ret = PTR_ERR(svm);
+ goto out;
+ }
+
+ if (svm) {
+ /*
+ * If we found svm for the PASID, there must be at
+ * least one device bond, otherwise svm should be freed.
+ */
+ if (WARN_ON(list_empty(&svm->devs))) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ for_each_svm_dev(sdev, svm, dev) {
+ /*
+ * For devices with aux domains, we should allow
+ * multiple bind calls with the same PASID and pdev.
+ */
+ if (iommu_dev_feature_enabled(dev,
+ IOMMU_DEV_FEAT_AUX)) {
+ sdev->users++;
+ } else {
+ dev_warn_ratelimited(dev,
+ "Already bound with PASID %u\n",
+ svm->pasid);
+ ret = -EBUSY;
+ }
+ goto out;
+ }
+ } else {
+ /* We come here when PASID has never been bond to a device. */
+ svm = kzalloc(sizeof(*svm), GFP_KERNEL);
+ if (!svm) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ /* REVISIT: upper layer/VFIO can track host process that bind
+ * the PASID. ioasid_set = mm might be sufficient for vfio to
+ * check pasid VMM ownership. We can drop the following line
+ * once VFIO and IOASID set check is in place.
+ */
+ svm->mm = get_task_mm(current);
+ svm->pasid = data->hpasid;
+ if (data->flags & IOMMU_SVA_GPASID_VAL) {
+ svm->gpasid = data->gpasid;
+ svm->flags |= SVM_FLAG_GUEST_PASID;
+ }
+ ioasid_set_data(data->hpasid, svm);
+ INIT_LIST_HEAD_RCU(&svm->devs);
+ mmput(svm->mm);
+ }
+ sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+ if (!sdev) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ sdev->dev = dev;
+
+ /* Only count users if device has aux domains */
+ if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX))
+ sdev->users = 1;
+
+ /* Set up device context entry for PASID if not enabled already */
+ ret = intel_iommu_enable_pasid(iommu, sdev->dev);
+ if (ret) {
+ dev_err_ratelimited(dev, "Failed to enable PASID capability\n");
+ kfree(sdev);
+ goto out;
+ }
+
+ /*
+ * PASID table is per device for better security. Therefore, for
+ * each bind of a new device even with an existing PASID, we need to
+ * call the nested mode setup function here.
+ */
+ spin_lock(&iommu->lock);
+ ret = intel_pasid_setup_nested(iommu, dev,
+ (pgd_t *)(uintptr_t)data->gpgd,
+ data->hpasid, &data->vtd, dmar_domain,
+ data->addr_width);
+ spin_unlock(&iommu->lock);
+ if (ret) {
+ dev_err_ratelimited(dev, "Failed to set up PASID %llu in nested mode, Err %d\n",
+ data->hpasid, ret);
+ /*
+ * PASID entry should be in cleared state if nested mode
+ * set up failed. So we only need to clear IOASID tracking
+ * data such that free call will succeed.
+ */
+ kfree(sdev);
+ goto out;
+ }
+
+ svm->flags |= SVM_FLAG_GUEST_MODE;
+
+ init_rcu_head(&sdev->rcu);
+ list_add_rcu(&sdev->list, &svm->devs);
+ out:
+ if (!IS_ERR_OR_NULL(svm) && list_empty(&svm->devs)) {
+ ioasid_set_data(data->hpasid, NULL);
+ kfree(svm);
+ }
+
+ mutex_unlock(&pasid_mutex);
+ return ret;
+}
+
+int intel_svm_unbind_gpasid(struct device *dev, int pasid)
+{
+ struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
+ struct intel_svm_dev *sdev;
+ struct intel_svm *svm;
+ int ret = -EINVAL;
+
+ if (WARN_ON(!iommu))
+ return -EINVAL;
+
+ mutex_lock(&pasid_mutex);
+ svm = ioasid_find(NULL, pasid, NULL);
+ if (!svm) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (IS_ERR(svm)) {
+ ret = PTR_ERR(svm);
+ goto out;
+ }
+
+ for_each_svm_dev(sdev, svm, dev) {
+ ret = 0;
+ if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX))
+ sdev->users--;
+ if (!sdev->users) {
+ list_del_rcu(&sdev->list);
+ intel_pasid_tear_down_entry(iommu, dev,
+ svm->pasid, false);
+ intel_svm_drain_prq(dev, svm->pasid);
+ kfree_rcu(sdev, rcu);
+
+ if (list_empty(&svm->devs)) {
+ /*
+ * We do not free the IOASID here in that
+ * IOMMU driver did not allocate it.
+ * Unlike native SVM, IOASID for guest use was
+ * allocated prior to the bind call.
+ * In any case, if the free call comes before
+ * the unbind, IOMMU driver will get notified
+ * and perform cleanup.
+ */
+ ioasid_set_data(pasid, NULL);
+ kfree(svm);
+ }
+ }
+ break;
+ }
+out:
+ mutex_unlock(&pasid_mutex);
+ return ret;
+}
+
+/* Caller must hold pasid_mutex, mm reference */
+static int
+intel_svm_bind_mm(struct device *dev, int flags, struct svm_dev_ops *ops,
+ struct mm_struct *mm, struct intel_svm_dev **sd)
{
struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
struct device_domain_info *info;
struct intel_svm_dev *sdev;
struct intel_svm *svm = NULL;
- struct mm_struct *mm = NULL;
int pasid_max;
int ret;
@@ -249,16 +450,15 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
} else
pasid_max = 1 << 20;
+ /* Bind supervisor PASID shuld have mm = NULL */
if (flags & SVM_FLAG_SUPERVISOR_MODE) {
- if (!ecap_srs(iommu->ecap))
+ if (!ecap_srs(iommu->ecap) || mm) {
+ pr_err("Supervisor PASID with user provided mm.\n");
return -EINVAL;
- } else if (pasid) {
- mm = get_task_mm(current);
- BUG_ON(!mm);
+ }
}
- mutex_lock(&pasid_mutex);
- if (pasid && !(flags & SVM_FLAG_PRIVATE_PASID)) {
+ if (!(flags & SVM_FLAG_PRIVATE_PASID)) {
struct intel_svm *t;
list_for_each_entry(t, &global_svm_list, list) {
@@ -296,19 +496,12 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
sdev->dev = dev;
ret = intel_iommu_enable_pasid(iommu, dev);
- if (ret || !pasid) {
- /* If they don't actually want to assign a PASID, this is
- * just an enabling check/preparation. */
- kfree(sdev);
- goto out;
- }
-
- info = dev->archdata.iommu;
- if (!info || !info->pasid_supported) {
+ if (ret) {
kfree(sdev);
goto out;
}
+ info = get_domain_info(dev);
sdev->did = FLPT_DEFAULT_DID;
sdev->sid = PCI_DEVID(info->bus, info->devfn);
if (info->ats_enabled) {
@@ -397,26 +590,24 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
}
}
list_add_rcu(&sdev->list, &svm->devs);
-
- success:
- *pasid = svm->pasid;
+success:
+ sdev->pasid = svm->pasid;
+ sdev->sva.dev = dev;
+ if (sd)
+ *sd = sdev;
ret = 0;
out:
- mutex_unlock(&pasid_mutex);
- if (mm)
- mmput(mm);
return ret;
}
-EXPORT_SYMBOL_GPL(intel_svm_bind_mm);
-int intel_svm_unbind_mm(struct device *dev, int pasid)
+/* Caller must hold pasid_mutex */
+static int intel_svm_unbind_mm(struct device *dev, int pasid)
{
struct intel_svm_dev *sdev;
struct intel_iommu *iommu;
struct intel_svm *svm;
int ret = -EINVAL;
- mutex_lock(&pasid_mutex);
iommu = intel_svm_device_to_iommu(dev);
if (!iommu)
goto out;
@@ -442,8 +633,9 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
* to use. We have a *shared* PASID table, because it's
* large and has to be physically contiguous. So it's
* hard to be as defensive as we might like. */
- intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
- intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
+ intel_pasid_tear_down_entry(iommu, dev,
+ svm->pasid, false);
+ intel_svm_drain_prq(dev, svm->pasid);
kfree_rcu(sdev, rcu);
if (list_empty(&svm->devs)) {
@@ -462,45 +654,9 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
break;
}
out:
- mutex_unlock(&pasid_mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);
-
-int intel_svm_is_pasid_valid(struct device *dev, int pasid)
-{
- struct intel_iommu *iommu;
- struct intel_svm *svm;
- int ret = -EINVAL;
-
- mutex_lock(&pasid_mutex);
- iommu = intel_svm_device_to_iommu(dev);
- if (!iommu)
- goto out;
-
- svm = ioasid_find(NULL, pasid, NULL);
- if (!svm)
- goto out;
-
- if (IS_ERR(svm)) {
- ret = PTR_ERR(svm);
- goto out;
- }
- /* init_mm is used in this case */
- if (!svm->mm)
- ret = 1;
- else if (atomic_read(&svm->mm->mm_users) > 0)
- ret = 1;
- else
- ret = 0;
-
- out:
- mutex_unlock(&pasid_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(intel_svm_is_pasid_valid);
/* Page request queue descriptor */
struct page_req_dsc {
@@ -557,6 +713,93 @@ static bool is_canonical_address(u64 addr)
return (((saddr << shift) >> shift) == saddr);
}
+/**
+ * intel_svm_drain_prq - Drain page requests and responses for a pasid
+ * @dev: target device
+ * @pasid: pasid for draining
+ *
+ * Drain all pending page requests and responses related to @pasid in both
+ * software and hardware. This is supposed to be called after the device
+ * driver has stopped DMA, the pasid entry has been cleared, and both IOTLB
+ * and DevTLB have been invalidated.
+ *
+ * It waits until all pending page requests for @pasid in the page fault
+ * queue are completed by the prq handling thread. Then follow the steps
+ * described in VT-d spec CH7.10 to drain all page requests and page
+ * responses pending in the hardware.
+ */
+static void intel_svm_drain_prq(struct device *dev, int pasid)
+{
+ struct device_domain_info *info;
+ struct dmar_domain *domain;
+ struct intel_iommu *iommu;
+ struct qi_desc desc[3];
+ struct pci_dev *pdev;
+ int head, tail;
+ u16 sid, did;
+ int qdep;
+
+ info = get_domain_info(dev);
+ if (WARN_ON(!info || !dev_is_pci(dev)))
+ return;
+
+ if (!info->pri_enabled)
+ return;
+
+ iommu = info->iommu;
+ domain = info->domain;
+ pdev = to_pci_dev(dev);
+ sid = PCI_DEVID(info->bus, info->devfn);
+ did = domain->iommu_did[iommu->seq_id];
+ qdep = pci_ats_queue_depth(pdev);
+
+ /*
+ * Check and wait until all pending page requests in the queue are
+ * handled by the prq handling thread.
+ */
+prq_retry:
+ reinit_completion(&iommu->prq_complete);
+ tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
+ head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
+ while (head != tail) {
+ struct page_req_dsc *req;
+
+ req = &iommu->prq[head / sizeof(*req)];
+ if (!req->pasid_present || req->pasid != pasid) {
+ head = (head + sizeof(*req)) & PRQ_RING_MASK;
+ continue;
+ }
+
+ wait_for_completion(&iommu->prq_complete);
+ goto prq_retry;
+ }
+
+ /*
+ * Perform steps described in VT-d spec CH7.10 to drain page
+ * requests and responses in hardware.
+ */
+ memset(desc, 0, sizeof(desc));
+ desc[0].qw0 = QI_IWD_STATUS_DATA(QI_DONE) |
+ QI_IWD_FENCE |
+ QI_IWD_TYPE;
+ desc[1].qw0 = QI_EIOTLB_PASID(pasid) |
+ QI_EIOTLB_DID(did) |
+ QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
+ QI_EIOTLB_TYPE;
+ desc[2].qw0 = QI_DEV_EIOTLB_PASID(pasid) |
+ QI_DEV_EIOTLB_SID(sid) |
+ QI_DEV_EIOTLB_QDEP(qdep) |
+ QI_DEIOTLB_TYPE |
+ QI_DEV_IOTLB_PFSID(info->pfsid);
+qi_retry:
+ reinit_completion(&iommu->prq_complete);
+ qi_submit_sync(iommu, desc, 3, QI_OPT_WAIT_DRAIN);
+ if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO) {
+ wait_for_completion(&iommu->prq_complete);
+ goto qi_retry;
+ }
+}
+
static irqreturn_t prq_event_thread(int irq, void *d)
{
struct intel_iommu *iommu = d;
@@ -620,7 +863,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
if (!mmget_not_zero(svm->mm))
goto bad_req;
- down_read(&svm->mm->mmap_sem);
+ mmap_read_lock(svm->mm);
vma = find_extend_vma(svm->mm, address);
if (!vma || address < vma->vm_start)
goto invalid;
@@ -635,7 +878,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
result = QI_RESP_SUCCESS;
invalid:
- up_read(&svm->mm->mmap_sem);
+ mmap_read_unlock(svm->mm);
mmput(svm->mm);
bad_req:
/* Accounting for major/minor faults? */
@@ -685,12 +928,75 @@ static irqreturn_t prq_event_thread(int irq, void *d)
sizeof(req->priv_data));
resp.qw2 = 0;
resp.qw3 = 0;
- qi_submit_sync(&resp, iommu);
+ qi_submit_sync(iommu, &resp, 1, 0);
}
head = (head + sizeof(*req)) & PRQ_RING_MASK;
}
dmar_writeq(iommu->reg + DMAR_PQH_REG, tail);
+ /*
+ * Clear the page request overflow bit and wake up all threads that
+ * are waiting for the completion of this handling.
+ */
+ if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO)
+ writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG);
+
+ if (!completion_done(&iommu->prq_complete))
+ complete(&iommu->prq_complete);
+
return IRQ_RETVAL(handled);
}
+
+#define to_intel_svm_dev(handle) container_of(handle, struct intel_svm_dev, sva)
+struct iommu_sva *
+intel_svm_bind(struct device *dev, struct mm_struct *mm, void *drvdata)
+{
+ struct iommu_sva *sva = ERR_PTR(-EINVAL);
+ struct intel_svm_dev *sdev = NULL;
+ int flags = 0;
+ int ret;
+
+ /*
+ * TODO: Consolidate with generic iommu-sva bind after it is merged.
+ * It will require shared SVM data structures, i.e. combine io_mm
+ * and intel_svm etc.
+ */
+ if (drvdata)
+ flags = *(int *)drvdata;
+ mutex_lock(&pasid_mutex);
+ ret = intel_svm_bind_mm(dev, flags, NULL, mm, &sdev);
+ if (ret)
+ sva = ERR_PTR(ret);
+ else if (sdev)
+ sva = &sdev->sva;
+ else
+ WARN(!sdev, "SVM bind succeeded with no sdev!\n");
+
+ mutex_unlock(&pasid_mutex);
+
+ return sva;
+}
+
+void intel_svm_unbind(struct iommu_sva *sva)
+{
+ struct intel_svm_dev *sdev;
+
+ mutex_lock(&pasid_mutex);
+ sdev = to_intel_svm_dev(sva);
+ intel_svm_unbind_mm(sdev->dev, sdev->pasid);
+ mutex_unlock(&pasid_mutex);
+}
+
+int intel_svm_get_pasid(struct iommu_sva *sva)
+{
+ struct intel_svm_dev *sdev;
+ int pasid;
+
+ mutex_lock(&pasid_mutex);
+ sdev = to_intel_svm_dev(sva);
+ pasid = sdev->pasid;
+ mutex_unlock(&pasid_mutex);
+
+ return pasid;
+}
diff --git a/drivers/iommu/intel-trace.c b/drivers/iommu/intel/trace.c
index bfb6a6e37a88..bfb6a6e37a88 100644
--- a/drivers/iommu/intel-trace.c
+++ b/drivers/iommu/intel/trace.c
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 03d6a26687bc..d43120eb1dc5 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -44,6 +44,7 @@ struct iommu_group {
int id;
struct iommu_domain *default_domain;
struct iommu_domain *domain;
+ struct list_head entry;
};
struct group_device {
@@ -79,6 +80,20 @@ static bool iommu_cmd_line_dma_api(void)
return !!(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API);
}
+static int iommu_alloc_default_domain(struct iommu_group *group,
+ struct device *dev);
+static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
+ unsigned type);
+static int __iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev);
+static int __iommu_attach_group(struct iommu_domain *domain,
+ struct iommu_group *group);
+static void __iommu_detach_group(struct iommu_domain *domain,
+ struct iommu_group *group);
+static int iommu_create_device_direct_mappings(struct iommu_group *group,
+ struct device *dev);
+static struct iommu_group *iommu_group_get_for_dev(struct device *dev);
+
#define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \
struct iommu_group_attribute iommu_group_attr_##_name = \
__ATTR(_name, _mode, _show, _store)
@@ -175,57 +190,118 @@ static void dev_iommu_free(struct device *dev)
dev->iommu = NULL;
}
-int iommu_probe_device(struct device *dev)
+static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
{
const struct iommu_ops *ops = dev->bus->iommu_ops;
+ struct iommu_device *iommu_dev;
+ struct iommu_group *group;
int ret;
- WARN_ON(dev->iommu_group);
if (!ops)
- return -EINVAL;
+ return -ENODEV;
if (!dev_iommu_get(dev))
return -ENOMEM;
if (!try_module_get(ops->owner)) {
ret = -EINVAL;
- goto err_free_dev_param;
+ goto err_free;
}
- ret = ops->add_device(dev);
- if (ret)
- goto err_module_put;
+ iommu_dev = ops->probe_device(dev);
+ if (IS_ERR(iommu_dev)) {
+ ret = PTR_ERR(iommu_dev);
+ goto out_module_put;
+ }
+
+ dev->iommu->iommu_dev = iommu_dev;
+
+ group = iommu_group_get_for_dev(dev);
+ if (IS_ERR(group)) {
+ ret = PTR_ERR(group);
+ goto out_release;
+ }
+ iommu_group_put(group);
+
+ if (group_list && !group->default_domain && list_empty(&group->entry))
+ list_add_tail(&group->entry, group_list);
+
+ iommu_device_link(iommu_dev, dev);
return 0;
-err_module_put:
+out_release:
+ ops->release_device(dev);
+
+out_module_put:
module_put(ops->owner);
-err_free_dev_param:
+
+err_free:
dev_iommu_free(dev);
+
return ret;
}
-void iommu_release_device(struct device *dev)
+int iommu_probe_device(struct device *dev)
{
const struct iommu_ops *ops = dev->bus->iommu_ops;
+ struct iommu_group *group;
+ int ret;
- if (dev->iommu_group)
- ops->remove_device(dev);
+ ret = __iommu_probe_device(dev, NULL);
+ if (ret)
+ goto err_out;
+
+ group = iommu_group_get(dev);
+ if (!group)
+ goto err_release;
+
+ /*
+ * Try to allocate a default domain - needs support from the
+ * IOMMU driver. There are still some drivers which don't
+ * support default domains, so the return value is not yet
+ * checked.
+ */
+ iommu_alloc_default_domain(group, dev);
+
+ if (group->default_domain)
+ ret = __iommu_attach_device(group->default_domain, dev);
+
+ iommu_create_device_direct_mappings(group, dev);
+
+ iommu_group_put(group);
+
+ if (ret)
+ goto err_release;
+
+ if (ops->probe_finalize)
+ ops->probe_finalize(dev);
+
+ return 0;
+
+err_release:
+ iommu_release_device(dev);
+
+err_out:
+ return ret;
- if (dev->iommu) {
- module_put(ops->owner);
- dev_iommu_free(dev);
- }
}
-static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
- unsigned type);
-static int __iommu_attach_device(struct iommu_domain *domain,
- struct device *dev);
-static int __iommu_attach_group(struct iommu_domain *domain,
- struct iommu_group *group);
-static void __iommu_detach_group(struct iommu_domain *domain,
- struct iommu_group *group);
+void iommu_release_device(struct device *dev)
+{
+ const struct iommu_ops *ops = dev->bus->iommu_ops;
+
+ if (!dev->iommu)
+ return;
+
+ iommu_device_unlink(dev->iommu->iommu_dev, dev);
+ iommu_group_remove_device(dev);
+
+ ops->release_device(dev);
+
+ module_put(ops->owner);
+ dev_iommu_free(dev);
+}
static int __init iommu_set_def_domain_type(char *str)
{
@@ -497,6 +573,7 @@ struct iommu_group *iommu_group_alloc(void)
group->kobj.kset = iommu_group_kset;
mutex_init(&group->mutex);
INIT_LIST_HEAD(&group->devices);
+ INIT_LIST_HEAD(&group->entry);
BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL);
@@ -638,8 +715,8 @@ int iommu_group_set_name(struct iommu_group *group, const char *name)
}
EXPORT_SYMBOL_GPL(iommu_group_set_name);
-static int iommu_group_create_direct_mappings(struct iommu_group *group,
- struct device *dev)
+static int iommu_create_device_direct_mappings(struct iommu_group *group,
+ struct device *dev)
{
struct iommu_domain *domain = group->default_domain;
struct iommu_resv_region *entry;
@@ -752,8 +829,6 @@ rename:
dev->iommu_group = group;
- iommu_group_create_direct_mappings(group, dev);
-
mutex_lock(&group->mutex);
list_add_tail(&device->list, &group->devices);
if (group->domain && !iommu_is_attach_deferred(group->domain, dev))
@@ -1371,6 +1446,61 @@ struct iommu_group *fsl_mc_device_group(struct device *dev)
}
EXPORT_SYMBOL_GPL(fsl_mc_device_group);
+static int iommu_get_def_domain_type(struct device *dev)
+{
+ const struct iommu_ops *ops = dev->bus->iommu_ops;
+ unsigned int type = 0;
+
+ if (ops->def_domain_type)
+ type = ops->def_domain_type(dev);
+
+ return (type == 0) ? iommu_def_domain_type : type;
+}
+
+static int iommu_group_alloc_default_domain(struct bus_type *bus,
+ struct iommu_group *group,
+ unsigned int type)
+{
+ struct iommu_domain *dom;
+
+ dom = __iommu_domain_alloc(bus, type);
+ if (!dom && type != IOMMU_DOMAIN_DMA) {
+ dom = __iommu_domain_alloc(bus, IOMMU_DOMAIN_DMA);
+ if (dom)
+ pr_warn("Failed to allocate default IOMMU domain of type %u for group %s - Falling back to IOMMU_DOMAIN_DMA",
+ type, group->name);
+ }
+
+ if (!dom)
+ return -ENOMEM;
+
+ group->default_domain = dom;
+ if (!group->domain)
+ group->domain = dom;
+
+ if (!iommu_dma_strict) {
+ int attr = 1;
+ iommu_domain_set_attr(dom,
+ DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
+ &attr);
+ }
+
+ return 0;
+}
+
+static int iommu_alloc_default_domain(struct iommu_group *group,
+ struct device *dev)
+{
+ unsigned int type;
+
+ if (group->default_domain)
+ return 0;
+
+ type = iommu_get_def_domain_type(dev);
+
+ return iommu_group_alloc_default_domain(dev->bus, group, type);
+}
+
/**
* iommu_group_get_for_dev - Find or create the IOMMU group for a device
* @dev: target device
@@ -1381,7 +1511,7 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_group);
* to the returned IOMMU group, which will already include the provided
* device. The reference should be released with iommu_group_put().
*/
-struct iommu_group *iommu_group_get_for_dev(struct device *dev)
+static struct iommu_group *iommu_group_get_for_dev(struct device *dev)
{
const struct iommu_ops *ops = dev->bus->iommu_ops;
struct iommu_group *group;
@@ -1401,59 +1531,37 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
if (IS_ERR(group))
return group;
- /*
- * Try to allocate a default domain - needs support from the
- * IOMMU driver.
- */
- if (!group->default_domain) {
- struct iommu_domain *dom;
-
- dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
- if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
- dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
- if (dom) {
- dev_warn(dev,
- "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
- iommu_def_domain_type);
- }
- }
-
- group->default_domain = dom;
- if (!group->domain)
- group->domain = dom;
-
- if (dom && !iommu_dma_strict) {
- int attr = 1;
- iommu_domain_set_attr(dom,
- DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
- &attr);
- }
- }
-
ret = iommu_group_add_device(group, dev);
- if (ret) {
- iommu_group_put(group);
- return ERR_PTR(ret);
- }
+ if (ret)
+ goto out_put_group;
return group;
+
+out_put_group:
+ iommu_group_put(group);
+
+ return ERR_PTR(ret);
}
-EXPORT_SYMBOL_GPL(iommu_group_get_for_dev);
struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
{
return group->default_domain;
}
-static int add_iommu_group(struct device *dev, void *data)
+static int probe_iommu_group(struct device *dev, void *data)
{
- int ret = iommu_probe_device(dev);
+ struct list_head *group_list = data;
+ struct iommu_group *group;
+ int ret;
- /*
- * We ignore -ENODEV errors for now, as they just mean that the
- * device is not translated by an IOMMU. We still care about
- * other errors and fail to initialize when they happen.
- */
+ /* Device is probed already if in a group */
+ group = iommu_group_get(dev);
+ if (group) {
+ iommu_group_put(group);
+ return 0;
+ }
+
+ ret = __iommu_probe_device(dev, group_list);
if (ret == -ENODEV)
ret = 0;
@@ -1519,10 +1627,152 @@ static int iommu_bus_notifier(struct notifier_block *nb,
return 0;
}
+struct __group_domain_type {
+ struct device *dev;
+ unsigned int type;
+};
+
+static int probe_get_default_domain_type(struct device *dev, void *data)
+{
+ const struct iommu_ops *ops = dev->bus->iommu_ops;
+ struct __group_domain_type *gtype = data;
+ unsigned int type = 0;
+
+ if (ops->def_domain_type)
+ type = ops->def_domain_type(dev);
+
+ if (type) {
+ if (gtype->type && gtype->type != type) {
+ dev_warn(dev, "Device needs domain type %s, but device %s in the same iommu group requires type %s - using default\n",
+ iommu_domain_type_str(type),
+ dev_name(gtype->dev),
+ iommu_domain_type_str(gtype->type));
+ gtype->type = 0;
+ }
+
+ if (!gtype->dev) {
+ gtype->dev = dev;
+ gtype->type = type;
+ }
+ }
+
+ return 0;
+}
+
+static void probe_alloc_default_domain(struct bus_type *bus,
+ struct iommu_group *group)
+{
+ struct __group_domain_type gtype;
+
+ memset(&gtype, 0, sizeof(gtype));
+
+ /* Ask for default domain requirements of all devices in the group */
+ __iommu_group_for_each_dev(group, &gtype,
+ probe_get_default_domain_type);
+
+ if (!gtype.type)
+ gtype.type = iommu_def_domain_type;
+
+ iommu_group_alloc_default_domain(bus, group, gtype.type);
+
+}
+
+static int iommu_group_do_dma_attach(struct device *dev, void *data)
+{
+ struct iommu_domain *domain = data;
+ int ret = 0;
+
+ if (!iommu_is_attach_deferred(domain, dev))
+ ret = __iommu_attach_device(domain, dev);
+
+ return ret;
+}
+
+static int __iommu_group_dma_attach(struct iommu_group *group)
+{
+ return __iommu_group_for_each_dev(group, group->default_domain,
+ iommu_group_do_dma_attach);
+}
+
+static int iommu_group_do_probe_finalize(struct device *dev, void *data)
+{
+ struct iommu_domain *domain = data;
+
+ if (domain->ops->probe_finalize)
+ domain->ops->probe_finalize(dev);
+
+ return 0;
+}
+
+static void __iommu_group_dma_finalize(struct iommu_group *group)
+{
+ __iommu_group_for_each_dev(group, group->default_domain,
+ iommu_group_do_probe_finalize);
+}
+
+static int iommu_do_create_direct_mappings(struct device *dev, void *data)
+{
+ struct iommu_group *group = data;
+
+ iommu_create_device_direct_mappings(group, dev);
+
+ return 0;
+}
+
+static int iommu_group_create_direct_mappings(struct iommu_group *group)
+{
+ return __iommu_group_for_each_dev(group, group,
+ iommu_do_create_direct_mappings);
+}
+
+int bus_iommu_probe(struct bus_type *bus)
+{
+ struct iommu_group *group, *next;
+ LIST_HEAD(group_list);
+ int ret;
+
+ /*
+ * This code-path does not allocate the default domain when
+ * creating the iommu group, so do it after the groups are
+ * created.
+ */
+ ret = bus_for_each_dev(bus, NULL, &group_list, probe_iommu_group);
+ if (ret)
+ return ret;
+
+ list_for_each_entry_safe(group, next, &group_list, entry) {
+ /* Remove item from the list */
+ list_del_init(&group->entry);
+
+ mutex_lock(&group->mutex);
+
+ /* Try to allocate default domain */
+ probe_alloc_default_domain(bus, group);
+
+ if (!group->default_domain) {
+ mutex_unlock(&group->mutex);
+ continue;
+ }
+
+ iommu_group_create_direct_mappings(group);
+
+ ret = __iommu_group_dma_attach(group);
+
+ mutex_unlock(&group->mutex);
+
+ if (ret)
+ break;
+
+ __iommu_group_dma_finalize(group);
+ }
+
+ return ret;
+}
+
static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
{
- int err;
struct notifier_block *nb;
+ int err;
nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
if (!nb)
@@ -1534,7 +1784,7 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
if (err)
goto out_free;
- err = bus_for_each_dev(bus, NULL, NULL, add_iommu_group);
+ err = bus_iommu_probe(bus);
if (err)
goto out_err;
@@ -2301,71 +2551,6 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
}
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
-static int
-request_default_domain_for_dev(struct device *dev, unsigned long type)
-{
- struct iommu_domain *domain;
- struct iommu_group *group;
- int ret;
-
- /* Device must already be in a group before calling this function */
- group = iommu_group_get(dev);
- if (!group)
- return -EINVAL;
-
- mutex_lock(&group->mutex);
-
- ret = 0;
- if (group->default_domain && group->default_domain->type == type)
- goto out;
-
- /* Don't change mappings of existing devices */
- ret = -EBUSY;
- if (iommu_group_device_count(group) != 1)
- goto out;
-
- ret = -ENOMEM;
- domain = __iommu_domain_alloc(dev->bus, type);
- if (!domain)
- goto out;
-
- /* Attach the device to the domain */
- ret = __iommu_attach_group(domain, group);
- if (ret) {
- iommu_domain_free(domain);
- goto out;
- }
-
- /* Make the domain the default for this group */
- if (group->default_domain)
- iommu_domain_free(group->default_domain);
- group->default_domain = domain;
-
- iommu_group_create_direct_mappings(group, dev);
-
- dev_info(dev, "Using iommu %s mapping\n",
- type == IOMMU_DOMAIN_DMA ? "dma" : "direct");
-
- ret = 0;
-out:
- mutex_unlock(&group->mutex);
- iommu_group_put(group);
-
- return ret;
-}
-
-/* Request that a device is direct mapped by the IOMMU */
-int iommu_request_dm_for_dev(struct device *dev)
-{
- return request_default_domain_for_dev(dev, IOMMU_DOMAIN_IDENTITY);
-}
-
-/* Request that a device can't be direct mapped by the IOMMU */
-int iommu_request_dma_domain_for_dev(struct device *dev)
-{
- return request_default_domain_for_dev(dev, IOMMU_DOMAIN_DMA);
-}
-
void iommu_set_default_passthrough(bool cmd_line)
{
if (cmd_line)
@@ -2643,17 +2828,6 @@ void iommu_sva_unbind_device(struct iommu_sva *handle)
}
EXPORT_SYMBOL_GPL(iommu_sva_unbind_device);
-int iommu_sva_set_ops(struct iommu_sva *handle,
- const struct iommu_sva_ops *sva_ops)
-{
- if (handle->ops && handle->ops != sva_ops)
- return -EEXIST;
-
- handle->ops = sva_ops;
- return 0;
-}
-EXPORT_SYMBOL_GPL(iommu_sva_set_ops);
-
int iommu_sva_get_pasid(struct iommu_sva *handle)
{
const struct iommu_ops *ops = handle->dev->bus->iommu_ops;
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index 0e6a9536eca6..49fc01f2a28d 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -253,7 +253,7 @@ int iova_cache_get(void)
SLAB_HWCACHE_ALIGN, NULL);
if (!iova_cache) {
mutex_unlock(&iova_cache_mutex);
- printk(KERN_ERR "Couldn't create iova cache\n");
+ pr_err("Couldn't create iova cache\n");
return -ENOMEM;
}
}
@@ -718,8 +718,8 @@ copy_reserved_iova(struct iova_domain *from, struct iova_domain *to)
new_iova = reserve_iova(to, iova->pfn_lo, iova->pfn_hi);
if (!new_iova)
- printk(KERN_ERR "Reserve iova range %lx@%lx failed\n",
- iova->pfn_lo, iova->pfn_lo);
+ pr_err("Reserve iova range %lx@%lx failed\n",
+ iova->pfn_lo, iova->pfn_lo);
}
spin_unlock_irqrestore(&from->iova_rbtree_lock, flags);
}
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 310cf09feea3..4c2972f3153b 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -805,24 +805,8 @@ static int ipmmu_of_xlate(struct device *dev,
static int ipmmu_init_arm_mapping(struct device *dev)
{
struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
- struct iommu_group *group;
int ret;
- /* Create a device group and add the device to it. */
- group = iommu_group_alloc();
- if (IS_ERR(group)) {
- dev_err(dev, "Failed to allocate IOMMU group\n");
- return PTR_ERR(group);
- }
-
- ret = iommu_group_add_device(group, dev);
- iommu_group_put(group);
-
- if (ret < 0) {
- dev_err(dev, "Failed to add device to IPMMU group\n");
- return ret;
- }
-
/*
* Create the ARM mapping, used by the ARM DMA mapping core to allocate
* VAs. This will allocate a corresponding IOMMU domain.
@@ -856,48 +840,39 @@ static int ipmmu_init_arm_mapping(struct device *dev)
return 0;
error:
- iommu_group_remove_device(dev);
if (mmu->mapping)
arm_iommu_release_mapping(mmu->mapping);
return ret;
}
-static int ipmmu_add_device(struct device *dev)
+static struct iommu_device *ipmmu_probe_device(struct device *dev)
{
struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
- struct iommu_group *group;
- int ret;
/*
* Only let through devices that have been verified in xlate()
*/
if (!mmu)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
- if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA)) {
- ret = ipmmu_init_arm_mapping(dev);
- if (ret)
- return ret;
- } else {
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
+ return &mmu->iommu;
+}
- iommu_group_put(group);
- }
+static void ipmmu_probe_finalize(struct device *dev)
+{
+ int ret = 0;
- iommu_device_link(&mmu->iommu, dev);
- return 0;
+ if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA))
+ ret = ipmmu_init_arm_mapping(dev);
+
+ if (ret)
+ dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n");
}
-static void ipmmu_remove_device(struct device *dev)
+static void ipmmu_release_device(struct device *dev)
{
- struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
-
- iommu_device_unlink(&mmu->iommu, dev);
arm_iommu_detach_device(dev);
- iommu_group_remove_device(dev);
}
static struct iommu_group *ipmmu_find_group(struct device *dev)
@@ -925,9 +900,11 @@ static const struct iommu_ops ipmmu_ops = {
.flush_iotlb_all = ipmmu_flush_iotlb_all,
.iotlb_sync = ipmmu_iotlb_sync,
.iova_to_phys = ipmmu_iova_to_phys,
- .add_device = ipmmu_add_device,
- .remove_device = ipmmu_remove_device,
- .device_group = ipmmu_find_group,
+ .probe_device = ipmmu_probe_device,
+ .release_device = ipmmu_release_device,
+ .probe_finalize = ipmmu_probe_finalize,
+ .device_group = IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA)
+ ? generic_device_group : ipmmu_find_group,
.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K,
.of_xlate = ipmmu_of_xlate,
};
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 94a6df1bddd6..3d8a63555c25 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -34,7 +34,7 @@ __asm__ __volatile__ ( \
/* bitmap of the page sizes currently supported */
#define MSM_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M)
-DEFINE_SPINLOCK(msm_iommu_lock);
+static DEFINE_SPINLOCK(msm_iommu_lock);
static LIST_HEAD(qcom_iommu_devices);
static struct iommu_ops msm_iommu_ops;
@@ -388,43 +388,23 @@ static struct msm_iommu_dev *find_iommu_for_dev(struct device *dev)
return ret;
}
-static int msm_iommu_add_device(struct device *dev)
+static struct iommu_device *msm_iommu_probe_device(struct device *dev)
{
struct msm_iommu_dev *iommu;
- struct iommu_group *group;
unsigned long flags;
spin_lock_irqsave(&msm_iommu_lock, flags);
iommu = find_iommu_for_dev(dev);
spin_unlock_irqrestore(&msm_iommu_lock, flags);
- if (iommu)
- iommu_device_link(&iommu->iommu, dev);
- else
- return -ENODEV;
-
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
+ if (!iommu)
+ return ERR_PTR(-ENODEV);
- return 0;
+ return &iommu->iommu;
}
-static void msm_iommu_remove_device(struct device *dev)
+static void msm_iommu_release_device(struct device *dev)
{
- struct msm_iommu_dev *iommu;
- unsigned long flags;
-
- spin_lock_irqsave(&msm_iommu_lock, flags);
- iommu = find_iommu_for_dev(dev);
- spin_unlock_irqrestore(&msm_iommu_lock, flags);
-
- if (iommu)
- iommu_device_unlink(&iommu->iommu, dev);
-
- iommu_group_remove_device(dev);
}
static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
@@ -708,8 +688,8 @@ static struct iommu_ops msm_iommu_ops = {
*/
.iotlb_sync = NULL,
.iova_to_phys = msm_iommu_iova_to_phys,
- .add_device = msm_iommu_add_device,
- .remove_device = msm_iommu_remove_device,
+ .probe_device = msm_iommu_probe_device,
+ .release_device = msm_iommu_release_device,
.device_group = generic_device_group,
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
.of_xlate = qcom_iommu_of_xlate,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 5f4d6df59cf6..2be96f1cdbd2 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -441,38 +441,26 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
return pa;
}
-static int mtk_iommu_add_device(struct device *dev)
+static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct mtk_iommu_data *data;
- struct iommu_group *group;
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
- return -ENODEV; /* Not a iommu client device */
+ return ERR_PTR(-ENODEV); /* Not a iommu client device */
data = dev_iommu_priv_get(dev);
- iommu_device_link(&data->iommu, dev);
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
- return 0;
+ return &data->iommu;
}
-static void mtk_iommu_remove_device(struct device *dev)
+static void mtk_iommu_release_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct mtk_iommu_data *data;
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
return;
- data = dev_iommu_priv_get(dev);
- iommu_device_unlink(&data->iommu, dev);
-
- iommu_group_remove_device(dev);
iommu_fwspec_free(dev);
}
@@ -526,8 +514,8 @@ static const struct iommu_ops mtk_iommu_ops = {
.flush_iotlb_all = mtk_iommu_flush_iotlb_all,
.iotlb_sync = mtk_iommu_iotlb_sync,
.iova_to_phys = mtk_iommu_iova_to_phys,
- .add_device = mtk_iommu_add_device,
- .remove_device = mtk_iommu_remove_device,
+ .probe_device = mtk_iommu_probe_device,
+ .release_device = mtk_iommu_release_device,
.device_group = mtk_iommu_device_group,
.of_xlate = mtk_iommu_of_xlate,
.pgsize_bitmap = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index a31be05601c9..c9d79cff4d17 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -265,10 +265,13 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
{
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+ struct dma_iommu_mapping *mtk_mapping;
int ret;
- if (!data)
- return -ENODEV;
+ /* Only allow the domain created internally. */
+ mtk_mapping = data->dev->archdata.iommu;
+ if (mtk_mapping->domain != domain)
+ return 0;
if (!data->m4u_dom) {
data->m4u_dom = dom;
@@ -288,9 +291,6 @@ static void mtk_iommu_detach_device(struct iommu_domain *domain,
{
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
- if (!data)
- return;
-
mtk_iommu_config(data, dev, false);
}
@@ -416,14 +416,17 @@ static int mtk_iommu_create_mapping(struct device *dev,
return 0;
}
-static int mtk_iommu_add_device(struct device *dev)
+static int mtk_iommu_def_domain_type(struct device *dev)
+{
+ return IOMMU_DOMAIN_UNMANAGED;
+}
+
+static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct dma_iommu_mapping *mtk_mapping;
struct of_phandle_args iommu_spec;
struct of_phandle_iterator it;
struct mtk_iommu_data *data;
- struct iommu_group *group;
int err;
of_for_each_phandle(&it, err, dev->of_node, "iommus",
@@ -442,46 +445,34 @@ static int mtk_iommu_add_device(struct device *dev)
}
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
- return -ENODEV; /* Not a iommu client device */
+ return ERR_PTR(-ENODEV); /* Not a iommu client device */
- /*
- * This is a short-term bodge because the ARM DMA code doesn't
- * understand multi-device groups, but we have to call into it
- * successfully (and not just rely on a normal IOMMU API attach
- * here) in order to set the correct DMA API ops on @dev.
- */
- group = iommu_group_alloc();
- if (IS_ERR(group))
- return PTR_ERR(group);
+ data = dev_iommu_priv_get(dev);
- err = iommu_group_add_device(group, dev);
- iommu_group_put(group);
- if (err)
- return err;
+ return &data->iommu;
+}
- data = dev_iommu_priv_get(dev);
+static void mtk_iommu_probe_finalize(struct device *dev)
+{
+ struct dma_iommu_mapping *mtk_mapping;
+ struct mtk_iommu_data *data;
+ int err;
+
+ data = dev_iommu_priv_get(dev);
mtk_mapping = data->dev->archdata.iommu;
- err = arm_iommu_attach_device(dev, mtk_mapping);
- if (err) {
- iommu_group_remove_device(dev);
- return err;
- }
- return iommu_device_link(&data->iommu, dev);
+ err = arm_iommu_attach_device(dev, mtk_mapping);
+ if (err)
+ dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n");
}
-static void mtk_iommu_remove_device(struct device *dev)
+static void mtk_iommu_release_device(struct device *dev)
{
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct mtk_iommu_data *data;
if (!fwspec || fwspec->ops != &mtk_iommu_ops)
return;
- data = dev_iommu_priv_get(dev);
- iommu_device_unlink(&data->iommu, dev);
-
- iommu_group_remove_device(dev);
iommu_fwspec_free(dev);
}
@@ -534,8 +525,11 @@ static const struct iommu_ops mtk_iommu_ops = {
.map = mtk_iommu_map,
.unmap = mtk_iommu_unmap,
.iova_to_phys = mtk_iommu_iova_to_phys,
- .add_device = mtk_iommu_add_device,
- .remove_device = mtk_iommu_remove_device,
+ .probe_device = mtk_iommu_probe_device,
+ .probe_finalize = mtk_iommu_probe_finalize,
+ .release_device = mtk_iommu_release_device,
+ .def_domain_type = mtk_iommu_def_domain_type,
+ .device_group = generic_device_group,
.pgsize_bitmap = ~0UL << MT2701_IOMMU_PAGE_SHIFT,
};
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 887fefcb03b4..c8282cc212cb 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -35,15 +35,6 @@
static const struct iommu_ops omap_iommu_ops;
-struct orphan_dev {
- struct device *dev;
- struct list_head node;
-};
-
-static LIST_HEAD(orphan_dev_list);
-
-static DEFINE_SPINLOCK(orphan_lock);
-
#define to_iommu(dev) ((struct omap_iommu *)dev_get_drvdata(dev))
/* bitmap of the page sizes currently supported */
@@ -62,8 +53,6 @@ static DEFINE_SPINLOCK(orphan_lock);
static struct platform_driver omap_iommu_driver;
static struct kmem_cache *iopte_cachep;
-static int _omap_iommu_add_device(struct device *dev);
-
/**
* to_omap_domain - Get struct omap_iommu_domain from generic iommu_domain
* @dom: generic iommu domain handle
@@ -1177,7 +1166,6 @@ static int omap_iommu_probe(struct platform_device *pdev)
struct omap_iommu *obj;
struct resource *res;
struct device_node *of = pdev->dev.of_node;
- struct orphan_dev *orphan_dev, *tmp;
if (!of) {
pr_err("%s: only DT-based devices are supported\n", __func__);
@@ -1248,6 +1236,7 @@ static int omap_iommu_probe(struct platform_device *pdev)
goto out_group;
iommu_device_set_ops(&obj->iommu, &omap_iommu_ops);
+ iommu_device_set_fwnode(&obj->iommu, &of->fwnode);
err = iommu_device_register(&obj->iommu);
if (err)
@@ -1260,13 +1249,8 @@ static int omap_iommu_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "%s registered\n", obj->name);
- list_for_each_entry_safe(orphan_dev, tmp, &orphan_dev_list, node) {
- err = _omap_iommu_add_device(orphan_dev->dev);
- if (!err) {
- list_del(&orphan_dev->node);
- kfree(orphan_dev);
- }
- }
+ /* Re-probe bus to probe device attached to this IOMMU */
+ bus_iommu_probe(&platform_bus_type);
return 0;
@@ -1657,17 +1641,13 @@ static phys_addr_t omap_iommu_iova_to_phys(struct iommu_domain *domain,
return ret;
}
-static int _omap_iommu_add_device(struct device *dev)
+static struct iommu_device *omap_iommu_probe_device(struct device *dev)
{
struct omap_iommu_arch_data *arch_data, *tmp;
+ struct platform_device *pdev;
struct omap_iommu *oiommu;
- struct iommu_group *group;
struct device_node *np;
- struct platform_device *pdev;
int num_iommus, i;
- int ret;
- struct orphan_dev *orphan_dev;
- unsigned long flags;
/*
* Allocate the archdata iommu structure for DT-based devices.
@@ -1676,7 +1656,7 @@ static int _omap_iommu_add_device(struct device *dev)
* IOMMU users.
*/
if (!dev->of_node)
- return 0;
+ return ERR_PTR(-ENODEV);
/*
* retrieve the count of IOMMU nodes using phandle size as element size
@@ -1689,43 +1669,27 @@ static int _omap_iommu_add_device(struct device *dev)
arch_data = kcalloc(num_iommus + 1, sizeof(*arch_data), GFP_KERNEL);
if (!arch_data)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
for (i = 0, tmp = arch_data; i < num_iommus; i++, tmp++) {
np = of_parse_phandle(dev->of_node, "iommus", i);
if (!np) {
kfree(arch_data);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
pdev = of_find_device_by_node(np);
if (!pdev) {
of_node_put(np);
kfree(arch_data);
- spin_lock_irqsave(&orphan_lock, flags);
- list_for_each_entry(orphan_dev, &orphan_dev_list,
- node) {
- if (orphan_dev->dev == dev)
- break;
- }
- spin_unlock_irqrestore(&orphan_lock, flags);
-
- if (orphan_dev && orphan_dev->dev == dev)
- return -EPROBE_DEFER;
-
- orphan_dev = kzalloc(sizeof(*orphan_dev), GFP_KERNEL);
- orphan_dev->dev = dev;
- spin_lock_irqsave(&orphan_lock, flags);
- list_add(&orphan_dev->node, &orphan_dev_list);
- spin_unlock_irqrestore(&orphan_lock, flags);
- return -EPROBE_DEFER;
+ return ERR_PTR(-ENODEV);
}
oiommu = platform_get_drvdata(pdev);
if (!oiommu) {
of_node_put(np);
kfree(arch_data);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
tmp->iommu_dev = oiommu;
@@ -1734,57 +1698,25 @@ static int _omap_iommu_add_device(struct device *dev)
of_node_put(np);
}
+ dev->archdata.iommu = arch_data;
+
/*
* use the first IOMMU alone for the sysfs device linking.
* TODO: Evaluate if a single iommu_group needs to be
* maintained for both IOMMUs
*/
oiommu = arch_data->iommu_dev;
- ret = iommu_device_link(&oiommu->iommu, dev);
- if (ret) {
- kfree(arch_data);
- return ret;
- }
-
- dev->archdata.iommu = arch_data;
-
- /*
- * IOMMU group initialization calls into omap_iommu_device_group, which
- * needs a valid dev->archdata.iommu pointer
- */
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group)) {
- iommu_device_unlink(&oiommu->iommu, dev);
- dev->archdata.iommu = NULL;
- kfree(arch_data);
- return PTR_ERR(group);
- }
- iommu_group_put(group);
- return 0;
+ return &oiommu->iommu;
}
-static int omap_iommu_add_device(struct device *dev)
-{
- int ret;
-
- ret = _omap_iommu_add_device(dev);
- if (ret == -EPROBE_DEFER)
- return 0;
-
- return ret;
-}
-
-static void omap_iommu_remove_device(struct device *dev)
+static void omap_iommu_release_device(struct device *dev)
{
struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
if (!dev->of_node || !arch_data)
return;
- iommu_device_unlink(&arch_data->iommu_dev->iommu, dev);
- iommu_group_remove_device(dev);
-
dev->archdata.iommu = NULL;
kfree(arch_data);
@@ -1795,6 +1727,9 @@ static struct iommu_group *omap_iommu_device_group(struct device *dev)
struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
struct iommu_group *group = ERR_PTR(-EINVAL);
+ if (!arch_data)
+ return ERR_PTR(-ENODEV);
+
if (arch_data->iommu_dev)
group = iommu_group_ref_get(arch_data->iommu_dev->group);
@@ -1809,8 +1744,8 @@ static const struct iommu_ops omap_iommu_ops = {
.map = omap_iommu_map,
.unmap = omap_iommu_unmap,
.iova_to_phys = omap_iommu_iova_to_phys,
- .add_device = omap_iommu_add_device,
- .remove_device = omap_iommu_remove_device,
+ .probe_device = omap_iommu_probe_device,
+ .release_device = omap_iommu_release_device,
.device_group = omap_iommu_device_group,
.pgsize_bitmap = OMAP_IOMMU_PGSIZES,
};
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index 5b3b270972f8..c3e1fbd1988c 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -524,14 +524,13 @@ static bool qcom_iommu_capable(enum iommu_cap cap)
}
}
-static int qcom_iommu_add_device(struct device *dev)
+static struct iommu_device *qcom_iommu_probe_device(struct device *dev)
{
struct qcom_iommu_dev *qcom_iommu = to_iommu(dev);
- struct iommu_group *group;
struct device_link *link;
if (!qcom_iommu)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
/*
* Establish the link between iommu and master, so that the
@@ -542,28 +541,19 @@ static int qcom_iommu_add_device(struct device *dev)
if (!link) {
dev_err(qcom_iommu->dev, "Unable to create device link between %s and %s\n",
dev_name(qcom_iommu->dev), dev_name(dev));
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
}
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
- iommu_device_link(&qcom_iommu->iommu, dev);
-
- return 0;
+ return &qcom_iommu->iommu;
}
-static void qcom_iommu_remove_device(struct device *dev)
+static void qcom_iommu_release_device(struct device *dev)
{
struct qcom_iommu_dev *qcom_iommu = to_iommu(dev);
if (!qcom_iommu)
return;
- iommu_device_unlink(&qcom_iommu->iommu, dev);
- iommu_group_remove_device(dev);
iommu_fwspec_free(dev);
}
@@ -619,8 +609,8 @@ static const struct iommu_ops qcom_iommu_ops = {
.flush_iotlb_all = qcom_iommu_flush_iotlb_all,
.iotlb_sync = qcom_iommu_iotlb_sync,
.iova_to_phys = qcom_iommu_iova_to_phys,
- .add_device = qcom_iommu_add_device,
- .remove_device = qcom_iommu_remove_device,
+ .probe_device = qcom_iommu_probe_device,
+ .release_device = qcom_iommu_release_device,
.device_group = generic_device_group,
.of_xlate = qcom_iommu_of_xlate,
.pgsize_bitmap = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index b33cdd5aad81..d25c2486ca07 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1054,40 +1054,28 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
kfree(rk_domain);
}
-static int rk_iommu_add_device(struct device *dev)
+static struct iommu_device *rk_iommu_probe_device(struct device *dev)
{
- struct iommu_group *group;
- struct rk_iommu *iommu;
struct rk_iommudata *data;
+ struct rk_iommu *iommu;
data = dev->archdata.iommu;
if (!data)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
iommu = rk_iommu_from_dev(dev);
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
- iommu_group_put(group);
-
- iommu_device_link(&iommu->iommu, dev);
data->link = device_link_add(dev, iommu->dev,
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
- return 0;
+ return &iommu->iommu;
}
-static void rk_iommu_remove_device(struct device *dev)
+static void rk_iommu_release_device(struct device *dev)
{
- struct rk_iommu *iommu;
struct rk_iommudata *data = dev->archdata.iommu;
- iommu = rk_iommu_from_dev(dev);
-
device_link_del(data->link);
- iommu_device_unlink(&iommu->iommu, dev);
- iommu_group_remove_device(dev);
}
static struct iommu_group *rk_iommu_device_group(struct device *dev)
@@ -1126,8 +1114,8 @@ static const struct iommu_ops rk_iommu_ops = {
.detach_dev = rk_iommu_detach_device,
.map = rk_iommu_map,
.unmap = rk_iommu_unmap,
- .add_device = rk_iommu_add_device,
- .remove_device = rk_iommu_remove_device,
+ .probe_device = rk_iommu_probe_device,
+ .release_device = rk_iommu_release_device,
.iova_to_phys = rk_iommu_iova_to_phys,
.device_group = rk_iommu_device_group,
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index 1137f3ddcb85..8895dbb705eb 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -87,7 +87,7 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
struct s390_domain *s390_domain = to_s390_domain(domain);
- struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
+ struct zpci_dev *zdev = to_zpci_dev(dev);
struct s390_domain_device *domain_device;
unsigned long flags;
int rc;
@@ -139,7 +139,7 @@ static void s390_iommu_detach_device(struct iommu_domain *domain,
struct device *dev)
{
struct s390_domain *s390_domain = to_s390_domain(domain);
- struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
+ struct zpci_dev *zdev = to_zpci_dev(dev);
struct s390_domain_device *domain_device, *tmp;
unsigned long flags;
int found = 0;
@@ -166,23 +166,16 @@ static void s390_iommu_detach_device(struct iommu_domain *domain,
}
}
-static int s390_iommu_add_device(struct device *dev)
+static struct iommu_device *s390_iommu_probe_device(struct device *dev)
{
- struct iommu_group *group = iommu_group_get_for_dev(dev);
- struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
+ struct zpci_dev *zdev = to_zpci_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
- iommu_device_link(&zdev->iommu_dev, dev);
-
- return 0;
+ return &zdev->iommu_dev;
}
-static void s390_iommu_remove_device(struct device *dev)
+static void s390_iommu_release_device(struct device *dev)
{
- struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
+ struct zpci_dev *zdev = to_zpci_dev(dev);
struct iommu_domain *domain;
/*
@@ -191,7 +184,7 @@ static void s390_iommu_remove_device(struct device *dev)
* to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers
* the attach_dev), removing the device via
* "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev,
- * only remove_device will be called via the BUS_NOTIFY_REMOVED_DEVICE
+ * only release_device will be called via the BUS_NOTIFY_REMOVED_DEVICE
* notifier.
*
* So let's call detach_dev from here if it hasn't been called before.
@@ -201,9 +194,6 @@ static void s390_iommu_remove_device(struct device *dev)
if (domain)
s390_iommu_detach_device(domain, dev);
}
-
- iommu_device_unlink(&zdev->iommu_dev, dev);
- iommu_group_remove_device(dev);
}
static int s390_iommu_update_trans(struct s390_domain *s390_domain,
@@ -373,8 +363,8 @@ static const struct iommu_ops s390_iommu_ops = {
.map = s390_iommu_map,
.unmap = s390_iommu_unmap,
.iova_to_phys = s390_iommu_iova_to_phys,
- .add_device = s390_iommu_add_device,
- .remove_device = s390_iommu_remove_device,
+ .probe_device = s390_iommu_probe_device,
+ .release_device = s390_iommu_release_device,
.device_group = generic_device_group,
.pgsize_bitmap = S390_IOMMU_PGSIZES,
};
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
new file mode 100644
index 000000000000..fce605e96aa2
--- /dev/null
+++ b/drivers/iommu/sun50i-iommu.c
@@ -0,0 +1,1023 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+// Copyright (C) 2016-2018, Allwinner Technology CO., LTD.
+// Copyright (C) 2019-2020, Cerno
+
+#include <linux/bitfield.h>
+#include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-iommu.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/iommu.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define IOMMU_RESET_REG 0x010
+#define IOMMU_ENABLE_REG 0x020
+#define IOMMU_ENABLE_ENABLE BIT(0)
+
+#define IOMMU_BYPASS_REG 0x030
+#define IOMMU_AUTO_GATING_REG 0x040
+#define IOMMU_AUTO_GATING_ENABLE BIT(0)
+
+#define IOMMU_WBUF_CTRL_REG 0x044
+#define IOMMU_OOO_CTRL_REG 0x048
+#define IOMMU_4KB_BDY_PRT_CTRL_REG 0x04c
+#define IOMMU_TTB_REG 0x050
+#define IOMMU_TLB_ENABLE_REG 0x060
+#define IOMMU_TLB_PREFETCH_REG 0x070
+#define IOMMU_TLB_PREFETCH_MASTER_ENABLE(m) BIT(m)
+
+#define IOMMU_TLB_FLUSH_REG 0x080
+#define IOMMU_TLB_FLUSH_PTW_CACHE BIT(17)
+#define IOMMU_TLB_FLUSH_MACRO_TLB BIT(16)
+#define IOMMU_TLB_FLUSH_MICRO_TLB(i) (BIT(i) & GENMASK(5, 0))
+
+#define IOMMU_TLB_IVLD_ADDR_REG 0x090
+#define IOMMU_TLB_IVLD_ADDR_MASK_REG 0x094
+#define IOMMU_TLB_IVLD_ENABLE_REG 0x098
+#define IOMMU_TLB_IVLD_ENABLE_ENABLE BIT(0)
+
+#define IOMMU_PC_IVLD_ADDR_REG 0x0a0
+#define IOMMU_PC_IVLD_ENABLE_REG 0x0a8
+#define IOMMU_PC_IVLD_ENABLE_ENABLE BIT(0)
+
+#define IOMMU_DM_AUT_CTRL_REG(d) (0x0b0 + ((d) / 2) * 4)
+#define IOMMU_DM_AUT_CTRL_RD_UNAVAIL(d, m) (1 << (((d & 1) * 16) + ((m) * 2)))
+#define IOMMU_DM_AUT_CTRL_WR_UNAVAIL(d, m) (1 << (((d & 1) * 16) + ((m) * 2) + 1))
+
+#define IOMMU_DM_AUT_OVWT_REG 0x0d0
+#define IOMMU_INT_ENABLE_REG 0x100
+#define IOMMU_INT_CLR_REG 0x104
+#define IOMMU_INT_STA_REG 0x108
+#define IOMMU_INT_ERR_ADDR_REG(i) (0x110 + (i) * 4)
+#define IOMMU_INT_ERR_ADDR_L1_REG 0x130
+#define IOMMU_INT_ERR_ADDR_L2_REG 0x134
+#define IOMMU_INT_ERR_DATA_REG(i) (0x150 + (i) * 4)
+#define IOMMU_L1PG_INT_REG 0x0180
+#define IOMMU_L2PG_INT_REG 0x0184
+
+#define IOMMU_INT_INVALID_L2PG BIT(17)
+#define IOMMU_INT_INVALID_L1PG BIT(16)
+#define IOMMU_INT_MASTER_PERMISSION(m) BIT(m)
+#define IOMMU_INT_MASTER_MASK (IOMMU_INT_MASTER_PERMISSION(0) | \
+ IOMMU_INT_MASTER_PERMISSION(1) | \
+ IOMMU_INT_MASTER_PERMISSION(2) | \
+ IOMMU_INT_MASTER_PERMISSION(3) | \
+ IOMMU_INT_MASTER_PERMISSION(4) | \
+ IOMMU_INT_MASTER_PERMISSION(5))
+#define IOMMU_INT_MASK (IOMMU_INT_INVALID_L1PG | \
+ IOMMU_INT_INVALID_L2PG | \
+ IOMMU_INT_MASTER_MASK)
+
+#define PT_ENTRY_SIZE sizeof(u32)
+
+#define NUM_DT_ENTRIES 4096
+#define DT_SIZE (NUM_DT_ENTRIES * PT_ENTRY_SIZE)
+
+#define NUM_PT_ENTRIES 256
+#define PT_SIZE (NUM_PT_ENTRIES * PT_ENTRY_SIZE)
+
+struct sun50i_iommu {
+ struct iommu_device iommu;
+
+ /* Lock to modify the IOMMU registers */
+ spinlock_t iommu_lock;
+
+ struct device *dev;
+ void __iomem *base;
+ struct reset_control *reset;
+ struct clk *clk;
+
+ struct iommu_domain *domain;
+ struct iommu_group *group;
+ struct kmem_cache *pt_pool;
+};
+
+struct sun50i_iommu_domain {
+ struct iommu_domain domain;
+
+ /* Number of devices attached to the domain */
+ refcount_t refcnt;
+
+ /* L1 Page Table */
+ u32 *dt;
+ dma_addr_t dt_dma;
+
+ struct sun50i_iommu *iommu;
+};
+
+static struct sun50i_iommu_domain *to_sun50i_domain(struct iommu_domain *domain)
+{
+ return container_of(domain, struct sun50i_iommu_domain, domain);
+}
+
+static struct sun50i_iommu *sun50i_iommu_from_dev(struct device *dev)
+{
+ return dev_iommu_priv_get(dev);
+}
+
+static u32 iommu_read(struct sun50i_iommu *iommu, u32 offset)
+{
+ return readl(iommu->base + offset);
+}
+
+static void iommu_write(struct sun50i_iommu *iommu, u32 offset, u32 value)
+{
+ writel(value, iommu->base + offset);
+}
+
+/*
+ * The Allwinner H6 IOMMU uses a 2-level page table.
+ *
+ * The first level is the usual Directory Table (DT), that consists of
+ * 4096 4-bytes Directory Table Entries (DTE), each pointing to a Page
+ * Table (PT).
+ *
+ * Each PT consits of 256 4-bytes Page Table Entries (PTE), each
+ * pointing to a 4kB page of physical memory.
+ *
+ * The IOMMU supports a single DT, pointed by the IOMMU_TTB_REG
+ * register that contains its physical address.
+ */
+
+#define SUN50I_IOVA_DTE_MASK GENMASK(31, 20)
+#define SUN50I_IOVA_PTE_MASK GENMASK(19, 12)
+#define SUN50I_IOVA_PAGE_MASK GENMASK(11, 0)
+
+static u32 sun50i_iova_get_dte_index(dma_addr_t iova)
+{
+ return FIELD_GET(SUN50I_IOVA_DTE_MASK, iova);
+}
+
+static u32 sun50i_iova_get_pte_index(dma_addr_t iova)
+{
+ return FIELD_GET(SUN50I_IOVA_PTE_MASK, iova);
+}
+
+static u32 sun50i_iova_get_page_offset(dma_addr_t iova)
+{
+ return FIELD_GET(SUN50I_IOVA_PAGE_MASK, iova);
+}
+
+/*
+ * Each Directory Table Entry has a Page Table address and a valid
+ * bit:
+
+ * +---------------------+-----------+-+
+ * | PT address | Reserved |V|
+ * +---------------------+-----------+-+
+ * 31:10 - Page Table address
+ * 9:2 - Reserved
+ * 1:0 - 1 if the entry is valid
+ */
+
+#define SUN50I_DTE_PT_ADDRESS_MASK GENMASK(31, 10)
+#define SUN50I_DTE_PT_ATTRS GENMASK(1, 0)
+#define SUN50I_DTE_PT_VALID 1
+
+static phys_addr_t sun50i_dte_get_pt_address(u32 dte)
+{
+ return (phys_addr_t)dte & SUN50I_DTE_PT_ADDRESS_MASK;
+}
+
+static bool sun50i_dte_is_pt_valid(u32 dte)
+{
+ return (dte & SUN50I_DTE_PT_ATTRS) == SUN50I_DTE_PT_VALID;
+}
+
+static u32 sun50i_mk_dte(dma_addr_t pt_dma)
+{
+ return (pt_dma & SUN50I_DTE_PT_ADDRESS_MASK) | SUN50I_DTE_PT_VALID;
+}
+
+/*
+ * Each PTE has a Page address, an authority index and a valid bit:
+ *
+ * +----------------+-----+-----+-----+---+-----+
+ * | Page address | Rsv | ACI | Rsv | V | Rsv |
+ * +----------------+-----+-----+-----+---+-----+
+ * 31:12 - Page address
+ * 11:8 - Reserved
+ * 7:4 - Authority Control Index
+ * 3:2 - Reserved
+ * 1 - 1 if the entry is valid
+ * 0 - Reserved
+ *
+ * The way permissions work is that the IOMMU has 16 "domains" that
+ * can be configured to give each masters either read or write
+ * permissions through the IOMMU_DM_AUT_CTRL_REG registers. The domain
+ * 0 seems like the default domain, and its permissions in the
+ * IOMMU_DM_AUT_CTRL_REG are only read-only, so it's not really
+ * useful to enforce any particular permission.
+ *
+ * Each page entry will then have a reference to the domain they are
+ * affected to, so that we can actually enforce them on a per-page
+ * basis.
+ *
+ * In order to make it work with the IOMMU framework, we will be using
+ * 4 different domains, starting at 1: RD_WR, RD, WR and NONE
+ * depending on the permission we want to enforce. Each domain will
+ * have each master setup in the same way, since the IOMMU framework
+ * doesn't seem to restrict page access on a per-device basis. And
+ * then we will use the relevant domain index when generating the page
+ * table entry depending on the permissions we want to be enforced.
+ */
+
+enum sun50i_iommu_aci {
+ SUN50I_IOMMU_ACI_DO_NOT_USE = 0,
+ SUN50I_IOMMU_ACI_NONE,
+ SUN50I_IOMMU_ACI_RD,
+ SUN50I_IOMMU_ACI_WR,
+ SUN50I_IOMMU_ACI_RD_WR,
+};
+
+#define SUN50I_PTE_PAGE_ADDRESS_MASK GENMASK(31, 12)
+#define SUN50I_PTE_ACI_MASK GENMASK(7, 4)
+#define SUN50I_PTE_PAGE_VALID BIT(1)
+
+static phys_addr_t sun50i_pte_get_page_address(u32 pte)
+{
+ return (phys_addr_t)pte & SUN50I_PTE_PAGE_ADDRESS_MASK;
+}
+
+static enum sun50i_iommu_aci sun50i_get_pte_aci(u32 pte)
+{
+ return FIELD_GET(SUN50I_PTE_ACI_MASK, pte);
+}
+
+static bool sun50i_pte_is_page_valid(u32 pte)
+{
+ return pte & SUN50I_PTE_PAGE_VALID;
+}
+
+static u32 sun50i_mk_pte(phys_addr_t page, int prot)
+{
+ enum sun50i_iommu_aci aci;
+ u32 flags = 0;
+
+ if (prot & (IOMMU_READ | IOMMU_WRITE))
+ aci = SUN50I_IOMMU_ACI_RD_WR;
+ else if (prot & IOMMU_READ)
+ aci = SUN50I_IOMMU_ACI_RD;
+ else if (prot & IOMMU_WRITE)
+ aci = SUN50I_IOMMU_ACI_WR;
+ else
+ aci = SUN50I_IOMMU_ACI_NONE;
+
+ flags |= FIELD_PREP(SUN50I_PTE_ACI_MASK, aci);
+ page &= SUN50I_PTE_PAGE_ADDRESS_MASK;
+ return page | flags | SUN50I_PTE_PAGE_VALID;
+}
+
+static void sun50i_table_flush(struct sun50i_iommu_domain *sun50i_domain,
+ void *vaddr, unsigned int count)
+{
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ dma_addr_t dma = virt_to_phys(vaddr);
+ size_t size = count * PT_ENTRY_SIZE;
+
+ dma_sync_single_for_device(iommu->dev, dma, size, DMA_TO_DEVICE);
+}
+
+static int sun50i_iommu_flush_all_tlb(struct sun50i_iommu *iommu)
+{
+ u32 reg;
+ int ret;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ iommu_write(iommu,
+ IOMMU_TLB_FLUSH_REG,
+ IOMMU_TLB_FLUSH_PTW_CACHE |
+ IOMMU_TLB_FLUSH_MACRO_TLB |
+ IOMMU_TLB_FLUSH_MICRO_TLB(5) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(4) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(3) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(2) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(1) |
+ IOMMU_TLB_FLUSH_MICRO_TLB(0));
+
+ ret = readl_poll_timeout(iommu->base + IOMMU_TLB_FLUSH_REG,
+ reg, !reg,
+ 1, 2000);
+ if (ret)
+ dev_warn(iommu->dev, "TLB Flush timed out!\n");
+
+ return ret;
+}
+
+static void sun50i_iommu_flush_iotlb_all(struct iommu_domain *domain)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ unsigned long flags;
+
+ /*
+ * At boot, we'll have a first call into .flush_iotlb_all right after
+ * .probe_device, and since we link our (single) domain to our iommu in
+ * the .attach_device callback, we don't have that pointer set.
+ *
+ * It shouldn't really be any trouble to ignore it though since we flush
+ * all caches as part of the device powerup.
+ */
+ if (!iommu)
+ return;
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+ sun50i_iommu_flush_all_tlb(iommu);
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+}
+
+static void sun50i_iommu_iotlb_sync(struct iommu_domain *domain,
+ struct iommu_iotlb_gather *gather)
+{
+ sun50i_iommu_flush_iotlb_all(domain);
+}
+
+static int sun50i_iommu_enable(struct sun50i_iommu *iommu)
+{
+ struct sun50i_iommu_domain *sun50i_domain;
+ unsigned long flags;
+ int ret;
+
+ if (!iommu->domain)
+ return 0;
+
+ sun50i_domain = to_sun50i_domain(iommu->domain);
+
+ ret = reset_control_deassert(iommu->reset);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(iommu->clk);
+ if (ret)
+ goto err_reset_assert;
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+
+ iommu_write(iommu, IOMMU_TTB_REG, sun50i_domain->dt_dma);
+ iommu_write(iommu, IOMMU_TLB_PREFETCH_REG,
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(0) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(1) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(2) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(3) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(4) |
+ IOMMU_TLB_PREFETCH_MASTER_ENABLE(5));
+ iommu_write(iommu, IOMMU_INT_ENABLE_REG, IOMMU_INT_MASK);
+ iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_NONE),
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 1) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 1) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 2) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 2) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 3) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 3) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 4) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 4) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 5) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 5));
+
+ iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_RD),
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 0) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 1) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 2) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 3) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 4) |
+ IOMMU_DM_AUT_CTRL_WR_UNAVAIL(SUN50I_IOMMU_ACI_RD, 5));
+
+ iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_WR),
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 0) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 1) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 2) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 3) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 4) |
+ IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_WR, 5));
+
+ ret = sun50i_iommu_flush_all_tlb(iommu);
+ if (ret) {
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+ goto err_clk_disable;
+ }
+
+ iommu_write(iommu, IOMMU_AUTO_GATING_REG, IOMMU_AUTO_GATING_ENABLE);
+ iommu_write(iommu, IOMMU_ENABLE_REG, IOMMU_ENABLE_ENABLE);
+
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+
+ return 0;
+
+err_clk_disable:
+ clk_disable_unprepare(iommu->clk);
+
+err_reset_assert:
+ reset_control_assert(iommu->reset);
+
+ return ret;
+}
+
+static void sun50i_iommu_disable(struct sun50i_iommu *iommu)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->iommu_lock, flags);
+
+ iommu_write(iommu, IOMMU_ENABLE_REG, 0);
+ iommu_write(iommu, IOMMU_TTB_REG, 0);
+
+ spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+
+ clk_disable_unprepare(iommu->clk);
+ reset_control_assert(iommu->reset);
+}
+
+static void *sun50i_iommu_alloc_page_table(struct sun50i_iommu *iommu,
+ gfp_t gfp)
+{
+ dma_addr_t pt_dma;
+ u32 *page_table;
+
+ page_table = kmem_cache_zalloc(iommu->pt_pool, gfp);
+ if (!page_table)
+ return ERR_PTR(-ENOMEM);
+
+ pt_dma = dma_map_single(iommu->dev, page_table, PT_SIZE, DMA_TO_DEVICE);
+ if (dma_mapping_error(iommu->dev, pt_dma)) {
+ dev_err(iommu->dev, "Couldn't map L2 Page Table\n");
+ kmem_cache_free(iommu->pt_pool, page_table);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* We rely on the physical address and DMA address being the same */
+ WARN_ON(pt_dma != virt_to_phys(page_table));
+
+ return page_table;
+}
+
+static void sun50i_iommu_free_page_table(struct sun50i_iommu *iommu,
+ u32 *page_table)
+{
+ phys_addr_t pt_phys = virt_to_phys(page_table);
+
+ dma_unmap_single(iommu->dev, pt_phys, PT_SIZE, DMA_TO_DEVICE);
+ kmem_cache_free(iommu->pt_pool, page_table);
+}
+
+static u32 *sun50i_dte_get_page_table(struct sun50i_iommu_domain *sun50i_domain,
+ dma_addr_t iova, gfp_t gfp)
+{
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ u32 *page_table;
+ u32 *dte_addr;
+ u32 old_dte;
+ u32 dte;
+
+ dte_addr = &sun50i_domain->dt[sun50i_iova_get_dte_index(iova)];
+ dte = *dte_addr;
+ if (sun50i_dte_is_pt_valid(dte)) {
+ phys_addr_t pt_phys = sun50i_dte_get_pt_address(dte);
+ return (u32 *)phys_to_virt(pt_phys);
+ }
+
+ page_table = sun50i_iommu_alloc_page_table(iommu, gfp);
+ if (IS_ERR(page_table))
+ return page_table;
+
+ dte = sun50i_mk_dte(virt_to_phys(page_table));
+ old_dte = cmpxchg(dte_addr, 0, dte);
+ if (old_dte) {
+ phys_addr_t installed_pt_phys =
+ sun50i_dte_get_pt_address(old_dte);
+ u32 *installed_pt = phys_to_virt(installed_pt_phys);
+ u32 *drop_pt = page_table;
+
+ page_table = installed_pt;
+ dte = old_dte;
+ sun50i_iommu_free_page_table(iommu, drop_pt);
+ }
+
+ sun50i_table_flush(sun50i_domain, page_table, PT_SIZE);
+ sun50i_table_flush(sun50i_domain, dte_addr, 1);
+
+ return page_table;
+}
+
+static int sun50i_iommu_map(struct iommu_domain *domain, unsigned long iova,
+ phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu = sun50i_domain->iommu;
+ u32 pte_index;
+ u32 *page_table, *pte_addr;
+ int ret = 0;
+
+ page_table = sun50i_dte_get_page_table(sun50i_domain, iova, gfp);
+ if (IS_ERR(page_table)) {
+ ret = PTR_ERR(page_table);
+ goto out;
+ }
+
+ pte_index = sun50i_iova_get_pte_index(iova);
+ pte_addr = &page_table[pte_index];
+ if (unlikely(sun50i_pte_is_page_valid(*pte_addr))) {
+ phys_addr_t page_phys = sun50i_pte_get_page_address(*pte_addr);
+ dev_err(iommu->dev,
+ "iova %pad already mapped to %pa cannot remap to %pa prot: %#x\n",
+ &iova, &page_phys, &paddr, prot);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ *pte_addr = sun50i_mk_pte(paddr, prot);
+ sun50i_table_flush(sun50i_domain, pte_addr, 1);
+
+out:
+ return ret;
+}
+
+static size_t sun50i_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+ size_t size, struct iommu_iotlb_gather *gather)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ phys_addr_t pt_phys;
+ dma_addr_t pte_dma;
+ u32 *pte_addr;
+ u32 dte;
+
+ dte = sun50i_domain->dt[sun50i_iova_get_dte_index(iova)];
+ if (!sun50i_dte_is_pt_valid(dte))
+ return 0;
+
+ pt_phys = sun50i_dte_get_pt_address(dte);
+ pte_addr = (u32 *)phys_to_virt(pt_phys) + sun50i_iova_get_pte_index(iova);
+ pte_dma = pt_phys + sun50i_iova_get_pte_index(iova) * PT_ENTRY_SIZE;
+
+ if (!sun50i_pte_is_page_valid(*pte_addr))
+ return 0;
+
+ memset(pte_addr, 0, sizeof(*pte_addr));
+ sun50i_table_flush(sun50i_domain, pte_addr, 1);
+
+ return SZ_4K;
+}
+
+static phys_addr_t sun50i_iommu_iova_to_phys(struct iommu_domain *domain,
+ dma_addr_t iova)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ phys_addr_t pt_phys;
+ u32 *page_table;
+ u32 dte, pte;
+
+ dte = sun50i_domain->dt[sun50i_iova_get_dte_index(iova)];
+ if (!sun50i_dte_is_pt_valid(dte))
+ return 0;
+
+ pt_phys = sun50i_dte_get_pt_address(dte);
+ page_table = (u32 *)phys_to_virt(pt_phys);
+ pte = page_table[sun50i_iova_get_pte_index(iova)];
+ if (!sun50i_pte_is_page_valid(pte))
+ return 0;
+
+ return sun50i_pte_get_page_address(pte) +
+ sun50i_iova_get_page_offset(iova);
+}
+
+static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
+{
+ struct sun50i_iommu_domain *sun50i_domain;
+
+ if (type != IOMMU_DOMAIN_DMA &&
+ type != IOMMU_DOMAIN_IDENTITY &&
+ type != IOMMU_DOMAIN_UNMANAGED)
+ return NULL;
+
+ sun50i_domain = kzalloc(sizeof(*sun50i_domain), GFP_KERNEL);
+ if (!sun50i_domain)
+ return NULL;
+
+ if (type == IOMMU_DOMAIN_DMA &&
+ iommu_get_dma_cookie(&sun50i_domain->domain))
+ goto err_free_domain;
+
+ sun50i_domain->dt = (u32 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+ get_order(DT_SIZE));
+ if (!sun50i_domain->dt)
+ goto err_put_cookie;
+
+ refcount_set(&sun50i_domain->refcnt, 1);
+
+ sun50i_domain->domain.geometry.aperture_start = 0;
+ sun50i_domain->domain.geometry.aperture_end = DMA_BIT_MASK(32);
+ sun50i_domain->domain.geometry.force_aperture = true;
+
+ return &sun50i_domain->domain;
+
+err_put_cookie:
+ if (type == IOMMU_DOMAIN_DMA)
+ iommu_put_dma_cookie(&sun50i_domain->domain);
+
+err_free_domain:
+ kfree(sun50i_domain);
+
+ return NULL;
+}
+
+static void sun50i_iommu_domain_free(struct iommu_domain *domain)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+
+ free_pages((unsigned long)sun50i_domain->dt, get_order(DT_SIZE));
+ sun50i_domain->dt = NULL;
+
+ iommu_put_dma_cookie(domain);
+
+ kfree(sun50i_domain);
+}
+
+static int sun50i_iommu_attach_domain(struct sun50i_iommu *iommu,
+ struct sun50i_iommu_domain *sun50i_domain)
+{
+ iommu->domain = &sun50i_domain->domain;
+ sun50i_domain->iommu = iommu;
+
+ sun50i_domain->dt_dma = dma_map_single(iommu->dev, sun50i_domain->dt,
+ DT_SIZE, DMA_TO_DEVICE);
+ if (dma_mapping_error(iommu->dev, sun50i_domain->dt_dma)) {
+ dev_err(iommu->dev, "Couldn't map L1 Page Table\n");
+ return -ENOMEM;
+ }
+
+ return sun50i_iommu_enable(iommu);
+}
+
+static void sun50i_iommu_detach_domain(struct sun50i_iommu *iommu,
+ struct sun50i_iommu_domain *sun50i_domain)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_DT_ENTRIES; i++) {
+ phys_addr_t pt_phys;
+ u32 *page_table;
+ u32 *dte_addr;
+ u32 dte;
+
+ dte_addr = &sun50i_domain->dt[i];
+ dte = *dte_addr;
+ if (!sun50i_dte_is_pt_valid(dte))
+ continue;
+
+ memset(dte_addr, 0, sizeof(*dte_addr));
+ sun50i_table_flush(sun50i_domain, dte_addr, 1);
+
+ pt_phys = sun50i_dte_get_pt_address(dte);
+ page_table = phys_to_virt(pt_phys);
+ sun50i_iommu_free_page_table(iommu, page_table);
+ }
+
+
+ sun50i_iommu_disable(iommu);
+
+ dma_unmap_single(iommu->dev, virt_to_phys(sun50i_domain->dt),
+ DT_SIZE, DMA_TO_DEVICE);
+
+ iommu->domain = NULL;
+}
+
+static void sun50i_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu = dev_iommu_priv_get(dev);
+
+ dev_dbg(dev, "Detaching from IOMMU domain\n");
+
+ if (iommu->domain != domain)
+ return;
+
+ if (refcount_dec_and_test(&sun50i_domain->refcnt))
+ sun50i_iommu_detach_domain(iommu, sun50i_domain);
+}
+
+static int sun50i_iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
+ struct sun50i_iommu *iommu;
+
+ iommu = sun50i_iommu_from_dev(dev);
+ if (!iommu)
+ return -ENODEV;
+
+ dev_dbg(dev, "Attaching to IOMMU domain\n");
+
+ refcount_inc(&sun50i_domain->refcnt);
+
+ if (iommu->domain == domain)
+ return 0;
+
+ if (iommu->domain)
+ sun50i_iommu_detach_device(iommu->domain, dev);
+
+ sun50i_iommu_attach_domain(iommu, sun50i_domain);
+
+ return 0;
+}
+
+static struct iommu_device *sun50i_iommu_probe_device(struct device *dev)
+{
+ struct sun50i_iommu *iommu;
+
+ iommu = sun50i_iommu_from_dev(dev);
+ if (!iommu)
+ return ERR_PTR(-ENODEV);
+
+ return &iommu->iommu;
+}
+
+static void sun50i_iommu_release_device(struct device *dev) {}
+
+static struct iommu_group *sun50i_iommu_device_group(struct device *dev)
+{
+ struct sun50i_iommu *iommu = sun50i_iommu_from_dev(dev);
+
+ return iommu_group_ref_get(iommu->group);
+}
+
+static int sun50i_iommu_of_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
+ unsigned id = args->args[0];
+
+ dev_iommu_priv_set(dev, platform_get_drvdata(iommu_pdev));
+
+ return iommu_fwspec_add_ids(dev, &id, 1);
+}
+
+static const struct iommu_ops sun50i_iommu_ops = {
+ .pgsize_bitmap = SZ_4K,
+ .attach_dev = sun50i_iommu_attach_device,
+ .detach_dev = sun50i_iommu_detach_device,
+ .device_group = sun50i_iommu_device_group,
+ .domain_alloc = sun50i_iommu_domain_alloc,
+ .domain_free = sun50i_iommu_domain_free,
+ .flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
+ .iotlb_sync = sun50i_iommu_iotlb_sync,
+ .iova_to_phys = sun50i_iommu_iova_to_phys,
+ .map = sun50i_iommu_map,
+ .of_xlate = sun50i_iommu_of_xlate,
+ .probe_device = sun50i_iommu_probe_device,
+ .release_device = sun50i_iommu_release_device,
+ .unmap = sun50i_iommu_unmap,
+};
+
+static void sun50i_iommu_report_fault(struct sun50i_iommu *iommu,
+ unsigned master, phys_addr_t iova,
+ unsigned prot)
+{
+ dev_err(iommu->dev, "Page fault for %pad (master %d, dir %s)\n",
+ &iova, master, (prot == IOMMU_FAULT_WRITE) ? "wr" : "rd");
+
+ if (iommu->domain)
+ report_iommu_fault(iommu->domain, iommu->dev, iova, prot);
+ else
+ dev_err(iommu->dev, "Page fault while iommu not attached to any domain?\n");
+}
+
+static phys_addr_t sun50i_iommu_handle_pt_irq(struct sun50i_iommu *iommu,
+ unsigned addr_reg,
+ unsigned blame_reg)
+{
+ phys_addr_t iova;
+ unsigned master;
+ u32 blame;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ iova = iommu_read(iommu, addr_reg);
+ blame = iommu_read(iommu, blame_reg);
+ master = ilog2(blame & IOMMU_INT_MASTER_MASK);
+
+ /*
+ * If the address is not in the page table, we can't get what
+ * operation triggered the fault. Assume it's a read
+ * operation.
+ */
+ sun50i_iommu_report_fault(iommu, master, iova, IOMMU_FAULT_READ);
+
+ return iova;
+}
+
+static phys_addr_t sun50i_iommu_handle_perm_irq(struct sun50i_iommu *iommu)
+{
+ enum sun50i_iommu_aci aci;
+ phys_addr_t iova;
+ unsigned master;
+ unsigned dir;
+ u32 blame;
+
+ assert_spin_locked(&iommu->iommu_lock);
+
+ blame = iommu_read(iommu, IOMMU_INT_STA_REG);
+ master = ilog2(blame & IOMMU_INT_MASTER_MASK);
+ iova = iommu_read(iommu, IOMMU_INT_ERR_ADDR_REG(master));
+ aci = sun50i_get_pte_aci(iommu_read(iommu,
+ IOMMU_INT_ERR_DATA_REG(master)));
+
+ switch (aci) {
+ /*
+ * If we are in the read-only domain, then it means we
+ * tried to write.
+ */
+ case SUN50I_IOMMU_ACI_RD:
+ dir = IOMMU_FAULT_WRITE;
+ break;
+
+ /*
+ * If we are in the write-only domain, then it means
+ * we tried to read.
+ */
+ case SUN50I_IOMMU_ACI_WR:
+
+ /*
+ * If we are in the domain without any permission, we
+ * can't really tell. Let's default to a read
+ * operation.
+ */
+ case SUN50I_IOMMU_ACI_NONE:
+
+ /* WTF? */
+ case SUN50I_IOMMU_ACI_RD_WR:
+ default:
+ dir = IOMMU_FAULT_READ;
+ break;
+ }
+
+ /*
+ * If the address is not in the page table, we can't get what
+ * operation triggered the fault. Assume it's a read
+ * operation.
+ */
+ sun50i_iommu_report_fault(iommu, master, iova, dir);
+
+ return iova;
+}
+
+static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+{
+ struct sun50i_iommu *iommu = dev_id;
+ phys_addr_t iova;
+ u32 status;
+
+ spin_lock(&iommu->iommu_lock);
+
+ status = iommu_read(iommu, IOMMU_INT_STA_REG);
+ if (!(status & IOMMU_INT_MASK)) {
+ spin_unlock(&iommu->iommu_lock);
+ return IRQ_NONE;
+ }
+
+ if (status & IOMMU_INT_INVALID_L2PG)
+ iova = sun50i_iommu_handle_pt_irq(iommu,
+ IOMMU_INT_ERR_ADDR_L2_REG,
+ IOMMU_L2PG_INT_REG);
+ else if (status & IOMMU_INT_INVALID_L1PG)
+ iova = sun50i_iommu_handle_pt_irq(iommu,
+ IOMMU_INT_ERR_ADDR_L1_REG,
+ IOMMU_L1PG_INT_REG);
+ else
+ iova = sun50i_iommu_handle_perm_irq(iommu);
+
+ iommu_write(iommu, IOMMU_INT_CLR_REG, status);
+
+ iommu_write(iommu, IOMMU_RESET_REG, ~status);
+ iommu_write(iommu, IOMMU_RESET_REG, status);
+
+ spin_unlock(&iommu->iommu_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sun50i_iommu_probe(struct platform_device *pdev)
+{
+ struct sun50i_iommu *iommu;
+ int ret, irq;
+
+ iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
+ if (!iommu)
+ return -ENOMEM;
+ spin_lock_init(&iommu->iommu_lock);
+ platform_set_drvdata(pdev, iommu);
+ iommu->dev = &pdev->dev;
+
+ iommu->pt_pool = kmem_cache_create(dev_name(&pdev->dev),
+ PT_SIZE, PT_SIZE,
+ SLAB_HWCACHE_ALIGN,
+ NULL);
+ if (!iommu->pt_pool)
+ return -ENOMEM;
+
+ iommu->group = iommu_group_alloc();
+ if (IS_ERR(iommu->group)) {
+ ret = PTR_ERR(iommu->group);
+ goto err_free_cache;
+ }
+
+ iommu->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(iommu->base)) {
+ ret = PTR_ERR(iommu->base);
+ goto err_free_group;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ ret = irq;
+ goto err_free_group;
+ }
+
+ iommu->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(iommu->clk)) {
+ dev_err(&pdev->dev, "Couldn't get our clock.\n");
+ ret = PTR_ERR(iommu->clk);
+ goto err_free_group;
+ }
+
+ iommu->reset = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(iommu->reset)) {
+ dev_err(&pdev->dev, "Couldn't get our reset line.\n");
+ ret = PTR_ERR(iommu->reset);
+ goto err_free_group;
+ }
+
+ ret = iommu_device_sysfs_add(&iommu->iommu, &pdev->dev,
+ NULL, dev_name(&pdev->dev));
+ if (ret)
+ goto err_free_group;
+
+ iommu_device_set_ops(&iommu->iommu, &sun50i_iommu_ops);
+ iommu_device_set_fwnode(&iommu->iommu, &pdev->dev.of_node->fwnode);
+
+ ret = iommu_device_register(&iommu->iommu);
+ if (ret)
+ goto err_remove_sysfs;
+
+ ret = devm_request_irq(&pdev->dev, irq, sun50i_iommu_irq, 0,
+ dev_name(&pdev->dev), iommu);
+ if (ret < 0)
+ goto err_unregister;
+
+ bus_set_iommu(&platform_bus_type, &sun50i_iommu_ops);
+
+ return 0;
+
+err_unregister:
+ iommu_device_unregister(&iommu->iommu);
+
+err_remove_sysfs:
+ iommu_device_sysfs_remove(&iommu->iommu);
+
+err_free_group:
+ iommu_group_put(iommu->group);
+
+err_free_cache:
+ kmem_cache_destroy(iommu->pt_pool);
+
+ return ret;
+}
+
+static const struct of_device_id sun50i_iommu_dt[] = {
+ { .compatible = "allwinner,sun50i-h6-iommu", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sun50i_iommu_dt);
+
+static struct platform_driver sun50i_iommu_driver = {
+ .driver = {
+ .name = "sun50i-iommu",
+ .of_match_table = sun50i_iommu_dt,
+ .suppress_bind_attrs = true,
+ }
+};
+builtin_platform_driver_probe(sun50i_iommu_driver, sun50i_iommu_probe);
+
+MODULE_DESCRIPTION("Allwinner H6 IOMMU driver");
+MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_AUTHOR("zhuxianbin <zhuxianbin@allwinnertech.com>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index db6559e8336f..5fbdff6ff41a 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -243,28 +243,16 @@ static bool gart_iommu_capable(enum iommu_cap cap)
return false;
}
-static int gart_iommu_add_device(struct device *dev)
+static struct iommu_device *gart_iommu_probe_device(struct device *dev)
{
- struct iommu_group *group;
-
if (!dev_iommu_fwspec_get(dev))
- return -ENODEV;
-
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
+ return ERR_PTR(-ENODEV);
- iommu_device_link(&gart_handle->iommu, dev);
-
- return 0;
+ return &gart_handle->iommu;
}
-static void gart_iommu_remove_device(struct device *dev)
+static void gart_iommu_release_device(struct device *dev)
{
- iommu_group_remove_device(dev);
- iommu_device_unlink(&gart_handle->iommu, dev);
}
static int gart_iommu_of_xlate(struct device *dev,
@@ -290,8 +278,8 @@ static const struct iommu_ops gart_iommu_ops = {
.domain_free = gart_iommu_domain_free,
.attach_dev = gart_iommu_attach_dev,
.detach_dev = gart_iommu_detach_dev,
- .add_device = gart_iommu_add_device,
- .remove_device = gart_iommu_remove_device,
+ .probe_device = gart_iommu_probe_device,
+ .release_device = gart_iommu_release_device,
.device_group = generic_device_group,
.map = gart_iommu_map,
.unmap = gart_iommu_unmap,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 63a147b623e6..7426b7666e2b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -757,11 +757,10 @@ static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
return 0;
}
-static int tegra_smmu_add_device(struct device *dev)
+static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
{
struct device_node *np = dev->of_node;
struct tegra_smmu *smmu = NULL;
- struct iommu_group *group;
struct of_phandle_args args;
unsigned int index = 0;
int err;
@@ -774,7 +773,7 @@ static int tegra_smmu_add_device(struct device *dev)
of_node_put(args.np);
if (err < 0)
- return err;
+ return ERR_PTR(err);
/*
* Only a single IOMMU master interface is currently
@@ -783,8 +782,6 @@ static int tegra_smmu_add_device(struct device *dev)
*/
dev->archdata.iommu = smmu;
- iommu_device_link(&smmu->iommu, dev);
-
break;
}
@@ -793,26 +790,14 @@ static int tegra_smmu_add_device(struct device *dev)
}
if (!smmu)
- return -ENODEV;
-
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- iommu_group_put(group);
+ return ERR_PTR(-ENODEV);
- return 0;
+ return &smmu->iommu;
}
-static void tegra_smmu_remove_device(struct device *dev)
+static void tegra_smmu_release_device(struct device *dev)
{
- struct tegra_smmu *smmu = dev->archdata.iommu;
-
- if (smmu)
- iommu_device_unlink(&smmu->iommu, dev);
-
dev->archdata.iommu = NULL;
- iommu_group_remove_device(dev);
}
static const struct tegra_smmu_group_soc *
@@ -895,8 +880,8 @@ static const struct iommu_ops tegra_smmu_ops = {
.domain_free = tegra_smmu_domain_free,
.attach_dev = tegra_smmu_attach_dev,
.detach_dev = tegra_smmu_detach_dev,
- .add_device = tegra_smmu_add_device,
- .remove_device = tegra_smmu_remove_device,
+ .probe_device = tegra_smmu_probe_device,
+ .release_device = tegra_smmu_release_device,
.device_group = tegra_smmu_device_group,
.map = tegra_smmu_map,
.unmap = tegra_smmu_unmap,
@@ -1015,7 +1000,7 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
* value. However the IOMMU registration process will attempt to add
* all devices to the IOMMU when bus_set_iommu() is called. In order
* not to rely on global variables to track the IOMMU instance, we
- * set it here so that it can be looked up from the .add_device()
+ * set it here so that it can be looked up from the .probe_device()
* callback via the IOMMU device's .drvdata field.
*/
mc->smmu = smmu;
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 4e1d11af23c8..f6f07489a9aa 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -865,24 +865,23 @@ static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode)
return dev ? dev_to_virtio(dev)->priv : NULL;
}
-static int viommu_add_device(struct device *dev)
+static struct iommu_device *viommu_probe_device(struct device *dev)
{
int ret;
- struct iommu_group *group;
struct viommu_endpoint *vdev;
struct viommu_dev *viommu = NULL;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
if (!fwspec || fwspec->ops != &viommu_ops)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
viommu = viommu_get_by_fwnode(fwspec->iommu_fwnode);
if (!viommu)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
if (!vdev)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
vdev->dev = dev;
vdev->viommu = viommu;
@@ -896,45 +895,25 @@ static int viommu_add_device(struct device *dev)
goto err_free_dev;
}
- ret = iommu_device_link(&viommu->iommu, dev);
- if (ret)
- goto err_free_dev;
+ return &viommu->iommu;
- /*
- * Last step creates a default domain and attaches to it. Everything
- * must be ready.
- */
- group = iommu_group_get_for_dev(dev);
- if (IS_ERR(group)) {
- ret = PTR_ERR(group);
- goto err_unlink_dev;
- }
-
- iommu_group_put(group);
-
- return PTR_ERR_OR_ZERO(group);
-
-err_unlink_dev:
- iommu_device_unlink(&viommu->iommu, dev);
err_free_dev:
generic_iommu_put_resv_regions(dev, &vdev->resv_regions);
kfree(vdev);
- return ret;
+ return ERR_PTR(ret);
}
-static void viommu_remove_device(struct device *dev)
+static void viommu_release_device(struct device *dev)
{
- struct viommu_endpoint *vdev;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct viommu_endpoint *vdev;
if (!fwspec || fwspec->ops != &viommu_ops)
return;
vdev = dev_iommu_priv_get(dev);
- iommu_group_remove_device(dev);
- iommu_device_unlink(&vdev->viommu->iommu, dev);
generic_iommu_put_resv_regions(dev, &vdev->resv_regions);
kfree(vdev);
}
@@ -960,8 +939,8 @@ static struct iommu_ops viommu_ops = {
.unmap = viommu_unmap,
.iova_to_phys = viommu_iova_to_phys,
.iotlb_sync = viommu_iotlb_sync,
- .add_device = viommu_add_device,
- .remove_device = viommu_remove_device,
+ .probe_device = viommu_probe_device,
+ .release_device = viommu_release_device,
.device_group = viommu_device_group,
.get_resv_regions = viommu_get_resv_regions,
.put_resv_regions = generic_iommu_put_resv_regions,
diff --git a/drivers/ipack/Kconfig b/drivers/ipack/Kconfig
index 68a422f7b271..fb30091dece3 100644
--- a/drivers/ipack/Kconfig
+++ b/drivers/ipack/Kconfig
@@ -6,7 +6,7 @@
menuconfig IPACK_BUS
tristate "IndustryPack bus support"
depends on HAS_IOMEM
- ---help---
+ help
This option provides support for the IndustryPack framework. There
are IndustryPack carrier boards, which interface another bus (such as
PCI) to an IndustryPack bus, and IndustryPack modules, that are
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 66b9a68f5e9f..29fead208cad 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -493,6 +493,19 @@ config TI_SCI_INTA_IRQCHIP
If you wish to use interrupt aggregator irq resources managed by the
TI System Controller, say Y here. Otherwise, say N.
+config RISCV_INTC
+ bool "RISC-V Local Interrupt Controller"
+ depends on RISCV
+ default y
+ help
+ This enables support for the per-HART local interrupt controller
+ found in standard RISC-V systems. The per-HART local interrupt
+ controller handles timer interrupts, software interrupts, and
+ hardware interrupts. Without a per-HART local interrupt controller,
+ a RISC-V system will be unable to handle any interrupts.
+
+ If you don't know what to do here, say Y.
+
config SIFIVE_PLIC
bool "SiFive Platform-Level Interrupt Controller"
depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 3a4ce283189a..133f9c45744a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_NDS32) += irq-ativic32.o
obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
obj-$(CONFIG_CSKY_MPINTC) += irq-csky-mpintc.o
obj-$(CONFIG_CSKY_APB_INTC) += irq-csky-apb-intc.o
+obj-$(CONFIG_RISCV_INTC) += irq-riscv-intc.o
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
new file mode 100644
index 000000000000..a6f97fa6ff69
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012 Regents of the University of California
+ * Copyright (C) 2017-2018 SiFive
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#define pr_fmt(fmt) "riscv-intc: " fmt
+#include <linux/atomic.h>
+#include <linux/bits.h>
+#include <linux/cpu.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+
+static struct irq_domain *intc_domain;
+
+static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
+{
+ unsigned long cause = regs->cause & ~CAUSE_IRQ_FLAG;
+
+ if (unlikely(cause >= BITS_PER_LONG))
+ panic("unexpected interrupt cause");
+
+ switch (cause) {
+#ifdef CONFIG_SMP
+ case RV_IRQ_SOFT:
+ /*
+ * We only use software interrupts to pass IPIs, so if a
+ * non-SMP system gets one, then we don't know what to do.
+ */
+ handle_IPI(regs);
+ break;
+#endif
+ default:
+ handle_domain_irq(intc_domain, cause, regs);
+ break;
+ }
+}
+
+/*
+ * On RISC-V systems local interrupts are masked or unmasked by writing
+ * the SIE (Supervisor Interrupt Enable) CSR. As CSRs can only be written
+ * on the local hart, these functions can only be called on the hart that
+ * corresponds to the IRQ chip.
+ */
+
+static void riscv_intc_irq_mask(struct irq_data *d)
+{
+ csr_clear(CSR_IE, BIT(d->hwirq));
+}
+
+static void riscv_intc_irq_unmask(struct irq_data *d)
+{
+ csr_set(CSR_IE, BIT(d->hwirq));
+}
+
+static int riscv_intc_cpu_starting(unsigned int cpu)
+{
+ csr_set(CSR_IE, BIT(RV_IRQ_SOFT));
+ return 0;
+}
+
+static int riscv_intc_cpu_dying(unsigned int cpu)
+{
+ csr_clear(CSR_IE, BIT(RV_IRQ_SOFT));
+ return 0;
+}
+
+static struct irq_chip riscv_intc_chip = {
+ .name = "RISC-V INTC",
+ .irq_mask = riscv_intc_irq_mask,
+ .irq_unmask = riscv_intc_irq_unmask,
+};
+
+static int riscv_intc_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_percpu_devid(irq);
+ irq_domain_set_info(d, irq, hwirq, &riscv_intc_chip, d->host_data,
+ handle_percpu_devid_irq, NULL, NULL);
+
+ return 0;
+}
+
+static const struct irq_domain_ops riscv_intc_domain_ops = {
+ .map = riscv_intc_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static int __init riscv_intc_init(struct device_node *node,
+ struct device_node *parent)
+{
+ int rc, hartid;
+
+ hartid = riscv_of_parent_hartid(node);
+ if (hartid < 0) {
+ pr_warn("unable to fine hart id for %pOF\n", node);
+ return 0;
+ }
+
+ /*
+ * The DT will have one INTC DT node under each CPU (or HART)
+ * DT node so riscv_intc_init() function will be called once
+ * for each INTC DT node. We only need to do INTC initialization
+ * for the INTC DT node belonging to boot CPU (or boot HART).
+ */
+ if (riscv_hartid_to_cpuid(hartid) != smp_processor_id())
+ return 0;
+
+ intc_domain = irq_domain_add_linear(node, BITS_PER_LONG,
+ &riscv_intc_domain_ops, NULL);
+ if (!intc_domain) {
+ pr_err("unable to add IRQ domain\n");
+ return -ENXIO;
+ }
+
+ rc = set_handle_irq(&riscv_intc_irq);
+ if (rc) {
+ pr_err("failed to set irq handler\n");
+ return rc;
+ }
+
+ cpuhp_setup_state(CPUHP_AP_IRQ_RISCV_STARTING,
+ "irqchip/riscv/intc:starting",
+ riscv_intc_cpu_starting,
+ riscv_intc_cpu_dying);
+
+ pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+
+ return 0;
+}
+
+IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index d9c53f85a68e..eaa3e9fe54e9 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -9,6 +9,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -76,6 +77,7 @@ struct plic_handler {
void __iomem *enable_base;
struct plic_priv *priv;
};
+static int plic_parent_irq;
static bool plic_cpuhp_setup_done;
static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
@@ -219,15 +221,17 @@ static const struct irq_domain_ops plic_irqdomain_ops = {
* that source ID back to the same claim register. This automatically enables
* and disables the interrupt, so there's nothing else to do.
*/
-static void plic_handle_irq(struct pt_regs *regs)
+static void plic_handle_irq(struct irq_desc *desc)
{
struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
void __iomem *claim = handler->hart_base + CONTEXT_CLAIM;
irq_hw_number_t hwirq;
WARN_ON_ONCE(!handler->present);
- csr_clear(CSR_IE, IE_EIE);
+ chained_irq_enter(chip, desc);
+
while ((hwirq = readl(claim))) {
int irq = irq_find_mapping(handler->priv->irqdomain, hwirq);
@@ -237,21 +241,8 @@ static void plic_handle_irq(struct pt_regs *regs)
else
generic_handle_irq(irq);
}
- csr_set(CSR_IE, IE_EIE);
-}
-
-/*
- * Walk up the DT tree until we find an active RISC-V core (HART) node and
- * extract the cpuid from it.
- */
-static int plic_find_hart_id(struct device_node *node)
-{
- for (; node; node = node->parent) {
- if (of_device_is_compatible(node, "riscv"))
- return riscv_of_processor_hartid(node);
- }
- return -1;
+ chained_irq_exit(chip, desc);
}
static void plic_set_threshold(struct plic_handler *handler, u32 threshold)
@@ -262,10 +253,8 @@ static void plic_set_threshold(struct plic_handler *handler, u32 threshold)
static int plic_dying_cpu(unsigned int cpu)
{
- struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
-
- csr_clear(CSR_IE, IE_EIE);
- plic_set_threshold(handler, PLIC_DISABLE_THRESHOLD);
+ if (plic_parent_irq)
+ disable_percpu_irq(plic_parent_irq);
return 0;
}
@@ -274,7 +263,11 @@ static int plic_starting_cpu(unsigned int cpu)
{
struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
- csr_set(CSR_IE, IE_EIE);
+ if (plic_parent_irq)
+ enable_percpu_irq(plic_parent_irq,
+ irq_get_trigger_type(plic_parent_irq));
+ else
+ pr_warn("cpu%d: parent irq not available\n", cpu);
plic_set_threshold(handler, PLIC_ENABLE_THRESHOLD);
return 0;
@@ -330,7 +323,7 @@ static int __init plic_init(struct device_node *node,
if (parent.args[0] != RV_IRQ_EXT)
continue;
- hartid = plic_find_hart_id(parent.np);
+ hartid = riscv_of_parent_hartid(parent.np);
if (hartid < 0) {
pr_warn("failed to parse hart ID for context %d.\n", i);
continue;
@@ -342,6 +335,14 @@ static int __init plic_init(struct device_node *node,
continue;
}
+ /* Find parent domain and register chained handler */
+ if (!plic_parent_irq && irq_find_host(parent.np)) {
+ plic_parent_irq = irq_of_parse_and_map(node, i);
+ if (plic_parent_irq)
+ irq_set_chained_handler(plic_parent_irq,
+ plic_handle_irq);
+ }
+
/*
* When running in M-mode we need to ignore the S-mode handler.
* Here we assume it always comes later, but that might be a
@@ -382,7 +383,6 @@ done:
pr_info("%pOFP: mapped %d interrupts with %d handlers for"
" %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
- set_handle_irq(plic_handle_irq);
return 0;
out_iounmap:
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index be8387c0eeef..2690e2c5a158 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -7,7 +7,7 @@ menuconfig ISDN
bool "ISDN support"
depends on NET && NETDEVICES
depends on !S390 && !UML
- ---help---
+ help
ISDN ("Integrated Services Digital Network", called RNIS in France)
is a fully digital telephone service that can be used for voice and
data connections. If your computer is equipped with an ISDN
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index fcb9d7bd5bd0..5cdc361da37c 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -4,7 +4,7 @@ menuconfig MACINTOSH_DRIVERS
bool "Macintosh device drivers"
depends on PPC || MAC || X86
default y if (PPC_PMAC || MAC)
- ---help---
+ help
Say Y here to get to see options for devices used with Macintosh
computers. This option alone does not add any kernel code.
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
index eb3adfb7f88d..d4759db002c6 100644
--- a/drivers/macintosh/macio-adb.c
+++ b/drivers/macintosh/macio-adb.c
@@ -9,10 +9,10 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/pgtable.h>
#include <asm/prom.h>
#include <linux/adb.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/hydra.h>
#include <asm/irq.h>
#include <linux/init.h>
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 74bf2938276b..eab7e83c11c4 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -16,8 +16,8 @@
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
+#include <linux/pgtable.h>
#include <asm/prom.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 8450d7c008d0..73e6ae88fafd 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -50,9 +50,9 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/uaccess.h>
+#include <linux/pgtable.h>
#include <asm/machdep.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/sections.h>
#include <asm/irq.h>
#ifdef CONFIG_PPC_PMAC
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 5a577a6734cf..05b1009e2820 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -236,4 +236,22 @@ config SUN6I_MSGBOX
various Allwinner SoCs. This mailbox is used for communication
between the application CPUs and the power management coprocessor.
+config SPRD_MBOX
+ tristate "Spreadtrum Mailbox"
+ depends on ARCH_SPRD || COMPILE_TEST
+ help
+ Mailbox driver implementation for the Spreadtrum platform. It is used
+ to send message between application processors and MCU. Say Y here if
+ you want to build the Spreatrum mailbox controller driver.
+
+config QCOM_IPCC
+ bool "Qualcomm Technologies, Inc. IPCC driver"
+ depends on ARCH_QCOM || COMPILE_TEST
+ help
+ Qualcomm Technologies, Inc. Inter-Processor Communication Controller
+ (IPCC) driver for MSM devices. The driver provides mailbox support for
+ sending interrupts to the clients. On the other hand, the driver also
+ acts as an interrupt controller for receiving interrupts from clients.
+ Say Y here if you want to build this driver.
+
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 2e4364ef5c47..60d224b723a1 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -50,3 +50,7 @@ obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o
obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o
obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o
+
+obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox.o
+
+obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 7906624a731c..7205b825c8b5 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -12,6 +12,7 @@
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#define IMX_MU_xSR_GIPn(x) BIT(28 + (3 - (x)))
@@ -66,6 +67,8 @@ struct imx_mu_priv {
struct clk *clk;
int irq;
+ u32 xcr;
+
bool side_b;
};
@@ -154,12 +157,17 @@ static int imx_mu_scu_tx(struct imx_mu_priv *priv,
switch (cp->type) {
case IMX_MU_TYPE_TX:
- if (msg->hdr.size > sizeof(*msg)) {
+ /*
+ * msg->hdr.size specifies the number of u32 words while
+ * sizeof yields bytes.
+ */
+
+ if (msg->hdr.size > sizeof(*msg) / 4) {
/*
* The real message size can be different to
* struct imx_sc_rpc_msg_max size
*/
- dev_err(priv->dev, "Exceed max msg size (%zu) on TX, got: %i\n", sizeof(*msg), msg->hdr.size);
+ dev_err(priv->dev, "Maximal message size (%zu bytes) exceeded on TX; got: %i bytes\n", sizeof(*msg), msg->hdr.size << 2);
return -EINVAL;
}
@@ -198,9 +206,8 @@ static int imx_mu_scu_rx(struct imx_mu_priv *priv,
imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(0));
*data++ = imx_mu_read(priv, priv->dcfg->xRR[0]);
- if (msg.hdr.size > sizeof(msg)) {
- dev_err(priv->dev, "Exceed max msg size (%zu) on RX, got: %i\n",
- sizeof(msg), msg.hdr.size);
+ if (msg.hdr.size > sizeof(msg) / 4) {
+ dev_err(priv->dev, "Maximal message size (%zu bytes) exceeded on RX; got: %i bytes\n", sizeof(msg), msg.hdr.size << 2);
return -EINVAL;
}
@@ -285,8 +292,10 @@ static int imx_mu_startup(struct mbox_chan *chan)
{
struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
struct imx_mu_con_priv *cp = chan->con_priv;
+ unsigned long irq_flag = IRQF_SHARED;
int ret;
+ pm_runtime_get_sync(priv->dev);
if (cp->type == IMX_MU_TYPE_TXDB) {
/* Tx doorbell don't have ACK support */
tasklet_init(&cp->txdb_tasklet, imx_mu_txdb_tasklet,
@@ -294,8 +303,12 @@ static int imx_mu_startup(struct mbox_chan *chan)
return 0;
}
- ret = request_irq(priv->irq, imx_mu_isr, IRQF_SHARED |
- IRQF_NO_SUSPEND, cp->irq_desc, chan);
+ /* IPC MU should be with IRQF_NO_SUSPEND set */
+ if (!priv->dev->pm_domain)
+ irq_flag |= IRQF_NO_SUSPEND;
+
+ ret = request_irq(priv->irq, imx_mu_isr, irq_flag,
+ cp->irq_desc, chan);
if (ret) {
dev_err(priv->dev,
"Unable to acquire IRQ %d\n", priv->irq);
@@ -323,6 +336,7 @@ static void imx_mu_shutdown(struct mbox_chan *chan)
if (cp->type == IMX_MU_TYPE_TXDB) {
tasklet_kill(&cp->txdb_tasklet);
+ pm_runtime_put_sync(priv->dev);
return;
}
@@ -341,6 +355,7 @@ static void imx_mu_shutdown(struct mbox_chan *chan)
}
free_irq(priv->irq, chan);
+ pm_runtime_put_sync(priv->dev);
}
static const struct mbox_chan_ops imx_mu_ops = {
@@ -374,7 +389,7 @@ static struct mbox_chan *imx_mu_scu_xlate(struct mbox_controller *mbox,
break;
default:
dev_err(mbox->dev, "Invalid chan type: %d\n", type);
- return NULL;
+ return ERR_PTR(-EINVAL);
}
if (chan >= mbox->num_chans) {
@@ -508,14 +523,39 @@ static int imx_mu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- return devm_mbox_controller_register(dev, &priv->mbox);
+ ret = devm_mbox_controller_register(dev, &priv->mbox);
+ if (ret) {
+ clk_disable_unprepare(priv->clk);
+ return ret;
+ }
+
+ pm_runtime_enable(dev);
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ goto disable_runtime_pm;
+ }
+
+ ret = pm_runtime_put_sync(dev);
+ if (ret < 0)
+ goto disable_runtime_pm;
+
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+
+disable_runtime_pm:
+ pm_runtime_disable(dev);
+ clk_disable_unprepare(priv->clk);
+ return ret;
}
static int imx_mu_remove(struct platform_device *pdev)
{
struct imx_mu_priv *priv = platform_get_drvdata(pdev);
- clk_disable_unprepare(priv->clk);
+ pm_runtime_disable(priv->dev);
return 0;
}
@@ -558,12 +598,69 @@ static const struct of_device_id imx_mu_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);
+static int imx_mu_suspend_noirq(struct device *dev)
+{
+ struct imx_mu_priv *priv = dev_get_drvdata(dev);
+
+ if (!priv->clk)
+ priv->xcr = imx_mu_read(priv, priv->dcfg->xCR);
+
+ return 0;
+}
+
+static int imx_mu_resume_noirq(struct device *dev)
+{
+ struct imx_mu_priv *priv = dev_get_drvdata(dev);
+
+ /*
+ * ONLY restore MU when context lost, the TIE could
+ * be set during noirq resume as there is MU data
+ * communication going on, and restore the saved
+ * value will overwrite the TIE and cause MU data
+ * send failed, may lead to system freeze. This issue
+ * is observed by testing freeze mode suspend.
+ */
+ if (!imx_mu_read(priv, priv->dcfg->xCR) && !priv->clk)
+ imx_mu_write(priv, priv->xcr, priv->dcfg->xCR);
+
+ return 0;
+}
+
+static int imx_mu_runtime_suspend(struct device *dev)
+{
+ struct imx_mu_priv *priv = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+}
+
+static int imx_mu_runtime_resume(struct device *dev)
+{
+ struct imx_mu_priv *priv = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ dev_err(dev, "failed to enable clock\n");
+
+ return ret;
+}
+
+static const struct dev_pm_ops imx_mu_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_mu_suspend_noirq,
+ imx_mu_resume_noirq)
+ SET_RUNTIME_PM_OPS(imx_mu_runtime_suspend,
+ imx_mu_runtime_resume, NULL)
+};
+
static struct platform_driver imx_mu_driver = {
.probe = imx_mu_probe,
.remove = imx_mu_remove,
.driver = {
.name = "imx_mu",
.of_match_table = imx_mu_dt_ids,
+ .pm = &imx_mu_pm_ops,
},
};
module_platform_driver(imx_mu_driver);
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index 34844b7a3675..8c7fac38bb1c 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -568,7 +568,7 @@ static int pcc_mbox_probe(struct platform_device *pdev)
return ret;
}
-struct platform_driver pcc_mbox_driver = {
+static struct platform_driver pcc_mbox_driver = {
.probe = pcc_mbox_probe,
.driver = {
.name = "PCCT",
diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
index eeebafd546e5..cec34f0af6ce 100644
--- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
+++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
@@ -24,6 +24,35 @@ struct qcom_apcs_ipc {
struct platform_device *clk;
};
+struct qcom_apcs_ipc_data {
+ int offset;
+ char *clk_name;
+};
+
+static const struct qcom_apcs_ipc_data ipq6018_apcs_data = {
+ .offset = 8, .clk_name = "qcom,apss-ipq6018-clk"
+};
+
+static const struct qcom_apcs_ipc_data ipq8074_apcs_data = {
+ .offset = 8, .clk_name = NULL
+};
+
+static const struct qcom_apcs_ipc_data msm8916_apcs_data = {
+ .offset = 8, .clk_name = "qcom-apcs-msm8916-clk"
+};
+
+static const struct qcom_apcs_ipc_data msm8996_apcs_data = {
+ .offset = 16, .clk_name = NULL
+};
+
+static const struct qcom_apcs_ipc_data msm8998_apcs_data = {
+ .offset = 8, .clk_name = NULL
+};
+
+static const struct qcom_apcs_ipc_data apps_shared_apcs_data = {
+ .offset = 12, .clk_name = NULL
+};
+
static const struct regmap_config apcs_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -48,17 +77,12 @@ static const struct mbox_chan_ops qcom_apcs_ipc_ops = {
static int qcom_apcs_ipc_probe(struct platform_device *pdev)
{
struct qcom_apcs_ipc *apcs;
+ const struct qcom_apcs_ipc_data *apcs_data;
struct regmap *regmap;
struct resource *res;
- unsigned long offset;
void __iomem *base;
unsigned long i;
int ret;
- const struct of_device_id apcs_clk_match_table[] = {
- { .compatible = "qcom,msm8916-apcs-kpss-global", },
- { .compatible = "qcom,qcs404-apcs-apps-global", },
- {}
- };
apcs = devm_kzalloc(&pdev->dev, sizeof(*apcs), GFP_KERNEL);
if (!apcs)
@@ -73,10 +97,10 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
- offset = (unsigned long)of_device_get_match_data(&pdev->dev);
+ apcs_data = of_device_get_match_data(&pdev->dev);
apcs->regmap = regmap;
- apcs->offset = offset;
+ apcs->offset = apcs_data->offset;
/* Initialize channel identifiers */
for (i = 0; i < ARRAY_SIZE(apcs->mbox_chans); i++)
@@ -93,9 +117,9 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)
return ret;
}
- if (of_match_device(apcs_clk_match_table, &pdev->dev)) {
+ if (apcs_data->clk_name) {
apcs->clk = platform_device_register_data(&pdev->dev,
- "qcom-apcs-msm8916-clk",
+ apcs_data->clk_name,
PLATFORM_DEVID_NONE,
NULL, 0);
if (IS_ERR(apcs->clk))
@@ -119,14 +143,15 @@ static int qcom_apcs_ipc_remove(struct platform_device *pdev)
/* .data is the offset of the ipc register within the global block */
static const struct of_device_id qcom_apcs_ipc_of_match[] = {
- { .compatible = "qcom,msm8916-apcs-kpss-global", .data = (void *)8 },
- { .compatible = "qcom,msm8996-apcs-hmss-global", .data = (void *)16 },
- { .compatible = "qcom,msm8998-apcs-hmss-global", .data = (void *)8 },
- { .compatible = "qcom,qcs404-apcs-apps-global", .data = (void *)8 },
- { .compatible = "qcom,sc7180-apss-shared", .data = (void *)12 },
- { .compatible = "qcom,sdm845-apss-shared", .data = (void *)12 },
- { .compatible = "qcom,sm8150-apss-shared", .data = (void *)12 },
- { .compatible = "qcom,ipq8074-apcs-apps-global", .data = (void *)8 },
+ { .compatible = "qcom,ipq6018-apcs-apps-global", .data = &ipq6018_apcs_data },
+ { .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq8074_apcs_data },
+ { .compatible = "qcom,msm8916-apcs-kpss-global", .data = &msm8916_apcs_data },
+ { .compatible = "qcom,msm8996-apcs-hmss-global", .data = &msm8996_apcs_data },
+ { .compatible = "qcom,msm8998-apcs-hmss-global", .data = &msm8998_apcs_data },
+ { .compatible = "qcom,qcs404-apcs-apps-global", .data = &msm8916_apcs_data },
+ { .compatible = "qcom,sc7180-apss-shared", .data = &apps_shared_apcs_data },
+ { .compatible = "qcom,sdm845-apss-shared", .data = &apps_shared_apcs_data },
+ { .compatible = "qcom,sm8150-apss-shared", .data = &apps_shared_apcs_data },
{}
};
MODULE_DEVICE_TABLE(of, qcom_apcs_ipc_of_match);
diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c
new file mode 100644
index 000000000000..2d13c72944c6
--- /dev/null
+++ b/drivers/mailbox/qcom-ipcc.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+
+#define IPCC_MBOX_MAX_CHAN 48
+
+/* IPCC Register offsets */
+#define IPCC_REG_SEND_ID 0x0c
+#define IPCC_REG_RECV_ID 0x10
+#define IPCC_REG_RECV_SIGNAL_ENABLE 0x14
+#define IPCC_REG_RECV_SIGNAL_DISABLE 0x18
+#define IPCC_REG_RECV_SIGNAL_CLEAR 0x1c
+#define IPCC_REG_CLIENT_CLEAR 0x38
+
+#define IPCC_SIGNAL_ID_MASK GENMASK(15, 0)
+#define IPCC_CLIENT_ID_MASK GENMASK(31, 16)
+
+#define IPCC_NO_PENDING_IRQ GENMASK(31, 0)
+
+/**
+ * struct qcom_ipcc_chan_info - Per-mailbox-channel info
+ * @client_id: The client-id to which the interrupt has to be triggered
+ * @signal_id: The signal-id to which the interrupt has to be triggered
+ */
+struct qcom_ipcc_chan_info {
+ u16 client_id;
+ u16 signal_id;
+};
+
+/**
+ * struct qcom_ipcc - Holder for the mailbox driver
+ * @dev: Device associated with this instance
+ * @base: Base address of the IPCC frame associated to APSS
+ * @irq_domain: The irq_domain associated with this instance
+ * @chan: The mailbox channels array
+ * @mchan: The per-mailbox channel info array
+ * @mbox: The mailbox controller
+ * @irq: Summary irq
+ */
+struct qcom_ipcc {
+ struct device *dev;
+ void __iomem *base;
+ struct irq_domain *irq_domain;
+ struct mbox_chan chan[IPCC_MBOX_MAX_CHAN];
+ struct qcom_ipcc_chan_info mchan[IPCC_MBOX_MAX_CHAN];
+ struct mbox_controller mbox;
+ int irq;
+};
+
+static inline struct qcom_ipcc *to_qcom_ipcc(struct mbox_controller *mbox)
+{
+ return container_of(mbox, struct qcom_ipcc, mbox);
+}
+
+static inline u32 qcom_ipcc_get_hwirq(u16 client_id, u16 signal_id)
+{
+ return FIELD_PREP(IPCC_CLIENT_ID_MASK, client_id) |
+ FIELD_PREP(IPCC_SIGNAL_ID_MASK, signal_id);
+}
+
+static irqreturn_t qcom_ipcc_irq_fn(int irq, void *data)
+{
+ struct qcom_ipcc *ipcc = data;
+ u32 hwirq;
+ int virq;
+
+ for (;;) {
+ hwirq = readl(ipcc->base + IPCC_REG_RECV_ID);
+ if (hwirq == IPCC_NO_PENDING_IRQ)
+ break;
+
+ virq = irq_find_mapping(ipcc->irq_domain, hwirq);
+ writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_CLEAR);
+ generic_handle_irq(virq);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void qcom_ipcc_mask_irq(struct irq_data *irqd)
+{
+ struct qcom_ipcc *ipcc = irq_data_get_irq_chip_data(irqd);
+ irq_hw_number_t hwirq = irqd_to_hwirq(irqd);
+
+ writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_DISABLE);
+}
+
+static void qcom_ipcc_unmask_irq(struct irq_data *irqd)
+{
+ struct qcom_ipcc *ipcc = irq_data_get_irq_chip_data(irqd);
+ irq_hw_number_t hwirq = irqd_to_hwirq(irqd);
+
+ writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_ENABLE);
+}
+
+static struct irq_chip qcom_ipcc_irq_chip = {
+ .name = "ipcc",
+ .irq_mask = qcom_ipcc_mask_irq,
+ .irq_unmask = qcom_ipcc_unmask_irq,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static int qcom_ipcc_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct qcom_ipcc *ipcc = d->host_data;
+
+ irq_set_chip_and_handler(irq, &qcom_ipcc_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, ipcc);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static int qcom_ipcc_domain_xlate(struct irq_domain *d,
+ struct device_node *node, const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (intsize != 3)
+ return -EINVAL;
+
+ *out_hwirq = qcom_ipcc_get_hwirq(intspec[0], intspec[1]);
+ *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
+
+ return 0;
+}
+
+static const struct irq_domain_ops qcom_ipcc_irq_ops = {
+ .map = qcom_ipcc_domain_map,
+ .xlate = qcom_ipcc_domain_xlate,
+};
+
+static int qcom_ipcc_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+ struct qcom_ipcc *ipcc = to_qcom_ipcc(chan->mbox);
+ struct qcom_ipcc_chan_info *mchan = chan->con_priv;
+ u32 hwirq;
+
+ hwirq = qcom_ipcc_get_hwirq(mchan->client_id, mchan->signal_id);
+ writel(hwirq, ipcc->base + IPCC_REG_SEND_ID);
+
+ return 0;
+}
+
+static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *ph)
+{
+ struct qcom_ipcc *ipcc = to_qcom_ipcc(mbox);
+ struct qcom_ipcc_chan_info *mchan;
+ struct mbox_chan *chan;
+ unsigned int i;
+
+ if (ph->args_count != 2)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < IPCC_MBOX_MAX_CHAN; i++) {
+ chan = &ipcc->chan[i];
+ if (!chan->con_priv) {
+ mchan = &ipcc->mchan[i];
+ mchan->client_id = ph->args[0];
+ mchan->signal_id = ph->args[1];
+ chan->con_priv = mchan;
+ break;
+ }
+
+ chan = NULL;
+ }
+
+ return chan ?: ERR_PTR(-EBUSY);
+}
+
+static const struct mbox_chan_ops ipcc_mbox_chan_ops = {
+ .send_data = qcom_ipcc_mbox_send_data,
+};
+
+static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc)
+{
+ struct mbox_controller *mbox;
+ struct device *dev = ipcc->dev;
+
+ mbox = &ipcc->mbox;
+ mbox->dev = dev;
+ mbox->num_chans = IPCC_MBOX_MAX_CHAN;
+ mbox->chans = ipcc->chan;
+ mbox->ops = &ipcc_mbox_chan_ops;
+ mbox->of_xlate = qcom_ipcc_mbox_xlate;
+ mbox->txdone_irq = false;
+ mbox->txdone_poll = false;
+
+ return devm_mbox_controller_register(dev, mbox);
+}
+
+static int qcom_ipcc_probe(struct platform_device *pdev)
+{
+ struct qcom_ipcc *ipcc;
+ int ret;
+
+ ipcc = devm_kzalloc(&pdev->dev, sizeof(*ipcc), GFP_KERNEL);
+ if (!ipcc)
+ return -ENOMEM;
+
+ ipcc->dev = &pdev->dev;
+
+ ipcc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ipcc->base))
+ return PTR_ERR(ipcc->base);
+
+ ipcc->irq = platform_get_irq(pdev, 0);
+ if (ipcc->irq < 0)
+ return ipcc->irq;
+
+ ipcc->irq_domain = irq_domain_add_tree(pdev->dev.of_node,
+ &qcom_ipcc_irq_ops, ipcc);
+ if (!ipcc->irq_domain)
+ return -ENOMEM;
+
+ ret = qcom_ipcc_setup_mbox(ipcc);
+ if (ret)
+ goto err_mbox;
+
+ ret = devm_request_irq(&pdev->dev, ipcc->irq, qcom_ipcc_irq_fn,
+ IRQF_TRIGGER_HIGH, "ipcc", ipcc);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register the irq: %d\n", ret);
+ goto err_mbox;
+ }
+
+ enable_irq_wake(ipcc->irq);
+ platform_set_drvdata(pdev, ipcc);
+
+ return 0;
+
+err_mbox:
+ irq_domain_remove(ipcc->irq_domain);
+
+ return ret;
+}
+
+static int qcom_ipcc_remove(struct platform_device *pdev)
+{
+ struct qcom_ipcc *ipcc = platform_get_drvdata(pdev);
+
+ disable_irq_wake(ipcc->irq);
+ irq_domain_remove(ipcc->irq_domain);
+
+ return 0;
+}
+
+static const struct of_device_id qcom_ipcc_of_match[] = {
+ { .compatible = "qcom,ipcc"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, qcom_ipcc_of_match);
+
+static struct platform_driver qcom_ipcc_driver = {
+ .probe = qcom_ipcc_probe,
+ .remove = qcom_ipcc_remove,
+ .driver = {
+ .name = "qcom-ipcc",
+ .of_match_table = qcom_ipcc_of_match,
+ },
+};
+
+static int __init qcom_ipcc_init(void)
+{
+ return platform_driver_register(&qcom_ipcc_driver);
+}
+arch_initcall(qcom_ipcc_init);
+
+MODULE_AUTHOR("Venkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>");
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPCC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mailbox/sprd-mailbox.c b/drivers/mailbox/sprd-mailbox.c
new file mode 100644
index 000000000000..f6fab24ae8a9
--- /dev/null
+++ b/drivers/mailbox/sprd-mailbox.c
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spreadtrum mailbox driver
+ *
+ * Copyright (c) 2020 Spreadtrum Communications Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#define SPRD_MBOX_ID 0x0
+#define SPRD_MBOX_MSG_LOW 0x4
+#define SPRD_MBOX_MSG_HIGH 0x8
+#define SPRD_MBOX_TRIGGER 0xc
+#define SPRD_MBOX_FIFO_RST 0x10
+#define SPRD_MBOX_FIFO_STS 0x14
+#define SPRD_MBOX_IRQ_STS 0x18
+#define SPRD_MBOX_IRQ_MSK 0x1c
+#define SPRD_MBOX_LOCK 0x20
+#define SPRD_MBOX_FIFO_DEPTH 0x24
+
+/* Bit and mask definiation for inbox's SPRD_MBOX_FIFO_STS register */
+#define SPRD_INBOX_FIFO_DELIVER_MASK GENMASK(23, 16)
+#define SPRD_INBOX_FIFO_OVERLOW_MASK GENMASK(15, 8)
+#define SPRD_INBOX_FIFO_DELIVER_SHIFT 16
+#define SPRD_INBOX_FIFO_BUSY_MASK GENMASK(7, 0)
+
+/* Bit and mask definiation for SPRD_MBOX_IRQ_STS register */
+#define SPRD_MBOX_IRQ_CLR BIT(0)
+
+/* Bit and mask definiation for outbox's SPRD_MBOX_FIFO_STS register */
+#define SPRD_OUTBOX_FIFO_FULL BIT(0)
+#define SPRD_OUTBOX_FIFO_WR_SHIFT 16
+#define SPRD_OUTBOX_FIFO_RD_SHIFT 24
+#define SPRD_OUTBOX_FIFO_POS_MASK GENMASK(7, 0)
+
+/* Bit and mask definiation for inbox's SPRD_MBOX_IRQ_MSK register */
+#define SPRD_INBOX_FIFO_BLOCK_IRQ BIT(0)
+#define SPRD_INBOX_FIFO_OVERFLOW_IRQ BIT(1)
+#define SPRD_INBOX_FIFO_DELIVER_IRQ BIT(2)
+#define SPRD_INBOX_FIFO_IRQ_MASK GENMASK(2, 0)
+
+/* Bit and mask definiation for outbox's SPRD_MBOX_IRQ_MSK register */
+#define SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ BIT(0)
+#define SPRD_OUTBOX_FIFO_IRQ_MASK GENMASK(4, 0)
+
+#define SPRD_MBOX_CHAN_MAX 8
+
+struct sprd_mbox_priv {
+ struct mbox_controller mbox;
+ struct device *dev;
+ void __iomem *inbox_base;
+ void __iomem *outbox_base;
+ struct clk *clk;
+ u32 outbox_fifo_depth;
+
+ struct mbox_chan chan[SPRD_MBOX_CHAN_MAX];
+};
+
+static struct sprd_mbox_priv *to_sprd_mbox_priv(struct mbox_controller *mbox)
+{
+ return container_of(mbox, struct sprd_mbox_priv, mbox);
+}
+
+static u32 sprd_mbox_get_fifo_len(struct sprd_mbox_priv *priv, u32 fifo_sts)
+{
+ u32 wr_pos = (fifo_sts >> SPRD_OUTBOX_FIFO_WR_SHIFT) &
+ SPRD_OUTBOX_FIFO_POS_MASK;
+ u32 rd_pos = (fifo_sts >> SPRD_OUTBOX_FIFO_RD_SHIFT) &
+ SPRD_OUTBOX_FIFO_POS_MASK;
+ u32 fifo_len;
+
+ /*
+ * If the read pointer is equal with write pointer, which means the fifo
+ * is full or empty.
+ */
+ if (wr_pos == rd_pos) {
+ if (fifo_sts & SPRD_OUTBOX_FIFO_FULL)
+ fifo_len = priv->outbox_fifo_depth;
+ else
+ fifo_len = 0;
+ } else if (wr_pos > rd_pos) {
+ fifo_len = wr_pos - rd_pos;
+ } else {
+ fifo_len = priv->outbox_fifo_depth - rd_pos + wr_pos;
+ }
+
+ return fifo_len;
+}
+
+static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data)
+{
+ struct sprd_mbox_priv *priv = data;
+ struct mbox_chan *chan;
+ u32 fifo_sts, fifo_len, msg[2];
+ int i, id;
+
+ fifo_sts = readl(priv->outbox_base + SPRD_MBOX_FIFO_STS);
+
+ fifo_len = sprd_mbox_get_fifo_len(priv, fifo_sts);
+ if (!fifo_len) {
+ dev_warn_ratelimited(priv->dev, "spurious outbox interrupt\n");
+ return IRQ_NONE;
+ }
+
+ for (i = 0; i < fifo_len; i++) {
+ msg[0] = readl(priv->outbox_base + SPRD_MBOX_MSG_LOW);
+ msg[1] = readl(priv->outbox_base + SPRD_MBOX_MSG_HIGH);
+ id = readl(priv->outbox_base + SPRD_MBOX_ID);
+
+ chan = &priv->chan[id];
+ mbox_chan_received_data(chan, (void *)msg);
+
+ /* Trigger to update outbox FIFO pointer */
+ writel(0x1, priv->outbox_base + SPRD_MBOX_TRIGGER);
+ }
+
+ /* Clear irq status after reading all message. */
+ writel(SPRD_MBOX_IRQ_CLR, priv->outbox_base + SPRD_MBOX_IRQ_STS);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data)
+{
+ struct sprd_mbox_priv *priv = data;
+ struct mbox_chan *chan;
+ u32 fifo_sts, send_sts, busy, id;
+
+ fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS);
+
+ /* Get the inbox data delivery status */
+ send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >>
+ SPRD_INBOX_FIFO_DELIVER_SHIFT;
+ if (!send_sts) {
+ dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n");
+ return IRQ_NONE;
+ }
+
+ while (send_sts) {
+ id = __ffs(send_sts);
+ send_sts &= (send_sts - 1);
+
+ chan = &priv->chan[id];
+
+ /*
+ * Check if the message was fetched by remote traget, if yes,
+ * that means the transmission has been completed.
+ */
+ busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK;
+ if (!(busy & BIT(id)))
+ mbox_chan_txdone(chan, 0);
+ }
+
+ /* Clear FIFO delivery and overflow status */
+ writel(fifo_sts &
+ (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK),
+ priv->inbox_base + SPRD_MBOX_FIFO_RST);
+
+ /* Clear irq status */
+ writel(SPRD_MBOX_IRQ_CLR, priv->inbox_base + SPRD_MBOX_IRQ_STS);
+
+ return IRQ_HANDLED;
+}
+
+static int sprd_mbox_send_data(struct mbox_chan *chan, void *msg)
+{
+ struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
+ unsigned long id = (unsigned long)chan->con_priv;
+ u32 *data = msg;
+
+ /* Write data into inbox FIFO, and only support 8 bytes every time */
+ writel(data[0], priv->inbox_base + SPRD_MBOX_MSG_LOW);
+ writel(data[1], priv->inbox_base + SPRD_MBOX_MSG_HIGH);
+
+ /* Set target core id */
+ writel(id, priv->inbox_base + SPRD_MBOX_ID);
+
+ /* Trigger remote request */
+ writel(0x1, priv->inbox_base + SPRD_MBOX_TRIGGER);
+
+ return 0;
+}
+
+static int sprd_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
+{
+ struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
+ unsigned long id = (unsigned long)chan->con_priv;
+ u32 busy;
+
+ timeout = jiffies + msecs_to_jiffies(timeout);
+
+ while (time_before(jiffies, timeout)) {
+ busy = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS) &
+ SPRD_INBOX_FIFO_BUSY_MASK;
+ if (!(busy & BIT(id))) {
+ mbox_chan_txdone(chan, 0);
+ return 0;
+ }
+
+ udelay(1);
+ }
+
+ return -ETIME;
+}
+
+static int sprd_mbox_startup(struct mbox_chan *chan)
+{
+ struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
+ u32 val;
+
+ /* Select outbox FIFO mode and reset the outbox FIFO status */
+ writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST);
+
+ /* Enable inbox FIFO overflow and delivery interrupt */
+ val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK);
+ val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ | SPRD_INBOX_FIFO_DELIVER_IRQ);
+ writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
+
+ /* Enable outbox FIFO not empty interrupt */
+ val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+ val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ;
+ writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+
+ return 0;
+}
+
+static void sprd_mbox_shutdown(struct mbox_chan *chan)
+{
+ struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox);
+
+ /* Disable inbox & outbox interrupt */
+ writel(SPRD_INBOX_FIFO_IRQ_MASK, priv->inbox_base + SPRD_MBOX_IRQ_MSK);
+ writel(SPRD_OUTBOX_FIFO_IRQ_MASK, priv->outbox_base + SPRD_MBOX_IRQ_MSK);
+}
+
+static const struct mbox_chan_ops sprd_mbox_ops = {
+ .send_data = sprd_mbox_send_data,
+ .flush = sprd_mbox_flush,
+ .startup = sprd_mbox_startup,
+ .shutdown = sprd_mbox_shutdown,
+};
+
+static void sprd_mbox_disable(void *data)
+{
+ struct sprd_mbox_priv *priv = data;
+
+ clk_disable_unprepare(priv->clk);
+}
+
+static int sprd_mbox_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sprd_mbox_priv *priv;
+ int ret, inbox_irq, outbox_irq;
+ unsigned long id;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+
+ /*
+ * The Spreadtrum mailbox uses an inbox to send messages to the target
+ * core, and uses an outbox to receive messages from other cores.
+ *
+ * Thus the mailbox controller supplies 2 different register addresses
+ * and IRQ numbers for inbox and outbox.
+ */
+ priv->inbox_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->inbox_base))
+ return PTR_ERR(priv->inbox_base);
+
+ priv->outbox_base = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(priv->outbox_base))
+ return PTR_ERR(priv->outbox_base);
+
+ priv->clk = devm_clk_get(dev, "enable");
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get mailbox clock\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, sprd_mbox_disable, priv);
+ if (ret) {
+ dev_err(dev, "failed to add mailbox disable action\n");
+ return ret;
+ }
+
+ inbox_irq = platform_get_irq(pdev, 0);
+ if (inbox_irq < 0)
+ return inbox_irq;
+
+ ret = devm_request_irq(dev, inbox_irq, sprd_mbox_inbox_isr,
+ IRQF_NO_SUSPEND, dev_name(dev), priv);
+ if (ret) {
+ dev_err(dev, "failed to request inbox IRQ: %d\n", ret);
+ return ret;
+ }
+
+ outbox_irq = platform_get_irq(pdev, 1);
+ if (outbox_irq < 0)
+ return outbox_irq;
+
+ ret = devm_request_irq(dev, outbox_irq, sprd_mbox_outbox_isr,
+ IRQF_NO_SUSPEND, dev_name(dev), priv);
+ if (ret) {
+ dev_err(dev, "failed to request outbox IRQ: %d\n", ret);
+ return ret;
+ }
+
+ /* Get the default outbox FIFO depth */
+ priv->outbox_fifo_depth =
+ readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1;
+ priv->mbox.dev = dev;
+ priv->mbox.chans = &priv->chan[0];
+ priv->mbox.num_chans = SPRD_MBOX_CHAN_MAX;
+ priv->mbox.ops = &sprd_mbox_ops;
+ priv->mbox.txdone_irq = true;
+
+ for (id = 0; id < SPRD_MBOX_CHAN_MAX; id++)
+ priv->chan[id].con_priv = (void *)id;
+
+ ret = devm_mbox_controller_register(dev, &priv->mbox);
+ if (ret) {
+ dev_err(dev, "failed to register mailbox: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id sprd_mbox_of_match[] = {
+ { .compatible = "sprd,sc9860-mailbox", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, sprd_mbox_of_match);
+
+static struct platform_driver sprd_mbox_driver = {
+ .driver = {
+ .name = "sprd-mailbox",
+ .of_match_table = sprd_mbox_of_match,
+ },
+ .probe = sprd_mbox_probe,
+};
+module_platform_driver(sprd_mbox_driver);
+
+MODULE_AUTHOR("Baolin Wang <baolin.wang@unisoc.com>");
+MODULE_DESCRIPTION("Spreadtrum mailbox driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
index 86887c9a349a..f44079d62b1a 100644
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
+++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
@@ -504,10 +504,9 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
mchan->req_buf_size = resource_size(&res);
mchan->req_buf = devm_ioremap(mdev, res.start,
mchan->req_buf_size);
- if (IS_ERR(mchan->req_buf)) {
+ if (!mchan->req_buf) {
dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
- ret = PTR_ERR(mchan->req_buf);
- return ret;
+ return -ENOMEM;
}
} else if (ret != -ENODEV) {
dev_err(mdev, "Unmatched resource %s, %d.\n", name, ret);
@@ -520,10 +519,9 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
mchan->resp_buf_size = resource_size(&res);
mchan->resp_buf = devm_ioremap(mdev, res.start,
mchan->resp_buf_size);
- if (IS_ERR(mchan->resp_buf)) {
+ if (!mchan->resp_buf) {
dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
- ret = PTR_ERR(mchan->resp_buf);
- return ret;
+ return -ENOMEM;
}
} else if (ret != -ENODEV) {
dev_err(mdev, "Unmatched resource %s.\n", name);
@@ -543,10 +541,9 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
mchan->req_buf_size = resource_size(&res);
mchan->req_buf = devm_ioremap(mdev, res.start,
mchan->req_buf_size);
- if (IS_ERR(mchan->req_buf)) {
+ if (!mchan->req_buf) {
dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
- ret = PTR_ERR(mchan->req_buf);
- return ret;
+ return -ENOMEM;
}
} else if (ret != -ENODEV) {
dev_err(mdev, "Unmatched resource %s.\n", name);
@@ -559,10 +556,9 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
mchan->resp_buf_size = resource_size(&res);
mchan->resp_buf = devm_ioremap(mdev, res.start,
mchan->resp_buf_size);
- if (IS_ERR(mchan->resp_buf)) {
+ if (!mchan->resp_buf) {
dev_err(mdev, "Unable to map IPI buffer I/O memory\n");
- ret = PTR_ERR(mchan->resp_buf);
- return ret;
+ return -ENOMEM;
}
} else if (ret != -ENODEV) {
dev_err(mdev, "Unmatched resource %s.\n", name);
@@ -668,10 +664,9 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
/* IPI IRQ */
ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
- dev_err(dev, "unable to find IPI IRQ.\n");
+ if (ret < 0)
goto free_mbox_dev;
- }
+
pdata->irq = ret;
ret = devm_request_irq(dev, pdata->irq, zynqmp_ipi_interrupt,
IRQF_SHARED, dev_name(dev), pdata);
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 6665b56865b7..921888df6764 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -15,7 +15,7 @@ if MD
config BLK_DEV_MD
tristate "RAID support"
- ---help---
+ help
This driver lets you combine several hard disk partitions into one
logical block device. This can be used to simply append one
partition to another one or to combine several redundant hard disks
@@ -36,7 +36,7 @@ config MD_AUTODETECT
bool "Autodetect RAID arrays during kernel boot"
depends on BLK_DEV_MD=y
default y
- ---help---
+ help
If you say Y here, then the kernel will try to autodetect raid
arrays as part of its boot process.
@@ -49,7 +49,7 @@ config MD_AUTODETECT
config MD_LINEAR
tristate "Linear (append) mode"
depends on BLK_DEV_MD
- ---help---
+ help
If you say Y here, then your multiple devices driver will be able to
use the so-called linear mode, i.e. it will combine the hard disk
partitions by simply appending one to the other.
@@ -62,7 +62,7 @@ config MD_LINEAR
config MD_RAID0
tristate "RAID-0 (striping) mode"
depends on BLK_DEV_MD
- ---help---
+ help
If you say Y here, then your multiple devices driver will be able to
use the so-called raid0 mode, i.e. it will combine the hard disk
partitions into one logical device in such a fashion as to fill them
@@ -82,7 +82,7 @@ config MD_RAID0
config MD_RAID1
tristate "RAID-1 (mirroring) mode"
depends on BLK_DEV_MD
- ---help---
+ help
A RAID-1 set consists of several disk drives which are exact copies
of each other. In the event of a mirror failure, the RAID driver
will continue to use the operational mirrors in the set, providing
@@ -104,7 +104,7 @@ config MD_RAID1
config MD_RAID10
tristate "RAID-10 (mirrored striping) mode"
depends on BLK_DEV_MD
- ---help---
+ help
RAID-10 provides a combination of striping (RAID-0) and
mirroring (RAID-1) with easier configuration and more flexible
layout.
@@ -129,7 +129,7 @@ config MD_RAID456
select ASYNC_XOR
select ASYNC_PQ
select ASYNC_RAID6_RECOV
- ---help---
+ help
A RAID-5 set of N drives with a capacity of C MB per drive provides
the capacity of C * (N - 1) MB, and protects against a failure
of a single drive. For a given sector (row) number, (N - 1) drives
@@ -183,7 +183,7 @@ config MD_CLUSTER
depends on BLK_DEV_MD
depends on DLM
default n
- ---help---
+ help
Clustering support for MD devices. This enables locking and
synchronization across multiple systems on the cluster, so all
nodes in the cluster can access the MD devices simultaneously.
@@ -203,7 +203,7 @@ config BLK_DEV_DM
tristate "Device mapper support"
select BLK_DEV_DM_BUILTIN
depends on DAX || DAX=n
- ---help---
+ help
Device-mapper is a low level volume manager. It works by allowing
people to specify mappings for ranges of logical sectors. Various
mapping types are available, in addition people may write their own
@@ -219,7 +219,7 @@ config BLK_DEV_DM
config DM_DEBUG
bool "Device mapper debugging support"
depends on BLK_DEV_DM
- ---help---
+ help
Enable this for messages that may help debug device-mapper problems.
If unsure, say N.
@@ -227,7 +227,7 @@ config DM_DEBUG
config DM_BUFIO
tristate
depends on BLK_DEV_DM
- ---help---
+ help
This interface allows you to do buffered I/O on a device and acts
as a cache, holding recently-read blocks in memory and performing
delayed writes.
@@ -235,7 +235,7 @@ config DM_BUFIO
config DM_DEBUG_BLOCK_MANAGER_LOCKING
bool "Block manager locking"
depends on DM_BUFIO
- ---help---
+ help
Block manager locking can catch various metadata corruption issues.
If unsure, say N.
@@ -244,7 +244,7 @@ config DM_DEBUG_BLOCK_STACK_TRACING
bool "Keep stack trace of persistent data block lock holders"
depends on STACKTRACE_SUPPORT && DM_DEBUG_BLOCK_MANAGER_LOCKING
select STACKTRACE
- ---help---
+ help
Enable this for messages that may help debug problems with the
block manager locking used by thin provisioning and caching.
@@ -253,7 +253,7 @@ config DM_DEBUG_BLOCK_STACK_TRACING
config DM_BIO_PRISON
tristate
depends on BLK_DEV_DM
- ---help---
+ help
Some bio locking schemes used by other device-mapper targets
including thin provisioning.
@@ -262,7 +262,7 @@ source "drivers/md/persistent-data/Kconfig"
config DM_UNSTRIPED
tristate "Unstriped target"
depends on BLK_DEV_DM
- ---help---
+ help
Unstripes I/O so it is issued solely on a single drive in a HW
RAID0 or dm-striped target.
@@ -273,7 +273,7 @@ config DM_CRYPT
select CRYPTO
select CRYPTO_CBC
select CRYPTO_ESSIV
- ---help---
+ help
This device-mapper target allows you to create a device that
transparently encrypts the data on it. You'll need to activate
the ciphers you're going to use in the cryptoapi configuration.
@@ -290,7 +290,7 @@ config DM_SNAPSHOT
tristate "Snapshot target"
depends on BLK_DEV_DM
select DM_BUFIO
- ---help---
+ help
Allow volume managers to take writable snapshots of a device.
config DM_THIN_PROVISIONING
@@ -298,7 +298,7 @@ config DM_THIN_PROVISIONING
depends on BLK_DEV_DM
select DM_PERSISTENT_DATA
select DM_BIO_PRISON
- ---help---
+ help
Provides thin provisioning and snapshots that share a data store.
config DM_CACHE
@@ -307,7 +307,7 @@ config DM_CACHE
default n
select DM_PERSISTENT_DATA
select DM_BIO_PRISON
- ---help---
+ help
dm-cache attempts to improve performance of a block device by
moving frequently used data to a smaller, higher performance
device. Different 'policy' plugins can be used to change the
@@ -318,7 +318,7 @@ config DM_CACHE_SMQ
tristate "Stochastic MQ Cache Policy (EXPERIMENTAL)"
depends on DM_CACHE
default y
- ---help---
+ help
A cache policy that uses a multiqueue ordered by recent hits
to select which blocks should be promoted and demoted.
This is meant to be a general purpose policy. It prioritises
@@ -329,7 +329,7 @@ config DM_CACHE_SMQ
config DM_WRITECACHE
tristate "Writecache target"
depends on BLK_DEV_DM
- ---help---
+ help
The writecache target caches writes on persistent memory or SSD.
It is intended for databases or other programs that need extremely
low commit latency.
@@ -351,7 +351,7 @@ config DM_ERA
default n
select DM_PERSISTENT_DATA
select DM_BIO_PRISON
- ---help---
+ help
dm-era tracks which parts of a block device are written to
over time. Useful for maintaining cache coherency when using
vendor snapshots.
@@ -361,7 +361,7 @@ config DM_CLONE
depends on BLK_DEV_DM
default n
select DM_PERSISTENT_DATA
- ---help---
+ help
dm-clone produces a one-to-one copy of an existing, read-only source
device into a writable destination device. The cloned device is
visible/mountable immediately and the copy of the source device to the
@@ -373,7 +373,7 @@ config DM_CLONE
config DM_MIRROR
tristate "Mirror target"
depends on BLK_DEV_DM
- ---help---
+ help
Allow volume managers to mirror logical volumes, also
needed for live data migration tools such as 'pvmove'.
@@ -381,7 +381,7 @@ config DM_LOG_USERSPACE
tristate "Mirror userspace logging"
depends on DM_MIRROR && NET
select CONNECTOR
- ---help---
+ help
The userspace logging module provides a mechanism for
relaying the dm-dirty-log API to userspace. Log designs
which are more suited to userspace implementation (e.g.
@@ -396,7 +396,7 @@ config DM_RAID
select MD_RAID10
select MD_RAID456
select BLK_DEV_MD
- ---help---
+ help
A dm target that supports RAID1, RAID10, RAID4, RAID5 and RAID6 mappings
A RAID-5 set of N drives with a capacity of C MB per drive provides
@@ -418,7 +418,7 @@ config DM_RAID
config DM_ZERO
tristate "Zero target"
depends on BLK_DEV_DM
- ---help---
+ help
A target that discards writes, and returns all zeroes for
reads. Useful in some recovery situations.
@@ -430,13 +430,13 @@ config DM_MULTIPATH
# it is, DM_MULTIPATH must depend on it. We get a build
# error if SCSI_DH=m and DM_MULTIPATH=y
depends on !SCSI_DH || SCSI
- ---help---
+ help
Allow volume managers to support multipath hardware.
config DM_MULTIPATH_QL
tristate "I/O Path Selector based on the number of in-flight I/Os"
depends on DM_MULTIPATH
- ---help---
+ help
This path selector is a dynamic load balancer which selects
the path with the least number of in-flight I/Os.
@@ -445,7 +445,7 @@ config DM_MULTIPATH_QL
config DM_MULTIPATH_ST
tristate "I/O Path Selector based on the service time"
depends on DM_MULTIPATH
- ---help---
+ help
This path selector is a dynamic load balancer which selects
the path expected to complete the incoming I/O in the shortest
time.
@@ -466,7 +466,7 @@ config DM_MULTIPATH_HST
config DM_DELAY
tristate "I/O delaying target"
depends on BLK_DEV_DM
- ---help---
+ help
A target that delays reads and/or writes and can send
them to different devices. Useful for testing.
@@ -475,7 +475,7 @@ config DM_DELAY
config DM_DUST
tristate "Bad sector simulation target"
depends on BLK_DEV_DM
- ---help---
+ help
A target that simulates bad sector behavior.
Useful for testing.
@@ -484,7 +484,7 @@ config DM_DUST
config DM_INIT
bool "DM \"dm-mod.create=\" parameter support"
depends on BLK_DEV_DM=y
- ---help---
+ help
Enable "dm-mod.create=" parameter to create mapped devices at init time.
This option is useful to allow mounting rootfs without requiring an
initramfs.
@@ -496,13 +496,13 @@ config DM_INIT
config DM_UEVENT
bool "DM uevents"
depends on BLK_DEV_DM
- ---help---
+ help
Generate udev events for DM events.
config DM_FLAKEY
tristate "Flakey target"
depends on BLK_DEV_DM
- ---help---
+ help
A target that intermittently fails I/O for debugging purposes.
config DM_VERITY
@@ -511,7 +511,7 @@ config DM_VERITY
select CRYPTO
select CRYPTO_HASH
select DM_BUFIO
- ---help---
+ help
This device-mapper target creates a read-only device that
transparently validates the data on one underlying device against
a pre-generated tree of cryptographic checksums stored on a second
@@ -542,7 +542,7 @@ config DM_VERITY_FEC
depends on DM_VERITY
select REED_SOLOMON
select REED_SOLOMON_DEC8
- ---help---
+ help
Add forward error correction support to dm-verity. This option
makes it possible to use pre-generated error correction data to
recover from corrupted blocks.
@@ -552,7 +552,7 @@ config DM_VERITY_FEC
config DM_SWITCH
tristate "Switch target support (EXPERIMENTAL)"
depends on BLK_DEV_DM
- ---help---
+ help
This device-mapper target creates a device that supports an arbitrary
mapping of fixed-size regions of I/O across a fixed set of paths.
The path used for any specific region can be switched dynamically
@@ -566,7 +566,7 @@ config DM_SWITCH
config DM_LOG_WRITES
tristate "Log writes target support"
depends on BLK_DEV_DM
- ---help---
+ help
This device-mapper target takes two devices, one device to use
normally, one to log all write operations done to the first device.
This is for use by file system developers wishing to verify that
@@ -586,7 +586,7 @@ config DM_INTEGRITY
select DM_BUFIO
select CRYPTO
select ASYNC_XOR
- ---help---
+ help
This device-mapper target emulates a block device that has
additional per-sector tags that can be used for storing
integrity information.
@@ -602,7 +602,7 @@ config DM_ZONED
tristate "Drive-managed zoned block device target support"
depends on BLK_DEV_DM
depends on BLK_DEV_ZONED
- ---help---
+ help
This device-mapper target takes a host-managed or host-aware zoned
block device and exposes most of its capacity as a regular block
device (drive-managed zoned block device) without any write
diff --git a/drivers/md/persistent-data/Kconfig b/drivers/md/persistent-data/Kconfig
index baaec1ae29c1..f4f948b0e173 100644
--- a/drivers/md/persistent-data/Kconfig
+++ b/drivers/md/persistent-data/Kconfig
@@ -4,7 +4,7 @@ config DM_PERSISTENT_DATA
depends on BLK_DEV_DM
select LIBCRC32C
select DM_BUFIO
- ---help---
+ help
Library providing immutable on-disk data structure support for
device-mapper targets such as the thin provisioning target.
diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig
index eea74b7cfa8c..7e830444bdbb 100644
--- a/drivers/media/cec/Kconfig
+++ b/drivers/media/cec/Kconfig
@@ -24,7 +24,7 @@ config CEC_PIN_ERROR_INJ
menuconfig MEDIA_CEC_SUPPORT
bool
prompt "HDMI CEC drivers"
- default y if !MEDIA_SUPPORT_FILTER
+ default y if MEDIA_SUPPORT && !MEDIA_SUPPORT_FILTER
help
Enable support for HDMI CEC (Consumer Electronics Control),
which is an optional HDMI feature.
diff --git a/drivers/media/cec/platform/Kconfig b/drivers/media/cec/platform/Kconfig
index 350533cd8261..b672d3142eb7 100644
--- a/drivers/media/cec/platform/Kconfig
+++ b/drivers/media/cec/platform/Kconfig
@@ -32,7 +32,7 @@ config CEC_MESON_G12A_AO
select REGMAP_MMIO
select CEC_CORE
select CEC_NOTIFIER
- ---help---
+ help
This is a driver for Amlogic Meson G12A SoCs AO CEC interface.
This driver if for the new AO-CEC module found in G12A SoCs,
usually named AO_CEC_B in documentation.
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index d3a3ee5b597b..f4b4a7c135eb 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -726,9 +726,8 @@ EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
{
if (!dev->dma_parms) {
- dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
- if (!dev->dma_parms)
- return -ENOMEM;
+ dev_err(dev, "Failed to set max_seg_size: dma_parms is NULL\n");
+ return -ENODEV;
}
if (dma_get_max_seg_size(dev) < size)
return dma_set_max_seg_size(dev, size);
@@ -737,21 +736,6 @@ int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
}
EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
-/*
- * vb2_dma_contig_clear_max_seg_size() - release resources for DMA parameters
- * @dev: device for configuring DMA parameters
- *
- * This function releases resources allocated to configure DMA parameters
- * (see vb2_dma_contig_set_max_seg_size() function). It should be called from
- * device drivers on driver remove.
- */
-void vb2_dma_contig_clear_max_seg_size(struct device *dev)
-{
- kfree(dev->dma_parms);
- dev->dma_parms = NULL;
-}
-EXPORT_SYMBOL_GPL(vb2_dma_contig_clear_max_seg_size);
-
MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
index 53af26ad1dfb..79ba15a9385a 100644
--- a/drivers/media/pci/bt8xx/bt878.c
+++ b/drivers/media/pci/bt8xx/bt878.c
@@ -13,9 +13,9 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
#include <linux/ioport.h>
-#include <asm/pgtable.h>
#include <asm/page.h>
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/pci/bt8xx/btcx-risc.c b/drivers/media/pci/bt8xx/btcx-risc.c
index 1139a5ad2418..51257980f539 100644
--- a/drivers/media/pci/bt8xx/btcx-risc.c
+++ b/drivers/media/pci/bt8xx/btcx-risc.c
@@ -17,8 +17,8 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/videodev2.h>
+#include <linux/pgtable.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include "btcx-risc.h"
diff --git a/drivers/media/pci/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c
index fc8708047be8..4af72826b006 100644
--- a/drivers/media/pci/bt8xx/bttv-risc.c
+++ b/drivers/media/pci/bt8xx/bttv-risc.c
@@ -20,8 +20,8 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
+#include <linux/pgtable.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <media/v4l2-ioctl.h>
#include "bttvp.h"
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 38d3088d4d38..7ab13eb7527d 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -17,7 +17,6 @@
#include <linux/videodev2.h>
#include <linux/slab.h>
-#include <asm/pgtable.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 6f769c527fae..10c214bd0903 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -10,7 +10,6 @@
* Sakari Ailus <sakari.ailus@iki.fi>
*/
-#include <asm/cacheflush.h>
#include <linux/clk.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -19,6 +18,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 5c2a23b953a4..eba2b9f040df 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1089,6 +1089,10 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev,
child->coherent_dma_mask = dev->coherent_dma_mask;
child->dma_mask = dev->dma_mask;
child->release = s5p_mfc_memdev_release;
+ child->dma_parms = devm_kzalloc(dev, sizeof(*child->dma_parms),
+ GFP_KERNEL);
+ if (!child->dma_parms)
+ goto err;
/*
* The memdevs are not proper OF platform devices, so in order for them
@@ -1104,7 +1108,7 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev,
return child;
device_del(child);
}
-
+err:
put_device(child);
return NULL;
}
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 9e8eb45a5b03..3dc17ebe14fa 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -41,7 +41,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/div64.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index b188577db40f..3f3fbcd60cc6 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1844,7 +1844,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
sizeof(p_hevc_pps->row_height_minus1));
p_hevc_pps->flags &=
- ~V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED;
+ ~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED;
}
if (p_hevc_pps->flags &
diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c
index 2686f03b322e..5c91fc3e65b5 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -535,7 +535,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
if (b->memory == V4L2_MEMORY_MMAP)
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
videobuf_queue_lock(q);
retval = -EBUSY;
@@ -622,7 +622,7 @@ done:
videobuf_queue_unlock(q);
if (b->memory == V4L2_MEMORY_MMAP)
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
return retval;
}
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
index aeb2f497c683..52312ce2ba05 100644
--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
@@ -169,7 +169,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
mem->size = PAGE_ALIGN(vb->size + offset);
ret = -EINVAL;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = find_vma(mm, untagged_baddr);
if (!vma)
@@ -201,7 +201,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
}
out_up:
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
return ret;
}
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 13b65ed9e74c..46ff19df9f53 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -21,13 +21,13 @@
#include <linux/sched/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/pgtable.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <media/videobuf-dma-sg.h>
@@ -200,9 +200,9 @@ static int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
{
int ret;
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
ret = videobuf_dma_init_user_locked(dma, direction, data, size);
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
return ret;
}
@@ -533,7 +533,7 @@ static int __videobuf_iolock(struct videobuf_queue *q,
} else {
/* NOTE: HACK: videobuf_iolock on V4L2_MEMORY_MMAP
buffers can only be called from videobuf_qbuf
- we take current->mm->mmap_sem there, to prevent
+ we take current->mm->mmap_lock there, to prevent
locking inversion, so don't take it here */
err = videobuf_dma_init_user_locked(&mem->dma,
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c
index f8bd5a369560..9b2443720ab0 100644
--- a/drivers/media/v4l2-core/videobuf-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf-vmalloc.c
@@ -15,12 +15,12 @@
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/pgtable.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <media/videobuf-vmalloc.h>
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index ba770c5ea8ef..a3d0288fd0e2 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -3,7 +3,7 @@
menuconfig FUSION
bool "Fusion MPT device support"
depends on PCI
- ---help---
+ help
Say Y here to get to see options for Fusion Message
Passing Technology (MPT) drivers.
This option alone does not add any kernel code.
@@ -16,7 +16,7 @@ config FUSION_SPI
tristate "Fusion MPT ScsiHost drivers for SPI"
depends on PCI && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
SCSI HOST support for a parallel SCSI host adapters.
List of supported controllers:
@@ -31,7 +31,7 @@ config FUSION_FC
tristate "Fusion MPT ScsiHost drivers for FC"
depends on PCI && SCSI
depends on SCSI_FC_ATTRS
- ---help---
+ help
SCSI HOST support for a Fiber Channel host adapters.
List of supported controllers:
@@ -50,7 +50,7 @@ config FUSION_SAS
tristate "Fusion MPT ScsiHost drivers for SAS"
depends on PCI && SCSI
select SCSI_SAS_ATTRS
- ---help---
+ help
SCSI HOST support for a SAS host adapters.
List of supported controllers:
@@ -75,7 +75,7 @@ config FUSION_MAX_SGE
config FUSION_CTL
tristate "Fusion MPT misc device (ioctl) driver"
depends on FUSION_SPI || FUSION_FC || FUSION_SAS
- ---help---
+ help
The Fusion MPT misc device driver provides specialized control
of MPT adapters via system ioctl calls. Use of ioctl calls to
the MPT driver requires that you create and use a misc device
@@ -94,7 +94,7 @@ config FUSION_CTL
config FUSION_LAN
tristate "Fusion MPT LAN driver"
depends on FUSION_FC && NET_FC
- ---help---
+ help
This module supports LAN IP traffic over Fibre Channel port(s)
on Fusion MPT compatible hardware (LSIFC9xx chips).
The physical interface used is defined in RFC 2625.
@@ -110,7 +110,7 @@ config FUSION_LAN
config FUSION_LOGGING
bool "Fusion MPT logging facility"
- ---help---
+ help
This turns on a logging facility that can be used to debug a number
of Fusion MPT related problems.
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4f8b73d92df3..a37d7d171382 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -15,7 +15,7 @@ config MFD_CS5535
tristate "AMD CS5535 and CS5536 southbridge core functions"
select MFD_CORE
depends on PCI && (X86_32 || (X86 && COMPILE_TEST))
- ---help---
+ help
This is the core driver for CS5535/CS5536 MFD functions. This is
necessary for using the board's GPIO and MFGPT functionality.
@@ -292,7 +292,7 @@ config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
select MFD_CORE
- ---help---
+ help
This driver supports the ASIC3 multifunction chip found on many
PDAs (mainly iPAQ and HTC based ones)
@@ -1165,7 +1165,7 @@ config MFD_SI476X_CORE
config MFD_SM501
tristate "Silicon Motion SM501"
depends on HAS_DMA
- ---help---
+ help
This is the core driver for the Silicon Motion SM501 multimedia
companion chip. This device is a multifunction device which may
provide numerous interfaces including USB host controller, USB gadget,
@@ -1176,7 +1176,7 @@ config MFD_SM501
config MFD_SM501_GPIO
bool "Export GPIO via GPIO layer"
depends on MFD_SM501 && GPIOLIB
- ---help---
+ help
This option uses the gpio library layer to export the 64 GPIO
lines on the SM501. The platform data is used to supply the
base number for the first GPIO line to register.
@@ -1721,7 +1721,7 @@ config MFD_TIMBERDALE
tristate "Timberdale FPGA"
select MFD_CORE
depends on PCI && GPIOLIB && (X86_32 || COMPILE_TEST)
- ---help---
+ help
This is the core driver for the timberdale FPGA. This device is a
multifunction device which exposes numerous platform devices.
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index edd5dd5ebfdc..e1b1ba5e2b92 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -60,7 +60,7 @@ config ATMEL_TCLIB
config DUMMY_IRQ
tristate "Dummy IRQ handler"
- ---help---
+ help
This module accepts a single 'irq' parameter, which it should register for.
The sole purpose of this module is to help with debugging of systems on
which spurious IRQs would happen on disabled IRQ vector.
@@ -69,7 +69,7 @@ config IBM_ASM
tristate "Device driver for IBM RSA service processor"
depends on X86 && PCI && INPUT
depends on SERIAL_8250 || SERIAL_8250=n
- ---help---
+ help
This option enables device driver support for in-band access to the
IBM RSA (Condor) service processor in eServer xSeries systems.
The ibmasm device driver allows user space application to access
@@ -167,7 +167,7 @@ config ICS932S401
config ATMEL_SSC
tristate "Device driver for Atmel SSC peripheral"
depends on HAS_IOMEM && (ARCH_AT91 || COMPILE_TEST)
- ---help---
+ help
This option enables device driver support for Atmel Synchronized
Serial Communication peripheral (SSC).
@@ -190,7 +190,7 @@ config SGI_XP
depends on (IA64_SGI_UV || X86_UV) && SMP
depends on X86_64 || BROKEN
select SGI_GRU if X86_64 && SMP
- ---help---
+ help
An SGI machine can be divided into multiple Single System
Images which act independently of each other and have
hardware based memory protection from the others. Enabling
@@ -267,7 +267,7 @@ config SGI_GRU
tristate "SGI GRU driver"
depends on X86_UV && SMP
select MMU_NOTIFIER
- ---help---
+ help
The GRU is a hardware resource located in the system chipset. The GRU
contains memory that can be mmapped into the user address space. This memory is
used to communicate with the GRU to perform functions such as load/store,
@@ -280,7 +280,7 @@ config SGI_GRU
config SGI_GRU_DEBUG
bool "SGI GRU driver debug"
depends on SGI_GRU
- ---help---
+ help
This option enables additional debugging code for the SGI GRU driver.
If you are unsure, say N.
@@ -327,7 +327,7 @@ config SENSORS_TSL2550
config SENSORS_BH1770
tristate "BH1770GLC / SFH7770 combined ALS - Proximity sensor"
depends on I2C
- ---help---
+ help
Say Y here if you want to build a driver for BH1770GLC (ROHM) or
SFH7770 (Osram) combined ambient light and proximity sensor chip.
@@ -337,7 +337,7 @@ config SENSORS_BH1770
config SENSORS_APDS990X
tristate "APDS990X combined als and proximity sensors"
depends on I2C
- ---help---
+ help
Say Y here if you want to build a driver for Avago APDS990x
combined ambient light and proximity sensor chip.
@@ -427,7 +427,7 @@ config PCI_ENDPOINT_TEST
depends on PCI
select CRC32
tristate "PCI Endpoint Test driver"
- ---help---
+ help
Enable this configuration option to enable the host side test driver
for PCI Endpoint.
diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c
index 258c43a95ac3..2a1783f32254 100644
--- a/drivers/misc/cxl/cxllib.c
+++ b/drivers/misc/cxl/cxllib.c
@@ -207,7 +207,7 @@ static int get_vma_info(struct mm_struct *mm, u64 addr,
struct vm_area_struct *vma = NULL;
int rc = 0;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = find_vma(mm, addr);
if (!vma) {
@@ -218,7 +218,7 @@ static int get_vma_info(struct mm_struct *mm, u64 addr,
*vma_start = vma->vm_start;
*vma_end = vma->vm_end;
out:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return rc;
}
@@ -245,9 +245,8 @@ int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags)
dar += page_size) {
if (dar < vma_start || dar >= vma_end) {
/*
- * We don't hold the mm->mmap_sem semaphore
- * while iterating, since the semaphore is
- * required by one of the lower-level page
+ * 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.
*
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 2297e6fc1544..01153b74334a 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -321,7 +321,7 @@ static void cxl_prefault_vma(struct cxl_context *ctx)
return;
}
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
for (ea = vma->vm_start; ea < vma->vm_end;
ea = next_segment(ea, slb.vsid)) {
@@ -336,7 +336,7 @@ static void cxl_prefault_vma(struct cxl_context *ctx)
last_esid = slb.esid;
}
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
}
diff --git a/drivers/misc/echo/Kconfig b/drivers/misc/echo/Kconfig
index be70b263e271..ce0a37a47fc1 100644
--- a/drivers/misc/echo/Kconfig
+++ b/drivers/misc/echo/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config ECHO
tristate "Line Echo Canceller support"
- ---help---
+ help
This driver provides line echo cancelling support for mISDN and
Zaptel drivers.
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index 60460a053b2d..77c21caf2acd 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <asm/pgtable.h>
+#include <linux/pgtable.h>
#include "genwqe_driver.h"
#include "card_base.h"
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
index 3bfe72c59864..8f201d019f5a 100644
--- a/drivers/misc/mic/Kconfig
+++ b/drivers/misc/mic/Kconfig
@@ -116,7 +116,7 @@ config MIC_COSM
config VOP
tristate "VOP Driver"
- depends on VOP_BUS && VHOST_DPN
+ depends on VOP_BUS
select VHOST_RING
select VIRTIO
help
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 4b713a80b572..b1521112dbbd 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -21,7 +21,6 @@
#include <linux/uaccess.h>
#include <linux/security.h>
#include <linux/prefetch.h>
-#include <asm/pgtable.h>
#include "gru.h"
#include "grutables.h"
#include "grulib.h"
@@ -43,7 +42,7 @@ static inline int is_gru_paddr(unsigned long paddr)
}
/*
- * Find the vma of a GRU segment. Caller must hold mmap_sem.
+ * Find the vma of a GRU segment. Caller must hold mmap_lock.
*/
struct vm_area_struct *gru_find_vma(unsigned long vaddr)
{
@@ -59,7 +58,7 @@ struct vm_area_struct *gru_find_vma(unsigned long vaddr)
* Find and lock the gts that contains the specified user vaddr.
*
* Returns:
- * - *gts with the mmap_sem locked for read and the GTS locked.
+ * - *gts with the mmap_lock locked for read and the GTS locked.
* - NULL if vaddr invalid OR is not a valid GSEG vaddr.
*/
@@ -69,14 +68,14 @@ static struct gru_thread_state *gru_find_lock_gts(unsigned long vaddr)
struct vm_area_struct *vma;
struct gru_thread_state *gts = NULL;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
vma = gru_find_vma(vaddr);
if (vma)
gts = gru_find_thread_state(vma, TSID(vaddr, vma));
if (gts)
mutex_lock(&gts->ts_ctxlock);
else
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return gts;
}
@@ -86,7 +85,7 @@ static struct gru_thread_state *gru_alloc_locked_gts(unsigned long vaddr)
struct vm_area_struct *vma;
struct gru_thread_state *gts = ERR_PTR(-EINVAL);
- down_write(&mm->mmap_sem);
+ mmap_write_lock(mm);
vma = gru_find_vma(vaddr);
if (!vma)
goto err;
@@ -95,11 +94,11 @@ static struct gru_thread_state *gru_alloc_locked_gts(unsigned long vaddr)
if (IS_ERR(gts))
goto err;
mutex_lock(&gts->ts_ctxlock);
- downgrade_write(&mm->mmap_sem);
+ mmap_write_downgrade(mm);
return gts;
err:
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
return gts;
}
@@ -109,7 +108,7 @@ err:
static void gru_unlock_gts(struct gru_thread_state *gts)
{
mutex_unlock(&gts->ts_ctxlock);
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
}
/*
@@ -199,7 +198,7 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
* Only supports Intel large pages (2MB only) on x86_64.
* ZZZ - hugepage support is incomplete
*
- * NOTE: mmap_sem is already held on entry to this function. This
+ * NOTE: mmap_lock is already held on entry to this function. This
* guarantees existence of the page tables.
*/
static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
@@ -570,14 +569,14 @@ static irqreturn_t gru_intr(int chiplet, int blade)
}
/*
- * This is running in interrupt context. Trylock the mmap_sem.
+ * This is running in interrupt context. Trylock the mmap_lock.
* If it fails, retry the fault in user context.
*/
gts->ustats.fmm_tlbmiss++;
if (!gts->ts_force_cch_reload &&
- down_read_trylock(&gts->ts_mm->mmap_sem)) {
+ mmap_read_trylock(gts->ts_mm)) {
gru_try_dropin(gru, gts, tfh, NULL);
- up_read(&gts->ts_mm->mmap_sem);
+ mmap_read_unlock(gts->ts_mm);
} else {
tfh_user_polling_mode(tfh);
STAT(intr_mm_lock_failed);
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 9d042310214f..93bb49ddda1f 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -135,7 +135,7 @@ static int gru_create_new_context(unsigned long arg)
if (!(req.options & GRU_OPT_MISS_MASK))
req.options |= GRU_OPT_MISS_FMM_INTR;
- down_write(&current->mm->mmap_sem);
+ mmap_write_lock(current->mm);
vma = gru_find_vma(req.gseg);
if (vma) {
vdata = vma->vm_private_data;
@@ -146,7 +146,7 @@ static int gru_create_new_context(unsigned long arg)
vdata->vd_tlb_preload_count = req.tlb_preload_count;
ret = 0;
}
- up_write(&current->mm->mmap_sem);
+ mmap_write_unlock(current->mm);
return ret;
}
diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c
index d39307f060bd..107028e77ca3 100644
--- a/drivers/misc/uacce/uacce.c
+++ b/drivers/misc/uacce/uacce.c
@@ -90,109 +90,39 @@ static long uacce_fops_compat_ioctl(struct file *filep,
}
#endif
-static int uacce_sva_exit(struct device *dev, struct iommu_sva *handle,
- void *data)
+static int uacce_bind_queue(struct uacce_device *uacce, struct uacce_queue *q)
{
- struct uacce_mm *uacce_mm = data;
- struct uacce_queue *q;
-
- /*
- * No new queue can be added concurrently because no caller can have a
- * reference to this mm. But there may be concurrent calls to
- * uacce_mm_put(), so we need the lock.
- */
- mutex_lock(&uacce_mm->lock);
- list_for_each_entry(q, &uacce_mm->queues, list)
- uacce_put_queue(q);
- uacce_mm->mm = NULL;
- mutex_unlock(&uacce_mm->lock);
+ int pasid;
+ struct iommu_sva *handle;
- return 0;
-}
-
-static struct iommu_sva_ops uacce_sva_ops = {
- .mm_exit = uacce_sva_exit,
-};
-
-static struct uacce_mm *uacce_mm_get(struct uacce_device *uacce,
- struct uacce_queue *q,
- struct mm_struct *mm)
-{
- struct uacce_mm *uacce_mm = NULL;
- struct iommu_sva *handle = NULL;
- int ret;
-
- lockdep_assert_held(&uacce->mm_lock);
-
- list_for_each_entry(uacce_mm, &uacce->mm_list, list) {
- if (uacce_mm->mm == mm) {
- mutex_lock(&uacce_mm->lock);
- list_add(&q->list, &uacce_mm->queues);
- mutex_unlock(&uacce_mm->lock);
- return uacce_mm;
- }
- }
-
- uacce_mm = kzalloc(sizeof(*uacce_mm), GFP_KERNEL);
- if (!uacce_mm)
- return NULL;
+ if (!(uacce->flags & UACCE_DEV_SVA))
+ return 0;
- if (uacce->flags & UACCE_DEV_SVA) {
- /*
- * Safe to pass an incomplete uacce_mm, since mm_exit cannot
- * fire while we hold a reference to the mm.
- */
- handle = iommu_sva_bind_device(uacce->parent, mm, uacce_mm);
- if (IS_ERR(handle))
- goto err_free;
+ handle = iommu_sva_bind_device(uacce->parent, current->mm, NULL);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
- ret = iommu_sva_set_ops(handle, &uacce_sva_ops);
- if (ret)
- goto err_unbind;
-
- uacce_mm->pasid = iommu_sva_get_pasid(handle);
- if (uacce_mm->pasid == IOMMU_PASID_INVALID)
- goto err_unbind;
+ pasid = iommu_sva_get_pasid(handle);
+ if (pasid == IOMMU_PASID_INVALID) {
+ iommu_sva_unbind_device(handle);
+ return -ENODEV;
}
- uacce_mm->mm = mm;
- uacce_mm->handle = handle;
- INIT_LIST_HEAD(&uacce_mm->queues);
- mutex_init(&uacce_mm->lock);
- list_add(&q->list, &uacce_mm->queues);
- list_add(&uacce_mm->list, &uacce->mm_list);
-
- return uacce_mm;
-
-err_unbind:
- if (handle)
- iommu_sva_unbind_device(handle);
-err_free:
- kfree(uacce_mm);
- return NULL;
+ q->handle = handle;
+ q->pasid = pasid;
+ return 0;
}
-static void uacce_mm_put(struct uacce_queue *q)
+static void uacce_unbind_queue(struct uacce_queue *q)
{
- struct uacce_mm *uacce_mm = q->uacce_mm;
-
- lockdep_assert_held(&q->uacce->mm_lock);
-
- mutex_lock(&uacce_mm->lock);
- list_del(&q->list);
- mutex_unlock(&uacce_mm->lock);
-
- if (list_empty(&uacce_mm->queues)) {
- if (uacce_mm->handle)
- iommu_sva_unbind_device(uacce_mm->handle);
- list_del(&uacce_mm->list);
- kfree(uacce_mm);
- }
+ if (!q->handle)
+ return;
+ iommu_sva_unbind_device(q->handle);
+ q->handle = NULL;
}
static int uacce_fops_open(struct inode *inode, struct file *filep)
{
- struct uacce_mm *uacce_mm = NULL;
struct uacce_device *uacce;
struct uacce_queue *q;
int ret = 0;
@@ -205,21 +135,16 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)
if (!q)
return -ENOMEM;
- mutex_lock(&uacce->mm_lock);
- uacce_mm = uacce_mm_get(uacce, q, current->mm);
- mutex_unlock(&uacce->mm_lock);
- if (!uacce_mm) {
- ret = -ENOMEM;
+ ret = uacce_bind_queue(uacce, q);
+ if (ret)
goto out_with_mem;
- }
q->uacce = uacce;
- q->uacce_mm = uacce_mm;
if (uacce->ops->get_queue) {
- ret = uacce->ops->get_queue(uacce, uacce_mm->pasid, q);
+ ret = uacce->ops->get_queue(uacce, q->pasid, q);
if (ret < 0)
- goto out_with_mm;
+ goto out_with_bond;
}
init_waitqueue_head(&q->wait);
@@ -227,12 +152,14 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)
uacce->inode = inode;
q->state = UACCE_Q_INIT;
+ mutex_lock(&uacce->queues_lock);
+ list_add(&q->list, &uacce->queues);
+ mutex_unlock(&uacce->queues_lock);
+
return 0;
-out_with_mm:
- mutex_lock(&uacce->mm_lock);
- uacce_mm_put(q);
- mutex_unlock(&uacce->mm_lock);
+out_with_bond:
+ uacce_unbind_queue(q);
out_with_mem:
kfree(q);
return ret;
@@ -241,14 +168,12 @@ out_with_mem:
static int uacce_fops_release(struct inode *inode, struct file *filep)
{
struct uacce_queue *q = filep->private_data;
- struct uacce_device *uacce = q->uacce;
+ mutex_lock(&q->uacce->queues_lock);
+ list_del(&q->list);
+ mutex_unlock(&q->uacce->queues_lock);
uacce_put_queue(q);
-
- mutex_lock(&uacce->mm_lock);
- uacce_mm_put(q);
- mutex_unlock(&uacce->mm_lock);
-
+ uacce_unbind_queue(q);
kfree(q);
return 0;
@@ -513,8 +438,8 @@ struct uacce_device *uacce_alloc(struct device *parent,
if (ret < 0)
goto err_with_uacce;
- INIT_LIST_HEAD(&uacce->mm_list);
- mutex_init(&uacce->mm_lock);
+ INIT_LIST_HEAD(&uacce->queues);
+ mutex_init(&uacce->queues_lock);
device_initialize(&uacce->dev);
uacce->dev.devt = MKDEV(MAJOR(uacce_devt), uacce->dev_id);
uacce->dev.class = uacce_class;
@@ -561,8 +486,7 @@ EXPORT_SYMBOL_GPL(uacce_register);
*/
void uacce_remove(struct uacce_device *uacce)
{
- struct uacce_mm *uacce_mm;
- struct uacce_queue *q;
+ struct uacce_queue *q, *next_q;
if (!uacce)
return;
@@ -574,24 +498,12 @@ void uacce_remove(struct uacce_device *uacce)
unmap_mapping_range(uacce->inode->i_mapping, 0, 0, 1);
/* ensure no open queue remains */
- mutex_lock(&uacce->mm_lock);
- list_for_each_entry(uacce_mm, &uacce->mm_list, list) {
- /*
- * We don't take the uacce_mm->lock here. Since we hold the
- * device's mm_lock, no queue can be added to or removed from
- * this uacce_mm. We may run concurrently with mm_exit, but
- * uacce_put_queue() is serialized and iommu_sva_unbind_device()
- * waits for the lock that mm_exit is holding.
- */
- list_for_each_entry(q, &uacce_mm->queues, list)
- uacce_put_queue(q);
-
- if (uacce->flags & UACCE_DEV_SVA) {
- iommu_sva_unbind_device(uacce_mm->handle);
- uacce_mm->handle = NULL;
- }
+ mutex_lock(&uacce->queues_lock);
+ list_for_each_entry_safe(q, next_q, &uacce->queues, list) {
+ uacce_put_queue(q);
+ uacce_unbind_queue(q);
}
- mutex_unlock(&uacce->mm_lock);
+ mutex_unlock(&uacce->queues_lock);
/* disable sva now since no opened queues */
if (uacce->flags & UACCE_DEV_SVA)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 0ce332ad986b..3b706af35ec3 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -436,7 +436,7 @@ config MMC_MESON_MX_SDIO
tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support"
depends on ARCH_MESON || COMPILE_TEST
depends on COMMON_CLK
- depends on OF
+ depends on OF_ADDRESS
help
This selects support for the SD/MMC Host Controller on
Amlogic Meson6, Meson8 and Meson8b SoCs.
@@ -577,7 +577,7 @@ config MMC_MVSDIO
tristate "Marvell MMC/SD/SDIO host driver"
depends on PLAT_ORION
depends on OF
- ---help---
+ help
This selects the Marvell SDIO host driver.
SDIO may currently be found on the Kirkwood 88F6281 and 88F6192
SoC controllers.
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 142c0f9485fe..42001c49833b 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -420,8 +420,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
extra_size = 0;
/* Protection Register info */
- extra_size += (extp->NumProtectionFields - 1) *
- sizeof(struct cfi_intelext_otpinfo);
+ if (extp->NumProtectionFields)
+ extra_size += (extp->NumProtectionFields - 1) *
+ sizeof(struct cfi_intelext_otpinfo);
}
if (extp->MinorVersion >= '1') {
@@ -695,14 +696,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
*/
if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
&& extp->FeatureSupport & (1 << 9)) {
+ int offs = 0;
struct cfi_private *newcfi;
struct flchip *chip;
struct flchip_shared *shared;
- int offs, numregions, numparts, partshift, numvirtchips, i, j;
+ int numregions, numparts, partshift, numvirtchips, i, j;
/* Protection Register info */
- offs = (extp->NumProtectionFields - 1) *
- sizeof(struct cfi_intelext_otpinfo);
+ if (extp->NumProtectionFields)
+ offs = (extp->NumProtectionFields - 1) *
+ sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */
offs += extp->extra[offs+1]+2;
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index eb0f4600efd1..a030792115bc 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -647,7 +647,7 @@ static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc)
for (i = 0; i < DOC_ECC_BCH_SIZE; i++)
ecc[i] = bitrev8(hwecc[i]);
- numerrs = decode_bch(docg3->cascade->bch, NULL,
+ numerrs = bch_decode(docg3->cascade->bch, NULL,
DOC_ECC_BCH_COVERED_BYTES,
NULL, ecc, NULL, errorpos);
BUG_ON(numerrs == -EINVAL);
@@ -1984,8 +1984,8 @@ static int __init docg3_probe(struct platform_device *pdev)
return ret;
cascade->base = base;
mutex_init(&cascade->lock);
- cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
- DOC_ECC_BCH_PRIMPOLY);
+ cascade->bch = bch_init(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
+ DOC_ECC_BCH_PRIMPOLY, false);
if (!cascade->bch)
return ret;
@@ -2021,7 +2021,7 @@ notfound:
ret = -ENODEV;
dev_info(dev, "No supported DiskOnChip found\n");
err_probe:
- free_bch(cascade->bch);
+ bch_free(cascade->bch);
for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
if (cascade->floors[floor])
doc_release_device(cascade->floors[floor]);
@@ -2045,7 +2045,7 @@ static int docg3_release(struct platform_device *pdev)
if (cascade->floors[floor])
doc_release_device(cascade->floors[floor]);
- free_bch(docg3->cascade->bch);
+ bch_free(docg3->cascade->bch);
return 0;
}
diff --git a/drivers/mtd/maps/physmap-gemini.c b/drivers/mtd/maps/physmap-gemini.c
index a289c8b5cabf..d4a46e159d38 100644
--- a/drivers/mtd/maps/physmap-gemini.c
+++ b/drivers/mtd/maps/physmap-gemini.c
@@ -46,11 +46,6 @@
#define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */
-static const struct of_device_id syscon_match[] = {
- { .compatible = "cortina,gemini-syscon" },
- { },
-};
-
struct gemini_flash {
struct device *dev;
struct pinctrl *p;
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 078e0f67377d..32e52d83b961 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -89,8 +89,6 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
ret = erase_write (mtd, mtdblk->cache_offset,
mtdblk->cache_size, mtdblk->cache_data);
- if (ret)
- return ret;
/*
* Here we could arguably set the cache state to STATE_CLEAN.
@@ -98,9 +96,14 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
* be notified if this content is altered on the flash by other
* means. Let's declare it empty and leave buffering tasks to
* the buffer cache instead.
+ *
+ * If this cache_offset points to a bad block, data cannot be
+ * written to the device. Clear cache_state to avoid writing to
+ * bad blocks repeatedly.
*/
- mtdblk->cache_state = STATE_EMPTY;
- return 0;
+ if (ret == 0 || ret == -EIO)
+ mtdblk->cache_state = STATE_EMPTY;
+ return ret;
}
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index b47691e1b81c..76d832a88e0c 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -617,6 +617,19 @@ int add_mtd_device(struct mtd_info *mtd)
!(mtd->flags & MTD_NO_ERASE)))
return -EINVAL;
+ /*
+ * MTD_SLC_ON_MLC_EMULATION can only be set on partitions, when the
+ * master is an MLC NAND and has a proper pairing scheme defined.
+ * We also reject masters that implement ->_writev() for now, because
+ * NAND controller drivers don't implement this hook, and adding the
+ * SLC -> MLC address/length conversion to this path is useless if we
+ * don't have a user.
+ */
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION &&
+ (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH ||
+ !master->pairing || master->_writev))
+ return -EINVAL;
+
mutex_lock(&mtd_table_mutex);
i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
@@ -632,6 +645,14 @@ int add_mtd_device(struct mtd_info *mtd)
if (mtd->bitflip_threshold == 0)
mtd->bitflip_threshold = mtd->ecc_strength;
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
+ int ngroups = mtd_pairing_groups(master);
+
+ mtd->erasesize /= ngroups;
+ mtd->size = (u64)mtd_div_by_eb(mtd->size, master) *
+ mtd->erasesize;
+ }
+
if (is_power_of_2(mtd->erasesize))
mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
else
@@ -1074,9 +1095,11 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{
struct mtd_info *master = mtd_get_master(mtd);
u64 mst_ofs = mtd_get_master_ofs(mtd, 0);
+ struct erase_info adjinstr;
int ret;
instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
+ adjinstr = *instr;
if (!mtd->erasesize || !master->_erase)
return -ENOTSUPP;
@@ -1091,12 +1114,27 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
ledtrig_mtd_activity();
- instr->addr += mst_ofs;
- ret = master->_erase(master, instr);
- if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
- instr->fail_addr -= mst_ofs;
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
+ adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) *
+ master->erasesize;
+ adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) *
+ master->erasesize) -
+ adjinstr.addr;
+ }
+
+ adjinstr.addr += mst_ofs;
+
+ ret = master->_erase(master, &adjinstr);
+
+ if (adjinstr.fail_addr != MTD_FAIL_ADDR_UNKNOWN) {
+ instr->fail_addr = adjinstr.fail_addr - mst_ofs;
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
+ instr->fail_addr = mtd_div_by_eb(instr->fail_addr,
+ master);
+ instr->fail_addr *= mtd->erasesize;
+ }
+ }
- instr->addr -= mst_ofs;
return ret;
}
EXPORT_SYMBOL_GPL(mtd_erase);
@@ -1276,6 +1314,101 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs,
return 0;
}
+static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_info *master = mtd_get_master(mtd);
+ int ret;
+
+ from = mtd_get_master_ofs(mtd, from);
+ if (master->_read_oob)
+ ret = master->_read_oob(master, from, ops);
+ else
+ ret = master->_read(master, from, ops->len, &ops->retlen,
+ ops->datbuf);
+
+ return ret;
+}
+
+static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_info *master = mtd_get_master(mtd);
+ int ret;
+
+ to = mtd_get_master_ofs(mtd, to);
+ if (master->_write_oob)
+ ret = master->_write_oob(master, to, ops);
+ else
+ ret = master->_write(master, to, ops->len, &ops->retlen,
+ ops->datbuf);
+
+ return ret;
+}
+
+static int mtd_io_emulated_slc(struct mtd_info *mtd, loff_t start, bool read,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_info *master = mtd_get_master(mtd);
+ int ngroups = mtd_pairing_groups(master);
+ int npairs = mtd_wunit_per_eb(master) / ngroups;
+ struct mtd_oob_ops adjops = *ops;
+ unsigned int wunit, oobavail;
+ struct mtd_pairing_info info;
+ int max_bitflips = 0;
+ u32 ebofs, pageofs;
+ loff_t base, pos;
+
+ ebofs = mtd_mod_by_eb(start, mtd);
+ base = (loff_t)mtd_div_by_eb(start, mtd) * master->erasesize;
+ info.group = 0;
+ info.pair = mtd_div_by_ws(ebofs, mtd);
+ pageofs = mtd_mod_by_ws(ebofs, mtd);
+ oobavail = mtd_oobavail(mtd, ops);
+
+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
+ int ret;
+
+ if (info.pair >= npairs) {
+ info.pair = 0;
+ base += master->erasesize;
+ }
+
+ wunit = mtd_pairing_info_to_wunit(master, &info);
+ pos = mtd_wunit_to_offset(mtd, base, wunit);
+
+ adjops.len = ops->len - ops->retlen;
+ if (adjops.len > mtd->writesize - pageofs)
+ adjops.len = mtd->writesize - pageofs;
+
+ adjops.ooblen = ops->ooblen - ops->oobretlen;
+ if (adjops.ooblen > oobavail - adjops.ooboffs)
+ adjops.ooblen = oobavail - adjops.ooboffs;
+
+ if (read) {
+ ret = mtd_read_oob_std(mtd, pos + pageofs, &adjops);
+ if (ret > 0)
+ max_bitflips = max(max_bitflips, ret);
+ } else {
+ ret = mtd_write_oob_std(mtd, pos + pageofs, &adjops);
+ }
+
+ if (ret < 0)
+ return ret;
+
+ max_bitflips = max(max_bitflips, ret);
+ ops->retlen += adjops.retlen;
+ ops->oobretlen += adjops.oobretlen;
+ adjops.datbuf += adjops.retlen;
+ adjops.oobbuf += adjops.oobretlen;
+ adjops.ooboffs = 0;
+ pageofs = 0;
+ info.pair++;
+ }
+
+ return max_bitflips;
+}
+
int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
{
struct mtd_info *master = mtd_get_master(mtd);
@@ -1294,12 +1427,10 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
if (!master->_read_oob && (!master->_read || ops->oobbuf))
return -EOPNOTSUPP;
- from = mtd_get_master_ofs(mtd, from);
- if (master->_read_oob)
- ret_code = master->_read_oob(master, from, ops);
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
+ ret_code = mtd_io_emulated_slc(mtd, from, true, ops);
else
- ret_code = master->_read(master, from, ops->len, &ops->retlen,
- ops->datbuf);
+ ret_code = mtd_read_oob_std(mtd, from, ops);
mtd_update_ecc_stats(mtd, master, &old_stats);
@@ -1338,13 +1469,10 @@ int mtd_write_oob(struct mtd_info *mtd, loff_t to,
if (!master->_write_oob && (!master->_write || ops->oobbuf))
return -EOPNOTSUPP;
- to = mtd_get_master_ofs(mtd, to);
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
+ return mtd_io_emulated_slc(mtd, to, false, ops);
- if (master->_write_oob)
- return master->_write_oob(master, to, ops);
- else
- return master->_write(master, to, ops->len, &ops->retlen,
- ops->datbuf);
+ return mtd_write_oob_std(mtd, to, ops);
}
EXPORT_SYMBOL_GPL(mtd_write_oob);
@@ -1672,7 +1800,7 @@ EXPORT_SYMBOL_GPL(mtd_ooblayout_get_databytes);
* @start: first ECC byte to set
* @nbytes: number of ECC bytes to set
*
- * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
+ * Works like mtd_ooblayout_set_bytes(), except it acts on free bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
@@ -1817,6 +1945,12 @@ int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return -EINVAL;
if (!len)
return 0;
+
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
+ }
+
return master->_lock(master, mtd_get_master_ofs(mtd, ofs), len);
}
EXPORT_SYMBOL_GPL(mtd_lock);
@@ -1831,6 +1965,12 @@ int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return -EINVAL;
if (!len)
return 0;
+
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
+ }
+
return master->_unlock(master, mtd_get_master_ofs(mtd, ofs), len);
}
EXPORT_SYMBOL_GPL(mtd_unlock);
@@ -1845,6 +1985,12 @@ int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return -EINVAL;
if (!len)
return 0;
+
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
+ }
+
return master->_is_locked(master, mtd_get_master_ofs(mtd, ofs), len);
}
EXPORT_SYMBOL_GPL(mtd_is_locked);
@@ -1857,6 +2003,10 @@ int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs)
return -EINVAL;
if (!master->_block_isreserved)
return 0;
+
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
+
return master->_block_isreserved(master, mtd_get_master_ofs(mtd, ofs));
}
EXPORT_SYMBOL_GPL(mtd_block_isreserved);
@@ -1869,6 +2019,10 @@ int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
return -EINVAL;
if (!master->_block_isbad)
return 0;
+
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
+
return master->_block_isbad(master, mtd_get_master_ofs(mtd, ofs));
}
EXPORT_SYMBOL_GPL(mtd_block_isbad);
@@ -1885,6 +2039,9 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
if (!(mtd->flags & MTD_WRITEABLE))
return -EROFS;
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
+
ret = master->_block_markbad(master, mtd_get_master_ofs(mtd, ofs));
if (ret)
return ret;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 3f6025684f58..c3575b686f79 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -35,9 +35,12 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
const struct mtd_partition *part,
int partno, uint64_t cur_offset)
{
- int wr_alignment = (parent->flags & MTD_NO_ERASE) ? parent->writesize :
- parent->erasesize;
- struct mtd_info *child, *master = mtd_get_master(parent);
+ struct mtd_info *master = mtd_get_master(parent);
+ int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
+ master->writesize : master->erasesize;
+ u64 parent_size = mtd_is_partition(parent) ?
+ parent->part.size : parent->size;
+ struct mtd_info *child;
u32 remainder;
char *name;
u64 tmp;
@@ -56,8 +59,9 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
/* set up the MTD object for this partition */
child->type = parent->type;
child->part.flags = parent->flags & ~part->mask_flags;
+ child->part.flags |= part->add_flags;
child->flags = child->part.flags;
- child->size = part->size;
+ child->part.size = part->size;
child->writesize = parent->writesize;
child->writebufsize = parent->writebufsize;
child->oobsize = parent->oobsize;
@@ -98,29 +102,29 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
}
if (child->part.offset == MTDPART_OFS_RETAIN) {
child->part.offset = cur_offset;
- if (parent->size - child->part.offset >= child->size) {
- child->size = parent->size - child->part.offset -
- child->size;
+ if (parent_size - child->part.offset >= child->part.size) {
+ child->part.size = parent_size - child->part.offset -
+ child->part.size;
} else {
printk(KERN_ERR "mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n",
- part->name, parent->size - child->part.offset,
- child->size);
+ part->name, parent_size - child->part.offset,
+ child->part.size);
/* register to preserve ordering */
goto out_register;
}
}
- if (child->size == MTDPART_SIZ_FULL)
- child->size = parent->size - child->part.offset;
+ if (child->part.size == MTDPART_SIZ_FULL)
+ child->part.size = parent_size - child->part.offset;
printk(KERN_NOTICE "0x%012llx-0x%012llx : \"%s\"\n",
- child->part.offset, child->part.offset + child->size,
+ child->part.offset, child->part.offset + child->part.size,
child->name);
/* let's do some sanity checks */
- if (child->part.offset >= parent->size) {
+ if (child->part.offset >= parent_size) {
/* let's register it anyway to preserve ordering */
child->part.offset = 0;
- child->size = 0;
+ child->part.size = 0;
/* Initialize ->erasesize to make add_mtd_device() happy. */
child->erasesize = parent->erasesize;
@@ -128,15 +132,16 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
part->name);
goto out_register;
}
- if (child->part.offset + child->size > parent->size) {
- child->size = parent->size - child->part.offset;
+ if (child->part.offset + child->part.size > parent->size) {
+ child->part.size = parent_size - child->part.offset;
printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n",
- part->name, parent->name, child->size);
+ part->name, parent->name, child->part.size);
}
+
if (parent->numeraseregions > 1) {
/* Deal with variable erase size stuff */
int i, max = parent->numeraseregions;
- u64 end = child->part.offset + child->size;
+ u64 end = child->part.offset + child->part.size;
struct mtd_erase_region_info *regions = parent->eraseregions;
/* Find the first erase regions which is part of this
@@ -156,7 +161,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
BUG_ON(child->erasesize == 0);
} else {
/* Single erase size */
- child->erasesize = parent->erasesize;
+ child->erasesize = master->erasesize;
}
/*
@@ -178,7 +183,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
part->name);
}
- tmp = mtd_get_master_ofs(child, 0) + child->size;
+ tmp = mtd_get_master_ofs(child, 0) + child->part.size;
remainder = do_div(tmp, wr_alignment);
if ((child->flags & MTD_WRITEABLE) && remainder) {
child->flags &= ~MTD_WRITEABLE;
@@ -186,6 +191,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
part->name);
}
+ child->size = child->part.size;
child->ecc_step_size = parent->ecc_step_size;
child->ecc_strength = parent->ecc_strength;
child->bitflip_threshold = parent->bitflip_threshold;
@@ -193,7 +199,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
if (master->_block_isbad) {
uint64_t offs = 0;
- while (offs < child->size) {
+ while (offs < child->part.size) {
if (mtd_block_isreserved(child, offs))
child->ecc_stats.bbtblocks++;
else if (mtd_block_isbad(child, offs))
@@ -234,6 +240,8 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
long long offset, long long length)
{
struct mtd_info *master = mtd_get_master(parent);
+ u64 parent_size = mtd_is_partition(parent) ?
+ parent->part.size : parent->size;
struct mtd_partition part;
struct mtd_info *child;
int ret = 0;
@@ -244,7 +252,7 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
return -EINVAL;
if (length == MTDPART_SIZ_FULL)
- length = parent->size - offset;
+ length = parent_size - offset;
if (length <= 0)
return -EINVAL;
@@ -419,7 +427,7 @@ int add_mtd_partitions(struct mtd_info *parent,
/* Look for subpartitions */
parse_mtd_partitions(child, parts[i].types, NULL);
- cur_offset = child->part.offset + child->size;
+ cur_offset = child->part.offset + child->part.size;
}
return 0;
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index a80a46bb5b8b..113f61052269 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -213,10 +213,6 @@ config MTD_NAND_MLC_LPC32XX
Please check the actual NAND chip connected and its support
by the MLC NAND controller.
-config MTD_NAND_CM_X270
- tristate "CM-X270 modules NAND controller"
- depends on MACH_ARMCORE
-
config MTD_NAND_PASEMI
tristate "PA Semi PWRficient NAND controller"
depends on PPC_PASEMI
@@ -457,6 +453,14 @@ config MTD_NAND_CADENCE
Enable the driver for NAND flash on platforms using a Cadence NAND
controller.
+config MTD_NAND_ARASAN
+ tristate "Support for Arasan NAND flash controller"
+ depends on HAS_IOMEM && HAS_DMA
+ select BCH
+ help
+ Enables the driver for the Arasan NAND flash controller on
+ Zynq Ultrascale+ MPSoC.
+
comment "Misc"
config MTD_SM_COMMON
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 2d136b158fb7..2930f5b9015d 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o
omap2_nand-objs := omap2.o
obj-$(CONFIG_MTD_NAND_OMAP2) += omap2_nand.o
obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD) += omap_elm.o
-obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
obj-$(CONFIG_MTD_NAND_MARVELL) += marvell_nand.o
obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
@@ -58,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o
+obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o
nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o
diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index d66dab25df20..3711e7a0436c 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -387,12 +387,15 @@ static int gpio_nand_remove(struct platform_device *pdev)
{
struct gpio_nand *priv = platform_get_drvdata(pdev);
struct mtd_info *mtd = nand_to_mtd(&priv->nand_chip);
+ int ret;
/* Apply write protection */
gpiod_set_value(priv->gpiod_nwp, 1);
/* Unregister device */
- nand_release(mtd_to_nand(mtd));
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(mtd_to_nand(mtd));
return 0;
}
diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c
new file mode 100644
index 000000000000..7141dcccba3c
--- /dev/null
+++ b/drivers/mtd/nand/raw/arasan-nand-controller.c
@@ -0,0 +1,1297 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Arasan NAND Flash Controller Driver
+ *
+ * Copyright (C) 2014 - 2020 Xilinx, Inc.
+ * Author:
+ * Miquel Raynal <miquel.raynal@bootlin.com>
+ * Original work (fully rewritten):
+ * Punnaiah Choudary Kalluri <punnaia@xilinx.com>
+ * Naga Sureshkumar Relli <nagasure@xilinx.com>
+ */
+
+#include <linux/bch.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define PKT_REG 0x00
+#define PKT_SIZE(x) FIELD_PREP(GENMASK(10, 0), (x))
+#define PKT_STEPS(x) FIELD_PREP(GENMASK(23, 12), (x))
+
+#define MEM_ADDR1_REG 0x04
+
+#define MEM_ADDR2_REG 0x08
+#define ADDR2_STRENGTH(x) FIELD_PREP(GENMASK(27, 25), (x))
+#define ADDR2_CS(x) FIELD_PREP(GENMASK(31, 30), (x))
+
+#define CMD_REG 0x0C
+#define CMD_1(x) FIELD_PREP(GENMASK(7, 0), (x))
+#define CMD_2(x) FIELD_PREP(GENMASK(15, 8), (x))
+#define CMD_PAGE_SIZE(x) FIELD_PREP(GENMASK(25, 23), (x))
+#define CMD_DMA_ENABLE BIT(27)
+#define CMD_NADDRS(x) FIELD_PREP(GENMASK(30, 28), (x))
+#define CMD_ECC_ENABLE BIT(31)
+
+#define PROG_REG 0x10
+#define PROG_PGRD BIT(0)
+#define PROG_ERASE BIT(2)
+#define PROG_STATUS BIT(3)
+#define PROG_PGPROG BIT(4)
+#define PROG_RDID BIT(6)
+#define PROG_RDPARAM BIT(7)
+#define PROG_RST BIT(8)
+#define PROG_GET_FEATURE BIT(9)
+#define PROG_SET_FEATURE BIT(10)
+
+#define INTR_STS_EN_REG 0x14
+#define INTR_SIG_EN_REG 0x18
+#define INTR_STS_REG 0x1C
+#define WRITE_READY BIT(0)
+#define READ_READY BIT(1)
+#define XFER_COMPLETE BIT(2)
+#define DMA_BOUNDARY BIT(6)
+#define EVENT_MASK GENMASK(7, 0)
+
+#define READY_STS_REG 0x20
+
+#define DMA_ADDR0_REG 0x50
+#define DMA_ADDR1_REG 0x24
+
+#define FLASH_STS_REG 0x28
+
+#define DATA_PORT_REG 0x30
+
+#define ECC_CONF_REG 0x34
+#define ECC_CONF_COL(x) FIELD_PREP(GENMASK(15, 0), (x))
+#define ECC_CONF_LEN(x) FIELD_PREP(GENMASK(26, 16), (x))
+#define ECC_CONF_BCH_EN BIT(27)
+
+#define ECC_ERR_CNT_REG 0x38
+#define GET_PKT_ERR_CNT(x) FIELD_GET(GENMASK(7, 0), (x))
+#define GET_PAGE_ERR_CNT(x) FIELD_GET(GENMASK(16, 8), (x))
+
+#define ECC_SP_REG 0x3C
+#define ECC_SP_CMD1(x) FIELD_PREP(GENMASK(7, 0), (x))
+#define ECC_SP_CMD2(x) FIELD_PREP(GENMASK(15, 8), (x))
+#define ECC_SP_ADDRS(x) FIELD_PREP(GENMASK(30, 28), (x))
+
+#define ECC_1ERR_CNT_REG 0x40
+#define ECC_2ERR_CNT_REG 0x44
+
+#define DATA_INTERFACE_REG 0x6C
+#define DIFACE_SDR_MODE(x) FIELD_PREP(GENMASK(2, 0), (x))
+#define DIFACE_DDR_MODE(x) FIELD_PREP(GENMASK(5, 3), (X))
+#define DIFACE_SDR 0
+#define DIFACE_NVDDR BIT(9)
+
+#define ANFC_MAX_CS 2
+#define ANFC_DFLT_TIMEOUT_US 1000000
+#define ANFC_MAX_CHUNK_SIZE SZ_1M
+#define ANFC_MAX_PARAM_SIZE SZ_4K
+#define ANFC_MAX_STEPS SZ_2K
+#define ANFC_MAX_PKT_SIZE (SZ_2K - 1)
+#define ANFC_MAX_ADDR_CYC 5U
+#define ANFC_RSVD_ECC_BYTES 21
+
+#define ANFC_XLNX_SDR_DFLT_CORE_CLK 100000000
+#define ANFC_XLNX_SDR_HS_CORE_CLK 80000000
+
+/**
+ * struct anfc_op - Defines how to execute an operation
+ * @pkt_reg: Packet register
+ * @addr1_reg: Memory address 1 register
+ * @addr2_reg: Memory address 2 register
+ * @cmd_reg: Command register
+ * @prog_reg: Program register
+ * @steps: Number of "packets" to read/write
+ * @rdy_timeout_ms: Timeout for waits on Ready/Busy pin
+ * @len: Data transfer length
+ * @read: Data transfer direction from the controller point of view
+ */
+struct anfc_op {
+ u32 pkt_reg;
+ u32 addr1_reg;
+ u32 addr2_reg;
+ u32 cmd_reg;
+ u32 prog_reg;
+ int steps;
+ unsigned int rdy_timeout_ms;
+ unsigned int len;
+ bool read;
+ u8 *buf;
+};
+
+/**
+ * struct anand - Defines the NAND chip related information
+ * @node: Used to store NAND chips into a list
+ * @chip: NAND chip information structure
+ * @cs: Chip select line
+ * @rb: Ready-busy line
+ * @page_sz: Register value of the page_sz field to use
+ * @clk: Expected clock frequency to use
+ * @timings: Data interface timing mode to use
+ * @ecc_conf: Hardware ECC configuration value
+ * @strength: Register value of the ECC strength
+ * @raddr_cycles: Row address cycle information
+ * @caddr_cycles: Column address cycle information
+ * @ecc_bits: Exact number of ECC bits per syndrome
+ * @ecc_total: Total number of ECC bytes
+ * @errloc: Array of errors located with soft BCH
+ * @hw_ecc: Buffer to store syndromes computed by hardware
+ * @bch: BCH structure
+ */
+struct anand {
+ struct list_head node;
+ struct nand_chip chip;
+ unsigned int cs;
+ unsigned int rb;
+ unsigned int page_sz;
+ unsigned long clk;
+ u32 timings;
+ u32 ecc_conf;
+ u32 strength;
+ u16 raddr_cycles;
+ u16 caddr_cycles;
+ unsigned int ecc_bits;
+ unsigned int ecc_total;
+ unsigned int *errloc;
+ u8 *hw_ecc;
+ struct bch_control *bch;
+};
+
+/**
+ * struct arasan_nfc - Defines the Arasan NAND flash controller driver instance
+ * @dev: Pointer to the device structure
+ * @base: Remapped register area
+ * @controller_clk: Pointer to the system clock
+ * @bus_clk: Pointer to the flash clock
+ * @controller: Base controller structure
+ * @chips: List of all NAND chips attached to the controller
+ * @assigned_cs: Bitmask describing already assigned CS lines
+ * @cur_clk: Current clock rate
+ */
+struct arasan_nfc {
+ struct device *dev;
+ void __iomem *base;
+ struct clk *controller_clk;
+ struct clk *bus_clk;
+ struct nand_controller controller;
+ struct list_head chips;
+ unsigned long assigned_cs;
+ unsigned int cur_clk;
+};
+
+static struct anand *to_anand(struct nand_chip *nand)
+{
+ return container_of(nand, struct anand, chip);
+}
+
+static struct arasan_nfc *to_anfc(struct nand_controller *ctrl)
+{
+ return container_of(ctrl, struct arasan_nfc, controller);
+}
+
+static int anfc_wait_for_event(struct arasan_nfc *nfc, unsigned int event)
+{
+ u32 val;
+ int ret;
+
+ ret = readl_relaxed_poll_timeout(nfc->base + INTR_STS_REG, val,
+ val & event, 0,
+ ANFC_DFLT_TIMEOUT_US);
+ if (ret) {
+ dev_err(nfc->dev, "Timeout waiting for event 0x%x\n", event);
+ return -ETIMEDOUT;
+ }
+
+ writel_relaxed(event, nfc->base + INTR_STS_REG);
+
+ return 0;
+}
+
+static int anfc_wait_for_rb(struct arasan_nfc *nfc, struct nand_chip *chip,
+ unsigned int timeout_ms)
+{
+ struct anand *anand = to_anand(chip);
+ u32 val;
+ int ret;
+
+ /* There is no R/B interrupt, we must poll a register */
+ ret = readl_relaxed_poll_timeout(nfc->base + READY_STS_REG, val,
+ val & BIT(anand->rb),
+ 1, timeout_ms * 1000);
+ if (ret) {
+ dev_err(nfc->dev, "Timeout waiting for R/B 0x%x\n",
+ readl_relaxed(nfc->base + READY_STS_REG));
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static void anfc_trigger_op(struct arasan_nfc *nfc, struct anfc_op *nfc_op)
+{
+ writel_relaxed(nfc_op->pkt_reg, nfc->base + PKT_REG);
+ writel_relaxed(nfc_op->addr1_reg, nfc->base + MEM_ADDR1_REG);
+ writel_relaxed(nfc_op->addr2_reg, nfc->base + MEM_ADDR2_REG);
+ writel_relaxed(nfc_op->cmd_reg, nfc->base + CMD_REG);
+ writel_relaxed(nfc_op->prog_reg, nfc->base + PROG_REG);
+}
+
+static int anfc_pkt_len_config(unsigned int len, unsigned int *steps,
+ unsigned int *pktsize)
+{
+ unsigned int nb, sz;
+
+ for (nb = 1; nb < ANFC_MAX_STEPS; nb *= 2) {
+ sz = len / nb;
+ if (sz <= ANFC_MAX_PKT_SIZE)
+ break;
+ }
+
+ if (sz * nb != len)
+ return -ENOTSUPP;
+
+ if (steps)
+ *steps = nb;
+
+ if (pktsize)
+ *pktsize = sz;
+
+ return 0;
+}
+
+/*
+ * When using the embedded hardware ECC engine, the controller is in charge of
+ * feeding the engine with, first, the ECC residue present in the data array.
+ * A typical read operation is:
+ * 1/ Assert the read operation by sending the relevant command/address cycles
+ * but targeting the column of the first ECC bytes in the OOB area instead of
+ * the main data directly.
+ * 2/ After having read the relevant number of ECC bytes, the controller uses
+ * the RNDOUT/RNDSTART commands which are set into the "ECC Spare Command
+ * Register" to move the pointer back at the beginning of the main data.
+ * 3/ It will read the content of the main area for a given size (pktsize) and
+ * will feed the ECC engine with this buffer again.
+ * 4/ The ECC engine derives the ECC bytes for the given data and compare them
+ * with the ones already received. It eventually trigger status flags and
+ * then set the "Buffer Read Ready" flag.
+ * 5/ The corrected data is then available for reading from the data port
+ * register.
+ *
+ * The hardware BCH ECC engine is known to be inconstent in BCH mode and never
+ * reports uncorrectable errors. Because of this bug, we have to use the
+ * software BCH implementation in the read path.
+ */
+static int anfc_read_page_hw_ecc(struct nand_chip *chip, u8 *buf,
+ int oob_required, int page)
+{
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ struct anand *anand = to_anand(chip);
+ unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
+ unsigned int max_bitflips = 0;
+ dma_addr_t dma_addr;
+ int step, ret;
+ struct anfc_op nfc_op = {
+ .pkt_reg =
+ PKT_SIZE(chip->ecc.size) |
+ PKT_STEPS(chip->ecc.steps),
+ .addr1_reg =
+ (page & 0xFF) << (8 * (anand->caddr_cycles)) |
+ (((page >> 8) & 0xFF) << (8 * (1 + anand->caddr_cycles))),
+ .addr2_reg =
+ ((page >> 16) & 0xFF) |
+ ADDR2_STRENGTH(anand->strength) |
+ ADDR2_CS(anand->cs),
+ .cmd_reg =
+ CMD_1(NAND_CMD_READ0) |
+ CMD_2(NAND_CMD_READSTART) |
+ CMD_PAGE_SIZE(anand->page_sz) |
+ CMD_DMA_ENABLE |
+ CMD_NADDRS(anand->caddr_cycles +
+ anand->raddr_cycles),
+ .prog_reg = PROG_PGRD,
+ };
+
+ dma_addr = dma_map_single(nfc->dev, (void *)buf, len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(nfc->dev, dma_addr)) {
+ dev_err(nfc->dev, "Buffer mapping error");
+ return -EIO;
+ }
+
+ writel_relaxed(lower_32_bits(dma_addr), nfc->base + DMA_ADDR0_REG);
+ writel_relaxed(upper_32_bits(dma_addr), nfc->base + DMA_ADDR1_REG);
+
+ anfc_trigger_op(nfc, &nfc_op);
+
+ ret = anfc_wait_for_event(nfc, XFER_COMPLETE);
+ dma_unmap_single(nfc->dev, dma_addr, len, DMA_FROM_DEVICE);
+ if (ret) {
+ dev_err(nfc->dev, "Error reading page %d\n", page);
+ return ret;
+ }
+
+ /* Store the raw OOB bytes as well */
+ ret = nand_change_read_column_op(chip, mtd->writesize, chip->oob_poi,
+ mtd->oobsize, 0);
+ if (ret)
+ return ret;
+
+ /*
+ * For each step, compute by softare the BCH syndrome over the raw data.
+ * Compare the theoretical amount of errors and compare with the
+ * hardware engine feedback.
+ */
+ for (step = 0; step < chip->ecc.steps; step++) {
+ u8 *raw_buf = &buf[step * chip->ecc.size];
+ unsigned int bit, byte;
+ int bf, i;
+
+ /* Extract the syndrome, it is not necessarily aligned */
+ memset(anand->hw_ecc, 0, chip->ecc.bytes);
+ nand_extract_bits(anand->hw_ecc, 0,
+ &chip->oob_poi[mtd->oobsize - anand->ecc_total],
+ anand->ecc_bits * step, anand->ecc_bits);
+
+ bf = bch_decode(anand->bch, raw_buf, chip->ecc.size,
+ anand->hw_ecc, NULL, NULL, anand->errloc);
+ if (!bf) {
+ continue;
+ } else if (bf > 0) {
+ for (i = 0; i < bf; i++) {
+ /* Only correct the data, not the syndrome */
+ if (anand->errloc[i] < (chip->ecc.size * 8)) {
+ bit = BIT(anand->errloc[i] & 7);
+ byte = anand->errloc[i] >> 3;
+ raw_buf[byte] ^= bit;
+ }
+ }
+
+ mtd->ecc_stats.corrected += bf;
+ max_bitflips = max_t(unsigned int, max_bitflips, bf);
+
+ continue;
+ }
+
+ bf = nand_check_erased_ecc_chunk(raw_buf, chip->ecc.size,
+ NULL, 0, NULL, 0,
+ chip->ecc.strength);
+ if (bf > 0) {
+ mtd->ecc_stats.corrected += bf;
+ max_bitflips = max_t(unsigned int, max_bitflips, bf);
+ memset(raw_buf, 0xFF, chip->ecc.size);
+ } else if (bf < 0) {
+ mtd->ecc_stats.failed++;
+ }
+ }
+
+ return 0;
+}
+
+static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
+ int oob_required, int page)
+{
+ struct anand *anand = to_anand(chip);
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
+ dma_addr_t dma_addr;
+ int ret;
+ struct anfc_op nfc_op = {
+ .pkt_reg =
+ PKT_SIZE(chip->ecc.size) |
+ PKT_STEPS(chip->ecc.steps),
+ .addr1_reg =
+ (page & 0xFF) << (8 * (anand->caddr_cycles)) |
+ (((page >> 8) & 0xFF) << (8 * (1 + anand->caddr_cycles))),
+ .addr2_reg =
+ ((page >> 16) & 0xFF) |
+ ADDR2_STRENGTH(anand->strength) |
+ ADDR2_CS(anand->cs),
+ .cmd_reg =
+ CMD_1(NAND_CMD_SEQIN) |
+ CMD_2(NAND_CMD_PAGEPROG) |
+ CMD_PAGE_SIZE(anand->page_sz) |
+ CMD_DMA_ENABLE |
+ CMD_NADDRS(anand->caddr_cycles +
+ anand->raddr_cycles) |
+ CMD_ECC_ENABLE,
+ .prog_reg = PROG_PGPROG,
+ };
+
+ writel_relaxed(anand->ecc_conf, nfc->base + ECC_CONF_REG);
+ writel_relaxed(ECC_SP_CMD1(NAND_CMD_RNDIN) |
+ ECC_SP_ADDRS(anand->caddr_cycles),
+ nfc->base + ECC_SP_REG);
+
+ dma_addr = dma_map_single(nfc->dev, (void *)buf, len, DMA_TO_DEVICE);
+ if (dma_mapping_error(nfc->dev, dma_addr)) {
+ dev_err(nfc->dev, "Buffer mapping error");
+ return -EIO;
+ }
+
+ writel_relaxed(lower_32_bits(dma_addr), nfc->base + DMA_ADDR0_REG);
+ writel_relaxed(upper_32_bits(dma_addr), nfc->base + DMA_ADDR1_REG);
+
+ anfc_trigger_op(nfc, &nfc_op);
+ ret = anfc_wait_for_event(nfc, XFER_COMPLETE);
+ dma_unmap_single(nfc->dev, dma_addr, len, DMA_TO_DEVICE);
+ if (ret) {
+ dev_err(nfc->dev, "Error writing page %d\n", page);
+ return ret;
+ }
+
+ /* Spare data is not protected */
+ if (oob_required)
+ ret = nand_write_oob_std(chip, page);
+
+ return ret;
+}
+
+/* NAND framework ->exec_op() hooks and related helpers */
+static int anfc_parse_instructions(struct nand_chip *chip,
+ const struct nand_subop *subop,
+ struct anfc_op *nfc_op)
+{
+ struct anand *anand = to_anand(chip);
+ const struct nand_op_instr *instr = NULL;
+ bool first_cmd = true;
+ unsigned int op_id;
+ int ret, i;
+
+ memset(nfc_op, 0, sizeof(*nfc_op));
+ nfc_op->addr2_reg = ADDR2_CS(anand->cs);
+ nfc_op->cmd_reg = CMD_PAGE_SIZE(anand->page_sz);
+
+ for (op_id = 0; op_id < subop->ninstrs; op_id++) {
+ unsigned int offset, naddrs, pktsize;
+ const u8 *addrs;
+ u8 *buf;
+
+ instr = &subop->instrs[op_id];
+
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ if (first_cmd)
+ nfc_op->cmd_reg |= CMD_1(instr->ctx.cmd.opcode);
+ else
+ nfc_op->cmd_reg |= CMD_2(instr->ctx.cmd.opcode);
+
+ first_cmd = false;
+ break;
+
+ case NAND_OP_ADDR_INSTR:
+ offset = nand_subop_get_addr_start_off(subop, op_id);
+ naddrs = nand_subop_get_num_addr_cyc(subop, op_id);
+ addrs = &instr->ctx.addr.addrs[offset];
+ nfc_op->cmd_reg |= CMD_NADDRS(naddrs);
+
+ for (i = 0; i < min(ANFC_MAX_ADDR_CYC, naddrs); i++) {
+ if (i < 4)
+ nfc_op->addr1_reg |= (u32)addrs[i] << i * 8;
+ else
+ nfc_op->addr2_reg |= addrs[i];
+ }
+
+ break;
+ case NAND_OP_DATA_IN_INSTR:
+ nfc_op->read = true;
+ fallthrough;
+ case NAND_OP_DATA_OUT_INSTR:
+ offset = nand_subop_get_data_start_off(subop, op_id);
+ buf = instr->ctx.data.buf.in;
+ nfc_op->buf = &buf[offset];
+ nfc_op->len = nand_subop_get_data_len(subop, op_id);
+ ret = anfc_pkt_len_config(nfc_op->len, &nfc_op->steps,
+ &pktsize);
+ if (ret)
+ return ret;
+
+ /*
+ * Number of DATA cycles must be aligned on 4, this
+ * means the controller might read/write more than
+ * requested. This is harmless most of the time as extra
+ * DATA are discarded in the write path and read pointer
+ * adjusted in the read path.
+ *
+ * FIXME: The core should mark operations where
+ * reading/writing more is allowed so the exec_op()
+ * implementation can take the right decision when the
+ * alignment constraint is not met: adjust the number of
+ * DATA cycles when it's allowed, reject the operation
+ * otherwise.
+ */
+ nfc_op->pkt_reg |= PKT_SIZE(round_up(pktsize, 4)) |
+ PKT_STEPS(nfc_op->steps);
+ break;
+ case NAND_OP_WAITRDY_INSTR:
+ nfc_op->rdy_timeout_ms = instr->ctx.waitrdy.timeout_ms;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int anfc_rw_pio_op(struct arasan_nfc *nfc, struct anfc_op *nfc_op)
+{
+ unsigned int dwords = (nfc_op->len / 4) / nfc_op->steps;
+ unsigned int last_len = nfc_op->len % 4;
+ unsigned int offset, dir;
+ u8 *buf = nfc_op->buf;
+ int ret, i;
+
+ for (i = 0; i < nfc_op->steps; i++) {
+ dir = nfc_op->read ? READ_READY : WRITE_READY;
+ ret = anfc_wait_for_event(nfc, dir);
+ if (ret) {
+ dev_err(nfc->dev, "PIO %s ready signal not received\n",
+ nfc_op->read ? "Read" : "Write");
+ return ret;
+ }
+
+ offset = i * (dwords * 4);
+ if (nfc_op->read)
+ ioread32_rep(nfc->base + DATA_PORT_REG, &buf[offset],
+ dwords);
+ else
+ iowrite32_rep(nfc->base + DATA_PORT_REG, &buf[offset],
+ dwords);
+ }
+
+ if (last_len) {
+ u32 remainder;
+
+ offset = nfc_op->len - last_len;
+
+ if (nfc_op->read) {
+ remainder = readl_relaxed(nfc->base + DATA_PORT_REG);
+ memcpy(&buf[offset], &remainder, last_len);
+ } else {
+ memcpy(&remainder, &buf[offset], last_len);
+ writel_relaxed(remainder, nfc->base + DATA_PORT_REG);
+ }
+ }
+
+ return anfc_wait_for_event(nfc, XFER_COMPLETE);
+}
+
+static int anfc_misc_data_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop,
+ u32 prog_reg)
+{
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct anfc_op nfc_op = {};
+ int ret;
+
+ ret = anfc_parse_instructions(chip, subop, &nfc_op);
+ if (ret)
+ return ret;
+
+ nfc_op.prog_reg = prog_reg;
+ anfc_trigger_op(nfc, &nfc_op);
+
+ if (nfc_op.rdy_timeout_ms) {
+ ret = anfc_wait_for_rb(nfc, chip, nfc_op.rdy_timeout_ms);
+ if (ret)
+ return ret;
+ }
+
+ return anfc_rw_pio_op(nfc, &nfc_op);
+}
+
+static int anfc_param_read_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ return anfc_misc_data_type_exec(chip, subop, PROG_RDPARAM);
+}
+
+static int anfc_data_read_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ return anfc_misc_data_type_exec(chip, subop, PROG_PGRD);
+}
+
+static int anfc_param_write_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ return anfc_misc_data_type_exec(chip, subop, PROG_SET_FEATURE);
+}
+
+static int anfc_data_write_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ return anfc_misc_data_type_exec(chip, subop, PROG_PGPROG);
+}
+
+static int anfc_misc_zerolen_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop,
+ u32 prog_reg)
+{
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct anfc_op nfc_op = {};
+ int ret;
+
+ ret = anfc_parse_instructions(chip, subop, &nfc_op);
+ if (ret)
+ return ret;
+
+ nfc_op.prog_reg = prog_reg;
+ anfc_trigger_op(nfc, &nfc_op);
+
+ ret = anfc_wait_for_event(nfc, XFER_COMPLETE);
+ if (ret)
+ return ret;
+
+ if (nfc_op.rdy_timeout_ms)
+ ret = anfc_wait_for_rb(nfc, chip, nfc_op.rdy_timeout_ms);
+
+ return ret;
+}
+
+static int anfc_status_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ u32 tmp;
+ int ret;
+
+ /* See anfc_check_op() for details about this constraint */
+ if (subop->instrs[0].ctx.cmd.opcode != NAND_CMD_STATUS)
+ return -ENOTSUPP;
+
+ ret = anfc_misc_zerolen_type_exec(chip, subop, PROG_STATUS);
+ if (ret)
+ return ret;
+
+ tmp = readl_relaxed(nfc->base + FLASH_STS_REG);
+ memcpy(subop->instrs[1].ctx.data.buf.in, &tmp, 1);
+
+ return 0;
+}
+
+static int anfc_reset_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ return anfc_misc_zerolen_type_exec(chip, subop, PROG_RST);
+}
+
+static int anfc_erase_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ return anfc_misc_zerolen_type_exec(chip, subop, PROG_ERASE);
+}
+
+static int anfc_wait_type_exec(struct nand_chip *chip,
+ const struct nand_subop *subop)
+{
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct anfc_op nfc_op = {};
+ int ret;
+
+ ret = anfc_parse_instructions(chip, subop, &nfc_op);
+ if (ret)
+ return ret;
+
+ return anfc_wait_for_rb(nfc, chip, nfc_op.rdy_timeout_ms);
+}
+
+static const struct nand_op_parser anfc_op_parser = NAND_OP_PARSER(
+ NAND_OP_PARSER_PATTERN(
+ anfc_param_read_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_ADDR_ELEM(false, ANFC_MAX_ADDR_CYC),
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
+ NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, ANFC_MAX_CHUNK_SIZE)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_param_write_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_ADDR_ELEM(false, ANFC_MAX_ADDR_CYC),
+ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, ANFC_MAX_PARAM_SIZE)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_data_read_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_ADDR_ELEM(false, ANFC_MAX_ADDR_CYC),
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
+ NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, ANFC_MAX_CHUNK_SIZE)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_data_write_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_ADDR_ELEM(false, ANFC_MAX_ADDR_CYC),
+ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, ANFC_MAX_CHUNK_SIZE),
+ NAND_OP_PARSER_PAT_CMD_ELEM(false)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_reset_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_erase_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_ADDR_ELEM(false, ANFC_MAX_ADDR_CYC),
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_status_type_exec,
+ NAND_OP_PARSER_PAT_CMD_ELEM(false),
+ NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, ANFC_MAX_CHUNK_SIZE)),
+ NAND_OP_PARSER_PATTERN(
+ anfc_wait_type_exec,
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+ );
+
+static int anfc_select_target(struct nand_chip *chip, int target)
+{
+ struct anand *anand = to_anand(chip);
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ int ret;
+
+ /* Update the controller timings and the potential ECC configuration */
+ writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG);
+
+ /* Update clock frequency */
+ if (nfc->cur_clk != anand->clk) {
+ clk_disable_unprepare(nfc->controller_clk);
+ ret = clk_set_rate(nfc->controller_clk, anand->clk);
+ if (ret) {
+ dev_err(nfc->dev, "Failed to change clock rate\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(nfc->controller_clk);
+ if (ret) {
+ dev_err(nfc->dev,
+ "Failed to re-enable the controller clock\n");
+ return ret;
+ }
+
+ nfc->cur_clk = anand->clk;
+ }
+
+ return 0;
+}
+
+static int anfc_check_op(struct nand_chip *chip,
+ const struct nand_operation *op)
+{
+ const struct nand_op_instr *instr;
+ int op_id;
+
+ /*
+ * The controller abstracts all the NAND operations and do not support
+ * data only operations.
+ *
+ * TODO: The nand_op_parser framework should be extended to
+ * support custom checks on DATA instructions.
+ */
+ for (op_id = 0; op_id < op->ninstrs; op_id++) {
+ instr = &op->instrs[op_id];
+
+ switch (instr->type) {
+ case NAND_OP_ADDR_INSTR:
+ if (instr->ctx.addr.naddrs > ANFC_MAX_ADDR_CYC)
+ return -ENOTSUPP;
+
+ break;
+ case NAND_OP_DATA_IN_INSTR:
+ case NAND_OP_DATA_OUT_INSTR:
+ if (instr->ctx.data.len > ANFC_MAX_CHUNK_SIZE)
+ return -ENOTSUPP;
+
+ if (anfc_pkt_len_config(instr->ctx.data.len, 0, 0))
+ return -ENOTSUPP;
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * The controller does not allow to proceed with a CMD+DATA_IN cycle
+ * manually on the bus by reading data from the data register. Instead,
+ * the controller abstract a status read operation with its own status
+ * register after ordering a read status operation. Hence, we cannot
+ * support any CMD+DATA_IN operation other than a READ STATUS.
+ *
+ * TODO: The nand_op_parser() framework should be extended to describe
+ * fixed patterns instead of open-coding this check here.
+ */
+ if (op->ninstrs == 2 &&
+ op->instrs[0].type == NAND_OP_CMD_INSTR &&
+ op->instrs[0].ctx.cmd.opcode != NAND_CMD_STATUS &&
+ op->instrs[1].type == NAND_OP_DATA_IN_INSTR)
+ return -ENOTSUPP;
+
+ return nand_op_parser_exec_op(chip, &anfc_op_parser, op, true);
+}
+
+static int anfc_exec_op(struct nand_chip *chip,
+ const struct nand_operation *op,
+ bool check_only)
+{
+ int ret;
+
+ if (check_only)
+ return anfc_check_op(chip, op);
+
+ ret = anfc_select_target(chip, op->cs);
+ if (ret)
+ return ret;
+
+ return nand_op_parser_exec_op(chip, &anfc_op_parser, op, check_only);
+}
+
+static int anfc_setup_data_interface(struct nand_chip *chip, int target,
+ const struct nand_data_interface *conf)
+{
+ struct anand *anand = to_anand(chip);
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct device_node *np = nfc->dev->of_node;
+
+ if (target < 0)
+ return 0;
+
+ anand->timings = DIFACE_SDR | DIFACE_SDR_MODE(conf->timings.mode);
+ anand->clk = ANFC_XLNX_SDR_DFLT_CORE_CLK;
+
+ /*
+ * Due to a hardware bug in the ZynqMP SoC, SDR timing modes 0-1 work
+ * with f > 90MHz (default clock is 100MHz) but signals are unstable
+ * with higher modes. Hence we decrease a little bit the clock rate to
+ * 80MHz when using modes 2-5 with this SoC.
+ */
+ if (of_device_is_compatible(np, "xlnx,zynqmp-nand-controller") &&
+ conf->timings.mode >= 2)
+ anand->clk = ANFC_XLNX_SDR_HS_CORE_CLK;
+
+ return 0;
+}
+
+static int anfc_calc_hw_ecc_bytes(int step_size, int strength)
+{
+ unsigned int bch_gf_mag, ecc_bits;
+
+ switch (step_size) {
+ case SZ_512:
+ bch_gf_mag = 13;
+ break;
+ case SZ_1K:
+ bch_gf_mag = 14;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ecc_bits = bch_gf_mag * strength;
+
+ return DIV_ROUND_UP(ecc_bits, 8);
+}
+
+static const int anfc_hw_ecc_512_strengths[] = {4, 8, 12};
+
+static const int anfc_hw_ecc_1024_strengths[] = {24};
+
+static const struct nand_ecc_step_info anfc_hw_ecc_step_infos[] = {
+ {
+ .stepsize = SZ_512,
+ .strengths = anfc_hw_ecc_512_strengths,
+ .nstrengths = ARRAY_SIZE(anfc_hw_ecc_512_strengths),
+ },
+ {
+ .stepsize = SZ_1K,
+ .strengths = anfc_hw_ecc_1024_strengths,
+ .nstrengths = ARRAY_SIZE(anfc_hw_ecc_1024_strengths),
+ },
+};
+
+static const struct nand_ecc_caps anfc_hw_ecc_caps = {
+ .stepinfos = anfc_hw_ecc_step_infos,
+ .nstepinfos = ARRAY_SIZE(anfc_hw_ecc_step_infos),
+ .calc_ecc_bytes = anfc_calc_hw_ecc_bytes,
+};
+
+static int anfc_init_hw_ecc_controller(struct arasan_nfc *nfc,
+ struct nand_chip *chip)
+{
+ struct anand *anand = to_anand(chip);
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ unsigned int bch_prim_poly = 0, bch_gf_mag = 0, ecc_offset;
+ int ret;
+
+ switch (mtd->writesize) {
+ case SZ_512:
+ case SZ_2K:
+ case SZ_4K:
+ case SZ_8K:
+ case SZ_16K:
+ break;
+ default:
+ dev_err(nfc->dev, "Unsupported page size %d\n", mtd->writesize);
+ return -EINVAL;
+ }
+
+ ret = nand_ecc_choose_conf(chip, &anfc_hw_ecc_caps, mtd->oobsize);
+ if (ret)
+ return ret;
+
+ switch (ecc->strength) {
+ case 12:
+ anand->strength = 0x1;
+ break;
+ case 8:
+ anand->strength = 0x2;
+ break;
+ case 4:
+ anand->strength = 0x3;
+ break;
+ case 24:
+ anand->strength = 0x4;
+ break;
+ default:
+ dev_err(nfc->dev, "Unsupported strength %d\n", ecc->strength);
+ return -EINVAL;
+ }
+
+ switch (ecc->size) {
+ case SZ_512:
+ bch_gf_mag = 13;
+ bch_prim_poly = 0x201b;
+ break;
+ case SZ_1K:
+ bch_gf_mag = 14;
+ bch_prim_poly = 0x4443;
+ break;
+ default:
+ dev_err(nfc->dev, "Unsupported step size %d\n", ecc->strength);
+ return -EINVAL;
+ }
+
+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
+
+ ecc->steps = mtd->writesize / ecc->size;
+ ecc->algo = NAND_ECC_BCH;
+ anand->ecc_bits = bch_gf_mag * ecc->strength;
+ ecc->bytes = DIV_ROUND_UP(anand->ecc_bits, 8);
+ anand->ecc_total = DIV_ROUND_UP(anand->ecc_bits * ecc->steps, 8);
+ ecc_offset = mtd->writesize + mtd->oobsize - anand->ecc_total;
+ anand->ecc_conf = ECC_CONF_COL(ecc_offset) |
+ ECC_CONF_LEN(anand->ecc_total) |
+ ECC_CONF_BCH_EN;
+
+ anand->errloc = devm_kmalloc_array(nfc->dev, ecc->strength,
+ sizeof(*anand->errloc), GFP_KERNEL);
+ if (!anand->errloc)
+ return -ENOMEM;
+
+ anand->hw_ecc = devm_kmalloc(nfc->dev, ecc->bytes, GFP_KERNEL);
+ if (!anand->hw_ecc)
+ return -ENOMEM;
+
+ /* Enforce bit swapping to fit the hardware */
+ anand->bch = bch_init(bch_gf_mag, ecc->strength, bch_prim_poly, true);
+ if (!anand->bch)
+ return -EINVAL;
+
+ ecc->read_page = anfc_read_page_hw_ecc;
+ ecc->write_page = anfc_write_page_hw_ecc;
+
+ return 0;
+}
+
+static int anfc_attach_chip(struct nand_chip *chip)
+{
+ struct anand *anand = to_anand(chip);
+ struct arasan_nfc *nfc = to_anfc(chip->controller);
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ int ret = 0;
+
+ if (mtd->writesize <= SZ_512)
+ anand->caddr_cycles = 1;
+ else
+ anand->caddr_cycles = 2;
+
+ if (chip->options & NAND_ROW_ADDR_3)
+ anand->raddr_cycles = 3;
+ else
+ anand->raddr_cycles = 2;
+
+ switch (mtd->writesize) {
+ case 512:
+ anand->page_sz = 0;
+ break;
+ case 1024:
+ anand->page_sz = 5;
+ break;
+ case 2048:
+ anand->page_sz = 1;
+ break;
+ case 4096:
+ anand->page_sz = 2;
+ break;
+ case 8192:
+ anand->page_sz = 3;
+ break;
+ case 16384:
+ anand->page_sz = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* These hooks are valid for all ECC providers */
+ chip->ecc.read_page_raw = nand_monolithic_read_page_raw;
+ chip->ecc.write_page_raw = nand_monolithic_write_page_raw;
+
+ switch (chip->ecc.mode) {
+ case NAND_ECC_NONE:
+ case NAND_ECC_SOFT:
+ case NAND_ECC_ON_DIE:
+ break;
+ case NAND_ECC_HW:
+ ret = anfc_init_hw_ecc_controller(nfc, chip);
+ break;
+ default:
+ dev_err(nfc->dev, "Unsupported ECC mode: %d\n",
+ chip->ecc.mode);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static void anfc_detach_chip(struct nand_chip *chip)
+{
+ struct anand *anand = to_anand(chip);
+
+ if (anand->bch)
+ bch_free(anand->bch);
+}
+
+static const struct nand_controller_ops anfc_ops = {
+ .exec_op = anfc_exec_op,
+ .setup_data_interface = anfc_setup_data_interface,
+ .attach_chip = anfc_attach_chip,
+ .detach_chip = anfc_detach_chip,
+};
+
+static int anfc_chip_init(struct arasan_nfc *nfc, struct device_node *np)
+{
+ struct anand *anand;
+ struct nand_chip *chip;
+ struct mtd_info *mtd;
+ int cs, rb, ret;
+
+ anand = devm_kzalloc(nfc->dev, sizeof(*anand), GFP_KERNEL);
+ if (!anand)
+ return -ENOMEM;
+
+ /* We do not support multiple CS per chip yet */
+ if (of_property_count_elems_of_size(np, "reg", sizeof(u32)) != 1) {
+ dev_err(nfc->dev, "Invalid reg property\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(np, "reg", &cs);
+ if (ret)
+ return ret;
+
+ ret = of_property_read_u32(np, "nand-rb", &rb);
+ if (ret)
+ return ret;
+
+ if (cs >= ANFC_MAX_CS || rb >= ANFC_MAX_CS) {
+ dev_err(nfc->dev, "Wrong CS %d or RB %d\n", cs, rb);
+ return -EINVAL;
+ }
+
+ if (test_and_set_bit(cs, &nfc->assigned_cs)) {
+ dev_err(nfc->dev, "Already assigned CS %d\n", cs);
+ return -EINVAL;
+ }
+
+ anand->cs = cs;
+ anand->rb = rb;
+
+ chip = &anand->chip;
+ mtd = nand_to_mtd(chip);
+ mtd->dev.parent = nfc->dev;
+ chip->controller = &nfc->controller;
+ chip->options = NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
+ NAND_USES_DMA;
+
+ nand_set_flash_node(chip, np);
+ if (!mtd->name) {
+ dev_err(nfc->dev, "NAND label property is mandatory\n");
+ return -EINVAL;
+ }
+
+ ret = nand_scan(chip, 1);
+ if (ret) {
+ dev_err(nfc->dev, "Scan operation failed\n");
+ return ret;
+ }
+
+ ret = mtd_device_register(mtd, NULL, 0);
+ if (ret) {
+ nand_cleanup(chip);
+ return ret;
+ }
+
+ list_add_tail(&anand->node, &nfc->chips);
+
+ return 0;
+}
+
+static void anfc_chips_cleanup(struct arasan_nfc *nfc)
+{
+ struct anand *anand, *tmp;
+ struct nand_chip *chip;
+ int ret;
+
+ list_for_each_entry_safe(anand, tmp, &nfc->chips, node) {
+ chip = &anand->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ list_del(&anand->node);
+ }
+}
+
+static int anfc_chips_init(struct arasan_nfc *nfc)
+{
+ struct device_node *np = nfc->dev->of_node, *nand_np;
+ int nchips = of_get_child_count(np);
+ int ret;
+
+ if (!nchips || nchips > ANFC_MAX_CS) {
+ dev_err(nfc->dev, "Incorrect number of NAND chips (%d)\n",
+ nchips);
+ return -EINVAL;
+ }
+
+ for_each_child_of_node(np, nand_np) {
+ ret = anfc_chip_init(nfc, nand_np);
+ if (ret) {
+ of_node_put(nand_np);
+ anfc_chips_cleanup(nfc);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static void anfc_reset(struct arasan_nfc *nfc)
+{
+ /* Disable interrupt signals */
+ writel_relaxed(0, nfc->base + INTR_SIG_EN_REG);
+
+ /* Enable interrupt status */
+ writel_relaxed(EVENT_MASK, nfc->base + INTR_STS_EN_REG);
+}
+
+static int anfc_probe(struct platform_device *pdev)
+{
+ struct arasan_nfc *nfc;
+ int ret;
+
+ nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL);
+ if (!nfc)
+ return -ENOMEM;
+
+ nfc->dev = &pdev->dev;
+ nand_controller_init(&nfc->controller);
+ nfc->controller.ops = &anfc_ops;
+ INIT_LIST_HEAD(&nfc->chips);
+
+ nfc->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(nfc->base))
+ return PTR_ERR(nfc->base);
+
+ anfc_reset(nfc);
+
+ nfc->controller_clk = devm_clk_get(&pdev->dev, "controller");
+ if (IS_ERR(nfc->controller_clk))
+ return PTR_ERR(nfc->controller_clk);
+
+ nfc->bus_clk = devm_clk_get(&pdev->dev, "bus");
+ if (IS_ERR(nfc->bus_clk))
+ return PTR_ERR(nfc->bus_clk);
+
+ ret = clk_prepare_enable(nfc->controller_clk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(nfc->bus_clk);
+ if (ret)
+ goto disable_controller_clk;
+
+ ret = anfc_chips_init(nfc);
+ if (ret)
+ goto disable_bus_clk;
+
+ platform_set_drvdata(pdev, nfc);
+
+ return 0;
+
+disable_bus_clk:
+ clk_disable_unprepare(nfc->bus_clk);
+
+disable_controller_clk:
+ clk_disable_unprepare(nfc->controller_clk);
+
+ return ret;
+}
+
+static int anfc_remove(struct platform_device *pdev)
+{
+ struct arasan_nfc *nfc = platform_get_drvdata(pdev);
+
+ anfc_chips_cleanup(nfc);
+
+ clk_disable_unprepare(nfc->bus_clk);
+ clk_disable_unprepare(nfc->controller_clk);
+
+ return 0;
+}
+
+static const struct of_device_id anfc_ids[] = {
+ {
+ .compatible = "xlnx,zynqmp-nand-controller",
+ },
+ {
+ .compatible = "arasan,nfc-v3p10",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, anfc_ids);
+
+static struct platform_driver anfc_driver = {
+ .driver = {
+ .name = "arasan-nand-controller",
+ .of_match_table = anfc_ids,
+ },
+ .probe = anfc_probe,
+ .remove = anfc_remove,
+};
+module_platform_driver(anfc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Punnaiah Choudary Kalluri <punnaia@xilinx.com>");
+MODULE_AUTHOR("Naga Sureshkumar Relli <nagasure@xilinx.com>");
+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
+MODULE_DESCRIPTION("Arasan NAND Flash Controller Driver");
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 3ba17a98df4d..46a3724a788e 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1494,7 +1494,7 @@ static void atmel_nand_init(struct atmel_nand_controller *nc,
* suitable for DMA.
*/
if (nc->dmac)
- chip->options |= NAND_USE_BOUNCE_BUFFER;
+ chip->options |= NAND_USES_DMA;
/* Default to HW ECC if pmecc is available. */
if (nc->pmecc)
diff --git a/drivers/mtd/nand/raw/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c
index 75eb3e97fae3..d865200ccd08 100644
--- a/drivers/mtd/nand/raw/au1550nd.c
+++ b/drivers/mtd/nand/raw/au1550nd.c
@@ -16,63 +16,16 @@
struct au1550nd_ctx {
+ struct nand_controller controller;
struct nand_chip chip;
int cs;
void __iomem *base;
- void (*write_byte)(struct nand_chip *, u_char);
};
-/**
- * au_read_byte - read one byte from the chip
- * @this: NAND chip object
- *
- * read function for 8bit buswidth
- */
-static u_char au_read_byte(struct nand_chip *this)
-{
- u_char ret = readb(this->legacy.IO_ADDR_R);
- wmb(); /* drain writebuffer */
- return ret;
-}
-
-/**
- * au_write_byte - write one byte to the chip
- * @this: NAND chip object
- * @byte: pointer to data byte to write
- *
- * write function for 8it buswidth
- */
-static void au_write_byte(struct nand_chip *this, u_char byte)
-{
- writeb(byte, this->legacy.IO_ADDR_W);
- wmb(); /* drain writebuffer */
-}
-
-/**
- * au_read_byte16 - read one byte endianness aware from the chip
- * @this: NAND chip object
- *
- * read function for 16bit buswidth with endianness conversion
- */
-static u_char au_read_byte16(struct nand_chip *this)
-{
- u_char ret = (u_char) cpu_to_le16(readw(this->legacy.IO_ADDR_R));
- wmb(); /* drain writebuffer */
- return ret;
-}
-
-/**
- * au_write_byte16 - write one byte endianness aware to the chip
- * @this: NAND chip object
- * @byte: pointer to data byte to write
- *
- * write function for 16bit buswidth with endianness conversion
- */
-static void au_write_byte16(struct nand_chip *this, u_char byte)
+static struct au1550nd_ctx *chip_to_au_ctx(struct nand_chip *this)
{
- writew(le16_to_cpu((u16) byte), this->legacy.IO_ADDR_W);
- wmb(); /* drain writebuffer */
+ return container_of(this, struct au1550nd_ctx, chip);
}
/**
@@ -83,12 +36,15 @@ static void au_write_byte16(struct nand_chip *this, u_char byte)
*
* write function for 8bit buswidth
*/
-static void au_write_buf(struct nand_chip *this, const u_char *buf, int len)
+static void au_write_buf(struct nand_chip *this, const void *buf,
+ unsigned int len)
{
+ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
+ const u8 *p = buf;
int i;
for (i = 0; i < len; i++) {
- writeb(buf[i], this->legacy.IO_ADDR_W);
+ writeb(p[i], ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
@@ -101,12 +57,15 @@ static void au_write_buf(struct nand_chip *this, const u_char *buf, int len)
*
* read function for 8bit buswidth
*/
-static void au_read_buf(struct nand_chip *this, u_char *buf, int len)
+static void au_read_buf(struct nand_chip *this, void *buf,
+ unsigned int len)
{
+ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
+ u8 *p = buf;
int i;
for (i = 0; i < len; i++) {
- buf[i] = readb(this->legacy.IO_ADDR_R);
+ p[i] = readb(ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
@@ -119,17 +78,18 @@ static void au_read_buf(struct nand_chip *this, u_char *buf, int len)
*
* write function for 16bit buswidth
*/
-static void au_write_buf16(struct nand_chip *this, const u_char *buf, int len)
+static void au_write_buf16(struct nand_chip *this, const void *buf,
+ unsigned int len)
{
- int i;
- u16 *p = (u16 *) buf;
- len >>= 1;
+ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
+ const u16 *p = buf;
+ unsigned int i;
+ len >>= 1;
for (i = 0; i < len; i++) {
- writew(p[i], this->legacy.IO_ADDR_W);
+ writew(p[i], ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
-
}
/**
@@ -140,239 +100,146 @@ static void au_write_buf16(struct nand_chip *this, const u_char *buf, int len)
*
* read function for 16bit buswidth
*/
-static void au_read_buf16(struct nand_chip *this, u_char *buf, int len)
+static void au_read_buf16(struct nand_chip *this, void *buf, unsigned int len)
{
- int i;
- u16 *p = (u16 *) buf;
- len >>= 1;
+ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
+ unsigned int i;
+ u16 *p = buf;
+ len >>= 1;
for (i = 0; i < len; i++) {
- p[i] = readw(this->legacy.IO_ADDR_R);
+ p[i] = readw(ctx->base + MEM_STNAND_DATA);
wmb(); /* drain writebuffer */
}
}
-/* Select the chip by setting nCE to low */
-#define NAND_CTL_SETNCE 1
-/* Deselect the chip by setting nCE to high */
-#define NAND_CTL_CLRNCE 2
-/* Select the command latch by setting CLE to high */
-#define NAND_CTL_SETCLE 3
-/* Deselect the command latch by setting CLE to low */
-#define NAND_CTL_CLRCLE 4
-/* Select the address latch by setting ALE to high */
-#define NAND_CTL_SETALE 5
-/* Deselect the address latch by setting ALE to low */
-#define NAND_CTL_CLRALE 6
-
-static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
+static int find_nand_cs(unsigned long nand_base)
{
- struct nand_chip *this = mtd_to_nand(mtd);
- struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx,
- chip);
+ void __iomem *base =
+ (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR);
+ unsigned long addr, staddr, start, mask, end;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ addr = 0x1000 + (i * 0x10); /* CSx */
+ staddr = __raw_readl(base + addr + 0x08); /* STADDRx */
+ /* figure out the decoded range of this CS */
+ start = (staddr << 4) & 0xfffc0000;
+ mask = (staddr << 18) & 0xfffc0000;
+ end = (start | (start - 1)) & ~(start ^ mask);
+ if ((nand_base >= start) && (nand_base < end))
+ return i;
+ }
- switch (cmd) {
+ return -ENODEV;
+}
- case NAND_CTL_SETCLE:
- this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_CMD;
- break;
+static int au1550nd_waitrdy(struct nand_chip *this, unsigned int timeout_ms)
+{
+ unsigned long timeout_jiffies = jiffies;
+
+ timeout_jiffies += msecs_to_jiffies(timeout_ms) + 1;
+ do {
+ if (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1)
+ return 0;
- case NAND_CTL_CLRCLE:
- this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_DATA;
+ usleep_range(10, 100);
+ } while (time_before(jiffies, timeout_jiffies));
+
+ return -ETIMEDOUT;
+}
+
+static int au1550nd_exec_instr(struct nand_chip *this,
+ const struct nand_op_instr *instr)
+{
+ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
+ unsigned int i;
+ int ret = 0;
+
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ writeb(instr->ctx.cmd.opcode,
+ ctx->base + MEM_STNAND_CMD);
+ /* Drain the writebuffer */
+ wmb();
break;
- case NAND_CTL_SETALE:
- this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_ADDR;
+ case NAND_OP_ADDR_INSTR:
+ for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+ writeb(instr->ctx.addr.addrs[i],
+ ctx->base + MEM_STNAND_ADDR);
+ /* Drain the writebuffer */
+ wmb();
+ }
break;
- case NAND_CTL_CLRALE:
- this->legacy.IO_ADDR_W = ctx->base + MEM_STNAND_DATA;
- /* FIXME: Nobody knows why this is necessary,
- * but it works only that way */
- udelay(1);
+ case NAND_OP_DATA_IN_INSTR:
+ if ((this->options & NAND_BUSWIDTH_16) &&
+ !instr->ctx.data.force_8bit)
+ au_read_buf16(this, instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ else
+ au_read_buf(this, instr->ctx.data.buf.in,
+ instr->ctx.data.len);
break;
- case NAND_CTL_SETNCE:
- /* assert (force assert) chip enable */
- alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL);
+ case NAND_OP_DATA_OUT_INSTR:
+ if ((this->options & NAND_BUSWIDTH_16) &&
+ !instr->ctx.data.force_8bit)
+ au_write_buf16(this, instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ else
+ au_write_buf(this, instr->ctx.data.buf.out,
+ instr->ctx.data.len);
break;
- case NAND_CTL_CLRNCE:
- /* deassert chip enable */
- alchemy_wrsmem(0, AU1000_MEM_STNDCTL);
+ case NAND_OP_WAITRDY_INSTR:
+ ret = au1550nd_waitrdy(this, instr->ctx.waitrdy.timeout_ms);
break;
+ default:
+ return -EINVAL;
}
- this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W;
-
- wmb(); /* Drain the writebuffer */
-}
-
-int au1550_device_ready(struct nand_chip *this)
-{
- return (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) ? 1 : 0;
-}
+ if (instr->delay_ns)
+ ndelay(instr->delay_ns);
-/**
- * au1550_select_chip - control -CE line
- * Forbid driving -CE manually permitting the NAND controller to do this.
- * Keeping -CE asserted during the whole sector reads interferes with the
- * NOR flash and PCMCIA drivers as it causes contention on the static bus.
- * We only have to hold -CE low for the NAND read commands since the flash
- * chip needs it to be asserted during chip not ready time but the NAND
- * controller keeps it released.
- *
- * @this: NAND chip object
- * @chip: chipnumber to select, -1 for deselect
- */
-static void au1550_select_chip(struct nand_chip *this, int chip)
-{
+ return ret;
}
-/**
- * au1550_command - Send command to NAND device
- * @this: NAND chip object
- * @command: the command to be sent
- * @column: the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
- */
-static void au1550_command(struct nand_chip *this, unsigned command,
- int column, int page_addr)
+static int au1550nd_exec_op(struct nand_chip *this,
+ const struct nand_operation *op,
+ bool check_only)
{
- struct mtd_info *mtd = nand_to_mtd(this);
- struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx,
- chip);
- int ce_override = 0, i;
- unsigned long flags = 0;
-
- /* Begin command latch cycle */
- au1550_hwcontrol(mtd, NAND_CTL_SETCLE);
- /*
- * Write out the command to the device.
- */
- if (command == NAND_CMD_SEQIN) {
- int readcmd;
-
- if (column >= mtd->writesize) {
- /* OOB area */
- column -= mtd->writesize;
- readcmd = NAND_CMD_READOOB;
- } else if (column < 256) {
- /* First 256 bytes --> READ0 */
- readcmd = NAND_CMD_READ0;
- } else {
- column -= 256;
- readcmd = NAND_CMD_READ1;
- }
- ctx->write_byte(this, readcmd);
- }
- ctx->write_byte(this, command);
+ struct au1550nd_ctx *ctx = chip_to_au_ctx(this);
+ unsigned int i;
+ int ret;
- /* Set ALE and clear CLE to start address cycle */
- au1550_hwcontrol(mtd, NAND_CTL_CLRCLE);
+ if (check_only)
+ return 0;
- if (column != -1 || page_addr != -1) {
- au1550_hwcontrol(mtd, NAND_CTL_SETALE);
+ /* assert (force assert) chip enable */
+ alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL);
+ /* Drain the writebuffer */
+ wmb();
- /* Serially input address */
- if (column != -1) {
- /* Adjust columns for 16 bit buswidth */
- if (this->options & NAND_BUSWIDTH_16 &&
- !nand_opcode_8bits(command))
- column >>= 1;
- ctx->write_byte(this, column);
- }
- if (page_addr != -1) {
- ctx->write_byte(this, (u8)(page_addr & 0xff));
-
- if (command == NAND_CMD_READ0 ||
- command == NAND_CMD_READ1 ||
- command == NAND_CMD_READOOB) {
- /*
- * NAND controller will release -CE after
- * the last address byte is written, so we'll
- * have to forcibly assert it. No interrupts
- * are allowed while we do this as we don't
- * want the NOR flash or PCMCIA drivers to
- * steal our precious bytes of data...
- */
- ce_override = 1;
- local_irq_save(flags);
- au1550_hwcontrol(mtd, NAND_CTL_SETNCE);
- }
-
- ctx->write_byte(this, (u8)(page_addr >> 8));
-
- if (this->options & NAND_ROW_ADDR_3)
- ctx->write_byte(this,
- ((page_addr >> 16) & 0x0f));
- }
- /* Latch in address */
- au1550_hwcontrol(mtd, NAND_CTL_CLRALE);
- }
-
- /*
- * Program and erase have their own busy handlers.
- * Status and sequential in need no delay.
- */
- switch (command) {
-
- case NAND_CMD_PAGEPROG:
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- case NAND_CMD_SEQIN:
- case NAND_CMD_STATUS:
- return;
-
- case NAND_CMD_RESET:
- break;
-
- case NAND_CMD_READ0:
- case NAND_CMD_READ1:
- case NAND_CMD_READOOB:
- /* Check if we're really driving -CE low (just in case) */
- if (unlikely(!ce_override))
+ for (i = 0; i < op->ninstrs; i++) {
+ ret = au1550nd_exec_instr(this, &op->instrs[i]);
+ if (ret)
break;
-
- /* Apply a short delay always to ensure that we do wait tWB. */
- ndelay(100);
- /* Wait for a chip to become ready... */
- for (i = this->legacy.chip_delay;
- !this->legacy.dev_ready(this) && i > 0; --i)
- udelay(1);
-
- /* Release -CE and re-enable interrupts. */
- au1550_hwcontrol(mtd, NAND_CTL_CLRNCE);
- local_irq_restore(flags);
- return;
}
- /* Apply this short delay always to ensure that we do wait tWB. */
- ndelay(100);
-
- while(!this->legacy.dev_ready(this));
-}
-static int find_nand_cs(unsigned long nand_base)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR);
- unsigned long addr, staddr, start, mask, end;
- int i;
+ /* deassert chip enable */
+ alchemy_wrsmem(0, AU1000_MEM_STNDCTL);
+ /* Drain the writebuffer */
+ wmb();
- for (i = 0; i < 4; i++) {
- addr = 0x1000 + (i * 0x10); /* CSx */
- staddr = __raw_readl(base + addr + 0x08); /* STADDRx */
- /* figure out the decoded range of this CS */
- start = (staddr << 4) & 0xfffc0000;
- mask = (staddr << 18) & 0xfffc0000;
- end = (start | (start - 1)) & ~(start ^ mask);
- if ((nand_base >= start) && (nand_base < end))
- return i;
- }
-
- return -ENODEV;
+ return ret;
}
+static const struct nand_controller_ops au1550nd_ops = {
+ .exec_op = au1550nd_exec_op,
+};
+
static int au1550nd_probe(struct platform_device *pdev)
{
struct au1550nd_platdata *pd;
@@ -424,23 +291,15 @@ static int au1550nd_probe(struct platform_device *pdev)
}
ctx->cs = cs;
- this->legacy.dev_ready = au1550_device_ready;
- this->legacy.select_chip = au1550_select_chip;
- this->legacy.cmdfunc = au1550_command;
-
- /* 30 us command delay time */
- this->legacy.chip_delay = 30;
+ nand_controller_init(&ctx->controller);
+ ctx->controller.ops = &au1550nd_ops;
+ this->controller = &ctx->controller;
this->ecc.mode = NAND_ECC_SOFT;
this->ecc.algo = NAND_ECC_HAMMING;
if (pd->devwidth)
this->options |= NAND_BUSWIDTH_16;
- this->legacy.read_byte = (pd->devwidth) ? au_read_byte16 : au_read_byte;
- ctx->write_byte = (pd->devwidth) ? au_write_byte16 : au_write_byte;
- this->legacy.write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf;
- this->legacy.read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf;
-
ret = nand_scan(this, 1);
if (ret) {
dev_err(&pdev->dev, "NAND scan failed with %d\n", ret);
@@ -466,8 +325,12 @@ static int au1550nd_remove(struct platform_device *pdev)
{
struct au1550nd_ctx *ctx = platform_get_drvdata(pdev);
struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct nand_chip *chip = &ctx->chip;
+ int ret;
- nand_release(&ctx->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
iounmap(ctx->base);
release_mem_region(r->start, 0x1000);
kfree(ctx);
diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/main.c b/drivers/mtd/nand/raw/bcm47xxnflash/main.c
index 8dae97c1dbe7..dcc70d9dc6e5 100644
--- a/drivers/mtd/nand/raw/bcm47xxnflash/main.c
+++ b/drivers/mtd/nand/raw/bcm47xxnflash/main.c
@@ -60,8 +60,12 @@ static int bcm47xxnflash_probe(struct platform_device *pdev)
static int bcm47xxnflash_remove(struct platform_device *pdev)
{
struct bcm47xxnflash *nflash = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &nflash->nand_chip;
+ int ret;
- nand_release(&nflash->nand_chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
return 0;
}
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 8f9ffb46a09f..44068e9eea03 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -4,7 +4,6 @@
*/
#include <linux/clk.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -264,6 +263,7 @@ struct brcmnand_controller {
const unsigned int *block_sizes;
unsigned int max_page_size;
const unsigned int *page_sizes;
+ unsigned int page_size_shift;
unsigned int max_oob;
u32 features;
@@ -338,8 +338,38 @@ enum brcmnand_reg {
BRCMNAND_FC_BASE,
};
-/* BRCMNAND v4.0 */
-static const u16 brcmnand_regs_v40[] = {
+/* BRCMNAND v2.1-v2.2 */
+static const u16 brcmnand_regs_v21[] = {
+ [BRCMNAND_CMD_START] = 0x04,
+ [BRCMNAND_CMD_EXT_ADDRESS] = 0x08,
+ [BRCMNAND_CMD_ADDRESS] = 0x0c,
+ [BRCMNAND_INTFC_STATUS] = 0x5c,
+ [BRCMNAND_CS_SELECT] = 0x14,
+ [BRCMNAND_CS_XOR] = 0x18,
+ [BRCMNAND_LL_OP] = 0,
+ [BRCMNAND_CS0_BASE] = 0x40,
+ [BRCMNAND_CS1_BASE] = 0,
+ [BRCMNAND_CORR_THRESHOLD] = 0,
+ [BRCMNAND_CORR_THRESHOLD_EXT] = 0,
+ [BRCMNAND_UNCORR_COUNT] = 0,
+ [BRCMNAND_CORR_COUNT] = 0,
+ [BRCMNAND_CORR_EXT_ADDR] = 0x60,
+ [BRCMNAND_CORR_ADDR] = 0x64,
+ [BRCMNAND_UNCORR_EXT_ADDR] = 0x68,
+ [BRCMNAND_UNCORR_ADDR] = 0x6c,
+ [BRCMNAND_SEMAPHORE] = 0x50,
+ [BRCMNAND_ID] = 0x54,
+ [BRCMNAND_ID_EXT] = 0,
+ [BRCMNAND_LL_RDATA] = 0,
+ [BRCMNAND_OOB_READ_BASE] = 0x20,
+ [BRCMNAND_OOB_READ_10_BASE] = 0,
+ [BRCMNAND_OOB_WRITE_BASE] = 0x30,
+ [BRCMNAND_OOB_WRITE_10_BASE] = 0,
+ [BRCMNAND_FC_BASE] = 0x200,
+};
+
+/* BRCMNAND v3.3-v4.0 */
+static const u16 brcmnand_regs_v33[] = {
[BRCMNAND_CMD_START] = 0x04,
[BRCMNAND_CMD_EXT_ADDRESS] = 0x08,
[BRCMNAND_CMD_ADDRESS] = 0x0c,
@@ -536,6 +566,9 @@ enum {
CFG_BUS_WIDTH = BIT(CFG_BUS_WIDTH_SHIFT),
CFG_DEVICE_SIZE_SHIFT = 24,
+ /* Only for v2.1 */
+ CFG_PAGE_SIZE_SHIFT_v2_1 = 30,
+
/* Only for pre-v7.1 (with no CFG_EXT register) */
CFG_PAGE_SIZE_SHIFT = 20,
CFG_BLK_SIZE_SHIFT = 28,
@@ -571,12 +604,16 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
{
static const unsigned int block_sizes_v6[] = { 8, 16, 128, 256, 512, 1024, 2048, 0 };
static const unsigned int block_sizes_v4[] = { 16, 128, 8, 512, 256, 1024, 2048, 0 };
- static const unsigned int page_sizes[] = { 512, 2048, 4096, 8192, 0 };
+ static const unsigned int block_sizes_v2_2[] = { 16, 128, 8, 512, 256, 0 };
+ static const unsigned int block_sizes_v2_1[] = { 16, 128, 8, 512, 0 };
+ static const unsigned int page_sizes_v3_4[] = { 512, 2048, 4096, 8192, 0 };
+ static const unsigned int page_sizes_v2_2[] = { 512, 2048, 4096, 0 };
+ static const unsigned int page_sizes_v2_1[] = { 512, 2048, 0 };
ctrl->nand_version = nand_readreg(ctrl, 0) & 0xffff;
- /* Only support v4.0+? */
- if (ctrl->nand_version < 0x0400) {
+ /* Only support v2.1+ */
+ if (ctrl->nand_version < 0x0201) {
dev_err(ctrl->dev, "version %#x not supported\n",
ctrl->nand_version);
return -ENODEV;
@@ -591,8 +628,10 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
ctrl->reg_offsets = brcmnand_regs_v60;
else if (ctrl->nand_version >= 0x0500)
ctrl->reg_offsets = brcmnand_regs_v50;
- else if (ctrl->nand_version >= 0x0400)
- ctrl->reg_offsets = brcmnand_regs_v40;
+ else if (ctrl->nand_version >= 0x0303)
+ ctrl->reg_offsets = brcmnand_regs_v33;
+ else if (ctrl->nand_version >= 0x0201)
+ ctrl->reg_offsets = brcmnand_regs_v21;
/* Chip-select stride */
if (ctrl->nand_version >= 0x0701)
@@ -606,8 +645,9 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
} else {
ctrl->cs_offsets = brcmnand_cs_offsets;
- /* v5.0 and earlier has a different CS0 offset layout */
- if (ctrl->nand_version <= 0x0500)
+ /* v3.3-5.0 have a different CS0 offset layout */
+ if (ctrl->nand_version >= 0x0303 &&
+ ctrl->nand_version <= 0x0500)
ctrl->cs0_offsets = brcmnand_cs_offsets_cs0;
}
@@ -617,14 +657,32 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
ctrl->max_page_size = 16 * 1024;
ctrl->max_block_size = 2 * 1024 * 1024;
} else {
- ctrl->page_sizes = page_sizes;
+ if (ctrl->nand_version >= 0x0304)
+ ctrl->page_sizes = page_sizes_v3_4;
+ else if (ctrl->nand_version >= 0x0202)
+ ctrl->page_sizes = page_sizes_v2_2;
+ else
+ ctrl->page_sizes = page_sizes_v2_1;
+
+ if (ctrl->nand_version >= 0x0202)
+ ctrl->page_size_shift = CFG_PAGE_SIZE_SHIFT;
+ else
+ ctrl->page_size_shift = CFG_PAGE_SIZE_SHIFT_v2_1;
+
if (ctrl->nand_version >= 0x0600)
ctrl->block_sizes = block_sizes_v6;
- else
+ else if (ctrl->nand_version >= 0x0400)
ctrl->block_sizes = block_sizes_v4;
+ else if (ctrl->nand_version >= 0x0202)
+ ctrl->block_sizes = block_sizes_v2_2;
+ else
+ ctrl->block_sizes = block_sizes_v2_1;
if (ctrl->nand_version < 0x0400) {
- ctrl->max_page_size = 4096;
+ if (ctrl->nand_version < 0x0202)
+ ctrl->max_page_size = 2048;
+ else
+ ctrl->max_page_size = 4096;
ctrl->max_block_size = 512 * 1024;
}
}
@@ -810,6 +868,9 @@ static void brcmnand_wr_corr_thresh(struct brcmnand_host *host, u8 val)
enum brcmnand_reg reg = BRCMNAND_CORR_THRESHOLD;
int cs = host->cs;
+ if (!ctrl->reg_offsets[reg])
+ return;
+
if (ctrl->nand_version == 0x0702)
bits = 7;
else if (ctrl->nand_version >= 0x0600)
@@ -868,8 +929,10 @@ static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
return GENMASK(7, 0);
else if (ctrl->nand_version >= 0x0600)
return GENMASK(6, 0);
- else
+ else if (ctrl->nand_version >= 0x0303)
return GENMASK(5, 0);
+ else
+ return GENMASK(4, 0);
}
#define NAND_ACC_CONTROL_ECC_SHIFT 16
@@ -1100,30 +1163,30 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section,
struct brcmnand_cfg *cfg = &host->hwcfg;
int sas = cfg->spare_area_size << cfg->sector_size_1k;
int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
+ u32 next;
- if (section >= sectors * 2)
+ if (section > sectors)
return -ERANGE;
- oobregion->offset = (section / 2) * sas;
+ next = (section * sas);
+ if (section < sectors)
+ next += 6;
- if (section & 1) {
- oobregion->offset += 9;
- oobregion->length = 7;
+ if (section) {
+ oobregion->offset = ((section - 1) * sas) + 9;
} else {
- oobregion->length = 6;
-
- /* First sector of each page may have BBI */
- if (!section) {
- /*
- * Small-page NAND use byte 6 for BBI while large-page
- * NAND use byte 0.
- */
- if (cfg->page_size > 512)
- oobregion->offset++;
- oobregion->length--;
+ if (cfg->page_size > 512) {
+ /* Large page NAND uses first 2 bytes for BBI */
+ oobregion->offset = 2;
+ } else {
+ /* Small page NAND uses last byte before ECC for BBI */
+ oobregion->offset = 0;
+ next--;
}
}
+ oobregion->length = next - oobregion->offset;
+
return 0;
}
@@ -2018,28 +2081,31 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd,
struct nand_chip *chip, void *buf, u64 addr)
{
- int i, sas;
- void *oob = chip->oob_poi;
+ struct mtd_oob_region ecc;
+ int i;
int bitflips = 0;
int page = addr >> chip->page_shift;
int ret;
+ void *ecc_bytes;
void *ecc_chunk;
if (!buf)
buf = nand_get_data_buf(chip);
- sas = mtd->oobsize / chip->ecc.steps;
-
/* read without ecc for verification */
ret = chip->ecc.read_page_raw(chip, buf, true, page);
if (ret)
return ret;
- for (i = 0; i < chip->ecc.steps; i++, oob += sas) {
+ for (i = 0; i < chip->ecc.steps; i++) {
ecc_chunk = buf + chip->ecc.size * i;
- ret = nand_check_erased_ecc_chunk(ecc_chunk,
- chip->ecc.size,
- oob, sas, NULL, 0,
+
+ mtd_ooblayout_ecc(mtd, i, &ecc);
+ ecc_bytes = chip->oob_poi + ecc.offset;
+
+ ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size,
+ ecc_bytes, ecc.length,
+ NULL, 0,
chip->ecc.strength);
if (ret < 0)
return ret;
@@ -2377,7 +2443,7 @@ static int brcmnand_set_cfg(struct brcmnand_host *host,
(!!(cfg->device_width == 16) << CFG_BUS_WIDTH_SHIFT) |
(device_size << CFG_DEVICE_SIZE_SHIFT);
if (cfg_offs == cfg_ext_offs) {
- tmp |= (page_size << CFG_PAGE_SIZE_SHIFT) |
+ tmp |= (page_size << ctrl->page_size_shift) |
(block_size << CFG_BLK_SIZE_SHIFT);
nand_writereg(ctrl, cfg_offs, tmp);
} else {
@@ -2389,9 +2455,11 @@ static int brcmnand_set_cfg(struct brcmnand_host *host,
tmp = nand_readreg(ctrl, acc_control_offs);
tmp &= ~brcmnand_ecc_level_mask(ctrl);
- tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT;
tmp &= ~brcmnand_spare_area_mask(ctrl);
- tmp |= cfg->spare_area_size;
+ if (ctrl->nand_version >= 0x0302) {
+ tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT;
+ tmp |= cfg->spare_area_size;
+ }
nand_writereg(ctrl, acc_control_offs, tmp);
brcmnand_set_sector_size_1k(host, cfg->sector_size_1k);
@@ -2577,7 +2645,7 @@ static int brcmnand_attach_chip(struct nand_chip *chip)
* to/from, and have nand_base pass us a bounce buffer instead, as
* needed.
*/
- chip->options |= NAND_USE_BOUNCE_BUFFER;
+ chip->options |= NAND_USES_DMA;
if (chip->bbt_options & NAND_BBT_USE_FLASH)
chip->bbt_options |= NAND_BBT_NO_OOB;
@@ -2764,6 +2832,8 @@ const struct dev_pm_ops brcmnand_pm_ops = {
EXPORT_SYMBOL_GPL(brcmnand_pm_ops);
static const struct of_device_id brcmnand_of_match[] = {
+ { .compatible = "brcm,brcmnand-v2.1" },
+ { .compatible = "brcm,brcmnand-v2.2" },
{ .compatible = "brcm,brcmnand-v4.0" },
{ .compatible = "brcm,brcmnand-v5.0" },
{ .compatible = "brcm,brcmnand-v6.0" },
@@ -3045,9 +3115,15 @@ int brcmnand_remove(struct platform_device *pdev)
{
struct brcmnand_controller *ctrl = dev_get_drvdata(&pdev->dev);
struct brcmnand_host *host;
+ struct nand_chip *chip;
+ int ret;
- list_for_each_entry(host, &ctrl->host_list, node)
- nand_release(&host->chip);
+ list_for_each_entry(host, &ctrl->host_list, node) {
+ chip = &host->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ }
clk_disable_unprepare(ctrl->clk);
diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c
index efddc5c68afb..c405722adfe1 100644
--- a/drivers/mtd/nand/raw/cadence-nand-controller.c
+++ b/drivers/mtd/nand/raw/cadence-nand-controller.c
@@ -2223,10 +2223,12 @@ static int cadence_nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{
- int status = cadence_nand_select_target(chip);
+ if (!check_only) {
+ int status = cadence_nand_select_target(chip);
- if (status)
- return status;
+ if (status)
+ return status;
+ }
return nand_op_parser_exec_op(chip, &cadence_nand_op_parser, op,
check_only);
@@ -2592,7 +2594,7 @@ cadence_nand_setup_data_interface(struct nand_chip *chip, int chipnr,
return 0;
}
-int cadence_nand_attach_chip(struct nand_chip *chip)
+static int cadence_nand_attach_chip(struct nand_chip *chip)
{
struct cdns_nand_ctrl *cdns_ctrl = to_cdns_nand_ctrl(chip->controller);
struct cdns_nand_chip *cdns_chip = to_cdns_nand_chip(chip);
@@ -2778,9 +2780,14 @@ static int cadence_nand_chip_init(struct cdns_nand_ctrl *cdns_ctrl,
static void cadence_nand_chips_cleanup(struct cdns_nand_ctrl *cdns_ctrl)
{
struct cdns_nand_chip *entry, *temp;
+ struct nand_chip *chip;
+ int ret;
list_for_each_entry_safe(entry, temp, &cdns_ctrl->chips, node) {
- nand_release(&entry->chip);
+ chip = &entry->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
list_del(&entry->node);
}
}
diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 2d1c22dc88c1..92173790f20b 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -546,11 +546,6 @@ static int cafe_nand_write_page_lowlevel(struct nand_chip *chip,
return nand_prog_page_end_op(chip);
}
-static int cafe_nand_block_bad(struct nand_chip *chip, loff_t ofs)
-{
- return 0;
-}
-
/* F_2[X]/(X**6+X+1) */
static unsigned short gf64_mul(u8 a, u8 b)
{
@@ -718,10 +713,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
/* Enable the following for a flash based bad block table */
cafe->nand.bbt_options = NAND_BBT_USE_FLASH;
- if (skipbbt) {
- cafe->nand.options |= NAND_SKIP_BBTSCAN;
- cafe->nand.legacy.block_bad = cafe_nand_block_bad;
- }
+ if (skipbbt)
+ cafe->nand.options |= NAND_SKIP_BBTSCAN | NAND_NO_BBM_QUIRK;
if (numtimings && numtimings != 3) {
dev_warn(&cafe->pdev->dev, "%d timing register values ignored; precisely three are required\n", numtimings);
@@ -814,11 +807,14 @@ static void cafe_nand_remove(struct pci_dev *pdev)
struct mtd_info *mtd = pci_get_drvdata(pdev);
struct nand_chip *chip = mtd_to_nand(mtd);
struct cafe_priv *cafe = nand_get_controller_data(chip);
+ int ret;
/* Disable NAND IRQ in global IRQ mask register */
cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
free_irq(pdev->irq, mtd);
- nand_release(chip);
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(chip);
free_rs(cafe->rs);
pci_iounmap(pdev, cafe->mmio);
dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
diff --git a/drivers/mtd/nand/raw/cmx270_nand.c b/drivers/mtd/nand/raw/cmx270_nand.c
deleted file mode 100644
index 045b6175ae79..000000000000
--- a/drivers/mtd/nand/raw/cmx270_nand.c
+++ /dev/null
@@ -1,236 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2006 Compulab, Ltd.
- * Mike Rapoport <mike@compulab.co.il>
- *
- * Derived from drivers/mtd/nand/h1910.c (removed in v3.10)
- * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
- * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
- * Overview:
- * This is a device driver for the NAND flash device found on the
- * CM-X270 board.
- */
-
-#include <linux/mtd/rawnand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/pxa2xx-regs.h>
-
-#define GPIO_NAND_CS (11)
-#define GPIO_NAND_RB (89)
-
-/* MTD structure for CM-X270 board */
-static struct mtd_info *cmx270_nand_mtd;
-
-/* remaped IO address of the device */
-static void __iomem *cmx270_nand_io;
-
-/*
- * Define static partitions for flash device
- */
-static const struct mtd_partition partition_info[] = {
- [0] = {
- .name = "cmx270-0",
- .offset = 0,
- .size = MTDPART_SIZ_FULL
- }
-};
-#define NUM_PARTITIONS (ARRAY_SIZE(partition_info))
-
-static u_char cmx270_read_byte(struct nand_chip *this)
-{
- return (readl(this->legacy.IO_ADDR_R) >> 16);
-}
-
-static void cmx270_write_buf(struct nand_chip *this, const u_char *buf,
- int len)
-{
- int i;
-
- for (i=0; i<len; i++)
- writel((*buf++ << 16), this->legacy.IO_ADDR_W);
-}
-
-static void cmx270_read_buf(struct nand_chip *this, u_char *buf, int len)
-{
- int i;
-
- for (i=0; i<len; i++)
- *buf++ = readl(this->legacy.IO_ADDR_R) >> 16;
-}
-
-static inline void nand_cs_on(void)
-{
- gpio_set_value(GPIO_NAND_CS, 0);
-}
-
-static void nand_cs_off(void)
-{
- dsb();
-
- gpio_set_value(GPIO_NAND_CS, 1);
-}
-
-/*
- * hardware specific access to control-lines
- */
-static void cmx270_hwcontrol(struct nand_chip *this, int dat,
- unsigned int ctrl)
-{
- unsigned int nandaddr = (unsigned int)this->legacy.IO_ADDR_W;
-
- dsb();
-
- if (ctrl & NAND_CTRL_CHANGE) {
- if ( ctrl & NAND_ALE )
- nandaddr |= (1 << 3);
- else
- nandaddr &= ~(1 << 3);
- if ( ctrl & NAND_CLE )
- nandaddr |= (1 << 2);
- else
- nandaddr &= ~(1 << 2);
- if ( ctrl & NAND_NCE )
- nand_cs_on();
- else
- nand_cs_off();
- }
-
- dsb();
- this->legacy.IO_ADDR_W = (void __iomem*)nandaddr;
- if (dat != NAND_CMD_NONE)
- writel((dat << 16), this->legacy.IO_ADDR_W);
-
- dsb();
-}
-
-/*
- * read device ready pin
- */
-static int cmx270_device_ready(struct nand_chip *this)
-{
- dsb();
-
- return (gpio_get_value(GPIO_NAND_RB));
-}
-
-/*
- * Main initialization routine
- */
-static int __init cmx270_init(void)
-{
- struct nand_chip *this;
- int ret;
-
- if (!(machine_is_armcore() && cpu_is_pxa27x()))
- return -ENODEV;
-
- ret = gpio_request(GPIO_NAND_CS, "NAND CS");
- if (ret) {
- pr_warn("CM-X270: failed to request NAND CS gpio\n");
- return ret;
- }
-
- gpio_direction_output(GPIO_NAND_CS, 1);
-
- ret = gpio_request(GPIO_NAND_RB, "NAND R/B");
- if (ret) {
- pr_warn("CM-X270: failed to request NAND R/B gpio\n");
- goto err_gpio_request;
- }
-
- gpio_direction_input(GPIO_NAND_RB);
-
- /* Allocate memory for MTD device structure and private data */
- this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
- if (!this) {
- ret = -ENOMEM;
- goto err_kzalloc;
- }
-
- cmx270_nand_io = ioremap(PXA_CS1_PHYS, 12);
- if (!cmx270_nand_io) {
- pr_debug("Unable to ioremap NAND device\n");
- ret = -EINVAL;
- goto err_ioremap;
- }
-
- cmx270_nand_mtd = nand_to_mtd(this);
-
- /* Link the private data with the MTD structure */
- cmx270_nand_mtd->owner = THIS_MODULE;
-
- /* insert callbacks */
- this->legacy.IO_ADDR_R = cmx270_nand_io;
- this->legacy.IO_ADDR_W = cmx270_nand_io;
- this->legacy.cmd_ctrl = cmx270_hwcontrol;
- this->legacy.dev_ready = cmx270_device_ready;
-
- /* 15 us command delay time */
- this->legacy.chip_delay = 20;
- this->ecc.mode = NAND_ECC_SOFT;
- this->ecc.algo = NAND_ECC_HAMMING;
-
- /* read/write functions */
- this->legacy.read_byte = cmx270_read_byte;
- this->legacy.read_buf = cmx270_read_buf;
- this->legacy.write_buf = cmx270_write_buf;
-
- /* Scan to find existence of the device */
- ret = nand_scan(this, 1);
- if (ret) {
- pr_notice("No NAND device\n");
- goto err_scan;
- }
-
- /* Register the partitions */
- ret = mtd_device_register(cmx270_nand_mtd, partition_info,
- NUM_PARTITIONS);
- if (ret)
- goto err_scan;
-
- /* Return happy */
- return 0;
-
-err_scan:
- iounmap(cmx270_nand_io);
-err_ioremap:
- kfree(this);
-err_kzalloc:
- gpio_free(GPIO_NAND_RB);
-err_gpio_request:
- gpio_free(GPIO_NAND_CS);
-
- return ret;
-
-}
-module_init(cmx270_init);
-
-/*
- * Clean up routine
- */
-static void __exit cmx270_cleanup(void)
-{
- /* Release resources, unregister device */
- nand_release(mtd_to_nand(cmx270_nand_mtd));
-
- gpio_free(GPIO_NAND_RB);
- gpio_free(GPIO_NAND_CS);
-
- iounmap(cmx270_nand_io);
-
- kfree(mtd_to_nand(cmx270_nand_mtd));
-}
-module_exit(cmx270_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
-MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Module");
diff --git a/drivers/mtd/nand/raw/cs553x_nand.c b/drivers/mtd/nand/raw/cs553x_nand.c
index e2322cee3229..9472bf798ed5 100644
--- a/drivers/mtd/nand/raw/cs553x_nand.c
+++ b/drivers/mtd/nand/raw/cs553x_nand.c
@@ -21,9 +21,9 @@
#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
+#include <linux/iopoll.h>
#include <asm/msr.h>
-#include <asm/io.h>
#define NR_CS553X_CONTROLLERS 4
@@ -89,76 +89,151 @@
#define CS_NAND_ECC_CLRECC (1<<1)
#define CS_NAND_ECC_ENECC (1<<0)
-static void cs553x_read_buf(struct nand_chip *this, u_char *buf, int len)
+struct cs553x_nand_controller {
+ struct nand_controller base;
+ struct nand_chip chip;
+ void __iomem *mmio;
+};
+
+static struct cs553x_nand_controller *
+to_cs553x(struct nand_controller *controller)
+{
+ return container_of(controller, struct cs553x_nand_controller, base);
+}
+
+static int cs553x_write_ctrl_byte(struct cs553x_nand_controller *cs553x,
+ u32 ctl, u8 data)
{
+ u8 status;
+ int ret;
+
+ writeb(ctl, cs553x->mmio + MM_NAND_CTL);
+ writeb(data, cs553x->mmio + MM_NAND_IO);
+ ret = readb_poll_timeout_atomic(cs553x->mmio + MM_NAND_STS, status,
+ !(status & CS_NAND_CTLR_BUSY), 1,
+ 100000);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void cs553x_data_in(struct cs553x_nand_controller *cs553x, void *buf,
+ unsigned int len)
+{
+ writeb(0, cs553x->mmio + MM_NAND_CTL);
while (unlikely(len > 0x800)) {
- memcpy_fromio(buf, this->legacy.IO_ADDR_R, 0x800);
+ memcpy_fromio(buf, cs553x->mmio, 0x800);
buf += 0x800;
len -= 0x800;
}
- memcpy_fromio(buf, this->legacy.IO_ADDR_R, len);
+ memcpy_fromio(buf, cs553x->mmio, len);
}
-static void cs553x_write_buf(struct nand_chip *this, const u_char *buf, int len)
+static void cs553x_data_out(struct cs553x_nand_controller *cs553x,
+ const void *buf, unsigned int len)
{
+ writeb(0, cs553x->mmio + MM_NAND_CTL);
while (unlikely(len > 0x800)) {
- memcpy_toio(this->legacy.IO_ADDR_R, buf, 0x800);
+ memcpy_toio(cs553x->mmio, buf, 0x800);
buf += 0x800;
len -= 0x800;
}
- memcpy_toio(this->legacy.IO_ADDR_R, buf, len);
+ memcpy_toio(cs553x->mmio, buf, len);
}
-static unsigned char cs553x_read_byte(struct nand_chip *this)
+static int cs553x_wait_ready(struct cs553x_nand_controller *cs553x,
+ unsigned int timeout_ms)
{
- return readb(this->legacy.IO_ADDR_R);
+ u8 mask = CS_NAND_CTLR_BUSY | CS_NAND_STS_FLASH_RDY;
+ u8 status;
+
+ return readb_poll_timeout(cs553x->mmio + MM_NAND_STS, status,
+ (status & mask) == CS_NAND_STS_FLASH_RDY, 100,
+ timeout_ms * 1000);
}
-static void cs553x_write_byte(struct nand_chip *this, u_char byte)
+static int cs553x_exec_instr(struct cs553x_nand_controller *cs553x,
+ const struct nand_op_instr *instr)
{
- int i = 100000;
+ unsigned int i;
+ int ret = 0;
+
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ ret = cs553x_write_ctrl_byte(cs553x, CS_NAND_CTL_CLE,
+ instr->ctx.cmd.opcode);
+ break;
+
+ case NAND_OP_ADDR_INSTR:
+ for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+ ret = cs553x_write_ctrl_byte(cs553x, CS_NAND_CTL_ALE,
+ instr->ctx.addr.addrs[i]);
+ if (ret)
+ break;
+ }
+ break;
+
+ case NAND_OP_DATA_IN_INSTR:
+ cs553x_data_in(cs553x, instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ break;
+
+ case NAND_OP_DATA_OUT_INSTR:
+ cs553x_data_out(cs553x, instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ break;
- while (i && readb(this->legacy.IO_ADDR_R + MM_NAND_STS) & CS_NAND_CTLR_BUSY) {
- udelay(1);
- i--;
+ case NAND_OP_WAITRDY_INSTR:
+ ret = cs553x_wait_ready(cs553x, instr->ctx.waitrdy.timeout_ms);
+ break;
}
- writeb(byte, this->legacy.IO_ADDR_W + 0x801);
+
+ if (instr->delay_ns)
+ ndelay(instr->delay_ns);
+
+ return ret;
}
-static void cs553x_hwcontrol(struct nand_chip *this, int cmd,
- unsigned int ctrl)
+static int cs553x_exec_op(struct nand_chip *this,
+ const struct nand_operation *op,
+ bool check_only)
{
- void __iomem *mmio_base = this->legacy.IO_ADDR_R;
- if (ctrl & NAND_CTRL_CHANGE) {
- unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01;
- writeb(ctl, mmio_base + MM_NAND_CTL);
+ struct cs553x_nand_controller *cs553x = to_cs553x(this->controller);
+ unsigned int i;
+ int ret;
+
+ if (check_only)
+ return true;
+
+ /* De-assert the CE pin */
+ writeb(0, cs553x->mmio + MM_NAND_CTL);
+ for (i = 0; i < op->ninstrs; i++) {
+ ret = cs553x_exec_instr(cs553x, &op->instrs[i]);
+ if (ret)
+ break;
}
- if (cmd != NAND_CMD_NONE)
- cs553x_write_byte(this, cmd);
-}
-static int cs553x_device_ready(struct nand_chip *this)
-{
- void __iomem *mmio_base = this->legacy.IO_ADDR_R;
- unsigned char foo = readb(mmio_base + MM_NAND_STS);
+ /* Re-assert the CE pin. */
+ writeb(CS_NAND_CTL_CE, cs553x->mmio + MM_NAND_CTL);
- return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY);
+ return ret;
}
static void cs_enable_hwecc(struct nand_chip *this, int mode)
{
- void __iomem *mmio_base = this->legacy.IO_ADDR_R;
+ struct cs553x_nand_controller *cs553x = to_cs553x(this->controller);
- writeb(0x07, mmio_base + MM_NAND_ECC_CTL);
+ writeb(0x07, cs553x->mmio + MM_NAND_ECC_CTL);
}
static int cs_calculate_ecc(struct nand_chip *this, const u_char *dat,
u_char *ecc_code)
{
+ struct cs553x_nand_controller *cs553x = to_cs553x(this->controller);
uint32_t ecc;
- void __iomem *mmio_base = this->legacy.IO_ADDR_R;
- ecc = readl(mmio_base + MM_NAND_STS);
+ ecc = readl(cs553x->mmio + MM_NAND_STS);
ecc_code[1] = ecc >> 8;
ecc_code[0] = ecc >> 16;
@@ -166,10 +241,15 @@ static int cs_calculate_ecc(struct nand_chip *this, const u_char *dat,
return 0;
}
-static struct mtd_info *cs553x_mtd[4];
+static struct cs553x_nand_controller *controllers[4];
+
+static const struct nand_controller_ops cs553x_nand_controller_ops = {
+ .exec_op = cs553x_exec_op,
+};
static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
{
+ struct cs553x_nand_controller *controller;
int err = 0;
struct nand_chip *this;
struct mtd_info *new_mtd;
@@ -183,33 +263,29 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
}
/* Allocate memory for MTD device structure and private data */
- this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
- if (!this) {
+ controller = kzalloc(sizeof(*controller), GFP_KERNEL);
+ if (!controller) {
err = -ENOMEM;
goto out;
}
+ this = &controller->chip;
+ nand_controller_init(&controller->base);
+ controller->base.ops = &cs553x_nand_controller_ops;
+ this->controller = &controller->base;
new_mtd = nand_to_mtd(this);
/* Link the private data with the MTD structure */
new_mtd->owner = THIS_MODULE;
/* map physical address */
- this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = ioremap(adr, 4096);
- if (!this->legacy.IO_ADDR_R) {
+ controller->mmio = ioremap(adr, 4096);
+ if (!controller->mmio) {
pr_warn("ioremap cs553x NAND @0x%08lx failed\n", adr);
err = -EIO;
goto out_mtd;
}
- this->legacy.cmd_ctrl = cs553x_hwcontrol;
- this->legacy.dev_ready = cs553x_device_ready;
- this->legacy.read_byte = cs553x_read_byte;
- this->legacy.read_buf = cs553x_read_buf;
- this->legacy.write_buf = cs553x_write_buf;
-
- this->legacy.chip_delay = 0;
-
this->ecc.mode = NAND_ECC_HW;
this->ecc.size = 256;
this->ecc.bytes = 3;
@@ -232,15 +308,15 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
if (err)
goto out_free;
- cs553x_mtd[cs] = new_mtd;
+ controllers[cs] = controller;
goto out;
out_free:
kfree(new_mtd->name);
out_ior:
- iounmap(this->legacy.IO_ADDR_R);
+ iounmap(controller->mmio);
out_mtd:
- kfree(this);
+ kfree(controller);
out:
return err;
}
@@ -295,9 +371,10 @@ static int __init cs553x_init(void)
/* Register all devices together here. This means we can easily hack it to
do mtdconcat etc. if we want to. */
for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
- if (cs553x_mtd[i]) {
+ if (controllers[i]) {
/* If any devices registered, return success. Else the last error. */
- mtd_device_register(cs553x_mtd[i], NULL, 0);
+ mtd_device_register(nand_to_mtd(&controllers[i]->chip),
+ NULL, 0);
err = 0;
}
}
@@ -312,26 +389,26 @@ static void __exit cs553x_cleanup(void)
int i;
for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
- struct mtd_info *mtd = cs553x_mtd[i];
- struct nand_chip *this;
- void __iomem *mmio_base;
+ struct cs553x_nand_controller *controller = controllers[i];
+ struct nand_chip *this = &controller->chip;
+ struct mtd_info *mtd = nand_to_mtd(this);
+ int ret;
if (!mtd)
continue;
- this = mtd_to_nand(mtd);
- mmio_base = this->legacy.IO_ADDR_R;
-
/* Release resources, unregister device */
- nand_release(this);
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(this);
kfree(mtd->name);
- cs553x_mtd[i] = NULL;
+ controllers[i] = NULL;
/* unmap physical address */
- iounmap(mmio_base);
+ iounmap(controller->mmio);
/* Free the MTD device structure */
- kfree(this);
+ kfree(controller);
}
}
diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c
index 25c185bea50c..d975a62caaa5 100644
--- a/drivers/mtd/nand/raw/davinci_nand.c
+++ b/drivers/mtd/nand/raw/davinci_nand.c
@@ -14,7 +14,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
-#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/slab.h>
@@ -38,6 +38,7 @@
* outputs in a "wire-AND" configuration, with no per-chip signals.
*/
struct davinci_nand_info {
+ struct nand_controller controller;
struct nand_chip chip;
struct platform_device *pdev;
@@ -81,46 +82,6 @@ static inline void davinci_nand_writel(struct davinci_nand_info *info,
/*----------------------------------------------------------------------*/
/*
- * Access to hardware control lines: ALE, CLE, secondary chipselect.
- */
-
-static void nand_davinci_hwcontrol(struct nand_chip *nand, int cmd,
- unsigned int ctrl)
-{
- struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(nand));
- void __iomem *addr = info->current_cs;
-
- /* Did the control lines change? */
- if (ctrl & NAND_CTRL_CHANGE) {
- if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
- addr += info->mask_cle;
- else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
- addr += info->mask_ale;
-
- nand->legacy.IO_ADDR_W = addr;
- }
-
- if (cmd != NAND_CMD_NONE)
- iowrite8(cmd, nand->legacy.IO_ADDR_W);
-}
-
-static void nand_davinci_select_chip(struct nand_chip *nand, int chip)
-{
- struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(nand));
-
- info->current_cs = info->vaddr;
-
- /* maybe kick in a second chipselect */
- if (chip > 0)
- info->current_cs += info->mask_chipsel;
-
- info->chip.legacy.IO_ADDR_W = info->current_cs;
- info->chip.legacy.IO_ADDR_R = info->chip.legacy.IO_ADDR_W;
-}
-
-/*----------------------------------------------------------------------*/
-
-/*
* 1-bit hardware ECC ... context maintained for each core chipselect
*/
@@ -410,48 +371,75 @@ correct:
return corrected;
}
-/*----------------------------------------------------------------------*/
-
-/*
- * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
- * how these chips are normally wired. This translates to both 8 and 16
- * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
+/**
+ * nand_read_page_hwecc_oob_first - hw ecc, read oob first
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
*
- * For now we assume that configuration, or any other one which ignores
- * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
- * and have that transparently morphed into multiple NAND operations.
+ * Hardware ECC for large page chips, require OOB to be read first. For this
+ * ECC mode, the write_page method is re-used from ECC_HW. These methods
+ * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
+ * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
+ * the data area, by overwriting the NAND manufacturer bad block markings.
*/
-static void nand_davinci_read_buf(struct nand_chip *chip, uint8_t *buf,
- int len)
+static int nand_davinci_read_page_hwecc_oob_first(struct nand_chip *chip,
+ uint8_t *buf,
+ int oob_required, int page)
{
- if ((0x03 & ((uintptr_t)buf)) == 0 && (0x03 & len) == 0)
- ioread32_rep(chip->legacy.IO_ADDR_R, buf, len >> 2);
- else if ((0x01 & ((uintptr_t)buf)) == 0 && (0x01 & len) == 0)
- ioread16_rep(chip->legacy.IO_ADDR_R, buf, len >> 1);
- else
- ioread8_rep(chip->legacy.IO_ADDR_R, buf, len);
-}
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ int i, eccsize = chip->ecc.size, ret;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps;
+ uint8_t *p = buf;
+ uint8_t *ecc_code = chip->ecc.code_buf;
+ uint8_t *ecc_calc = chip->ecc.calc_buf;
+ unsigned int max_bitflips = 0;
+
+ /* Read the OOB area first */
+ ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
+ if (ret)
+ return ret;
-static void nand_davinci_write_buf(struct nand_chip *chip, const uint8_t *buf,
- int len)
-{
- if ((0x03 & ((uintptr_t)buf)) == 0 && (0x03 & len) == 0)
- iowrite32_rep(chip->legacy.IO_ADDR_R, buf, len >> 2);
- else if ((0x01 & ((uintptr_t)buf)) == 0 && (0x01 & len) == 0)
- iowrite16_rep(chip->legacy.IO_ADDR_R, buf, len >> 1);
- else
- iowrite8_rep(chip->legacy.IO_ADDR_R, buf, len);
-}
+ ret = nand_read_page_op(chip, page, 0, NULL, 0);
+ if (ret)
+ return ret;
-/*
- * Check hardware register for wait status. Returns 1 if device is ready,
- * 0 if it is still busy.
- */
-static int nand_davinci_dev_ready(struct nand_chip *chip)
-{
- struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip));
+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
+ chip->ecc.total);
+ if (ret)
+ return ret;
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ int stat;
+
+ chip->ecc.hwctl(chip, NAND_ECC_READ);
- return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
+ ret = nand_read_data_op(chip, p, eccsize, false, false);
+ if (ret)
+ return ret;
+
+ chip->ecc.calculate(chip, p, &ecc_calc[i]);
+
+ stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL);
+ if (stat == -EBADMSG &&
+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
+ /* check for empty pages with bitflips */
+ stat = nand_check_erased_ecc_chunk(p, eccsize,
+ &ecc_code[i],
+ eccbytes, NULL, 0,
+ chip->ecc.strength);
+ }
+
+ if (stat < 0) {
+ mtd->ecc_stats.failed++;
+ } else {
+ mtd->ecc_stats.corrected += stat;
+ max_bitflips = max_t(unsigned int, max_bitflips, stat);
+ }
+ }
+ return max_bitflips;
}
/*----------------------------------------------------------------------*/
@@ -613,6 +601,13 @@ static int davinci_nand_attach_chip(struct nand_chip *chip)
break;
case NAND_ECC_HW:
if (pdata->ecc_bits == 4) {
+ int chunks = mtd->writesize / 512;
+
+ if (!chunks || mtd->oobsize < 16) {
+ dev_dbg(&info->pdev->dev, "too small\n");
+ return -EINVAL;
+ }
+
/*
* No sanity checks: CPUs must support this,
* and the chips may not use NAND_BUSWIDTH_16.
@@ -635,6 +630,26 @@ static int davinci_nand_attach_chip(struct nand_chip *chip)
info->chip.ecc.bytes = 10;
info->chip.ecc.options = NAND_ECC_GENERIC_ERASED_CHECK;
info->chip.ecc.algo = NAND_ECC_BCH;
+
+ /*
+ * Update ECC layout if needed ... for 1-bit HW ECC, the
+ * default is OK, but it allocates 6 bytes when only 3
+ * are needed (for each 512 bytes). For 4-bit HW ECC,
+ * the default is not usable: 10 bytes needed, not 6.
+ *
+ * For small page chips, preserve the manufacturer's
+ * badblock marking data ... and make sure a flash BBT
+ * table marker fits in the free bytes.
+ */
+ if (chunks == 1) {
+ mtd_set_ooblayout(mtd,
+ &hwecc4_small_ooblayout_ops);
+ } else if (chunks == 4 || chunks == 8) {
+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
+ info->chip.ecc.read_page = nand_davinci_read_page_hwecc_oob_first;
+ } else {
+ return -EIO;
+ }
} else {
/* 1bit ecc hamming */
info->chip.ecc.calculate = nand_davinci_calculate_1bit;
@@ -650,39 +665,111 @@ static int davinci_nand_attach_chip(struct nand_chip *chip)
return -EINVAL;
}
- /*
- * Update ECC layout if needed ... for 1-bit HW ECC, the default
- * is OK, but it allocates 6 bytes when only 3 are needed (for
- * each 512 bytes). For the 4-bit HW ECC, that default is not
- * usable: 10 bytes are needed, not 6.
- */
- if (pdata->ecc_bits == 4) {
- int chunks = mtd->writesize / 512;
+ return ret;
+}
- if (!chunks || mtd->oobsize < 16) {
- dev_dbg(&info->pdev->dev, "too small\n");
- return -EINVAL;
- }
+static void nand_davinci_data_in(struct davinci_nand_info *info, void *buf,
+ unsigned int len, bool force_8bit)
+{
+ u32 alignment = ((uintptr_t)buf | len) & 3;
- /* For small page chips, preserve the manufacturer's
- * badblock marking data ... and make sure a flash BBT
- * table marker fits in the free bytes.
- */
- if (chunks == 1) {
- mtd_set_ooblayout(mtd, &hwecc4_small_ooblayout_ops);
- } else if (chunks == 4 || chunks == 8) {
- mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
- info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
- } else {
- return -EIO;
+ if (force_8bit || (alignment & 1))
+ ioread8_rep(info->current_cs, buf, len);
+ else if (alignment & 3)
+ ioread16_rep(info->current_cs, buf, len >> 1);
+ else
+ ioread32_rep(info->current_cs, buf, len >> 2);
+}
+
+static void nand_davinci_data_out(struct davinci_nand_info *info,
+ const void *buf, unsigned int len,
+ bool force_8bit)
+{
+ u32 alignment = ((uintptr_t)buf | len) & 3;
+
+ if (force_8bit || (alignment & 1))
+ iowrite8_rep(info->current_cs, buf, len);
+ else if (alignment & 3)
+ iowrite16_rep(info->current_cs, buf, len >> 1);
+ else
+ iowrite32_rep(info->current_cs, buf, len >> 2);
+}
+
+static int davinci_nand_exec_instr(struct davinci_nand_info *info,
+ const struct nand_op_instr *instr)
+{
+ unsigned int i, timeout_us;
+ u32 status;
+ int ret;
+
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ iowrite8(instr->ctx.cmd.opcode,
+ info->current_cs + info->mask_cle);
+ break;
+
+ case NAND_OP_ADDR_INSTR:
+ for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+ iowrite8(instr->ctx.addr.addrs[i],
+ info->current_cs + info->mask_ale);
}
+ break;
+
+ case NAND_OP_DATA_IN_INSTR:
+ nand_davinci_data_in(info, instr->ctx.data.buf.in,
+ instr->ctx.data.len,
+ instr->ctx.data.force_8bit);
+ break;
+
+ case NAND_OP_DATA_OUT_INSTR:
+ nand_davinci_data_out(info, instr->ctx.data.buf.out,
+ instr->ctx.data.len,
+ instr->ctx.data.force_8bit);
+ break;
+
+ case NAND_OP_WAITRDY_INSTR:
+ timeout_us = instr->ctx.waitrdy.timeout_ms * 1000;
+ ret = readl_relaxed_poll_timeout(info->base + NANDFSR_OFFSET,
+ status, status & BIT(0), 100,
+ timeout_us);
+ if (ret)
+ return ret;
+
+ break;
}
- return ret;
+ if (instr->delay_ns)
+ ndelay(instr->delay_ns);
+
+ return 0;
+}
+
+static int davinci_nand_exec_op(struct nand_chip *chip,
+ const struct nand_operation *op,
+ bool check_only)
+{
+ struct davinci_nand_info *info = to_davinci_nand(nand_to_mtd(chip));
+ unsigned int i;
+
+ if (check_only)
+ return 0;
+
+ info->current_cs = info->vaddr + (op->cs * info->mask_chipsel);
+
+ for (i = 0; i < op->ninstrs; i++) {
+ int ret;
+
+ ret = davinci_nand_exec_instr(info, &op->instrs[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static const struct nand_controller_ops davinci_nand_controller_ops = {
.attach_chip = davinci_nand_attach_chip,
+ .exec_op = davinci_nand_exec_op,
};
static int nand_davinci_probe(struct platform_device *pdev)
@@ -746,11 +833,6 @@ static int nand_davinci_probe(struct platform_device *pdev)
mtd->dev.parent = &pdev->dev;
nand_set_flash_node(&info->chip, pdev->dev.of_node);
- info->chip.legacy.IO_ADDR_R = vaddr;
- info->chip.legacy.IO_ADDR_W = vaddr;
- info->chip.legacy.chip_delay = 0;
- info->chip.legacy.select_chip = nand_davinci_select_chip;
-
/* options such as NAND_BBT_USE_FLASH */
info->chip.bbt_options = pdata->bbt_options;
/* options such as 16-bit widths */
@@ -767,14 +849,6 @@ static int nand_davinci_probe(struct platform_device *pdev)
info->mask_ale = pdata->mask_ale ? : MASK_ALE;
info->mask_cle = pdata->mask_cle ? : MASK_CLE;
- /* Set address of hardware control function */
- info->chip.legacy.cmd_ctrl = nand_davinci_hwcontrol;
- info->chip.legacy.dev_ready = nand_davinci_dev_ready;
-
- /* Speed up buffer I/O */
- info->chip.legacy.read_buf = nand_davinci_read_buf;
- info->chip.legacy.write_buf = nand_davinci_write_buf;
-
/* Use board-specific ECC config */
info->chip.ecc.mode = pdata->ecc_mode;
@@ -788,7 +862,9 @@ static int nand_davinci_probe(struct platform_device *pdev)
spin_unlock_irq(&davinci_nand_lock);
/* Scan to find existence of the device(s) */
- info->chip.legacy.dummy_controller.ops = &davinci_nand_controller_ops;
+ nand_controller_init(&info->controller);
+ info->controller.ops = &davinci_nand_controller_ops;
+ info->chip.controller = &info->controller;
ret = nand_scan(&info->chip, pdata->mask_chipsel ? 2 : 1);
if (ret < 0) {
dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
@@ -817,13 +893,17 @@ err_cleanup_nand:
static int nand_davinci_remove(struct platform_device *pdev)
{
struct davinci_nand_info *info = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &info->chip;
+ int ret;
spin_lock_irq(&davinci_nand_lock);
if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME)
ecc4_busy = false;
spin_unlock_irq(&davinci_nand_lock);
- nand_release(&info->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
return 0;
}
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 6a6c919b2569..4e6e1578aa2d 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -764,6 +764,7 @@ static int denali_write_page(struct nand_chip *chip, const u8 *buf,
static int denali_setup_data_interface(struct nand_chip *chip, int chipnr,
const struct nand_data_interface *conf)
{
+ static const unsigned int data_setup_on_host = 10000;
struct denali_controller *denali = to_denali_controller(chip);
struct denali_chip_sel *sel;
const struct nand_sdr_timings *timings;
@@ -796,15 +797,6 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr,
sel = &to_denali_chip(chip)->sels[chipnr];
- /* tREA -> ACC_CLKS */
- acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x);
- acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
-
- tmp = ioread32(denali->reg + ACC_CLKS);
- tmp &= ~ACC_CLKS__VALUE;
- tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
- sel->acc_clks = tmp;
-
/* tRWH -> RE_2_WE */
re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x);
re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE);
@@ -862,14 +854,45 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr,
tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi);
sel->rdwr_en_hi_cnt = tmp;
- /* tRP, tWP -> RDWR_EN_LO_CNT */
+ /*
+ * tREA -> ACC_CLKS
+ * tRP, tWP, tRHOH, tRC, tWC -> RDWR_EN_LO_CNT
+ */
+
+ /*
+ * Determine the minimum of acc_clks to meet the setup timing when
+ * capturing the incoming data.
+ *
+ * The delay on the chip side is well-defined as tREA, but we need to
+ * take additional delay into account. This includes a certain degree
+ * of unknowledge, such as signal propagation delays on the PCB and
+ * in the SoC, load capacity of the I/O pins, etc.
+ */
+ acc_clks = DIV_ROUND_UP(timings->tREA_max + data_setup_on_host, t_x);
+
+ /* Determine the minimum of rdwr_en_lo_cnt from RE#/WE# pulse width */
rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x);
+
+ /* Extend rdwr_en_lo to meet the data hold timing */
+ rdwr_en_lo = max_t(int, rdwr_en_lo,
+ acc_clks - timings->tRHOH_min / t_x);
+
+ /* Extend rdwr_en_lo to meet the requirement for RE#/WE# cycle time */
rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min),
t_x);
- rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x);
rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi);
rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE);
+ /* Center the data latch timing for extra safety */
+ acc_clks = (acc_clks + rdwr_en_lo +
+ DIV_ROUND_UP(timings->tRHOH_min, t_x)) / 2;
+ acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
+
+ tmp = ioread32(denali->reg + ACC_CLKS);
+ tmp &= ~ACC_CLKS__VALUE;
+ tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
+ sel->acc_clks = tmp;
+
tmp = ioread32(denali->reg + RDWR_EN_LO_CNT);
tmp &= ~RDWR_EN_LO_CNT__VALUE;
tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo);
@@ -1203,7 +1226,7 @@ int denali_chip_init(struct denali_controller *denali,
mtd->name = "denali-nand";
if (denali->dma_avail) {
- chip->options |= NAND_USE_BOUNCE_BUFFER;
+ chip->options |= NAND_USES_DMA;
chip->buf_align = 16;
}
@@ -1336,10 +1359,17 @@ EXPORT_SYMBOL(denali_init);
void denali_remove(struct denali_controller *denali)
{
- struct denali_chip *dchip;
+ struct denali_chip *dchip, *tmp;
+ struct nand_chip *chip;
+ int ret;
- list_for_each_entry(dchip, &denali->chips, node)
- nand_release(&dchip->chip);
+ list_for_each_entry_safe(dchip, tmp, &denali->chips, node) {
+ chip = &dchip->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ list_del(&dchip->node);
+ }
denali_disable_irq(denali);
}
diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
index c2a391ad2c35..43721863a0d8 100644
--- a/drivers/mtd/nand/raw/diskonchip.c
+++ b/drivers/mtd/nand/raw/diskonchip.c
@@ -58,6 +58,7 @@ static unsigned long doc_locations[] __initdata = {
static struct mtd_info *doclist = NULL;
struct doc_priv {
+ struct nand_controller base;
void __iomem *virtadr;
unsigned long physadr;
u_char ChipID;
@@ -69,6 +70,7 @@ struct doc_priv {
int mh1_page;
struct rs_control *rs_decoder;
struct mtd_info *nextdoc;
+ bool supports_32b_reads;
/* Handle the last stage of initialization (BBT scan, partitioning) */
int (*late_init)(struct mtd_info *mtd);
@@ -84,10 +86,6 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
-static void doc200x_hwcontrol(struct nand_chip *this, int cmd,
- unsigned int bitmask);
-static void doc200x_select_chip(struct nand_chip *this, int chip);
-
static int debug = 0;
module_param(debug, int, 0);
@@ -302,20 +300,6 @@ static void doc2000_write_byte(struct nand_chip *this, u_char datum)
WriteDOC(datum, docptr, 2k_CDSN_IO);
}
-static u_char doc2000_read_byte(struct nand_chip *this)
-{
- struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
- u_char ret;
-
- ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- ret = ReadDOC(docptr, 2k_CDSN_IO);
- if (debug)
- printk("read_byte returns %02x\n", ret);
- return ret;
-}
-
static void doc2000_writebuf(struct nand_chip *this, const u_char *buf,
int len)
{
@@ -337,33 +321,42 @@ static void doc2000_readbuf(struct nand_chip *this, u_char *buf, int len)
{
struct doc_priv *doc = nand_get_controller_data(this);
void __iomem *docptr = doc->virtadr;
+ u32 *buf32 = (u32 *)buf;
int i;
if (debug)
printk("readbuf of %d bytes: ", len);
- for (i = 0; i < len; i++)
- buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
+ if (!doc->supports_32b_reads ||
+ ((((unsigned long)buf) | len) & 3)) {
+ for (i = 0; i < len; i++)
+ buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
+ } else {
+ for (i = 0; i < len / 4; i++)
+ buf32[i] = readl(docptr + DoC_2k_CDSN_IO + i);
+ }
}
-static void doc2000_readbuf_dword(struct nand_chip *this, u_char *buf, int len)
+/*
+ * We need our own readid() here because it's called before the NAND chip
+ * has been initialized, and calling nand_op_readid() would lead to a NULL
+ * pointer exception when dereferencing the NAND timings.
+ */
+static void doc200x_readid(struct nand_chip *this, unsigned int cs, u8 *id)
{
- struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
- int i;
+ u8 addr = 0;
+ struct nand_op_instr instrs[] = {
+ NAND_OP_CMD(NAND_CMD_READID, 0),
+ NAND_OP_ADDR(1, &addr, 50),
+ NAND_OP_8BIT_DATA_IN(2, id, 0),
+ };
- if (debug)
- printk("readbuf_dword of %d bytes: ", len);
+ struct nand_operation op = NAND_OPERATION(cs, instrs);
- if (unlikely((((unsigned long)buf) | len) & 3)) {
- for (i = 0; i < len; i++) {
- *(uint8_t *) (&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
- }
- } else {
- for (i = 0; i < len; i += 4) {
- *(uint32_t *) (&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
- }
- }
+ if (!id)
+ op.ninstrs--;
+
+ this->controller->ops->exec_op(this, &op, false);
}
static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
@@ -371,20 +364,11 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
struct nand_chip *this = mtd_to_nand(mtd);
struct doc_priv *doc = nand_get_controller_data(this);
uint16_t ret;
+ u8 id[2];
- doc200x_select_chip(this, nr);
- doc200x_hwcontrol(this, NAND_CMD_READID,
- NAND_CTRL_CLE | NAND_CTRL_CHANGE);
- doc200x_hwcontrol(this, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
- doc200x_hwcontrol(this, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+ doc200x_readid(this, nr, id);
- /* We can't use dev_ready here, but at least we wait for the
- * command to complete
- */
- udelay(50);
-
- ret = this->legacy.read_byte(this) << 8;
- ret |= this->legacy.read_byte(this);
+ ret = ((u16)id[0] << 8) | id[1];
if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) {
/* First chip probe. See if we get same results by 32-bit access */
@@ -394,18 +378,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
} ident;
void __iomem *docptr = doc->virtadr;
- doc200x_hwcontrol(this, NAND_CMD_READID,
- NAND_CTRL_CLE | NAND_CTRL_CHANGE);
- doc200x_hwcontrol(this, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
- doc200x_hwcontrol(this, NAND_CMD_NONE,
- NAND_NCE | NAND_CTRL_CHANGE);
-
- udelay(50);
+ doc200x_readid(this, nr, NULL);
ident.dword = readl(docptr + DoC_2k_CDSN_IO);
if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
pr_info("DiskOnChip 2000 responds to DWORD access\n");
- this->legacy.read_buf = &doc2000_readbuf_dword;
+ doc->supports_32b_reads = true;
}
}
@@ -434,20 +412,6 @@ static void __init doc2000_count_chips(struct mtd_info *mtd)
pr_debug("Detected %d chips per floor.\n", i);
}
-static int doc200x_wait(struct nand_chip *this)
-{
- struct doc_priv *doc = nand_get_controller_data(this);
-
- int status;
-
- DoC_WaitReady(doc);
- nand_status_op(this, NULL);
- DoC_WaitReady(doc);
- status = (int)this->legacy.read_byte(this);
-
- return status;
-}
-
static void doc2001_write_byte(struct nand_chip *this, u_char datum)
{
struct doc_priv *doc = nand_get_controller_data(this);
@@ -458,19 +422,6 @@ static void doc2001_write_byte(struct nand_chip *this, u_char datum)
WriteDOC(datum, docptr, WritePipeTerm);
}
-static u_char doc2001_read_byte(struct nand_chip *this)
-{
- struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
-
- //ReadDOC(docptr, CDSNSlowIO);
- /* 11.4.5 -- delay twice to allow extended length cycle */
- DoC_Delay(doc, 2);
- ReadDOC(docptr, ReadPipeInit);
- //return ReadDOC(docptr, Mil_CDSN_IO);
- return ReadDOC(docptr, LastDataRead);
-}
-
static void doc2001_writebuf(struct nand_chip *this, const u_char *buf, int len)
{
struct doc_priv *doc = nand_get_controller_data(this);
@@ -499,20 +450,6 @@ static void doc2001_readbuf(struct nand_chip *this, u_char *buf, int len)
buf[i] = ReadDOC(docptr, LastDataRead);
}
-static u_char doc2001plus_read_byte(struct nand_chip *this)
-{
- struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
- u_char ret;
-
- ReadDOC(docptr, Mplus_ReadPipeInit);
- ReadDOC(docptr, Mplus_ReadPipeInit);
- ret = ReadDOC(docptr, Mplus_LastDataRead);
- if (debug)
- printk("read_byte returns %02x\n", ret);
- return ret;
-}
-
static void doc2001plus_writebuf(struct nand_chip *this, const u_char *buf, int len)
{
struct doc_priv *doc = nand_get_controller_data(this);
@@ -550,9 +487,12 @@ static void doc2001plus_readbuf(struct nand_chip *this, u_char *buf, int len)
}
/* Terminate read pipeline */
- buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead);
- if (debug && i < 16)
- printk("%02x ", buf[len - 2]);
+ if (len >= 2) {
+ buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug && i < 16)
+ printk("%02x ", buf[len - 2]);
+ }
+
buf[len - 1] = ReadDOC(docptr, Mplus_LastDataRead);
if (debug && i < 16)
printk("%02x ", buf[len - 1]);
@@ -560,226 +500,163 @@ static void doc2001plus_readbuf(struct nand_chip *this, u_char *buf, int len)
printk("\n");
}
-static void doc2001plus_select_chip(struct nand_chip *this, int chip)
+static void doc200x_write_control(struct doc_priv *doc, u8 value)
+{
+ WriteDOC(value, doc->virtadr, CDSNControl);
+ /* 11.4.3 -- 4 NOPs after CSDNControl write */
+ DoC_Delay(doc, 4);
+}
+
+static void doc200x_exec_instr(struct nand_chip *this,
+ const struct nand_op_instr *instr)
{
struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
- int floor = 0;
+ unsigned int i;
- if (debug)
- printk("select chip (%d)\n", chip);
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ doc200x_write_control(doc, CDSN_CTRL_CE | CDSN_CTRL_CLE);
+ doc2000_write_byte(this, instr->ctx.cmd.opcode);
+ break;
- if (chip == -1) {
- /* Disable flash internally */
- WriteDOC(0, docptr, Mplus_FlashSelect);
- return;
- }
+ case NAND_OP_ADDR_INSTR:
+ doc200x_write_control(doc, CDSN_CTRL_CE | CDSN_CTRL_ALE);
+ for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+ u8 addr = instr->ctx.addr.addrs[i];
- floor = chip / doc->chips_per_floor;
- chip -= (floor * doc->chips_per_floor);
+ if (DoC_is_2000(doc))
+ doc2000_write_byte(this, addr);
+ else
+ doc2001_write_byte(this, addr);
+ }
+ break;
- /* Assert ChipEnable and deassert WriteProtect */
- WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
- nand_reset_op(this);
+ case NAND_OP_DATA_IN_INSTR:
+ doc200x_write_control(doc, CDSN_CTRL_CE);
+ if (DoC_is_2000(doc))
+ doc2000_readbuf(this, instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ else
+ doc2001_readbuf(this, instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ break;
- doc->curchip = chip;
- doc->curfloor = floor;
+ case NAND_OP_DATA_OUT_INSTR:
+ doc200x_write_control(doc, CDSN_CTRL_CE);
+ if (DoC_is_2000(doc))
+ doc2000_writebuf(this, instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ else
+ doc2001_writebuf(this, instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ break;
+
+ case NAND_OP_WAITRDY_INSTR:
+ DoC_WaitReady(doc);
+ break;
+ }
+
+ if (instr->delay_ns)
+ ndelay(instr->delay_ns);
}
-static void doc200x_select_chip(struct nand_chip *this, int chip)
+static int doc200x_exec_op(struct nand_chip *this,
+ const struct nand_operation *op,
+ bool check_only)
{
struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
- int floor = 0;
+ unsigned int i;
- if (debug)
- printk("select chip (%d)\n", chip);
+ if (check_only)
+ return true;
- if (chip == -1)
- return;
+ doc->curchip = op->cs % doc->chips_per_floor;
+ doc->curfloor = op->cs / doc->chips_per_floor;
- floor = chip / doc->chips_per_floor;
- chip -= (floor * doc->chips_per_floor);
+ WriteDOC(doc->curfloor, doc->virtadr, FloorSelect);
+ WriteDOC(doc->curchip, doc->virtadr, CDSNDeviceSelect);
- /* 11.4.4 -- deassert CE before changing chip */
- doc200x_hwcontrol(this, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+ /* Assert CE pin */
+ doc200x_write_control(doc, CDSN_CTRL_CE);
- WriteDOC(floor, docptr, FloorSelect);
- WriteDOC(chip, docptr, CDSNDeviceSelect);
+ for (i = 0; i < op->ninstrs; i++)
+ doc200x_exec_instr(this, &op->instrs[i]);
- doc200x_hwcontrol(this, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+ /* De-assert CE pin */
+ doc200x_write_control(doc, 0);
- doc->curchip = chip;
- doc->curfloor = floor;
+ return 0;
}
-#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE)
-
-static void doc200x_hwcontrol(struct nand_chip *this, int cmd,
- unsigned int ctrl)
+static void doc2001plus_write_pipe_term(struct doc_priv *doc)
{
- struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
-
- if (ctrl & NAND_CTRL_CHANGE) {
- doc->CDSNControl &= ~CDSN_CTRL_MSK;
- doc->CDSNControl |= ctrl & CDSN_CTRL_MSK;
- if (debug)
- printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
- WriteDOC(doc->CDSNControl, docptr, CDSNControl);
- /* 11.4.3 -- 4 NOPs after CSDNControl write */
- DoC_Delay(doc, 4);
- }
- if (cmd != NAND_CMD_NONE) {
- if (DoC_is_2000(doc))
- doc2000_write_byte(this, cmd);
- else
- doc2001_write_byte(this, cmd);
- }
+ WriteDOC(0x00, doc->virtadr, Mplus_WritePipeTerm);
+ WriteDOC(0x00, doc->virtadr, Mplus_WritePipeTerm);
}
-static void doc2001plus_command(struct nand_chip *this, unsigned command,
- int column, int page_addr)
+static void doc2001plus_exec_instr(struct nand_chip *this,
+ const struct nand_op_instr *instr)
{
- struct mtd_info *mtd = nand_to_mtd(this);
struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
+ unsigned int i;
- /*
- * Must terminate write pipeline before sending any commands
- * to the device.
- */
- if (command == NAND_CMD_PAGEPROG) {
- WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
- WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
- }
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ WriteDOC(instr->ctx.cmd.opcode, doc->virtadr, Mplus_FlashCmd);
+ doc2001plus_write_pipe_term(doc);
+ break;
- /*
- * Write out the command to the device.
- */
- if (command == NAND_CMD_SEQIN) {
- int readcmd;
-
- if (column >= mtd->writesize) {
- /* OOB area */
- column -= mtd->writesize;
- readcmd = NAND_CMD_READOOB;
- } else if (column < 256) {
- /* First 256 bytes --> READ0 */
- readcmd = NAND_CMD_READ0;
- } else {
- column -= 256;
- readcmd = NAND_CMD_READ1;
- }
- WriteDOC(readcmd, docptr, Mplus_FlashCmd);
- }
- WriteDOC(command, docptr, Mplus_FlashCmd);
- WriteDOC(0, docptr, Mplus_WritePipeTerm);
- WriteDOC(0, docptr, Mplus_WritePipeTerm);
-
- if (column != -1 || page_addr != -1) {
- /* Serially input address */
- if (column != -1) {
- /* Adjust columns for 16 bit buswidth */
- if (this->options & NAND_BUSWIDTH_16 &&
- !nand_opcode_8bits(command))
- column >>= 1;
- WriteDOC(column, docptr, Mplus_FlashAddress);
- }
- if (page_addr != -1) {
- WriteDOC((unsigned char)(page_addr & 0xff), docptr, Mplus_FlashAddress);
- WriteDOC((unsigned char)((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
- if (this->options & NAND_ROW_ADDR_3) {
- WriteDOC((unsigned char)((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
- printk("high density\n");
- }
+ case NAND_OP_ADDR_INSTR:
+ for (i = 0; i < instr->ctx.addr.naddrs; i++) {
+ u8 addr = instr->ctx.addr.addrs[i];
+
+ WriteDOC(addr, doc->virtadr, Mplus_FlashAddress);
}
- WriteDOC(0, docptr, Mplus_WritePipeTerm);
- WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ doc2001plus_write_pipe_term(doc);
/* deassert ALE */
- if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
- command == NAND_CMD_READOOB || command == NAND_CMD_READID)
- WriteDOC(0, docptr, Mplus_FlashControl);
- }
-
- /*
- * program and erase have their own busy handlers
- * status and sequential in needs no delay
- */
- switch (command) {
-
- case NAND_CMD_PAGEPROG:
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- case NAND_CMD_SEQIN:
- case NAND_CMD_STATUS:
- return;
+ WriteDOC(0, doc->virtadr, Mplus_FlashControl);
+ break;
- case NAND_CMD_RESET:
- if (this->legacy.dev_ready)
- break;
- udelay(this->legacy.chip_delay);
- WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
- WriteDOC(0, docptr, Mplus_WritePipeTerm);
- WriteDOC(0, docptr, Mplus_WritePipeTerm);
- while (!(this->legacy.read_byte(this) & 0x40)) ;
- return;
-
- /* This applies to read commands */
- default:
- /*
- * If we don't have access to the busy pin, we apply the given
- * command delay
- */
- if (!this->legacy.dev_ready) {
- udelay(this->legacy.chip_delay);
- return;
- }
+ case NAND_OP_DATA_IN_INSTR:
+ doc2001plus_readbuf(this, instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ break;
+ case NAND_OP_DATA_OUT_INSTR:
+ doc2001plus_writebuf(this, instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ doc2001plus_write_pipe_term(doc);
+ break;
+ case NAND_OP_WAITRDY_INSTR:
+ DoC_WaitReady(doc);
+ break;
}
- /* Apply this short delay always to ensure that we do wait tWB in
- * any case on any machine. */
- ndelay(100);
- /* wait until command is processed */
- while (!this->legacy.dev_ready(this)) ;
+ if (instr->delay_ns)
+ ndelay(instr->delay_ns);
}
-static int doc200x_dev_ready(struct nand_chip *this)
+static int doc2001plus_exec_op(struct nand_chip *this,
+ const struct nand_operation *op,
+ bool check_only)
{
struct doc_priv *doc = nand_get_controller_data(this);
- void __iomem *docptr = doc->virtadr;
+ unsigned int i;
- if (DoC_is_MillenniumPlus(doc)) {
- /* 11.4.2 -- must NOP four times before checking FR/B# */
- DoC_Delay(doc, 4);
- if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
- if (debug)
- printk("not ready\n");
- return 0;
- }
- if (debug)
- printk("was ready\n");
- return 1;
- } else {
- /* 11.4.2 -- must NOP four times before checking FR/B# */
- DoC_Delay(doc, 4);
- if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
- if (debug)
- printk("not ready\n");
- return 0;
- }
- /* 11.4.2 -- Must NOP twice if it's ready */
- DoC_Delay(doc, 2);
- if (debug)
- printk("was ready\n");
- return 1;
- }
-}
+ if (check_only)
+ return true;
+
+ doc->curchip = op->cs % doc->chips_per_floor;
+ doc->curfloor = op->cs / doc->chips_per_floor;
+
+ /* Assert ChipEnable and deassert WriteProtect */
+ WriteDOC(DOC_FLASH_CE, doc->virtadr, Mplus_FlashSelect);
+
+ for (i = 0; i < op->ninstrs; i++)
+ doc2001plus_exec_instr(this, &op->instrs[i]);
+
+ /* De-assert ChipEnable */
+ WriteDOC(0, doc->virtadr, Mplus_FlashSelect);
-static int doc200x_block_bad(struct nand_chip *this, loff_t ofs)
-{
- /* This is our last resort if we couldn't find or create a BBT. Just
- pretend all blocks are good. */
return 0;
}
@@ -1344,9 +1221,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd)
struct nand_chip *this = mtd_to_nand(mtd);
struct doc_priv *doc = nand_get_controller_data(this);
- this->legacy.read_byte = doc2000_read_byte;
- this->legacy.write_buf = doc2000_writebuf;
- this->legacy.read_buf = doc2000_readbuf;
doc->late_init = nftl_scan_bbt;
doc->CDSNControl = CDSN_CTRL_FLASH_IO | CDSN_CTRL_ECC_IO;
@@ -1360,10 +1234,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
struct nand_chip *this = mtd_to_nand(mtd);
struct doc_priv *doc = nand_get_controller_data(this);
- this->legacy.read_byte = doc2001_read_byte;
- this->legacy.write_buf = doc2001_writebuf;
- this->legacy.read_buf = doc2001_readbuf;
-
ReadDOC(doc->virtadr, ChipID);
ReadDOC(doc->virtadr, ChipID);
ReadDOC(doc->virtadr, ChipID);
@@ -1390,13 +1260,7 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
struct nand_chip *this = mtd_to_nand(mtd);
struct doc_priv *doc = nand_get_controller_data(this);
- this->legacy.read_byte = doc2001plus_read_byte;
- this->legacy.write_buf = doc2001plus_writebuf;
- this->legacy.read_buf = doc2001plus_readbuf;
doc->late_init = inftl_scan_bbt;
- this->legacy.cmd_ctrl = NULL;
- this->legacy.select_chip = doc2001plus_select_chip;
- this->legacy.cmdfunc = doc2001plus_command;
this->ecc.hwctl = doc2001plus_enable_hwecc;
doc->chips_per_floor = 1;
@@ -1405,6 +1269,14 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
return 1;
}
+static const struct nand_controller_ops doc200x_ops = {
+ .exec_op = doc200x_exec_op,
+};
+
+static const struct nand_controller_ops doc2001plus_ops = {
+ .exec_op = doc2001plus_exec_op,
+};
+
static int __init doc_probe(unsigned long physadr)
{
struct nand_chip *nand = NULL;
@@ -1548,7 +1420,6 @@ static int __init doc_probe(unsigned long physadr)
goto fail;
}
-
/*
* Allocate a RS codec instance
*
@@ -1566,6 +1437,12 @@ static int __init doc_probe(unsigned long physadr)
goto fail;
}
+ nand_controller_init(&doc->base);
+ if (ChipID == DOC_ChipID_DocMilPlus16)
+ doc->base.ops = &doc2001plus_ops;
+ else
+ doc->base.ops = &doc200x_ops;
+
mtd = nand_to_mtd(nand);
nand->bbt_td = (struct nand_bbt_descr *) (doc + 1);
nand->bbt_md = nand->bbt_td + 1;
@@ -1573,12 +1450,8 @@ static int __init doc_probe(unsigned long physadr)
mtd->owner = THIS_MODULE;
mtd_set_ooblayout(mtd, &doc200x_ooblayout_ops);
+ nand->controller = &doc->base;
nand_set_controller_data(nand, doc);
- nand->legacy.select_chip = doc200x_select_chip;
- nand->legacy.cmd_ctrl = doc200x_hwcontrol;
- nand->legacy.dev_ready = doc200x_dev_ready;
- nand->legacy.waitfunc = doc200x_wait;
- nand->legacy.block_bad = doc200x_block_bad;
nand->ecc.hwctl = doc200x_enable_hwecc;
nand->ecc.calculate = doc200x_calculate_ecc;
nand->ecc.correct = doc200x_correct_data;
@@ -1590,7 +1463,7 @@ static int __init doc_probe(unsigned long physadr)
nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK;
nand->bbt_options = NAND_BBT_USE_FLASH;
/* Skip the automatic BBT scan so we can run it manually */
- nand->options |= NAND_SKIP_BBTSCAN;
+ nand->options |= NAND_SKIP_BBTSCAN | NAND_NO_BBM_QUIRK;
doc->physadr = physadr;
doc->virtadr = virtadr;
@@ -1609,13 +1482,10 @@ static int __init doc_probe(unsigned long physadr)
numchips = doc2001_init(mtd);
if ((ret = nand_scan(nand, numchips)) || (ret = doc->late_init(mtd))) {
- /* DBB note: i believe nand_release is necessary here, as
+ /* DBB note: i believe nand_cleanup is necessary here, as
buffers may have been allocated in nand_base. Check with
Thomas. FIX ME! */
- /* nand_release will call mtd_device_unregister, but we
- haven't yet added it. This is handled without incident by
- mtd_device_unregister, as far as I can tell. */
- nand_release(nand);
+ nand_cleanup(nand);
goto fail;
}
@@ -1644,13 +1514,16 @@ static void release_nanddoc(void)
struct mtd_info *mtd, *nextmtd;
struct nand_chip *nand;
struct doc_priv *doc;
+ int ret;
for (mtd = doclist; mtd; mtd = nextmtd) {
nand = mtd_to_nand(mtd);
doc = nand_get_controller_data(nand);
nextmtd = doc->nextdoc;
- nand_release(nand);
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(nand);
iounmap(doc->virtadr);
release_mem_region(doc->physadr, DOC_IOREMAP_LEN);
free_rs(doc->rs_decoder);
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index e1dc675b12bb..088692b2e27a 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -956,8 +956,13 @@ static int fsl_elbc_nand_remove(struct platform_device *pdev)
{
struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand;
struct fsl_elbc_mtd *priv = dev_get_drvdata(&pdev->dev);
+ struct nand_chip *chip = &priv->chip;
+ int ret;
+
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
- nand_release(&priv->chip);
fsl_elbc_chip_remove(priv);
mutex_lock(&fsl_elbc_nand_mutex);
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index 2af09edf405b..00ae7a910b03 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -1093,8 +1093,13 @@ err:
static int fsl_ifc_nand_remove(struct platform_device *dev)
{
struct fsl_ifc_mtd *priv = dev_get_drvdata(&dev->dev);
+ struct nand_chip *chip = &priv->chip;
+ int ret;
+
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
- nand_release(&priv->chip);
fsl_ifc_chip_remove(priv);
mutex_lock(&fsl_ifc_nand_mutex);
diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c
index f31fae3a4c68..627deb26db51 100644
--- a/drivers/mtd/nand/raw/fsl_upm.c
+++ b/drivers/mtd/nand/raw/fsl_upm.c
@@ -317,10 +317,13 @@ err1:
static int fun_remove(struct platform_device *ofdev)
{
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
- struct mtd_info *mtd = nand_to_mtd(&fun->chip);
- int i;
+ struct nand_chip *chip = &fun->chip;
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ int ret, i;
- nand_release(&fun->chip);
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(chip);
kfree(mtd->name);
for (i = 0; i < fun->mchip_count; i++) {
diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
index a6964feeec77..3909752b14c5 100644
--- a/drivers/mtd/nand/raw/fsmc_nand.c
+++ b/drivers/mtd/nand/raw/fsmc_nand.c
@@ -608,6 +608,9 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op,
unsigned int op_id;
int i;
+ if (check_only)
+ return 0;
+
pr_debug("Executing operation [%d instructions]:\n", op->ninstrs);
for (op_id = 0; op_id < op->ninstrs; op_id++) {
@@ -691,7 +694,7 @@ static int fsmc_read_page_hwecc(struct nand_chip *chip, u8 *buf,
for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
nand_read_page_op(chip, page, s * eccsize, NULL, 0);
chip->ecc.hwctl(chip, NAND_ECC_READ);
- ret = nand_read_data_op(chip, p, eccsize, false);
+ ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret)
return ret;
@@ -809,11 +812,12 @@ static int fsmc_bch8_correct_data(struct nand_chip *chip, u8 *dat,
i = 0;
while (num_err--) {
- change_bit(0, (unsigned long *)&err_idx[i]);
- change_bit(1, (unsigned long *)&err_idx[i]);
+ err_idx[i] ^= 3;
if (err_idx[i] < chip->ecc.size * 8) {
- change_bit(err_idx[i], (unsigned long *)dat);
+ int err = err_idx[i];
+
+ dat[err >> 3] ^= BIT(err & 7);
i++;
}
}
@@ -1132,7 +1136,12 @@ static int fsmc_nand_remove(struct platform_device *pdev)
struct fsmc_nand_data *host = platform_get_drvdata(pdev);
if (host) {
- nand_release(&host->nand);
+ struct nand_chip *chip = &host->nand;
+ int ret;
+
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
fsmc_nand_disable(host);
if (host->mode == USE_DMA_ACCESS) {
diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c
index f6b12354024f..938077e5c6a9 100644
--- a/drivers/mtd/nand/raw/gpio.c
+++ b/drivers/mtd/nand/raw/gpio.c
@@ -190,8 +190,12 @@ gpio_nand_get_io_sync(struct platform_device *pdev)
static int gpio_nand_remove(struct platform_device *pdev)
{
struct gpiomtd *gpiomtd = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &gpiomtd->nand_chip;
+ int ret;
- nand_release(&gpiomtd->nand_chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
/* Enable write protection and disable the chip */
if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 53b00c841aec..061a8ddda275 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -540,8 +540,10 @@ static int bch_set_geometry(struct gpmi_nand_data *this)
return ret;
ret = pm_runtime_get_sync(this->dev);
- if (ret < 0)
+ if (ret < 0) {
+ pm_runtime_put_autosuspend(this->dev);
return ret;
+ }
/*
* Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this
@@ -834,158 +836,6 @@ map_fail:
return false;
}
-/**
- * gpmi_copy_bits - copy bits from one memory region to another
- * @dst: destination buffer
- * @dst_bit_off: bit offset we're starting to write at
- * @src: source buffer
- * @src_bit_off: bit offset we're starting to read from
- * @nbits: number of bits to copy
- *
- * This functions copies bits from one memory region to another, and is used by
- * the GPMI driver to copy ECC sections which are not guaranteed to be byte
- * aligned.
- *
- * src and dst should not overlap.
- *
- */
-static void gpmi_copy_bits(u8 *dst, size_t dst_bit_off, const u8 *src,
- size_t src_bit_off, size_t nbits)
-{
- size_t i;
- size_t nbytes;
- u32 src_buffer = 0;
- size_t bits_in_src_buffer = 0;
-
- if (!nbits)
- return;
-
- /*
- * Move src and dst pointers to the closest byte pointer and store bit
- * offsets within a byte.
- */
- src += src_bit_off / 8;
- src_bit_off %= 8;
-
- dst += dst_bit_off / 8;
- dst_bit_off %= 8;
-
- /*
- * Initialize the src_buffer value with bits available in the first
- * byte of data so that we end up with a byte aligned src pointer.
- */
- if (src_bit_off) {
- src_buffer = src[0] >> src_bit_off;
- if (nbits >= (8 - src_bit_off)) {
- bits_in_src_buffer += 8 - src_bit_off;
- } else {
- src_buffer &= GENMASK(nbits - 1, 0);
- bits_in_src_buffer += nbits;
- }
- nbits -= bits_in_src_buffer;
- src++;
- }
-
- /* Calculate the number of bytes that can be copied from src to dst. */
- nbytes = nbits / 8;
-
- /* Try to align dst to a byte boundary. */
- if (dst_bit_off) {
- if (bits_in_src_buffer < (8 - dst_bit_off) && nbytes) {
- src_buffer |= src[0] << bits_in_src_buffer;
- bits_in_src_buffer += 8;
- src++;
- nbytes--;
- }
-
- if (bits_in_src_buffer >= (8 - dst_bit_off)) {
- dst[0] &= GENMASK(dst_bit_off - 1, 0);
- dst[0] |= src_buffer << dst_bit_off;
- src_buffer >>= (8 - dst_bit_off);
- bits_in_src_buffer -= (8 - dst_bit_off);
- dst_bit_off = 0;
- dst++;
- if (bits_in_src_buffer > 7) {
- bits_in_src_buffer -= 8;
- dst[0] = src_buffer;
- dst++;
- src_buffer >>= 8;
- }
- }
- }
-
- if (!bits_in_src_buffer && !dst_bit_off) {
- /*
- * Both src and dst pointers are byte aligned, thus we can
- * just use the optimized memcpy function.
- */
- if (nbytes)
- memcpy(dst, src, nbytes);
- } else {
- /*
- * src buffer is not byte aligned, hence we have to copy each
- * src byte to the src_buffer variable before extracting a byte
- * to store in dst.
- */
- for (i = 0; i < nbytes; i++) {
- src_buffer |= src[i] << bits_in_src_buffer;
- dst[i] = src_buffer;
- src_buffer >>= 8;
- }
- }
- /* Update dst and src pointers */
- dst += nbytes;
- src += nbytes;
-
- /*
- * nbits is the number of remaining bits. It should not exceed 8 as
- * we've already copied as much bytes as possible.
- */
- nbits %= 8;
-
- /*
- * If there's no more bits to copy to the destination and src buffer
- * was already byte aligned, then we're done.
- */
- if (!nbits && !bits_in_src_buffer)
- return;
-
- /* Copy the remaining bits to src_buffer */
- if (nbits)
- src_buffer |= (*src & GENMASK(nbits - 1, 0)) <<
- bits_in_src_buffer;
- bits_in_src_buffer += nbits;
-
- /*
- * In case there were not enough bits to get a byte aligned dst buffer
- * prepare the src_buffer variable to match the dst organization (shift
- * src_buffer by dst_bit_off and retrieve the least significant bits
- * from dst).
- */
- if (dst_bit_off)
- src_buffer = (src_buffer << dst_bit_off) |
- (*dst & GENMASK(dst_bit_off - 1, 0));
- bits_in_src_buffer += dst_bit_off;
-
- /*
- * Keep most significant bits from dst if we end up with an unaligned
- * number of bits.
- */
- nbytes = bits_in_src_buffer / 8;
- if (bits_in_src_buffer % 8) {
- src_buffer |= (dst[nbytes] &
- GENMASK(7, bits_in_src_buffer % 8)) <<
- (nbytes * 8);
- nbytes++;
- }
-
- /* Copy the remaining bytes to dst */
- for (i = 0; i < nbytes; i++) {
- dst[i] = src_buffer;
- src_buffer >>= 8;
- }
-}
-
/* add our owner bbt descriptor */
static uint8_t scan_ff_pattern[] = { 0xff };
static struct nand_bbt_descr gpmi_bbt_descr = {
@@ -1713,7 +1563,7 @@ static int gpmi_ecc_write_oob(struct nand_chip *chip, int page)
* inline (interleaved with payload DATA), and do not align data chunk on
* byte boundaries.
* We thus need to take care moving the payload data and ECC bits stored in the
- * page into the provided buffers, which is why we're using gpmi_copy_bits.
+ * page into the provided buffers, which is why we're using nand_extract_bits().
*
* See set_geometry_by_ecc_info inline comments to have a full description
* of the layout used by the GPMI controller.
@@ -1762,9 +1612,8 @@ static int gpmi_ecc_read_page_raw(struct nand_chip *chip, uint8_t *buf,
/* Extract interleaved payload data and ECC bits */
for (step = 0; step < nfc_geo->ecc_chunk_count; step++) {
if (buf)
- gpmi_copy_bits(buf, step * eccsize * 8,
- tmp_buf, src_bit_off,
- eccsize * 8);
+ nand_extract_bits(buf, step * eccsize, tmp_buf,
+ src_bit_off, eccsize * 8);
src_bit_off += eccsize * 8;
/* Align last ECC block to align a byte boundary */
@@ -1773,9 +1622,8 @@ static int gpmi_ecc_read_page_raw(struct nand_chip *chip, uint8_t *buf,
eccbits += 8 - ((oob_bit_off + eccbits) % 8);
if (oob_required)
- gpmi_copy_bits(oob, oob_bit_off,
- tmp_buf, src_bit_off,
- eccbits);
+ nand_extract_bits(oob, oob_bit_off, tmp_buf,
+ src_bit_off, eccbits);
src_bit_off += eccbits;
oob_bit_off += eccbits;
@@ -1800,7 +1648,7 @@ static int gpmi_ecc_read_page_raw(struct nand_chip *chip, uint8_t *buf,
* inline (interleaved with payload DATA), and do not align data chunk on
* byte boundaries.
* We thus need to take care moving the OOB area at the right place in the
- * final page, which is why we're using gpmi_copy_bits.
+ * final page, which is why we're using nand_extract_bits().
*
* See set_geometry_by_ecc_info inline comments to have a full description
* of the layout used by the GPMI controller.
@@ -1839,8 +1687,8 @@ static int gpmi_ecc_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
/* Interleave payload data and ECC bits */
for (step = 0; step < nfc_geo->ecc_chunk_count; step++) {
if (buf)
- gpmi_copy_bits(tmp_buf, dst_bit_off,
- buf, step * eccsize * 8, eccsize * 8);
+ nand_extract_bits(tmp_buf, dst_bit_off, buf,
+ step * eccsize * 8, eccsize * 8);
dst_bit_off += eccsize * 8;
/* Align last ECC block to align a byte boundary */
@@ -1849,8 +1697,8 @@ static int gpmi_ecc_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
eccbits += 8 - ((oob_bit_off + eccbits) % 8);
if (oob_required)
- gpmi_copy_bits(tmp_buf, dst_bit_off,
- oob, oob_bit_off, eccbits);
+ nand_extract_bits(tmp_buf, dst_bit_off, oob,
+ oob_bit_off, eccbits);
dst_bit_off += eccbits;
oob_bit_off += eccbits;
@@ -2408,6 +2256,9 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip,
struct completion *completion;
unsigned long to;
+ if (check_only)
+ return 0;
+
this->ntransfers = 0;
for (i = 0; i < GPMI_MAX_TRANSFERS; i++)
this->transfers[i].direction = DMA_NONE;
@@ -2658,7 +2509,7 @@ static int gpmi_nand_probe(struct platform_device *pdev)
ret = __gpmi_enable_clk(this, true);
if (ret)
- goto exit_nfc_init;
+ goto exit_acquire_resources;
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
pm_runtime_use_autosuspend(&pdev->dev);
@@ -2693,11 +2544,15 @@ exit_acquire_resources:
static int gpmi_nand_remove(struct platform_device *pdev)
{
struct gpmi_nand_data *this = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &this->nand;
+ int ret;
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- nand_release(&this->nand);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
gpmi_free_dma_buffer(this);
release_resources(this);
return 0;
diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
index 0b48be54ba6f..b84238e2268a 100644
--- a/drivers/mtd/nand/raw/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -806,8 +806,12 @@ static int hisi_nfc_probe(struct platform_device *pdev)
static int hisi_nfc_remove(struct platform_device *pdev)
{
struct hinfc_host *host = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &host->chip;
+ int ret;
- nand_release(&host->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
return 0;
}
diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c
index 935c4902ada7..69423bb29adb 100644
--- a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c
+++ b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c
@@ -27,9 +27,6 @@
#define DRV_NAME "ingenic-nand"
-/* Command delay when there is no R/B pin. */
-#define RB_DELAY_US 100
-
struct jz_soc_info {
unsigned long data_offset;
unsigned long addr_offset;
@@ -49,7 +46,6 @@ struct ingenic_nfc {
struct nand_controller controller;
unsigned int num_banks;
struct list_head chips;
- int selected;
struct ingenic_nand_cs cs[];
};
@@ -102,7 +98,7 @@ static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section,
return 0;
}
-const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = {
+static const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = {
.ecc = qi_lb60_ooblayout_ecc,
.free = qi_lb60_ooblayout_free,
};
@@ -142,51 +138,6 @@ static const struct mtd_ooblayout_ops jz4725b_ooblayout_ops = {
.free = jz4725b_ooblayout_free,
};
-static void ingenic_nand_select_chip(struct nand_chip *chip, int chipnr)
-{
- struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip));
- struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller);
- struct ingenic_nand_cs *cs;
-
- /* Ensure the currently selected chip is deasserted. */
- if (chipnr == -1 && nfc->selected >= 0) {
- cs = &nfc->cs[nfc->selected];
- jz4780_nemc_assert(nfc->dev, cs->bank, false);
- }
-
- nfc->selected = chipnr;
-}
-
-static void ingenic_nand_cmd_ctrl(struct nand_chip *chip, int cmd,
- unsigned int ctrl)
-{
- struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip));
- struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller);
- struct ingenic_nand_cs *cs;
-
- if (WARN_ON(nfc->selected < 0))
- return;
-
- cs = &nfc->cs[nfc->selected];
-
- jz4780_nemc_assert(nfc->dev, cs->bank, ctrl & NAND_NCE);
-
- if (cmd == NAND_CMD_NONE)
- return;
-
- if (ctrl & NAND_ALE)
- writeb(cmd, cs->base + nfc->soc_info->addr_offset);
- else if (ctrl & NAND_CLE)
- writeb(cmd, cs->base + nfc->soc_info->cmd_offset);
-}
-
-static int ingenic_nand_dev_ready(struct nand_chip *chip)
-{
- struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip));
-
- return !gpiod_get_value_cansleep(nand->busy_gpio);
-}
-
static void ingenic_nand_ecc_hwctl(struct nand_chip *chip, int mode)
{
struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip));
@@ -298,8 +249,91 @@ static int ingenic_nand_attach_chip(struct nand_chip *chip)
return 0;
}
+static int ingenic_nand_exec_instr(struct nand_chip *chip,
+ struct ingenic_nand_cs *cs,
+ const struct nand_op_instr *instr)
+{
+ struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip));
+ struct ingenic_nfc *nfc = to_ingenic_nfc(chip->controller);
+ unsigned int i;
+
+ switch (instr->type) {
+ case NAND_OP_CMD_INSTR:
+ writeb(instr->ctx.cmd.opcode,
+ cs->base + nfc->soc_info->cmd_offset);
+ return 0;
+ case NAND_OP_ADDR_INSTR:
+ for (i = 0; i < instr->ctx.addr.naddrs; i++)
+ writeb(instr->ctx.addr.addrs[i],
+ cs->base + nfc->soc_info->addr_offset);
+ return 0;
+ case NAND_OP_DATA_IN_INSTR:
+ if (instr->ctx.data.force_8bit ||
+ !(chip->options & NAND_BUSWIDTH_16))
+ ioread8_rep(cs->base + nfc->soc_info->data_offset,
+ instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ else
+ ioread16_rep(cs->base + nfc->soc_info->data_offset,
+ instr->ctx.data.buf.in,
+ instr->ctx.data.len);
+ return 0;
+ case NAND_OP_DATA_OUT_INSTR:
+ if (instr->ctx.data.force_8bit ||
+ !(chip->options & NAND_BUSWIDTH_16))
+ iowrite8_rep(cs->base + nfc->soc_info->data_offset,
+ instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ else
+ iowrite16_rep(cs->base + nfc->soc_info->data_offset,
+ instr->ctx.data.buf.out,
+ instr->ctx.data.len);
+ return 0;
+ case NAND_OP_WAITRDY_INSTR:
+ if (!nand->busy_gpio)
+ return nand_soft_waitrdy(chip,
+ instr->ctx.waitrdy.timeout_ms);
+
+ return nand_gpio_waitrdy(chip, nand->busy_gpio,
+ instr->ctx.waitrdy.timeout_ms);
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ingenic_nand_exec_op(struct nand_chip *chip,
+ const struct nand_operation *op,
+ bool check_only)
+{
+ struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip));
+ struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller);
+ struct ingenic_nand_cs *cs;
+ unsigned int i;
+ int ret = 0;
+
+ if (check_only)
+ return 0;
+
+ cs = &nfc->cs[op->cs];
+ jz4780_nemc_assert(nfc->dev, cs->bank, true);
+ for (i = 0; i < op->ninstrs; i++) {
+ ret = ingenic_nand_exec_instr(chip, cs, &op->instrs[i]);
+ if (ret)
+ break;
+
+ if (op->instrs[i].delay_ns)
+ ndelay(op->instrs[i].delay_ns);
+ }
+ jz4780_nemc_assert(nfc->dev, cs->bank, false);
+
+ return ret;
+}
+
static const struct nand_controller_ops ingenic_nand_controller_ops = {
.attach_chip = ingenic_nand_attach_chip,
+ .exec_op = ingenic_nand_exec_op,
};
static int ingenic_nand_init_chip(struct platform_device *pdev,
@@ -339,10 +373,20 @@ static int ingenic_nand_init_chip(struct platform_device *pdev,
ret = PTR_ERR(nand->busy_gpio);
dev_err(dev, "failed to request busy GPIO: %d\n", ret);
return ret;
- } else if (nand->busy_gpio) {
- nand->chip.legacy.dev_ready = ingenic_nand_dev_ready;
}
+ /*
+ * The rb-gpios semantics was undocumented and qi,lb60 (along with
+ * the ingenic driver) got it wrong. The active state encodes the
+ * NAND ready state, which is high level. Since there's no signal
+ * inverter on this board, it should be active-high. Let's fix that
+ * here for older DTs so we can re-use the generic nand_gpio_waitrdy()
+ * helper, and be consistent with what other drivers do.
+ */
+ if (of_machine_is_compatible("qi,lb60") &&
+ gpiod_is_active_low(nand->busy_gpio))
+ gpiod_toggle_active_low(nand->busy_gpio);
+
nand->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_LOW);
if (IS_ERR(nand->wp_gpio)) {
@@ -359,12 +403,7 @@ static int ingenic_nand_init_chip(struct platform_device *pdev,
return -ENOMEM;
mtd->dev.parent = dev;
- chip->legacy.IO_ADDR_R = cs->base + nfc->soc_info->data_offset;
- chip->legacy.IO_ADDR_W = cs->base + nfc->soc_info->data_offset;
- chip->legacy.chip_delay = RB_DELAY_US;
chip->options = NAND_NO_SUBPAGE_WRITE;
- chip->legacy.select_chip = ingenic_nand_select_chip;
- chip->legacy.cmd_ctrl = ingenic_nand_cmd_ctrl;
chip->ecc.mode = NAND_ECC_HW;
chip->controller = &nfc->controller;
nand_set_flash_node(chip, np);
@@ -376,7 +415,7 @@ static int ingenic_nand_init_chip(struct platform_device *pdev,
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
- nand_release(chip);
+ nand_cleanup(chip);
return ret;
}
@@ -387,13 +426,18 @@ static int ingenic_nand_init_chip(struct platform_device *pdev,
static void ingenic_nand_cleanup_chips(struct ingenic_nfc *nfc)
{
- struct ingenic_nand *chip;
+ struct ingenic_nand *ingenic_chip;
+ struct nand_chip *chip;
+ int ret;
while (!list_empty(&nfc->chips)) {
- chip = list_first_entry(&nfc->chips,
- struct ingenic_nand, chip_list);
- nand_release(&chip->chip);
- list_del(&chip->chip_list);
+ ingenic_chip = list_first_entry(&nfc->chips,
+ struct ingenic_nand, chip_list);
+ chip = &ingenic_chip->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ list_del(&ingenic_chip->chip_list);
}
}
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index 9d0caadf940e..03866b0aadea 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -75,6 +75,9 @@ extern const struct nand_manufacturer_ops micron_nand_manuf_ops;
extern const struct nand_manufacturer_ops samsung_nand_manuf_ops;
extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops;
+/* MLC pairing schemes */
+extern const struct mtd_pairing_scheme dist3_pairing_scheme;
+
/* Core functions */
const struct nand_manufacturer *nand_get_manufacturer(u8 id);
int nand_bbm_get_next_page(struct nand_chip *chip, int page);
@@ -106,6 +109,15 @@ static inline bool nand_has_exec_op(struct nand_chip *chip)
return true;
}
+static inline int nand_check_op(struct nand_chip *chip,
+ const struct nand_operation *op)
+{
+ if (!nand_has_exec_op(chip))
+ return 0;
+
+ return chip->controller->ops->exec_op(chip, op, true);
+}
+
static inline int nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op)
{
diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c
index 241b58b83240..7521038af2ef 100644
--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
@@ -826,8 +826,13 @@ free_gpio:
static int lpc32xx_nand_remove(struct platform_device *pdev)
{
struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &host->nand_chip;
+ int ret;
+
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
- nand_release(&host->nand_chip);
free_irq(host->irq, host);
if (use_dma)
dma_release_channel(host->dma_chan);
diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
index 163f976353f8..b151fd000815 100644
--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
@@ -947,8 +947,12 @@ static int lpc32xx_nand_remove(struct platform_device *pdev)
{
uint32_t tmp;
struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &host->nand_chip;
+ int ret;
- nand_release(&host->nand_chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
dma_release_channel(host->dma_chan);
/* Force CE high */
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index 179f0ca585f8..260a0430313e 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -707,7 +707,7 @@ static int marvell_nfc_wait_op(struct nand_chip *chip, unsigned int timeout_ms)
* In case the interrupt was not served in the required time frame,
* check if the ISR was not served or if something went actually wrong.
*/
- if (ret && !pending) {
+ if (!ret && !pending) {
dev_err(nfc->dev, "Timeout waiting for RB signal\n");
return -ETIMEDOUT;
}
@@ -932,14 +932,14 @@ static void marvell_nfc_check_empty_chunk(struct nand_chip *chip,
}
/*
- * Check a chunk is correct or not according to hardware ECC engine.
+ * Check if a chunk is correct or not according to the hardware ECC engine.
* mtd->ecc_stats.corrected is updated, as well as max_bitflips, however
* mtd->ecc_stats.failure is not, the function will instead return a non-zero
* value indicating that a check on the emptyness of the subpage must be
- * performed before declaring the subpage corrupted.
+ * performed before actually declaring the subpage as "corrupted".
*/
-static int marvell_nfc_hw_ecc_correct(struct nand_chip *chip,
- unsigned int *max_bitflips)
+static int marvell_nfc_hw_ecc_check_bitflips(struct nand_chip *chip,
+ unsigned int *max_bitflips)
{
struct mtd_info *mtd = nand_to_mtd(chip);
struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
@@ -1053,7 +1053,7 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct nand_chip *chip, u8 *buf,
marvell_nfc_enable_hw_ecc(chip);
marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi, false,
page);
- ret = marvell_nfc_hw_ecc_correct(chip, &max_bitflips);
+ ret = marvell_nfc_hw_ecc_check_bitflips(chip, &max_bitflips);
marvell_nfc_disable_hw_ecc(chip);
if (!ret)
@@ -1224,12 +1224,12 @@ static int marvell_nfc_hw_ecc_bch_read_page_raw(struct nand_chip *chip, u8 *buf,
/* Read spare bytes */
nand_read_data_op(chip, oob + (lt->spare_bytes * chunk),
- spare_len, false);
+ spare_len, false, false);
/* Read ECC bytes */
nand_read_data_op(chip, oob + ecc_offset +
(ALIGN(lt->ecc_bytes, 32) * chunk),
- ecc_len, false);
+ ecc_len, false, false);
}
return 0;
@@ -1336,7 +1336,7 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip,
/* Read the chunk and detect number of bitflips */
marvell_nfc_hw_ecc_bch_read_chunk(chip, chunk, data, data_len,
spare, spare_len, page);
- ret = marvell_nfc_hw_ecc_correct(chip, &max_bitflips);
+ ret = marvell_nfc_hw_ecc_check_bitflips(chip, &max_bitflips);
if (ret)
failure_mask |= BIT(chunk);
@@ -1358,10 +1358,9 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip,
*/
/*
- * In case there is any subpage read error reported by ->correct(), we
- * usually re-read only ECC bytes in raw mode and check if the whole
- * page is empty. In this case, it is normal that the ECC check failed
- * and we just ignore the error.
+ * In case there is any subpage read error, we usually re-read only ECC
+ * bytes in raw mode and check if the whole page is empty. In this case,
+ * it is normal that the ECC check failed and we just ignore the error.
*
* However, it has been empirically observed that for some layouts (e.g
* 2k page, 8b strength per 512B chunk), the controller tries to correct
@@ -2107,7 +2106,8 @@ static int marvell_nfc_exec_op(struct nand_chip *chip,
{
struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
- marvell_nfc_select_target(chip, op->cs);
+ if (!check_only)
+ marvell_nfc_select_target(chip, op->cs);
if (nfc->caps->is_nfcv2)
return nand_op_parser_exec_op(chip, &marvell_nfcv2_op_parser,
@@ -2166,8 +2166,8 @@ static const struct mtd_ooblayout_ops marvell_nand_ooblayout_ops = {
.free = marvell_nand_ooblayout_free,
};
-static int marvell_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
- struct nand_ecc_ctrl *ecc)
+static int marvell_nand_hw_ecc_controller_init(struct mtd_info *mtd,
+ struct nand_ecc_ctrl *ecc)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct marvell_nfc *nfc = to_marvell_nfc(chip->controller);
@@ -2261,7 +2261,7 @@ static int marvell_nand_ecc_init(struct mtd_info *mtd,
switch (ecc->mode) {
case NAND_ECC_HW:
- ret = marvell_nand_hw_ecc_ctrl_init(mtd, ecc);
+ ret = marvell_nand_hw_ecc_controller_init(mtd, ecc);
if (ret)
return ret;
break;
@@ -2664,7 +2664,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(dev, "failed to register mtd device: %d\n", ret);
- nand_release(chip);
+ nand_cleanup(chip);
return ret;
}
@@ -2673,6 +2673,21 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
return 0;
}
+static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc)
+{
+ struct marvell_nand_chip *entry, *temp;
+ struct nand_chip *chip;
+ int ret;
+
+ list_for_each_entry_safe(entry, temp, &nfc->chips, node) {
+ chip = &entry->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ list_del(&entry->node);
+ }
+}
+
static int marvell_nand_chips_init(struct device *dev, struct marvell_nfc *nfc)
{
struct device_node *np = dev->of_node;
@@ -2707,21 +2722,16 @@ static int marvell_nand_chips_init(struct device *dev, struct marvell_nfc *nfc)
ret = marvell_nand_chip_init(dev, nfc, nand_np);
if (ret) {
of_node_put(nand_np);
- return ret;
+ goto cleanup_chips;
}
}
return 0;
-}
-static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc)
-{
- struct marvell_nand_chip *entry, *temp;
+cleanup_chips:
+ marvell_nand_chips_cleanup(nfc);
- list_for_each_entry_safe(entry, temp, &nfc->chips, node) {
- nand_release(&entry->chip);
- list_del(&entry->node);
- }
+ return ret;
}
static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
@@ -2854,7 +2864,6 @@ static int marvell_nfc_init(struct marvell_nfc *nfc)
static int marvell_nfc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct resource *r;
struct marvell_nfc *nfc;
int ret;
int irq;
@@ -2869,8 +2878,7 @@ static int marvell_nfc_probe(struct platform_device *pdev)
nfc->controller.ops = &marvell_nand_controller_ops;
INIT_LIST_HEAD(&nfc->chips);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- nfc->regs = devm_ioremap_resource(dev, r);
+ nfc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(nfc->regs))
return PTR_ERR(nfc->regs);
diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index f6fb5c0e6255..3f376471f3f7 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -899,6 +899,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
u32 op_id, delay_idle, cmd;
int i;
+ if (check_only)
+ return 0;
+
meson_nfc_select_chip(nand, op->cs);
for (op_id = 0; op_id < op->ninstrs; op_id++) {
instr = &op->instrs[op_id];
@@ -1266,7 +1269,7 @@ meson_nfc_nand_chip_init(struct device *dev,
nand_set_flash_node(nand, np);
nand_set_controller_data(nand, nfc);
- nand->options |= NAND_USE_BOUNCE_BUFFER;
+ nand->options |= NAND_USES_DMA;
mtd = nand_to_mtd(nand);
mtd->owner = THIS_MODULE;
mtd->dev.parent = dev;
diff --git a/drivers/mtd/nand/raw/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c
index a2fcb739e5f8..18ecb096a32d 100644
--- a/drivers/mtd/nand/raw/mpc5121_nfc.c
+++ b/drivers/mtd/nand/raw/mpc5121_nfc.c
@@ -805,8 +805,11 @@ static int mpc5121_nfc_remove(struct platform_device *op)
{
struct device *dev = &op->dev;
struct mtd_info *mtd = dev_get_drvdata(dev);
+ int ret;
- nand_release(mtd_to_nand(mtd));
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(mtd_to_nand(mtd));
mpc5121_nfc_free(dev, mtd);
return 0;
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index ef149e8b26d0..c1a6e31aabb8 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1380,7 +1380,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
nand_set_flash_node(nand, np);
nand_set_controller_data(nand, nfc);
- nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_SUBPAGE_READ;
+ nand->options |= NAND_USES_DMA | NAND_SUBPAGE_READ;
nand->legacy.dev_ready = mtk_nfc_dev_ready;
nand->legacy.select_chip = mtk_nfc_select_chip;
nand->legacy.write_byte = mtk_nfc_write_byte;
@@ -1419,7 +1419,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(dev, "mtd parse partition error\n");
- nand_release(nand);
+ nand_cleanup(nand);
return ret;
}
@@ -1578,13 +1578,18 @@ release_ecc:
static int mtk_nfc_remove(struct platform_device *pdev)
{
struct mtk_nfc *nfc = platform_get_drvdata(pdev);
- struct mtk_nfc_nand_chip *chip;
+ struct mtk_nfc_nand_chip *mtk_chip;
+ struct nand_chip *chip;
+ int ret;
while (!list_empty(&nfc->chips)) {
- chip = list_first_entry(&nfc->chips, struct mtk_nfc_nand_chip,
- node);
- nand_release(&chip->nand);
- list_del(&chip->node);
+ mtk_chip = list_first_entry(&nfc->chips,
+ struct mtk_nfc_nand_chip, node);
+ chip = &mtk_chip->nand;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ list_del(&mtk_chip->node);
}
mtk_ecc_release(nfc->ecc);
diff --git a/drivers/mtd/nand/raw/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c
index 59554c187e01..09dacb83cb5a 100644
--- a/drivers/mtd/nand/raw/mxc_nand.c
+++ b/drivers/mtd/nand/raw/mxc_nand.c
@@ -1919,8 +1919,12 @@ escan:
static int mxcnd_remove(struct platform_device *pdev)
{
struct mxc_nand_host *host = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &host->nand;
+ int ret;
- nand_release(&host->nand);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
if (host->clk_act)
clk_disable_unprepare(host->clk);
diff --git a/drivers/mtd/nand/raw/mxic_nand.c b/drivers/mtd/nand/raw/mxic_nand.c
index ed7a4e021bf5..57f36721f4c6 100644
--- a/drivers/mtd/nand/raw/mxic_nand.c
+++ b/drivers/mtd/nand/raw/mxic_nand.c
@@ -393,6 +393,9 @@ static int mxic_nfc_exec_op(struct nand_chip *chip,
int ret = 0;
unsigned int op_id;
+ if (check_only)
+ return 0;
+
mxic_nfc_cs_enable(nfc);
init_completion(&nfc->complete);
for (op_id = 0; op_id < op->ninstrs; op_id++) {
@@ -553,8 +556,13 @@ fail:
static int mxic_nfc_remove(struct platform_device *pdev)
{
struct mxic_nand_ctlr *nfc = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &nfc->chip;
+ int ret;
+
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
- nand_release(&nfc->chip);
mxic_nfc_clk_disable(nfc);
return 0;
}
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index c24e5e2ba130..45124dbb1835 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -205,6 +205,56 @@ static const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = {
.free = nand_ooblayout_free_lp_hamming,
};
+static int nand_pairing_dist3_get_info(struct mtd_info *mtd, int page,
+ struct mtd_pairing_info *info)
+{
+ int lastpage = (mtd->erasesize / mtd->writesize) - 1;
+ int dist = 3;
+
+ if (page == lastpage)
+ dist = 2;
+
+ if (!page || (page & 1)) {
+ info->group = 0;
+ info->pair = (page + 1) / 2;
+ } else {
+ info->group = 1;
+ info->pair = (page + 1 - dist) / 2;
+ }
+
+ return 0;
+}
+
+static int nand_pairing_dist3_get_wunit(struct mtd_info *mtd,
+ const struct mtd_pairing_info *info)
+{
+ int lastpair = ((mtd->erasesize / mtd->writesize) - 1) / 2;
+ int page = info->pair * 2;
+ int dist = 3;
+
+ if (!info->group && !info->pair)
+ return 0;
+
+ if (info->pair == lastpair && info->group)
+ dist = 2;
+
+ if (!info->group)
+ page--;
+ else if (info->pair)
+ page += dist - 1;
+
+ if (page >= mtd->erasesize / mtd->writesize)
+ return -EINVAL;
+
+ return page;
+}
+
+const struct mtd_pairing_scheme dist3_pairing_scheme = {
+ .ngroups = 2,
+ .get_info = nand_pairing_dist3_get_info,
+ .get_wunit = nand_pairing_dist3_get_wunit,
+};
+
static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len)
{
int ret = 0;
@@ -225,6 +275,50 @@ static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len)
}
/**
+ * nand_extract_bits - Copy unaligned bits from one buffer to another one
+ * @dst: destination buffer
+ * @dst_off: bit offset at which the writing starts
+ * @src: source buffer
+ * @src_off: bit offset at which the reading starts
+ * @nbits: number of bits to copy from @src to @dst
+ *
+ * Copy bits from one memory region to another (overlap authorized).
+ */
+void nand_extract_bits(u8 *dst, unsigned int dst_off, const u8 *src,
+ unsigned int src_off, unsigned int nbits)
+{
+ unsigned int tmp, n;
+
+ dst += dst_off / 8;
+ dst_off %= 8;
+ src += src_off / 8;
+ src_off %= 8;
+
+ while (nbits) {
+ n = min3(8 - dst_off, 8 - src_off, nbits);
+
+ tmp = (*src >> src_off) & GENMASK(n - 1, 0);
+ *dst &= ~GENMASK(n - 1 + dst_off, dst_off);
+ *dst |= tmp << dst_off;
+
+ dst_off += n;
+ if (dst_off >= 8) {
+ dst++;
+ dst_off -= 8;
+ }
+
+ src_off += n;
+ if (src_off >= 8) {
+ src++;
+ src_off -= 8;
+ }
+
+ nbits -= n;
+ }
+}
+EXPORT_SYMBOL_GPL(nand_extract_bits);
+
+/**
* nand_select_target() - Select a NAND target (A.K.A. die)
* @chip: NAND chip object
* @cs: the CS line to select. Note that this CS id is always from the chip
@@ -345,6 +439,9 @@ static int nand_block_bad(struct nand_chip *chip, loff_t ofs)
static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
{
+ if (chip->options & NAND_NO_BBM_QUIRK)
+ return 0;
+
if (chip->legacy.block_bad)
return chip->legacy.block_bad(chip, ofs);
@@ -690,7 +787,8 @@ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)
*/
timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1;
do {
- ret = nand_read_data_op(chip, &status, sizeof(status), true);
+ ret = nand_read_data_op(chip, &status, sizeof(status), true,
+ false);
if (ret)
break;
@@ -736,8 +834,14 @@ EXPORT_SYMBOL_GPL(nand_soft_waitrdy);
int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod,
unsigned long timeout_ms)
{
- /* Wait until R/B pin indicates chip is ready or timeout occurs */
- timeout_ms = jiffies + msecs_to_jiffies(timeout_ms);
+
+ /*
+ * Wait until R/B pin indicates chip is ready or timeout occurs.
+ * +1 below is necessary because if we are now in the last fraction
+ * of jiffy and msecs_to_jiffies is 1 then we will wait only that
+ * small jiffy fraction - possibly leading to false timeout.
+ */
+ timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1;
do {
if (gpiod_get_value_cansleep(gpiod))
return 0;
@@ -770,7 +874,7 @@ void panic_nand_wait(struct nand_chip *chip, unsigned long timeo)
u8 status;
ret = nand_read_data_op(chip, &status, sizeof(status),
- true);
+ true, false);
if (ret)
return;
@@ -1868,6 +1972,8 @@ EXPORT_SYMBOL_GPL(nand_reset_op);
* @buf: buffer used to store the data
* @len: length of the buffer
* @force_8bit: force 8-bit bus access
+ * @check_only: do not actually run the command, only checks if the
+ * controller driver supports it
*
* This function does a raw data read on the bus. Usually used after launching
* another NAND operation like nand_read_page_op().
@@ -1876,7 +1982,7 @@ EXPORT_SYMBOL_GPL(nand_reset_op);
* Returns 0 on success, a negative error code otherwise.
*/
int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
- bool force_8bit)
+ bool force_8bit, bool check_only)
{
if (!len || !buf)
return -EINVAL;
@@ -1889,9 +1995,15 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
instrs[0].ctx.data.force_8bit = force_8bit;
+ if (check_only)
+ return nand_check_op(chip, &op);
+
return nand_exec_op(chip, &op);
}
+ if (check_only)
+ return 0;
+
if (force_8bit) {
u8 *p = buf;
unsigned int i;
@@ -2112,7 +2224,7 @@ static void nand_op_parser_trace(const struct nand_op_parser_ctx *ctx)
char *prefix = " ";
unsigned int i;
- pr_debug("executing subop:\n");
+ pr_debug("executing subop (CS%d):\n", ctx->subop.cs);
for (i = 0; i < ctx->ninstrs; i++) {
instr = &ctx->instrs[i];
@@ -2176,6 +2288,7 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
const struct nand_operation *op, bool check_only)
{
struct nand_op_parser_ctx ctx = {
+ .subop.cs = op->cs,
.subop.instrs = op->instrs,
.instrs = op->instrs,
.ninstrs = op->ninstrs,
@@ -2620,7 +2733,7 @@ int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required,
if (oob_required) {
ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
- false);
+ false, false);
if (ret)
return ret;
}
@@ -2630,6 +2743,47 @@ int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required,
EXPORT_SYMBOL(nand_read_page_raw);
/**
+ * nand_monolithic_read_page_raw - Monolithic page read in raw mode
+ * @chip: NAND chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
+ *
+ * This is a raw page read, ie. without any error detection/correction.
+ * Monolithic means we are requesting all the relevant data (main plus
+ * eventually OOB) to be loaded in the NAND cache and sent over the
+ * bus (from the NAND chip to the NAND controller) in a single
+ * operation. This is an alternative to nand_read_page_raw(), which
+ * first reads the main data, and if the OOB data is requested too,
+ * then reads more data on the bus.
+ */
+int nand_monolithic_read_page_raw(struct nand_chip *chip, u8 *buf,
+ int oob_required, int page)
+{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ unsigned int size = mtd->writesize;
+ u8 *read_buf = buf;
+ int ret;
+
+ if (oob_required) {
+ size += mtd->oobsize;
+
+ if (buf != chip->data_buf)
+ read_buf = nand_get_data_buf(chip);
+ }
+
+ ret = nand_read_page_op(chip, page, 0, read_buf, size);
+ if (ret)
+ return ret;
+
+ if (buf != chip->data_buf)
+ memcpy(buf, read_buf, mtd->writesize);
+
+ return 0;
+}
+EXPORT_SYMBOL(nand_monolithic_read_page_raw);
+
+/**
* nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
* @chip: nand chip info structure
* @buf: buffer to store read data
@@ -2652,7 +2806,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
return ret;
for (steps = chip->ecc.steps; steps > 0; steps--) {
- ret = nand_read_data_op(chip, buf, eccsize, false);
+ ret = nand_read_data_op(chip, buf, eccsize, false, false);
if (ret)
return ret;
@@ -2660,14 +2814,14 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
if (chip->ecc.prepad) {
ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
- false);
+ false, false);
if (ret)
return ret;
oob += chip->ecc.prepad;
}
- ret = nand_read_data_op(chip, oob, eccbytes, false);
+ ret = nand_read_data_op(chip, oob, eccbytes, false, false);
if (ret)
return ret;
@@ -2675,7 +2829,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
if (chip->ecc.postpad) {
ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
- false);
+ false, false);
if (ret)
return ret;
@@ -2685,7 +2839,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
size = mtd->oobsize - (oob - chip->oob_poi);
if (size) {
- ret = nand_read_data_op(chip, oob, size, false);
+ ret = nand_read_data_op(chip, oob, size, false, false);
if (ret)
return ret;
}
@@ -2878,14 +3032,15 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf,
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
chip->ecc.hwctl(chip, NAND_ECC_READ);
- ret = nand_read_data_op(chip, p, eccsize, false);
+ ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret)
return ret;
chip->ecc.calculate(chip, p, &ecc_calc[i]);
}
- ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false);
+ ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false,
+ false);
if (ret)
return ret;
@@ -2921,76 +3076,6 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf,
}
/**
- * nand_read_page_hwecc_oob_first - [REPLACEABLE] hw ecc, read oob first
- * @chip: nand chip info structure
- * @buf: buffer to store read data
- * @oob_required: caller requires OOB data read to chip->oob_poi
- * @page: page number to read
- *
- * Hardware ECC for large page chips, require OOB to be read first. For this
- * ECC mode, the write_page method is re-used from ECC_HW. These methods
- * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
- * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
- * the data area, by overwriting the NAND manufacturer bad block markings.
- */
-static int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf,
- int oob_required, int page)
-{
- struct mtd_info *mtd = nand_to_mtd(chip);
- int i, eccsize = chip->ecc.size, ret;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- uint8_t *ecc_code = chip->ecc.code_buf;
- uint8_t *ecc_calc = chip->ecc.calc_buf;
- unsigned int max_bitflips = 0;
-
- /* Read the OOB area first */
- ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
- if (ret)
- return ret;
-
- ret = nand_read_page_op(chip, page, 0, NULL, 0);
- if (ret)
- return ret;
-
- ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
- chip->ecc.total);
- if (ret)
- return ret;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- int stat;
-
- chip->ecc.hwctl(chip, NAND_ECC_READ);
-
- ret = nand_read_data_op(chip, p, eccsize, false);
- if (ret)
- return ret;
-
- chip->ecc.calculate(chip, p, &ecc_calc[i]);
-
- stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL);
- if (stat == -EBADMSG &&
- (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
- /* check for empty pages with bitflips */
- stat = nand_check_erased_ecc_chunk(p, eccsize,
- &ecc_code[i], eccbytes,
- NULL, 0,
- chip->ecc.strength);
- }
-
- if (stat < 0) {
- mtd->ecc_stats.failed++;
- } else {
- mtd->ecc_stats.corrected += stat;
- max_bitflips = max_t(unsigned int, max_bitflips, stat);
- }
- }
- return max_bitflips;
-}
-
-/**
* nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
* @chip: nand chip info structure
* @buf: buffer to store read data
@@ -3021,13 +3106,13 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
chip->ecc.hwctl(chip, NAND_ECC_READ);
- ret = nand_read_data_op(chip, p, eccsize, false);
+ ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret)
return ret;
if (chip->ecc.prepad) {
ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
- false);
+ false, false);
if (ret)
return ret;
@@ -3036,7 +3121,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
chip->ecc.hwctl(chip, NAND_ECC_READSYN);
- ret = nand_read_data_op(chip, oob, eccbytes, false);
+ ret = nand_read_data_op(chip, oob, eccbytes, false, false);
if (ret)
return ret;
@@ -3046,7 +3131,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
if (chip->ecc.postpad) {
ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
- false);
+ false, false);
if (ret)
return ret;
@@ -3074,7 +3159,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
/* Calculate remaining oob bytes */
i = mtd->oobsize - (oob - chip->oob_poi);
if (i) {
- ret = nand_read_data_op(chip, oob, i, false);
+ ret = nand_read_data_op(chip, oob, i, false, false);
if (ret)
return ret;
}
@@ -3166,7 +3251,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
uint32_t max_oobsize = mtd_oobavail(mtd, ops);
uint8_t *bufpoi, *oob, *buf;
- int use_bufpoi;
+ int use_bounce_buf;
unsigned int max_bitflips = 0;
int retry_mode = 0;
bool ecc_fail = false;
@@ -3184,25 +3269,25 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
oob_required = oob ? 1 : 0;
while (1) {
- unsigned int ecc_failures = mtd->ecc_stats.failed;
+ struct mtd_ecc_stats ecc_stats = mtd->ecc_stats;
bytes = min(mtd->writesize - col, readlen);
aligned = (bytes == mtd->writesize);
if (!aligned)
- use_bufpoi = 1;
- else if (chip->options & NAND_USE_BOUNCE_BUFFER)
- use_bufpoi = !virt_addr_valid(buf) ||
- !IS_ALIGNED((unsigned long)buf,
- chip->buf_align);
+ use_bounce_buf = 1;
+ else if (chip->options & NAND_USES_DMA)
+ use_bounce_buf = !virt_addr_valid(buf) ||
+ !IS_ALIGNED((unsigned long)buf,
+ chip->buf_align);
else
- use_bufpoi = 0;
+ use_bounce_buf = 0;
/* Is the current page in the buffer? */
if (realpage != chip->pagecache.page || oob) {
- bufpoi = use_bufpoi ? chip->data_buf : buf;
+ bufpoi = use_bounce_buf ? chip->data_buf : buf;
- if (use_bufpoi && aligned)
+ if (use_bounce_buf && aligned)
pr_debug("%s: using read bounce buffer for buf@%p\n",
__func__, buf);
@@ -3223,16 +3308,19 @@ read_retry:
ret = chip->ecc.read_page(chip, bufpoi,
oob_required, page);
if (ret < 0) {
- if (use_bufpoi)
+ if (use_bounce_buf)
/* Invalidate page cache */
chip->pagecache.page = -1;
break;
}
- /* Transfer not aligned data */
- if (use_bufpoi) {
+ /*
+ * Copy back the data in the initial buffer when reading
+ * partial pages or when a bounce buffer is required.
+ */
+ if (use_bounce_buf) {
if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
- !(mtd->ecc_stats.failed - ecc_failures) &&
+ !(mtd->ecc_stats.failed - ecc_stats.failed) &&
(ops->mode != MTD_OPS_RAW)) {
chip->pagecache.page = realpage;
chip->pagecache.bitflips = ret;
@@ -3240,7 +3328,7 @@ read_retry:
/* Invalidate page cache */
chip->pagecache.page = -1;
}
- memcpy(buf, chip->data_buf + col, bytes);
+ memcpy(buf, bufpoi + col, bytes);
}
if (unlikely(oob)) {
@@ -3255,7 +3343,7 @@ read_retry:
nand_wait_readrdy(chip);
- if (mtd->ecc_stats.failed - ecc_failures) {
+ if (mtd->ecc_stats.failed - ecc_stats.failed) {
if (retry_mode + 1 < chip->read_retries) {
retry_mode++;
ret = nand_setup_read_retry(chip,
@@ -3263,8 +3351,8 @@ read_retry:
if (ret < 0)
break;
- /* Reset failures; retry */
- mtd->ecc_stats.failed = ecc_failures;
+ /* Reset ecc_stats; retry */
+ mtd->ecc_stats = ecc_stats;
goto read_retry;
} else {
/* No more retry modes; real failure */
@@ -3373,7 +3461,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page)
sndrnd = 1;
toread = min_t(int, length, chunk);
- ret = nand_read_data_op(chip, bufpoi, toread, false);
+ ret = nand_read_data_op(chip, bufpoi, toread, false, false);
if (ret)
return ret;
@@ -3381,7 +3469,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page)
length -= toread;
}
if (length > 0) {
- ret = nand_read_data_op(chip, bufpoi, length, false);
+ ret = nand_read_data_op(chip, bufpoi, length, false, false);
if (ret)
return ret;
}
@@ -3634,6 +3722,42 @@ int nand_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
EXPORT_SYMBOL(nand_write_page_raw);
/**
+ * nand_monolithic_write_page_raw - Monolithic page write in raw mode
+ * @chip: NAND chip info structure
+ * @buf: data buffer to write
+ * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
+ *
+ * This is a raw page write, ie. without any error detection/correction.
+ * Monolithic means we are requesting all the relevant data (main plus
+ * eventually OOB) to be sent over the bus and effectively programmed
+ * into the NAND chip arrays in a single operation. This is an
+ * alternative to nand_write_page_raw(), which first sends the main
+ * data, then eventually send the OOB data by latching more data
+ * cycles on the NAND bus, and finally sends the program command to
+ * synchronyze the NAND chip cache.
+ */
+int nand_monolithic_write_page_raw(struct nand_chip *chip, const u8 *buf,
+ int oob_required, int page)
+{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ unsigned int size = mtd->writesize;
+ u8 *write_buf = (u8 *)buf;
+
+ if (oob_required) {
+ size += mtd->oobsize;
+
+ if (buf != chip->data_buf) {
+ write_buf = nand_get_data_buf(chip);
+ memcpy(write_buf, buf, mtd->writesize);
+ }
+ }
+
+ return nand_prog_page_op(chip, page, 0, write_buf, size);
+}
+EXPORT_SYMBOL(nand_monolithic_write_page_raw);
+
+/**
* nand_write_page_raw_syndrome - [INTERN] raw page write function
* @chip: nand chip info structure
* @buf: data buffer
@@ -4012,20 +4136,23 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
while (1) {
int bytes = mtd->writesize;
uint8_t *wbuf = buf;
- int use_bufpoi;
+ int use_bounce_buf;
int part_pagewr = (column || writelen < mtd->writesize);
if (part_pagewr)
- use_bufpoi = 1;
- else if (chip->options & NAND_USE_BOUNCE_BUFFER)
- use_bufpoi = !virt_addr_valid(buf) ||
- !IS_ALIGNED((unsigned long)buf,
- chip->buf_align);
+ use_bounce_buf = 1;
+ else if (chip->options & NAND_USES_DMA)
+ use_bounce_buf = !virt_addr_valid(buf) ||
+ !IS_ALIGNED((unsigned long)buf,
+ chip->buf_align);
else
- use_bufpoi = 0;
+ use_bounce_buf = 0;
- /* Partial page write?, or need to use bounce buffer */
- if (use_bufpoi) {
+ /*
+ * Copy the data from the initial buffer when doing partial page
+ * writes or when a bounce buffer is required.
+ */
+ if (use_bounce_buf) {
pr_debug("%s: using write bounce buffer for buf@%p\n",
__func__, buf);
if (part_pagewr)
@@ -4883,7 +5010,6 @@ static const char * const nand_ecc_modes[] = {
[NAND_ECC_SOFT] = "soft",
[NAND_ECC_HW] = "hw",
[NAND_ECC_HW_SYNDROME] = "hw_syndrome",
- [NAND_ECC_HW_OOB_FIRST] = "hw_oob_first",
[NAND_ECC_ON_DIE] = "on-die",
};
@@ -4896,14 +5022,14 @@ static int of_get_nand_ecc_mode(struct device_node *np)
if (err < 0)
return err;
- for (i = 0; i < ARRAY_SIZE(nand_ecc_modes); i++)
+ for (i = NAND_ECC_NONE; i < ARRAY_SIZE(nand_ecc_modes); i++)
if (!strcasecmp(pm, nand_ecc_modes[i]))
return i;
/*
* For backward compatibility we support few obsoleted values that don't
- * have their mappings into nand_ecc_modes_t anymore (they were merged
- * with other enums).
+ * have their mappings into the nand_ecc_mode enum anymore (they were
+ * merged with other enums).
*/
if (!strcasecmp(pm, "soft_bch"))
return NAND_ECC_SOFT;
@@ -4917,17 +5043,20 @@ static const char * const nand_ecc_algos[] = {
[NAND_ECC_RS] = "rs",
};
-static int of_get_nand_ecc_algo(struct device_node *np)
+static enum nand_ecc_algo of_get_nand_ecc_algo(struct device_node *np)
{
+ enum nand_ecc_algo ecc_algo;
const char *pm;
- int err, i;
+ int err;
err = of_property_read_string(np, "nand-ecc-algo", &pm);
if (!err) {
- for (i = NAND_ECC_HAMMING; i < ARRAY_SIZE(nand_ecc_algos); i++)
- if (!strcasecmp(pm, nand_ecc_algos[i]))
- return i;
- return -ENODEV;
+ for (ecc_algo = NAND_ECC_HAMMING;
+ ecc_algo < ARRAY_SIZE(nand_ecc_algos);
+ ecc_algo++) {
+ if (!strcasecmp(pm, nand_ecc_algos[ecc_algo]))
+ return ecc_algo;
+ }
}
/*
@@ -4935,15 +5064,14 @@ static int of_get_nand_ecc_algo(struct device_node *np)
* for some obsoleted values that were specifying ECC algorithm.
*/
err = of_property_read_string(np, "nand-ecc-mode", &pm);
- if (err < 0)
- return err;
-
- if (!strcasecmp(pm, "soft"))
- return NAND_ECC_HAMMING;
- else if (!strcasecmp(pm, "soft_bch"))
- return NAND_ECC_BCH;
+ if (!err) {
+ if (!strcasecmp(pm, "soft"))
+ return NAND_ECC_HAMMING;
+ else if (!strcasecmp(pm, "soft_bch"))
+ return NAND_ECC_BCH;
+ }
- return -ENODEV;
+ return NAND_ECC_UNKNOWN;
}
static int of_get_nand_ecc_step_size(struct device_node *np)
@@ -4988,7 +5116,8 @@ static bool of_get_nand_on_flash_bbt(struct device_node *np)
static int nand_dt_init(struct nand_chip *chip)
{
struct device_node *dn = nand_get_flash_node(chip);
- int ecc_mode, ecc_algo, ecc_strength, ecc_step;
+ enum nand_ecc_algo ecc_algo;
+ int ecc_mode, ecc_strength, ecc_step;
if (!dn)
return 0;
@@ -5010,7 +5139,7 @@ static int nand_dt_init(struct nand_chip *chip)
if (ecc_mode >= 0)
chip->ecc.mode = ecc_mode;
- if (ecc_algo >= 0)
+ if (ecc_algo != NAND_ECC_UNKNOWN)
chip->ecc.algo = ecc_algo;
if (ecc_strength >= 0)
@@ -5140,8 +5269,10 @@ static int nand_set_ecc_soft_ops(struct nand_chip *chip)
ecc->read_page = nand_read_page_swecc;
ecc->read_subpage = nand_read_subpage;
ecc->write_page = nand_write_page_swecc;
- ecc->read_page_raw = nand_read_page_raw;
- ecc->write_page_raw = nand_write_page_raw;
+ if (!ecc->read_page_raw)
+ ecc->read_page_raw = nand_read_page_raw;
+ if (!ecc->write_page_raw)
+ ecc->write_page_raw = nand_write_page_raw;
ecc->read_oob = nand_read_oob_std;
ecc->write_oob = nand_write_oob_std;
if (!ecc->size)
@@ -5163,8 +5294,10 @@ static int nand_set_ecc_soft_ops(struct nand_chip *chip)
ecc->read_page = nand_read_page_swecc;
ecc->read_subpage = nand_read_subpage;
ecc->write_page = nand_write_page_swecc;
- ecc->read_page_raw = nand_read_page_raw;
- ecc->write_page_raw = nand_write_page_raw;
+ if (!ecc->read_page_raw)
+ ecc->read_page_raw = nand_read_page_raw;
+ if (!ecc->write_page_raw)
+ ecc->write_page_raw = nand_write_page_raw;
ecc->read_oob = nand_read_oob_std;
ecc->write_oob = nand_write_oob_std;
@@ -5628,16 +5761,6 @@ static int nand_scan_tail(struct nand_chip *chip)
*/
switch (ecc->mode) {
- case NAND_ECC_HW_OOB_FIRST:
- /* Similar to NAND_ECC_HW, but a separate read_page handle */
- if (!ecc->calculate || !ecc->correct || !ecc->hwctl) {
- WARN(1, "No ECC functions supplied; hardware ECC not possible\n");
- ret = -EINVAL;
- goto err_nand_manuf_cleanup;
- }
- if (!ecc->read_page)
- ecc->read_page = nand_read_page_hwecc_oob_first;
- fallthrough;
case NAND_ECC_HW:
/* Use standard hwecc read page function? */
if (!ecc->read_page)
@@ -5781,8 +5904,10 @@ static int nand_scan_tail(struct nand_chip *chip)
/* ECC sanity check: warn if it's too weak */
if (!nand_ecc_strength_good(chip))
- pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
- mtd->name);
+ pr_warn("WARNING: %s: the ECC used on your system (%db/%dB) is too weak compared to the one required by the NAND chip (%db/%dB)\n",
+ mtd->name, chip->ecc.strength, chip->ecc.size,
+ chip->base.eccreq.strength,
+ chip->base.eccreq.step_size);
/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
@@ -5975,18 +6100,6 @@ void nand_cleanup(struct nand_chip *chip)
EXPORT_SYMBOL_GPL(nand_cleanup);
-/**
- * nand_release - [NAND Interface] Unregister the MTD device and free resources
- * held by the NAND device
- * @chip: NAND chip object
- */
-void nand_release(struct nand_chip *chip)
-{
- mtd_device_unregister(nand_to_mtd(chip));
- nand_cleanup(chip);
-}
-EXPORT_SYMBOL_GPL(nand_release);
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
diff --git a/drivers/mtd/nand/raw/nand_bch.c b/drivers/mtd/nand/raw/nand_bch.c
index 17527310c3a1..d5af8c5fd02f 100644
--- a/drivers/mtd/nand/raw/nand_bch.c
+++ b/drivers/mtd/nand/raw/nand_bch.c
@@ -41,7 +41,7 @@ int nand_bch_calculate_ecc(struct nand_chip *chip, const unsigned char *buf,
unsigned int i;
memset(code, 0, chip->ecc.bytes);
- encode_bch(nbc->bch, buf, chip->ecc.size, code);
+ bch_encode(nbc->bch, buf, chip->ecc.size, code);
/* apply mask so that an erased page is a valid codeword */
for (i = 0; i < chip->ecc.bytes; i++)
@@ -67,7 +67,7 @@ int nand_bch_correct_data(struct nand_chip *chip, unsigned char *buf,
unsigned int *errloc = nbc->errloc;
int i, count;
- count = decode_bch(nbc->bch, NULL, chip->ecc.size, read_ecc, calc_ecc,
+ count = bch_decode(nbc->bch, NULL, chip->ecc.size, read_ecc, calc_ecc,
NULL, errloc);
if (count > 0) {
for (i = 0; i < count; i++) {
@@ -130,7 +130,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
if (!nbc)
goto fail;
- nbc->bch = init_bch(m, t, 0);
+ nbc->bch = bch_init(m, t, 0, false);
if (!nbc->bch)
goto fail;
@@ -182,7 +182,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
goto fail;
memset(erased_page, 0xff, eccsize);
- encode_bch(nbc->bch, erased_page, eccsize, nbc->eccmask);
+ bch_encode(nbc->bch, erased_page, eccsize, nbc->eccmask);
kfree(erased_page);
for (i = 0; i < eccbytes; i++)
@@ -205,7 +205,7 @@ EXPORT_SYMBOL(nand_bch_init);
void nand_bch_free(struct nand_bch_control *nbc)
{
if (nbc) {
- free_bch(nbc->bch);
+ bch_free(nbc->bch);
kfree(nbc->errloc);
kfree(nbc->eccmask);
kfree(nbc);
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 9b540e76f84f..b15c42f48755 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -16,6 +16,8 @@
#include "internals.h"
+#define JEDEC_PARAM_PAGES 3
+
/*
* Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise.
*/
@@ -25,9 +27,11 @@ int nand_jedec_detect(struct nand_chip *chip)
struct nand_memory_organization *memorg;
struct nand_jedec_params *p;
struct jedec_ecc_info *ecc;
+ bool use_datain = false;
int jedec_version = 0;
char id[5];
int i, val, ret;
+ u16 crc;
memorg = nanddev_get_memorg(&chip->base);
@@ -41,25 +45,31 @@ int nand_jedec_detect(struct nand_chip *chip)
if (!p)
return -ENOMEM;
- ret = nand_read_param_page_op(chip, 0x40, NULL, 0);
- if (ret) {
- ret = 0;
- goto free_jedec_param_page;
- }
-
- for (i = 0; i < 3; i++) {
- ret = nand_read_data_op(chip, p, sizeof(*p), true);
+ if (!nand_has_exec_op(chip) ||
+ !nand_read_data_op(chip, p, sizeof(*p), true, true))
+ use_datain = true;
+
+ for (i = 0; i < JEDEC_PARAM_PAGES; i++) {
+ if (!i)
+ ret = nand_read_param_page_op(chip, 0x40, p,
+ sizeof(*p));
+ else if (use_datain)
+ ret = nand_read_data_op(chip, p, sizeof(*p), true,
+ false);
+ else
+ ret = nand_change_read_column_op(chip, sizeof(*p) * i,
+ p, sizeof(*p), true);
if (ret) {
ret = 0;
goto free_jedec_param_page;
}
- if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
- le16_to_cpu(p->crc))
+ crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)p, 510);
+ if (crc == le16_to_cpu(p->crc))
break;
}
- if (i == 3) {
+ if (i == JEDEC_PARAM_PAGES) {
pr_err("Could not find valid JEDEC parameter page; aborting\n");
goto free_jedec_param_page;
}
diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c
index f91e92e1b972..d64791c06a97 100644
--- a/drivers/mtd/nand/raw/nand_legacy.c
+++ b/drivers/mtd/nand/raw/nand_legacy.c
@@ -225,7 +225,8 @@ static void nand_wait_status_ready(struct nand_chip *chip, unsigned long timeo)
do {
u8 status;
- ret = nand_read_data_op(chip, &status, sizeof(status), true);
+ ret = nand_read_data_op(chip, &status, sizeof(status), true,
+ false);
if (ret)
return;
@@ -552,7 +553,8 @@ static int nand_wait(struct nand_chip *chip)
break;
} else {
ret = nand_read_data_op(chip, &status,
- sizeof(status), true);
+ sizeof(status), true,
+ false);
if (ret)
return ret;
@@ -563,7 +565,7 @@ static int nand_wait(struct nand_chip *chip)
} while (time_before(jiffies, timeo));
}
- ret = nand_read_data_op(chip, &status, sizeof(status), true);
+ ret = nand_read_data_op(chip, &status, sizeof(status), true, false);
if (ret)
return ret;
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index 56654030ec7f..3589b4fce0d4 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -192,6 +192,7 @@ static int micron_nand_on_die_ecc_status_4(struct nand_chip *chip, u8 status,
struct micron_nand *micron = nand_get_manufacturer_data(chip);
struct mtd_info *mtd = nand_to_mtd(chip);
unsigned int step, max_bitflips = 0;
+ bool use_datain = false;
int ret;
if (!(status & NAND_ECC_STATUS_WRITE_RECOMMENDED)) {
@@ -211,8 +212,27 @@ static int micron_nand_on_die_ecc_status_4(struct nand_chip *chip, u8 status,
* in non-raw mode, even if the user did not request those bytes.
*/
if (!oob_required) {
- ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
- false);
+ /*
+ * We first check which operation is supported by the controller
+ * before running it. This trick makes it possible to support
+ * all controllers, even the most constraints, without almost
+ * any performance hit.
+ *
+ * TODO: could be enhanced to avoid repeating the same check
+ * over and over in the fast path.
+ */
+ if (!nand_has_exec_op(chip) ||
+ !nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false,
+ true))
+ use_datain = true;
+
+ if (use_datain)
+ ret = nand_read_data_op(chip, chip->oob_poi,
+ mtd->oobsize, false, false);
+ else
+ ret = nand_change_read_column_op(chip, mtd->writesize,
+ chip->oob_poi,
+ mtd->oobsize, false);
if (ret)
return ret;
}
@@ -285,6 +305,7 @@ micron_nand_read_page_on_die_ecc(struct nand_chip *chip, uint8_t *buf,
int oob_required, int page)
{
struct mtd_info *mtd = nand_to_mtd(chip);
+ bool use_datain = false;
u8 status;
int ret, max_bitflips = 0;
@@ -300,14 +321,36 @@ micron_nand_read_page_on_die_ecc(struct nand_chip *chip, uint8_t *buf,
if (ret)
goto out;
- ret = nand_exit_status_op(chip);
- if (ret)
- goto out;
+ /*
+ * We first check which operation is supported by the controller before
+ * running it. This trick makes it possible to support all controllers,
+ * even the most constraints, without almost any performance hit.
+ *
+ * TODO: could be enhanced to avoid repeating the same check over and
+ * over in the fast path.
+ */
+ if (!nand_has_exec_op(chip) ||
+ !nand_read_data_op(chip, buf, mtd->writesize, false, true))
+ use_datain = true;
- ret = nand_read_data_op(chip, buf, mtd->writesize, false);
- if (!ret && oob_required)
- ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
+ if (use_datain) {
+ ret = nand_exit_status_op(chip);
+ if (ret)
+ goto out;
+
+ ret = nand_read_data_op(chip, buf, mtd->writesize, false,
false);
+ if (!ret && oob_required)
+ ret = nand_read_data_op(chip, chip->oob_poi,
+ mtd->oobsize, false, false);
+ } else {
+ ret = nand_change_read_column_op(chip, 0, buf, mtd->writesize,
+ false);
+ if (!ret && oob_required)
+ ret = nand_change_read_column_op(chip, mtd->writesize,
+ chip->oob_poi,
+ mtd->oobsize, false);
+ }
if (chip->ecc.strength == 4)
max_bitflips = micron_nand_on_die_ecc_status_4(chip, status,
@@ -508,8 +551,10 @@ static int micron_nand_init(struct nand_chip *chip)
chip->ecc.read_page_raw = nand_read_page_raw_notsupp;
chip->ecc.write_page_raw = nand_write_page_raw_notsupp;
} else {
- chip->ecc.read_page_raw = nand_read_page_raw;
- chip->ecc.write_page_raw = nand_write_page_raw;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw;
}
}
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index 0b879bd0a68c..be3456627288 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -16,6 +16,8 @@
#include "internals.h"
+#define ONFI_PARAM_PAGES 3
+
u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
{
int i;
@@ -45,12 +47,10 @@ static int nand_flash_detect_ext_param_page(struct nand_chip *chip,
if (!ep)
return -ENOMEM;
- /* Send our own NAND_CMD_PARAM. */
- ret = nand_read_param_page_op(chip, 0, NULL, 0);
- if (ret)
- goto ext_out;
-
- /* Use the Change Read Column command to skip the ONFI param pages. */
+ /*
+ * Use the Change Read Column command to skip the ONFI param pages and
+ * ensure we read at the right location.
+ */
ret = nand_change_read_column_op(chip,
sizeof(*p) * p->num_of_param_pages,
ep, len, true);
@@ -141,11 +141,13 @@ int nand_onfi_detect(struct nand_chip *chip)
{
struct mtd_info *mtd = nand_to_mtd(chip);
struct nand_memory_organization *memorg;
- struct nand_onfi_params *p;
+ struct nand_onfi_params *p = NULL, *pbuf;
struct onfi_params *onfi;
+ bool use_datain = false;
int onfi_version = 0;
char id[4];
int i, ret, val;
+ u16 crc;
memorg = nanddev_get_memorg(&chip->base);
@@ -155,43 +157,54 @@ int nand_onfi_detect(struct nand_chip *chip)
return 0;
/* ONFI chip: allocate a buffer to hold its parameter page */
- p = kzalloc((sizeof(*p) * 3), GFP_KERNEL);
- if (!p)
+ pbuf = kzalloc((sizeof(*pbuf) * ONFI_PARAM_PAGES), GFP_KERNEL);
+ if (!pbuf)
return -ENOMEM;
- ret = nand_read_param_page_op(chip, 0, NULL, 0);
- if (ret) {
- ret = 0;
- goto free_onfi_param_page;
- }
-
- for (i = 0; i < 3; i++) {
- ret = nand_read_data_op(chip, &p[i], sizeof(*p), true);
+ if (!nand_has_exec_op(chip) ||
+ !nand_read_data_op(chip, &pbuf[0], sizeof(*pbuf), true, true))
+ use_datain = true;
+
+ for (i = 0; i < ONFI_PARAM_PAGES; i++) {
+ if (!i)
+ ret = nand_read_param_page_op(chip, 0, &pbuf[i],
+ sizeof(*pbuf));
+ else if (use_datain)
+ ret = nand_read_data_op(chip, &pbuf[i], sizeof(*pbuf),
+ true, false);
+ else
+ ret = nand_change_read_column_op(chip, sizeof(*pbuf) * i,
+ &pbuf[i], sizeof(*pbuf),
+ true);
if (ret) {
ret = 0;
goto free_onfi_param_page;
}
- if (onfi_crc16(ONFI_CRC_BASE, (u8 *)&p[i], 254) ==
- le16_to_cpu(p->crc)) {
- if (i)
- memcpy(p, &p[i], sizeof(*p));
+ crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)&pbuf[i], 254);
+ if (crc == le16_to_cpu(pbuf[i].crc)) {
+ p = &pbuf[i];
break;
}
}
- if (i == 3) {
- const void *srcbufs[3] = {p, p + 1, p + 2};
+ if (i == ONFI_PARAM_PAGES) {
+ const void *srcbufs[ONFI_PARAM_PAGES];
+ unsigned int j;
+
+ for (j = 0; j < ONFI_PARAM_PAGES; j++)
+ srcbufs[j] = pbuf + j;
pr_warn("Could not find a valid ONFI parameter page, trying bit-wise majority to recover it\n");
- nand_bit_wise_majority(srcbufs, ARRAY_SIZE(srcbufs), p,
- sizeof(*p));
+ nand_bit_wise_majority(srcbufs, ONFI_PARAM_PAGES, pbuf,
+ sizeof(*pbuf));
- if (onfi_crc16(ONFI_CRC_BASE, (u8 *)p, 254) !=
- le16_to_cpu(p->crc)) {
+ crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)pbuf, 254);
+ if (crc != le16_to_cpu(pbuf->crc)) {
pr_err("ONFI parameter recovery failed, aborting\n");
goto free_onfi_param_page;
}
+ p = pbuf;
}
if (chip->manufacturer.desc && chip->manufacturer.desc->ops &&
@@ -299,14 +312,14 @@ int nand_onfi_detect(struct nand_chip *chip)
chip->parameters.onfi = onfi;
/* Identification done, free the full ONFI parameter page and exit */
- kfree(p);
+ kfree(pbuf);
return 1;
free_model:
kfree(chip->parameters.model);
free_onfi_param_page:
- kfree(p);
+ kfree(pbuf);
return ret;
}
diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c
index f64b06a71dfa..36d21be3dfe5 100644
--- a/drivers/mtd/nand/raw/nand_timings.c
+++ b/drivers/mtd/nand/raw/nand_timings.c
@@ -16,6 +16,7 @@ static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 0 */
{
.type = NAND_SDR_IFACE,
+ .timings.mode = 0,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
@@ -58,6 +59,7 @@ static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 1 */
{
.type = NAND_SDR_IFACE,
+ .timings.mode = 1,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
@@ -100,6 +102,7 @@ static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 2 */
{
.type = NAND_SDR_IFACE,
+ .timings.mode = 2,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
@@ -142,6 +145,7 @@ static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 3 */
{
.type = NAND_SDR_IFACE,
+ .timings.mode = 3,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
@@ -184,6 +188,7 @@ static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 4 */
{
.type = NAND_SDR_IFACE,
+ .timings.mode = 4,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
@@ -226,6 +231,7 @@ static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 5 */
{
.type = NAND_SDR_IFACE,
+ .timings.mode = 5,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
@@ -314,10 +320,9 @@ int onfi_fill_data_interface(struct nand_chip *chip,
/* microseconds -> picoseconds */
timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
- timings->tR_max = 1000000ULL * 200000000ULL;
- /* nanoseconds -> picoseconds */
- timings->tCCS_min = 1000UL * 500000;
+ timings->tR_max = 200000000;
+ timings->tCCS_min = 500000;
}
return 0;
diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c
index f3dcd695b5db..ae069905d7e4 100644
--- a/drivers/mtd/nand/raw/nand_toshiba.c
+++ b/drivers/mtd/nand/raw/nand_toshiba.c
@@ -194,6 +194,17 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
}
}
+static int tc58teg5dclta00_init(struct nand_chip *chip)
+{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+
+ chip->onfi_timing_mode_default = 5;
+ chip->options |= NAND_NEED_SCRAMBLING;
+ mtd_set_pairing_scheme(mtd, &dist3_pairing_scheme);
+
+ return 0;
+}
+
static int toshiba_nand_init(struct nand_chip *chip)
{
if (nand_is_slc(chip))
@@ -204,6 +215,9 @@ static int toshiba_nand_init(struct nand_chip *chip)
chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND)
toshiba_nand_benand_init(chip);
+ if (!strcmp("TC58TEG5DCLTA00", chip->parameters.model))
+ tc58teg5dclta00_init(chip);
+
return 0;
}
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
index 1de03bb34e84..0a5cb77966cc 100644
--- a/drivers/mtd/nand/raw/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -353,6 +353,9 @@ struct nandsim {
void *file_buf;
struct page *held_pages[NS_MAX_HELD_PAGES];
int held_cnt;
+
+ /* debugfs entry */
+ struct dentry *dent;
};
/*
@@ -432,7 +435,7 @@ static unsigned long total_wear = 0;
/* MTD structure for NAND controller */
static struct mtd_info *nsmtd;
-static int nandsim_show(struct seq_file *m, void *private)
+static int ns_show(struct seq_file *m, void *private)
{
unsigned long wmin = -1, wmax = 0, avg;
unsigned long deciles[10], decile_max[10], tot = 0;
@@ -483,19 +486,18 @@ static int nandsim_show(struct seq_file *m, void *private)
return 0;
}
-DEFINE_SHOW_ATTRIBUTE(nandsim);
+DEFINE_SHOW_ATTRIBUTE(ns);
/**
- * nandsim_debugfs_create - initialize debugfs
- * @dev: nandsim device description object
+ * ns_debugfs_create - initialize debugfs
+ * @ns: nandsim device description object
*
* This function creates all debugfs files for UBI device @ubi. Returns zero in
* case of success and a negative error code in case of failure.
*/
-static int nandsim_debugfs_create(struct nandsim *dev)
+static int ns_debugfs_create(struct nandsim *ns)
{
struct dentry *root = nsmtd->dbg.dfs_dir;
- struct dentry *dent;
/*
* Just skip debugfs initialization when the debugfs directory is
@@ -508,9 +510,9 @@ static int nandsim_debugfs_create(struct nandsim *dev)
return 0;
}
- dent = debugfs_create_file("nandsim_wear_report", S_IRUSR,
- root, dev, &nandsim_fops);
- if (IS_ERR_OR_NULL(dent)) {
+ ns->dent = debugfs_create_file("nandsim_wear_report", 0400, root, ns,
+ &ns_fops);
+ if (IS_ERR_OR_NULL(ns->dent)) {
NS_ERR("cannot create \"nandsim_wear_report\" debugfs entry\n");
return -1;
}
@@ -518,13 +520,18 @@ static int nandsim_debugfs_create(struct nandsim *dev)
return 0;
}
+static void ns_debugfs_remove(struct nandsim *ns)
+{
+ debugfs_remove_recursive(ns->dent);
+}
+
/*
* Allocate array of page pointers, create slab allocation for an array
* and initialize the array by NULL pointers.
*
* RETURNS: 0 if success, -ENOMEM if memory alloc fails.
*/
-static int __init alloc_device(struct nandsim *ns)
+static int __init ns_alloc_device(struct nandsim *ns)
{
struct file *cfile;
int i, err;
@@ -536,12 +543,12 @@ static int __init alloc_device(struct nandsim *ns)
if (!(cfile->f_mode & FMODE_CAN_READ)) {
NS_ERR("alloc_device: cache file not readable\n");
err = -EINVAL;
- goto err_close;
+ goto err_close_filp;
}
if (!(cfile->f_mode & FMODE_CAN_WRITE)) {
NS_ERR("alloc_device: cache file not writeable\n");
err = -EINVAL;
- goto err_close;
+ goto err_close_filp;
}
ns->pages_written =
vzalloc(array_size(sizeof(unsigned long),
@@ -549,16 +556,24 @@ static int __init alloc_device(struct nandsim *ns)
if (!ns->pages_written) {
NS_ERR("alloc_device: unable to allocate pages written array\n");
err = -ENOMEM;
- goto err_close;
+ goto err_close_filp;
}
ns->file_buf = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
if (!ns->file_buf) {
NS_ERR("alloc_device: unable to allocate file buf\n");
err = -ENOMEM;
- goto err_free;
+ goto err_free_pw;
}
ns->cfile = cfile;
+
return 0;
+
+err_free_pw:
+ vfree(ns->pages_written);
+err_close_filp:
+ filp_close(cfile, NULL);
+
+ return err;
}
ns->pages = vmalloc(array_size(sizeof(union ns_mem), ns->geom.pgnum));
@@ -573,22 +588,22 @@ static int __init alloc_device(struct nandsim *ns)
ns->geom.pgszoob, 0, 0, NULL);
if (!ns->nand_pages_slab) {
NS_ERR("cache_create: unable to create kmem_cache\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_free_pg;
}
return 0;
-err_free:
- vfree(ns->pages_written);
-err_close:
- filp_close(cfile, NULL);
+err_free_pg:
+ vfree(ns->pages);
+
return err;
}
/*
* Free any allocated pages, and free the array of page pointers.
*/
-static void free_device(struct nandsim *ns)
+static void ns_free_device(struct nandsim *ns)
{
int i;
@@ -610,7 +625,7 @@ static void free_device(struct nandsim *ns)
}
}
-static char __init *get_partition_name(int i)
+static char __init *ns_get_partition_name(int i)
{
return kasprintf(GFP_KERNEL, "NAND simulator partition %d", i);
}
@@ -620,7 +635,7 @@ static char __init *get_partition_name(int i)
*
* RETURNS: 0 if success, -ERRNO if failure.
*/
-static int __init init_nandsim(struct mtd_info *mtd)
+static int __init ns_init(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct nandsim *ns = nand_get_controller_data(chip);
@@ -693,7 +708,7 @@ static int __init init_nandsim(struct mtd_info *mtd)
NS_ERR("bad partition size.\n");
return -EINVAL;
}
- ns->partitions[i].name = get_partition_name(i);
+ ns->partitions[i].name = ns_get_partition_name(i);
if (!ns->partitions[i].name) {
NS_ERR("unable to allocate memory.\n");
return -ENOMEM;
@@ -707,12 +722,14 @@ static int __init init_nandsim(struct mtd_info *mtd)
if (remains) {
if (parts_num + 1 > ARRAY_SIZE(ns->partitions)) {
NS_ERR("too many partitions.\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto free_partition_names;
}
- ns->partitions[i].name = get_partition_name(i);
+ ns->partitions[i].name = ns_get_partition_name(i);
if (!ns->partitions[i].name) {
NS_ERR("unable to allocate memory.\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto free_partition_names;
}
ns->partitions[i].offset = next_offset;
ns->partitions[i].size = remains;
@@ -739,33 +756,48 @@ static int __init init_nandsim(struct mtd_info *mtd)
printk("sector address bytes: %u\n", ns->geom.secaddrbytes);
printk("options: %#x\n", ns->options);
- if ((ret = alloc_device(ns)) != 0)
- return ret;
+ ret = ns_alloc_device(ns);
+ if (ret)
+ goto free_partition_names;
/* Allocate / initialize the internal buffer */
ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
if (!ns->buf.byte) {
NS_ERR("init_nandsim: unable to allocate %u bytes for the internal buffer\n",
ns->geom.pgszoob);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto free_device;
}
memset(ns->buf.byte, 0xFF, ns->geom.pgszoob);
return 0;
+
+free_device:
+ ns_free_device(ns);
+free_partition_names:
+ for (i = 0; i < ARRAY_SIZE(ns->partitions); ++i)
+ kfree(ns->partitions[i].name);
+
+ return ret;
}
/*
* Free the nandsim structure.
*/
-static void free_nandsim(struct nandsim *ns)
+static void ns_free(struct nandsim *ns)
{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ns->partitions); ++i)
+ kfree(ns->partitions[i].name);
+
kfree(ns->buf.byte);
- free_device(ns);
+ ns_free_device(ns);
return;
}
-static int parse_badblocks(struct nandsim *ns, struct mtd_info *mtd)
+static int ns_parse_badblocks(struct nandsim *ns, struct mtd_info *mtd)
{
char *w;
int zero_ok;
@@ -793,7 +825,7 @@ static int parse_badblocks(struct nandsim *ns, struct mtd_info *mtd)
return 0;
}
-static int parse_weakblocks(void)
+static int ns_parse_weakblocks(void)
{
char *w;
int zero_ok;
@@ -830,7 +862,7 @@ static int parse_weakblocks(void)
return 0;
}
-static int erase_error(unsigned int erase_block_no)
+static int ns_erase_error(unsigned int erase_block_no)
{
struct weak_block *wb;
@@ -844,7 +876,7 @@ static int erase_error(unsigned int erase_block_no)
return 0;
}
-static int parse_weakpages(void)
+static int ns_parse_weakpages(void)
{
char *w;
int zero_ok;
@@ -881,7 +913,7 @@ static int parse_weakpages(void)
return 0;
}
-static int write_error(unsigned int page_no)
+static int ns_write_error(unsigned int page_no)
{
struct weak_page *wp;
@@ -895,7 +927,7 @@ static int write_error(unsigned int page_no)
return 0;
}
-static int parse_gravepages(void)
+static int ns_parse_gravepages(void)
{
char *g;
int zero_ok;
@@ -932,7 +964,7 @@ static int parse_gravepages(void)
return 0;
}
-static int read_error(unsigned int page_no)
+static int ns_read_error(unsigned int page_no)
{
struct grave_page *gp;
@@ -946,25 +978,7 @@ static int read_error(unsigned int page_no)
return 0;
}
-static void free_lists(void)
-{
- struct list_head *pos, *n;
- list_for_each_safe(pos, n, &weak_blocks) {
- list_del(pos);
- kfree(list_entry(pos, struct weak_block, list));
- }
- list_for_each_safe(pos, n, &weak_pages) {
- list_del(pos);
- kfree(list_entry(pos, struct weak_page, list));
- }
- list_for_each_safe(pos, n, &grave_pages) {
- list_del(pos);
- kfree(list_entry(pos, struct grave_page, list));
- }
- kfree(erase_block_wear);
-}
-
-static int setup_wear_reporting(struct mtd_info *mtd)
+static int ns_setup_wear_reporting(struct mtd_info *mtd)
{
size_t mem;
@@ -982,7 +996,7 @@ static int setup_wear_reporting(struct mtd_info *mtd)
return 0;
}
-static void update_wear(unsigned int erase_block_no)
+static void ns_update_wear(unsigned int erase_block_no)
{
if (!erase_block_wear)
return;
@@ -1001,7 +1015,7 @@ static void update_wear(unsigned int erase_block_no)
/*
* Returns the string representation of 'state' state.
*/
-static char *get_state_name(uint32_t state)
+static char *ns_get_state_name(uint32_t state)
{
switch (NS_STATE(state)) {
case STATE_CMD_READ0:
@@ -1061,7 +1075,7 @@ static char *get_state_name(uint32_t state)
*
* RETURNS: 1 if wrong command, 0 if right.
*/
-static int check_command(int cmd)
+static int ns_check_command(int cmd)
{
switch (cmd) {
@@ -1088,7 +1102,7 @@ static int check_command(int cmd)
/*
* Returns state after command is accepted by command number.
*/
-static uint32_t get_state_by_command(unsigned command)
+static uint32_t ns_get_state_by_command(unsigned command)
{
switch (command) {
case NAND_CMD_READ0:
@@ -1126,7 +1140,7 @@ static uint32_t get_state_by_command(unsigned command)
/*
* Move an address byte to the correspondent internal register.
*/
-static inline void accept_addr_byte(struct nandsim *ns, u_char bt)
+static inline void ns_accept_addr_byte(struct nandsim *ns, u_char bt)
{
uint byte = (uint)bt;
@@ -1144,9 +1158,10 @@ static inline void accept_addr_byte(struct nandsim *ns, u_char bt)
/*
* Switch to STATE_READY state.
*/
-static inline void switch_to_ready_state(struct nandsim *ns, u_char status)
+static inline void ns_switch_to_ready_state(struct nandsim *ns, u_char status)
{
- NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
+ NS_DBG("switch_to_ready_state: switch to %s state\n",
+ ns_get_state_name(STATE_READY));
ns->state = STATE_READY;
ns->nxstate = STATE_UNKNOWN;
@@ -1203,7 +1218,7 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status)
* -1 - several matches.
* 0 - operation is found.
*/
-static int find_operation(struct nandsim *ns, uint32_t flag)
+static int ns_find_operation(struct nandsim *ns, uint32_t flag)
{
int opsfound = 0;
int i, j, idx = 0;
@@ -1256,7 +1271,8 @@ static int find_operation(struct nandsim *ns, uint32_t flag)
ns->state = ns->op[ns->stateidx];
ns->nxstate = ns->op[ns->stateidx + 1];
NS_DBG("find_operation: operation found, index: %d, state: %s, nxstate %s\n",
- idx, get_state_name(ns->state), get_state_name(ns->nxstate));
+ idx, ns_get_state_name(ns->state),
+ ns_get_state_name(ns->nxstate));
return 0;
}
@@ -1264,13 +1280,13 @@ static int find_operation(struct nandsim *ns, uint32_t flag)
/* Nothing was found. Try to ignore previous commands (if any) and search again */
if (ns->npstates != 0) {
NS_DBG("find_operation: no operation found, try again with state %s\n",
- get_state_name(ns->state));
+ ns_get_state_name(ns->state));
ns->npstates = 0;
- return find_operation(ns, 0);
+ return ns_find_operation(ns, 0);
}
NS_DBG("find_operation: no operations found\n");
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return -2;
}
@@ -1287,7 +1303,7 @@ static int find_operation(struct nandsim *ns, uint32_t flag)
return -1;
}
-static void put_pages(struct nandsim *ns)
+static void ns_put_pages(struct nandsim *ns)
{
int i;
@@ -1296,7 +1312,8 @@ static void put_pages(struct nandsim *ns)
}
/* Get page cache pages in advance to provide NOFS memory allocation */
-static int get_pages(struct nandsim *ns, struct file *file, size_t count, loff_t pos)
+static int ns_get_pages(struct nandsim *ns, struct file *file, size_t count,
+ loff_t pos)
{
pgoff_t index, start_index, end_index;
struct page *page;
@@ -1316,7 +1333,7 @@ static int get_pages(struct nandsim *ns, struct file *file, size_t count, loff_t
page = find_or_create_page(mapping, index, GFP_NOFS);
}
if (page == NULL) {
- put_pages(ns);
+ ns_put_pages(ns);
return -ENOMEM;
}
unlock_page(page);
@@ -1326,35 +1343,37 @@ static int get_pages(struct nandsim *ns, struct file *file, size_t count, loff_t
return 0;
}
-static ssize_t read_file(struct nandsim *ns, struct file *file, void *buf, size_t count, loff_t pos)
+static ssize_t ns_read_file(struct nandsim *ns, struct file *file, void *buf,
+ size_t count, loff_t pos)
{
ssize_t tx;
int err;
unsigned int noreclaim_flag;
- err = get_pages(ns, file, count, pos);
+ err = ns_get_pages(ns, file, count, pos);
if (err)
return err;
noreclaim_flag = memalloc_noreclaim_save();
tx = kernel_read(file, buf, count, &pos);
memalloc_noreclaim_restore(noreclaim_flag);
- put_pages(ns);
+ ns_put_pages(ns);
return tx;
}
-static ssize_t write_file(struct nandsim *ns, struct file *file, void *buf, size_t count, loff_t pos)
+static ssize_t ns_write_file(struct nandsim *ns, struct file *file, void *buf,
+ size_t count, loff_t pos)
{
ssize_t tx;
int err;
unsigned int noreclaim_flag;
- err = get_pages(ns, file, count, pos);
+ err = ns_get_pages(ns, file, count, pos);
if (err)
return err;
noreclaim_flag = memalloc_noreclaim_save();
tx = kernel_write(file, buf, count, &pos);
memalloc_noreclaim_restore(noreclaim_flag);
- put_pages(ns);
+ ns_put_pages(ns);
return tx;
}
@@ -1374,11 +1393,11 @@ static inline u_char *NS_PAGE_BYTE_OFF(struct nandsim *ns)
return NS_GET_PAGE(ns)->byte + ns->regs.column + ns->regs.off;
}
-static int do_read_error(struct nandsim *ns, int num)
+static int ns_do_read_error(struct nandsim *ns, int num)
{
unsigned int page_no = ns->regs.row;
- if (read_error(page_no)) {
+ if (ns_read_error(page_no)) {
prandom_bytes(ns->buf.byte, num);
NS_WARN("simulating read error in page %u\n", page_no);
return 1;
@@ -1386,7 +1405,7 @@ static int do_read_error(struct nandsim *ns, int num)
return 0;
}
-static void do_bit_flips(struct nandsim *ns, int num)
+static void ns_do_bit_flips(struct nandsim *ns, int num)
{
if (bitflips && prandom_u32() < (1 << 22)) {
int flips = 1;
@@ -1406,7 +1425,7 @@ static void do_bit_flips(struct nandsim *ns, int num)
/*
* Fill the NAND buffer with data read from the specified page.
*/
-static void read_page(struct nandsim *ns, int num)
+static void ns_read_page(struct nandsim *ns, int num)
{
union ns_mem *mypage;
@@ -1420,15 +1439,16 @@ static void read_page(struct nandsim *ns, int num)
NS_DBG("read_page: page %d written, reading from %d\n",
ns->regs.row, ns->regs.column + ns->regs.off);
- if (do_read_error(ns, num))
+ if (ns_do_read_error(ns, num))
return;
pos = (loff_t)NS_RAW_OFFSET(ns) + ns->regs.off;
- tx = read_file(ns, ns->cfile, ns->buf.byte, num, pos);
+ tx = ns_read_file(ns, ns->cfile, ns->buf.byte, num,
+ pos);
if (tx != num) {
NS_ERR("read_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx);
return;
}
- do_bit_flips(ns, num);
+ ns_do_bit_flips(ns, num);
}
return;
}
@@ -1440,17 +1460,17 @@ static void read_page(struct nandsim *ns, int num)
} else {
NS_DBG("read_page: page %d allocated, reading from %d\n",
ns->regs.row, ns->regs.column + ns->regs.off);
- if (do_read_error(ns, num))
+ if (ns_do_read_error(ns, num))
return;
memcpy(ns->buf.byte, NS_PAGE_BYTE_OFF(ns), num);
- do_bit_flips(ns, num);
+ ns_do_bit_flips(ns, num);
}
}
/*
* Erase all pages in the specified sector.
*/
-static void erase_sector(struct nandsim *ns)
+static void ns_erase_sector(struct nandsim *ns)
{
union ns_mem *mypage;
int i;
@@ -1478,7 +1498,7 @@ static void erase_sector(struct nandsim *ns)
/*
* Program the specified page with the contents from the NAND buffer.
*/
-static int prog_page(struct nandsim *ns, int num)
+static int ns_prog_page(struct nandsim *ns, int num)
{
int i;
union ns_mem *mypage;
@@ -1497,7 +1517,7 @@ static int prog_page(struct nandsim *ns, int num)
memset(ns->file_buf, 0xff, ns->geom.pgszoob);
} else {
all = 0;
- tx = read_file(ns, ns->cfile, pg_off, num, off);
+ tx = ns_read_file(ns, ns->cfile, pg_off, num, off);
if (tx != num) {
NS_ERR("prog_page: read error for page %d ret %ld\n", ns->regs.row, (long)tx);
return -1;
@@ -1507,14 +1527,15 @@ static int prog_page(struct nandsim *ns, int num)
pg_off[i] &= ns->buf.byte[i];
if (all) {
loff_t pos = (loff_t)ns->regs.row * ns->geom.pgszoob;
- tx = write_file(ns, ns->cfile, ns->file_buf, ns->geom.pgszoob, pos);
+ tx = ns_write_file(ns, ns->cfile, ns->file_buf,
+ ns->geom.pgszoob, pos);
if (tx != ns->geom.pgszoob) {
NS_ERR("prog_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx);
return -1;
}
__set_bit(ns->regs.row, ns->pages_written);
} else {
- tx = write_file(ns, ns->cfile, pg_off, num, off);
+ tx = ns_write_file(ns, ns->cfile, pg_off, num, off);
if (tx != num) {
NS_ERR("prog_page: write error for page %d ret %ld\n", ns->regs.row, (long)tx);
return -1;
@@ -1552,7 +1573,7 @@ static int prog_page(struct nandsim *ns, int num)
*
* RETURNS: 0 if success, -1 if error.
*/
-static int do_state_action(struct nandsim *ns, uint32_t action)
+static int ns_do_state_action(struct nandsim *ns, uint32_t action)
{
int num;
int busdiv = ns->busw == 8 ? 1 : 2;
@@ -1579,7 +1600,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action)
break;
}
num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
- read_page(ns, num);
+ ns_read_page(ns, num);
NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
num, NS_RAW_OFFSET(ns) + ns->regs.off);
@@ -1622,14 +1643,14 @@ static int do_state_action(struct nandsim *ns, uint32_t action)
ns->regs.row, NS_RAW_OFFSET(ns));
NS_LOG("erase sector %u\n", erase_block_no);
- erase_sector(ns);
+ ns_erase_sector(ns);
NS_MDELAY(erase_delay);
if (erase_block_wear)
- update_wear(erase_block_no);
+ ns_update_wear(erase_block_no);
- if (erase_error(erase_block_no)) {
+ if (ns_erase_error(erase_block_no)) {
NS_WARN("simulating erase failure in erase block %u\n", erase_block_no);
return -1;
}
@@ -1653,7 +1674,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action)
return -1;
}
- if (prog_page(ns, num) == -1)
+ if (ns_prog_page(ns, num) == -1)
return -1;
page_no = ns->regs.row;
@@ -1665,7 +1686,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action)
NS_UDELAY(programm_delay);
NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
- if (write_error(page_no)) {
+ if (ns_write_error(page_no)) {
NS_WARN("simulating write failure in page %u\n", page_no);
return -1;
}
@@ -1702,7 +1723,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action)
/*
* Switch simulator's state.
*/
-static void switch_state(struct nandsim *ns)
+static void ns_switch_state(struct nandsim *ns)
{
if (ns->op) {
/*
@@ -1716,11 +1737,13 @@ static void switch_state(struct nandsim *ns)
NS_DBG("switch_state: operation is known, switch to the next state, "
"state: %s, nxstate: %s\n",
- get_state_name(ns->state), get_state_name(ns->nxstate));
+ ns_get_state_name(ns->state),
+ ns_get_state_name(ns->nxstate));
/* See, whether we need to do some action */
- if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ if ((ns->state & ACTION_MASK) &&
+ ns_do_state_action(ns, ns->state) < 0) {
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
@@ -1734,15 +1757,16 @@ static void switch_state(struct nandsim *ns)
* The only event causing the switch_state function to
* be called with yet unknown operation is new command.
*/
- ns->state = get_state_by_command(ns->regs.command);
+ ns->state = ns_get_state_by_command(ns->regs.command);
NS_DBG("switch_state: operation is unknown, try to find it\n");
- if (find_operation(ns, 0) != 0)
+ if (!ns_find_operation(ns, 0))
return;
- if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ if ((ns->state & ACTION_MASK) &&
+ ns_do_state_action(ns, ns->state) < 0) {
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
}
@@ -1770,7 +1794,7 @@ static void switch_state(struct nandsim *ns)
NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
- switch_to_ready_state(ns, status);
+ ns_switch_to_ready_state(ns, status);
return;
} else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
@@ -1784,7 +1808,8 @@ static void switch_state(struct nandsim *ns)
NS_DBG("switch_state: the next state is data I/O, switch, "
"state: %s, nxstate: %s\n",
- get_state_name(ns->state), get_state_name(ns->nxstate));
+ ns_get_state_name(ns->state),
+ ns_get_state_name(ns->nxstate));
/*
* Set the internal register to the count of bytes which
@@ -1862,8 +1887,8 @@ static u_char ns_nand_read_byte(struct nand_chip *chip)
return outb;
}
if (!(ns->state & STATE_DATAOUT_MASK)) {
- NS_WARN("read_byte: unexpected data output cycle, state is %s "
- "return %#x\n", get_state_name(ns->state), (uint)outb);
+ NS_WARN("read_byte: unexpected data output cycle, state is %s return %#x\n",
+ ns_get_state_name(ns->state), (uint)outb);
return outb;
}
@@ -1902,7 +1927,7 @@ static u_char ns_nand_read_byte(struct nand_chip *chip)
NS_DBG("read_byte: all bytes were read\n");
if (NS_STATE(ns->nxstate) == STATE_READY)
- switch_state(ns);
+ ns_switch_state(ns);
}
return outb;
@@ -1929,12 +1954,12 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
if (byte == NAND_CMD_RESET) {
NS_LOG("reset chip\n");
- switch_to_ready_state(ns, NS_STATUS_OK(ns));
+ ns_switch_to_ready_state(ns, NS_STATUS_OK(ns));
return;
}
/* Check that the command byte is correct */
- if (check_command(byte)) {
+ if (ns_check_command(byte)) {
NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
return;
}
@@ -1943,7 +1968,7 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
|| NS_STATE(ns->state) == STATE_DATAOUT) {
int row = ns->regs.row;
- switch_state(ns);
+ ns_switch_state(ns);
if (byte == NAND_CMD_RNDOUT)
ns->regs.row = row;
}
@@ -1958,16 +1983,17 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
* was expected but command was input. In this case ignore
* previous command(s)/state(s) and accept the last one.
*/
- NS_WARN("write_byte: command (%#x) wasn't expected, expected state is %s, "
- "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
+ NS_WARN("write_byte: command (%#x) wasn't expected, expected state is %s, ignore previous states\n",
+ (uint)byte,
+ ns_get_state_name(ns->nxstate));
}
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
}
NS_DBG("command byte corresponding to %s state accepted\n",
- get_state_name(get_state_by_command(byte)));
+ ns_get_state_name(ns_get_state_by_command(byte)));
ns->regs.command = byte;
- switch_state(ns);
+ ns_switch_state(ns);
} else if (ns->lines.ale == 1) {
/*
@@ -1978,11 +2004,13 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
NS_DBG("write_byte: operation isn't known yet, identify it\n");
- if (find_operation(ns, 1) < 0)
+ if (ns_find_operation(ns, 1) < 0)
return;
- if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ if ((ns->state & ACTION_MASK) &&
+ ns_do_state_action(ns, ns->state) < 0) {
+ ns_switch_to_ready_state(ns,
+ NS_STATUS_FAILED(ns));
return;
}
@@ -2004,20 +2032,20 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
/* Check that chip is expecting address */
if (!(ns->nxstate & STATE_ADDR_MASK)) {
- NS_ERR("write_byte: address (%#x) isn't expected, expected state is %s, "
- "switch to STATE_READY\n", (uint)byte, get_state_name(ns->nxstate));
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ NS_ERR("write_byte: address (%#x) isn't expected, expected state is %s, switch to STATE_READY\n",
+ (uint)byte, ns_get_state_name(ns->nxstate));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
/* Check if this is expected byte */
if (ns->regs.count == ns->regs.num) {
NS_ERR("write_byte: no more address bytes expected\n");
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
- accept_addr_byte(ns, byte);
+ ns_accept_addr_byte(ns, byte);
ns->regs.count += 1;
@@ -2026,7 +2054,7 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
if (ns->regs.count == ns->regs.num) {
NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
- switch_state(ns);
+ ns_switch_state(ns);
}
} else {
@@ -2036,10 +2064,10 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte)
/* Check that chip is expecting data input */
if (!(ns->state & STATE_DATAIN_MASK)) {
- NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
- "switch to %s\n", (uint)byte,
- get_state_name(ns->state), get_state_name(STATE_READY));
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, switch to %s\n",
+ (uint)byte, ns_get_state_name(ns->state),
+ ns_get_state_name(STATE_READY));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
@@ -2069,16 +2097,16 @@ static void ns_nand_write_buf(struct nand_chip *chip, const u_char *buf,
/* Check that chip is expecting data input */
if (!(ns->state & STATE_DATAIN_MASK)) {
- NS_ERR("write_buf: data input isn't expected, state is %s, "
- "switch to STATE_READY\n", get_state_name(ns->state));
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ NS_ERR("write_buf: data input isn't expected, state is %s, switch to STATE_READY\n",
+ ns_get_state_name(ns->state));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
/* Check if these are expected bytes */
if (ns->regs.count + len > ns->regs.num) {
NS_ERR("write_buf: too many input bytes\n");
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
@@ -2105,7 +2133,7 @@ static void ns_nand_read_buf(struct nand_chip *chip, u_char *buf, int len)
}
if (!(ns->state & STATE_DATAOUT_MASK)) {
NS_WARN("read_buf: unexpected data output cycle, current state is %s\n",
- get_state_name(ns->state));
+ ns_get_state_name(ns->state));
return;
}
@@ -2121,7 +2149,7 @@ static void ns_nand_read_buf(struct nand_chip *chip, u_char *buf, int len)
/* Check if these are expected bytes */
if (ns->regs.count + len > ns->regs.num) {
NS_ERR("read_buf: too many bytes to read\n");
- switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+ ns_switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return;
}
@@ -2130,7 +2158,7 @@ static void ns_nand_read_buf(struct nand_chip *chip, u_char *buf, int len)
if (ns->regs.count == ns->regs.num) {
if (NS_STATE(ns->nxstate) == STATE_READY)
- switch_state(ns);
+ ns_switch_state(ns);
}
return;
@@ -2144,6 +2172,9 @@ static int ns_exec_op(struct nand_chip *chip, const struct nand_operation *op,
const struct nand_op_instr *instr = NULL;
struct nandsim *ns = nand_get_controller_data(chip);
+ if (check_only)
+ return 0;
+
ns->lines.ce = 1;
for (op_id = 0; op_id < op->ninstrs; op_id++) {
@@ -2224,9 +2255,10 @@ static const struct nand_controller_ops ns_controller_ops = {
*/
static int __init ns_init_module(void)
{
+ struct list_head *pos, *n;
struct nand_chip *chip;
struct nandsim *ns;
- int retval = -ENOMEM, i;
+ int ret;
if (bus_width != 8 && bus_width != 16) {
NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
@@ -2259,8 +2291,8 @@ static int __init ns_init_module(void)
break;
default:
NS_ERR("bbt has to be 0..2\n");
- retval = -EINVAL;
- goto error;
+ ret = -EINVAL;
+ goto free_ns_struct;
}
/*
* Perform minimum nandsim structure initialization to handle
@@ -2285,23 +2317,26 @@ static int __init ns_init_module(void)
nsmtd->owner = THIS_MODULE;
- if ((retval = parse_weakblocks()) != 0)
- goto error;
+ ret = ns_parse_weakblocks();
+ if (ret)
+ goto free_ns_struct;
- if ((retval = parse_weakpages()) != 0)
- goto error;
+ ret = ns_parse_weakpages();
+ if (ret)
+ goto free_wb_list;
- if ((retval = parse_gravepages()) != 0)
- goto error;
+ ret = ns_parse_gravepages();
+ if (ret)
+ goto free_wp_list;
nand_controller_init(&ns->base);
ns->base.ops = &ns_controller_ops;
chip->controller = &ns->base;
- retval = nand_scan(chip, 1);
- if (retval) {
+ ret = nand_scan(chip, 1);
+ if (ret) {
NS_ERR("Could not scan NAND Simulator device\n");
- goto error;
+ goto free_gp_list;
}
if (overridesize) {
@@ -2313,8 +2348,8 @@ static int __init ns_init_module(void)
if (new_size >> overridesize != nsmtd->erasesize) {
NS_ERR("overridesize is too big\n");
- retval = -EINVAL;
- goto err_exit;
+ ret = -EINVAL;
+ goto cleanup_nand;
}
/* N.B. This relies on nand_scan not doing anything with the size before we change it */
@@ -2325,39 +2360,60 @@ static int __init ns_init_module(void)
chip->pagemask = (targetsize >> chip->page_shift) - 1;
}
- if ((retval = setup_wear_reporting(nsmtd)) != 0)
- goto err_exit;
+ ret = ns_setup_wear_reporting(nsmtd);
+ if (ret)
+ goto cleanup_nand;
- if ((retval = init_nandsim(nsmtd)) != 0)
- goto err_exit;
+ ret = ns_init(nsmtd);
+ if (ret)
+ goto free_ebw;
- if ((retval = nand_create_bbt(chip)) != 0)
- goto err_exit;
+ ret = nand_create_bbt(chip);
+ if (ret)
+ goto free_ns_object;
- if ((retval = parse_badblocks(ns, nsmtd)) != 0)
- goto err_exit;
+ ret = ns_parse_badblocks(ns, nsmtd);
+ if (ret)
+ goto free_ns_object;
/* Register NAND partitions */
- retval = mtd_device_register(nsmtd, &ns->partitions[0],
- ns->nbparts);
- if (retval != 0)
- goto err_exit;
+ ret = mtd_device_register(nsmtd, &ns->partitions[0], ns->nbparts);
+ if (ret)
+ goto free_ns_object;
- if ((retval = nandsim_debugfs_create(ns)) != 0)
- goto err_exit;
+ ret = ns_debugfs_create(ns);
+ if (ret)
+ goto unregister_mtd;
return 0;
-err_exit:
- free_nandsim(ns);
- nand_release(chip);
- for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i)
- kfree(ns->partitions[i].name);
-error:
+unregister_mtd:
+ WARN_ON(mtd_device_unregister(nsmtd));
+free_ns_object:
+ ns_free(ns);
+free_ebw:
+ kfree(erase_block_wear);
+cleanup_nand:
+ nand_cleanup(chip);
+free_gp_list:
+ list_for_each_safe(pos, n, &grave_pages) {
+ list_del(pos);
+ kfree(list_entry(pos, struct grave_page, list));
+ }
+free_wp_list:
+ list_for_each_safe(pos, n, &weak_pages) {
+ list_del(pos);
+ kfree(list_entry(pos, struct weak_page, list));
+ }
+free_wb_list:
+ list_for_each_safe(pos, n, &weak_blocks) {
+ list_del(pos);
+ kfree(list_entry(pos, struct weak_block, list));
+ }
+free_ns_struct:
kfree(ns);
- free_lists();
- return retval;
+ return ret;
}
module_init(ns_init_module);
@@ -2369,14 +2425,30 @@ static void __exit ns_cleanup_module(void)
{
struct nand_chip *chip = mtd_to_nand(nsmtd);
struct nandsim *ns = nand_get_controller_data(chip);
- int i;
+ struct list_head *pos, *n;
- free_nandsim(ns); /* Free nandsim private resources */
- nand_release(chip); /* Unregister driver */
- for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i)
- kfree(ns->partitions[i].name);
- kfree(ns); /* Free other structures */
- free_lists();
+ ns_debugfs_remove(ns);
+ WARN_ON(mtd_device_unregister(nsmtd));
+ ns_free(ns);
+ kfree(erase_block_wear);
+ nand_cleanup(chip);
+
+ list_for_each_safe(pos, n, &grave_pages) {
+ list_del(pos);
+ kfree(list_entry(pos, struct grave_page, list));
+ }
+
+ list_for_each_safe(pos, n, &weak_pages) {
+ list_del(pos);
+ kfree(list_entry(pos, struct weak_page, list));
+ }
+
+ list_for_each_safe(pos, n, &weak_blocks) {
+ list_del(pos);
+ kfree(list_entry(pos, struct weak_block, list));
+ }
+
+ kfree(ns);
}
module_exit(ns_cleanup_module);
diff --git a/drivers/mtd/nand/raw/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
index d324396ab7ff..ed38338c1383 100644
--- a/drivers/mtd/nand/raw/ndfc.c
+++ b/drivers/mtd/nand/raw/ndfc.c
@@ -244,9 +244,13 @@ static int ndfc_probe(struct platform_device *ofdev)
static int ndfc_remove(struct platform_device *ofdev)
{
struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev);
- struct mtd_info *mtd = nand_to_mtd(&ndfc->chip);
+ struct nand_chip *chip = &ndfc->chip;
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ int ret;
- nand_release(&ndfc->chip);
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(chip);
kfree(mtd->name);
return 0;
diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c
index ad77c112a78a..eb7fcfd9276b 100644
--- a/drivers/mtd/nand/raw/omap2.c
+++ b/drivers/mtd/nand/raw/omap2.c
@@ -2283,14 +2283,18 @@ static int omap_nand_remove(struct platform_device *pdev)
struct mtd_info *mtd = platform_get_drvdata(pdev);
struct nand_chip *nand_chip = mtd_to_nand(mtd);
struct omap_nand_info *info = mtd_to_omap(mtd);
+ int ret;
+
if (nand_chip->ecc.priv) {
nand_bch_free(nand_chip->ecc.priv);
nand_chip->ecc.priv = NULL;
}
if (info->dma)
dma_release_channel(info->dma);
- nand_release(nand_chip);
- return 0;
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(nand_chip);
+ return ret;
}
static const struct of_device_id omap_nand_ids[] = {
diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c
index 3fa0e2cbbe53..078b1022ac2a 100644
--- a/drivers/mtd/nand/raw/omap_elm.c
+++ b/drivers/mtd/nand/raw/omap_elm.c
@@ -411,6 +411,7 @@ static int elm_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
if (pm_runtime_get_sync(&pdev->dev) < 0) {
ret = -EINVAL;
+ pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
dev_err(&pdev->dev, "can't enable clock\n");
return ret;
diff --git a/drivers/mtd/nand/raw/orion_nand.c b/drivers/mtd/nand/raw/orion_nand.c
index d27b39a7223c..880b54ca1b41 100644
--- a/drivers/mtd/nand/raw/orion_nand.c
+++ b/drivers/mtd/nand/raw/orion_nand.c
@@ -180,7 +180,7 @@ static int __init orion_nand_probe(struct platform_device *pdev)
mtd->name = "orion_nand";
ret = mtd_device_register(mtd, board->parts, board->nr_parts);
if (ret) {
- nand_release(nc);
+ nand_cleanup(nc);
goto no_dev;
}
@@ -195,8 +195,12 @@ static int orion_nand_remove(struct platform_device *pdev)
{
struct orion_nand_info *info = platform_get_drvdata(pdev);
struct nand_chip *chip = &info->chip;
+ int ret;
- nand_release(chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+
+ nand_cleanup(chip);
clk_disable_unprepare(info->clk);
diff --git a/drivers/mtd/nand/raw/oxnas_nand.c b/drivers/mtd/nand/raw/oxnas_nand.c
index c43cb4d92d3d..8d0d76ad319d 100644
--- a/drivers/mtd/nand/raw/oxnas_nand.c
+++ b/drivers/mtd/nand/raw/oxnas_nand.c
@@ -32,6 +32,7 @@ struct oxnas_nand_ctrl {
void __iomem *io_base;
struct clk *clk;
struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
+ unsigned int nchips;
};
static uint8_t oxnas_nand_read_byte(struct nand_chip *chip)
@@ -79,9 +80,9 @@ static int oxnas_nand_probe(struct platform_device *pdev)
struct nand_chip *chip;
struct mtd_info *mtd;
struct resource *res;
- int nchips = 0;
int count = 0;
int err = 0;
+ int i;
/* Allocate memory for the device structure (and zero it) */
oxnas = devm_kzalloc(&pdev->dev, sizeof(*oxnas),
@@ -140,17 +141,15 @@ static int oxnas_nand_probe(struct platform_device *pdev)
goto err_release_child;
err = mtd_device_register(mtd, NULL, 0);
- if (err) {
- nand_release(chip);
- goto err_release_child;
- }
+ if (err)
+ goto err_cleanup_nand;
- oxnas->chips[nchips] = chip;
- ++nchips;
+ oxnas->chips[oxnas->nchips] = chip;
+ ++oxnas->nchips;
}
/* Exit if no chips found */
- if (!nchips) {
+ if (!oxnas->nchips) {
err = -ENODEV;
goto err_clk_unprepare;
}
@@ -159,8 +158,17 @@ static int oxnas_nand_probe(struct platform_device *pdev)
return 0;
+err_cleanup_nand:
+ nand_cleanup(chip);
err_release_child:
of_node_put(nand_np);
+
+ for (i = 0; i < oxnas->nchips; i++) {
+ chip = oxnas->chips[i];
+ WARN_ON(mtd_device_unregister(nand_to_mtd(chip)));
+ nand_cleanup(chip);
+ }
+
err_clk_unprepare:
clk_disable_unprepare(oxnas->clk);
return err;
@@ -169,9 +177,14 @@ err_clk_unprepare:
static int oxnas_nand_remove(struct platform_device *pdev)
{
struct oxnas_nand_ctrl *oxnas = platform_get_drvdata(pdev);
+ struct nand_chip *chip;
+ int i;
- if (oxnas->chips[0])
- nand_release(oxnas->chips[0]);
+ for (i = 0; i < oxnas->nchips; i++) {
+ chip = oxnas->chips[i];
+ WARN_ON(mtd_device_unregister(nand_to_mtd(chip)));
+ nand_cleanup(chip);
+ }
clk_disable_unprepare(oxnas->clk);
diff --git a/drivers/mtd/nand/raw/pasemi_nand.c b/drivers/mtd/nand/raw/pasemi_nand.c
index 9cfe7395172a..d8eca8c3fdcd 100644
--- a/drivers/mtd/nand/raw/pasemi_nand.c
+++ b/drivers/mtd/nand/raw/pasemi_nand.c
@@ -146,7 +146,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev)
if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) {
dev_err(dev, "Unable to register MTD device\n");
err = -ENODEV;
- goto out_lpc;
+ goto out_cleanup_nand;
}
dev_info(dev, "PA Semi NAND flash at %pR, control at I/O %x\n", &res,
@@ -154,6 +154,8 @@ static int pasemi_nand_probe(struct platform_device *ofdev)
return 0;
+ out_cleanup_nand:
+ nand_cleanup(chip);
out_lpc:
release_region(lpcctl, 4);
out_ior:
@@ -167,6 +169,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev)
static int pasemi_nand_remove(struct platform_device *ofdev)
{
struct nand_chip *chip;
+ int ret;
if (!pasemi_nand_mtd)
return 0;
@@ -174,7 +177,9 @@ static int pasemi_nand_remove(struct platform_device *ofdev)
chip = mtd_to_nand(pasemi_nand_mtd);
/* Release resources, unregister device */
- nand_release(chip);
+ ret = mtd_device_unregister(pasemi_nand_mtd);
+ WARN_ON(ret);
+ nand_cleanup(chip);
release_region(lpcctl, 4);
diff --git a/drivers/mtd/nand/raw/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c
index dc0f3074ddbf..556182f26057 100644
--- a/drivers/mtd/nand/raw/plat_nand.c
+++ b/drivers/mtd/nand/raw/plat_nand.c
@@ -92,7 +92,7 @@ static int plat_nand_probe(struct platform_device *pdev)
if (!err)
return err;
- nand_release(&data->chip);
+ nand_cleanup(&data->chip);
out:
if (pdata->ctrl.remove)
pdata->ctrl.remove(pdev);
@@ -106,8 +106,12 @@ static int plat_nand_remove(struct platform_device *pdev)
{
struct plat_nand_data *data = platform_get_drvdata(pdev);
struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev);
+ struct nand_chip *chip = &data->chip;
+ int ret;
- nand_release(&data->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
if (pdata->ctrl.remove)
pdata->ctrl.remove(pdev);
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 5b11c7061497..f1daf330951b 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2836,7 +2836,7 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
chip->legacy.block_markbad = qcom_nandc_block_markbad;
chip->controller = &nandc->controller;
- chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER |
+ chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA |
NAND_SKIP_BBTSCAN;
/* set up initial status value */
@@ -3005,10 +3005,15 @@ static int qcom_nandc_remove(struct platform_device *pdev)
struct qcom_nand_controller *nandc = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct qcom_nand_host *host;
+ struct nand_chip *chip;
+ int ret;
- list_for_each_entry(host, &nandc->host_list, node)
- nand_release(&host->chip);
-
+ list_for_each_entry(host, &nandc->host_list, node) {
+ chip = &host->chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ }
qcom_nandc_unalloc(nandc);
diff --git a/drivers/mtd/nand/raw/r852.c b/drivers/mtd/nand/raw/r852.c
index 77774250fb11..f865e3a47b01 100644
--- a/drivers/mtd/nand/raw/r852.c
+++ b/drivers/mtd/nand/raw/r852.c
@@ -651,7 +651,8 @@ static int r852_register_nand_device(struct r852_device *dev)
dev->card_registered = 1;
return 0;
error3:
- nand_release(dev->chip);
+ WARN_ON(mtd_device_unregister(nand_to_mtd(dev->chip)));
+ nand_cleanup(dev->chip);
error1:
/* Force card redetect */
dev->card_detected = 0;
@@ -670,7 +671,8 @@ static void r852_unregister_nand_device(struct r852_device *dev)
return;
device_remove_file(&mtd->dev, &dev_attr_media_type);
- nand_release(dev->chip);
+ WARN_ON(mtd_device_unregister(mtd));
+ nand_cleanup(dev->chip);
r852_engine_disable(dev);
dev->card_registered = 0;
}
diff --git a/drivers/mtd/nand/raw/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c
index 0009c1820e21..f86dff311464 100644
--- a/drivers/mtd/nand/raw/s3c2410.c
+++ b/drivers/mtd/nand/raw/s3c2410.c
@@ -779,7 +779,8 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) {
pr_debug("releasing mtd %d (%p)\n", mtdno, ptr);
- nand_release(&ptr->chip);
+ WARN_ON(mtd_device_unregister(nand_to_mtd(&ptr->chip)));
+ nand_cleanup(&ptr->chip);
}
}
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
index 058e99d0cbcf..a661b8bb2dd5 100644
--- a/drivers/mtd/nand/raw/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -1204,9 +1204,13 @@ err_chip:
static int flctl_remove(struct platform_device *pdev)
{
struct sh_flctl *flctl = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &flctl->chip;
+ int ret;
flctl_release_dma(flctl);
- nand_release(&flctl->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
pm_runtime_disable(&pdev->dev);
return 0;
diff --git a/drivers/mtd/nand/raw/sharpsl.c b/drivers/mtd/nand/raw/sharpsl.c
index b47a9eaff89b..51286f7acf54 100644
--- a/drivers/mtd/nand/raw/sharpsl.c
+++ b/drivers/mtd/nand/raw/sharpsl.c
@@ -183,7 +183,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev)
return 0;
err_add:
- nand_release(this);
+ nand_cleanup(this);
err_scan:
iounmap(sharpsl->io);
@@ -199,13 +199,19 @@ err_get_res:
static int sharpsl_nand_remove(struct platform_device *pdev)
{
struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &sharpsl->chip;
+ int ret;
- /* Release resources, unregister device */
- nand_release(&sharpsl->chip);
+ /* Unregister device */
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+
+ /* Release resources */
+ nand_cleanup(chip);
iounmap(sharpsl->io);
- /* Free the MTD device structure */
+ /* Free the driver's structure */
kfree(sharpsl);
return 0;
diff --git a/drivers/mtd/nand/raw/socrates_nand.c b/drivers/mtd/nand/raw/socrates_nand.c
index 20f40c0e812c..243b34cfbc1b 100644
--- a/drivers/mtd/nand/raw/socrates_nand.c
+++ b/drivers/mtd/nand/raw/socrates_nand.c
@@ -169,7 +169,7 @@ static int socrates_nand_probe(struct platform_device *ofdev)
if (!res)
return res;
- nand_release(nand_chip);
+ nand_cleanup(nand_chip);
out:
iounmap(host->io_base);
@@ -182,8 +182,12 @@ out:
static int socrates_nand_remove(struct platform_device *ofdev)
{
struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
+ struct nand_chip *chip = &host->nand_chip;
+ int ret;
- nand_release(&host->nand_chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
iounmap(host->io_base);
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b6d45cd911ae..65c9d17b25a3 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -4,6 +4,7 @@
* Author: Christophe Kerello <christophe.kerello@st.com>
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
@@ -37,8 +38,7 @@
/* Max ECC buffer length */
#define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
-#define FMC2_TIMEOUT_US 1000
-#define FMC2_TIMEOUT_MS 1000
+#define FMC2_TIMEOUT_MS 5000
/* Timings */
#define FMC2_THIZ 1
@@ -85,20 +85,16 @@
/* Register: FMC2_PCR */
#define FMC2_PCR_PWAITEN BIT(1)
#define FMC2_PCR_PBKEN BIT(2)
-#define FMC2_PCR_PWID_MASK GENMASK(5, 4)
-#define FMC2_PCR_PWID(x) (((x) & 0x3) << 4)
+#define FMC2_PCR_PWID GENMASK(5, 4)
#define FMC2_PCR_PWID_BUSWIDTH_8 0
#define FMC2_PCR_PWID_BUSWIDTH_16 1
#define FMC2_PCR_ECCEN BIT(6)
#define FMC2_PCR_ECCALG BIT(8)
-#define FMC2_PCR_TCLR_MASK GENMASK(12, 9)
-#define FMC2_PCR_TCLR(x) (((x) & 0xf) << 9)
+#define FMC2_PCR_TCLR GENMASK(12, 9)
#define FMC2_PCR_TCLR_DEFAULT 0xf
-#define FMC2_PCR_TAR_MASK GENMASK(16, 13)
-#define FMC2_PCR_TAR(x) (((x) & 0xf) << 13)
+#define FMC2_PCR_TAR GENMASK(16, 13)
#define FMC2_PCR_TAR_DEFAULT 0xf
-#define FMC2_PCR_ECCSS_MASK GENMASK(19, 17)
-#define FMC2_PCR_ECCSS(x) (((x) & 0x7) << 17)
+#define FMC2_PCR_ECCSS GENMASK(19, 17)
#define FMC2_PCR_ECCSS_512 1
#define FMC2_PCR_ECCSS_2048 3
#define FMC2_PCR_BCHECC BIT(24)
@@ -108,17 +104,17 @@
#define FMC2_SR_NWRF BIT(6)
/* Register: FMC2_PMEM */
-#define FMC2_PMEM_MEMSET(x) (((x) & 0xff) << 0)
-#define FMC2_PMEM_MEMWAIT(x) (((x) & 0xff) << 8)
-#define FMC2_PMEM_MEMHOLD(x) (((x) & 0xff) << 16)
-#define FMC2_PMEM_MEMHIZ(x) (((x) & 0xff) << 24)
+#define FMC2_PMEM_MEMSET GENMASK(7, 0)
+#define FMC2_PMEM_MEMWAIT GENMASK(15, 8)
+#define FMC2_PMEM_MEMHOLD GENMASK(23, 16)
+#define FMC2_PMEM_MEMHIZ GENMASK(31, 24)
#define FMC2_PMEM_DEFAULT 0x0a0a0a0a
/* Register: FMC2_PATT */
-#define FMC2_PATT_ATTSET(x) (((x) & 0xff) << 0)
-#define FMC2_PATT_ATTWAIT(x) (((x) & 0xff) << 8)
-#define FMC2_PATT_ATTHOLD(x) (((x) & 0xff) << 16)
-#define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24)
+#define FMC2_PATT_ATTSET GENMASK(7, 0)
+#define FMC2_PATT_ATTWAIT GENMASK(15, 8)
+#define FMC2_PATT_ATTHOLD GENMASK(23, 16)
+#define FMC2_PATT_ATTHIZ GENMASK(31, 24)
#define FMC2_PATT_DEFAULT 0x0a0a0a0a
/* Register: FMC2_ISR */
@@ -133,9 +129,9 @@
/* Register: FMC2_CSQCFGR1 */
#define FMC2_CSQCFGR1_CMD2EN BIT(1)
#define FMC2_CSQCFGR1_DMADEN BIT(2)
-#define FMC2_CSQCFGR1_ACYNBR(x) (((x) & 0x7) << 4)
-#define FMC2_CSQCFGR1_CMD1(x) (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR1_CMD2(x) (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR1_ACYNBR GENMASK(6, 4)
+#define FMC2_CSQCFGR1_CMD1 GENMASK(15, 8)
+#define FMC2_CSQCFGR1_CMD2 GENMASK(23, 16)
#define FMC2_CSQCFGR1_CMD1T BIT(24)
#define FMC2_CSQCFGR1_CMD2T BIT(25)
@@ -143,13 +139,13 @@
#define FMC2_CSQCFGR2_SQSDTEN BIT(0)
#define FMC2_CSQCFGR2_RCMD2EN BIT(1)
#define FMC2_CSQCFGR2_DMASEN BIT(2)
-#define FMC2_CSQCFGR2_RCMD1(x) (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR2_RCMD2(x) (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR2_RCMD1 GENMASK(15, 8)
+#define FMC2_CSQCFGR2_RCMD2 GENMASK(23, 16)
#define FMC2_CSQCFGR2_RCMD1T BIT(24)
#define FMC2_CSQCFGR2_RCMD2T BIT(25)
/* Register: FMC2_CSQCFGR3 */
-#define FMC2_CSQCFGR3_SNBR(x) (((x) & 0x1f) << 8)
+#define FMC2_CSQCFGR3_SNBR GENMASK(13, 8)
#define FMC2_CSQCFGR3_AC1T BIT(16)
#define FMC2_CSQCFGR3_AC2T BIT(17)
#define FMC2_CSQCFGR3_AC3T BIT(18)
@@ -160,15 +156,15 @@
#define FMC2_CSQCFGR3_RAC2T BIT(23)
/* Register: FMC2_CSQCAR1 */
-#define FMC2_CSQCAR1_ADDC1(x) (((x) & 0xff) << 0)
-#define FMC2_CSQCAR1_ADDC2(x) (((x) & 0xff) << 8)
-#define FMC2_CSQCAR1_ADDC3(x) (((x) & 0xff) << 16)
-#define FMC2_CSQCAR1_ADDC4(x) (((x) & 0xff) << 24)
+#define FMC2_CSQCAR1_ADDC1 GENMASK(7, 0)
+#define FMC2_CSQCAR1_ADDC2 GENMASK(15, 8)
+#define FMC2_CSQCAR1_ADDC3 GENMASK(23, 16)
+#define FMC2_CSQCAR1_ADDC4 GENMASK(31, 24)
/* Register: FMC2_CSQCAR2 */
-#define FMC2_CSQCAR2_ADDC5(x) (((x) & 0xff) << 0)
-#define FMC2_CSQCAR2_NANDCEN(x) (((x) & 0x3) << 10)
-#define FMC2_CSQCAR2_SAO(x) (((x) & 0xffff) << 16)
+#define FMC2_CSQCAR2_ADDC5 GENMASK(7, 0)
+#define FMC2_CSQCAR2_NANDCEN GENMASK(11, 10)
+#define FMC2_CSQCAR2_SAO GENMASK(31, 16)
/* Register: FMC2_CSQIER */
#define FMC2_CSQIER_TCIE BIT(0)
@@ -189,28 +185,23 @@
/* Register: FMC2_BCHDSR0 */
#define FMC2_BCHDSR0_DUE BIT(0)
#define FMC2_BCHDSR0_DEF BIT(1)
-#define FMC2_BCHDSR0_DEN_MASK GENMASK(7, 4)
-#define FMC2_BCHDSR0_DEN_SHIFT 4
+#define FMC2_BCHDSR0_DEN GENMASK(7, 4)
/* Register: FMC2_BCHDSR1 */
-#define FMC2_BCHDSR1_EBP1_MASK GENMASK(12, 0)
-#define FMC2_BCHDSR1_EBP2_MASK GENMASK(28, 16)
-#define FMC2_BCHDSR1_EBP2_SHIFT 16
+#define FMC2_BCHDSR1_EBP1 GENMASK(12, 0)
+#define FMC2_BCHDSR1_EBP2 GENMASK(28, 16)
/* Register: FMC2_BCHDSR2 */
-#define FMC2_BCHDSR2_EBP3_MASK GENMASK(12, 0)
-#define FMC2_BCHDSR2_EBP4_MASK GENMASK(28, 16)
-#define FMC2_BCHDSR2_EBP4_SHIFT 16
+#define FMC2_BCHDSR2_EBP3 GENMASK(12, 0)
+#define FMC2_BCHDSR2_EBP4 GENMASK(28, 16)
/* Register: FMC2_BCHDSR3 */
-#define FMC2_BCHDSR3_EBP5_MASK GENMASK(12, 0)
-#define FMC2_BCHDSR3_EBP6_MASK GENMASK(28, 16)
-#define FMC2_BCHDSR3_EBP6_SHIFT 16
+#define FMC2_BCHDSR3_EBP5 GENMASK(12, 0)
+#define FMC2_BCHDSR3_EBP6 GENMASK(28, 16)
/* Register: FMC2_BCHDSR4 */
-#define FMC2_BCHDSR4_EBP7_MASK GENMASK(12, 0)
-#define FMC2_BCHDSR4_EBP8_MASK GENMASK(28, 16)
-#define FMC2_BCHDSR4_EBP8_SHIFT 16
+#define FMC2_BCHDSR4_EBP7 GENMASK(12, 0)
+#define FMC2_BCHDSR4_EBP8 GENMASK(28, 16)
enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
@@ -281,43 +272,41 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_controller *base)
return container_of(base, struct stm32_fmc2_nfc, base);
}
-/* Timings configuration */
-static void stm32_fmc2_timings_init(struct nand_chip *chip)
+static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = &nand->timings;
- u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+ u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
/* Set tclr/tar timings */
- pcr &= ~FMC2_PCR_TCLR_MASK;
- pcr |= FMC2_PCR_TCLR(timings->tclr);
- pcr &= ~FMC2_PCR_TAR_MASK;
- pcr |= FMC2_PCR_TAR(timings->tar);
+ pcr &= ~FMC2_PCR_TCLR;
+ pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr);
+ pcr &= ~FMC2_PCR_TAR;
+ pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar);
/* Set tset/twait/thold/thiz timings in common bank */
- pmem = FMC2_PMEM_MEMSET(timings->tset_mem);
- pmem |= FMC2_PMEM_MEMWAIT(timings->twait);
- pmem |= FMC2_PMEM_MEMHOLD(timings->thold_mem);
- pmem |= FMC2_PMEM_MEMHIZ(timings->thiz);
+ pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem);
+ pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait);
+ pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem);
+ pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz);
/* Set tset/twait/thold/thiz timings in attribut bank */
- patt = FMC2_PATT_ATTSET(timings->tset_att);
- patt |= FMC2_PATT_ATTWAIT(timings->twait);
- patt |= FMC2_PATT_ATTHOLD(timings->thold_att);
- patt |= FMC2_PATT_ATTHIZ(timings->thiz);
-
- writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
- writel_relaxed(pmem, fmc2->io_base + FMC2_PMEM);
- writel_relaxed(patt, fmc2->io_base + FMC2_PATT);
+ patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att);
+ patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait);
+ patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att);
+ patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz);
+
+ writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
+ writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
+ writel_relaxed(patt, nfc->io_base + FMC2_PATT);
}
-/* Controller configuration */
-static void stm32_fmc2_setup(struct nand_chip *chip)
+static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
- u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
+ u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
/* Configure ECC algorithm (default configuration is Hamming) */
pcr &= ~FMC2_PCR_ECCALG;
@@ -330,195 +319,182 @@ static void stm32_fmc2_setup(struct nand_chip *chip)
}
/* Set buswidth */
- pcr &= ~FMC2_PCR_PWID_MASK;
+ pcr &= ~FMC2_PCR_PWID;
if (chip->options & NAND_BUSWIDTH_16)
- pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
+ pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16);
/* Set ECC sector size */
- pcr &= ~FMC2_PCR_ECCSS_MASK;
- pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
+ pcr &= ~FMC2_PCR_ECCSS;
+ pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512);
- writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+ writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
}
-/* Select target */
-static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr)
+static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct dma_slave_config dma_cfg;
int ret;
- if (nand->cs_used[chipnr] == fmc2->cs_sel)
+ if (nand->cs_used[chipnr] == nfc->cs_sel)
return 0;
- fmc2->cs_sel = nand->cs_used[chipnr];
+ nfc->cs_sel = nand->cs_used[chipnr];
+ stm32_fmc2_nfc_setup(chip);
+ stm32_fmc2_nfc_timings_init(chip);
- /* FMC2 setup routine */
- stm32_fmc2_setup(chip);
-
- /* Apply timings */
- stm32_fmc2_timings_init(chip);
-
- if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) {
+ if (nfc->dma_tx_ch && nfc->dma_rx_ch) {
memset(&dma_cfg, 0, sizeof(dma_cfg));
- dma_cfg.src_addr = fmc2->data_phys_addr[fmc2->cs_sel];
- dma_cfg.dst_addr = fmc2->data_phys_addr[fmc2->cs_sel];
+ dma_cfg.src_addr = nfc->data_phys_addr[nfc->cs_sel];
+ dma_cfg.dst_addr = nfc->data_phys_addr[nfc->cs_sel];
dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_cfg.src_maxburst = 32;
dma_cfg.dst_maxburst = 32;
- ret = dmaengine_slave_config(fmc2->dma_tx_ch, &dma_cfg);
+ ret = dmaengine_slave_config(nfc->dma_tx_ch, &dma_cfg);
if (ret) {
- dev_err(fmc2->dev, "tx DMA engine slave config failed\n");
+ dev_err(nfc->dev, "tx DMA engine slave config failed\n");
return ret;
}
- ret = dmaengine_slave_config(fmc2->dma_rx_ch, &dma_cfg);
+ ret = dmaengine_slave_config(nfc->dma_rx_ch, &dma_cfg);
if (ret) {
- dev_err(fmc2->dev, "rx DMA engine slave config failed\n");
+ dev_err(nfc->dev, "rx DMA engine slave config failed\n");
return ret;
}
}
- if (fmc2->dma_ecc_ch) {
+ if (nfc->dma_ecc_ch) {
/*
* Hamming: we read HECCR register
* BCH4/BCH8: we read BCHDSRSx registers
*/
memset(&dma_cfg, 0, sizeof(dma_cfg));
- dma_cfg.src_addr = fmc2->io_phys_addr;
+ dma_cfg.src_addr = nfc->io_phys_addr;
dma_cfg.src_addr += chip->ecc.strength == FMC2_ECC_HAM ?
FMC2_HECCR : FMC2_BCHDSR0;
dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- ret = dmaengine_slave_config(fmc2->dma_ecc_ch, &dma_cfg);
+ ret = dmaengine_slave_config(nfc->dma_ecc_ch, &dma_cfg);
if (ret) {
- dev_err(fmc2->dev, "ECC DMA engine slave config failed\n");
+ dev_err(nfc->dev, "ECC DMA engine slave config failed\n");
return ret;
}
/* Calculate ECC length needed for one sector */
- fmc2->dma_ecc_len = chip->ecc.strength == FMC2_ECC_HAM ?
- FMC2_HECCR_LEN : FMC2_BCHDSRS_LEN;
+ nfc->dma_ecc_len = chip->ecc.strength == FMC2_ECC_HAM ?
+ FMC2_HECCR_LEN : FMC2_BCHDSRS_LEN;
}
return 0;
}
-/* Set bus width to 16-bit or 8-bit */
-static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set)
+static void stm32_fmc2_nfc_set_buswidth_16(struct stm32_fmc2_nfc *nfc, bool set)
{
- u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+ u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
- pcr &= ~FMC2_PCR_PWID_MASK;
+ pcr &= ~FMC2_PCR_PWID;
if (set)
- pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
- writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+ pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16);
+ writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
}
-/* Enable/disable ECC */
-static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
+static void stm32_fmc2_nfc_set_ecc(struct stm32_fmc2_nfc *nfc, bool enable)
{
- u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+ u32 pcr = readl(nfc->io_base + FMC2_PCR);
pcr &= ~FMC2_PCR_ECCEN;
if (enable)
pcr |= FMC2_PCR_ECCEN;
- writel(pcr, fmc2->io_base + FMC2_PCR);
+ writel(pcr, nfc->io_base + FMC2_PCR);
}
-/* Enable irq sources in case of the sequencer is used */
-static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2)
+static inline void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc)
{
- u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER);
+ u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER);
csqier |= FMC2_CSQIER_TCIE;
- fmc2->irq_state = FMC2_IRQ_SEQ;
+ nfc->irq_state = FMC2_IRQ_SEQ;
- writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
+ writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER);
}
-/* Disable irq sources in case of the sequencer is used */
-static inline void stm32_fmc2_disable_seq_irq(struct stm32_fmc2_nfc *fmc2)
+static inline void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc)
{
- u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER);
+ u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER);
csqier &= ~FMC2_CSQIER_TCIE;
- writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
+ writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER);
- fmc2->irq_state = FMC2_IRQ_UNKNOWN;
+ nfc->irq_state = FMC2_IRQ_UNKNOWN;
}
-/* Clear irq sources in case of the sequencer is used */
-static inline void stm32_fmc2_clear_seq_irq(struct stm32_fmc2_nfc *fmc2)
+static inline void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc)
{
- writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR);
+ writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, nfc->io_base + FMC2_CSQICR);
}
-/* Enable irq sources in case of bch is used */
-static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2,
- int mode)
+static inline void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc,
+ int mode)
{
- u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+ u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER);
if (mode == NAND_ECC_WRITE)
bchier |= FMC2_BCHIER_EPBRIE;
else
bchier |= FMC2_BCHIER_DERIE;
- fmc2->irq_state = FMC2_IRQ_BCH;
+ nfc->irq_state = FMC2_IRQ_BCH;
- writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+ writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER);
}
-/* Disable irq sources in case of bch is used */
-static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2)
+static inline void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc)
{
- u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+ u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER);
bchier &= ~FMC2_BCHIER_DERIE;
bchier &= ~FMC2_BCHIER_EPBRIE;
- writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+ writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER);
- fmc2->irq_state = FMC2_IRQ_UNKNOWN;
+ nfc->irq_state = FMC2_IRQ_UNKNOWN;
}
-/* Clear irq sources in case of bch is used */
-static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
+static inline void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc)
{
- writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
+ writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, nfc->io_base + FMC2_BCHICR);
}
/*
* Enable ECC logic and reset syndrome/parity bits previously calculated
* Syndrome/parity bits is cleared by setting the ECCEN bit to 0
*/
-static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode)
+static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
- stm32_fmc2_set_ecc(fmc2, false);
+ stm32_fmc2_nfc_set_ecc(nfc, false);
if (chip->ecc.strength != FMC2_ECC_HAM) {
- u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+ u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
if (mode == NAND_ECC_WRITE)
pcr |= FMC2_PCR_WEN;
else
pcr &= ~FMC2_PCR_WEN;
- writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+ writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
- reinit_completion(&fmc2->complete);
- stm32_fmc2_clear_bch_irq(fmc2);
- stm32_fmc2_enable_bch_irq(fmc2, mode);
+ reinit_completion(&nfc->complete);
+ stm32_fmc2_nfc_clear_bch_irq(nfc);
+ stm32_fmc2_nfc_enable_bch_irq(nfc, mode);
}
- stm32_fmc2_set_ecc(fmc2, true);
+ stm32_fmc2_nfc_set_ecc(nfc, true);
}
/*
@@ -526,40 +502,37 @@ static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode)
* ECC is 3 bytes for 512 bytes of data (supports error correction up to
* max of 1-bit)
*/
-static inline void stm32_fmc2_ham_set_ecc(const u32 ecc_sta, u8 *ecc)
+static inline void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc)
{
ecc[0] = ecc_sta;
ecc[1] = ecc_sta >> 8;
ecc[2] = ecc_sta >> 16;
}
-static int stm32_fmc2_ham_calculate(struct nand_chip *chip, const u8 *data,
- u8 *ecc)
+static int stm32_fmc2_nfc_ham_calculate(struct nand_chip *chip, const u8 *data,
+ u8 *ecc)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
u32 sr, heccr;
int ret;
- ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
- sr, sr & FMC2_SR_NWRF, 10,
- FMC2_TIMEOUT_MS);
+ ret = readl_relaxed_poll_timeout(nfc->io_base + FMC2_SR,
+ sr, sr & FMC2_SR_NWRF, 1,
+ 1000 * FMC2_TIMEOUT_MS);
if (ret) {
- dev_err(fmc2->dev, "ham timeout\n");
+ dev_err(nfc->dev, "ham timeout\n");
return ret;
}
- heccr = readl_relaxed(fmc2->io_base + FMC2_HECCR);
-
- stm32_fmc2_ham_set_ecc(heccr, ecc);
-
- /* Disable ECC */
- stm32_fmc2_set_ecc(fmc2, false);
+ heccr = readl_relaxed(nfc->io_base + FMC2_HECCR);
+ stm32_fmc2_nfc_ham_set_ecc(heccr, ecc);
+ stm32_fmc2_nfc_set_ecc(nfc, false);
return 0;
}
-static int stm32_fmc2_ham_correct(struct nand_chip *chip, u8 *dat,
- u8 *read_ecc, u8 *calc_ecc)
+static int stm32_fmc2_nfc_ham_correct(struct nand_chip *chip, u8 *dat,
+ u8 *read_ecc, u8 *calc_ecc)
{
u8 bit_position = 0, b0, b1, b2;
u32 byte_addr = 0, b;
@@ -615,28 +588,28 @@ static int stm32_fmc2_ham_correct(struct nand_chip *chip, u8 *dat,
* ECC is 7/13 bytes for 512 bytes of data (supports error correction up to
* max of 4-bit/8-bit)
*/
-static int stm32_fmc2_bch_calculate(struct nand_chip *chip, const u8 *data,
- u8 *ecc)
+static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data,
+ u8 *ecc)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
u32 bchpbr;
/* Wait until the BCH code is ready */
- if (!wait_for_completion_timeout(&fmc2->complete,
+ if (!wait_for_completion_timeout(&nfc->complete,
msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
- dev_err(fmc2->dev, "bch timeout\n");
- stm32_fmc2_disable_bch_irq(fmc2);
+ dev_err(nfc->dev, "bch timeout\n");
+ stm32_fmc2_nfc_disable_bch_irq(nfc);
return -ETIMEDOUT;
}
/* Read parity bits */
- bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR1);
+ bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR1);
ecc[0] = bchpbr;
ecc[1] = bchpbr >> 8;
ecc[2] = bchpbr >> 16;
ecc[3] = bchpbr >> 24;
- bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR2);
+ bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR2);
ecc[4] = bchpbr;
ecc[5] = bchpbr >> 8;
ecc[6] = bchpbr >> 16;
@@ -644,24 +617,22 @@ static int stm32_fmc2_bch_calculate(struct nand_chip *chip, const u8 *data,
if (chip->ecc.strength == FMC2_ECC_BCH8) {
ecc[7] = bchpbr >> 24;
- bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR3);
+ bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR3);
ecc[8] = bchpbr;
ecc[9] = bchpbr >> 8;
ecc[10] = bchpbr >> 16;
ecc[11] = bchpbr >> 24;
- bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR4);
+ bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR4);
ecc[12] = bchpbr;
}
- /* Disable ECC */
- stm32_fmc2_set_ecc(fmc2, false);
+ stm32_fmc2_nfc_set_ecc(nfc, false);
return 0;
}
-/* BCH algorithm correction */
-static int stm32_fmc2_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta)
+static int stm32_fmc2_nfc_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta)
{
u32 bchdsr0 = ecc_sta[0];
u32 bchdsr1 = ecc_sta[1];
@@ -680,16 +651,16 @@ static int stm32_fmc2_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta)
if (unlikely(bchdsr0 & FMC2_BCHDSR0_DUE))
return -EBADMSG;
- pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK;
- pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT;
- pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK;
- pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT;
- pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK;
- pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT;
- pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK;
- pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT;
+ pos[0] = FIELD_GET(FMC2_BCHDSR1_EBP1, bchdsr1);
+ pos[1] = FIELD_GET(FMC2_BCHDSR1_EBP2, bchdsr1);
+ pos[2] = FIELD_GET(FMC2_BCHDSR2_EBP3, bchdsr2);
+ pos[3] = FIELD_GET(FMC2_BCHDSR2_EBP4, bchdsr2);
+ pos[4] = FIELD_GET(FMC2_BCHDSR3_EBP5, bchdsr3);
+ pos[5] = FIELD_GET(FMC2_BCHDSR3_EBP6, bchdsr3);
+ pos[6] = FIELD_GET(FMC2_BCHDSR4_EBP7, bchdsr4);
+ pos[7] = FIELD_GET(FMC2_BCHDSR4_EBP8, bchdsr4);
- den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT;
+ den = FIELD_GET(FMC2_BCHDSR0_DEN, bchdsr0);
for (i = 0; i < den; i++) {
if (pos[i] < eccsize * 8) {
change_bit(pos[i], (unsigned long *)dat);
@@ -700,34 +671,33 @@ static int stm32_fmc2_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta)
return nb_errs;
}
-static int stm32_fmc2_bch_correct(struct nand_chip *chip, u8 *dat,
- u8 *read_ecc, u8 *calc_ecc)
+static int stm32_fmc2_nfc_bch_correct(struct nand_chip *chip, u8 *dat,
+ u8 *read_ecc, u8 *calc_ecc)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
u32 ecc_sta[5];
/* Wait until the decoding error is ready */
- if (!wait_for_completion_timeout(&fmc2->complete,
+ if (!wait_for_completion_timeout(&nfc->complete,
msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
- dev_err(fmc2->dev, "bch timeout\n");
- stm32_fmc2_disable_bch_irq(fmc2);
+ dev_err(nfc->dev, "bch timeout\n");
+ stm32_fmc2_nfc_disable_bch_irq(nfc);
return -ETIMEDOUT;
}
- ecc_sta[0] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR0);
- ecc_sta[1] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR1);
- ecc_sta[2] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR2);
- ecc_sta[3] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR3);
- ecc_sta[4] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR4);
+ ecc_sta[0] = readl_relaxed(nfc->io_base + FMC2_BCHDSR0);
+ ecc_sta[1] = readl_relaxed(nfc->io_base + FMC2_BCHDSR1);
+ ecc_sta[2] = readl_relaxed(nfc->io_base + FMC2_BCHDSR2);
+ ecc_sta[3] = readl_relaxed(nfc->io_base + FMC2_BCHDSR3);
+ ecc_sta[4] = readl_relaxed(nfc->io_base + FMC2_BCHDSR4);
- /* Disable ECC */
- stm32_fmc2_set_ecc(fmc2, false);
+ stm32_fmc2_nfc_set_ecc(nfc, false);
- return stm32_fmc2_bch_decode(chip->ecc.size, dat, ecc_sta);
+ return stm32_fmc2_nfc_bch_decode(chip->ecc.size, dat, ecc_sta);
}
-static int stm32_fmc2_read_page(struct nand_chip *chip, u8 *buf,
- int oob_required, int page)
+static int stm32_fmc2_nfc_read_page(struct nand_chip *chip, u8 *buf,
+ int oob_required, int page)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int ret, i, s, stat, eccsize = chip->ecc.size;
@@ -789,21 +759,21 @@ static int stm32_fmc2_read_page(struct nand_chip *chip, u8 *buf,
}
/* Sequencer read/write configuration */
-static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page,
- int raw, bool write_data)
+static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page,
+ int raw, bool write_data)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct mtd_info *mtd = nand_to_mtd(chip);
u32 csqcfgr1, csqcfgr2, csqcfgr3;
u32 csqar1, csqar2;
u32 ecc_offset = mtd->writesize + FMC2_BBM_LEN;
- u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+ u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
if (write_data)
pcr |= FMC2_PCR_WEN;
else
pcr &= ~FMC2_PCR_WEN;
- writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+ writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
/*
* - Set Program Page/Page Read command
@@ -812,11 +782,11 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page,
*/
csqcfgr1 = FMC2_CSQCFGR1_DMADEN | FMC2_CSQCFGR1_CMD1T;
if (write_data)
- csqcfgr1 |= FMC2_CSQCFGR1_CMD1(NAND_CMD_SEQIN);
+ csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_SEQIN);
else
- csqcfgr1 |= FMC2_CSQCFGR1_CMD1(NAND_CMD_READ0) |
+ csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_READ0) |
FMC2_CSQCFGR1_CMD2EN |
- FMC2_CSQCFGR1_CMD2(NAND_CMD_READSTART) |
+ FIELD_PREP(FMC2_CSQCFGR1_CMD2, NAND_CMD_READSTART) |
FMC2_CSQCFGR1_CMD2T;
/*
@@ -826,11 +796,12 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page,
* - Set timings
*/
if (write_data)
- csqcfgr2 = FMC2_CSQCFGR2_RCMD1(NAND_CMD_RNDIN);
+ csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDIN);
else
- csqcfgr2 = FMC2_CSQCFGR2_RCMD1(NAND_CMD_RNDOUT) |
+ csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDOUT) |
FMC2_CSQCFGR2_RCMD2EN |
- FMC2_CSQCFGR2_RCMD2(NAND_CMD_RNDOUTSTART) |
+ FIELD_PREP(FMC2_CSQCFGR2_RCMD2,
+ NAND_CMD_RNDOUTSTART) |
FMC2_CSQCFGR2_RCMD1T |
FMC2_CSQCFGR2_RCMD2T;
if (!raw) {
@@ -842,7 +813,7 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page,
* - Set the number of sectors to be written
* - Set timings
*/
- csqcfgr3 = FMC2_CSQCFGR3_SNBR(chip->ecc.steps - 1);
+ csqcfgr3 = FIELD_PREP(FMC2_CSQCFGR3_SNBR, chip->ecc.steps - 1);
if (write_data) {
csqcfgr3 |= FMC2_CSQCFGR3_RAC2T;
if (chip->options & NAND_ROW_ADDR_3)
@@ -856,8 +827,8 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page,
* Byte 1 and byte 2 => column, we start at 0x0
* Byte 3 and byte 4 => page
*/
- csqar1 = FMC2_CSQCAR1_ADDC3(page);
- csqar1 |= FMC2_CSQCAR1_ADDC4(page >> 8);
+ csqar1 = FIELD_PREP(FMC2_CSQCAR1_ADDC3, page);
+ csqar1 |= FIELD_PREP(FMC2_CSQCAR1_ADDC4, page >> 8);
/*
* - Set chip enable number
@@ -865,43 +836,44 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page,
* - Calculate the number of address cycles to be issued
* - Set byte 5 of address cycle if needed
*/
- csqar2 = FMC2_CSQCAR2_NANDCEN(fmc2->cs_sel);
+ csqar2 = FIELD_PREP(FMC2_CSQCAR2_NANDCEN, nfc->cs_sel);
if (chip->options & NAND_BUSWIDTH_16)
- csqar2 |= FMC2_CSQCAR2_SAO(ecc_offset >> 1);
+ csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset >> 1);
else
- csqar2 |= FMC2_CSQCAR2_SAO(ecc_offset);
+ csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset);
if (chip->options & NAND_ROW_ADDR_3) {
- csqcfgr1 |= FMC2_CSQCFGR1_ACYNBR(5);
- csqar2 |= FMC2_CSQCAR2_ADDC5(page >> 16);
+ csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 5);
+ csqar2 |= FIELD_PREP(FMC2_CSQCAR2_ADDC5, page >> 16);
} else {
- csqcfgr1 |= FMC2_CSQCFGR1_ACYNBR(4);
+ csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 4);
}
- writel_relaxed(csqcfgr1, fmc2->io_base + FMC2_CSQCFGR1);
- writel_relaxed(csqcfgr2, fmc2->io_base + FMC2_CSQCFGR2);
- writel_relaxed(csqcfgr3, fmc2->io_base + FMC2_CSQCFGR3);
- writel_relaxed(csqar1, fmc2->io_base + FMC2_CSQAR1);
- writel_relaxed(csqar2, fmc2->io_base + FMC2_CSQAR2);
+ writel_relaxed(csqcfgr1, nfc->io_base + FMC2_CSQCFGR1);
+ writel_relaxed(csqcfgr2, nfc->io_base + FMC2_CSQCFGR2);
+ writel_relaxed(csqcfgr3, nfc->io_base + FMC2_CSQCFGR3);
+ writel_relaxed(csqar1, nfc->io_base + FMC2_CSQAR1);
+ writel_relaxed(csqar2, nfc->io_base + FMC2_CSQAR2);
}
-static void stm32_fmc2_dma_callback(void *arg)
+static void stm32_fmc2_nfc_dma_callback(void *arg)
{
complete((struct completion *)arg);
}
/* Read/write data from/to a page */
-static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf,
- int raw, bool write_data)
+static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf,
+ int raw, bool write_data)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct dma_async_tx_descriptor *desc_data, *desc_ecc;
struct scatterlist *sg;
- struct dma_chan *dma_ch = fmc2->dma_rx_ch;
+ struct dma_chan *dma_ch = nfc->dma_rx_ch;
enum dma_data_direction dma_data_dir = DMA_FROM_DEVICE;
enum dma_transfer_direction dma_transfer_dir = DMA_DEV_TO_MEM;
- u32 csqcr = readl_relaxed(fmc2->io_base + FMC2_CSQCR);
+ u32 csqcr = readl_relaxed(nfc->io_base + FMC2_CSQCR);
int eccsteps = chip->ecc.steps;
int eccsize = chip->ecc.size;
+ unsigned long timeout = msecs_to_jiffies(FMC2_TIMEOUT_MS);
const u8 *p = buf;
int s, ret;
@@ -909,20 +881,20 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf,
if (write_data) {
dma_data_dir = DMA_TO_DEVICE;
dma_transfer_dir = DMA_MEM_TO_DEV;
- dma_ch = fmc2->dma_tx_ch;
+ dma_ch = nfc->dma_tx_ch;
}
- for_each_sg(fmc2->dma_data_sg.sgl, sg, eccsteps, s) {
+ for_each_sg(nfc->dma_data_sg.sgl, sg, eccsteps, s) {
sg_set_buf(sg, p, eccsize);
p += eccsize;
}
- ret = dma_map_sg(fmc2->dev, fmc2->dma_data_sg.sgl,
+ ret = dma_map_sg(nfc->dev, nfc->dma_data_sg.sgl,
eccsteps, dma_data_dir);
if (ret < 0)
return ret;
- desc_data = dmaengine_prep_slave_sg(dma_ch, fmc2->dma_data_sg.sgl,
+ desc_data = dmaengine_prep_slave_sg(dma_ch, nfc->dma_data_sg.sgl,
eccsteps, dma_transfer_dir,
DMA_PREP_INTERRUPT);
if (!desc_data) {
@@ -930,10 +902,10 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf,
goto err_unmap_data;
}
- reinit_completion(&fmc2->dma_data_complete);
- reinit_completion(&fmc2->complete);
- desc_data->callback = stm32_fmc2_dma_callback;
- desc_data->callback_param = &fmc2->dma_data_complete;
+ reinit_completion(&nfc->dma_data_complete);
+ reinit_completion(&nfc->complete);
+ desc_data->callback = stm32_fmc2_nfc_dma_callback;
+ desc_data->callback_param = &nfc->dma_data_complete;
ret = dma_submit_error(dmaengine_submit(desc_data));
if (ret)
goto err_unmap_data;
@@ -942,19 +914,19 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf,
if (!write_data && !raw) {
/* Configure DMA ECC status */
- p = fmc2->ecc_buf;
- for_each_sg(fmc2->dma_ecc_sg.sgl, sg, eccsteps, s) {
- sg_set_buf(sg, p, fmc2->dma_ecc_len);
- p += fmc2->dma_ecc_len;
+ p = nfc->ecc_buf;
+ for_each_sg(nfc->dma_ecc_sg.sgl, sg, eccsteps, s) {
+ sg_set_buf(sg, p, nfc->dma_ecc_len);
+ p += nfc->dma_ecc_len;
}
- ret = dma_map_sg(fmc2->dev, fmc2->dma_ecc_sg.sgl,
+ ret = dma_map_sg(nfc->dev, nfc->dma_ecc_sg.sgl,
eccsteps, dma_data_dir);
if (ret < 0)
goto err_unmap_data;
- desc_ecc = dmaengine_prep_slave_sg(fmc2->dma_ecc_ch,
- fmc2->dma_ecc_sg.sgl,
+ desc_ecc = dmaengine_prep_slave_sg(nfc->dma_ecc_ch,
+ nfc->dma_ecc_sg.sgl,
eccsteps, dma_transfer_dir,
DMA_PREP_INTERRUPT);
if (!desc_ecc) {
@@ -962,76 +934,73 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf,
goto err_unmap_ecc;
}
- reinit_completion(&fmc2->dma_ecc_complete);
- desc_ecc->callback = stm32_fmc2_dma_callback;
- desc_ecc->callback_param = &fmc2->dma_ecc_complete;
+ reinit_completion(&nfc->dma_ecc_complete);
+ desc_ecc->callback = stm32_fmc2_nfc_dma_callback;
+ desc_ecc->callback_param = &nfc->dma_ecc_complete;
ret = dma_submit_error(dmaengine_submit(desc_ecc));
if (ret)
goto err_unmap_ecc;
- dma_async_issue_pending(fmc2->dma_ecc_ch);
+ dma_async_issue_pending(nfc->dma_ecc_ch);
}
- stm32_fmc2_clear_seq_irq(fmc2);
- stm32_fmc2_enable_seq_irq(fmc2);
+ stm32_fmc2_nfc_clear_seq_irq(nfc);
+ stm32_fmc2_nfc_enable_seq_irq(nfc);
/* Start the transfer */
csqcr |= FMC2_CSQCR_CSQSTART;
- writel_relaxed(csqcr, fmc2->io_base + FMC2_CSQCR);
+ writel_relaxed(csqcr, nfc->io_base + FMC2_CSQCR);
/* Wait end of sequencer transfer */
- if (!wait_for_completion_timeout(&fmc2->complete,
- msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
- dev_err(fmc2->dev, "seq timeout\n");
- stm32_fmc2_disable_seq_irq(fmc2);
+ if (!wait_for_completion_timeout(&nfc->complete, timeout)) {
+ dev_err(nfc->dev, "seq timeout\n");
+ stm32_fmc2_nfc_disable_seq_irq(nfc);
dmaengine_terminate_all(dma_ch);
if (!write_data && !raw)
- dmaengine_terminate_all(fmc2->dma_ecc_ch);
+ dmaengine_terminate_all(nfc->dma_ecc_ch);
ret = -ETIMEDOUT;
goto err_unmap_ecc;
}
/* Wait DMA data transfer completion */
- if (!wait_for_completion_timeout(&fmc2->dma_data_complete,
- msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
- dev_err(fmc2->dev, "data DMA timeout\n");
+ if (!wait_for_completion_timeout(&nfc->dma_data_complete, timeout)) {
+ dev_err(nfc->dev, "data DMA timeout\n");
dmaengine_terminate_all(dma_ch);
ret = -ETIMEDOUT;
}
/* Wait DMA ECC transfer completion */
if (!write_data && !raw) {
- if (!wait_for_completion_timeout(&fmc2->dma_ecc_complete,
- msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
- dev_err(fmc2->dev, "ECC DMA timeout\n");
- dmaengine_terminate_all(fmc2->dma_ecc_ch);
+ if (!wait_for_completion_timeout(&nfc->dma_ecc_complete,
+ timeout)) {
+ dev_err(nfc->dev, "ECC DMA timeout\n");
+ dmaengine_terminate_all(nfc->dma_ecc_ch);
ret = -ETIMEDOUT;
}
}
err_unmap_ecc:
if (!write_data && !raw)
- dma_unmap_sg(fmc2->dev, fmc2->dma_ecc_sg.sgl,
+ dma_unmap_sg(nfc->dev, nfc->dma_ecc_sg.sgl,
eccsteps, dma_data_dir);
err_unmap_data:
- dma_unmap_sg(fmc2->dev, fmc2->dma_data_sg.sgl, eccsteps, dma_data_dir);
+ dma_unmap_sg(nfc->dev, nfc->dma_data_sg.sgl, eccsteps, dma_data_dir);
return ret;
}
-static int stm32_fmc2_sequencer_write(struct nand_chip *chip,
- const u8 *buf, int oob_required,
- int page, int raw)
+static int stm32_fmc2_nfc_seq_write(struct nand_chip *chip, const u8 *buf,
+ int oob_required, int page, int raw)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int ret;
/* Configure the sequencer */
- stm32_fmc2_rw_page_init(chip, page, raw, true);
+ stm32_fmc2_nfc_rw_page_init(chip, page, raw, true);
/* Write the page */
- ret = stm32_fmc2_xfer(chip, buf, raw, true);
+ ret = stm32_fmc2_nfc_xfer(chip, buf, raw, true);
if (ret)
return ret;
@@ -1047,55 +1016,50 @@ static int stm32_fmc2_sequencer_write(struct nand_chip *chip,
return nand_prog_page_end_op(chip);
}
-static int stm32_fmc2_sequencer_write_page(struct nand_chip *chip,
- const u8 *buf,
- int oob_required,
- int page)
+static int stm32_fmc2_nfc_seq_write_page(struct nand_chip *chip, const u8 *buf,
+ int oob_required, int page)
{
int ret;
- /* Select the target */
- ret = stm32_fmc2_select_chip(chip, chip->cur_cs);
+ ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs);
if (ret)
return ret;
- return stm32_fmc2_sequencer_write(chip, buf, oob_required, page, false);
+ return stm32_fmc2_nfc_seq_write(chip, buf, oob_required, page, false);
}
-static int stm32_fmc2_sequencer_write_page_raw(struct nand_chip *chip,
- const u8 *buf,
- int oob_required,
- int page)
+static int stm32_fmc2_nfc_seq_write_page_raw(struct nand_chip *chip,
+ const u8 *buf, int oob_required,
+ int page)
{
int ret;
- /* Select the target */
- ret = stm32_fmc2_select_chip(chip, chip->cur_cs);
+ ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs);
if (ret)
return ret;
- return stm32_fmc2_sequencer_write(chip, buf, oob_required, page, true);
+ return stm32_fmc2_nfc_seq_write(chip, buf, oob_required, page, true);
}
/* Get a status indicating which sectors have errors */
-static inline u16 stm32_fmc2_get_mapping_status(struct stm32_fmc2_nfc *fmc2)
+static inline u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc)
{
- u32 csqemsr = readl_relaxed(fmc2->io_base + FMC2_CSQEMSR);
+ u32 csqemsr = readl_relaxed(nfc->io_base + FMC2_CSQEMSR);
return csqemsr & FMC2_CSQEMSR_SEM;
}
-static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat,
- u8 *read_ecc, u8 *calc_ecc)
+static int stm32_fmc2_nfc_seq_correct(struct nand_chip *chip, u8 *dat,
+ u8 *read_ecc, u8 *calc_ecc)
{
struct mtd_info *mtd = nand_to_mtd(chip);
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
int eccstrength = chip->ecc.strength;
int i, s, eccsize = chip->ecc.size;
- u32 *ecc_sta = (u32 *)fmc2->ecc_buf;
- u16 sta_map = stm32_fmc2_get_mapping_status(fmc2);
+ u32 *ecc_sta = (u32 *)nfc->ecc_buf;
+ u16 sta_map = stm32_fmc2_nfc_get_mapping_status(nfc);
unsigned int max_bitflips = 0;
for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, dat += eccsize) {
@@ -1104,10 +1068,11 @@ static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat,
if (eccstrength == FMC2_ECC_HAM) {
/* Ecc_sta = FMC2_HECCR */
if (sta_map & BIT(s)) {
- stm32_fmc2_ham_set_ecc(*ecc_sta, &calc_ecc[i]);
- stat = stm32_fmc2_ham_correct(chip, dat,
- &read_ecc[i],
- &calc_ecc[i]);
+ stm32_fmc2_nfc_ham_set_ecc(*ecc_sta,
+ &calc_ecc[i]);
+ stat = stm32_fmc2_nfc_ham_correct(chip, dat,
+ &read_ecc[i],
+ &calc_ecc[i]);
}
ecc_sta++;
} else {
@@ -1119,8 +1084,8 @@ static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat,
* Ecc_sta[4] = FMC2_BCHDSR4
*/
if (sta_map & BIT(s))
- stat = stm32_fmc2_bch_decode(eccsize, dat,
- ecc_sta);
+ stat = stm32_fmc2_nfc_bch_decode(eccsize, dat,
+ ecc_sta);
ecc_sta += 5;
}
@@ -1143,30 +1108,29 @@ static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat,
return max_bitflips;
}
-static int stm32_fmc2_sequencer_read_page(struct nand_chip *chip, u8 *buf,
- int oob_required, int page)
+static int stm32_fmc2_nfc_seq_read_page(struct nand_chip *chip, u8 *buf,
+ int oob_required, int page)
{
struct mtd_info *mtd = nand_to_mtd(chip);
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
u8 *ecc_calc = chip->ecc.calc_buf;
u8 *ecc_code = chip->ecc.code_buf;
u16 sta_map;
int ret;
- /* Select the target */
- ret = stm32_fmc2_select_chip(chip, chip->cur_cs);
+ ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs);
if (ret)
return ret;
/* Configure the sequencer */
- stm32_fmc2_rw_page_init(chip, page, 0, false);
+ stm32_fmc2_nfc_rw_page_init(chip, page, 0, false);
/* Read the page */
- ret = stm32_fmc2_xfer(chip, buf, 0, false);
+ ret = stm32_fmc2_nfc_xfer(chip, buf, 0, false);
if (ret)
return ret;
- sta_map = stm32_fmc2_get_mapping_status(fmc2);
+ sta_map = stm32_fmc2_nfc_get_mapping_status(nfc);
/* Check if errors happen */
if (likely(!sta_map)) {
@@ -1193,22 +1157,21 @@ static int stm32_fmc2_sequencer_read_page(struct nand_chip *chip, u8 *buf,
return chip->ecc.correct(chip, buf, ecc_code, ecc_calc);
}
-static int stm32_fmc2_sequencer_read_page_raw(struct nand_chip *chip, u8 *buf,
- int oob_required, int page)
+static int stm32_fmc2_nfc_seq_read_page_raw(struct nand_chip *chip, u8 *buf,
+ int oob_required, int page)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int ret;
- /* Select the target */
- ret = stm32_fmc2_select_chip(chip, chip->cur_cs);
+ ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs);
if (ret)
return ret;
/* Configure the sequencer */
- stm32_fmc2_rw_page_init(chip, page, 1, false);
+ stm32_fmc2_nfc_rw_page_init(chip, page, 1, false);
/* Read the page */
- ret = stm32_fmc2_xfer(chip, buf, 1, false);
+ ret = stm32_fmc2_nfc_xfer(chip, buf, 1, false);
if (ret)
return ret;
@@ -1221,31 +1184,31 @@ static int stm32_fmc2_sequencer_read_page_raw(struct nand_chip *chip, u8 *buf,
return 0;
}
-static irqreturn_t stm32_fmc2_irq(int irq, void *dev_id)
+static irqreturn_t stm32_fmc2_nfc_irq(int irq, void *dev_id)
{
- struct stm32_fmc2_nfc *fmc2 = (struct stm32_fmc2_nfc *)dev_id;
+ struct stm32_fmc2_nfc *nfc = (struct stm32_fmc2_nfc *)dev_id;
- if (fmc2->irq_state == FMC2_IRQ_SEQ)
+ if (nfc->irq_state == FMC2_IRQ_SEQ)
/* Sequencer is used */
- stm32_fmc2_disable_seq_irq(fmc2);
- else if (fmc2->irq_state == FMC2_IRQ_BCH)
+ stm32_fmc2_nfc_disable_seq_irq(nfc);
+ else if (nfc->irq_state == FMC2_IRQ_BCH)
/* BCH is used */
- stm32_fmc2_disable_bch_irq(fmc2);
+ stm32_fmc2_nfc_disable_bch_irq(nfc);
- complete(&fmc2->complete);
+ complete(&nfc->complete);
return IRQ_HANDLED;
}
-static void stm32_fmc2_read_data(struct nand_chip *chip, void *buf,
- unsigned int len, bool force_8bit)
+static void stm32_fmc2_nfc_read_data(struct nand_chip *chip, void *buf,
+ unsigned int len, bool force_8bit)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
- void __iomem *io_addr_r = fmc2->data_base[fmc2->cs_sel];
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
+ void __iomem *io_addr_r = nfc->data_base[nfc->cs_sel];
if (force_8bit && chip->options & NAND_BUSWIDTH_16)
/* Reconfigure bus width to 8-bit */
- stm32_fmc2_set_buswidth_16(fmc2, false);
+ stm32_fmc2_nfc_set_buswidth_16(nfc, false);
if (!IS_ALIGNED((uintptr_t)buf, sizeof(u32))) {
if (!IS_ALIGNED((uintptr_t)buf, sizeof(u16)) && len) {
@@ -1281,18 +1244,18 @@ static void stm32_fmc2_read_data(struct nand_chip *chip, void *buf,
if (force_8bit && chip->options & NAND_BUSWIDTH_16)
/* Reconfigure bus width to 16-bit */
- stm32_fmc2_set_buswidth_16(fmc2, true);
+ stm32_fmc2_nfc_set_buswidth_16(nfc, true);
}
-static void stm32_fmc2_write_data(struct nand_chip *chip, const void *buf,
- unsigned int len, bool force_8bit)
+static void stm32_fmc2_nfc_write_data(struct nand_chip *chip, const void *buf,
+ unsigned int len, bool force_8bit)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
- void __iomem *io_addr_w = fmc2->data_base[fmc2->cs_sel];
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
+ void __iomem *io_addr_w = nfc->data_base[nfc->cs_sel];
if (force_8bit && chip->options & NAND_BUSWIDTH_16)
/* Reconfigure bus width to 8-bit */
- stm32_fmc2_set_buswidth_16(fmc2, false);
+ stm32_fmc2_nfc_set_buswidth_16(nfc, false);
if (!IS_ALIGNED((uintptr_t)buf, sizeof(u32))) {
if (!IS_ALIGNED((uintptr_t)buf, sizeof(u16)) && len) {
@@ -1328,48 +1291,49 @@ static void stm32_fmc2_write_data(struct nand_chip *chip, const void *buf,
if (force_8bit && chip->options & NAND_BUSWIDTH_16)
/* Reconfigure bus width to 16-bit */
- stm32_fmc2_set_buswidth_16(fmc2, true);
+ stm32_fmc2_nfc_set_buswidth_16(nfc, true);
}
-static int stm32_fmc2_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)
+static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip,
+ unsigned long timeout_ms)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
const struct nand_sdr_timings *timings;
u32 isr, sr;
/* Check if there is no pending requests to the NAND flash */
- if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
+ if (readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_SR, sr,
sr & FMC2_SR_NWRF, 1,
- FMC2_TIMEOUT_US))
- dev_warn(fmc2->dev, "Waitrdy timeout\n");
+ 1000 * FMC2_TIMEOUT_MS))
+ dev_warn(nfc->dev, "Waitrdy timeout\n");
/* Wait tWB before R/B# signal is low */
timings = nand_get_sdr_timings(&chip->data_interface);
ndelay(PSEC_TO_NSEC(timings->tWB_max));
/* R/B# signal is low, clear high level flag */
- writel_relaxed(FMC2_ICR_CIHLF, fmc2->io_base + FMC2_ICR);
+ writel_relaxed(FMC2_ICR_CIHLF, nfc->io_base + FMC2_ICR);
/* Wait R/B# signal is high */
- return readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_ISR,
+ return readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_ISR,
isr, isr & FMC2_ISR_IHLF,
5, 1000 * timeout_ms);
}
-static int stm32_fmc2_exec_op(struct nand_chip *chip,
- const struct nand_operation *op,
- bool check_only)
+static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip,
+ const struct nand_operation *op,
+ bool check_only)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
const struct nand_op_instr *instr = NULL;
- unsigned int op_id, i;
+ unsigned int op_id, i, timeout;
int ret;
- ret = stm32_fmc2_select_chip(chip, op->cs);
- if (ret)
- return ret;
-
if (check_only)
+ return 0;
+
+ ret = stm32_fmc2_nfc_select_chip(chip, op->cs);
+ if (ret)
return ret;
for (op_id = 0; op_id < op->ninstrs; op_id++) {
@@ -1378,30 +1342,30 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip,
switch (instr->type) {
case NAND_OP_CMD_INSTR:
writeb_relaxed(instr->ctx.cmd.opcode,
- fmc2->cmd_base[fmc2->cs_sel]);
+ nfc->cmd_base[nfc->cs_sel]);
break;
case NAND_OP_ADDR_INSTR:
for (i = 0; i < instr->ctx.addr.naddrs; i++)
writeb_relaxed(instr->ctx.addr.addrs[i],
- fmc2->addr_base[fmc2->cs_sel]);
+ nfc->addr_base[nfc->cs_sel]);
break;
case NAND_OP_DATA_IN_INSTR:
- stm32_fmc2_read_data(chip, instr->ctx.data.buf.in,
- instr->ctx.data.len,
- instr->ctx.data.force_8bit);
+ stm32_fmc2_nfc_read_data(chip, instr->ctx.data.buf.in,
+ instr->ctx.data.len,
+ instr->ctx.data.force_8bit);
break;
case NAND_OP_DATA_OUT_INSTR:
- stm32_fmc2_write_data(chip, instr->ctx.data.buf.out,
- instr->ctx.data.len,
- instr->ctx.data.force_8bit);
+ stm32_fmc2_nfc_write_data(chip, instr->ctx.data.buf.out,
+ instr->ctx.data.len,
+ instr->ctx.data.force_8bit);
break;
case NAND_OP_WAITRDY_INSTR:
- ret = stm32_fmc2_waitrdy(chip,
- instr->ctx.waitrdy.timeout_ms);
+ timeout = instr->ctx.waitrdy.timeout_ms;
+ ret = stm32_fmc2_nfc_waitrdy(chip, timeout);
break;
}
}
@@ -1409,21 +1373,20 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip,
return ret;
}
-/* Controller initialization */
-static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2)
+static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc)
{
- u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
- u32 bcr1 = readl_relaxed(fmc2->io_base + FMC2_BCR1);
+ u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
+ u32 bcr1 = readl_relaxed(nfc->io_base + FMC2_BCR1);
/* Set CS used to undefined */
- fmc2->cs_sel = -1;
+ nfc->cs_sel = -1;
/* Enable wait feature and nand flash memory bank */
pcr |= FMC2_PCR_PWAITEN;
pcr |= FMC2_PCR_PBKEN;
/* Set buswidth to 8 bits mode for identification */
- pcr &= ~FMC2_PCR_PWID_MASK;
+ pcr &= ~FMC2_PCR_PWID;
/* ECC logic is disabled */
pcr &= ~FMC2_PCR_ECCEN;
@@ -1434,32 +1397,31 @@ static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2)
pcr &= ~FMC2_PCR_WEN;
/* Set default ECC sector size */
- pcr &= ~FMC2_PCR_ECCSS_MASK;
- pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048);
+ pcr &= ~FMC2_PCR_ECCSS;
+ pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_2048);
/* Set default tclr/tar timings */
- pcr &= ~FMC2_PCR_TCLR_MASK;
- pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT);
- pcr &= ~FMC2_PCR_TAR_MASK;
- pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT);
+ pcr &= ~FMC2_PCR_TCLR;
+ pcr |= FIELD_PREP(FMC2_PCR_TCLR, FMC2_PCR_TCLR_DEFAULT);
+ pcr &= ~FMC2_PCR_TAR;
+ pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT);
/* Enable FMC2 controller */
bcr1 |= FMC2_BCR1_FMC2EN;
- writel_relaxed(bcr1, fmc2->io_base + FMC2_BCR1);
- writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
- writel_relaxed(FMC2_PMEM_DEFAULT, fmc2->io_base + FMC2_PMEM);
- writel_relaxed(FMC2_PATT_DEFAULT, fmc2->io_base + FMC2_PATT);
+ writel_relaxed(bcr1, nfc->io_base + FMC2_BCR1);
+ writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
+ writel_relaxed(FMC2_PMEM_DEFAULT, nfc->io_base + FMC2_PMEM);
+ writel_relaxed(FMC2_PATT_DEFAULT, nfc->io_base + FMC2_PATT);
}
-/* Controller timings */
-static void stm32_fmc2_calc_timings(struct nand_chip *chip,
- const struct nand_sdr_timings *sdrt)
+static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip,
+ const struct nand_sdr_timings *sdrt)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *tims = &nand->timings;
- unsigned long hclk = clk_get_rate(fmc2->clk);
+ unsigned long hclk = clk_get_rate(nfc->clk);
unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);
unsigned long timing, tar, tclr, thiz, twait;
unsigned long tset_mem, tset_att, thold_mem, thold_att;
@@ -1583,8 +1545,8 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip,
tims->thold_att = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK);
}
-static int stm32_fmc2_setup_interface(struct nand_chip *chip, int chipnr,
- const struct nand_data_interface *conf)
+static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr,
+ const struct nand_data_interface *conf)
{
const struct nand_sdr_timings *sdrt;
@@ -1595,71 +1557,67 @@ static int stm32_fmc2_setup_interface(struct nand_chip *chip, int chipnr,
if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
return 0;
- stm32_fmc2_calc_timings(chip, sdrt);
-
- /* Apply timings */
- stm32_fmc2_timings_init(chip);
+ stm32_fmc2_nfc_calc_timings(chip, sdrt);
+ stm32_fmc2_nfc_timings_init(chip);
return 0;
}
-/* DMA configuration */
-static int stm32_fmc2_dma_setup(struct stm32_fmc2_nfc *fmc2)
+static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc)
{
int ret = 0;
- fmc2->dma_tx_ch = dma_request_chan(fmc2->dev, "tx");
- if (IS_ERR(fmc2->dma_tx_ch)) {
- ret = PTR_ERR(fmc2->dma_tx_ch);
+ nfc->dma_tx_ch = dma_request_chan(nfc->dev, "tx");
+ if (IS_ERR(nfc->dma_tx_ch)) {
+ ret = PTR_ERR(nfc->dma_tx_ch);
if (ret != -ENODEV)
- dev_err(fmc2->dev,
+ dev_err(nfc->dev,
"failed to request tx DMA channel: %d\n", ret);
- fmc2->dma_tx_ch = NULL;
+ nfc->dma_tx_ch = NULL;
goto err_dma;
}
- fmc2->dma_rx_ch = dma_request_chan(fmc2->dev, "rx");
- if (IS_ERR(fmc2->dma_rx_ch)) {
- ret = PTR_ERR(fmc2->dma_rx_ch);
+ nfc->dma_rx_ch = dma_request_chan(nfc->dev, "rx");
+ if (IS_ERR(nfc->dma_rx_ch)) {
+ ret = PTR_ERR(nfc->dma_rx_ch);
if (ret != -ENODEV)
- dev_err(fmc2->dev,
+ dev_err(nfc->dev,
"failed to request rx DMA channel: %d\n", ret);
- fmc2->dma_rx_ch = NULL;
+ nfc->dma_rx_ch = NULL;
goto err_dma;
}
- fmc2->dma_ecc_ch = dma_request_chan(fmc2->dev, "ecc");
- if (IS_ERR(fmc2->dma_ecc_ch)) {
- ret = PTR_ERR(fmc2->dma_ecc_ch);
+ nfc->dma_ecc_ch = dma_request_chan(nfc->dev, "ecc");
+ if (IS_ERR(nfc->dma_ecc_ch)) {
+ ret = PTR_ERR(nfc->dma_ecc_ch);
if (ret != -ENODEV)
- dev_err(fmc2->dev,
+ dev_err(nfc->dev,
"failed to request ecc DMA channel: %d\n", ret);
- fmc2->dma_ecc_ch = NULL;
+ nfc->dma_ecc_ch = NULL;
goto err_dma;
}
- ret = sg_alloc_table(&fmc2->dma_ecc_sg, FMC2_MAX_SG, GFP_KERNEL);
+ ret = sg_alloc_table(&nfc->dma_ecc_sg, FMC2_MAX_SG, GFP_KERNEL);
if (ret)
return ret;
/* Allocate a buffer to store ECC status registers */
- fmc2->ecc_buf = devm_kzalloc(fmc2->dev, FMC2_MAX_ECC_BUF_LEN,
- GFP_KERNEL);
- if (!fmc2->ecc_buf)
+ nfc->ecc_buf = devm_kzalloc(nfc->dev, FMC2_MAX_ECC_BUF_LEN, GFP_KERNEL);
+ if (!nfc->ecc_buf)
return -ENOMEM;
- ret = sg_alloc_table(&fmc2->dma_data_sg, FMC2_MAX_SG, GFP_KERNEL);
+ ret = sg_alloc_table(&nfc->dma_data_sg, FMC2_MAX_SG, GFP_KERNEL);
if (ret)
return ret;
- init_completion(&fmc2->dma_data_complete);
- init_completion(&fmc2->dma_ecc_complete);
+ init_completion(&nfc->dma_data_complete);
+ init_completion(&nfc->dma_ecc_complete);
return 0;
err_dma:
if (ret == -ENODEV) {
- dev_warn(fmc2->dev,
+ dev_warn(nfc->dev,
"DMAs not defined in the DT, polling mode is used\n");
ret = 0;
}
@@ -1667,35 +1625,34 @@ err_dma:
return ret;
}
-/* NAND callbacks setup */
-static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip)
+static void stm32_fmc2_nfc_nand_callbacks_setup(struct nand_chip *chip)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
/*
* Specific callbacks to read/write a page depending on
* the mode (polling/sequencer) and the algo used (Hamming, BCH).
*/
- if (fmc2->dma_tx_ch && fmc2->dma_rx_ch && fmc2->dma_ecc_ch) {
+ if (nfc->dma_tx_ch && nfc->dma_rx_ch && nfc->dma_ecc_ch) {
/* DMA => use sequencer mode callbacks */
- chip->ecc.correct = stm32_fmc2_sequencer_correct;
- chip->ecc.write_page = stm32_fmc2_sequencer_write_page;
- chip->ecc.read_page = stm32_fmc2_sequencer_read_page;
- chip->ecc.write_page_raw = stm32_fmc2_sequencer_write_page_raw;
- chip->ecc.read_page_raw = stm32_fmc2_sequencer_read_page_raw;
+ chip->ecc.correct = stm32_fmc2_nfc_seq_correct;
+ chip->ecc.write_page = stm32_fmc2_nfc_seq_write_page;
+ chip->ecc.read_page = stm32_fmc2_nfc_seq_read_page;
+ chip->ecc.write_page_raw = stm32_fmc2_nfc_seq_write_page_raw;
+ chip->ecc.read_page_raw = stm32_fmc2_nfc_seq_read_page_raw;
} else {
/* No DMA => use polling mode callbacks */
- chip->ecc.hwctl = stm32_fmc2_hwctl;
+ chip->ecc.hwctl = stm32_fmc2_nfc_hwctl;
if (chip->ecc.strength == FMC2_ECC_HAM) {
/* Hamming is used */
- chip->ecc.calculate = stm32_fmc2_ham_calculate;
- chip->ecc.correct = stm32_fmc2_ham_correct;
+ chip->ecc.calculate = stm32_fmc2_nfc_ham_calculate;
+ chip->ecc.correct = stm32_fmc2_nfc_ham_correct;
chip->ecc.options |= NAND_ECC_GENERIC_ERASED_CHECK;
} else {
/* BCH is used */
- chip->ecc.calculate = stm32_fmc2_bch_calculate;
- chip->ecc.correct = stm32_fmc2_bch_correct;
- chip->ecc.read_page = stm32_fmc2_read_page;
+ chip->ecc.calculate = stm32_fmc2_nfc_bch_calculate;
+ chip->ecc.correct = stm32_fmc2_nfc_bch_correct;
+ chip->ecc.read_page = stm32_fmc2_nfc_read_page;
}
}
@@ -1708,9 +1665,8 @@ static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip)
chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 8 : 7;
}
-/* FMC2 layout */
-static int stm32_fmc2_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
- struct mtd_oob_region *oobregion)
+static int stm32_fmc2_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct nand_ecc_ctrl *ecc = &chip->ecc;
@@ -1724,8 +1680,8 @@ static int stm32_fmc2_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
return 0;
}
-static int stm32_fmc2_nand_ooblayout_free(struct mtd_info *mtd, int section,
- struct mtd_oob_region *oobregion)
+static int stm32_fmc2_nfc_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *oobregion)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct nand_ecc_ctrl *ecc = &chip->ecc;
@@ -1739,13 +1695,12 @@ static int stm32_fmc2_nand_ooblayout_free(struct mtd_info *mtd, int section,
return 0;
}
-static const struct mtd_ooblayout_ops stm32_fmc2_nand_ooblayout_ops = {
- .ecc = stm32_fmc2_nand_ooblayout_ecc,
- .free = stm32_fmc2_nand_ooblayout_free,
+static const struct mtd_ooblayout_ops stm32_fmc2_nfc_ooblayout_ops = {
+ .ecc = stm32_fmc2_nfc_ooblayout_ecc,
+ .free = stm32_fmc2_nfc_ooblayout_free,
};
-/* FMC2 caps */
-static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength)
+static int stm32_fmc2_nfc_calc_ecc_bytes(int step_size, int strength)
{
/* Hamming */
if (strength == FMC2_ECC_HAM)
@@ -1759,14 +1714,13 @@ static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength)
return 8;
}
-NAND_ECC_CAPS_SINGLE(stm32_fmc2_ecc_caps, stm32_fmc2_calc_ecc_bytes,
+NAND_ECC_CAPS_SINGLE(stm32_fmc2_nfc_ecc_caps, stm32_fmc2_nfc_calc_ecc_bytes,
FMC2_ECC_STEP_SIZE,
FMC2_ECC_HAM, FMC2_ECC_BCH4, FMC2_ECC_BCH8);
-/* FMC2 controller ops */
-static int stm32_fmc2_attach_chip(struct nand_chip *chip)
+static int stm32_fmc2_nfc_attach_chip(struct nand_chip *chip)
{
- struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct mtd_info *mtd = nand_to_mtd(chip);
int ret;
@@ -1778,49 +1732,45 @@ static int stm32_fmc2_attach_chip(struct nand_chip *chip)
* ECC sector size = 512
*/
if (chip->ecc.mode != NAND_ECC_HW) {
- dev_err(fmc2->dev, "nand_ecc_mode is not well defined in the DT\n");
+ dev_err(nfc->dev, "nand_ecc_mode is not well defined in the DT\n");
return -EINVAL;
}
- ret = nand_ecc_choose_conf(chip, &stm32_fmc2_ecc_caps,
+ ret = nand_ecc_choose_conf(chip, &stm32_fmc2_nfc_ecc_caps,
mtd->oobsize - FMC2_BBM_LEN);
if (ret) {
- dev_err(fmc2->dev, "no valid ECC settings set\n");
+ dev_err(nfc->dev, "no valid ECC settings set\n");
return ret;
}
if (mtd->writesize / chip->ecc.size > FMC2_MAX_SG) {
- dev_err(fmc2->dev, "nand page size is not supported\n");
+ dev_err(nfc->dev, "nand page size is not supported\n");
return -EINVAL;
}
if (chip->bbt_options & NAND_BBT_USE_FLASH)
chip->bbt_options |= NAND_BBT_NO_OOB;
- /* NAND callbacks setup */
- stm32_fmc2_nand_callbacks_setup(chip);
+ stm32_fmc2_nfc_nand_callbacks_setup(chip);
- /* Define ECC layout */
- mtd_set_ooblayout(mtd, &stm32_fmc2_nand_ooblayout_ops);
+ mtd_set_ooblayout(mtd, &stm32_fmc2_nfc_ooblayout_ops);
- /* Configure bus width to 16-bit */
if (chip->options & NAND_BUSWIDTH_16)
- stm32_fmc2_set_buswidth_16(fmc2, true);
+ stm32_fmc2_nfc_set_buswidth_16(nfc, true);
return 0;
}
-static const struct nand_controller_ops stm32_fmc2_nand_controller_ops = {
- .attach_chip = stm32_fmc2_attach_chip,
- .exec_op = stm32_fmc2_exec_op,
- .setup_data_interface = stm32_fmc2_setup_interface,
+static const struct nand_controller_ops stm32_fmc2_nfc_controller_ops = {
+ .attach_chip = stm32_fmc2_nfc_attach_chip,
+ .exec_op = stm32_fmc2_nfc_exec_op,
+ .setup_data_interface = stm32_fmc2_nfc_setup_interface,
};
-/* FMC2 probe */
-static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2,
- struct device_node *dn)
+static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
+ struct device_node *dn)
{
- struct stm32_fmc2_nand *nand = &fmc2->nand;
+ struct stm32_fmc2_nand *nand = &nfc->nand;
u32 cs;
int ret, i;
@@ -1829,29 +1779,29 @@ static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2,
nand->ncs /= sizeof(u32);
if (!nand->ncs) {
- dev_err(fmc2->dev, "invalid reg property size\n");
+ dev_err(nfc->dev, "invalid reg property size\n");
return -EINVAL;
}
for (i = 0; i < nand->ncs; i++) {
ret = of_property_read_u32_index(dn, "reg", i, &cs);
if (ret) {
- dev_err(fmc2->dev, "could not retrieve reg property: %d\n",
+ dev_err(nfc->dev, "could not retrieve reg property: %d\n",
ret);
return ret;
}
if (cs > FMC2_MAX_CE) {
- dev_err(fmc2->dev, "invalid reg value: %d\n", cs);
+ dev_err(nfc->dev, "invalid reg value: %d\n", cs);
return -EINVAL;
}
- if (fmc2->cs_assigned & BIT(cs)) {
- dev_err(fmc2->dev, "cs already assigned: %d\n", cs);
+ if (nfc->cs_assigned & BIT(cs)) {
+ dev_err(nfc->dev, "cs already assigned: %d\n", cs);
return -EINVAL;
}
- fmc2->cs_assigned |= BIT(cs);
+ nfc->cs_assigned |= BIT(cs);
nand->cs_used[i] = cs;
}
@@ -1860,25 +1810,25 @@ static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2,
return 0;
}
-static int stm32_fmc2_parse_dt(struct stm32_fmc2_nfc *fmc2)
+static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc *nfc)
{
- struct device_node *dn = fmc2->dev->of_node;
+ struct device_node *dn = nfc->dev->of_node;
struct device_node *child;
int nchips = of_get_child_count(dn);
int ret = 0;
if (!nchips) {
- dev_err(fmc2->dev, "NAND chip not defined\n");
+ dev_err(nfc->dev, "NAND chip not defined\n");
return -EINVAL;
}
if (nchips > 1) {
- dev_err(fmc2->dev, "too many NAND chips defined\n");
+ dev_err(nfc->dev, "too many NAND chips defined\n");
return -EINVAL;
}
for_each_child_of_node(dn, child) {
- ret = stm32_fmc2_parse_child(fmc2, child);
+ ret = stm32_fmc2_nfc_parse_child(nfc, child);
if (ret < 0) {
of_node_put(child);
return ret;
@@ -1888,106 +1838,108 @@ static int stm32_fmc2_parse_dt(struct stm32_fmc2_nfc *fmc2)
return ret;
}
-static int stm32_fmc2_probe(struct platform_device *pdev)
+static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct reset_control *rstc;
- struct stm32_fmc2_nfc *fmc2;
+ struct stm32_fmc2_nfc *nfc;
struct stm32_fmc2_nand *nand;
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
int chip_cs, mem_region, ret, irq;
- fmc2 = devm_kzalloc(dev, sizeof(*fmc2), GFP_KERNEL);
- if (!fmc2)
+ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
+ if (!nfc)
return -ENOMEM;
- fmc2->dev = dev;
- nand_controller_init(&fmc2->base);
- fmc2->base.ops = &stm32_fmc2_nand_controller_ops;
+ nfc->dev = dev;
+ nand_controller_init(&nfc->base);
+ nfc->base.ops = &stm32_fmc2_nfc_controller_ops;
- ret = stm32_fmc2_parse_dt(fmc2);
+ ret = stm32_fmc2_nfc_parse_dt(nfc);
if (ret)
return ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- fmc2->io_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(fmc2->io_base))
- return PTR_ERR(fmc2->io_base);
+ nfc->io_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(nfc->io_base))
+ return PTR_ERR(nfc->io_base);
- fmc2->io_phys_addr = res->start;
+ nfc->io_phys_addr = res->start;
for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE;
chip_cs++, mem_region += 3) {
- if (!(fmc2->cs_assigned & BIT(chip_cs)))
+ if (!(nfc->cs_assigned & BIT(chip_cs)))
continue;
res = platform_get_resource(pdev, IORESOURCE_MEM, mem_region);
- fmc2->data_base[chip_cs] = devm_ioremap_resource(dev, res);
- if (IS_ERR(fmc2->data_base[chip_cs]))
- return PTR_ERR(fmc2->data_base[chip_cs]);
+ nfc->data_base[chip_cs] = devm_ioremap_resource(dev, res);
+ if (IS_ERR(nfc->data_base[chip_cs]))
+ return PTR_ERR(nfc->data_base[chip_cs]);
- fmc2->data_phys_addr[chip_cs] = res->start;
+ nfc->data_phys_addr[chip_cs] = res->start;
res = platform_get_resource(pdev, IORESOURCE_MEM,
mem_region + 1);
- fmc2->cmd_base[chip_cs] = devm_ioremap_resource(dev, res);
- if (IS_ERR(fmc2->cmd_base[chip_cs]))
- return PTR_ERR(fmc2->cmd_base[chip_cs]);
+ nfc->cmd_base[chip_cs] = devm_ioremap_resource(dev, res);
+ if (IS_ERR(nfc->cmd_base[chip_cs]))
+ return PTR_ERR(nfc->cmd_base[chip_cs]);
res = platform_get_resource(pdev, IORESOURCE_MEM,
mem_region + 2);
- fmc2->addr_base[chip_cs] = devm_ioremap_resource(dev, res);
- if (IS_ERR(fmc2->addr_base[chip_cs]))
- return PTR_ERR(fmc2->addr_base[chip_cs]);
+ nfc->addr_base[chip_cs] = devm_ioremap_resource(dev, res);
+ if (IS_ERR(nfc->addr_base[chip_cs]))
+ return PTR_ERR(nfc->addr_base[chip_cs]);
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
- ret = devm_request_irq(dev, irq, stm32_fmc2_irq, 0,
- dev_name(dev), fmc2);
+ ret = devm_request_irq(dev, irq, stm32_fmc2_nfc_irq, 0,
+ dev_name(dev), nfc);
if (ret) {
dev_err(dev, "failed to request irq\n");
return ret;
}
- init_completion(&fmc2->complete);
+ init_completion(&nfc->complete);
- fmc2->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(fmc2->clk))
- return PTR_ERR(fmc2->clk);
+ nfc->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(nfc->clk))
+ return PTR_ERR(nfc->clk);
- ret = clk_prepare_enable(fmc2->clk);
+ ret = clk_prepare_enable(nfc->clk);
if (ret) {
dev_err(dev, "can not enable the clock\n");
return ret;
}
rstc = devm_reset_control_get(dev, NULL);
- if (!IS_ERR(rstc)) {
+ if (IS_ERR(rstc)) {
+ ret = PTR_ERR(rstc);
+ if (ret == -EPROBE_DEFER)
+ goto err_clk_disable;
+ } else {
reset_control_assert(rstc);
reset_control_deassert(rstc);
}
- /* DMA setup */
- ret = stm32_fmc2_dma_setup(fmc2);
+ ret = stm32_fmc2_nfc_dma_setup(nfc);
if (ret)
- return ret;
+ goto err_release_dma;
- /* FMC2 init routine */
- stm32_fmc2_init(fmc2);
+ stm32_fmc2_nfc_init(nfc);
- nand = &fmc2->nand;
+ nand = &nfc->nand;
chip = &nand->chip;
mtd = nand_to_mtd(chip);
mtd->dev.parent = dev;
- chip->controller = &fmc2->base;
+ chip->controller = &nfc->base;
chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
- NAND_USE_BOUNCE_BUFFER;
+ NAND_USES_DMA;
/* Default ECC settings */
chip->ecc.mode = NAND_ECC_HW;
@@ -1997,86 +1949,91 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
/* Scan to find existence of the device */
ret = nand_scan(chip, nand->ncs);
if (ret)
- goto err_scan;
+ goto err_release_dma;
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
- goto err_device_register;
+ goto err_nand_cleanup;
- platform_set_drvdata(pdev, fmc2);
+ platform_set_drvdata(pdev, nfc);
return 0;
-err_device_register:
+err_nand_cleanup:
nand_cleanup(chip);
-err_scan:
- if (fmc2->dma_ecc_ch)
- dma_release_channel(fmc2->dma_ecc_ch);
- if (fmc2->dma_tx_ch)
- dma_release_channel(fmc2->dma_tx_ch);
- if (fmc2->dma_rx_ch)
- dma_release_channel(fmc2->dma_rx_ch);
+err_release_dma:
+ if (nfc->dma_ecc_ch)
+ dma_release_channel(nfc->dma_ecc_ch);
+ if (nfc->dma_tx_ch)
+ dma_release_channel(nfc->dma_tx_ch);
+ if (nfc->dma_rx_ch)
+ dma_release_channel(nfc->dma_rx_ch);
- sg_free_table(&fmc2->dma_data_sg);
- sg_free_table(&fmc2->dma_ecc_sg);
+ sg_free_table(&nfc->dma_data_sg);
+ sg_free_table(&nfc->dma_ecc_sg);
- clk_disable_unprepare(fmc2->clk);
+err_clk_disable:
+ clk_disable_unprepare(nfc->clk);
return ret;
}
-static int stm32_fmc2_remove(struct platform_device *pdev)
+static int stm32_fmc2_nfc_remove(struct platform_device *pdev)
{
- struct stm32_fmc2_nfc *fmc2 = platform_get_drvdata(pdev);
- struct stm32_fmc2_nand *nand = &fmc2->nand;
+ struct stm32_fmc2_nfc *nfc = platform_get_drvdata(pdev);
+ struct stm32_fmc2_nand *nand = &nfc->nand;
+ struct nand_chip *chip = &nand->chip;
+ int ret;
- nand_release(&nand->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
- if (fmc2->dma_ecc_ch)
- dma_release_channel(fmc2->dma_ecc_ch);
- if (fmc2->dma_tx_ch)
- dma_release_channel(fmc2->dma_tx_ch);
- if (fmc2->dma_rx_ch)
- dma_release_channel(fmc2->dma_rx_ch);
+ if (nfc->dma_ecc_ch)
+ dma_release_channel(nfc->dma_ecc_ch);
+ if (nfc->dma_tx_ch)
+ dma_release_channel(nfc->dma_tx_ch);
+ if (nfc->dma_rx_ch)
+ dma_release_channel(nfc->dma_rx_ch);
- sg_free_table(&fmc2->dma_data_sg);
- sg_free_table(&fmc2->dma_ecc_sg);
+ sg_free_table(&nfc->dma_data_sg);
+ sg_free_table(&nfc->dma_ecc_sg);
- clk_disable_unprepare(fmc2->clk);
+ clk_disable_unprepare(nfc->clk);
return 0;
}
-static int __maybe_unused stm32_fmc2_suspend(struct device *dev)
+static int __maybe_unused stm32_fmc2_nfc_suspend(struct device *dev)
{
- struct stm32_fmc2_nfc *fmc2 = dev_get_drvdata(dev);
+ struct stm32_fmc2_nfc *nfc = dev_get_drvdata(dev);
- clk_disable_unprepare(fmc2->clk);
+ clk_disable_unprepare(nfc->clk);
pinctrl_pm_select_sleep_state(dev);
return 0;
}
-static int __maybe_unused stm32_fmc2_resume(struct device *dev)
+static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)
{
- struct stm32_fmc2_nfc *fmc2 = dev_get_drvdata(dev);
- struct stm32_fmc2_nand *nand = &fmc2->nand;
+ struct stm32_fmc2_nfc *nfc = dev_get_drvdata(dev);
+ struct stm32_fmc2_nand *nand = &nfc->nand;
int chip_cs, ret;
pinctrl_pm_select_default_state(dev);
- ret = clk_prepare_enable(fmc2->clk);
+ ret = clk_prepare_enable(nfc->clk);
if (ret) {
dev_err(dev, "can not enable the clock\n");
return ret;
}
- stm32_fmc2_init(fmc2);
+ stm32_fmc2_nfc_init(nfc);
for (chip_cs = 0; chip_cs < FMC2_MAX_CE; chip_cs++) {
- if (!(fmc2->cs_assigned & BIT(chip_cs)))
+ if (!(nfc->cs_assigned & BIT(chip_cs)))
continue;
nand_reset(&nand->chip, chip_cs);
@@ -2085,27 +2042,27 @@ static int __maybe_unused stm32_fmc2_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(stm32_fmc2_pm_ops, stm32_fmc2_suspend,
- stm32_fmc2_resume);
+static SIMPLE_DEV_PM_OPS(stm32_fmc2_nfc_pm_ops, stm32_fmc2_nfc_suspend,
+ stm32_fmc2_nfc_resume);
-static const struct of_device_id stm32_fmc2_match[] = {
+static const struct of_device_id stm32_fmc2_nfc_match[] = {
{.compatible = "st,stm32mp15-fmc2"},
{}
};
-MODULE_DEVICE_TABLE(of, stm32_fmc2_match);
+MODULE_DEVICE_TABLE(of, stm32_fmc2_nfc_match);
-static struct platform_driver stm32_fmc2_driver = {
- .probe = stm32_fmc2_probe,
- .remove = stm32_fmc2_remove,
+static struct platform_driver stm32_fmc2_nfc_driver = {
+ .probe = stm32_fmc2_nfc_probe,
+ .remove = stm32_fmc2_nfc_remove,
.driver = {
- .name = "stm32_fmc2_nand",
- .of_match_table = stm32_fmc2_match,
- .pm = &stm32_fmc2_pm_ops,
+ .name = "stm32_fmc2_nfc",
+ .of_match_table = stm32_fmc2_nfc_match,
+ .pm = &stm32_fmc2_nfc_pm_ops,
},
};
-module_platform_driver(stm32_fmc2_driver);
+module_platform_driver(stm32_fmc2_nfc_driver);
-MODULE_ALIAS("platform:stm32_fmc2_nand");
+MODULE_ALIAS("platform:stm32_fmc2_nfc");
MODULE_AUTHOR("Christophe Kerello <christophe.kerello@st.com>");
-MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 nand driver");
+MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 NFC driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index 5f3e40b79fb1..ffbc1651fadc 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1698,7 +1698,7 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand,
ecc->read_page = sunxi_nfc_hw_ecc_read_page_dma;
ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage_dma;
ecc->write_page = sunxi_nfc_hw_ecc_write_page_dma;
- nand->options |= NAND_USE_BOUNCE_BUFFER;
+ nand->options |= NAND_USES_DMA;
} else {
ecc->read_page = sunxi_nfc_hw_ecc_read_page;
ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
@@ -1907,7 +1907,8 @@ static int sunxi_nfc_exec_op(struct nand_chip *nand,
struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
const struct nand_op_parser *parser;
- sunxi_nfc_select_chip(nand, op->cs);
+ if (!check_only)
+ sunxi_nfc_select_chip(nand, op->cs);
if (sunxi_nand->sels[op->cs].rb >= 0)
parser = &sunxi_nfc_op_parser;
@@ -2003,7 +2004,7 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(dev, "failed to register mtd device: %d\n", ret);
- nand_release(nand);
+ nand_cleanup(nand);
return ret;
}
@@ -2038,13 +2039,18 @@ static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
{
struct sunxi_nand_chip *sunxi_nand;
+ struct nand_chip *chip;
+ int ret;
while (!list_empty(&nfc->chips)) {
sunxi_nand = list_first_entry(&nfc->chips,
struct sunxi_nand_chip,
node);
- nand_release(&sunxi_nand->nand);
- sunxi_nand_ecc_cleanup(&sunxi_nand->nand.ecc);
+ chip = &sunxi_nand->nand;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ sunxi_nand_ecc_cleanup(&chip->ecc);
list_del(&sunxi_nand->node);
}
}
diff --git a/drivers/mtd/nand/raw/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c
index 9acf2de37ee0..246871e01027 100644
--- a/drivers/mtd/nand/raw/tango_nand.c
+++ b/drivers/mtd/nand/raw/tango_nand.c
@@ -568,7 +568,7 @@ static int chip_init(struct device *dev, struct device_node *np)
chip->legacy.select_chip = tango_select_chip;
chip->legacy.cmd_ctrl = tango_cmd_ctrl;
chip->legacy.dev_ready = tango_dev_ready;
- chip->options = NAND_USE_BOUNCE_BUFFER |
+ chip->options = NAND_USES_DMA |
NAND_NO_SUBPAGE_WRITE |
NAND_WAIT_TCCS;
chip->controller = &nfc->hw;
@@ -600,14 +600,19 @@ static int chip_init(struct device *dev, struct device_node *np)
static int tango_nand_remove(struct platform_device *pdev)
{
- int cs;
struct tango_nfc *nfc = platform_get_drvdata(pdev);
+ struct nand_chip *chip;
+ int cs, ret;
dma_release_channel(nfc->chan);
for (cs = 0; cs < MAX_CS; ++cs) {
- if (nfc->chips[cs])
- nand_release(&nfc->chips[cs]->nand_chip);
+ if (nfc->chips[cs]) {
+ chip = &nfc->chips[cs]->nand_chip;
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
+ }
}
return 0;
diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index 3cc9a4c41443..f9d046b2cd3b 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -467,7 +467,9 @@ static int tegra_nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{
- tegra_nand_select_target(chip, op->cs);
+ if (!check_only)
+ tegra_nand_select_target(chip, op->cs);
+
return nand_op_parser_exec_op(chip, &tegra_nand_op_parser, op,
check_only);
}
@@ -1113,7 +1115,7 @@ static int tegra_nand_chips_init(struct device *dev,
if (!mtd->name)
mtd->name = "tegra_nand";
- chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER;
+ chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA;
ret = nand_scan(chip, 1);
if (ret)
diff --git a/drivers/mtd/nand/raw/tmio_nand.c b/drivers/mtd/nand/raw/tmio_nand.c
index db030f1701ee..843a8683b737 100644
--- a/drivers/mtd/nand/raw/tmio_nand.c
+++ b/drivers/mtd/nand/raw/tmio_nand.c
@@ -448,7 +448,7 @@ static int tmio_probe(struct platform_device *dev)
if (!retval)
return retval;
- nand_release(nand_chip);
+ nand_cleanup(nand_chip);
err_irq:
tmio_hw_stop(dev, tmio);
@@ -458,8 +458,12 @@ err_irq:
static int tmio_remove(struct platform_device *dev)
{
struct tmio_nand *tmio = platform_get_drvdata(dev);
+ struct nand_chip *chip = &tmio->chip;
+ int ret;
- nand_release(&tmio->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
tmio_hw_stop(dev, tmio);
return 0;
}
diff --git a/drivers/mtd/nand/raw/txx9ndfmc.c b/drivers/mtd/nand/raw/txx9ndfmc.c
index 2642d5bb3241..47d966871445 100644
--- a/drivers/mtd/nand/raw/txx9ndfmc.c
+++ b/drivers/mtd/nand/raw/txx9ndfmc.c
@@ -371,7 +371,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
static int __exit txx9ndfmc_remove(struct platform_device *dev)
{
struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
- int i;
+ int ret, i;
if (!drvdata)
return 0;
@@ -385,7 +385,9 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev)
chip = mtd_to_nand(mtd);
txx9_priv = nand_get_controller_data(chip);
- nand_release(chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
kfree(txx9_priv->mtdname);
kfree(txx9_priv);
}
diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
index 6b399a75f9ae..7248c5901183 100644
--- a/drivers/mtd/nand/raw/vf610_nfc.c
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -502,7 +502,9 @@ static int vf610_nfc_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{
- vf610_nfc_select_target(chip, op->cs);
+ if (!check_only)
+ vf610_nfc_select_target(chip, op->cs);
+
return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op,
check_only);
}
@@ -915,8 +917,12 @@ err_disable_clk:
static int vf610_nfc_remove(struct platform_device *pdev)
{
struct vf610_nfc *nfc = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &nfc->chip;
+ int ret;
- nand_release(&nfc->chip);
+ ret = mtd_device_unregister(nand_to_mtd(chip));
+ WARN_ON(ret);
+ nand_cleanup(chip);
clk_disable_unprepare(nfc->clk);
return 0;
}
diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
index 834f794816a9..94bfba994326 100644
--- a/drivers/mtd/nand/raw/xway_nand.c
+++ b/drivers/mtd/nand/raw/xway_nand.c
@@ -210,7 +210,7 @@ static int xway_nand_probe(struct platform_device *pdev)
err = mtd_device_register(mtd, NULL, 0);
if (err)
- nand_release(&data->chip);
+ nand_cleanup(&data->chip);
return err;
}
@@ -221,8 +221,12 @@ static int xway_nand_probe(struct platform_device *pdev)
static int xway_nand_remove(struct platform_device *pdev)
{
struct xway_nand_data *data = platform_get_drvdata(pdev);
+ struct nand_chip *chip = &data->chip;
+ int ret;
- nand_release(&data->chip);
+ ret = mtd_device_unregister(mtd);
+ WARN_ON(ret);
+ nand_cleanup(chip);
return 0;
}
diff --git a/drivers/mtd/parsers/cmdlinepart.c b/drivers/mtd/parsers/cmdlinepart.c
index c86f2db8c882..a79e4d866b08 100644
--- a/drivers/mtd/parsers/cmdlinepart.c
+++ b/drivers/mtd/parsers/cmdlinepart.c
@@ -9,7 +9,7 @@
*
* mtdparts=<mtddef>[;<mtddef]
* <mtddef> := <mtd-id>:<partdef>[,<partdef>]
- * <partdef> := <size>[@<offset>][<name>][ro][lk]
+ * <partdef> := <size>[@<offset>][<name>][ro][lk][slc]
* <mtd-id> := unique name used in mapping driver/device (mtd->name)
* <size> := standard linux memsize OR "-" to denote all remaining space
* size is automatically truncated at end of device
@@ -92,7 +92,7 @@ static struct mtd_partition * newpart(char *s,
int name_len;
unsigned char *extra_mem;
char delim;
- unsigned int mask_flags;
+ unsigned int mask_flags, add_flags;
/* fetch the partition size */
if (*s == '-') {
@@ -109,6 +109,7 @@ static struct mtd_partition * newpart(char *s,
/* fetch partition name and flags */
mask_flags = 0; /* this is going to be a regular partition */
+ add_flags = 0;
delim = 0;
/* check for offset */
@@ -152,6 +153,12 @@ static struct mtd_partition * newpart(char *s,
s += 2;
}
+ /* if slc is found use emulated SLC mode on this partition*/
+ if (!strncmp(s, "slc", 3)) {
+ add_flags |= MTD_SLC_ON_MLC_EMULATION;
+ s += 3;
+ }
+
/* test if more partitions are following */
if (*s == ',') {
if (size == SIZE_REMAINING) {
@@ -184,6 +191,7 @@ static struct mtd_partition * newpart(char *s,
parts[this_part].size = size;
parts[this_part].offset = offset;
parts[this_part].mask_flags = mask_flags;
+ parts[this_part].add_flags = add_flags;
if (name)
strlcpy(extra_mem, name, name_len + 1);
else
@@ -218,12 +226,29 @@ static int mtdpart_setup_real(char *s)
struct cmdline_mtd_partition *this_mtd;
struct mtd_partition *parts;
int mtd_id_len, num_parts;
- char *p, *mtd_id;
+ char *p, *mtd_id, *semicol;
+
+ /*
+ * Replace the first ';' by a NULL char so strrchr can work
+ * properly.
+ */
+ semicol = strchr(s, ';');
+ if (semicol)
+ *semicol = '\0';
mtd_id = s;
- /* fetch <mtd-id> */
- p = strchr(s, ':');
+ /*
+ * fetch <mtd-id>. We use strrchr to ignore all ':' that could
+ * be present in the MTD name, only the last one is interpreted
+ * as an <mtd-id>/<part-definition> separator.
+ */
+ p = strrchr(s, ':');
+
+ /* Restore the ';' now. */
+ if (semicol)
+ *semicol = ';';
+
if (!p) {
pr_err("no mtd-id\n");
return -EINVAL;
diff --git a/drivers/mtd/parsers/ofpart.c b/drivers/mtd/parsers/ofpart.c
index 3caeabf27987..daf507c123e6 100644
--- a/drivers/mtd/parsers/ofpart.c
+++ b/drivers/mtd/parsers/ofpart.c
@@ -117,6 +117,9 @@ static int parse_fixed_partitions(struct mtd_info *master,
if (of_get_property(pp, "lock", &len))
parts[i].mask_flags |= MTD_POWERUP_LOCK;
+ if (of_property_read_bool(pp, "slc-mode"))
+ parts[i].add_flags |= MTD_SLC_ON_MLC_EMULATION;
+
i++;
}
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 6e816eafb312..ffc4b380f2b1 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -1,12 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig MTD_SPI_NOR
- tristate "SPI-NOR device support"
+ tristate "SPI NOR device support"
depends on MTD
depends on MTD && SPI_MASTER
select SPI_MEM
help
This is the framework for the SPI NOR which can be used by the SPI
- device drivers and the SPI-NOR device driver.
+ device drivers and the SPI NOR device driver.
if MTD_SPI_NOR
diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
index 10b86660b821..d89a5ea9446a 100644
--- a/drivers/mtd/spi-nor/controllers/Kconfig
+++ b/drivers/mtd/spi-nor/controllers/Kconfig
@@ -21,11 +21,11 @@ config SPI_CADENCE_QUADSPI
Flash as an MTD device.
config SPI_HISI_SFC
- tristate "Hisilicon FMC SPI-NOR Flash Controller(SFC)"
+ tristate "Hisilicon FMC SPI NOR Flash Controller(SFC)"
depends on ARCH_HISI || COMPILE_TEST
depends on HAS_IOMEM
help
- This enables support for HiSilicon FMC SPI-NOR flash controller.
+ This enables support for HiSilicon FMC SPI NOR flash controller.
config SPI_NXP_SPIFI
tristate "NXP SPI Flash Interface (SPIFI)"
diff --git a/drivers/mtd/spi-nor/controllers/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
index ae85e4c0e114..7225870e8b18 100644
--- a/drivers/mtd/spi-nor/controllers/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
@@ -727,7 +727,7 @@ static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
/*
* TODO: Adjust clocks if fast read is supported and interpret
- * SPI-NOR flags to adjust controller settings.
+ * SPI NOR flags to adjust controller settings.
*/
if (chip->nor.read_proto == SNOR_PROTO_1_1_1) {
if (chip->nor.read_dummy == 0)
diff --git a/drivers/mtd/spi-nor/controllers/hisi-sfc.c b/drivers/mtd/spi-nor/controllers/hisi-sfc.c
index 6c7a4118752e..95c502173cbd 100644
--- a/drivers/mtd/spi-nor/controllers/hisi-sfc.c
+++ b/drivers/mtd/spi-nor/controllers/hisi-sfc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * HiSilicon FMC SPI-NOR flash controller driver
+ * HiSilicon FMC SPI NOR flash controller driver
*
* Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.
*/
diff --git a/drivers/mtd/spi-nor/controllers/nxp-spifi.c b/drivers/mtd/spi-nor/controllers/nxp-spifi.c
index 9a5b1a7c636a..5703e8313980 100644
--- a/drivers/mtd/spi-nor/controllers/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/controllers/nxp-spifi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * SPI-NOR driver for NXP SPI Flash Interface (SPIFI)
+ * SPI NOR driver for NXP SPI Flash Interface (SPIFI)
*
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index cc68ea84318e..0369d98b2d12 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -499,7 +499,7 @@ int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
* the flash is ready for new commands.
* @nor: pointer to 'struct spi_nor'.
*
- * Return: 0 on success, -errno otherwise.
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
*/
static int spi_nor_xsr_ready(struct spi_nor *nor)
{
@@ -542,7 +542,7 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
* for new commands.
* @nor: pointer to 'struct spi_nor'.
*
- * Return: 0 on success, -errno otherwise.
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
*/
static int spi_nor_sr_ready(struct spi_nor *nor)
{
@@ -606,7 +606,7 @@ static void spi_nor_clear_fsr(struct spi_nor *nor)
* ready for new commands.
* @nor: pointer to 'struct spi_nor'.
*
- * Return: 0 on success, -errno otherwise.
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
*/
static int spi_nor_fsr_ready(struct spi_nor *nor)
{
@@ -640,14 +640,14 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
return -EIO;
}
- return nor->bouncebuf[0] & FSR_READY;
+ return !!(nor->bouncebuf[0] & FSR_READY);
}
/**
* spi_nor_ready() - Query the flash to see if it is ready for new commands.
* @nor: pointer to 'struct spi_nor'.
*
- * Return: 0 on success, -errno otherwise.
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
*/
static int spi_nor_ready(struct spi_nor *nor)
{
@@ -2469,7 +2469,7 @@ static int spi_nor_select_read(struct spi_nor *nor,
nor->read_proto = read->proto;
/*
- * In the spi-nor framework, we don't need to make the difference
+ * In the SPI NOR framework, we don't need to make the difference
* between mode clock cycles and wait state clock cycles.
* Indeed, the value of the mode clock cycles is used by a QSPI
* flash memory to know whether it should enter or leave its 0-4-4
@@ -2675,7 +2675,7 @@ static int spi_nor_setup(struct spi_nor *nor,
/**
* spi_nor_manufacturer_init_params() - Initialize the flash's parameters and
* settings based on MFR register and ->default_init() hook.
- * @nor: pointer to a 'struct spi-nor'.
+ * @nor: pointer to a 'struct spi_nor'.
*/
static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
{
@@ -2690,7 +2690,7 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
/**
* spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
* based on JESD216 SFDP standard.
- * @nor: pointer to a 'struct spi-nor'.
+ * @nor: pointer to a 'struct spi_nor'.
*
* The method has a roll-back mechanism: in case the SFDP parsing fails, the
* legacy flash parameters and settings will be restored.
@@ -2712,7 +2712,7 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
/**
* spi_nor_info_init_params() - Initialize the flash's parameters and settings
* based on nor->info data.
- * @nor: pointer to a 'struct spi-nor'.
+ * @nor: pointer to a 'struct spi_nor'.
*/
static void spi_nor_info_init_params(struct spi_nor *nor)
{
@@ -2841,7 +2841,7 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
/**
* spi_nor_init_params() - Initialize the flash's parameters and settings.
- * @nor: pointer to a 'struct spi-nor'.
+ * @nor: pointer to a 'struct spi_nor'.
*
* The flash parameters and settings are initialized based on a sequence of
* calls that are ordered by priority:
@@ -3126,7 +3126,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
/*
* Make sure the XSR_RDY flag is set before calling
* spi_nor_wait_till_ready(). Xilinx S3AN share MFR
- * with Atmel spi-nor
+ * with Atmel SPI NOR.
*/
if (info->flags & SPI_NOR_XSR_RDY)
nor->flags |= SNOR_F_READY_XSR_RDY;
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index ab0f963d630c..96735d83c77c 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -63,10 +63,16 @@ static const struct flash_info macronix_parts[] = {
.fixups = &mx25l25635_fixups },
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_4B_OPCODES) },
+ { "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ |
+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ "mx25v8035f", INFO(0xc22314, 0, 64 * 1024, 16,
SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+ { "mx25l51245g", INFO(0xc2201a, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_4B_OPCODES) },
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024,
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_4B_OPCODES) },
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 6c034b9718e2..3dca5b9af3b6 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -29,7 +29,9 @@ static const struct flash_info st_parts[] = {
{ "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128,
SECT_4K | SPI_NOR_QUAD_READ) },
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256,
- SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+ SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ "mt25ql256a", INFO6(0x20ba19, 0x104400, 64 * 1024, 512,
@@ -59,6 +61,8 @@ static const struct flash_info st_parts[] = {
SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
{ "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+ SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6 |
NO_CHIP_ERASE) },
{ "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048,
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index f6038d3a3684..55c0c508464b 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -21,10 +21,6 @@
#define SFDP_4BAIT_ID 0xff84 /* 4-byte Address Instruction Table */
#define SFDP_SIGNATURE 0x50444653U
-#define SFDP_JESD216_MAJOR 1
-#define SFDP_JESD216_MINOR 0
-#define SFDP_JESD216A_MINOR 5
-#define SFDP_JESD216B_MINOR 6
struct sfdp_header {
u32 signature; /* Ox50444653U <=> "SFDP" */
@@ -437,7 +433,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
struct sfdp_bfpt bfpt;
size_t len;
int i, cmd, err;
- u32 addr;
+ u32 addr, val;
u16 half;
u8 erase_mask;
@@ -460,6 +456,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
/* Number of address bytes. */
switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) {
case BFPT_DWORD1_ADDRESS_BYTES_3_ONLY:
+ case BFPT_DWORD1_ADDRESS_BYTES_3_OR_4:
nor->addr_width = 3;
break;
@@ -472,21 +469,21 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
}
/* Flash Memory Density (in bits). */
- params->size = bfpt.dwords[BFPT_DWORD(2)];
- if (params->size & BIT(31)) {
- params->size &= ~BIT(31);
+ val = bfpt.dwords[BFPT_DWORD(2)];
+ if (val & BIT(31)) {
+ val &= ~BIT(31);
/*
* Prevent overflows on params->size. Anyway, a NOR of 2^64
* bits is unlikely to exist so this error probably means
* the BFPT we are reading is corrupted/wrong.
*/
- if (params->size > 63)
+ if (val > 63)
return -EINVAL;
- params->size = 1ULL << params->size;
+ params->size = 1ULL << val;
} else {
- params->size++;
+ params->size = val + 1;
}
params->size >>= 3; /* Convert to bytes. */
@@ -548,15 +545,15 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
SNOR_ERASE_TYPE_MASK;
/* Stop here if not JESD216 rev A or later. */
- if (bfpt_header->length < BFPT_DWORD_MAX)
+ if (bfpt_header->length == BFPT_DWORD_MAX_JESD216)
return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt,
params);
/* Page size: this field specifies 'N' so the page size = 2^N bytes. */
- params->page_size = bfpt.dwords[BFPT_DWORD(11)];
- params->page_size &= BFPT_DWORD11_PAGE_SIZE_MASK;
- params->page_size >>= BFPT_DWORD11_PAGE_SIZE_SHIFT;
- params->page_size = 1U << params->page_size;
+ val = bfpt.dwords[BFPT_DWORD(11)];
+ val &= BFPT_DWORD11_PAGE_SIZE_MASK;
+ val >>= BFPT_DWORD11_PAGE_SIZE_SHIFT;
+ params->page_size = 1U << val;
/* Quad Enable Requirements. */
switch (bfpt.dwords[BFPT_DWORD(15)] & BFPT_DWORD15_QER_MASK) {
@@ -604,6 +601,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
return -EINVAL;
}
+ /* Stop here if not JESD216 rev C or later. */
+ if (bfpt_header->length == BFPT_DWORD_MAX_JESD216B)
+ return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt,
+ params);
+
return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params);
}
diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h
index e0a8ded04890..7f9846b3a1ad 100644
--- a/drivers/mtd/spi-nor/sfdp.h
+++ b/drivers/mtd/spi-nor/sfdp.h
@@ -7,14 +7,20 @@
#ifndef __LINUX_MTD_SFDP_H
#define __LINUX_MTD_SFDP_H
+/* SFDP revisions */
+#define SFDP_JESD216_MAJOR 1
+#define SFDP_JESD216_MINOR 0
+#define SFDP_JESD216A_MINOR 5
+#define SFDP_JESD216B_MINOR 6
+
/* Basic Flash Parameter Table */
/*
- * JESD216 rev B defines a Basic Flash Parameter Table of 16 DWORDs.
+ * JESD216 rev D defines a Basic Flash Parameter Table of 20 DWORDs.
* They are indexed from 1 but C arrays are indexed from 0.
*/
#define BFPT_DWORD(i) ((i) - 1)
-#define BFPT_DWORD_MAX 16
+#define BFPT_DWORD_MAX 20
struct sfdp_bfpt {
u32 dwords[BFPT_DWORD_MAX];
@@ -22,6 +28,7 @@ struct sfdp_bfpt {
/* The first version of JESD216 defined only 9 DWORDs. */
#define BFPT_DWORD_MAX_JESD216 9
+#define BFPT_DWORD_MAX_JESD216B 16
/* 1st DWORD. */
#define BFPT_DWORD1_FAST_READ_1_1_2 BIT(16)
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index 6756202ace4b..e550cd5c9d3a 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -8,6 +8,27 @@
#include "core.h"
+static int
+s25fs_s_post_bfpt_fixups(struct spi_nor *nor,
+ const struct sfdp_parameter_header *bfpt_header,
+ const struct sfdp_bfpt *bfpt,
+ struct spi_nor_flash_parameter *params)
+{
+ /*
+ * The S25FS-S chip family reports 512-byte pages in BFPT but
+ * in reality the write buffer still wraps at the safe default
+ * of 256 bytes. Overwrite the page size advertised by BFPT
+ * to get the writes working.
+ */
+ params->page_size = 256;
+
+ return 0;
+}
+
+static struct spi_nor_fixups s25fs_s_fixups = {
+ .post_bfpt = s25fs_s_post_bfpt_fixups,
+};
+
static const struct flash_info spansion_parts[] = {
/* Spansion/Cypress -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
@@ -22,16 +43,27 @@ static const struct flash_info spansion_parts[] = {
{ "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256,
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
USE_CLSR) },
- { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
- { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512,
- SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
- USE_CLSR) },
+ { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128,
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ USE_CLSR) },
+ { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512,
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ USE_CLSR) },
{ "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | USE_CLSR) },
- { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256,
+ { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256,
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)
+ .fixups = &s25fs_s_fixups, },
+ { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128,
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ USE_CLSR) },
+ { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512,
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
USE_CLSR) },
+ { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256,
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)
+ .fixups = &s25fs_s_fixups, },
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
@@ -70,6 +102,8 @@ static const struct flash_info spansion_parts[] = {
{ "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_4B_OPCODES) },
+ { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1,
+ SPI_NOR_NO_ERASE) },
};
static void spansion_post_sfdp_fixups(struct spi_nor *nor)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index 17deabad57e1..5062af10f138 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -8,6 +8,31 @@
#include "core.h"
+static int
+w25q256_post_bfpt_fixups(struct spi_nor *nor,
+ const struct sfdp_parameter_header *bfpt_header,
+ const struct sfdp_bfpt *bfpt,
+ struct spi_nor_flash_parameter *params)
+{
+ /*
+ * W25Q256JV supports 4B opcodes but W25Q256FV does not.
+ * Unfortunately, Winbond has re-used the same JEDEC ID for both
+ * variants which prevents us from defining a new entry in the parts
+ * table.
+ * To differentiate between W25Q256JV and W25Q256FV check SFDP header
+ * version: only JV has JESD216A compliant structure (version 5).
+ */
+ if (bfpt_header->major == SFDP_JESD216_MAJOR &&
+ bfpt_header->minor == SFDP_JESD216A_MINOR)
+ nor->flags |= SNOR_F_4B_OPCODES;
+
+ return 0;
+}
+
+static struct spi_nor_fixups w25q256_fixups = {
+ .post_bfpt = w25q256_post_bfpt_fixups,
+};
+
static const struct flash_info winbond_parts[] = {
/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
{ "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) },
@@ -53,8 +78,8 @@ static const struct flash_info winbond_parts[] = {
{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512,
- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
- SPI_NOR_4B_OPCODES) },
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+ .fixups = &w25q256_fixups },
{ "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512,
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 12c02342149c..e85b04e9716b 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -867,8 +867,11 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
* Both UBI and UBIFS have been designed for SLC NAND and NOR flashes.
* MLC NAND is different and needs special care, otherwise UBI or UBIFS
* will die soon and you will lose all your data.
+ * Relax this rule if the partition we're attaching to operates in SLC
+ * mode.
*/
- if (mtd->type == MTD_MLCNANDFLASH) {
+ if (mtd->type == MTD_MLCNANDFLASH &&
+ !(mtd->flags & MTD_SLC_ON_MLC_EMULATION)) {
pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n",
mtd->index);
return -EINVAL;
diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
index b486250923c5..83afc00e365a 100644
--- a/drivers/mtd/ubi/fastmap-wl.c
+++ b/drivers/mtd/ubi/fastmap-wl.c
@@ -116,6 +116,21 @@ void ubi_refill_pools(struct ubi_device *ubi)
wl_pool->size = 0;
pool->size = 0;
+ if (ubi->fm_anchor) {
+ wl_tree_add(ubi->fm_anchor, &ubi->free);
+ ubi->free_count++;
+ }
+ if (ubi->fm_next_anchor) {
+ wl_tree_add(ubi->fm_next_anchor, &ubi->free);
+ ubi->free_count++;
+ }
+
+ /* All available PEBs are in ubi->free, now is the time to get
+ * the best anchor PEBs.
+ */
+ ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1);
+ ubi->fm_next_anchor = ubi_wl_get_fm_peb(ubi, 1);
+
for (;;) {
enough = 0;
if (pool->size < pool->max_size) {
@@ -271,26 +286,20 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
int ubi_ensure_anchor_pebs(struct ubi_device *ubi)
{
struct ubi_work *wrk;
- struct ubi_wl_entry *anchor;
spin_lock(&ubi->wl_lock);
- /* Do we already have an anchor? */
- if (ubi->fm_anchor) {
- spin_unlock(&ubi->wl_lock);
- return 0;
- }
-
- /* See if we can find an anchor PEB on the list of free PEBs */
- anchor = ubi_wl_get_fm_peb(ubi, 1);
- if (anchor) {
- ubi->fm_anchor = anchor;
- spin_unlock(&ubi->wl_lock);
- return 0;
+ /* Do we have a next anchor? */
+ if (!ubi->fm_next_anchor) {
+ ubi->fm_next_anchor = ubi_wl_get_fm_peb(ubi, 1);
+ if (!ubi->fm_next_anchor)
+ /* Tell wear leveling to produce a new anchor PEB */
+ ubi->fm_do_produce_anchor = 1;
}
- /* No luck, trigger wear leveling to produce a new anchor PEB */
- ubi->fm_do_produce_anchor = 1;
+ /* Do wear leveling to get a new anchor PEB or check the
+ * existing next anchor candidate.
+ */
if (ubi->wl_scheduled) {
spin_unlock(&ubi->wl_lock);
return 0;
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 53f448e7433a..022af59906aa 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1220,6 +1220,17 @@ static int ubi_write_fastmap(struct ubi_device *ubi,
fm_pos += sizeof(*fec);
ubi_assert(fm_pos <= ubi->fm_size);
}
+ if (ubi->fm_next_anchor) {
+ fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+ fec->pnum = cpu_to_be32(ubi->fm_next_anchor->pnum);
+ set_seen(ubi, ubi->fm_next_anchor->pnum, seen_pebs);
+ fec->ec = cpu_to_be32(ubi->fm_next_anchor->ec);
+
+ free_peb_count++;
+ fm_pos += sizeof(*fec);
+ ubi_assert(fm_pos <= ubi->fm_size);
+ }
fmh->free_peb_count = cpu_to_be32(free_peb_count);
ubi_for_each_used_peb(ubi, wl_e, tmp_rb) {
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 73c67e5c08f8..c2da77163f94 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -26,7 +26,7 @@
#include <linux/notifier.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/ubi.h>
-#include <asm/pgtable.h>
+#include <linux/pgtable.h>
#include "ubi-media.h"
@@ -491,7 +491,8 @@ struct ubi_debug_info {
* @fm_work: fastmap work queue
* @fm_work_scheduled: non-zero if fastmap work was scheduled
* @fast_attach: non-zero if UBI was attached by fastmap
- * @fm_anchor: The next anchor PEB to use for fastmap
+ * @fm_anchor: The new anchor PEB used during fastmap update
+ * @fm_next_anchor: An anchor PEB candidate for the next time fastmap is updated
* @fm_do_produce_anchor: If true produce an anchor PEB in wl
*
* @used: RB-tree of used physical eraseblocks
@@ -602,6 +603,7 @@ struct ubi_device {
int fm_work_scheduled;
int fast_attach;
struct ubi_wl_entry *fm_anchor;
+ struct ubi_wl_entry *fm_next_anchor;
int fm_do_produce_anchor;
/* Wear-leveling sub-system's stuff */
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 5146cce5fe32..27636063ed1b 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -687,20 +687,27 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
}
#ifdef CONFIG_MTD_UBI_FASTMAP
+ e1 = find_anchor_wl_entry(&ubi->used);
+ if (e1 && ubi->fm_next_anchor &&
+ (ubi->fm_next_anchor->ec - e1->ec >= UBI_WL_THRESHOLD)) {
+ ubi->fm_do_produce_anchor = 1;
+ /* fm_next_anchor is no longer considered a good anchor
+ * candidate.
+ * NULL assignment also prevents multiple wear level checks
+ * of this PEB.
+ */
+ wl_tree_add(ubi->fm_next_anchor, &ubi->free);
+ ubi->fm_next_anchor = NULL;
+ ubi->free_count++;
+ }
+
if (ubi->fm_do_produce_anchor) {
- e1 = find_anchor_wl_entry(&ubi->used);
if (!e1)
goto out_cancel;
e2 = get_peb_for_wl(ubi);
if (!e2)
goto out_cancel;
- /*
- * Anchor move within the anchor area is useless.
- */
- if (e2->pnum < UBI_FM_MAX_START)
- goto out_cancel;
-
self_check_in_wl_tree(ubi, e1, &ubi->used);
rb_erase(&e1->u.rb, &ubi->used);
dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum);
@@ -1079,8 +1086,11 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
if (!err) {
spin_lock(&ubi->wl_lock);
- if (!ubi->fm_anchor && e->pnum < UBI_FM_MAX_START) {
- ubi->fm_anchor = e;
+ if (!ubi->fm_next_anchor && e->pnum < UBI_FM_MAX_START) {
+ /* Abort anchor production, if needed it will be
+ * enabled again in the wear leveling started below.
+ */
+ ubi->fm_next_anchor = e;
ubi->fm_do_produce_anchor = 0;
} else {
wl_tree_add(e, &ubi->free);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c7d310ef1c83..9a49c4c2316b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -7,7 +7,7 @@ menuconfig NETDEVICES
default y if UML
depends on NET
bool "Network device support"
- ---help---
+ help
You can say N here if you don't intend to connect your Linux box to
any other computer at all.
@@ -32,7 +32,7 @@ config MII
config NET_CORE
default y
bool "Network core driver support"
- ---help---
+ help
You can say N here if you do not intend to use any of the
networking core drivers (i.e. VLAN, bridging, bonding, etc.)
@@ -42,7 +42,7 @@ config BONDING
tristate "Bonding driver support"
depends on INET
depends on IPV6 || IPV6=n
- ---help---
+ help
Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
Channels together. This is called 'Etherchannel' by Cisco,
'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux.
@@ -58,7 +58,7 @@ config BONDING
config DUMMY
tristate "Dummy net driver support"
- ---help---
+ help
This is essentially a bit-bucket device (i.e. traffic you send to
this device is consigned into oblivion) with a configurable IP
address. It is most commonly used in order to make your currently
@@ -116,7 +116,7 @@ config WIREGUARD_DEBUG
config EQUALIZER
tristate "EQL (serial line load balancing) support"
- ---help---
+ help
If you have two serial connections to some other computer (this
usually requires two modems and two telephone lines) and you use
SLIP (the protocol for sending Internet traffic over telephone
@@ -150,7 +150,7 @@ config IFB
tristate "Intermediate Functional Block support"
depends on NET_CLS_ACT
select NET_REDIRECT
- ---help---
+ help
This is an intermediate driver that allows sharing of
resources.
To compile this driver as a module, choose M here: the module
@@ -164,7 +164,7 @@ source "drivers/net/team/Kconfig"
config MACVLAN
tristate "MAC-VLAN support"
- ---help---
+ help
This allows one to create virtual interfaces that map packets to
or from specific MAC addresses to a particular interface.
@@ -200,7 +200,7 @@ config IPVLAN
tristate "IP-VLAN support"
depends on INET
depends on IPV6 || !IPV6
- ---help---
+ help
This allows one to create virtual devices off of a main interface
and packets will be delivered based on the dest L3 (IPv6/IPv4 addr)
on packets. All interfaces (including the main interface) share L2
@@ -219,7 +219,7 @@ config IPVTAP
depends on IPVLAN
depends on INET
select TAP
- ---help---
+ help
This adds a specialized tap character device driver that is based
on the IP-VLAN network interface, called ipvtap. An ipvtap device
can be added in the same way as a ipvlan device, using 'type
@@ -233,7 +233,7 @@ config VXLAN
depends on INET
select NET_UDP_TUNNEL
select GRO_CELLS
- ---help---
+ help
This allows one to create vxlan virtual interfaces that provide
Layer 2 Networks over Layer 3 Networks. VXLAN is often used
to tunnel virtual network infrastructure in virtualized environments.
@@ -249,7 +249,7 @@ config GENEVE
depends on IPV6 || !IPV6
select NET_UDP_TUNNEL
select GRO_CELLS
- ---help---
+ help
This allows one to create geneve virtual interfaces that provide
Layer 2 Networks over Layer 3 Networks. GENEVE is often used
to tunnel virtual network infrastructure in virtualized environments.
@@ -276,7 +276,7 @@ config GTP
tristate "GPRS Tunneling Protocol datapath (GTP-U)"
depends on INET
select NET_UDP_TUNNEL
- ---help---
+ help
This allows one to create gtp virtual interfaces that provide
the GPRS Tunneling Protocol datapath (GTP-U). This tunneling protocol
is used to prevent subscribers from accessing mobile carrier core
@@ -295,12 +295,12 @@ config MACSEC
select CRYPTO_AES
select CRYPTO_GCM
select GRO_CELLS
- ---help---
+ help
MACsec is an encryption standard for Ethernet.
config NETCONSOLE
tristate "Network console logging support"
- ---help---
+ help
If you want to log kernel messages over the network, enable this.
See <file:Documentation/networking/netconsole.rst> for details.
@@ -343,7 +343,7 @@ config TUN
tristate "Universal TUN/TAP device driver support"
depends on INET
select CRC32
- ---help---
+ help
TUN/TAP provides packet reception and transmission for user space
programs. It can be viewed as a simple Point-to-Point or Ethernet
device, which instead of receiving packets from a physical media,
@@ -365,14 +365,14 @@ config TUN
config TAP
tristate
- ---help---
+ help
This option is selected by any driver implementing tap user space
interface for a virtual interface to re-use core tap functionality.
config TUN_VNET_CROSS_LE
bool "Support for cross-endian vnet headers on little-endian kernels"
default n
- ---help---
+ help
This option allows TUN/TAP and MACVTAP device drivers in a
little-endian kernel to parse vnet headers that come from a
big-endian legacy virtio device.
@@ -385,7 +385,7 @@ config TUN_VNET_CROSS_LE
config VETH
tristate "Virtual ethernet pair device"
- ---help---
+ help
This device is a local ethernet tunnel. Devices are created in pairs.
When one end receives the packet it appears on its pair and vice
versa.
@@ -394,13 +394,13 @@ config VIRTIO_NET
tristate "Virtio network driver"
depends on VIRTIO
select NET_FAILOVER
- ---help---
+ help
This is the virtual network driver for virtio. It can be used with
QEMU based VMMs (like KVM or Xen). Say Y or M.
config NLMON
tristate "Virtual netlink monitoring device"
- ---help---
+ help
This option enables a monitoring net device for netlink skbs. The
purpose of this is to analyze netlink messages with packet sockets.
Thus applications like tcpdump will be able to see local netlink
@@ -414,14 +414,14 @@ config NET_VRF
depends on NET_L3_MASTER_DEV
depends on IPV6 || IPV6=n
depends on IPV6_MULTIPLE_TABLES || IPV6=n
- ---help---
+ help
This option enables the support for mapping interfaces into VRF's. The
support enables VRF devices.
config VSOCKMON
tristate "Virtual vsock monitoring device"
depends on VHOST_VSOCK
- ---help---
+ help
This option enables a monitoring net device for vsock sockets. It is
mostly intended for developers or support to debug vsock issues. If
unsure, say N.
@@ -450,7 +450,7 @@ source "drivers/net/ipa/Kconfig"
config NET_SB1000
tristate "General Instruments Surfboard 1000"
depends on PNP
- ---help---
+ help
This is a driver for the General Instrument (also known as
NextLevel) SURFboard 1000 internal
cable modem. This is an ISA card which is used by a number of cable
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
index 10589a82263b..09f94d4b14e2 100644
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -5,7 +5,7 @@
config ATALK
tristate "Appletalk protocol support"
select LLC
- ---help---
+ help
AppleTalk is the protocol that Apple computers can use to communicate
on a network. If your Linux box is connected to such a network and you
wish to connect to it, say Y. You will need to use the netatalk package
@@ -79,7 +79,7 @@ config COPS_TANGENT
config IPDDP
tristate "Appletalk-IP driver support"
depends on DEV_APPLETALK && ATALK
- ---help---
+ help
This allows IP networking for users who only have AppleTalk
networking available. This feature is experimental. With this
driver, you can encapsulate IP inside AppleTalk (e.g. if your Linux
diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
index 43eef60653b2..a51b9dab6d3a 100644
--- a/drivers/net/arcnet/Kconfig
+++ b/drivers/net/arcnet/Kconfig
@@ -6,7 +6,7 @@
menuconfig ARCNET
depends on NETDEVICES && (ISA || PCI || PCMCIA)
tristate "ARCnet support"
- ---help---
+ help
If you have a network card of this type, say Y and check out the
(arguably) beautiful poetry in
<file:Documentation/networking/arcnet.rst>.
@@ -33,7 +33,7 @@ config ARCNET_1201
config ARCNET_1051
tristate "Enable old ARCNet packet format (RFC 1051)"
- ---help---
+ help
This allows you to use RFC1051 with your ARCnet card via the virtual
arc0s device. You only need arc0s if you want to talk to ARCnet
software complying with the "old" standard, specifically, the DOS
@@ -82,7 +82,7 @@ config ARCNET_COM90xx
config ARCNET_COM90xxIO
tristate "ARCnet COM90xx (IO mapped) chipset driver"
- ---help---
+ help
This is the chipset driver for the COM90xx cards, using them in
IO-mapped mode instead of memory-mapped mode. This is slower than
the normal driver. Only use it if your card doesn't support shared
@@ -93,7 +93,7 @@ config ARCNET_COM90xxIO
config ARCNET_RIM_I
tristate "ARCnet COM90xx (RIM I) chipset driver"
- ---help---
+ help
This is yet another chipset driver for the COM90xx cards, but this
time only using memory-mapped mode, and no IO ports at all. This
driver is completely untested, so if you have one of these cards,
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index 1538ad194cf4..c245edddb48b 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -15,7 +15,7 @@ config CAIF_TTY
tristate "CAIF TTY transport driver"
depends on CAIF && TTY
default n
- ---help---
+ help
The CAIF TTY transport driver is a Line Discipline (ldisc)
identified as N_CAIF. When this ldisc is opened from user space
it will redirect the TTY's traffic into the CAIF stack.
@@ -24,7 +24,7 @@ config CAIF_SPI_SLAVE
tristate "CAIF SPI transport driver for slave interface"
depends on CAIF && HAS_DMA
default n
- ---help---
+ help
The CAIF Link layer SPI Protocol driver for Slave SPI interface.
This driver implements a platform driver to accommodate for a
platform specific SPI device. A sample CAIF SPI Platform device is
@@ -34,7 +34,7 @@ config CAIF_SPI_SYNC
bool "Next command and length in start of frame"
depends on CAIF_SPI_SLAVE
default n
- ---help---
+ help
Putting the next command and length in the start of the frame can
help to synchronize to the next transfer in case of over or under-runs.
This option also needs to be enabled on the modem.
@@ -43,19 +43,19 @@ config CAIF_HSI
tristate "CAIF HSI transport driver"
depends on CAIF
default n
- ---help---
+ help
The CAIF low level driver for CAIF over HSI.
Be aware that if you enable this then you also need to
enable a low-level HSI driver.
config CAIF_VIRTIO
tristate "CAIF virtio transport driver"
- depends on CAIF && HAS_DMA && VHOST_DPN
+ depends on CAIF && HAS_DMA
select VHOST_RING
select VIRTIO
select GENERIC_ALLOCATOR
default n
- ---help---
+ help
The CAIF driver for CAIF over Virtio.
endif # CAIF_DRIVERS
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 17c166cc8482..f07012a76c0c 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -3,7 +3,7 @@ menu "CAN Device Drivers"
config CAN_VCAN
tristate "Virtual Local CAN Interface (vcan)"
- ---help---
+ help
Similar to the network loopback devices, vcan offers a
virtual local CAN interface.
@@ -12,7 +12,7 @@ config CAN_VCAN
config CAN_VXCAN
tristate "Virtual CAN Tunnel (vxcan)"
- ---help---
+ help
Similar to the virtual ethernet driver veth, vxcan implements a
local CAN traffic tunnel between two virtual CAN network devices.
When creating a vxcan, two vxcan devices are created as pair.
@@ -31,7 +31,7 @@ config CAN_VXCAN
config CAN_SLCAN
tristate "Serial / USB serial CAN Adaptors (slcan)"
depends on TTY
- ---help---
+ help
CAN driver for several 'low cost' CAN interfaces that are attached
via serial lines or via USB-to-serial adapters using the LAWICEL
ASCII protocol. The driver implements the tty linediscipline N_SLCAN.
@@ -51,7 +51,7 @@ config CAN_SLCAN
config CAN_DEV
tristate "Platform CAN drivers with Netlink support"
default y
- ---help---
+ help
Enables the common framework for platform CAN drivers with Netlink
support. This is the standard library for CAN drivers.
If unsure, say Y.
@@ -61,7 +61,7 @@ if CAN_DEV
config CAN_CALC_BITTIMING
bool "CAN bit-timing calculation"
default y
- ---help---
+ help
If enabled, CAN bit-timing parameters will be calculated for the
bit-rate specified via Netlink argument "bitrate" when the device
get started. This works fine for the most common CAN controllers
@@ -81,7 +81,7 @@ config CAN_LEDS
# fulfills your needs instead of fixing this driver.
depends on BROKEN
select LEDS_TRIGGERS
- ---help---
+ help
This option adds two LED triggers for packet receive and transmit
events on each supported CAN device.
@@ -91,20 +91,20 @@ config CAN_LEDS
config CAN_AT91
tristate "Atmel AT91 onchip CAN controller"
depends on (ARCH_AT91 || COMPILE_TEST) && HAS_IOMEM
- ---help---
+ help
This is a driver for the SoC CAN controller in Atmel's AT91SAM9263
and AT91SAM9X5 processors.
config CAN_FLEXCAN
tristate "Support for Freescale FLEXCAN based chips"
depends on OF && HAS_IOMEM
- ---help---
+ help
Say Y here if you want to support for Freescale FlexCAN.
config CAN_GRCAN
tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
depends on OF && HAS_DMA
- ---help---
+ help
Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
Note that the driver supports little endian, even though little
endian syntheses of the cores would need some modifications on
@@ -113,7 +113,7 @@ config CAN_GRCAN
config CAN_JANZ_ICAN3
tristate "Janz VMOD-ICAN3 Intelligent CAN controller"
depends on MFD_JANZ_CMODIO
- ---help---
+ help
Driver for Janz VMOD-ICAN3 Intelligent CAN controller module, which
connects to a MODULbus carrier board.
@@ -136,7 +136,7 @@ config CAN_KVASER_PCIEFD
config CAN_SUN4I
tristate "Allwinner A10 CAN controller"
depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
- ---help---
+ help
Say Y here if you want to use CAN controller found on Allwinner
A10/A20 SoCs.
@@ -146,7 +146,7 @@ config CAN_SUN4I
config CAN_TI_HECC
depends on ARM
tristate "TI High End CAN Controller"
- ---help---
+ help
Driver for TI HECC (High End CAN Controller) module found on many
TI devices. The device specifications are available from www.ti.com
@@ -154,14 +154,14 @@ config CAN_XILINXCAN
tristate "Xilinx CAN"
depends on ARCH_ZYNQ || ARM64 || MICROBLAZE || COMPILE_TEST
depends on COMMON_CLK && HAS_IOMEM
- ---help---
+ help
Xilinx CAN driver. This driver supports both soft AXI CAN IP and
Zynq CANPS IP.
config PCH_CAN
tristate "Intel EG20T PCH CAN controller"
depends on PCI && (X86_32 || COMPILE_TEST)
- ---help---
+ help
This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which
is an IOH for x86 embedded processor (Intel Atom E6xx series).
This driver can access CAN bus.
@@ -182,7 +182,7 @@ endif
config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages"
- ---help---
+ help
Say Y here if you want the CAN device drivers to produce a bunch of
debug messages to the system log. Select this if you are having
a problem with CAN support and want to see more of what is going
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig
index b0f206d36f55..962725788b0a 100644
--- a/drivers/net/can/c_can/Kconfig
+++ b/drivers/net/can/c_can/Kconfig
@@ -7,7 +7,7 @@ if CAN_C_CAN
config CAN_C_CAN_PLATFORM
tristate "Generic Platform Bus based C_CAN/D_CAN driver"
- ---help---
+ help
This driver adds support for the C_CAN/D_CAN chips connected
to the "platform bus" (Linux abstraction for directly to the
processor attached devices) which can be found on various
@@ -18,7 +18,7 @@ config CAN_C_CAN_PLATFORM
config CAN_C_CAN_PCI
tristate "Generic PCI Bus based C_CAN/D_CAN driver"
depends on PCI
- ---help---
+ help
This driver adds support for the C_CAN/D_CAN chips connected
to the PCI bus.
endif
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
index 13a4593a52df..9ef1359319f0 100644
--- a/drivers/net/can/cc770/Kconfig
+++ b/drivers/net/can/cc770/Kconfig
@@ -7,14 +7,14 @@ if CAN_CC770
config CAN_CC770_ISA
tristate "ISA Bus based legacy CC770 driver"
- ---help---
+ help
This driver adds legacy support for CC770 and AN82527 chips
connected to the ISA bus using I/O port, memory mapped or
indirect access.
config CAN_CC770_PLATFORM
tristate "Generic Platform Bus based CC770 driver"
- ---help---
+ help
This driver adds support for the CC770 and AN82527 chips
connected to the "platform bus" (Linux abstraction for directly
to the processor attached devices).
diff --git a/drivers/net/can/ifi_canfd/Kconfig b/drivers/net/can/ifi_canfd/Kconfig
index ce0197641a59..b5dd9c13d529 100644
--- a/drivers/net/can/ifi_canfd/Kconfig
+++ b/drivers/net/can/ifi_canfd/Kconfig
@@ -2,7 +2,7 @@
config CAN_IFI_CANFD
depends on HAS_IOMEM
tristate "IFI CAN_FD IP"
- ---help---
+ help
This driver adds support for the I/F/I CAN_FD soft IP block
connected to the "platform bus" (Linux abstraction for directly
to the processor attached devices). The CAN_FD is most often
diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig
index 1ff0b7fe81d6..d9216147ca93 100644
--- a/drivers/net/can/m_can/Kconfig
+++ b/drivers/net/can/m_can/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config CAN_M_CAN
tristate "Bosch M_CAN support"
- ---help---
+ help
Say Y here if you want support for Bosch M_CAN controller framework.
This is common support for devices that embed the Bosch M_CAN IP.
@@ -9,7 +9,7 @@ config CAN_M_CAN_PLATFORM
tristate "Bosch M_CAN support for io-mapped devices"
depends on HAS_IOMEM
depends on CAN_M_CAN
- ---help---
+ help
Say Y here if you want support for IO Mapped Bosch M_CAN controller.
This support is for devices that have the Bosch M_CAN controller
IP embedded into the device and the IP is IO Mapped to the processor.
@@ -18,7 +18,7 @@ config CAN_M_CAN_TCAN4X5X
depends on CAN_M_CAN
depends on REGMAP_SPI
tristate "TCAN4X5X M_CAN device"
- ---help---
+ help
Say Y here if you want support for Texas Instruments TCAN4x5x
M_CAN controller. This device is a peripherial device that uses the
SPI bus for communication.
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig
index 3a57a51be22e..dfe6bd9947bb 100644
--- a/drivers/net/can/mscan/Kconfig
+++ b/drivers/net/can/mscan/Kconfig
@@ -2,7 +2,7 @@
config CAN_MSCAN
depends on PPC
tristate "Support for Freescale MSCAN based chips"
- ---help---
+ help
The Motorola Scalable Controller Area Network (MSCAN) definition
is based on the MSCAN12 definition which is the specific
implementation of the Motorola Scalable CAN concept targeted for
@@ -13,7 +13,7 @@ if CAN_MSCAN
config CAN_MPC5XXX
tristate "Freescale MPC5xxx onboard CAN controller"
depends on (PPC_MPC52xx || PPC_MPC512x)
- ---help---
+ help
If you say yes here you get support for Freescale's MPC5xxx
onboard CAN controller. Currently, the MPC5200, MPC5200B and
MPC5121 (Rev. 2 and later) are supported.
diff --git a/drivers/net/can/peak_canfd/Kconfig b/drivers/net/can/peak_canfd/Kconfig
index c29ab2150794..f7e412766dbd 100644
--- a/drivers/net/can/peak_canfd/Kconfig
+++ b/drivers/net/can/peak_canfd/Kconfig
@@ -2,7 +2,7 @@
config CAN_PEAK_PCIEFD
depends on PCI
tristate "PEAK-System PCAN-PCIe FD cards"
- ---help---
+ help
This driver adds support for the PEAK-System PCI Express FD
CAN-FD cards family.
These 1x or 2x CAN-FD channels cards offer CAN 2.0 a/b as well as
diff --git a/drivers/net/can/rcar/Kconfig b/drivers/net/can/rcar/Kconfig
index bd5a8fcd83e1..8d36101b78e3 100644
--- a/drivers/net/can/rcar/Kconfig
+++ b/drivers/net/can/rcar/Kconfig
@@ -2,7 +2,7 @@
config CAN_RCAR
tristate "Renesas R-Car CAN controller"
depends on ARCH_RENESAS || ARM
- ---help---
+ help
Say Y here if you want to use CAN controller found on Renesas R-Car
SoCs.
@@ -12,7 +12,7 @@ config CAN_RCAR
config CAN_RCAR_CANFD
tristate "Renesas R-Car CAN FD controller"
depends on ARCH_RENESAS || ARM
- ---help---
+ help
Say Y here if you want to use CAN FD controller found on
Renesas R-Car SoCs. The driver puts the controller in CAN FD only
mode, which can interoperate with CAN2.0 nodes but does not support
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index 32d242dc0d9f..110071b26921 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -9,7 +9,7 @@ if CAN_SJA1000
config CAN_EMS_PCI
tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
depends on PCI
- ---help---
+ help
This driver is for the one, two or four channel CPC-PCI,
CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
(http://www.ems-wuensche.de).
@@ -17,7 +17,7 @@ config CAN_EMS_PCI
config CAN_EMS_PCMCIA
tristate "EMS CPC-CARD Card"
depends on PCMCIA
- ---help---
+ help
This driver is for the one or two channel CPC-CARD cards from
EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
@@ -34,14 +34,14 @@ config CAN_F81601
config CAN_KVASER_PCI
tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
depends on PCI
- ---help---
+ help
This driver is for the PCIcanx and PCIcan cards (1, 2 or
4 channel) from Kvaser (http://www.kvaser.com).
config CAN_PEAK_PCI
tristate "PEAK PCAN-PCI/PCIe/miniPCI Cards"
depends on PCI
- ---help---
+ help
This driver is for the PCAN-PCI/PCIe/miniPCI cards
(1, 2, 3 or 4 channels) from PEAK-System Technik
(http://www.peak-system.com).
@@ -52,7 +52,7 @@ config CAN_PEAK_PCIEC
select I2C
select I2C_ALGOBIT
default y
- ---help---
+ help
Say Y here if you want to use a PCAN-ExpressCard from PEAK-System
Technik. This will also automatically select I2C and I2C_ALGO
configuration options.
@@ -61,7 +61,7 @@ config CAN_PEAK_PCMCIA
tristate "PEAK PCAN-PC Card"
depends on PCMCIA
depends on HAS_IOPORT_MAP
- ---help---
+ help
This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels)
from PEAK-System (http://www.peak-system.com). To compile this
driver as a module, choose M here: the module will be called
@@ -70,7 +70,7 @@ config CAN_PEAK_PCMCIA
config CAN_PLX_PCI
tristate "PLX90xx PCI-bridge based Cards"
depends on PCI
- ---help---
+ help
This driver is for CAN interface cards based on
the PLX90xx PCI bridge.
Driver supports now:
@@ -87,13 +87,13 @@ config CAN_PLX_PCI
config CAN_SJA1000_ISA
tristate "ISA Bus based legacy SJA1000 driver"
- ---help---
+ help
This driver adds legacy support for SJA1000 chips connected to
the ISA bus using I/O port, memory mapped or indirect access.
config CAN_SJA1000_PLATFORM
tristate "Generic Platform Bus based SJA1000 driver"
- ---help---
+ help
This driver adds support for the SJA1000 chips connected to
the "platform bus" (Linux abstraction for directly to the
processor attached devices). Which can be found on various
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig
index 0f1708f99308..16b9eec63490 100644
--- a/drivers/net/can/softing/Kconfig
+++ b/drivers/net/can/softing/Kconfig
@@ -2,7 +2,7 @@
config CAN_SOFTING
tristate "Softing Gmbh CAN generic support"
depends on HAS_IOMEM
- ---help---
+ help
Support for CAN cards from Softing Gmbh & some cards
from Vector Gmbh.
Softing Gmbh CAN cards come with 1 or 2 physical busses.
@@ -20,7 +20,7 @@ config CAN_SOFTING_CS
tristate "Softing Gmbh CAN pcmcia cards"
depends on PCMCIA
depends on CAN_SOFTING
- ---help---
+ help
Support for PCMCIA cards from Softing Gmbh & some cards
from Vector Gmbh.
You need firmware for these, which you can get at
diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
index 1c50788055cb..f780c79aac6f 100644
--- a/drivers/net/can/spi/Kconfig
+++ b/drivers/net/can/spi/Kconfig
@@ -5,13 +5,13 @@ menu "CAN SPI interfaces"
config CAN_HI311X
tristate "Holt HI311x SPI CAN controllers"
depends on CAN_DEV && SPI && HAS_DMA
- ---help---
+ help
Driver for the Holt HI311x SPI CAN controllers.
config CAN_MCP251X
tristate "Microchip MCP251x and MCP25625 SPI CAN controllers"
depends on HAS_DMA
- ---help---
+ help
Driver for the Microchip MCP251x and MCP25625 SPI CAN
controllers.
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
index b412f7ba4f89..77fa830fe7dd 100644
--- a/drivers/net/can/usb/Kconfig
+++ b/drivers/net/can/usb/Kconfig
@@ -4,25 +4,25 @@ menu "CAN USB interfaces"
config CAN_8DEV_USB
tristate "8 devices USB2CAN interface"
- ---help---
+ help
This driver supports the USB2CAN interface
from 8 devices (http://www.8devices.com).
config CAN_EMS_USB
tristate "EMS CPC-USB/ARM7 CAN/USB interface"
- ---help---
+ help
This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
config CAN_ESD_USB2
tristate "ESD USB/2 CAN/USB interface"
- ---help---
+ help
This driver supports the CAN-USB/2 interface
from esd electronic system design gmbh (http://www.esd.eu).
config CAN_GS_USB
tristate "Geschwister Schneider UG interfaces"
- ---help---
+ help
This driver supports the Geschwister Schneider and bytewerk.org
candleLight USB CAN interfaces USB/CAN devices
If unsure choose N,
@@ -31,7 +31,7 @@ config CAN_GS_USB
config CAN_KVASER_USB
tristate "Kvaser CAN/USB interface"
- ---help---
+ help
This driver adds support for Kvaser CAN/USB devices like Kvaser
Leaf Light, Kvaser USBcan II and Kvaser Memorator Pro 5xHS.
@@ -82,13 +82,13 @@ config CAN_KVASER_USB
config CAN_MCBA_USB
tristate "Microchip CAN BUS Analyzer interface"
- ---help---
+ help
This driver supports the CAN BUS Analyzer interface
from Microchip (http://www.microchip.com/development-tools/).
config CAN_PEAK_USB
tristate "PEAK PCAN-USB/USB Pro interfaces for CAN 2.0b/CAN-FD"
- ---help---
+ help
This driver supports the PEAK-System Technik USB adapters that enable
access to the CAN bus, with repect to the CAN 2.0b and/or CAN-FD
standards, that is:
@@ -104,7 +104,7 @@ config CAN_PEAK_USB
config CAN_UCAN
tristate "Theobroma Systems UCAN interface"
- ---help---
+ help
This driver supports the Theobroma Systems
UCAN USB-CAN interface.
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 2d38dbc9dd8c..d0024cb30a7b 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -12,7 +12,7 @@ config NET_DSA_BCM_SF2
select BCM7XXX_PHY
select MDIO_BCM_UNIMAC
select B53
- ---help---
+ help
This enables support for the Broadcom Starfighter 2 Ethernet
switch chips.
@@ -20,7 +20,7 @@ config NET_DSA_LOOP
tristate "DSA mock-up Ethernet switch chip support"
depends on NET_DSA
select FIXED_PHY
- ---help---
+ help
This enables support for a fake mock-up switch chip which
exercises the DSA APIs.
@@ -28,7 +28,7 @@ config NET_DSA_LANTIQ_GSWIP
tristate "Lantiq / Intel GSWIP"
depends on HAS_IOMEM && NET_DSA
select NET_DSA_TAG_GSWIP
- ---help---
+ help
This enables support for the Lantiq / Intel GSWIP 2.1 found in
the xrx200 / VR9 SoC.
@@ -36,7 +36,7 @@ config NET_DSA_MT7530
tristate "Mediatek MT7530 Ethernet switch support"
depends on NET_DSA
select NET_DSA_TAG_MTK
- ---help---
+ help
This enables support for the Mediatek MT7530 Ethernet switch
chip.
@@ -44,7 +44,7 @@ config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
depends on NET_DSA
select NET_DSA_TAG_TRAILER
- ---help---
+ help
This enables support for the Marvell 88E6060 ethernet switch
chip.
@@ -63,7 +63,7 @@ config NET_DSA_QCA8K
depends on NET_DSA
select NET_DSA_TAG_QCA
select REGMAP
- ---help---
+ help
This enables support for the Qualcomm Atheros QCA8K Ethernet
switch chips.
@@ -74,7 +74,7 @@ config NET_DSA_REALTEK_SMI
select IRQ_DOMAIN
select REALTEK_PHY
select REGMAP
- ---help---
+ help
This enables support for the Realtek SMI-based switch
chips, currently only RTL8366RB.
@@ -82,7 +82,7 @@ config NET_DSA_SMSC_LAN9303
tristate
select NET_DSA_TAG_LAN9303
select REGMAP
- ---help---
+ help
This enables support for the SMSC/Microchip LAN9303 3 port ethernet
switch chips.
@@ -91,7 +91,7 @@ config NET_DSA_SMSC_LAN9303_I2C
depends on NET_DSA && I2C
select NET_DSA_SMSC_LAN9303
select REGMAP_I2C
- ---help---
+ help
Enable access functions if the SMSC/Microchip LAN9303 is configured
for I2C managed mode.
@@ -99,7 +99,7 @@ config NET_DSA_SMSC_LAN9303_MDIO
tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in MDIO managed mode"
depends on NET_DSA
select NET_DSA_SMSC_LAN9303
- ---help---
+ help
Enable access functions if the SMSC/Microchip LAN9303 is configured
for MDIO managed mode.
@@ -109,7 +109,7 @@ config NET_DSA_VITESSE_VSC73XX
select FIXED_PHY
select VITESSE_PHY
select GPIOLIB
- ---help---
+ help
This enables support for the Vitesse VSC7385, VSC7388,
VSC7395 and VSC7398 SparX integrated ethernet switches.
@@ -118,7 +118,7 @@ config NET_DSA_VITESSE_VSC73XX_SPI
depends on NET_DSA
depends on SPI
select NET_DSA_VITESSE_VSC73XX
- ---help---
+ help
This enables support for the Vitesse VSC7385, VSC7388, VSC7395
and VSC7398 SparX integrated ethernet switches in SPI managed mode.
@@ -127,7 +127,7 @@ config NET_DSA_VITESSE_VSC73XX_PLATFORM
depends on NET_DSA
depends on HAS_IOMEM
select NET_DSA_VITESSE_VSC73XX
- ---help---
+ help
This enables support for the Vitesse VSC7385, VSC7388, VSC7395
and VSC7398 SparX integrated ethernet switches, connected over
a CPU-attached address bus and work in memory-mapped I/O mode.
diff --git a/drivers/net/dsa/qca/Kconfig b/drivers/net/dsa/qca/Kconfig
index e3c8d715a18f..13b7e679b8b5 100644
--- a/drivers/net/dsa/qca/Kconfig
+++ b/drivers/net/dsa/qca/Kconfig
@@ -4,6 +4,6 @@ config NET_DSA_AR9331
depends on NET_DSA
select NET_DSA_TAG_AR9331
select REGMAP
- ---help---
+ help
This enables support for the Qualcomm Atheros AR9331 built-in Ethernet
switch.
diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig
index 7cc259893cb9..074b0974769c 100644
--- a/drivers/net/ethernet/3com/Kconfig
+++ b/drivers/net/ethernet/3com/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_3COM
bool "3Com devices"
default y
depends on ISA || EISA || PCI || PCMCIA
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_3COM
config EL3
tristate "3c509/3c579 \"EtherLink III\" support"
depends on (ISA || EISA)
- ---help---
+ help
If you have a network (Ethernet) card belonging to the 3Com
EtherLinkIII series, say Y here.
@@ -34,7 +34,7 @@ config EL3
config 3C515
tristate "3c515 ISA \"Fast EtherLink\""
depends on ISA && ISA_DMA_API && !PPC32
- ---help---
+ help
If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
network card, say Y here.
@@ -44,7 +44,7 @@ config 3C515
config PCMCIA_3C574
tristate "3Com 3c574 PCMCIA support"
depends on PCMCIA
- ---help---
+ help
Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
(PC-card) Fast Ethernet card to your computer.
@@ -54,7 +54,7 @@ config PCMCIA_3C574
config PCMCIA_3C589
tristate "3Com 3c589 PCMCIA support"
depends on PCMCIA
- ---help---
+ help
Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
(PC-card) Ethernet card to your computer.
@@ -65,7 +65,7 @@ config VORTEX
tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
depends on (PCI || EISA) && HAS_IOPORT_MAP
select MII
- ---help---
+ help
This option enables driver support for a large number of 10Mbps and
10/100Mbps EISA, PCI and Cardbus 3Com network cards:
@@ -86,7 +86,7 @@ config TYPHOON
tristate "3cr990 series \"Typhoon\" support"
depends on PCI
select CRC32
- ---help---
+ help
This option enables driver support for the 3cr990 series of cards:
3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index a9478577b495..9f4b302fd2ce 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_8390
bool "National Semiconductor 8390 devices"
default y
depends on NET_VENDOR_NATSEMI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_8390
config PCMCIA_AXNET
tristate "Asix AX88190 PCMCIA support"
depends on PCMCIA
- ---help---
+ help
Say Y here if you intend to attach an Asix AX88190-based PCMCIA
(PC-card) Fast Ethernet card to your computer. These cards are
nearly NE2000 compatible but need a separate driver due to a few
@@ -35,7 +35,7 @@ config AX88796
select CRC32
select PHYLIB
select MDIO_BITBANG
- ---help---
+ help
AX88796 driver, using platform bus to provide
chip detection and resources
@@ -43,7 +43,7 @@ config AX88796_93CX6
bool "ASIX AX88796 external 93CX6 eeprom support"
depends on AX88796
select EEPROM_93CX6
- ---help---
+ help
Select this if your platform comes with an external 93CX6 eeprom.
config XSURF100
@@ -63,7 +63,7 @@ config HYDRA
tristate "Hydra support"
depends on ZORRO
select CRC32
- ---help---
+ help
If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
To compile this driver as a module, choose M here: the module
@@ -73,7 +73,7 @@ config ARM_ETHERH
tristate "I-cubed EtherH/ANT EtherM support"
depends on ARM && ARCH_ACORN
select CRC32
- ---help---
+ help
If you have an Acorn system with one of these network cards, you
should say Y to this option if you wish to use it with Linux.
@@ -81,7 +81,7 @@ config MAC8390
tristate "Macintosh NS 8390 based ethernet cards"
depends on MAC
select CRC32
- ---help---
+ help
If you want to include a driver to support Nubus or LC-PDS
Ethernet cards using an NS8390 chipset or its equivalent, say Y.
@@ -89,7 +89,7 @@ config MCF8390
tristate "ColdFire NS8390 based Ethernet support"
depends on COLDFIRE
select CRC32
- ---help---
+ help
This driver is for Ethernet devices using an NS8390-compatible
chipset on many common ColdFire CPU based boards. Many of the older
Freescale dev boards use this, and some other common boards like
@@ -103,7 +103,7 @@ config NE2000
tristate "NE2000/NE1000 support"
depends on (ISA || (Q40 && m) || MACH_TX49XX || ATARI_ETHERNEC)
select CRC32
- ---help---
+ help
If you have a network (Ethernet) card of this type, say Y here.
Many Ethernet cards without a specific driver are compatible with
the NE2000.
@@ -118,7 +118,7 @@ config NE2K_PCI
tristate "PCI NE2000 and clones support (see help)"
depends on PCI
select CRC32
- ---help---
+ help
This driver is for NE2000 compatible PCI cards. It will not work
with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
support" below). If you have a PCI NE2000 network (Ethernet) card,
@@ -136,7 +136,7 @@ config APNE
tristate "PCMCIA NE2000 support"
depends on AMIGA_PCMCIA
select CRC32
- ---help---
+ help
If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
say N.
@@ -147,7 +147,7 @@ config PCMCIA_PCNET
tristate "NE2000 compatible PCMCIA support"
depends on PCMCIA
select CRC32
- ---help---
+ help
Say Y here if you intend to attach an NE2000 compatible PCMCIA
(PC-card) Ethernet or Fast Ethernet card to your computer.
@@ -158,7 +158,7 @@ config STNIC
tristate "National DP83902AV support"
depends on SUPERH
select CRC32
- ---help---
+ help
Support for cards based on the National Semiconductor DP83902AV
ST-NIC Serial Network Interface Controller for Twisted Pair. This
is a 10Mbit/sec Ethernet controller. Product overview and specs at
@@ -170,7 +170,7 @@ config ULTRA
tristate "SMC Ultra support"
depends on ISA
select CRC32
- ---help---
+ help
If you have a network (Ethernet) card of this type, say Y here.
Important: There have been many reports that, with some motherboards
@@ -187,7 +187,7 @@ config WD80x3
tristate "WD80*3 support"
depends on ISA
select CRC32
- ---help---
+ help
If you have a network (Ethernet) card of this type, say Y here.
To compile this driver as a module, choose M here. The module
@@ -197,7 +197,7 @@ config ZORRO8390
tristate "Zorro NS8390-based Ethernet support"
depends on ZORRO
select CRC32
- ---help---
+ help
This driver is for Zorro Ethernet cards using an NS8390-compatible
chipset, like the Village Tronic Ariadne II and the Individual
Computers X-Surf Ethernet cards. If you have such a card, say Y.
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 4ded81b27d0a..de50e8b9e656 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -7,7 +7,7 @@ menuconfig ETHERNET
bool "Ethernet driver support"
depends on NET
default y
- ---help---
+ help
This section contains all the Ethernet device drivers.
if ETHERNET
@@ -48,7 +48,7 @@ config CX_ECAT
tristate "Beckhoff CX5020 EtherCAT master support"
depends on PCI
depends on X86 || COMPILE_TEST
- ---help---
+ help
Driver for EtherCAT master module located on CCAT FPGA
that can be found on Beckhoff CX5020, and possibly other of CX
Beckhoff CX series industrial PCs.
@@ -62,7 +62,7 @@ config DNET
tristate "Dave ethernet support (DNET)"
depends on HAS_IOMEM
select PHYLIB
- ---help---
+ help
The Dave ethernet interface (DNET) is found on Qong Board FPGA.
Say Y to include support for the DNET chip.
@@ -89,7 +89,7 @@ config JME
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver supports the PCI-Express gigabit ethernet adapters
based on JMicron JMC250 chipset.
@@ -99,20 +99,20 @@ config JME
config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
depends on MIKROTIK_RB532
- ---help---
+ help
If you have a Mikrotik RouterBoard 500 or IDT RC32434
based system say Y. Otherwise say N.
config LANTIQ_ETOP
tristate "Lantiq SoC ETOP driver"
depends on SOC_TYPE_XWAY
- ---help---
+ help
Support for the MII0 inside the Lantiq SoC
config LANTIQ_XRX200
tristate "Lantiq / Intel xRX200 PMAC network driver"
depends on SOC_TYPE_XWAY
- ---help---
+ help
Support for the PMAC of the Gigabit switch (GSWIP) inside the
Lantiq / Intel VRX200 VDSL SoC
@@ -130,7 +130,7 @@ config FEALNX
depends on PCI
select CRC32
select MII
- ---help---
+ help
Say Y here to support the Myson MTD-800 family of PCI-based Ethernet
cards. <http://www.myson.com.tw/>
@@ -150,7 +150,7 @@ config ETHOC
select PHYLIB
select CRC32
select BITREVERSE
- ---help---
+ help
Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
source "drivers/net/ethernet/packetengines/Kconfig"
diff --git a/drivers/net/ethernet/adaptec/Kconfig b/drivers/net/ethernet/adaptec/Kconfig
index 86e02da4f993..c96edc2e582f 100644
--- a/drivers/net/ethernet/adaptec/Kconfig
+++ b/drivers/net/ethernet/adaptec/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_ADAPTEC
bool "Adaptec devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config ADAPTEC_STARFIRE
depends on PCI
select CRC32
select MII
- ---help---
+ help
Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
adapter. The DuraLAN chip is used on the 64 bit PCI boards from
Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
diff --git a/drivers/net/ethernet/aeroflex/Kconfig b/drivers/net/ethernet/aeroflex/Kconfig
index 2fa0a317266b..ea4be67f787b 100644
--- a/drivers/net/ethernet/aeroflex/Kconfig
+++ b/drivers/net/ethernet/aeroflex/Kconfig
@@ -8,5 +8,5 @@ config GRETH
depends on SPARC
select PHYLIB
select CRC32
- ---help---
+ help
Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
diff --git a/drivers/net/ethernet/agere/Kconfig b/drivers/net/ethernet/agere/Kconfig
index 084c7190ce2f..d92516ae59cc 100644
--- a/drivers/net/ethernet/agere/Kconfig
+++ b/drivers/net/ethernet/agere/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_AGERE
bool "Agere devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config ET131X
tristate "Agere ET-1310 Gigabit Ethernet support"
depends on PCI
select PHYLIB
- ---help---
+ help
This driver supports Agere ET-1310 ethernet adapters.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/alacritech/Kconfig b/drivers/net/ethernet/alacritech/Kconfig
index 212f92c8e6a9..5f285e18faf7 100644
--- a/drivers/net/ethernet/alacritech/Kconfig
+++ b/drivers/net/ethernet/alacritech/Kconfig
@@ -2,7 +2,7 @@
config NET_VENDOR_ALACRITECH
bool "Alacritech devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -16,7 +16,7 @@ config SLICOSS
tristate "Alacritech Slicoss support"
depends on PCI
select CRC32
- ---help---
+ help
This driver supports Gigabit Ethernet adapters based on the
Session Layer Interface (SLIC) technology by Alacritech.
diff --git a/drivers/net/ethernet/allwinner/Kconfig b/drivers/net/ethernet/allwinner/Kconfig
index 264a482ec31d..3e81059f8693 100644
--- a/drivers/net/ethernet/allwinner/Kconfig
+++ b/drivers/net/ethernet/allwinner/Kconfig
@@ -8,7 +8,7 @@ config NET_VENDOR_ALLWINNER
default y
depends on ARCH_SUNXI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this
class, say Y here.
@@ -28,7 +28,7 @@ config SUN4I_EMAC
select MII
select PHYLIB
select MDIO_SUN4I
- ---help---
+ help
Support for Allwinner A10 EMAC ethernet driver.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/alteon/Kconfig b/drivers/net/ethernet/alteon/Kconfig
index c3f7067d2d10..cfe1f3159d61 100644
--- a/drivers/net/ethernet/alteon/Kconfig
+++ b/drivers/net/ethernet/alteon/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_ALTEON
bool "Alteon devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_ALTEON
config ACENIC
tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
depends on PCI
- ---help---
+ help
Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
adapter. The driver allows for using the Jumbo Frame option (9000
@@ -34,7 +34,7 @@ config ACENIC
config ACENIC_OMIT_TIGON_I
bool "Omit support for old Tigon I based AceNICs"
depends on ACENIC
- ---help---
+ help
Say Y here if you only have Tigon II based AceNICs and want to leave
out support for the older Tigon I based cards which are no longer
being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
diff --git a/drivers/net/ethernet/altera/Kconfig b/drivers/net/ethernet/altera/Kconfig
index 2690c398d2b2..914e56b91467 100644
--- a/drivers/net/ethernet/altera/Kconfig
+++ b/drivers/net/ethernet/altera/Kconfig
@@ -3,7 +3,7 @@ config ALTERA_TSE
tristate "Altera Triple-Speed Ethernet MAC support"
depends on HAS_DMA
select PHYLIB
- ---help---
+ help
This driver supports the Altera Triple-Speed (TSE) Ethernet MAC.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/amazon/Kconfig b/drivers/net/ethernet/amazon/Kconfig
index cca72a75f551..c37fa393b99e 100644
--- a/drivers/net/ethernet/amazon/Kconfig
+++ b/drivers/net/ethernet/amazon/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_AMAZON
bool "Amazon Devices"
default y
- ---help---
+ help
If you have a network (Ethernet) device belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config ENA_ETHERNET
tristate "Elastic Network Adapter (ENA) support"
depends on PCI_MSI && !CPU_BIG_ENDIAN
select DIMLIB
- ---help---
+ help
This driver supports Elastic Network Adapter (ENA)"
To compile this driver as a module, choose M here.
diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c
index 50fb66369415..ef512cf89abf 100644
--- a/drivers/net/ethernet/amd/7990.c
+++ b/drivers/net/ethernet/amd/7990.c
@@ -28,6 +28,7 @@
#include <linux/route.h>
#include <linux/string.h>
#include <linux/skbuff.h>
+#include <linux/pgtable.h>
#include <asm/irq.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
@@ -35,7 +36,6 @@
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/pgtable.h>
#ifdef CONFIG_HP300
#include <asm/blinken.h>
#endif
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
index 9f965cdfff5c..db7d956a9c9b 100644
--- a/drivers/net/ethernet/amd/Kconfig
+++ b/drivers/net/ethernet/amd/Kconfig
@@ -9,7 +9,7 @@ config NET_VENDOR_AMD
depends on DIO || MACH_DECSTATION || MVME147 || ATARI || SUN3 || \
SUN3X || SBUS || PCI || ZORRO || (ISA && ISA_DMA_API) || \
(ARM && ARCH_EBSA110) || ISA || EISA || PCMCIA || ARM64
- ---help---
+ help
If you have a network (Ethernet) chipset belonging to this class,
say Y.
@@ -24,7 +24,7 @@ config A2065
tristate "A2065 support"
depends on ZORRO
select CRC32
- ---help---
+ help
If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
say N.
@@ -36,7 +36,7 @@ config AMD8111_ETH
depends on PCI
select CRC32
select MII
- ---help---
+ help
If you have an AMD 8111-based PCI LANCE ethernet card,
answer Y here.
@@ -46,7 +46,7 @@ config AMD8111_ETH
config LANCE
tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
depends on ISA && ISA_DMA_API && !ARM && !PPC32
- ---help---
+ help
If you have a network (Ethernet) card of this type, say Y here.
Some LinkSys cards are of this type.
@@ -58,7 +58,7 @@ config PCNET32
depends on PCI
select CRC32
select MII
- ---help---
+ help
If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
answer Y here.
@@ -68,7 +68,7 @@ config PCNET32
config ARIADNE
tristate "Ariadne support"
depends on ZORRO
- ---help---
+ help
If you have a Village Tronic Ariadne Ethernet adapter, say Y.
Otherwise, say N.
@@ -79,14 +79,14 @@ config ARM_AM79C961A
bool "ARM EBSA110 AM79C961A support"
depends on ARM && ARCH_EBSA110
select CRC32
- ---help---
+ help
If you wish to compile a kernel for the EBSA-110, then you should
always answer Y to this.
config ATARILANCE
tristate "Atari LANCE support"
depends on ATARI
- ---help---
+ help
Say Y to include support for several Atari Ethernet adapters based
on the AMD LANCE chipset: RieblCard (with or without battery), or
PAMCard VME (also the version by Rhotron, with different addresses).
@@ -95,7 +95,7 @@ config DECLANCE
tristate "DEC LANCE ethernet controller support"
depends on MACH_DECSTATION
select CRC32
- ---help---
+ help
This driver is for the series of Ethernet controllers produced by
DEC (now Compaq) based on the AMD LANCE chipset, including the
DEPCA series. (This chipset is better known via the NE2100 cards.)
@@ -104,7 +104,7 @@ config HPLANCE
tristate "HP on-board LANCE support"
depends on DIO
select CRC32
- ---help---
+ help
If you want to use the builtin "LANCE" Ethernet controller on an
HP300 machine, say Y here.
@@ -113,7 +113,7 @@ config MIPS_AU1X00_ENET
depends on MIPS_ALCHEMY
select PHYLIB
select CRC32
- ---help---
+ help
If you have an Alchemy Semi AU1X00 based system
say Y. Otherwise, say N.
@@ -121,7 +121,7 @@ config MVME147_NET
tristate "MVME147 (LANCE) Ethernet support"
depends on MVME147
select CRC32
- ---help---
+ help
Support for the on-board Ethernet interface on the Motorola MVME147
single-board computer. Say Y here to include the
driver for this chip in your kernel.
@@ -140,7 +140,7 @@ config PCMCIA_NMCLAN
config NI65
tristate "NI6510 support"
depends on ISA && ISA_DMA_API && !ARM && !PPC32
- ---help---
+ help
If you have a network (Ethernet) card of this type, say Y here.
To compile this driver as a module, choose M here. The module
@@ -149,7 +149,7 @@ config NI65
config SUN3LANCE
tristate "Sun3/Sun3x on-board LANCE support"
depends on (SUN3 || SUN3X)
- ---help---
+ help
Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
featured an AMD LANCE 10Mbit Ethernet controller on board; say Y
here to compile in the Linux driver for this and enable Ethernet.
@@ -163,7 +163,7 @@ config SUNLANCE
tristate "Sun LANCE support"
depends on SBUS
select CRC32
- ---help---
+ help
This driver supports the "le" interface present on all 32-bit Sparc
systems, on some older Ultra systems and as an Sbus option. These
cards are based on the AMD LANCE chipset, which is better known
@@ -181,7 +181,7 @@ config AMD_XGBE
select PHYLIB
select AMD_XGBE_HAVE_ECC if X86
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports the AMD 10GbE Ethernet device found on an
AMD SoC.
@@ -192,7 +192,7 @@ config AMD_XGBE_DCB
bool "Data Center Bridging (DCB) support"
default n
depends on AMD_XGBE && DCB
- ---help---
+ help
Say Y here to enable Data Center Bridging (DCB) support in the
driver.
diff --git a/drivers/net/ethernet/amd/hplance.c b/drivers/net/ethernet/amd/hplance.c
index 1381a474063f..e10aceb2b767 100644
--- a/drivers/net/ethernet/amd/hplance.c
+++ b/drivers/net/ethernet/amd/hplance.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/pgtable.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
#include <linux/route.h>
@@ -24,7 +25,6 @@
#include <linux/skbuff.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include "hplance.h"
diff --git a/drivers/net/ethernet/amd/mvme147.c b/drivers/net/ethernet/amd/mvme147.c
index 72abd3f82249..3f2e4cdd0b83 100644
--- a/drivers/net/ethernet/amd/mvme147.c
+++ b/drivers/net/ethernet/amd/mvme147.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/gfp.h>
+#include <linux/pgtable.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
#include <linux/route.h>
@@ -24,7 +25,6 @@
#include <linux/skbuff.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/mvme147hw.h>
/* We have 32K of RAM for the init block and buffers. This places
diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c
index da7e3d4f4166..e1fde585fd0d 100644
--- a/drivers/net/ethernet/amd/sun3lance.c
+++ b/drivers/net/ethernet/amd/sun3lance.c
@@ -37,12 +37,12 @@ static const char version[] =
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/bitops.h>
+#include <linux/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/dvma.h>
#include <asm/idprom.h>
#include <asm/machines.h>
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index a21b2e60157e..ddece276ae23 100644
--- a/drivers/net/ethernet/amd/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -94,10 +94,10 @@ static char lancestr[] = "LANCE";
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gfp.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/pgtable.h>
#include <asm/byteorder.h> /* Used by the checksum routines */
#include <asm/idprom.h>
#include <asm/prom.h>
diff --git a/drivers/net/ethernet/apple/Kconfig b/drivers/net/ethernet/apple/Kconfig
index f78b9c841296..a4176d2ecec6 100644
--- a/drivers/net/ethernet/apple/Kconfig
+++ b/drivers/net/ethernet/apple/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_APPLE
bool "Apple devices"
default y
depends on (PPC_PMAC && PPC32) || MAC
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config MACE
tristate "MACE (Power Mac ethernet) support"
depends on PPC_PMAC && PPC32
select CRC32
- ---help---
+ help
Power Macintoshes and clones with Ethernet built-in on the
motherboard will usually use a MACE (Medium Access Control for
Ethernet) interface. Say Y to include support for the MACE chip.
@@ -32,7 +32,7 @@ config MACE
config MACE_AAUI_PORT
bool "Use AAUI port instead of TP by default"
depends on MACE
- ---help---
+ help
Some Apple machines (notably the Apple Network Server) which use the
MACE ethernet chip have an Apple AUI port (small 15-pin connector),
instead of an 8-pin RJ45 connector for twisted-pair ethernet. Say
@@ -44,7 +44,7 @@ config BMAC
tristate "BMAC (G3 ethernet) support"
depends on PPC_PMAC && PPC32
select CRC32
- ---help---
+ help
Say Y for support of BMAC Ethernet interfaces. These are used on G3
computers.
@@ -55,7 +55,7 @@ config MACMACE
tristate "Macintosh (AV) onboard MACE ethernet"
depends on MAC
select CRC32
- ---help---
+ help
Support for the onboard AMD 79C940 MACE Ethernet controller used in
the 660AV and 840AV Macintosh. If you have one of these Macintoshes
say Y here.
diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
index 3e3711b60d01..1e4e402f07d7 100644
--- a/drivers/net/ethernet/apple/bmac.c
+++ b/drivers/net/ethernet/apple/bmac.c
@@ -24,11 +24,11 @@
#include <linux/bitrev.h>
#include <linux/ethtool.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/macio.h>
diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
index b8ba2abf5b3a..9e5006e59215 100644
--- a/drivers/net/ethernet/apple/mace.c
+++ b/drivers/net/ethernet/apple/mace.c
@@ -19,10 +19,10 @@
#include <linux/spinlock.h>
#include <linux/bitrev.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/macio.h>
#include "mace.h"
diff --git a/drivers/net/ethernet/aquantia/Kconfig b/drivers/net/ethernet/aquantia/Kconfig
index 76a44b2546ff..efb33c078a3c 100644
--- a/drivers/net/ethernet/aquantia/Kconfig
+++ b/drivers/net/ethernet/aquantia/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_AQUANTIA
bool "aQuantia devices"
default y
- ---help---
+ help
Set this to y if you have an Ethernet network cards that uses the aQuantia
AQC107/AQC108 chipset.
@@ -21,7 +21,7 @@ config AQTION
depends on PCI
depends on X86_64 || ARM64 || COMPILE_TEST
depends on MACSEC || MACSEC=n
- ---help---
+ help
This enables the support for the aQuantia AQtion(tm) Ethernet card.
endif # NET_VENDOR_AQUANTIA
diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
index 45c663d8b9aa..37a41773dd43 100644
--- a/drivers/net/ethernet/arc/Kconfig
+++ b/drivers/net/ethernet/arc/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_ARC
bool "ARC devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -27,7 +27,7 @@ config ARC_EMAC
select ARC_EMAC_CORE
depends on OF_IRQ && OF_NET
depends on ARC || COMPILE_TEST
- ---help---
+ help
On some legacy ARC (Synopsys) FPGA boards such as ARCAngel4/ML50x
non-standard on-chip ethernet device ARC EMAC 10/100 is used.
Say Y here if you have such a board. If unsure, say N.
@@ -37,7 +37,7 @@ config EMAC_ROCKCHIP
select ARC_EMAC_CORE
depends on OF_IRQ && OF_NET && REGULATOR
depends on ARCH_ROCKCHIP || COMPILE_TEST
- ---help---
+ help
Support for Rockchip RK3036/RK3066/RK3188 EMAC ethernet controllers.
This selects Rockchip SoC glue layer support for the
emac device driver. This driver is used for RK3036/RK3066/RK3188
diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig
index 2720bde5034e..fb803bf92ded 100644
--- a/drivers/net/ethernet/atheros/Kconfig
+++ b/drivers/net/ethernet/atheros/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_ATHEROS
bool "Atheros devices"
default y
depends on (PCI || ATH79)
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -30,7 +30,7 @@ config ATL2
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver supports the Atheros L2 fast ethernet adapter.
To compile this driver as a module, choose M here. The module
@@ -41,7 +41,7 @@ config ATL1
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver supports the Atheros/Attansic L1 gigabit ethernet
adapter.
@@ -53,7 +53,7 @@ config ATL1E
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver supports the Atheros L1E gigabit ethernet adapter.
To compile this driver as a module, choose M here. The module
@@ -64,7 +64,7 @@ config ATL1C
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver supports the Atheros L1C gigabit ethernet adapter.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index 2a69c0d06f3c..7fb42f388d59 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -8,7 +8,7 @@ config NET_VENDOR_BROADCOM
default y
depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \
SIBYTE_SB1xxx_SOC
- ---help---
+ help
If you have a network (Ethernet) chipset belonging to this class,
say Y.
@@ -25,7 +25,7 @@ config B44
select SSB
select MII
select PHYLIB
- ---help---
+ help
If you have a network (Ethernet) controller of this type, say Y
or M here.
@@ -79,7 +79,7 @@ config BNX2
depends on PCI
select CRC32
select FW_LOADER
- ---help---
+ help
This driver supports QLogic bnx2 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
@@ -90,7 +90,7 @@ config CNIC
depends on PCI && (IPV6 || IPV6=n)
select BNX2
select UIO
- ---help---
+ help
This driver supports offload features of QLogic bnx2 gigabit
Ethernet cards.
@@ -101,7 +101,7 @@ config SB1250_MAC
tristate "SB1250 Gigabit Ethernet support"
depends on SIBYTE_SB1xxx_SOC
select PHYLIB
- ---help---
+ help
This driver supports Gigabit Ethernet interfaces based on the
Broadcom SiByte family of System-On-a-Chip parts. They include
the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
@@ -115,7 +115,7 @@ config TIGON3
depends on PCI
select PHYLIB
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
@@ -125,7 +125,7 @@ config TIGON3_HWMON
bool "Broadcom Tigon3 HWMON support"
default y
depends on TIGON3 && HWMON && !(TIGON3=y && HWMON=m)
- ---help---
+ help
Say Y if you want to expose the thermal sensor on Tigon3 devices.
config BNX2X
@@ -136,7 +136,7 @@ config BNX2X
select ZLIB_INFLATE
select LIBCRC32C
select MDIO
- ---help---
+ help
This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called bnx2x. This is recommended.
@@ -145,7 +145,7 @@ config BNX2X_SRIOV
bool "Broadcom 578xx and 57712 SR-IOV support"
depends on BNX2X && PCI_IOV
default y
- ---help---
+ help
This configuration parameter enables Single Root Input Output
Virtualization support in the 578xx and 57712 products. This
allows for virtual function acceleration in virtual environments.
@@ -164,7 +164,7 @@ config BGMAC_BCMA
select BGMAC
select PHYLIB
select FIXED_PHY
- ---help---
+ help
This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
They can be found on BCM47xx SoCs and provide gigabit ethernet.
In case of using this driver on BCM4706 it's also requires to enable
@@ -178,7 +178,7 @@ config BGMAC_PLATFORM
select PHYLIB
select FIXED_PHY
default ARCH_BCM_IPROC
- ---help---
+ help
Say Y here if you want to use the Broadcom iProc Gigabit Ethernet
controller through the generic platform interface
@@ -203,7 +203,7 @@ config BNXT
select NET_DEVLINK
select PAGE_POOL
select DIMLIB
- ---help---
+ help
This driver supports Broadcom NetXtreme-C/E 10/25/40/50 gigabit
Ethernet cards. To compile this driver as a module, choose M here:
the module will be called bnxt_en. This is recommended.
@@ -212,7 +212,7 @@ config BNXT_SRIOV
bool "Broadcom NetXtreme-C/E SR-IOV support"
depends on BNXT && PCI_IOV
default y
- ---help---
+ help
This configuration parameter enables Single Root Input Output
Virtualization support in the NetXtreme-C/E products. This
allows for virtual function acceleration in virtual environments.
@@ -221,7 +221,7 @@ config BNXT_FLOWER_OFFLOAD
bool "TC Flower offload support for NetXtreme-C/E"
depends on BNXT
default y
- ---help---
+ help
This configuration parameter enables TC Flower packet classifier
offload for eswitch. This option enables SR-IOV switchdev eswitch
offload.
@@ -230,7 +230,7 @@ config BNXT_DCB
bool "Data Center Bridging (DCB) Support"
default n
depends on BNXT && DCB
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
@@ -240,7 +240,7 @@ config BNXT_HWMON
bool "Broadcom NetXtreme-C/E HWMON support"
default y
depends on BNXT && HWMON && !(BNXT=y && HWMON=m)
- ---help---
+ help
Say Y if you want to expose the thermal sensor data on NetXtreme-C/E
devices, via the hwmon sysfs interface.
diff --git a/drivers/net/ethernet/brocade/Kconfig b/drivers/net/ethernet/brocade/Kconfig
index d4564c7a279c..fb4c3cdf7233 100644
--- a/drivers/net/ethernet/brocade/Kconfig
+++ b/drivers/net/ethernet/brocade/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_BROCADE
bool "QLogic BR-series devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/ethernet/brocade/bna/Kconfig b/drivers/net/ethernet/brocade/bna/Kconfig
index b124a628f86a..0a48ad93ed6c 100644
--- a/drivers/net/ethernet/brocade/bna/Kconfig
+++ b/drivers/net/ethernet/brocade/bna/Kconfig
@@ -6,7 +6,7 @@
config BNA
tristate "QLogic BR-series 1010/1020/1860 10Gb Ethernet Driver support"
depends on PCI
- ---help---
+ help
This driver supports QLogic BR-series 1010/1020/1860 10Gb CEE capable
Ethernet cards.
To compile this driver as a module, choose M here: the module
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
index 2c4c12b03502..85858163bac5 100644
--- a/drivers/net/ethernet/cadence/Kconfig
+++ b/drivers/net/ethernet/cadence/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_CADENCE
bool "Cadence devices"
depends on HAS_IOMEM
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
If unsure, say Y.
@@ -23,7 +23,7 @@ config MACB
tristate "Cadence MACB/GEM support"
depends on HAS_DMA && COMMON_CLK
select PHYLINK
- ---help---
+ help
The Cadence MACB ethernet interface is found on many Atmel AT32 and
AT91 parts. This driver also supports the Cadence GEM (Gigabit
Ethernet MAC found in some ARM SoC devices). Say Y to include
@@ -37,13 +37,13 @@ config MACB_USE_HWSTAMP
depends on MACB
depends on PTP_1588_CLOCK
default y
- ---help---
+ help
Enable IEEE 1588 Precision Time Protocol (PTP) support for MACB.
config MACB_PCI
tristate "Cadence PCI MACB/GEM support"
depends on MACB && PCI
- ---help---
+ help
This is PCI wrapper for MACB driver.
To compile this driver as a module, choose M here: the module
diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig
index 4520e7ee00fe..4875cdae622e 100644
--- a/drivers/net/ethernet/cavium/Kconfig
+++ b/drivers/net/ethernet/cavium/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_CAVIUM
bool "Cavium ethernet drivers"
default y
- ---help---
+ help
Select this option if you want enable Cavium network support.
If you have a Cavium SoC or network adapter, say Y.
@@ -17,7 +17,7 @@ config THUNDER_NIC_PF
tristate "Thunder Physical function driver"
depends on 64BIT && PCI
select THUNDER_NIC_BGX
- ---help---
+ help
This driver supports Thunder's NIC physical function.
The NIC provides the controller and DMA engines to
move network traffic to/from the memory. The NIC
@@ -29,7 +29,7 @@ config THUNDER_NIC_VF
tristate "Thunder Virtual function driver"
imply CAVIUM_PTP
depends on 64BIT && PCI
- ---help---
+ help
This driver supports Thunder's NIC virtual function
config THUNDER_NIC_BGX
@@ -38,7 +38,7 @@ config THUNDER_NIC_BGX
select PHYLIB
select MDIO_THUNDER if PCI
select THUNDER_NIC_RGX
- ---help---
+ help
This driver supports programming and controlling of MAC
interface from NIC physical function driver.
@@ -47,7 +47,7 @@ config THUNDER_NIC_RGX
depends on 64BIT && PCI
select PHYLIB
select MDIO_THUNDER if PCI
- ---help---
+ help
This driver supports configuring XCV block of RGX interface
present on CN81XX chip.
@@ -55,7 +55,7 @@ config CAVIUM_PTP
tristate "Cavium PTP coprocessor as PTP clock"
depends on 64BIT && PCI
depends on PTP_1588_CLOCK
- ---help---
+ help
This driver adds support for the Precision Time Protocol Clocks and
Timestamping coprocessor (PTP) found on Cavium processors.
PTP provides timestamping mechanism that is suitable for use in IEEE 1588
@@ -70,7 +70,7 @@ config LIQUIDIO
select FW_LOADER
select LIBCRC32C
select NET_DEVLINK
- ---help---
+ help
This driver supports Cavium LiquidIO Intelligent Server Adapters
based on CN66XX, CN68XX and CN23XX chips.
@@ -92,7 +92,7 @@ config LIQUIDIO_VF
tristate "Cavium LiquidIO VF support"
depends on 64BIT && PCI_MSI
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports Cavium LiquidIO Intelligent Server Adapter
based on CN23XX chips.
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig
index 82cdfa51ce37..b7f43254598f 100644
--- a/drivers/net/ethernet/chelsio/Kconfig
+++ b/drivers/net/ethernet/chelsio/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_CHELSIO
bool "Chelsio devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config CHELSIO_T1
depends on PCI
select CRC32
select MDIO
- ---help---
+ help
This driver supports Chelsio gigabit and 10-gigabit
Ethernet cards. More information about adapter features and
performance tuning is in
@@ -42,7 +42,7 @@ config CHELSIO_T1
config CHELSIO_T1_1G
bool "Chelsio gigabit Ethernet support"
depends on CHELSIO_T1
- ---help---
+ help
Enables support for Chelsio's gigabit Ethernet PCI cards. If you
are using only 10G cards say 'N' here.
@@ -51,7 +51,7 @@ config CHELSIO_T3
depends on PCI && INET
select FW_LOADER
select MDIO
- ---help---
+ help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
@@ -72,7 +72,7 @@ config CHELSIO_T4
select FW_LOADER
select MDIO
select ZLIB_DEFLATE
- ---help---
+ help
This driver supports Chelsio T4, T5 & T6 based gigabit, 10Gb Ethernet
adapter and T5/T6 based 40Gb and T6 based 25Gb, 50Gb and 100Gb
Ethernet adapters.
@@ -92,7 +92,7 @@ config CHELSIO_T4_DCB
bool "Data Center Bridging (DCB) Support for Chelsio T4/T5/T6 cards"
default n
depends on CHELSIO_T4 && DCB
- ---help---
+ help
Enable DCB support through rtNetlink interface.
Say Y here if you want to enable Data Center Bridging (DCB) support
in the driver.
@@ -103,7 +103,7 @@ config CHELSIO_T4_FCOE
bool "Fibre Channel over Ethernet (FCoE) Support for Chelsio T5 cards"
default n
depends on CHELSIO_T4 && CHELSIO_T4_DCB && FCOE
- ---help---
+ help
Enable FCoE offload features.
Say Y here if you want to enable Fibre Channel over Ethernet (FCoE) support
in the driver.
@@ -113,7 +113,7 @@ config CHELSIO_T4_FCOE
config CHELSIO_T4VF
tristate "Chelsio Communications T4/T5/T6 Virtual Function Ethernet support"
depends on PCI
- ---help---
+ help
This driver supports Chelsio T4, T5 & T6 based gigabit, 10Gb Ethernet
adapters and T5/T6 based 40Gb and T6 based 25Gb, 50Gb and 100Gb
Ethernet adapters with PCI-E SR-IOV Virtual Functions.
@@ -131,7 +131,7 @@ config CHELSIO_T4VF
config CHELSIO_LIB
tristate
- ---help---
+ help
Common library for Chelsio drivers.
endif # NET_VENDOR_CHELSIO
diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig
index 8d845f5ee0c5..7cf4526596f3 100644
--- a/drivers/net/ethernet/cirrus/Kconfig
+++ b/drivers/net/ethernet/cirrus/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_CIRRUS
bool "Cirrus devices"
default y
depends on ISA || EISA || ARM || MAC
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config CS89x0
tristate "CS89x0 support"
depends on ISA || EISA || ARM
depends on !PPC32
- ---help---
+ help
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the file
<file:Documentation/networking/device_drivers/cirrus/cs89x0.rst>.
@@ -51,7 +51,7 @@ config EP93XX_ETH
config MAC89x0
tristate "Macintosh CS89x0 based ethernet cards"
depends on MAC
- ---help---
+ help
Support for CS89x0 chipset based Ethernet cards. If you have a
Nubus or LC-PDS network (Ethernet) card of this type, say Y here.
diff --git a/drivers/net/ethernet/cisco/Kconfig b/drivers/net/ethernet/cisco/Kconfig
index ee5b7b3868c7..18c3a0718d6f 100644
--- a/drivers/net/ethernet/cisco/Kconfig
+++ b/drivers/net/ethernet/cisco/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_CISCO
bool "Cisco devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/ethernet/cisco/enic/Kconfig b/drivers/net/ethernet/cisco/enic/Kconfig
index edaae706a102..ad80c0fa96a6 100644
--- a/drivers/net/ethernet/cisco/enic/Kconfig
+++ b/drivers/net/ethernet/cisco/enic/Kconfig
@@ -6,5 +6,5 @@
config ENIC
tristate "Cisco VIC Ethernet NIC Support"
depends on PCI
- ---help---
+ help
This enables the support for the Cisco VIC Ethernet card.
diff --git a/drivers/net/ethernet/cortina/Kconfig b/drivers/net/ethernet/cortina/Kconfig
index 89bc4579724d..ac8cb5744a87 100644
--- a/drivers/net/ethernet/cortina/Kconfig
+++ b/drivers/net/ethernet/cortina/Kconfig
@@ -4,7 +4,7 @@
config NET_VENDOR_CORTINA
bool "Cortina Gemini devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
@@ -17,7 +17,7 @@ config GEMINI_ETHERNET
depends on HAS_IOMEM
select PHYLIB
select CRC32
- ---help---
+ help
This driver supports StorLink SL351x (Gemini) dual Gigabit Ethernet.
endif # NET_VENDOR_CORTINA
diff --git a/drivers/net/ethernet/davicom/Kconfig b/drivers/net/ethernet/davicom/Kconfig
index a321a7144fb0..76247103e566 100644
--- a/drivers/net/ethernet/davicom/Kconfig
+++ b/drivers/net/ethernet/davicom/Kconfig
@@ -8,7 +8,7 @@ config DM9000
depends on ARM || MIPS || COLDFIRE || NIOS2
select CRC32
select MII
- ---help---
+ help
Support for DM9000 chipset.
To compile this driver as a module, choose M here. The module
@@ -17,7 +17,7 @@ config DM9000
config DM9000_FORCE_SIMPLE_PHY_POLL
bool "Force simple NSR based PHY polling"
depends on DM9000
- ---help---
+ help
This configuration forces the DM9000 to use the NSR's LinkStatus
bit to determine if the link is up or down instead of the more
costly MII PHY reads. Note, this will not work if the chip is
diff --git a/drivers/net/ethernet/dec/Kconfig b/drivers/net/ethernet/dec/Kconfig
index df1eeb04d5ea..9e5e5f10bd19 100644
--- a/drivers/net/ethernet/dec/Kconfig
+++ b/drivers/net/ethernet/dec/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_DEC
bool "Digital Equipment devices"
default y
depends on PCI || EISA || CARDBUS
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/ethernet/dec/tulip/Kconfig b/drivers/net/ethernet/dec/tulip/Kconfig
index 177f36f4b89d..8afc5942179a 100644
--- a/drivers/net/ethernet/dec/tulip/Kconfig
+++ b/drivers/net/ethernet/dec/tulip/Kconfig
@@ -6,7 +6,7 @@
config NET_TULIP
bool "DEC - Tulip devices"
depends on (PCI || EISA || CARDBUS)
- ---help---
+ help
This selects the "Tulip" family of EISA/PCI network cards.
if NET_TULIP
@@ -15,7 +15,7 @@ config DE2104X
tristate "Early DECchip Tulip (dc2104x) PCI support"
depends on PCI
select CRC32
- ---help---
+ help
This driver is developed for the SMC EtherPower series Ethernet
cards and also works with cards based on the DECchip
21040 (Tulip series) chips. Some LinkSys PCI cards are
@@ -32,7 +32,7 @@ config DE2104X_DSL
depends on DE2104X
range 0 31
default 0
- ---help---
+ help
Setting this value allows to align ring buffer descriptors into their
own cache lines. Value of 4 corresponds to the typical 32 byte line
(the descriptor is 16 bytes). This is necessary on systems that lack
@@ -43,7 +43,7 @@ config TULIP
tristate "DECchip Tulip (dc2114x) PCI support"
depends on PCI
select CRC32
- ---help---
+ help
This driver is developed for the SMC EtherPower series Ethernet
cards and also works with cards based on the DECchip
21140 (Tulip series) chips. Some LinkSys PCI cards are
@@ -58,7 +58,7 @@ config TULIP
config TULIP_MWI
bool "New bus configuration"
depends on TULIP
- ---help---
+ help
This configures your Tulip card specifically for the card and
system cache line size type you are using.
@@ -69,7 +69,7 @@ config TULIP_MWI
config TULIP_MMIO
bool "Use PCI shared mem for NIC registers"
depends on TULIP
- ---help---
+ help
Use PCI shared memory for the NIC registers, rather than going through
the Tulip's PIO (programmed I/O ports). Faster, but could produce
obscure bugs if your mainboard has memory controller timing issues.
@@ -78,7 +78,7 @@ config TULIP_MMIO
config TULIP_NAPI
bool "Use RX polling (NAPI)"
depends on TULIP
- ---help---
+ help
NAPI is a new driver API designed to reduce CPU and interrupt load
when the driver is receiving lots of packets from the card. It is
still somewhat experimental and thus not yet enabled by default.
@@ -92,7 +92,7 @@ config TULIP_NAPI
config TULIP_NAPI_HW_MITIGATION
bool "Use Interrupt Mitigation"
depends on TULIP_NAPI
- ---help---
+ help
Use HW to reduce RX interrupts. Not strictly necessary since NAPI
reduces RX interrupts by itself. Interrupt mitigation reduces RX
interrupts even at low levels of traffic at the cost of a small
@@ -109,7 +109,7 @@ config DE4X5
depends on (PCI || EISA)
depends on VIRT_TO_BUS || ALPHA || PPC || SPARC
select CRC32
- ---help---
+ help
This is support for the DIGITAL series of PCI/EISA Ethernet cards.
These include the DE425, DE434, DE435, DE450 and DE500 models. If
you have a network card of this type, say Y. More specific
@@ -124,7 +124,7 @@ config WINBOND_840
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver is for the Winbond W89c840 chip. It also works with
the TX9882 chip on the Compex RL100-ATX board.
More specific information and updates are available from
@@ -134,7 +134,7 @@ config DM9102
tristate "Davicom DM910x/DM980x support"
depends on PCI
select CRC32
- ---help---
+ help
This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
Davicom (<http://www.davicom.com.tw/>). If you have such a network
(Ethernet) card, say Y. Some information is contained in the file
@@ -147,7 +147,7 @@ config ULI526X
tristate "ULi M526x controller support"
depends on PCI
select CRC32
- ---help---
+ help
This driver is for ULi M5261/M5263 10/100M Ethernet Controller
(<http://www.nvidia.com/page/uli_drivers.html>).
@@ -157,7 +157,7 @@ config ULI526X
config PCMCIA_XIRCOM
tristate "Xircom CardBus support"
depends on CARDBUS
- ---help---
+ help
This driver is for the Digital "Tulip" Ethernet CardBus adapters.
It should work with most DEC 21*4*-based chips/ethercards, as well
as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and
diff --git a/drivers/net/ethernet/dlink/Kconfig b/drivers/net/ethernet/dlink/Kconfig
index 1362658a3030..0d77f84c8e7b 100644
--- a/drivers/net/ethernet/dlink/Kconfig
+++ b/drivers/net/ethernet/dlink/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_DLINK
bool "D-Link devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config DL2K
tristate "DL2000/TC902x/IP1000A-based Gigabit Ethernet support"
depends on PCI
select CRC32
- ---help---
+ help
This driver supports DL2000/TC902x/IP1000A-based Gigabit ethernet cards,
which includes
D-Link DGE-550T Gigabit Ethernet Adapter.
@@ -37,7 +37,7 @@ config SUNDANCE
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver is for the Sundance "Alta" chip.
More specific information and updates are available from
<http://www.scyld.com/network/sundance.html>.
@@ -45,7 +45,7 @@ config SUNDANCE
config SUNDANCE_MMIO
bool "Use MMIO instead of PIO"
depends on SUNDANCE
- ---help---
+ help
Enable memory-mapped I/O for interaction with Sundance NIC registers.
Do NOT enable this by default, PIO (enabled when MMIO is disabled)
is known to solve bugs on certain chips.
diff --git a/drivers/net/ethernet/emulex/Kconfig b/drivers/net/ethernet/emulex/Kconfig
index 22c143f2d787..5797a76dc731 100644
--- a/drivers/net/ethernet/emulex/Kconfig
+++ b/drivers/net/ethernet/emulex/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_EMULEX
bool "Emulex devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/ethernet/ezchip/Kconfig b/drivers/net/ethernet/ezchip/Kconfig
index 6db75fd2f9af..38aa824efb25 100644
--- a/drivers/net/ethernet/ezchip/Kconfig
+++ b/drivers/net/ethernet/ezchip/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_EZCHIP
bool "EZchip devices"
default y
- ---help---
+ help
If you have a network (Ethernet) device belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config EZCHIP_NPS_MANAGEMENT_ENET
tristate "EZchip NPS management enet support"
depends on OF_IRQ && OF_NET
depends on HAS_IOMEM
- ---help---
+ help
Simple LAN device for debug or management purposes.
Device supports interrupts for RX and TX(completion).
Device does not have DMA ability.
diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig
index 73e4f2648e49..c2677ec0564d 100644
--- a/drivers/net/ethernet/faraday/Kconfig
+++ b/drivers/net/ethernet/faraday/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_FARADAY
bool "Faraday devices"
default y
depends on ARM || NDS32 || COMPILE_TEST
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config FTMAC100
depends on ARM || NDS32 || COMPILE_TEST
depends on !64BIT || BROKEN
select MII
- ---help---
+ help
This driver supports the FTMAC100 10/100 Ethernet controller
from Faraday. It is used on Faraday A320, Andes AG101 and some
other ARM/NDS32 SoC's.
@@ -33,7 +33,7 @@ config FTGMAC100
depends on !64BIT || BROKEN
select PHYLIB
select MDIO_ASPEED if MACH_ASPEED_G6
- ---help---
+ help
This driver supports the FTGMAC100 Gigabit Ethernet controller
from Faraday. It is used on Faraday A369, Andes AG102 and some
other ARM/NDS32 SoC's.
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index bfc6bfe94d0a..a1d53ddf1593 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -10,7 +10,7 @@ config NET_VENDOR_FREESCALE
M523x || M527x || M5272 || M528x || M520x || M532x || \
ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
ARCH_LAYERSCAPE || COMPILE_TEST
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -27,7 +27,7 @@ config FEC
default ARCH_MXC || SOC_IMX28 if ARM
select PHYLIB
imply PTP_1588_CLOCK
- ---help---
+ help
Say Y here if you want to use the built-in 10/100 Fast ethernet
controller on some Motorola ColdFire and Freescale i.MX processors.
@@ -37,7 +37,7 @@ config FEC_MPC52xx
select CRC32
select PHYLIB
select PPC_BESTCOMM_FEC
- ---help---
+ help
This option enables support for the MPC5200's on-chip
Fast Ethernet Controller
If compiled as module, it will be called fec_mpc52xx.
@@ -46,7 +46,7 @@ config FEC_MPC52xx_MDIO
bool "FEC MPC52xx MDIO bus driver"
depends on FEC_MPC52xx
default y
- ---help---
+ help
The MPC5200's FEC can connect to the Ethernet either with
an external MII PHY chip or 10 Mbps 7-wire interface
(Motorola? industry standard).
@@ -60,7 +60,7 @@ source "drivers/net/ethernet/freescale/fman/Kconfig"
config FSL_PQ_MDIO
tristate "Freescale PQ MDIO"
select PHYLIB
- ---help---
+ help
This driver supports the MDIO bus used by the gianfar and UCC drivers.
config FSL_XGMAC_MDIO
@@ -68,7 +68,7 @@ config FSL_XGMAC_MDIO
select PHYLIB
depends on OF
select OF_MDIO
- ---help---
+ help
This driver supports the MDIO bus on the Fman 10G Ethernet MACs, and
on the FMan mEMAC (which supports both Clauses 22 and 45)
@@ -78,7 +78,7 @@ config UCC_GETH
select FSL_PQ_MDIO
select PHYLIB
select FIXED_PHY
- ---help---
+ help
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
which is available on some Freescale SOCs.
@@ -93,7 +93,7 @@ config GIANFAR
select PHYLIB
select FIXED_PHY
select CRC32
- ---help---
+ help
This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
and MPC86xx family of chips, the eTSEC on LS1021A and the FEC
on the 8540.
diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig b/drivers/net/ethernet/freescale/dpaa/Kconfig
index 0a54c7e0e4ae..626ec58a0afc 100644
--- a/drivers/net/ethernet/freescale/dpaa/Kconfig
+++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
@@ -5,7 +5,7 @@ menuconfig FSL_DPAA_ETH
select PHYLIB
select FIXED_PHY
select FSL_FMAN_MAC
- ---help---
+ help
Data Path Acceleration Architecture Ethernet driver,
supporting the Freescale QorIQ chips.
Depends on Freescale Buffer Manager and Queue Manager
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index ce85feaac357..b0d4b1984a70 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -40,9 +40,9 @@
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_net.h>
+#include <linux/pgtable.h>
#include <linux/vmalloc.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include <linux/uaccess.h>
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
index 6e64989f8478..b47490be872c 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
@@ -35,12 +35,12 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/gfp.h>
+#include <linux/pgtable.h>
#include <asm/immap_cpm2.h>
#include <asm/mpc8260.h>
#include <asm/cpm2.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include <linux/uaccess.h>
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
index 1582d82483ec..8b51ee142fa3 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
@@ -32,8 +32,8 @@
#include <linux/platform_device.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
+#include <linux/pgtable.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include <linux/uaccess.h>
#include <asm/mpc5xxx.h>
diff --git a/drivers/net/ethernet/fujitsu/Kconfig b/drivers/net/ethernet/fujitsu/Kconfig
index cee99f20d2c2..0a1400cb410a 100644
--- a/drivers/net/ethernet/fujitsu/Kconfig
+++ b/drivers/net/ethernet/fujitsu/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_FUJITSU
bool "Fujitsu devices"
default y
depends on PCMCIA
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config PCMCIA_FMVJ18X
tristate "Fujitsu FMV-J18x PCMCIA support"
depends on PCMCIA
select CRC32
- ---help---
+ help
Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible
PCMCIA (PC-card) Ethernet card to your computer.
diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig
index 2fff43509098..44f9279cdde1 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -8,7 +8,7 @@ config NET_VENDOR_HISILICON
default y
depends on OF || ACPI
depends on ARM || ARM64 || COMPILE_TEST
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -42,7 +42,7 @@ config HIP04_ETH
select MARVELL_PHY
select MFD_SYSCON
select HNS_MDIO
- ---help---
+ help
If you wish to compile a kernel for a hardware with hisilicon p04 SoC and
want to use the internal ethernet then you should answer Y to this.
@@ -59,13 +59,13 @@ config HI13X1_GMAC
config HNS_MDIO
tristate
select PHYLIB
- ---help---
+ help
This selects the HNS MDIO support. It is needed by HNS_DSAF to access
the PHY
config HNS
tristate
- ---help---
+ help
This selects the framework support for Hisilicon Network Subsystem. It
is needed by any driver which provides HNS acceleration engine or make
use of the engine
@@ -74,7 +74,7 @@ config HNS_DSAF
tristate "Hisilicon HNS DSAF device Support"
select HNS
select HNS_MDIO
- ---help---
+ help
This selects the DSAF (Distributed System Area Frabric) network
acceleration engine support. The engine is used in Hisilicon hip05,
Hi1610 and further ICT SoC
@@ -83,14 +83,14 @@ config HNS_ENET
tristate "Hisilicon HNS Ethernet Device Support"
select PHYLIB
select HNS
- ---help---
+ help
This selects the general ethernet driver for HNS. This module make
use of any HNS AE driver, such as HNS_DSAF
config HNS3
tristate "Hisilicon Network Subsystem Support HNS3 (Framework)"
depends on PCI
- ---help---
+ help
This selects the framework support for Hisilicon Network Subsystem 3.
This layer facilitates clients like ENET, RoCE and user-space ethernet
drivers(like ODP)to register with HNAE devices and their associated
@@ -102,7 +102,7 @@ config HNS3_HCLGE
tristate "Hisilicon HNS3 HCLGE Acceleration Engine & Compatibility Layer Support"
default m
depends on PCI_MSI
- ---help---
+ help
This selects the HNS3_HCLGE network acceleration engine & its hardware
compatibility layer. The engine would be used in Hisilicon hip08 family of
SoCs and further upcoming SoCs.
@@ -111,7 +111,7 @@ config HNS3_DCB
bool "Hisilicon HNS3 Data Center Bridge Support"
default n
depends on HNS3_HCLGE && DCB
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the HNS3 driver.
If unsure, say N.
@@ -120,7 +120,7 @@ config HNS3_HCLGEVF
tristate "Hisilicon HNS3VF Acceleration Engine & Compatibility Layer Support"
depends on PCI_MSI
depends on HNS3_HCLGE
- ---help---
+ help
This selects the HNS3 VF drivers network acceleration engine & its hardware
compatibility layer. The engine would be used in Hisilicon hip08 family of
SoCs and further upcoming SoCs.
@@ -130,7 +130,7 @@ config HNS3_ENET
default m
depends on 64BIT && PCI
depends on INET
- ---help---
+ help
This selects the Ethernet Driver for Hisilicon Network Subsystem 3 for hip08
family of SoCs. This module depends upon HNAE3 driver to access the HNAE3
devices and their associated operations.
diff --git a/drivers/net/ethernet/huawei/Kconfig b/drivers/net/ethernet/huawei/Kconfig
index bdcbface62d7..c05fce15eb51 100644
--- a/drivers/net/ethernet/huawei/Kconfig
+++ b/drivers/net/ethernet/huawei/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_HUAWEI
bool "Huawei devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
diff --git a/drivers/net/ethernet/huawei/hinic/Kconfig b/drivers/net/ethernet/huawei/hinic/Kconfig
index cabc2f72d9d7..936e2dd3bb13 100644
--- a/drivers/net/ethernet/huawei/hinic/Kconfig
+++ b/drivers/net/ethernet/huawei/hinic/Kconfig
@@ -6,7 +6,7 @@
config HINIC
tristate "Huawei Intelligent PCIE Network Interface Card"
depends on (PCI_MSI && (X86 || ARM64))
- ---help---
+ help
This driver supports HiNIC PCIE Ethernet cards.
To compile this driver as part of the kernel, choose Y here.
If unsure, choose N.
diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c
index bef676d93339..fc8c7cd67471 100644
--- a/drivers/net/ethernet/i825xx/82596.c
+++ b/drivers/net/ethernet/i825xx/82596.c
@@ -53,10 +53,10 @@
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/gfp.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/pgtable.h>
#include <asm/cacheflush.h>
static char version[] __initdata =
diff --git a/drivers/net/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig
index 33faff985438..3b5fab123824 100644
--- a/drivers/net/ethernet/i825xx/Kconfig
+++ b/drivers/net/ethernet/i825xx/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_I825XX
bool "Intel (82586/82593/82596) devices"
default y
depends on NET_VENDOR_INTEL
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question does not directly affect the
@@ -20,14 +20,14 @@ if NET_VENDOR_I825XX
config ARM_ETHER1
tristate "Acorn Ether1 support"
depends on ARM && ARCH_ACORN
- ---help---
+ help
If you have an Acorn system with one of these (AKA25) network cards,
you should say Y to this option if you wish to use it with Linux.
config BVME6000_NET
tristate "BVME6000 Ethernet support"
depends on BVME6000
- ---help---
+ help
This is the driver for the Ethernet interface on BVME4000 and
BVME6000 VME boards. Say Y here to include the driver for this chip
in your kernel.
@@ -36,14 +36,14 @@ config BVME6000_NET
config LASI_82596
tristate "Lasi ethernet"
depends on GSC
- ---help---
+ help
Say Y here to support the builtin Intel 82596 ethernet controller
found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
config MVME16x_NET
tristate "MVME16x Ethernet support"
depends on MVME16x
- ---help---
+ help
This is the driver for the Ethernet interface on the Motorola
MVME162, 166, 167, 172 and 177 boards. Say Y here to include the
driver for this chip in your kernel.
@@ -52,14 +52,14 @@ config MVME16x_NET
config SNI_82596
tristate "SNI RM ethernet"
depends on SNI_RM
- ---help---
+ help
Say Y here to support the on-board Intel 82596 ethernet controller
built into SNI RM machines.
config SUN3_82586
bool "Sun3 on-board Intel 82586 support"
depends on SUN3
- ---help---
+ help
This driver enables support for the on-board Intel 82586 based
Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards. Note
that this driver does not support 82586-based adapters on additional
diff --git a/drivers/net/ethernet/ibm/Kconfig b/drivers/net/ethernet/ibm/Kconfig
index a95d941360f8..c0c112d95b89 100644
--- a/drivers/net/ethernet/ibm/Kconfig
+++ b/drivers/net/ethernet/ibm/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_IBM
bool "IBM devices"
default y
depends on PPC_PSERIES || PPC_DCR || (IBMEBUS && SPARSEMEM)
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_IBM
config IBMVETH
tristate "IBM LAN Virtual Ethernet support"
depends on PPC_PSERIES
- ---help---
+ help
This driver supports virtual ethernet adapters on newer IBM iSeries
and pSeries systems.
@@ -32,7 +32,7 @@ source "drivers/net/ethernet/ibm/emac/Kconfig"
config EHEA
tristate "eHEA Ethernet support"
depends on IBMEBUS && SPARSEMEM
- ---help---
+ help
This driver supports the IBM pSeries eHEA ethernet adapter.
To compile the driver as a module, choose M here. The module
@@ -41,7 +41,7 @@ config EHEA
config IBMVNIC
tristate "IBM Virtual NIC support"
depends on PPC_PSERIES
- ---help---
+ help
This driver supports Virtual NIC adapters on IBM i and IBM System p
systems.
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index ad34e4335df2..48a8f9aa1dd0 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_INTEL
bool "Intel devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config E100
tristate "Intel(R) PRO/100+ support"
depends on PCI
select MII
- ---help---
+ help
This driver supports Intel(R) PRO/100 family of adapters.
To verify that your adapter is supported, find the board ID number
on the adapter. Look for a label that has a barcode and a number
@@ -42,7 +42,7 @@ config E100
config E1000
tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
depends on PCI
- ---help---
+ help
This driver supports Intel(R) PRO/1000 gigabit ethernet family of
adapters. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide that can be located at:
@@ -60,7 +60,7 @@ config E1000E
depends on PCI && (!SPARC32 || BROKEN)
select CRC32
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
ethernet family of adapters. For PCI or PCI-X e1000 adapters,
use the regular e1000 driver For more information on how to
@@ -79,7 +79,7 @@ config E1000E_HWTS
bool "Support HW cross-timestamp on PCH devices"
default y
depends on E1000E && X86
- ---help---
+ help
Say Y to enable hardware supported cross-timestamping on PCH
devices. The cross-timestamp is available through the PTP clock
driver precise cross-timestamp ioctl (PTP_SYS_OFFSET_PRECISE).
@@ -90,7 +90,7 @@ config IGB
imply PTP_1588_CLOCK
select I2C
select I2C_ALGOBIT
- ---help---
+ help
This driver supports Intel(R) 82575/82576 gigabit ethernet family of
adapters. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide that can be located at:
@@ -107,7 +107,7 @@ config IGB_HWMON
bool "Intel(R) PCI-Express Gigabit adapters HWMON support"
default y
depends on IGB && HWMON && !(IGB=y && HWMON=m)
- ---help---
+ help
Say Y if you want to expose thermal sensor data on Intel devices.
Some of our devices contain thermal sensors, both external and internal.
@@ -118,7 +118,7 @@ config IGB_DCA
bool "Direct Cache Access (DCA) Support"
default y
depends on IGB && DCA && !(IGB=y && DCA=m)
- ---help---
+ help
Say Y here if you want to use Direct Cache Access (DCA) in the
driver. DCA is a method for warming the CPU cache before data
is used, with the intent of lessening the impact of cache misses.
@@ -126,7 +126,7 @@ config IGB_DCA
config IGBVF
tristate "Intel(R) 82576 Virtual Function Ethernet support"
depends on PCI
- ---help---
+ help
This driver supports Intel(R) 82576 virtual functions. For more
information on how to identify your adapter, go to the Adapter &
Driver ID Guide that can be located at:
@@ -142,7 +142,7 @@ config IGBVF
config IXGB
tristate "Intel(R) PRO/10GbE support"
depends on PCI
- ---help---
+ help
This driver supports Intel(R) PRO/10GbE family of adapters for
PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver
instead. For more information on how to identify your adapter, go
@@ -162,7 +162,7 @@ config IXGBE
select MDIO
select PHYLIB
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide that can be located at:
@@ -179,7 +179,7 @@ config IXGBE_HWMON
bool "Intel(R) 10GbE PCI Express adapters HWMON support"
default y
depends on IXGBE && HWMON && !(IXGBE=y && HWMON=m)
- ---help---
+ help
Say Y if you want to expose the thermal sensor data on some of
our cards, via a hwmon sysfs interface.
@@ -187,7 +187,7 @@ config IXGBE_DCA
bool "Direct Cache Access (DCA) Support"
default y
depends on IXGBE && DCA && !(IXGBE=y && DCA=m)
- ---help---
+ help
Say Y here if you want to use Direct Cache Access (DCA) in the
driver. DCA is a method for warming the CPU cache before data
is used, with the intent of lessening the impact of cache misses.
@@ -196,7 +196,7 @@ config IXGBE_DCB
bool "Data Center Bridging (DCB) Support"
default n
depends on IXGBE && DCB
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
@@ -208,13 +208,13 @@ config IXGBE_IPSEC
depends on XFRM_OFFLOAD
default y
select XFRM_ALGO
- ---help---
+ help
Enable support for IPSec offload in ixgbe.ko
config IXGBEVF
tristate "Intel(R) 10GbE PCI Express Virtual Function Ethernet support"
depends on PCI_MSI
- ---help---
+ help
This driver supports Intel(R) PCI Express virtual functions for the
Intel(R) ixgbe driver. For more information on how to identify your
adapter, go to the Adapter & Driver ID Guide that can be located at:
@@ -234,14 +234,14 @@ config IXGBEVF_IPSEC
depends on XFRM_OFFLOAD
default y
select XFRM_ALGO
- ---help---
+ help
Enable support for IPSec offload in ixgbevf.ko
config I40E
tristate "Intel(R) Ethernet Controller XL710 Family support"
imply PTP_1588_CLOCK
depends on PCI
- ---help---
+ help
This driver supports Intel(R) Ethernet Controller XL710 Family of
devices. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide that can be located at:
@@ -258,7 +258,7 @@ config I40E_DCB
bool "Data Center Bridging (DCB) Support"
default n
depends on I40E && DCB
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
@@ -272,7 +272,7 @@ config I40EVF
tristate "Intel(R) Ethernet Adaptive Virtual Function support"
select IAVF
depends on PCI_MSI
- ---help---
+ help
This driver supports virtual functions for Intel XL710,
X710, X722, XXV710, and all devices advertising support for
Intel Ethernet Adaptive Virtual Function devices. For more
@@ -295,7 +295,7 @@ config ICE
default n
depends on PCI_MSI
select NET_DEVLINK
- ---help---
+ help
This driver supports Intel(R) Ethernet Connection E800 Series of
devices. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide that can be located at:
@@ -313,7 +313,7 @@ config FM10K
default n
depends on PCI_MSI
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports Intel(R) FM10000 Ethernet Switch Host
Interface. For more information on how to identify your adapter,
go to the Adapter & Driver ID Guide that can be located at:
@@ -330,7 +330,7 @@ config IGC
tristate "Intel(R) Ethernet Controller I225-LM/I225-V support"
default n
depends on PCI
- ---help---
+ help
This driver supports Intel(R) Ethernet Controller I225-LM/I225-V
family of adapters.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index f1d84921e42b..03e034918d14 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -53,10 +53,10 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
+#include <linux/pgtable.h>
#include <asm/bootinfo.h>
#include <asm/bitops.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 3d5caea096fb..cd8ddd1ef6f2 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_MARVELL
bool "Marvell devices"
default y
depends on PCI || CPU_PXA168 || MV64X60 || PPC32 || PLAT_ORION || INET || COMPILE_TEST
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config MV643XX_ETH
depends on INET
select PHYLIB
select MVMDIO
- ---help---
+ help
This driver supports the gigabit ethernet MACs in the
Marvell Discovery PPC/MIPS chipset family (MV643XX) and
in the Marvell Orion ARM SoC family.
@@ -35,7 +35,7 @@ config MVMDIO
tristate "Marvell MDIO interface support"
depends on HAS_IOMEM
select PHYLIB
- ---help---
+ help
This driver supports the MDIO interface found in the network
interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
Dove, Armada 370 and Armada XP).
@@ -46,7 +46,7 @@ config MVNETA_BM_ENABLE
tristate "Marvell Armada 38x/XP network interface BM support"
depends on MVNETA
depends on !64BIT
- ---help---
+ help
This driver supports auxiliary block of the network
interface units in the Marvell ARMADA XP and ARMADA 38x SoC
family, which is called buffer manager.
@@ -62,7 +62,7 @@ config MVNETA
select MVMDIO
select PHYLINK
select PAGE_POOL
- ---help---
+ help
This driver supports the network interface units in the
Marvell ARMADA XP, ARMADA 370, ARMADA 38x and
ARMADA 37xx SoC family.
@@ -87,7 +87,7 @@ config MVPP2
depends on ARCH_MVEBU || COMPILE_TEST
select MVMDIO
select PHYLINK
- ---help---
+ help
This driver supports the network interface units in the
Marvell ARMADA 375, 7K and 8K SoCs.
@@ -96,7 +96,7 @@ config PXA168_ETH
depends on HAS_IOMEM
depends on CPU_PXA168 || ARCH_BERLIN || COMPILE_TEST
select PHYLIB
- ---help---
+ help
This driver supports the pxa168 Ethernet ports.
To compile this driver as a module, choose M here. The module
@@ -106,7 +106,7 @@ config SKGE
tristate "Marvell Yukon Gigabit Ethernet support"
depends on PCI
select CRC32
- ---help---
+ help
This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
and related Gigabit Ethernet adapters. It is a new smaller driver
with better performance and more complete ethtool support.
@@ -127,7 +127,7 @@ config SKGE
config SKGE_DEBUG
bool "Debugging interface"
depends on SKGE && DEBUG_FS
- ---help---
+ help
This option adds the ability to dump driver state for debugging.
The file /sys/kernel/debug/skge/ethX displays the state of the internal
transmit and receive rings.
@@ -137,7 +137,7 @@ config SKGE_DEBUG
config SKGE_GENESIS
bool "Support for older SysKonnect Genesis boards"
depends on SKGE
- ---help---
+ help
This enables support for the older and uncommon SysKonnect Genesis
chips, which support MII via an external transceiver, instead of
an internal one. Disabling this option will save some memory
@@ -147,7 +147,7 @@ config SKY2
tristate "Marvell Yukon 2 support"
depends on PCI
select CRC32
- ---help---
+ help
This driver supports Gigabit Ethernet adapters based on the
Marvell Yukon 2 chipset:
Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
@@ -162,7 +162,7 @@ config SKY2
config SKY2_DEBUG
bool "Debugging interface"
depends on SKY2 && DEBUG_FS
- ---help---
+ help
This option adds the ability to dump driver state for debugging.
The file /sys/kernel/debug/sky2/ethX displays the state of the internal
transmit and receive rings.
diff --git a/drivers/net/ethernet/marvell/octeontx2/Kconfig b/drivers/net/ethernet/marvell/octeontx2/Kconfig
index d9dfb614daa6..543a1d047567 100644
--- a/drivers/net/ethernet/marvell/octeontx2/Kconfig
+++ b/drivers/net/ethernet/marvell/octeontx2/Kconfig
@@ -21,7 +21,7 @@ config NDC_DIS_DYNAMIC_CACHING
bool "Disable caching of dynamic entries in NDC"
depends on OCTEONTX2_AF
default n
- ---help---
+ help
This config option disables caching of dynamic entries such as NIX SQEs
, NPA stack pages etc in NDC. Also locks down NIX SQ/CQ/RQ/RSS and
NPA Aura/Pool contexts.
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 17243bb5ba91..eb8cf60ecf12 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -31,8 +31,8 @@
#include <linux/types.h>
#include <linux/udp.h>
#include <linux/workqueue.h>
+#include <linux/pgtable.h>
-#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#define DRIVER_NAME "pxa168-eth"
diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
index 500c15e7ea4a..62a820b1eb16 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -2,7 +2,7 @@
config NET_VENDOR_MEDIATEK
bool "MediaTek devices"
depends on ARCH_MEDIATEK || SOC_MT7621 || SOC_MT7620
- ---help---
+ help
If you have a Mediatek SoC with ethernet, say Y.
if NET_VENDOR_MEDIATEK
@@ -10,7 +10,7 @@ if NET_VENDOR_MEDIATEK
config NET_MEDIATEK_SOC
tristate "MediaTek SoC Gigabit Ethernet support"
select PHYLINK
- ---help---
+ help
This driver supports the gigabit ethernet MACs in the
MediaTek SoC family.
diff --git a/drivers/net/ethernet/mellanox/Kconfig b/drivers/net/ethernet/mellanox/Kconfig
index 23cf7917a0c9..ff6613a5cdd3 100644
--- a/drivers/net/ethernet/mellanox/Kconfig
+++ b/drivers/net/ethernet/mellanox/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_MELLANOX
bool "Mellanox devices"
default y
depends on PCI || I2C
- ---help---
+ help
If you have a network (Ethernet or RDMA) device belonging to this
class, say Y.
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig
index e69c3c31e701..400e611ba041 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig
@@ -8,7 +8,7 @@ config MLX4_EN
depends on PCI && NETDEVICES && ETHERNET && INET
select MLX4_CORE
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports Mellanox Technologies ConnectX Ethernet
devices.
@@ -16,7 +16,7 @@ config MLX4_EN_DCB
bool "Data Center Bridging (DCB) Support"
default y
depends on MLX4_EN && DCB
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
If set to N, will not be able to configure QoS and ratelimit attributes.
@@ -34,7 +34,7 @@ config MLX4_DEBUG
bool "Verbose debugging output" if (MLX4_CORE && EXPERT)
depends on MLX4_CORE
default y
- ---help---
+ help
This option causes debugging code to be compiled into the
mlx4_core driver. The output can be turned on via the
debug_level module parameter (which can also be set after
@@ -44,6 +44,6 @@ config MLX4_CORE_GEN2
bool "Support for old gen2 Mellanox PCI IDs" if (MLX4_CORE)
depends on MLX4_CORE
default y
- ---help---
+ help
Say Y here if you want to use old gen2 Mellanox devices in the
driver.
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index b6ffd1622cfd..4dfdbb82ea9d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -12,7 +12,7 @@ config MLX5_CORE
depends on PTP_1588_CLOCK || !PTP_1588_CLOCK
depends on PCI_HYPERV_INTERFACE || !PCI_HYPERV_INTERFACE
default n
- ---help---
+ help
Core driver for low level functionality of the ConnectX-4 and
Connect-IB cards by Mellanox Technologies.
@@ -23,7 +23,7 @@ config MLX5_FPGA
bool "Mellanox Technologies Innova support"
depends on MLX5_CORE
select MLX5_ACCEL
- ---help---
+ help
Build support for the Innova family of network cards by Mellanox
Technologies. Innova network cards are comprised of a ConnectX chip
and an FPGA chip on one board. If you select this option, the
@@ -36,14 +36,14 @@ config MLX5_CORE_EN
select PAGE_POOL
select DIMLIB
default n
- ---help---
+ help
Ethernet support in Mellanox Technologies ConnectX-4 NIC.
config MLX5_EN_ARFS
bool "Mellanox MLX5 ethernet accelerated receive flow steering (ARFS) support"
depends on MLX5_CORE_EN && RFS_ACCEL
default y
- ---help---
+ help
Mellanox MLX5 ethernet hardware-accelerated receive flow steering support,
Enables ethernet netdevice arfs support and ntuple filtering.
@@ -51,7 +51,7 @@ config MLX5_EN_RXNFC
bool "Mellanox MLX5 ethernet rx nfc flow steering support"
depends on MLX5_CORE_EN
default y
- ---help---
+ help
Mellanox MLX5 ethernet rx nfc flow steering support
Enables ethtool receive network flow classification, which allows user defined
flow rules to direct traffic into arbitrary rx queue via ethtool set/get_rxnfc
@@ -61,7 +61,7 @@ config MLX5_MPFS
bool "Mellanox Technologies MLX5 MPFS support"
depends on MLX5_CORE_EN
default y
- ---help---
+ help
Mellanox Technologies Ethernet Multi-Physical Function Switch (MPFS)
support in ConnectX NIC. MPFs is required for when multi-PF configuration
is enabled to allow passing user configured unicast MAC addresses to the
@@ -71,7 +71,7 @@ config MLX5_ESWITCH
bool "Mellanox Technologies MLX5 SRIOV E-Switch support"
depends on MLX5_CORE_EN && NET_SWITCHDEV
default y
- ---help---
+ help
Mellanox Technologies Ethernet SRIOV E-Switch support in ConnectX NIC.
E-Switch provides internal SRIOV packet steering and switching for the
enabled VFs and PF in two available modes:
@@ -107,7 +107,7 @@ config MLX5_CORE_EN_DCB
bool "Data Center Bridging (DCB) Support"
default y
depends on MLX5_CORE_EN && DCB
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
If set to N, will not be able to configure QoS and ratelimit attributes.
@@ -119,7 +119,7 @@ config MLX5_CORE_IPOIB
bool "Mellanox 5th generation network adapters (connectX series) IPoIB offloads support"
depends on MLX5_CORE_EN
default n
- ---help---
+ help
MLX5 IPoIB offloads & acceleration support.
config MLX5_FPGA_IPSEC
diff --git a/drivers/net/ethernet/mellanox/mlxfw/Kconfig b/drivers/net/ethernet/mellanox/mlxfw/Kconfig
index 5b604501f33e..c339f3c46e45 100644
--- a/drivers/net/ethernet/mellanox/mlxfw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxfw/Kconfig
@@ -5,7 +5,7 @@
config MLXFW
tristate "Mellanox Technologies firmware flash module"
- ---help---
+ help
This driver supports Mellanox Technologies Firmware
flashing common logic.
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
index f458fd1ce9f8..872e9910bb7c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
@@ -6,7 +6,7 @@
config MLXSW_CORE
tristate "Mellanox Technologies Switch ASICs support"
select NET_DEVLINK
- ---help---
+ help
This driver supports Mellanox Technologies Switch ASICs family.
To compile this driver as a module, choose M here: the
@@ -17,14 +17,14 @@ config MLXSW_CORE_HWMON
depends on MLXSW_CORE && HWMON
depends on !(MLXSW_CORE=y && HWMON=m)
default y
- ---help---
+ help
Say Y here if you want to expose HWMON interface on mlxsw devices.
config MLXSW_CORE_THERMAL
bool "Thermal zone support for Mellanox Technologies Switch ASICs"
depends on MLXSW_CORE && THERMAL
default y
- ---help---
+ help
Say Y here if you want to automatically control fans speed according
ambient temperature reported by ASIC.
@@ -32,7 +32,7 @@ config MLXSW_PCI
tristate "PCI bus implementation for Mellanox Technologies Switch ASICs"
depends on PCI && HAS_IOMEM && MLXSW_CORE
default m
- ---help---
+ help
This is PCI bus implementation for Mellanox Technologies Switch ASICs.
To compile this driver as a module, choose M here: the
@@ -42,7 +42,7 @@ config MLXSW_I2C
tristate "I2C bus implementation for Mellanox Technologies Switch ASICs"
depends on I2C && MLXSW_CORE
default m
- ---help---
+ help
This is I2C bus implementation for Mellanox Technologies Switch ASICs.
To compile this driver as a module, choose M here: the
@@ -52,7 +52,7 @@ config MLXSW_SWITCHIB
tristate "Mellanox Technologies SwitchIB and SwitchIB-2 support"
depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV
default m
- ---help---
+ help
This driver supports Mellanox Technologies SwitchIB and SwitchIB-2
Infiniband Switch ASICs.
@@ -63,7 +63,7 @@ config MLXSW_SWITCHX2
tristate "Mellanox Technologies SwitchX-2 support"
depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV
default m
- ---help---
+ help
This driver supports Mellanox Technologies SwitchX-2 Ethernet
Switch ASICs.
@@ -86,7 +86,7 @@ config MLXSW_SPECTRUM
imply PTP_1588_CLOCK
select NET_PTP_CLASSIFY if PTP_1588_CLOCK
default m
- ---help---
+ help
This driver supports Mellanox Technologies
Spectrum/Spectrum-2/Spectrum-3 Ethernet Switch ASICs.
@@ -97,7 +97,7 @@ config MLXSW_SPECTRUM_DCB
bool "Data Center Bridging (DCB) support"
depends on MLXSW_SPECTRUM && DCB
default y
- ---help---
+ help
Say Y here if you want to use Data Center Bridging (DCB) in the
driver.
@@ -105,7 +105,7 @@ config MLXSW_MINIMAL
tristate "Mellanox Technologies minimal I2C support"
depends on MLXSW_CORE && MLXSW_I2C
default m
- ---help---
+ help
This driver supports I2C access for Mellanox Technologies Switch
ASICs.
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
index 09f35209d43d..42bc014136fe 100644
--- a/drivers/net/ethernet/micrel/Kconfig
+++ b/drivers/net/ethernet/micrel/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_MICREL
bool "Micrel devices"
default y
depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_MICREL
config KS8842
tristate "Micrel KSZ8841/42 with generic bus interface"
depends on HAS_IOMEM && DMA_ENGINE
- ---help---
+ help
This platform driver is for KSZ8841(1-port) / KS8842(2-port)
ethernet switch chip (managed, VLAN, QoS) from Micrel or
Timberdale(FPGA).
@@ -31,7 +31,7 @@ config KS8851
select MII
select CRC32
select EEPROM_93CX6
- ---help---
+ help
SPI driver for Micrel KS8851 SPI attached network chip.
config KS8851_MLL
@@ -40,7 +40,7 @@ config KS8851_MLL
select MII
select CRC32
select EEPROM_93CX6
- ---help---
+ help
This platform driver is for Micrel KS8851 Address/data bus
multiplexed network chip.
@@ -49,7 +49,7 @@ config KSZ884X_PCI
depends on PCI
select MII
select CRC32
- ---help---
+ help
This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index 45fe41f3d9f3..31f9a82dc113 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_MICROCHIP
bool "Microchip devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config ENC28J60
tristate "ENC28J60 support"
depends on SPI
select CRC32
- ---help---
+ help
Support for the Microchip EN28J60 ethernet chip.
To compile this driver as a module, choose M here. The module will be
@@ -29,14 +29,14 @@ config ENC28J60
config ENC28J60_WRITEVERIFY
bool "Enable write verify"
depends on ENC28J60
- ---help---
+ help
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
config ENCX24J600
tristate "ENCX24J600 support"
depends on SPI
- ---help---
+ help
Support for the Microchip ENC424J600/624J600 ethernet chip.
To compile this driver as a module, choose M here. The module will be
@@ -47,7 +47,7 @@ config LAN743X
depends on PCI
select PHYLIB
select CRC16
- ---help---
+ help
Support for the Microchip LAN743x PCI Express Gigabit Ethernet chip
To compile this driver as a module, choose M here. The module will be
diff --git a/drivers/net/ethernet/moxa/Kconfig b/drivers/net/ethernet/moxa/Kconfig
index 1a7cacbc0c59..134802b521cb 100644
--- a/drivers/net/ethernet/moxa/Kconfig
+++ b/drivers/net/ethernet/moxa/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_MOXART
bool "MOXA ART devices"
default y
depends on (ARM && ARCH_MOXART)
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config ARM_MOXART_ETHER
tristate "MOXART Ethernet support"
depends on ARM && ARCH_MOXART
select NET_CORE
- ---help---
+ help
If you wish to compile a kernel for a hardware with MOXA ART SoC and
want to use the internal ethernet then you should answer Y to this.
diff --git a/drivers/net/ethernet/myricom/Kconfig b/drivers/net/ethernet/myricom/Kconfig
index 6bc993eae4c4..81267fd72dbf 100644
--- a/drivers/net/ethernet/myricom/Kconfig
+++ b/drivers/net/ethernet/myricom/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_MYRI
bool "Myricom devices"
default y
depends on PCI && INET
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config MYRI10GE
depends on PCI && INET
select FW_LOADER
select CRC32
- ---help---
+ help
This driver supports Myricom Myri-10G Dual Protocol interface in
Ethernet mode. If the eeprom on your board is not recent enough,
you will need a newer firmware image.
@@ -37,7 +37,7 @@ config MYRI10GE_DCA
bool "Direct Cache Access (DCA) Support"
default y
depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m)
- ---help---
+ help
Say Y here if you want to use Direct Cache Access (DCA) in the
driver. DCA is a method for warming the CPU cache before data
is used, with the intent of lessening the impact of cache misses.
diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig
index c519c1f30225..0a92101aa3f1 100644
--- a/drivers/net/ethernet/natsemi/Kconfig
+++ b/drivers/net/ethernet/natsemi/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_NATSEMI
bool "National Semiconductor devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -19,7 +19,7 @@ if NET_VENDOR_NATSEMI
config MACSONIC
tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
depends on MAC
- ---help---
+ help
Support for NatSemi SONIC based Ethernet devices. This includes
the onboard Ethernet in many Quadras as well as some LC-PDS,
a few Nubus and all known Comm Slot Ethernet cards. If you have
@@ -31,7 +31,7 @@ config MACSONIC
config MIPS_JAZZ_SONIC
tristate "MIPS JAZZ onboard SONIC Ethernet support"
depends on MACH_JAZZ
- ---help---
+ help
This is the driver for the onboard card of MIPS Magnum 4000,
Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
@@ -39,7 +39,7 @@ config NATSEMI
tristate "National Semiconductor DP8381x series PCI Ethernet support"
depends on PCI
select CRC32
- ---help---
+ help
This driver is for the National Semiconductor DP83810 series,
which is used in cards from PureData, NetGear, Linksys
and others, including the 83815 chip.
@@ -49,7 +49,7 @@ config NATSEMI
config NS83820
tristate "National Semiconductor DP83820 support"
depends on PCI
- ---help---
+ help
This is a driver for the National Semiconductor DP83820 series
of gigabit ethernet MACs. Cards using this chipset include
the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
@@ -59,7 +59,7 @@ config NS83820
config XTENSA_XT2000_SONIC
tristate "Xtensa XT2000 onboard SONIC Ethernet support"
depends on XTENSA_PLATFORM_XT2000
- ---help---
+ help
This is the driver for the onboard card of the Xtensa XT2000 board.
endif # NET_VENDOR_NATSEMI
diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c
index 8b018ed37b1b..ce3eca5d152b 100644
--- a/drivers/net/ethernet/natsemi/jazzsonic.c
+++ b/drivers/net/ethernet/natsemi/jazzsonic.c
@@ -36,9 +36,9 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
#include <asm/bootinfo.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/jazz.h>
diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c
index 1b5559aacb38..776b7d264dc3 100644
--- a/drivers/net/ethernet/natsemi/macsonic.c
+++ b/drivers/net/ethernet/natsemi/macsonic.c
@@ -51,8 +51,8 @@
#include <linux/dma-mapping.h>
#include <linux/bitrev.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/hwtest.h>
#include <asm/dma.h>
diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c
index dda9ec7d9cee..afa166ff7aef 100644
--- a/drivers/net/ethernet/natsemi/xtsonic.c
+++ b/drivers/net/ethernet/natsemi/xtsonic.c
@@ -35,9 +35,9 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/dma.h>
static char xtsonic_string[] = "xtsonic";
diff --git a/drivers/net/ethernet/neterion/Kconfig b/drivers/net/ethernet/neterion/Kconfig
index a82a37094579..5484f18f272e 100644
--- a/drivers/net/ethernet/neterion/Kconfig
+++ b/drivers/net/ethernet/neterion/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_NETERION
bool "Neterion (Exar) devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_NETERION
config S2IO
tristate "Neterion (Exar) Xframe 10Gb Ethernet Adapter"
depends on PCI
- ---help---
+ help
This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters.
These were originally released from S2IO, which renamed itself
Neterion. So, the adapters might be labeled as either one, depending
@@ -35,7 +35,7 @@ config S2IO
config VXGE
tristate "Neterion (Exar) X3100 Series 10GbE PCIe Server Adapter"
depends on PCI
- ---help---
+ help
This driver supports Exar Corp's X3100 Series 10 GbE PCIe
I/O Virtualized Server Adapter. These were originally released from
Neterion, which was later acquired by Exar. So, the adapters might be
@@ -51,7 +51,7 @@ config VXGE_DEBUG_TRACE_ALL
bool "Enabling All Debug trace statements in driver"
default n
depends on VXGE
- ---help---
+ help
Say Y here if you want to enabling all the debug trace statements in
the vxge driver. By default only few debug trace statements are
enabled.
diff --git a/drivers/net/ethernet/netronome/Kconfig b/drivers/net/ethernet/netronome/Kconfig
index a3f68a718813..d8b99d6a0356 100644
--- a/drivers/net/ethernet/netronome/Kconfig
+++ b/drivers/net/ethernet/netronome/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_NETRONOME
bool "Netronome(R) devices"
default y
- ---help---
+ help
If you have a Netronome(R) network (Ethernet) card or device, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config NFP
depends on VXLAN || VXLAN=n
depends on TLS && TLS_DEVICE || TLS_DEVICE=n
select NET_DEVLINK
- ---help---
+ help
This driver supports the Netronome(R) NFP4000/NFP6000 based
cards working as a advanced Ethernet NIC. It works with both
SR-IOV physical and virtual functions.
@@ -33,7 +33,7 @@ config NFP_APP_FLOWER
depends on NET_SWITCHDEV
depends on IPV6!=m || NFP=m
default y
- ---help---
+ help
Enable driver support for TC Flower offload on NFP4000 and NFP6000.
Say Y, if you are planning to make use of TC Flower offload
either directly, with Open vSwitch, or any other way. Note that
@@ -55,7 +55,7 @@ config NFP_APP_ABM_NIC
config NFP_DEBUG
bool "Debug support for Netronome(R) NFP4000/NFP6000 NIC drivers"
depends on NFP
- ---help---
+ help
Enable extra sanity checks and debugfs support in
Netronome(R) NFP4000/NFP6000 NIC drivers.
Note: selecting this option may adversely impact
diff --git a/drivers/net/ethernet/nvidia/Kconfig b/drivers/net/ethernet/nvidia/Kconfig
index faacbd129c44..c653786b1d05 100644
--- a/drivers/net/ethernet/nvidia/Kconfig
+++ b/drivers/net/ethernet/nvidia/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_NVIDIA
bool "NVIDIA devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_NVIDIA
config FORCEDETH
tristate "nForce Ethernet support"
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) controller of this type, say Y here.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/oki-semi/Kconfig b/drivers/net/ethernet/oki-semi/Kconfig
index 1c455c645bce..c2fff04ba7b6 100644
--- a/drivers/net/ethernet/oki-semi/Kconfig
+++ b/drivers/net/ethernet/oki-semi/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_OKI
bool "OKI Semiconductor devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
index 69e11d19bdc6..af84f72bf08e 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
@@ -9,7 +9,7 @@ config PCH_GBE
select MII
select PTP_1588_CLOCK_PCH
select NET_PTP_CLASSIFY
- ---help---
+ help
This is a gigabit ethernet driver for EG20T PCH.
EG20T PCH is the platform controller hub that is used in Intel's
general embedded platform. EG20T PCH has Gigabit Ethernet interface.
diff --git a/drivers/net/ethernet/packetengines/Kconfig b/drivers/net/ethernet/packetengines/Kconfig
index ead3750b4489..de91331dcb7d 100644
--- a/drivers/net/ethernet/packetengines/Kconfig
+++ b/drivers/net/ethernet/packetengines/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_PACKET_ENGINES
bool "Packet Engines devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config HAMACHI
tristate "Packet Engines Hamachi GNIC-II support"
depends on PCI
select MII
- ---help---
+ help
If you have a Gigabit Ethernet card of this type, say Y here.
To compile this driver as a module, choose M here. The module will be
@@ -31,7 +31,7 @@ config YELLOWFIN
tristate "Packet Engines Yellowfin Gigabit-NIC support"
depends on PCI
select CRC32
- ---help---
+ help
Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet
adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is
used by the Beowulf Linux cluster project. See
diff --git a/drivers/net/ethernet/pasemi/Kconfig b/drivers/net/ethernet/pasemi/Kconfig
index f4562243d4a0..cd68ebcf3e47 100644
--- a/drivers/net/ethernet/pasemi/Kconfig
+++ b/drivers/net/ethernet/pasemi/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_PASEMI
bool "PA Semi devices"
default y
depends on PPC_PASEMI && PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config PASEMI_MAC
tristate "PA Semi 1/10Gbit MAC"
depends on PPC_PASEMI && PCI
select PHYLIB
- ---help---
+ help
This driver supports the on-chip 1/10Gbit Ethernet controller on
PA Semi's PWRficient line of chips.
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index 55a29ec76680..8f743d80760b 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_QLOGIC
bool "QLogic devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_QLOGIC
config QLA3XXX
tristate "QLogic QLA3XXX Network Driver Support"
depends on PCI
- ---help---
+ help
This driver supports QLogic ISP3XXX gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
@@ -30,7 +30,7 @@ config QLCNIC
tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
depends on PCI
select FW_LOADER
- ---help---
+ help
This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
devices.
@@ -38,7 +38,7 @@ config QLCNIC_SRIOV
bool "QLOGIC QLCNIC 83XX family SR-IOV Support"
depends on QLCNIC && PCI_IOV
default y
- ---help---
+ help
This configuration parameter enables Single Root Input Output
Virtualization support for QLE83XX Converged Ethernet devices.
This allows for virtual function acceleration in virtualized
@@ -48,7 +48,7 @@ config QLCNIC_DCB
bool "QLOGIC QLCNIC 82XX and 83XX family DCB Support"
depends on QLCNIC && DCB
default y
- ---help---
+ help
This configuration parameter enables DCB support in QLE83XX
and QLE82XX Converged Ethernet devices. This allows for DCB
get operations support through rtNetlink interface. Only CEE
@@ -59,7 +59,7 @@ config QLCNIC_HWMON
bool "QLOGIC QLCNIC 82XX and 83XX family HWMON support"
depends on QLCNIC && HWMON && !(QLCNIC=y && HWMON=m)
default y
- ---help---
+ help
This configuration parameter can be used to read the
board temperature in Converged Ethernet devices
supported by qlcnic.
@@ -70,7 +70,7 @@ config NETXEN_NIC
tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
depends on PCI
select FW_LOADER
- ---help---
+ help
This enables the support for NetXen's Gigabit Ethernet card.
config QED
@@ -79,7 +79,7 @@ config QED
select ZLIB_INFLATE
select CRC8
select NET_DEVLINK
- ---help---
+ help
This enables the support for ...
config QED_LL2
@@ -89,7 +89,7 @@ config QED_SRIOV
bool "QLogic QED 25/40/100Gb SR-IOV support"
depends on QED && PCI_IOV
default y
- ---help---
+ help
This configuration parameter enables Single Root Input Output
Virtualization support for QED devices.
This allows for virtual function acceleration in virtualized
@@ -99,7 +99,7 @@ config QEDE
tristate "QLogic QED 25/40/100Gb Ethernet NIC"
depends on QED
imply PTP_1588_CLOCK
- ---help---
+ help
This enables the support for ...
config QED_RDMA
diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
index 09a678a94634..a4434eb38950 100644
--- a/drivers/net/ethernet/qualcomm/Kconfig
+++ b/drivers/net/ethernet/qualcomm/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_QUALCOMM
bool "Qualcomm devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -25,7 +25,7 @@ config QCA7000_SPI
tristate "Qualcomm Atheros QCA7000 SPI support"
select QCA7000
depends on SPI_MASTER && OF
- ---help---
+ help
This SPI protocol driver supports the Qualcomm Atheros QCA7000.
To compile this driver as a module, choose M here. The module
@@ -35,7 +35,7 @@ config QCA7000_UART
tristate "Qualcomm Atheros QCA7000 UART support"
select QCA7000
depends on SERIAL_DEV_BUS && OF
- ---help---
+ help
This UART protocol driver supports the Qualcomm Atheros QCA7000.
Currently the driver assumes these device UART settings:
@@ -52,7 +52,7 @@ config QCOM_EMAC
depends on HAS_DMA && HAS_IOMEM
select CRC32
select PHYLIB
- ---help---
+ help
This driver supports the Qualcomm Technologies, Inc. Gigabit
Ethernet Media Access Controller (EMAC). The controller
supports IEEE 802.3-2002, half-duplex mode at 10/100 Mb/s,
diff --git a/drivers/net/ethernet/qualcomm/rmnet/Kconfig b/drivers/net/ethernet/qualcomm/rmnet/Kconfig
index 9f9279575e2e..b4a575eb0175 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/Kconfig
+++ b/drivers/net/ethernet/qualcomm/rmnet/Kconfig
@@ -7,7 +7,7 @@ menuconfig RMNET
tristate "RmNet MAP driver"
default n
select GRO_CELLS
- ---help---
+ help
If you select this, you will enable the RMNET module which is used
for handling data in the multiplexing and aggregation protocol (MAP)
format in the embedded data path. RMNET devices can be attached to
diff --git a/drivers/net/ethernet/rdc/Kconfig b/drivers/net/ethernet/rdc/Kconfig
index 76df60c2f4ac..6884c7864bb9 100644
--- a/drivers/net/ethernet/rdc/Kconfig
+++ b/drivers/net/ethernet/rdc/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_RDC
bool "RDC devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config R6040
select CRC32
select MII
select PHYLIB
- ---help---
+ help
This is a driver for the R6040 Fast Ethernet MACs found in the
the RDC R-321x System-on-chips.
diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig
index 5e0b9d2f14f7..93d9df55b361 100644
--- a/drivers/net/ethernet/realtek/Kconfig
+++ b/drivers/net/ethernet/realtek/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_REALTEK
bool "Realtek devices"
default y
depends on PCI || (PARPORT && X86)
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config ATP
tristate "AT-LAN-TEC/RealTek pocket adapter support"
depends on PARPORT && X86
select CRC32
- ---help---
+ help
This is a network (Ethernet) device which attaches to your parallel
port. Read the file <file:drivers/net/ethernet/realtek/atp.c>
if you want to use this. If you intend to use this driver, you
@@ -36,7 +36,7 @@ config 8139CP
depends on PCI
select CRC32
select MII
- ---help---
+ help
This is a driver for the Fast Ethernet PCI network cards based on
the RTL8139C+ chips. If you have one of those, say Y here.
@@ -48,7 +48,7 @@ config 8139TOO
depends on PCI
select CRC32
select MII
- ---help---
+ help
This is a driver for the Fast Ethernet PCI network cards based on
the RTL 8129/8130/8139 chips. If you have one of those, say Y here.
@@ -59,7 +59,7 @@ config 8139TOO_PIO
bool "Use PIO instead of MMIO"
default y
depends on 8139TOO
- ---help---
+ help
This instructs the driver to use programmed I/O ports (PIO) instead
of PCI shared memory (MMIO). This can possibly solve some problems
in case your mainboard has memory consistency issues. If unsure,
@@ -68,7 +68,7 @@ config 8139TOO_PIO
config 8139TOO_TUNE_TWISTER
bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
depends on 8139TOO
- ---help---
+ help
This implements a function which might come in handy in case you
are using low quality on long cabling. It is required for RealTek
RTL-8139 revision K boards, and totally unused otherwise. It tries
@@ -79,7 +79,7 @@ config 8139TOO_TUNE_TWISTER
config 8139TOO_8129
bool "Support for older RTL-8129/8130 boards"
depends on 8139TOO
- ---help---
+ help
This enables support for the older and uncommon RTL-8129 and
RTL-8130 chips, which support MII via an external transceiver,
instead of an internal one. Disabling this option will save some
@@ -88,7 +88,7 @@ config 8139TOO_8129
config 8139_OLD_RX_RESET
bool "Use older RX-reset method"
depends on 8139TOO
- ---help---
+ help
The 8139too driver was recently updated to contain a more rapid
reset sequence, in the face of severe receive errors. This "new"
RX-reset method should be adequate for all boards. But if you
@@ -102,7 +102,7 @@ config R8169
select CRC32
select PHYLIB
select REALTEK_PHY
- ---help---
+ help
Say Y here if you have a Realtek Ethernet adapter belonging to
the following families:
RTL8169 Gigabit Ethernet
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
index bb0ebdfd4459..5a2a4af31812 100644
--- a/drivers/net/ethernet/renesas/Kconfig
+++ b/drivers/net/ethernet/renesas/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_RENESAS
bool "Renesas devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config SH_ETH
select MII
select MDIO_BITBANG
select PHYLIB
- ---help---
+ help
Renesas SuperH Ethernet device driver.
This driver supporting CPUs are:
- SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757,
diff --git a/drivers/net/ethernet/rocker/Kconfig b/drivers/net/ethernet/rocker/Kconfig
index 1083de99830d..99e1290e0307 100644
--- a/drivers/net/ethernet/rocker/Kconfig
+++ b/drivers/net/ethernet/rocker/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_ROCKER
bool "Rocker devices"
default y
- ---help---
+ help
If you have a network device belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -19,7 +19,7 @@ if NET_VENDOR_ROCKER
config ROCKER
tristate "Rocker switch driver (EXPERIMENTAL)"
depends on PCI && NET_SWITCHDEV && BRIDGE
- ---help---
+ help
This driver supports Rocker switch device.
To compile this driver as a module, choose M here: the
diff --git a/drivers/net/ethernet/samsung/Kconfig b/drivers/net/ethernet/samsung/Kconfig
index e92a178a76df..0582e110b1c0 100644
--- a/drivers/net/ethernet/samsung/Kconfig
+++ b/drivers/net/ethernet/samsung/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_SAMSUNG
bool "Samsung Ethernet devices"
default y
- ---help---
+ help
If you have a network (Ethernet) chipset belonging to this class,
say Y.
@@ -23,7 +23,7 @@ config SXGBE_ETH
select PHYLIB
select CRC32
imply PTP_1588_CLOCK
- ---help---
+ help
This is the driver for the SXGBE 10G Ethernet IP block found on
Samsung platforms.
diff --git a/drivers/net/ethernet/seeq/Kconfig b/drivers/net/ethernet/seeq/Kconfig
index f3ac9cba5770..ad1df37571dd 100644
--- a/drivers/net/ethernet/seeq/Kconfig
+++ b/drivers/net/ethernet/seeq/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_SEEQ
bool "SEEQ devices"
default y
depends on HAS_IOMEM
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,14 +20,14 @@ if NET_VENDOR_SEEQ
config ARM_ETHER3
tristate "Acorn/ANT Ether3 support"
depends on ARM && ARCH_ACORN
- ---help---
+ help
If you have an Acorn system with one of these network cards, you
should say Y to this option if you wish to use it with Linux.
config SGISEEQ
tristate "SGI Seeq ethernet controller support"
depends on SGI_HAS_SEEQ
- ---help---
+ help
Say Y here if you have an Seeq based Ethernet network card. This is
used in many Silicon Graphics machines.
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index ea5a9220196c..81b0f7d3a025 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_SOLARFLARE
bool "Solarflare devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config SFC
select MDIO
select CRC32
imply PTP_1588_CLOCK
- ---help---
+ help
This driver supports 10/40-gigabit Ethernet cards based on
the Solarflare SFC9000-family and SFC9100-family controllers.
@@ -32,7 +32,7 @@ config SFC_MTD
bool "Solarflare SFC9000/SFC9100-family MTD support"
depends on SFC && MTD && !(SFC=y && MTD=m)
default y
- ---help---
+ help
This exposes the on-board flash and/or EEPROM as MTD devices
(e.g. /dev/mtd1). This is required to update the firmware or
the boot configuration under Linux.
@@ -40,14 +40,14 @@ config SFC_MCDI_MON
bool "Solarflare SFC9000/SFC9100-family hwmon support"
depends on SFC && HWMON && !(SFC=y && HWMON=m)
default y
- ---help---
+ help
This exposes the on-board firmware-managed sensors as a
hardware monitor device.
config SFC_SRIOV
bool "Solarflare SFC9000-family SR-IOV support"
depends on SFC && PCI_IOV
default y
- ---help---
+ help
This enables support for the SFC9000 I/O Virtualization
features, allowing accelerated network performance in
virtualized environments.
@@ -55,7 +55,7 @@ config SFC_MCDI_LOGGING
bool "Solarflare SFC9000/SFC9100-family MCDI logging support"
depends on SFC
default y
- ---help---
+ help
This enables support for tracing of MCDI (Management-Controller-to-
Driver-Interface) commands and responses, allowing debugging of
driver/firmware interaction. The tracing is actually enabled by
diff --git a/drivers/net/ethernet/sfc/falcon/Kconfig b/drivers/net/ethernet/sfc/falcon/Kconfig
index 20e361950f7d..071154045dc2 100644
--- a/drivers/net/ethernet/sfc/falcon/Kconfig
+++ b/drivers/net/ethernet/sfc/falcon/Kconfig
@@ -6,7 +6,7 @@ config SFC_FALCON
select CRC32
select I2C
select I2C_ALGOBIT
- ---help---
+ help
This driver supports 10-gigabit Ethernet cards based on
the Solarflare SFC4000 controller.
@@ -16,7 +16,7 @@ config SFC_FALCON_MTD
bool "Solarflare SFC4000 MTD support"
depends on SFC_FALCON && MTD && !(SFC_FALCON=y && MTD=m)
default y
- ---help---
+ help
This exposes the on-board flash and/or EEPROM as MTD devices
(e.g. /dev/mtd1). This is required to update the boot
configuration under Linux.
diff --git a/drivers/net/ethernet/sgi/Kconfig b/drivers/net/ethernet/sgi/Kconfig
index bc26fa0d196f..af66bb0a20d1 100644
--- a/drivers/net/ethernet/sgi/Kconfig
+++ b/drivers/net/ethernet/sgi/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_SGI
bool "SGI devices"
default y
depends on (PCI && SGI_MFD_IOC3) || SGI_IP32
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config SGI_IOC3_ETH
select CRC16
select CRC32
select MII
- ---help---
+ help
If you have a network (Ethernet) card of this type, say Y here.
config SGI_O2MACE_ETH
diff --git a/drivers/net/ethernet/silan/Kconfig b/drivers/net/ethernet/silan/Kconfig
index 71929d148c3c..7ed08d588ac2 100644
--- a/drivers/net/ethernet/silan/Kconfig
+++ b/drivers/net/ethernet/silan/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_SILAN
bool "Silan devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config SC92031
tristate "Silan SC92031 PCI Fast Ethernet Adapter driver"
depends on PCI
select CRC32
- ---help---
+ help
This is a driver for the Fast Ethernet PCI network cards based on
the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you
have one of these, say Y here.
diff --git a/drivers/net/ethernet/sis/Kconfig b/drivers/net/ethernet/sis/Kconfig
index d848ab0349a7..775d76d9890e 100644
--- a/drivers/net/ethernet/sis/Kconfig
+++ b/drivers/net/ethernet/sis/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_SIS
bool "Silicon Integrated Systems (SiS) devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config SIS900
depends on PCI
select CRC32
select MII
- ---help---
+ help
This is a driver for the Fast Ethernet PCI network cards based on
the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
SiS 630 and SiS 540 chipsets.
@@ -38,7 +38,7 @@ config SIS190
depends on PCI
select CRC32
select MII
- ---help---
+ help
Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
appear in lan on motherboard designs which are based on SiS 965
diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig
index 4d2d91ec8b41..6293b1e6c772 100644
--- a/drivers/net/ethernet/smsc/Kconfig
+++ b/drivers/net/ethernet/smsc/Kconfig
@@ -9,7 +9,7 @@ config NET_VENDOR_SMSC
depends on ARM || ARM64 || ATARI_ETHERNAT || COLDFIRE || \
ISA || MAC || MIPS || NIOS2 || PCI || \
PCMCIA || SUPERH || XTENSA || H8300
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config SMC9194
tristate "SMC 9194 support"
depends on ISA
select CRC32
- ---help---
+ help
This is support for the SMC9xxx based Ethernet cards. Choose this
option if you have a DELL laptop with the docking station, or
another SMC9192/9194 based chipset. Say Y if you want it compiled
@@ -40,7 +40,7 @@ config SMC91X
depends on !OF || GPIOLIB
depends on ARM || ARM64 || ATARI_ETHERNAT || COLDFIRE || \
MIPS || NIOS2 || SUPERH || XTENSA || H8300
- ---help---
+ help
This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it
compiled into the kernel, and read the file
@@ -56,7 +56,7 @@ config PCMCIA_SMC91C92
depends on PCMCIA
select CRC32
select MII
- ---help---
+ help
Say Y here if you intend to attach an SMC 91Cxx compatible PCMCIA
(PC-card) Ethernet or Fast Ethernet card to your computer.
@@ -68,7 +68,7 @@ config EPIC100
depends on PCI
select CRC32
select MII
- ---help---
+ help
This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
which is based on the SMC83c17x (EPIC/100).
More specific information and updates are available from
@@ -79,7 +79,7 @@ config SMC911X
select CRC32
select MII
depends on (ARM || SUPERH)
- ---help---
+ help
This is a driver for SMSC's LAN911x series of Ethernet chipsets
including the new LAN9115, LAN9116, LAN9117, and LAN9118.
Say Y here if you want it compiled into the kernel.
@@ -94,7 +94,7 @@ config SMSC911X
select CRC32
select MII
select PHYLIB
- ---help---
+ help
Say Y here if you want support for SMSC LAN911x and LAN921x families
of ethernet controllers.
@@ -104,7 +104,7 @@ config SMSC911X
config SMSC911X_ARCH_HOOKS
def_bool n
depends on SMSC911X
- ---help---
+ help
If the arch enables this, it allows the arch to implement various
hooks for more comprehensive interrupt control and also to override
the source of the MAC address.
@@ -115,7 +115,7 @@ config SMSC9420
select CRC32
select PHYLIB
select SMSC_PHY
- ---help---
+ help
This is a driver for SMSC's LAN9420 PCI ethernet adapter.
Say Y here if you want it compiled into the kernel.
diff --git a/drivers/net/ethernet/socionext/Kconfig b/drivers/net/ethernet/socionext/Kconfig
index 95e99baf3f45..48298389851d 100644
--- a/drivers/net/ethernet/socionext/Kconfig
+++ b/drivers/net/ethernet/socionext/Kconfig
@@ -2,7 +2,7 @@
config NET_VENDOR_SOCIONEXT
bool "Socionext ethernet drivers"
default y
- ---help---
+ help
Option to select ethernet drivers for Socionext platforms.
Note that the answer to this question doesn't directly affect the
@@ -18,7 +18,7 @@ config SNI_AVE
depends on HAS_IOMEM
select MFD_SYSCON
select PHYLIB
- ---help---
+ help
Driver for gigabit ethernet MACs, called AVE, in the
Socionext UniPhier family.
@@ -28,7 +28,7 @@ config SNI_NETSEC
select PHYLIB
select PAGE_POOL
select MII
- ---help---
+ help
Enable to add support for the SocioNext NetSec Gigabit Ethernet
controller + PHY, as found on the Synquacer SC2A11 SoC
diff --git a/drivers/net/ethernet/stmicro/Kconfig b/drivers/net/ethernet/stmicro/Kconfig
index 39ef86360417..cc136b4c9afd 100644
--- a/drivers/net/ethernet/stmicro/Kconfig
+++ b/drivers/net/ethernet/stmicro/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_STMICRO
bool "STMicroelectronics devices"
default y
depends on HAS_IOMEM
- ---help---
+ help
If you have a network (Ethernet) card based on Synopsys Ethernet IP
Cores, say Y.
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 36bd2e18f23b..9a47c5aec91a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -9,7 +9,7 @@ config STMMAC_ETH
select CRC32
imply PTP_1588_CLOCK
select RESET_CONTROLLER
- ---help---
+ help
This is the driver for the Ethernet IPs built around a
Synopsys IP Core.
@@ -20,7 +20,7 @@ config STMMAC_SELFTESTS
depends on INET
depends on STMMAC_ETH
default n
- ---help---
+ help
This adds support for STMMAC Selftests using ethtool. Enable this
feature if you are facing problems with your HW and submit the test
results to the netdev Mailing List.
@@ -30,7 +30,7 @@ config STMMAC_PLATFORM
depends on STMMAC_ETH
select MFD_SYSCON
default y
- ---help---
+ help
This selects the platform specific bus support for the stmmac driver.
This is the driver used on several SoCs:
STi, Allwinner, Amlogic Meson, Altera SOCFPGA.
@@ -52,7 +52,7 @@ config DWMAC_DWC_QOS_ETH
config DWMAC_GENERIC
tristate "Generic driver for DWMAC"
default STMMAC_PLATFORM
- ---help---
+ help
Generic DWMAC driver for platforms that don't require any
platform specific code to function or is using platform
data for setup.
@@ -84,7 +84,7 @@ config DWMAC_LPC18XX
default ARCH_LPC18XX
depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
select MFD_SYSCON
- ---help---
+ help
Support for NXP LPC18xx/43xx DWMAC Ethernet.
config DWMAC_MEDIATEK
@@ -155,7 +155,7 @@ config DWMAC_STI
default ARCH_STI
depends on OF && (ARCH_STI || COMPILE_TEST)
select MFD_SYSCON
- ---help---
+ help
Support for ethernet controller on STi SOCs.
This selects STi SoC glue layer support for the stmmac
@@ -167,7 +167,7 @@ config DWMAC_STM32
default ARCH_STM32
depends on OF && HAS_IOMEM && (ARCH_STM32 || COMPILE_TEST)
select MFD_SYSCON
- ---help---
+ help
Support for ethernet controller on STM32 SOCs.
This selects STM32 SoC glue layer support for the stmmac
@@ -178,7 +178,7 @@ config DWMAC_SUNXI
tristate "Allwinner GMAC support"
default ARCH_SUNXI
depends on OF && (ARCH_SUNXI || COMPILE_TEST)
- ---help---
+ help
Support for Allwinner A20/A31 GMAC ethernet controllers.
This selects Allwinner SoC glue layer support for the
@@ -190,7 +190,7 @@ config DWMAC_SUN8I
default ARCH_SUNXI
depends on OF && (ARCH_SUNXI || COMPILE_TEST)
select MDIO_BUS_MUX
- ---help---
+ help
Support for Allwinner H3 A83T A64 EMAC ethernet controllers.
This selects Allwinner SoC glue layer support for the
@@ -202,7 +202,7 @@ config DWMAC_IMX8
default ARCH_MXC
depends on OF && (ARCH_MXC || COMPILE_TEST)
select MFD_SYSCON
- ---help---
+ help
Support for ethernet controller on NXP i.MX8 SOCs.
This selects NXP SoC glue layer support for the stmmac
@@ -216,7 +216,7 @@ config DWMAC_INTEL
default X86
depends on X86 && STMMAC_ETH && PCI
depends on COMMON_CLK
- ---help---
+ help
This selects the Intel platform specific bus support for the
stmmac driver. This driver is used for Intel Quark/EHL/TGL.
@@ -224,7 +224,7 @@ config STMMAC_PCI
tristate "STMMAC PCI bus support"
depends on STMMAC_ETH && PCI
depends on COMMON_CLK
- ---help---
+ help
This selects the platform specific bus support for the stmmac driver.
This driver was tested on XLINX XC2V3000 FF1152AMT0221
D1215994A VIRTEX FPGA board and SNPS QoS IPK Prototyping Kit.
diff --git a/drivers/net/ethernet/sun/Kconfig b/drivers/net/ethernet/sun/Kconfig
index 7b982e02ea3a..309de38a7530 100644
--- a/drivers/net/ethernet/sun/Kconfig
+++ b/drivers/net/ethernet/sun/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_SUN
bool "Sun devices"
default y
depends on SUN3 || SBUS || PCI || SUN_LDOMS
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config HAPPYMEAL
tristate "Sun Happy Meal 10/100baseT support"
depends on (SBUS || PCI)
select CRC32
- ---help---
+ help
This driver supports the "hme" interface present on most Ultra
systems and as an option on older Sbus systems. This driver supports
both PCI and Sbus devices. This driver also supports the "qfe" quad
@@ -34,7 +34,7 @@ config SUNBMAC
tristate "Sun BigMAC 10/100baseT support"
depends on SBUS
select CRC32
- ---help---
+ help
This driver supports the "be" interface available as an Sbus option.
This is Sun's older 100baseT Ethernet device.
@@ -45,7 +45,7 @@ config SUNQE
tristate "Sun QuadEthernet support"
depends on SBUS
select CRC32
- ---help---
+ help
This driver supports the "qe" 10baseT Ethernet device, available as
an Sbus option. Note that this is not the same as Quad FastEthernet
"qfe" which is supported by the Happy Meal driver instead.
@@ -58,7 +58,7 @@ config SUNGEM
depends on PCI
select CRC32
select SUNGEM_PHY
- ---help---
+ help
Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also
<http://docs.oracle.com/cd/E19455-01/806-3985-10/806-3985-10.pdf>.
@@ -66,7 +66,7 @@ config CASSINI
tristate "Sun Cassini support"
depends on PCI
select CRC32
- ---help---
+ help
Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
<http://docs.oracle.com/cd/E19113-01/giga.ether.pci/817-4341-10/817-4341-10.pdf>.
@@ -80,7 +80,7 @@ config SUNVNET
default m
depends on SUN_LDOMS
depends on SUNVNET_COMMON
- ---help---
+ help
Support for virtual network devices under Sun Logical Domains.
config LDMVSW
@@ -88,7 +88,7 @@ config LDMVSW
default m
depends on SUN_LDOMS
depends on SUNVNET_COMMON
- ---help---
+ help
Support for virtual switch devices under Sun4v Logical Domains.
This driver adds a network interface for every vsw-port node
found in the machine description of a service domain.
@@ -100,7 +100,7 @@ config NIU
tristate "Sun Neptune 10Gbit Ethernet support"
depends on PCI
select CRC32
- ---help---
+ help
This enables support for cards based upon Sun's
Neptune chipset.
diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
index c5add0b45eed..34fdbc6d6031 100644
--- a/drivers/net/ethernet/sun/sunbmac.c
+++ b/drivers/net/ethernet/sun/sunbmac.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
+#include <linux/pgtable.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -34,7 +35,6 @@
#include <asm/io.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
-#include <asm/pgtable.h>
#include "sunbmac.h"
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index f0fe7bb2a750..54b53dbdb33c 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -52,7 +52,6 @@
#endif
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#ifdef CONFIG_PCI
diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c
index 2102b95ec347..577cd9753d8e 100644
--- a/drivers/net/ethernet/sun/sunqe.c
+++ b/drivers/net/ethernet/sun/sunqe.c
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -36,7 +37,6 @@
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/auxio.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include "sunqe.h"
diff --git a/drivers/net/ethernet/synopsys/Kconfig b/drivers/net/ethernet/synopsys/Kconfig
index 9e199772c1d7..f2a4287c48b8 100644
--- a/drivers/net/ethernet/synopsys/Kconfig
+++ b/drivers/net/ethernet/synopsys/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_SYNOPSYS
bool "Synopsys devices"
default y
- ---help---
+ help
If you have a network (Ethernet) device belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config DWC_XLGMAC
depends on HAS_IOMEM && HAS_DMA
select BITREVERSE
select CRC32
- ---help---
+ help
This driver supports the Synopsys DesignWare Cores Enterprise
Ethernet (dwc-xlgmac).
@@ -30,7 +30,7 @@ if DWC_XLGMAC
config DWC_XLGMAC_PCI
tristate "XLGMAC PCI bus support"
depends on DWC_XLGMAC && PCI
- ---help---
+ help
This selects the pci bus support for the dwc-xlgmac driver.
This driver was tested on Synopsys XLGMAC IP Prototyping Kit.
diff --git a/drivers/net/ethernet/tehuti/Kconfig b/drivers/net/ethernet/tehuti/Kconfig
index 8ad1526f4bdd..8735633765a1 100644
--- a/drivers/net/ethernet/tehuti/Kconfig
+++ b/drivers/net/ethernet/tehuti/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_TEHUTI
bool "Tehuti devices"
default y
depends on PCI
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_TEHUTI
config TEHUTI
tristate "Tehuti Networks 10G Ethernet"
depends on PCI
- ---help---
+ help
Tehuti Networks 10G Ethernet NIC
endif # NET_VENDOR_TEHUTI
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 182d10f171f6..50f55364d4fb 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_TI
bool "Texas Instruments (TI) devices"
default y
depends on PCI || EISA || AR7 || ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config TI_DAVINCI_EMAC
select TI_DAVINCI_MDIO
select PHYLIB
select GENERIC_ALLOCATOR
- ---help---
+ help
This driver supports TI's DaVinci Ethernet .
To compile this driver as a module, choose M here: the module
@@ -33,7 +33,7 @@ config TI_DAVINCI_MDIO
tristate "TI DaVinci MDIO Support"
depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
select PHYLIB
- ---help---
+ help
This driver supports TI's DaVinci MDIO module.
To compile this driver as a module, choose M here: the module
@@ -42,7 +42,7 @@ config TI_DAVINCI_MDIO
config TI_CPSW_PHY_SEL
bool "TI CPSW Phy mode Selection (DEPRECATED)"
default n
- ---help---
+ help
This driver supports configuring of the phy mode connected to
the CPSW. DEPRECATED: use PHY_TI_GMII_SEL.
@@ -55,7 +55,7 @@ config TI_CPSW
select PAGE_POOL
select REGMAP
imply PHY_TI_GMII_SEL
- ---help---
+ help
This driver supports TI's CPSW Ethernet Switch.
To compile this driver as a module, choose M here: the module
@@ -83,7 +83,7 @@ config TI_CPTS
depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST
depends on COMMON_CLK
depends on PTP_1588_CLOCK
- ---help---
+ help
This driver supports the Common Platform Time Sync unit of
the CPSW Ethernet Switch and Keystone 2 1g/10g Switch Subsystem.
The unit can time stamp PTP UDP/IPv4 and Layer 2 packets, and the
@@ -133,7 +133,7 @@ config TI_KEYSTONE_NETCP
depends on OF
depends on KEYSTONE_NAVIGATOR_DMA && KEYSTONE_NAVIGATOR_QMSS
depends on TI_CPTS || !TI_CPTS
- ---help---
+ help
This driver supports TI's Keystone NETCP Core.
To compile this driver as a module, choose M here: the module
@@ -142,7 +142,7 @@ config TI_KEYSTONE_NETCP
config TI_KEYSTONE_NETCP_ETHSS
depends on TI_KEYSTONE_NETCP
tristate "TI Keystone NETCP Ethernet subsystem Support"
- ---help---
+ help
To compile this driver as a module, choose M here: the module
will be called keystone_netcp_ethss.
@@ -150,7 +150,7 @@ config TI_KEYSTONE_NETCP_ETHSS
config TLAN
tristate "TI ThunderLAN support"
depends on (PCI || EISA)
- ---help---
+ help
If you have a PCI Ethernet network card based on the ThunderLAN chip
which is supported by this driver, say Y here.
@@ -168,7 +168,7 @@ config CPMAC
tristate "TI AR7 CPMAC Ethernet support"
depends on AR7
select PHYLIB
- ---help---
+ help
TI AR7 CPMAC Ethernet support
endif # NET_VENDOR_TI
diff --git a/drivers/net/ethernet/toshiba/Kconfig b/drivers/net/ethernet/toshiba/Kconfig
index 9ccdf032404e..701e9b7c1c3b 100644
--- a/drivers/net/ethernet/toshiba/Kconfig
+++ b/drivers/net/ethernet/toshiba/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_TOSHIBA
bool "Toshiba devices"
default y
depends on PCI && (PPC_IBM_CELL_BLADE || MIPS) || PPC_PS3
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -21,7 +21,7 @@ config GELIC_NET
tristate "PS3 Gigabit Ethernet driver"
depends on PPC_PS3
select PS3_SYS_MANAGER
- ---help---
+ help
This driver supports the network device on the PS3 game
console. This driver has built-in support for Ethernet.
@@ -32,7 +32,7 @@ config GELIC_WIRELESS
bool "PS3 Wireless support"
depends on GELIC_NET && WLAN
select WIRELESS_EXT
- ---help---
+ help
This option adds the support for the wireless feature of PS3.
If you have the wireless-less model of PS3 or have no plan to
use wireless feature, disabling this option saves memory. As
@@ -44,7 +44,7 @@ config SPIDER_NET
depends on PCI && PPC_IBM_CELL_BLADE
select FW_LOADER
select SUNGEM_PHY
- ---help---
+ help
This driver supports the Gigabit Ethernet chips present on the
Cell Processor-Based Blades from IBM.
diff --git a/drivers/net/ethernet/tundra/Kconfig b/drivers/net/ethernet/tundra/Kconfig
index 5c909df0c3b9..edd52b2bd135 100644
--- a/drivers/net/ethernet/tundra/Kconfig
+++ b/drivers/net/ethernet/tundra/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_TUNDRA
bool "Tundra devices"
default y
depends on TSI108_BRIDGE
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_TUNDRA
config TSI108_ETH
tristate "Tundra TSI108 gigabit Ethernet support"
depends on TSI108_BRIDGE
- ---help---
+ help
This driver supports Tundra TSI108 gigabit Ethernet ports.
To compile this driver as a module, choose M here: the module
will be called tsi108_eth.
diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig
index 6cff5f7d57c4..da287ef65be7 100644
--- a/drivers/net/ethernet/via/Kconfig
+++ b/drivers/net/ethernet/via/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_VIA
bool "VIA devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config VIA_RHINE
depends on HAS_DMA
select CRC32
select MII
- ---help---
+ help
If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
Ethernet functions can also be found integrated on South Bridges
@@ -35,7 +35,7 @@ config VIA_RHINE
config VIA_RHINE_MMIO
bool "Use MMIO instead of PIO"
depends on VIA_RHINE
- ---help---
+ help
This instructs the driver to use PCI shared memory (MMIO) instead of
programmed I/O ports (PIO). Enabling this gives an improvement in
processing time in parts of the driver.
@@ -49,7 +49,7 @@ config VIA_VELOCITY
select CRC32
select CRC_CCITT
select MII
- ---help---
+ help
If you have a VIA "Velocity" based network card say Y here.
To compile this driver as a module, choose M here. The module
diff --git a/drivers/net/ethernet/wiznet/Kconfig b/drivers/net/ethernet/wiznet/Kconfig
index 0422775e1659..4bac2ad2d6a1 100644
--- a/drivers/net/ethernet/wiznet/Kconfig
+++ b/drivers/net/ethernet/wiznet/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_WIZNET
bool "WIZnet devices"
depends on HAS_IOMEM
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_WIZNET
config WIZNET_W5100
tristate "WIZnet W5100 Ethernet support"
depends on HAS_IOMEM
- ---help---
+ help
Support for WIZnet W5100 chips.
W5100 is a single chip with integrated 10/100 Ethernet MAC,
@@ -33,7 +33,7 @@ config WIZNET_W5100
config WIZNET_W5300
tristate "WIZnet W5300 Ethernet support"
depends on HAS_IOMEM
- ---help---
+ help
Support for WIZnet W5300 chips.
W5300 is a single chip with integrated 10/100 Ethernet MAC,
@@ -50,20 +50,20 @@ choice
config WIZNET_BUS_DIRECT
bool "Direct address bus mode"
- ---help---
+ help
In direct address mode host system can directly access all registers
after mapping to Memory-Mapped I/O space.
config WIZNET_BUS_INDIRECT
bool "Indirect address bus mode"
- ---help---
+ help
In indirect address mode host system indirectly accesses registers
using Indirect Mode Address Register and Indirect Mode Data Register,
which are directly mapped to Memory-Mapped I/O space.
config WIZNET_BUS_ANY
bool "Select interface mode in runtime"
- ---help---
+ help
If interface mode is unknown in compile time, it can be selected
in runtime from board/platform resources configuration.
@@ -74,7 +74,7 @@ config WIZNET_W5100_SPI
tristate "WIZnet W5100/W5200/W5500 Ethernet support for SPI mode"
depends on WIZNET_BUS_ANY && WIZNET_W5100
depends on SPI
- ---help---
+ help
In SPI mode host system accesses registers using SPI protocol
(mode 0) on the SPI bus.
diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
index 0810af8193cb..d0d0d4fe9d40 100644
--- a/drivers/net/ethernet/xilinx/Kconfig
+++ b/drivers/net/ethernet/xilinx/Kconfig
@@ -6,7 +6,7 @@
config NET_VENDOR_XILINX
bool "Xilinx devices"
default y
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,20 +20,20 @@ config XILINX_EMACLITE
tristate "Xilinx 10/100 Ethernet Lite support"
depends on PPC32 || MICROBLAZE || ARCH_ZYNQ || MIPS
select PHYLIB
- ---help---
+ help
This driver supports the 10/100 Ethernet Lite from Xilinx.
config XILINX_AXI_EMAC
tristate "Xilinx 10/100/1000 AXI Ethernet support"
select PHYLINK
- ---help---
+ help
This driver supports the 10/100/1000 Ethernet from Xilinx for the
AXI bus interface used in Xilinx Virtex FPGAs and Soc's.
config XILINX_LL_TEMAC
tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
select PHYLIB
- ---help---
+ help
This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
core used in Xilinx Spartan and Virtex FPGAs
diff --git a/drivers/net/ethernet/xircom/Kconfig b/drivers/net/ethernet/xircom/Kconfig
index ad5390079b13..7497b9bea511 100644
--- a/drivers/net/ethernet/xircom/Kconfig
+++ b/drivers/net/ethernet/xircom/Kconfig
@@ -7,7 +7,7 @@ config NET_VENDOR_XIRCOM
bool "Xircom devices"
default y
depends on PCMCIA
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ if NET_VENDOR_XIRCOM
config PCMCIA_XIRC2PS
tristate "Xircom 16-bit PCMCIA support"
depends on PCMCIA
- ---help---
+ help
Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card)
Ethernet or Fast Ethernet card to your computer.
diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
index 98aa7b8ddb06..7b83a6e5d894 100644
--- a/drivers/net/ethernet/xscale/Kconfig
+++ b/drivers/net/ethernet/xscale/Kconfig
@@ -8,7 +8,7 @@ config NET_VENDOR_XSCALE
default y
depends on NET_VENDOR_INTEL && (ARM && ARCH_IXP4XX && \
IXP4XX_NPE && IXP4XX_QMGR)
- ---help---
+ help
If you have a network (Ethernet) card belonging to this class, say Y.
Note that the answer to this question does not directly affect the
@@ -23,7 +23,7 @@ config IXP4XX_ETH
depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
select PHYLIB
select NET_PTP_CLASSIFY
- ---help---
+ help
Say Y here if you want to use built-in Ethernet ports
on IXP4xx processor.
diff --git a/drivers/net/fddi/Kconfig b/drivers/net/fddi/Kconfig
index da4f58eed08f..60cc7524520c 100644
--- a/drivers/net/fddi/Kconfig
+++ b/drivers/net/fddi/Kconfig
@@ -6,7 +6,7 @@
config FDDI
tristate "FDDI driver support"
depends on PCI || EISA || TC
- ---help---
+ help
Fiber Distributed Data Interface is a high speed local area network
design; essentially a replacement for high speed Ethernet. FDDI can
run over copper or fiber. If you are connected to such a network and
@@ -30,7 +30,7 @@ config DEFZA
config DEFXX
tristate "Digital DEFTA/DEFEA/DEFPA adapter support"
depends on FDDI && (PCI || EISA || TC)
- ---help---
+ help
This is support for the DIGITAL series of TURBOchannel (DEFTA),
EISA (DEFEA) and PCI (DEFPA) controllers which can connect you
to a local FDDI network.
@@ -44,7 +44,7 @@ config DEFXX_MMIO
depends on DEFXX
default n if PCI || EISA
default y
- ---help---
+ help
This instructs the driver to use EISA or PCI memory-mapped I/O
(MMIO) as appropriate instead of programmed I/O ports (PIO).
Enabling this gives an improvement in processing time in parts
@@ -58,7 +58,7 @@ config SKFP
tristate "SysKonnect FDDI PCI support"
depends on FDDI && PCI
select BITREVERSE
- ---help---
+ help
Say Y here if you have a SysKonnect FDDI PCI adapter.
The following adapters are supported by this driver:
- SK-5521 (SK-NET FDDI-UP)
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index f4500f04147d..70f754abbeca 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -3,7 +3,7 @@ config MKISS
tristate "Serial port KISS driver"
depends on AX25 && TTY
select CRC16
- ---help---
+ help
KISS is a protocol used for the exchange of data between a computer
and a Terminal Node Controller (a small embedded system commonly
used for networking over AX.25 amateur radio connections; it
@@ -20,7 +20,7 @@ config MKISS
config 6PACK
tristate "Serial port 6PACK driver"
depends on AX25 && TTY
- ---help---
+ help
6pack is a transmission protocol for the data exchange between your
PC and your TNC (the Terminal Node Controller acts as a kind of
modem connecting your computer's serial port to your radio's
@@ -48,7 +48,7 @@ config BPQETHER
config DMASCC
tristate "High-speed (DMA) SCC driver for AX.25"
depends on ISA && AX25 && BROKEN_ON_SMP && ISA_DMA_API
- ---help---
+ help
This is a driver for high-speed SCC boards, i.e. those supporting
DMA on one port. You usually use those boards to connect your
computer to an amateur radio modem (such as the WA4DSY 56kbps
@@ -81,7 +81,7 @@ config DMASCC
config SCC
tristate "Z8530 SCC driver"
depends on ISA && AX25 && ISA_DMA_API
- ---help---
+ help
These cards are used to connect your Linux box to an amateur radio
in order to communicate with other computers. If you want to use
this, read <file:Documentation/networking/z8530drv.rst> and the
@@ -116,7 +116,7 @@ config BAYCOM_SER_FDX
tristate "BAYCOM ser12 fullduplex driver for AX.25"
depends on AX25 && !S390
select CRC_CCITT
- ---help---
+ help
This is one of two drivers for Baycom style simple amateur radio
modems that connect to a serial interface. The driver supports the
ser12 design in full-duplex mode. In addition, it allows the
@@ -136,7 +136,7 @@ config BAYCOM_SER_HDX
tristate "BAYCOM ser12 halfduplex driver for AX.25"
depends on AX25 && !S390
select CRC_CCITT
- ---help---
+ help
This is one of two drivers for Baycom style simple amateur radio
modems that connect to a serial interface. The driver supports the
ser12 design in half-duplex mode. This is the old driver. It is
@@ -154,7 +154,7 @@ config BAYCOM_PAR
tristate "BAYCOM picpar and par96 driver for AX.25"
depends on PARPORT && AX25
select CRC_CCITT
- ---help---
+ help
This is a driver for Baycom style simple amateur radio modems that
connect to a parallel interface. The driver supports the picpar and
par96 designs. To configure the driver, use the sethdlc utility
@@ -169,7 +169,7 @@ config BAYCOM_EPP
tristate "BAYCOM epp driver for AX.25"
depends on PARPORT && AX25 && !64BIT
select CRC_CCITT
- ---help---
+ help
This is a driver for Baycom style simple amateur radio modems that
connect to a parallel interface. The driver supports the EPP
designs. To configure the driver, use the sethdlc utility available
diff --git a/drivers/net/hippi/Kconfig b/drivers/net/hippi/Kconfig
index de78504a5798..46b911bb8493 100644
--- a/drivers/net/hippi/Kconfig
+++ b/drivers/net/hippi/Kconfig
@@ -6,7 +6,7 @@
config HIPPI
bool "HIPPI driver support"
depends on INET && PCI
- ---help---
+ help
HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
can run over copper (25m) or fiber (300m on multi-mode or 10km on
@@ -21,7 +21,7 @@ if HIPPI
config ROADRUNNER
tristate "Essential RoadRunner HIPPI PCI adapter support"
depends on PCI
- ---help---
+ help
Say Y here if this is your PCI HIPPI network card.
To compile this driver as a module, choose M here: the module
@@ -30,7 +30,7 @@ config ROADRUNNER
config ROADRUNNER_LARGE_RINGS
bool "Use large TX/RX rings"
depends on ROADRUNNER
- ---help---
+ help
If you say Y here, the RoadRunner driver will preallocate up to 2 MB
of additional memory to allow for fastest operation, both for
transmitting and receiving. This memory cannot be used by any other
diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
index c92a62dbf398..0f7c6dc2ed15 100644
--- a/drivers/net/ieee802154/Kconfig
+++ b/drivers/net/ieee802154/Kconfig
@@ -3,7 +3,7 @@ menuconfig IEEE802154_DRIVERS
tristate "IEEE 802.15.4 drivers"
depends on NETDEVICES && IEEE802154
default y
- ---help---
+ help
Say Y here to get to see options for IEEE 802.15.4 Low-Rate
Wireless Personal Area Network device drivers. This option alone
does not add any kernel code.
@@ -14,7 +14,7 @@ menuconfig IEEE802154_DRIVERS
config IEEE802154_FAKELB
depends on IEEE802154_DRIVERS && MAC802154
tristate "IEEE 802.15.4 loopback driver"
- ---help---
+ help
Say Y here to enable the fake driver that can emulate a net
of several interconnected radio devices.
@@ -26,7 +26,7 @@ config IEEE802154_AT86RF230
tristate "AT86RF230/231/233/212 transceiver driver"
depends on SPI
select REGMAP_SPI
- ---help---
+ help
Say Y here to enable the at86rf230/231/233/212 SPI 802.15.4 wireless
controller.
@@ -37,7 +37,7 @@ config IEEE802154_AT86RF230_DEBUGFS
depends on IEEE802154_AT86RF230
bool "AT86RF230 debugfs interface"
depends on DEBUG_FS
- ---help---
+ help
This option compiles debugfs code for the at86rf230 driver.
config IEEE802154_MRF24J40
@@ -45,7 +45,7 @@ config IEEE802154_MRF24J40
depends on IEEE802154_DRIVERS && MAC802154
depends on SPI
select REGMAP_SPI
- ---help---
+ help
Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
controller.
@@ -56,7 +56,7 @@ config IEEE802154_CC2520
depends on IEEE802154_DRIVERS && MAC802154
tristate "CC2520 transceiver driver"
depends on SPI
- ---help---
+ help
Say Y here to enable the CC2520 SPI 802.15.4 wireless
controller.
@@ -66,7 +66,7 @@ config IEEE802154_CC2520
config IEEE802154_ATUSB
tristate "ATUSB transceiver driver"
depends on IEEE802154_DRIVERS && MAC802154 && USB
- ---help---
+ help
Say Y here to enable the ATUSB IEEE 802.15.4 wireless
controller.
@@ -77,7 +77,7 @@ config IEEE802154_ADF7242
tristate "ADF7242 transceiver driver"
depends on IEEE802154_DRIVERS && MAC802154
depends on SPI
- ---help---
+ help
Say Y here to enable the ADF7242 SPI 802.15.4 wireless
controller.
@@ -89,7 +89,7 @@ config IEEE802154_CA8210
depends on IEEE802154_DRIVERS && MAC802154
depends on COMMON_CLK
depends on SPI
- ---help---
+ help
Say Y here to enable the CA8210 SPI 802.15.4 wireless
controller.
@@ -100,7 +100,7 @@ config IEEE802154_CA8210_DEBUGFS
bool "CA8210 debugfs interface"
depends on IEEE802154_CA8210
depends on DEBUG_FS
- ---help---
+ help
This option compiles debugfs code for the ca8210 driver. This
exposes a debugfs node for each CA8210 instance which allows
direct use of the Cascoda API, exposing the 802.15.4 MAC
@@ -110,7 +110,7 @@ config IEEE802154_MCR20A
tristate "MCR20A transceiver driver"
depends on IEEE802154_DRIVERS && MAC802154
depends on SPI
- ---help---
+ help
Say Y here to enable the MCR20A SPI 802.15.4 wireless
controller.
@@ -120,7 +120,7 @@ config IEEE802154_MCR20A
config IEEE802154_HWSIM
depends on IEEE802154_DRIVERS && MAC802154
tristate "Simulated radio testing tool for mac802154"
- ---help---
+ help
This driver is a developer testing tool that can be used to test
IEEE 802.15.4 networking stack (mac802154) functionality. This is not
needed for normal wpan usage and is only for testing.
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 047c27087b10..f25702386d83 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -134,7 +134,7 @@ config MDIO_GPIO
tristate "GPIO lib-based bitbanged MDIO buses"
depends on MDIO_BITBANG
depends on GPIOLIB || COMPILE_TEST
- ---help---
+ help
Supports GPIO lib-based MDIO busses.
To compile this driver as a module, choose M here: the module
@@ -265,7 +265,7 @@ config SWPHY
config LED_TRIGGER_PHY
bool "Support LED triggers for tracking link state"
depends on LEDS_TRIGGERS
- ---help---
+ help
Adds support for a set of LED trigger events per-PHY. Link
state change will trigger the events, for consumption by an
LED class driver. There are triggers for each link speed currently
@@ -298,12 +298,12 @@ config ADIN_PHY
config AMD_PHY
tristate "AMD PHYs"
- ---help---
+ help
Currently supports the am79c874
config AQUANTIA_PHY
tristate "Aquantia PHYs"
- ---help---
+ help
Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
config AX88796B_PHY
@@ -316,13 +316,13 @@ config BCM63XX_PHY
tristate "Broadcom 63xx SOCs internal PHY"
depends on BCM63XX || COMPILE_TEST
select BCM_NET_PHYLIB
- ---help---
+ help
Currently supports the 6348 and 6358 PHYs.
config BCM7XXX_PHY
tristate "Broadcom 7xxx SOCs internal PHYs"
select BCM_NET_PHYLIB
- ---help---
+ help
Currently supports the BCM7366, BCM7439, BCM7445, and
40nm and 65nm generation of BCM7xxx Set Top Box SoCs.
@@ -336,7 +336,7 @@ config BCM_CYGNUS_PHY
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on MDIO_BCM_IPROC
select BCM_NET_PHYLIB
- ---help---
+ help
This PHY driver is for the 1G internal PHYs of the Broadcom
Cygnus and Omega Family SoC.
@@ -350,7 +350,7 @@ config BCM_NET_PHYLIB
config BROADCOM_PHY
tristate "Broadcom PHYs"
select BCM_NET_PHYLIB
- ---help---
+ help
Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
BCM5481, BCM54810 and BCM5482 PHYs.
@@ -368,48 +368,48 @@ config BCM54140_PHY
config BCM84881_PHY
tristate "Broadcom BCM84881 PHY"
depends on PHYLIB
- ---help---
+ help
Support the Broadcom BCM84881 PHY.
config CICADA_PHY
tristate "Cicada PHYs"
- ---help---
+ help
Currently supports the cis8204
config CORTINA_PHY
tristate "Cortina EDC CDR 10G Ethernet PHY"
- ---help---
+ help
Currently supports the CS4340 phy.
config DAVICOM_PHY
tristate "Davicom PHYs"
- ---help---
+ help
Currently supports dm9161e and dm9131
config DP83822_PHY
tristate "Texas Instruments DP83822/825/826 PHYs"
- ---help---
+ help
Supports the DP83822, DP83825I, DP83825CM, DP83825CS, DP83825S,
DP83826C and DP83826NC PHYs.
config DP83TC811_PHY
tristate "Texas Instruments DP83TC811 PHY"
- ---help---
+ help
Supports the DP83TC811 PHY.
config DP83848_PHY
tristate "Texas Instruments DP83848 PHY"
- ---help---
+ help
Supports the DP83848 PHY.
config DP83867_PHY
tristate "Texas Instruments DP83867 Gigabit PHY"
- ---help---
+ help
Currently supports the DP83867 PHY.
config DP83869_PHY
tristate "Texas Instruments DP83869 Gigabit PHY"
- ---help---
+ help
Currently supports the DP83869 PHY. This PHY supports copper and
fiber connections.
@@ -417,7 +417,7 @@ config FIXED_PHY
tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB
select SWPHY
- ---help---
+ help
Adds the platform "fixed" MDIO Bus to cover the boards that use
PHYs that are not connected to the real MDIO bus.
@@ -425,12 +425,12 @@ config FIXED_PHY
config ICPLUS_PHY
tristate "ICPlus PHYs"
- ---help---
+ help
Currently supports the IP175C and IP1001 PHYs.
config INTEL_XWAY_PHY
tristate "Intel XWAY PHYs"
- ---help---
+ help
Supports the Intel XWAY (former Lantiq) 11G and 22E PHYs.
These PHYs are marked as standalone chips under the names
PEF 7061, PEF 7071 and PEF 7072 or integrated into the Intel
@@ -438,33 +438,33 @@ config INTEL_XWAY_PHY
config LSI_ET1011C_PHY
tristate "LSI ET1011C PHY"
- ---help---
+ help
Supports the LSI ET1011C PHY.
config LXT_PHY
tristate "Intel LXT PHYs"
- ---help---
+ help
Currently supports the lxt970, lxt971
config MARVELL_PHY
tristate "Marvell PHYs"
- ---help---
+ help
Currently has a driver for the 88E1011S
config MARVELL_10G_PHY
tristate "Marvell Alaska 10Gbit PHYs"
- ---help---
+ help
Support for the Marvell Alaska MV88X3310 and compatible PHYs.
config MESON_GXL_PHY
tristate "Amlogic Meson GXL Internal PHY"
depends on ARCH_MESON || COMPILE_TEST
- ---help---
+ help
Currently has a driver for the Amlogic Meson GXL Internal PHY
config MICREL_PHY
tristate "Micrel PHYs"
- ---help---
+ help
Supports the KSZ9021, VSC8201, KS8001 PHYs.
config MICROCHIP_PHY
@@ -474,7 +474,7 @@ config MICROCHIP_PHY
config MICROCHIP_T1_PHY
tristate "Microchip T1 PHYs"
- ---help---
+ help
Supports the LAN87XX PHYs.
config MICROSEMI_PHY
@@ -482,18 +482,18 @@ config MICROSEMI_PHY
depends on MACSEC || MACSEC=n
select CRYPTO_AES
select CRYPTO_ECB
- ---help---
+ help
Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs
config NATIONAL_PHY
tristate "National Semiconductor PHYs"
- ---help---
+ help
Currently supports the DP83865 PHY.
config NXP_TJA11XX_PHY
tristate "NXP TJA11xx PHYs support"
depends on HWMON
- ---help---
+ help
Currently supports the NXP TJA1100 and TJA1101 PHY.
config AT803X_PHY
@@ -504,47 +504,47 @@ config AT803X_PHY
config QSEMI_PHY
tristate "Quality Semiconductor PHYs"
- ---help---
+ help
Currently supports the qs6612
config REALTEK_PHY
tristate "Realtek PHYs"
- ---help---
+ help
Supports the Realtek 821x PHY.
config RENESAS_PHY
tristate "Driver for Renesas PHYs"
- ---help---
+ help
Supports the Renesas PHYs uPD60620 and uPD60620A.
config ROCKCHIP_PHY
tristate "Driver for Rockchip Ethernet PHYs"
- ---help---
+ help
Currently supports the integrated Ethernet PHY.
config SMSC_PHY
tristate "SMSC PHYs"
- ---help---
+ help
Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
config STE10XP
tristate "STMicroelectronics STe10Xp PHYs"
- ---help---
+ help
This is the driver for the STe100p and STe101p PHYs.
config TERANETICS_PHY
tristate "Teranetics PHYs"
- ---help---
+ help
Currently supports the Teranetics TN2020
config VITESSE_PHY
tristate "Vitesse PHYs"
- ---help---
+ help
Currently supports the vsc8244
config XILINX_GMII2RGMII
tristate "Xilinx GMII2RGMII converter driver"
- ---help---
+ help
This driver support xilinx GMII to RGMII IP core it provides
the Reduced Gigabit Media Independent Interface(RGMII) between
Ethernet physical media devices and the Gigabit Ethernet controller.
diff --git a/drivers/net/plip/Kconfig b/drivers/net/plip/Kconfig
index e03556d1d0c2..67bfb01de6f7 100644
--- a/drivers/net/plip/Kconfig
+++ b/drivers/net/plip/Kconfig
@@ -6,7 +6,7 @@
config PLIP
tristate "PLIP (parallel port) support"
depends on PARPORT
- ---help---
+ help
PLIP (Parallel Line Internet Protocol) is used to create a
reasonably fast mini network consisting of two (or, rarely, more)
local machines. A PLIP link from a Linux box is a popular means to
diff --git a/drivers/net/ppp/Kconfig b/drivers/net/ppp/Kconfig
index 1a2e2f7629f3..ac4d162d9455 100644
--- a/drivers/net/ppp/Kconfig
+++ b/drivers/net/ppp/Kconfig
@@ -6,7 +6,7 @@
config PPP
tristate "PPP (point-to-point protocol) support"
select SLHC
- ---help---
+ help
PPP (Point to Point Protocol) is a newer and better SLIP. It serves
the same purpose: sending Internet traffic over telephone (and other
serial) lines. Ask your access provider if they support it, because
@@ -38,7 +38,7 @@ if PPP
config PPP_BSDCOMP
tristate "PPP BSD-Compress compression"
depends on PPP
- ---help---
+ help
Support for the BSD-Compress compression method for PPP, which uses
the LZW compression method to compress each PPP packet before it is
sent over the wire. The machine at the other end of the PPP link
@@ -59,7 +59,7 @@ config PPP_DEFLATE
depends on PPP
select ZLIB_INFLATE
select ZLIB_DEFLATE
- ---help---
+ help
Support for the Deflate compression method for PPP, which uses the
Deflate algorithm (the same algorithm that gzip uses) to compress
each PPP packet before it is sent over the wire. The machine at the
@@ -72,7 +72,7 @@ config PPP_DEFLATE
config PPP_FILTER
bool "PPP filtering"
depends on PPP
- ---help---
+ help
Say Y here if you want to be able to filter the packets passing over
PPP interfaces. This allows you to control which packets count as
activity (i.e. which packets will reset the idle timer or bring up
@@ -88,7 +88,7 @@ config PPP_MPPE
select CRYPTO
select CRYPTO_SHA1
select CRYPTO_LIB_ARC4
- ---help---
+ help
Support for the MPPE Encryption protocol, as employed by the
Microsoft Point-to-Point Tunneling Protocol.
@@ -98,7 +98,7 @@ config PPP_MPPE
config PPP_MULTILINK
bool "PPP multilink support"
depends on PPP
- ---help---
+ help
PPP multilink is a protocol (defined in RFC 1990) which allows you
to combine several (logical or physical) lines into one logical PPP
connection, so that you can utilize your full bandwidth.
@@ -111,7 +111,7 @@ config PPP_MULTILINK
config PPPOATM
tristate "PPP over ATM"
depends on ATM && PPP
- ---help---
+ help
Support PPP (Point to Point Protocol) encapsulated in ATM frames.
This implementation does not yet comply with section 8 of RFC2364,
which can lead to bad results if the ATM peer loses state and
@@ -120,7 +120,7 @@ config PPPOATM
config PPPOE
tristate "PPP over Ethernet"
depends on PPP
- ---help---
+ help
Support for PPP over Ethernet.
This driver requires the latest version of pppd from the CVS
@@ -132,7 +132,7 @@ config PPPOE
config PPTP
tristate "PPP over IPv4 (PPTP)"
depends on PPP && NET_IPGRE_DEMUX
- ---help---
+ help
Support for PPP over IPv4.(Point-to-Point Tunneling Protocol)
This driver requires pppd plugin to work in client mode or
@@ -143,7 +143,7 @@ config PPTP
config PPPOL2TP
tristate "PPP over L2TP"
depends on L2TP && PPP
- ---help---
+ help
Support for PPP-over-L2TP socket family. L2TP is a protocol
used by ISPs and enterprises to tunnel PPP traffic over UDP
tunnels. L2TP is replacing PPTP for VPN uses.
@@ -153,7 +153,7 @@ config PPP_ASYNC
tristate "PPP support for async serial ports"
depends on PPP
select CRC_CCITT
- ---help---
+ help
Say Y (or M) here if you want to be able to use PPP over standard
asynchronous serial ports, such as COM1 or COM2 on a PC. If you use
a modem (not a synchronous or ISDN modem) to contact your ISP, you
@@ -166,7 +166,7 @@ config PPP_ASYNC
config PPP_SYNC_TTY
tristate "PPP support for sync tty ports"
depends on PPP
- ---help---
+ help
Say Y (or M) here if you want to be able to use PPP over synchronous
(HDLC) tty devices, such as the SyncLink adapter. These devices
are often used for high-speed leased lines like T1/E1.
diff --git a/drivers/net/slip/Kconfig b/drivers/net/slip/Kconfig
index 30bbafb0e3c7..ea68fc15c945 100644
--- a/drivers/net/slip/Kconfig
+++ b/drivers/net/slip/Kconfig
@@ -6,7 +6,7 @@
config SLIP
tristate "SLIP (serial line) support"
depends on TTY
- ---help---
+ help
Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
connect to your Internet service provider or to connect to some
other local Unix box or if you want to configure your Linux box as a
@@ -36,7 +36,7 @@ config SLIP
config SLHC
tristate
- ---help---
+ help
This option enables Van Jacobsen serial line header compression
routines.
@@ -46,7 +46,7 @@ config SLIP_COMPRESSED
bool "CSLIP compressed headers"
depends on SLIP
select SLHC
- ---help---
+ help
This protocol is faster than SLIP because it uses compression on the
TCP/IP headers (not on the data itself), but it has to be supported
on both ends. Ask your access provider if you are not sure and
@@ -61,7 +61,7 @@ config SLIP_COMPRESSED
config SLIP_SMART
bool "Keepalive and linefill"
depends on SLIP
- ---help---
+ help
Adds additional capabilities to the SLIP driver to support the
RELCOM line fill and keepalive monitoring. Ideal on poor quality
analogue lines.
@@ -69,7 +69,7 @@ config SLIP_SMART
config SLIP_MODE_SLIP6
bool "Six bit SLIP encapsulation"
depends on SLIP
- ---help---
+ help
Just occasionally you may need to run IP over hostile serial
networks that don't pass all control characters or are only seven
bit. Saying Y here adds an extra mode you can use with SLIP:
diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
index 2aa9fd7b57df..4d449845dac7 100644
--- a/drivers/net/team/Kconfig
+++ b/drivers/net/team/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig NET_TEAM
tristate "Ethernet team driver support"
- ---help---
+ help
This allows one to create virtual interfaces that teams together
multiple ethernet devices.
@@ -18,7 +18,7 @@ if NET_TEAM
config NET_TEAM_MODE_BROADCAST
tristate "Broadcast mode support"
depends on NET_TEAM
- ---help---
+ help
Basic mode where packets are transmitted always by all suitable ports.
All added ports are setup to have team's device address.
@@ -29,7 +29,7 @@ config NET_TEAM_MODE_BROADCAST
config NET_TEAM_MODE_ROUNDROBIN
tristate "Round-robin mode support"
depends on NET_TEAM
- ---help---
+ help
Basic mode where port used for transmitting packets is selected in
round-robin fashion using packet counter.
@@ -41,7 +41,7 @@ config NET_TEAM_MODE_ROUNDROBIN
config NET_TEAM_MODE_RANDOM
tristate "Random mode support"
depends on NET_TEAM
- ---help---
+ help
Basic mode where port used for transmitting packets is selected
randomly.
@@ -53,7 +53,7 @@ config NET_TEAM_MODE_RANDOM
config NET_TEAM_MODE_ACTIVEBACKUP
tristate "Active-backup mode support"
depends on NET_TEAM
- ---help---
+ help
Only one port is active at a time and the rest of ports are used
for backup.
@@ -66,7 +66,7 @@ config NET_TEAM_MODE_ACTIVEBACKUP
config NET_TEAM_MODE_LOADBALANCE
tristate "Load-balance mode support"
depends on NET_TEAM
- ---help---
+ help
This mode provides load balancing functionality. Tx port selection
is done using BPF function set up from userspace (bpf_hash_func
option)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 05bdcc5917f6..a7fbc3ccd29e 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -15,7 +15,7 @@ if USB_NET_DRIVERS
config USB_CATC
tristate "USB CATC NetMate-based Ethernet device support"
select CRC32
- ---help---
+ help
Say Y if you want to use one of the following 10Mbps USB Ethernet
device based on the EL1210A chip. Supported devices are:
Belkin F5U011
@@ -33,7 +33,7 @@ config USB_CATC
config USB_KAWETH
tristate "USB KLSI KL5USB101-based ethernet device support"
- ---help---
+ help
Say Y here if you want to use one of the following 10Mbps only
USB Ethernet adapters based on the KLSI KL5KUSB101B chipset:
3Com 3C19250
@@ -73,7 +73,7 @@ config USB_KAWETH
config USB_PEGASUS
tristate "USB Pegasus/Pegasus-II based ethernet device support"
select MII
- ---help---
+ help
Say Y here if you know you have Pegasus or Pegasus-II based adapter.
If in doubt then look at <file:drivers/net/usb/pegasus.h> for the
complete list of supported devices.
@@ -128,7 +128,7 @@ config USB_LAN78XX
config USB_USBNET
tristate "Multi-purpose USB Networking Framework"
select MII
- ---help---
+ help
This driver supports several kinds of network links over USB,
with "minidrivers" built around a common network driver core
that supports deep queues for efficient transfers. (This gives
@@ -321,7 +321,7 @@ config USB_NET_SR9800
tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices"
depends on USB_USBNET
select CRC32
- ---help---
+ help
Say Y if you want to use one of the following 100Mbps USB Ethernet
device based on the CoreChip-sz SR9800 chip.
@@ -570,7 +570,7 @@ config USB_CDC_PHONET
config USB_IPHETH
tristate "Apple iPhone USB Ethernet driver"
default n
- ---help---
+ help
Module used to share Internet connection (tethering) from your
iPhone (Original, 3G and 3GS) to your system.
Note that you need userspace libraries and programs that are needed
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 3e21726c36e8..39e5ab261d7c 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -5,7 +5,7 @@
menuconfig WAN
bool "Wan interfaces support"
- ---help---
+ help
Wide Area Networks (WANs), such as X.25, Frame Relay and leased
lines, are used to interconnect Local Area Networks (LANs) over vast
distances with data transfer rates significantly higher than those
@@ -39,7 +39,7 @@ config HOSTESS_SV11
config COSA
tristate "COSA/SRP sync serial boards support"
depends on ISA && m && ISA_DMA_API && HDLC && VIRT_TO_BUS
- ---help---
+ help
Driver for COSA and SRP synchronous serial boards.
These boards allow to connect synchronous serial devices (for example
@@ -63,7 +63,7 @@ config COSA
config LANMEDIA
tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
depends on PCI && VIRT_TO_BUS && HDLC
- ---help---
+ help
Driver for the following Lan Media family of serial boards:
- LMC 1000 board allows you to connect synchronous serial devices
@@ -251,7 +251,7 @@ config C101
config FARSYNC
tristate "FarSync T-Series support"
depends on HDLC && PCI
- ---help---
+ help
Support for the FarSync T-Series X.21 (and V.35/V.24) cards by
FarSite Communications Ltd.
@@ -323,7 +323,7 @@ config IXP4XX_HSS
config DLCI
tristate "Frame Relay DLCI support"
- ---help---
+ help
Support for the Frame Relay protocol.
Frame Relay is a fast low-cost way to connect to a remote Internet
@@ -370,7 +370,7 @@ config SDLA
config LAPBETHER
tristate "LAPB over Ethernet driver"
depends on LAPB && X25
- ---help---
+ help
Driver for a pseudo device (typically called /dev/lapb0) which allows
you to open an LAPB point-to-point connection to some other computer
on your Ethernet network.
@@ -386,7 +386,7 @@ config LAPBETHER
config X25_ASY
tristate "X.25 async driver"
depends on LAPB && X25 && TTY
- ---help---
+ help
Send and receive X.25 frames over regular asynchronous serial
lines such as telephone lines equipped with ordinary modems.
@@ -401,7 +401,7 @@ config X25_ASY
config SBNI
tristate "Granch SBNI12 Leased Line adapter support"
depends on X86
- ---help---
+ help
Driver for ISA SBNI12-xx cards which are low cost alternatives to
leased line modems.
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 15b0ad171f4c..8ab62bb6b853 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -9,7 +9,7 @@ menuconfig WLAN
depends on NET
select WIRELESS
default y
- ---help---
+ help
This section contains all the pre 802.11 and 802.11 wireless
device drivers. For a complete list of drivers and documentation
on them refer to the wireless wiki:
@@ -54,7 +54,7 @@ config PCMCIA_RAYCS
select WIRELESS_EXT
select WEXT_SPY
select WEXT_PRIV
- ---help---
+ help
Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
(PC-card) wireless Ethernet networking card to your computer.
Please read the file <file:Documentation/networking/ray_cs.rst> for
@@ -76,7 +76,7 @@ config PCMCIA_WL3501
config MAC80211_HWSIM
tristate "Simulated radio testing tool for mac80211"
depends on MAC80211
- ---help---
+ help
This driver is a developer testing tool that can be used to test
IEEE 802.11 networking stack (mac80211) functionality. This is not
needed for normal wireless LAN usage and is only for testing. See
@@ -94,7 +94,7 @@ config USB_NET_RNDIS_WLAN
select USB_USBNET
select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST
- ---help---
+ help
This is a driver for wireless RNDIS devices.
These are USB based adapters found in devices such as:
@@ -118,7 +118,7 @@ config USB_NET_RNDIS_WLAN
config VIRT_WIFI
tristate "Wifi wrapper for ethernet drivers"
depends on CFG80211
- ---help---
+ help
This option adds support for ethernet connections to appear as if they
are wifi connections through a special rtnetlink device.
diff --git a/drivers/net/wireless/admtek/Kconfig b/drivers/net/wireless/admtek/Kconfig
index a91cc1459c96..678979a1d987 100644
--- a/drivers/net/wireless/admtek/Kconfig
+++ b/drivers/net/wireless/admtek/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_ADMTEK
bool "ADMtek devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -17,7 +17,7 @@ config ADM8211
depends on MAC80211 && PCI
select CRC32
select EEPROM_93CX6
- ---help---
+ help
This driver is for ADM8211A, ADM8211B, and ADM8211C based cards.
These are PCI/mini-PCI/Cardbus 802.11b chips found in cards such as:
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index b10972b6cba4..6e9d46b96555 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -5,7 +5,7 @@ config ATH_COMMON
config WLAN_VENDOR_ATH
bool "Atheros/Qualcomm devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -25,7 +25,7 @@ if WLAN_VENDOR_ATH
config ATH_DEBUG
bool "Atheros wireless debugging"
- ---help---
+ help
Say Y, if you want to debug atheros wireless drivers.
Right now only ath9k makes use of this.
@@ -33,7 +33,7 @@ config ATH_TRACEPOINTS
bool "Atheros wireless tracing"
depends on ATH_DEBUG
depends on EVENT_TRACING
- ---help---
+ help
This option enables tracepoints for atheros wireless drivers.
Currently, ath9k makes use of this facility.
@@ -41,7 +41,7 @@ config ATH_REG_DYNAMIC_USER_REG_HINTS
bool "Atheros dynamic user regulatory hints"
depends on CFG80211_CERTIFICATION_ONUS
default n
- ---help---
+ help
Say N. This should only be enabled in countries where
this feature is explicitly allowed and only on cards that
specifically have been tested for this.
@@ -50,7 +50,7 @@ config ATH_REG_DYNAMIC_USER_CERT_TESTING
bool "Atheros dynamic user regulatory testing"
depends on ATH_REG_DYNAMIC_USER_REG_HINTS && CFG80211_CERTIFICATION_ONUS
default n
- ---help---
+ help
Say N. This should only be enabled on systems
undergoing certification testing.
diff --git a/drivers/net/wireless/ath/ar5523/Kconfig b/drivers/net/wireless/ath/ar5523/Kconfig
index e82df5f1ea67..0d838c1e7b12 100644
--- a/drivers/net/wireless/ath/ar5523/Kconfig
+++ b/drivers/net/wireless/ath/ar5523/Kconfig
@@ -4,6 +4,6 @@ config AR5523
depends on MAC80211 && USB
select ATH_COMMON
select FW_LOADER
- ---help---
+ help
This module add support for AR5523 based USB dongles such as D-Link
DWL-G132, Netgear WPN111 and many more.
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index b99fd0eff994..40f91bc8514d 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -6,7 +6,7 @@ config ATH10K
select CRC32
select WANT_DEV_COREDUMP
select ATH10K_CE
- ---help---
+ help
This module adds support for wireless adapters based on
Atheros IEEE 802.11ac family of chipsets.
@@ -18,25 +18,25 @@ config ATH10K_CE
config ATH10K_PCI
tristate "Atheros ath10k PCI support"
depends on ATH10K && PCI
- ---help---
+ help
This module adds support for PCIE bus
config ATH10K_AHB
bool "Atheros ath10k AHB support"
depends on ATH10K_PCI && OF && RESET_CONTROLLER
- ---help---
+ help
This module adds support for AHB bus
config ATH10K_SDIO
tristate "Atheros ath10k SDIO support"
depends on ATH10K && MMC
- ---help---
+ help
This module adds support for SDIO/MMC bus.
config ATH10K_USB
tristate "Atheros ath10k USB support (EXPERIMENTAL)"
depends on ATH10K && USB
- ---help---
+ help
This module adds experimental support for USB bus. Currently
work in progress and will not fully work.
@@ -45,14 +45,14 @@ config ATH10K_SNOC
depends on ATH10K
depends on ARCH_QCOM || COMPILE_TEST
select QCOM_QMI_HELPERS
- ---help---
+ help
This module adds support for integrated WCN3990 chip connected
to system NOC(SNOC).
config ATH10K_DEBUG
bool "Atheros ath10k debugging"
depends on ATH10K
- ---help---
+ help
Enables debug support
If unsure, say Y to make it easier to debug problems.
@@ -60,7 +60,7 @@ config ATH10K_DEBUG
config ATH10K_DEBUGFS
bool "Atheros ath10k debugfs support"
depends on ATH10K && DEBUG_FS
- ---help---
+ help
Enabled debugfs support
If unsure, say Y to make it easier to debug problems.
@@ -70,20 +70,20 @@ config ATH10K_SPECTRAL
depends on ATH10K_DEBUGFS
select RELAY
default n
- ---help---
+ help
Say Y to enable access to the FFT/spectral data via debugfs.
config ATH10K_TRACING
bool "Atheros ath10k tracing support"
depends on ATH10K
depends on EVENT_TRACING
- ---help---
+ help
Select this to ath10k use tracing infrastructure.
config ATH10K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
default n
- ---help---
+ help
This option enables DFS support for initiating radiation on
ath10k.
diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig
index 738f99090d83..7acb42e2e6e2 100644
--- a/drivers/net/wireless/ath/ath11k/Kconfig
+++ b/drivers/net/wireless/ath/ath11k/Kconfig
@@ -7,7 +7,7 @@ config ATH11K
depends on ARCH_QCOM || COMPILE_TEST
select ATH_COMMON
select QCOM_QMI_HELPERS
- ---help---
+ help
This module adds support for Qualcomm Technologies 802.11ax family of
chipsets.
@@ -16,7 +16,7 @@ config ATH11K
config ATH11K_DEBUG
bool "QCA ath11k debugging"
depends on ATH11K
- ---help---
+ help
Enables debug support
If unsure, say Y to make it easier to debug problems.
@@ -24,7 +24,7 @@ config ATH11K_DEBUG
config ATH11K_DEBUGFS
bool "QCA ath11k debugfs support"
depends on ATH11K && DEBUG_FS && MAC80211_DEBUGFS
- ---help---
+ help
Enable ath11k debugfs support
If unsure, say Y to make it easier to debug problems.
@@ -32,5 +32,5 @@ config ATH11K_DEBUGFS
config ATH11K_TRACING
bool "ath11k tracing support"
depends on ATH11K && EVENT_TRACING
- ---help---
+ help
Select this to use ath11k tracing infrastructure.
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 96010d4b00e7..f35cd8de228e 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -8,7 +8,7 @@ config ATH5K
select NEW_LEDS
select ATH5K_AHB if ATH25
select ATH5K_PCI if !ATH25
- ---help---
+ help
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
@@ -25,7 +25,7 @@ config ATH5K
config ATH5K_DEBUG
bool "Atheros 5xxx debugging"
depends on ATH5K
- ---help---
+ help
Atheros 5xxx debugging messages.
Say Y, if and you will get debug options for ath5k.
@@ -45,7 +45,7 @@ config ATH5K_TRACER
bool "Atheros 5xxx tracer"
depends on ATH5K
depends on EVENT_TRACING
- ---help---
+ help
Say Y here to enable tracepoints for the ath5k driver
using the kernel tracing infrastructure. Select this
option if you are interested in debugging the driver.
@@ -55,21 +55,21 @@ config ATH5K_TRACER
config ATH5K_AHB
bool "Atheros 5xxx AHB bus support"
depends on ATH25 && ATH5K
- ---help---
+ help
This adds support for WiSoC type chipsets of the 5xxx Atheros
family.
config ATH5K_PCI
bool "Atheros 5xxx PCI bus support"
depends on (!ATH25 && PCI)
- ---help---
+ help
This adds support for PCI type chipsets of the 5xxx Atheros
family.
config ATH5K_TEST_CHANNELS
bool "Enables testing channels on ath5k"
depends on ATH5K && CFG80211_CERTIFICATION_ONUS
- ---help---
+ help
This enables non-standard IEEE 802.11 channels on ath5k, which
can be used for research purposes. This option should be disabled
unless doing research.
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index 62c22fdcca38..cd96cf8d9940 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -2,7 +2,7 @@
config ATH6KL
tristate "Atheros mobile chipsets support"
depends on CFG80211
- ---help---
+ help
This module adds core support for wireless adapters based on
Atheros AR6003 and AR6004 chipsets. You still need separate
bus drivers for USB and SDIO to be able to use real devices.
@@ -15,7 +15,7 @@ config ATH6KL_SDIO
tristate "Atheros ath6kl SDIO support"
depends on ATH6KL
depends on MMC
- ---help---
+ help
This module adds support for wireless adapters based on
Atheros AR6003 and AR6004 chipsets running over SDIO. If you
choose to build it as a module, it will be called ath6kl_sdio.
@@ -26,7 +26,7 @@ config ATH6KL_USB
tristate "Atheros ath6kl USB support"
depends on ATH6KL
depends on USB
- ---help---
+ help
This module adds support for wireless adapters based on
Atheros AR6004 chipset and chipsets based on it running over
USB. If you choose to build it as a module, it will be
@@ -35,7 +35,7 @@ config ATH6KL_USB
config ATH6KL_DEBUG
bool "Atheros ath6kl debugging"
depends on ATH6KL
- ---help---
+ help
Enables ath6kl debug support, including debug messages
enabled with debug_mask module parameter and debugfs
interface.
@@ -46,7 +46,7 @@ config ATH6KL_TRACING
bool "Atheros ath6kl tracing support"
depends on ATH6KL
depends on EVENT_TRACING
- ---help---
+ help
Select this to ath6kl use tracing infrastructure which, for
example, can be enabled with help of trace-cmd. All debug
messages and commands are delivered to using individually
@@ -58,7 +58,7 @@ config ATH6KL_REGDOMAIN
bool "Atheros ath6kl regdomain support"
depends on ATH6KL
depends on CFG80211_CERTIFICATION_ONUS
- ---help---
+ help
Enabling this makes it possible to change the regdomain in
the firmware. This can be only enabled if regulatory requirements
are taken into account.
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 78620c6b64a2..42bfdb4a6214 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -14,7 +14,7 @@ config ATH9K_BTCOEX_SUPPORT
bool "Atheros bluetooth coexistence support"
depends on (ATH9K || ATH9K_HTC)
default y
- ---help---
+ help
Say Y, if you want to use the ath9k/ath9k_htc radios together with
Bluetooth modules in the same system.
@@ -26,7 +26,7 @@ config ATH9K
select LEDS_CLASS
select NEW_LEDS
select ATH9K_COMMON
- ---help---
+ help
This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
of chipsets. For a specific list of supported external
@@ -42,7 +42,7 @@ config ATH9K_PCI
bool "Atheros ath9k PCI/PCIe bus support"
default y
depends on ATH9K && PCI
- ---help---
+ help
This option enables the PCI bus support in ath9k.
Say Y, if you have a compatible PCI/PCIe wireless card.
@@ -51,7 +51,7 @@ config ATH9K_AHB
bool "Atheros ath9k AHB bus support"
depends on ATH9K
default n
- ---help---
+ help
This option enables the AHB bus support in ath9k.
Say Y, if you have a SoC with a compatible built-in
@@ -62,7 +62,7 @@ config ATH9K_DEBUGFS
depends on ATH9K && DEBUG_FS
select MAC80211_DEBUGFS
select ATH9K_COMMON_DEBUG
- ---help---
+ help
Say Y, if you need access to ath9k's statistics for
interrupts, rate control, etc.
@@ -74,14 +74,14 @@ config ATH9K_STATION_STATISTICS
depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS
select MAC80211_DEBUGFS
default n
- ---help---
+ help
This option enables detailed statistics for association stations.
config ATH9K_TX99
bool "Atheros ath9k TX99 testing support"
depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS
default n
- ---help---
+ help
Say N. This should only be enabled on systems undergoing
certification testing and evaluation in a controlled environment.
Enabling this will only enable TX99 support, all other modes of
@@ -101,7 +101,7 @@ config ATH9K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH9K && CFG80211_CERTIFICATION_ONUS
default n
- ---help---
+ help
This option enables DFS support for initiating radiation on
ath9k. There is no way to dynamically detect if a card was DFS
certified and as such this is left as a build time option. This
@@ -120,7 +120,7 @@ config ATH9K_DYNACK
bool "Atheros ath9k ACK timeout estimation algorithm"
depends on ATH9K
default n
- ---help---
+ help
This option enables ath9k dynamic ACK timeout estimation algorithm
based on ACK frame RX timestamp, TX frame timestamp and frame
duration
@@ -129,7 +129,7 @@ config ATH9K_WOW
bool "Wake on Wireless LAN support (EXPERIMENTAL)"
depends on ATH9K && PM
default n
- ---help---
+ help
This option enables Wake on Wireless LAN support for certain cards.
Currently, AR9462 is supported.
@@ -147,7 +147,7 @@ config ATH9K_CHANNEL_CONTEXT
bool "Channel Context support"
depends on ATH9K
default n
- ---help---
+ help
This option enables channel context support in ath9k, which is needed
for multi-channel concurrency. Enable this if P2P PowerSave support
is required.
@@ -181,7 +181,7 @@ config ATH9K_HTC
select LEDS_CLASS
select NEW_LEDS
select ATH9K_COMMON
- ---help---
+ help
Support for Atheros HTC based cards.
Chipsets supported: AR9271
@@ -193,7 +193,7 @@ config ATH9K_HTC_DEBUGFS
bool "Atheros ath9k_htc debugging"
depends on ATH9K_HTC && DEBUG_FS
select ATH9K_COMMON_DEBUG
- ---help---
+ help
Say Y, if you need access to ath9k_htc's statistics.
As well as access to the FFT/spectral data.
@@ -201,7 +201,7 @@ config ATH9K_HWRNG
bool "Random number generator support"
depends on ATH9K && (HW_RANDOM = y || HW_RANDOM = ATH9K)
default n
- ---help---
+ help
This option incorporates the ADC register output as a source of
randomness into Linux entropy pool (/dev/urandom and /dev/random)
@@ -213,5 +213,5 @@ config ATH9K_COMMON_SPECTRAL
depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS
select RELAY
default n
- ---help---
+ help
Say Y to enable access to the FFT/spectral data via debugfs.
diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig b/drivers/net/wireless/ath/wcn36xx/Kconfig
index a4b153470a2c..5832c7ef9352 100644
--- a/drivers/net/wireless/ath/wcn36xx/Kconfig
+++ b/drivers/net/wireless/ath/wcn36xx/Kconfig
@@ -4,7 +4,7 @@ config WCN36XX
depends on MAC80211 && HAS_DMA
depends on QCOM_WCNSS_CTRL || QCOM_WCNSS_CTRL=n
depends on RPMSG || RPMSG=n
- ---help---
+ help
This module adds support for wireless adapters based on
Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
@@ -13,7 +13,7 @@ config WCN36XX
config WCN36XX_DEBUGFS
bool "WCN36XX debugfs support"
depends on WCN36XX
- ---help---
+ help
Enabled debugfs support
If unsure, say Y to make it easier to debug problems.
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index 0d1a8dab30ed..dadba2d41bbb 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -5,7 +5,7 @@ config WIL6210
depends on CFG80211
depends on PCI
default n
- ---help---
+ help
This module adds support for wireless adapter based on
wil6210 chip by Wilocity. It supports operation on the
60 GHz band, covered by the IEEE802.11ad standard.
@@ -19,7 +19,7 @@ config WIL6210_ISR_COR
bool "Use Clear-On-Read mode for ISR registers for wil6210"
depends on WIL6210
default y
- ---help---
+ help
ISR registers on wil6210 chip may operate in either
COR (Clear-On-Read) or W1C (Write-1-to-Clear) mode.
For production code, use COR (say y); is default since
@@ -35,7 +35,7 @@ config WIL6210_TRACING
depends on WIL6210
depends on EVENT_TRACING
default n
- ---help---
+ help
Say Y here to enable tracepoints for the wil6210 driver
using the kernel tracing infrastructure. Select this
option if you are interested in debugging the driver.
@@ -47,7 +47,7 @@ config WIL6210_DEBUGFS
depends on WIL6210
depends on DEBUG_FS
default y
- ---help---
+ help
Say Y here to enable wil6210 debugfs support, using the
kernel debugfs infrastructure. Select this
option if you are interested in debugging the driver.
diff --git a/drivers/net/wireless/atmel/Kconfig b/drivers/net/wireless/atmel/Kconfig
index c2142c70f25d..ca45a1021cf4 100644
--- a/drivers/net/wireless/atmel/Kconfig
+++ b/drivers/net/wireless/atmel/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_ATMEL
bool "Atmel devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -19,7 +19,7 @@ config ATMEL
select WEXT_PRIV
select FW_LOADER
select CRC32
- ---help---
+ help
A driver 802.11b wireless cards based on the Atmel fast-vnet
chips. This driver supports standard Linux wireless extensions.
@@ -33,7 +33,7 @@ config ATMEL
config PCI_ATMEL
tristate "Atmel at76c506 PCI cards"
depends on ATMEL && PCI
- ---help---
+ help
Enable support for PCI and mini-PCI cards containing the
Atmel at76c506 chip.
@@ -43,7 +43,7 @@ config PCMCIA_ATMEL
select WIRELESS_EXT
select FW_LOADER
select CRC32
- ---help---
+ help
Enable support for PCMCIA cards containing the
Atmel at76c502 and at76c504 chips.
@@ -51,7 +51,7 @@ config AT76C50X_USB
tristate "Atmel at76c503/at76c505/at76c505a USB cards"
depends on MAC80211 && USB
select FW_LOADER
- ---help---
+ help
Enable support for USB Wireless devices using Atmel at76c503,
at76c505 or at76c505a chips.
diff --git a/drivers/net/wireless/broadcom/Kconfig b/drivers/net/wireless/broadcom/Kconfig
index bb1cb402a919..f74333366a90 100644
--- a/drivers/net/wireless/broadcom/Kconfig
+++ b/drivers/net/wireless/broadcom/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_BROADCOM
bool "Broadcom devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/wireless/broadcom/b43/Kconfig b/drivers/net/wireless/broadcom/b43/Kconfig
index 3b582e76762b..4559549b80fe 100644
--- a/drivers/net/wireless/broadcom/b43/Kconfig
+++ b/drivers/net/wireless/broadcom/b43/Kconfig
@@ -6,7 +6,7 @@ config B43
select SSB if B43_SSB
select FW_LOADER
select CORDIC
- ---help---
+ help
b43 is a driver for the Broadcom 43xx series wireless devices.
Check "lspci" for something like
@@ -77,7 +77,7 @@ config B43_SDIO
bool "Broadcom 43xx SDIO device support"
depends on B43 && B43_SSB && SSB_SDIOHOST_POSSIBLE
select SSB_SDIOHOST
- ---help---
+ help
Broadcom 43xx device support for Soft-MAC SDIO devices.
With this config option you can drive Soft-MAC b43 cards with a
@@ -108,7 +108,7 @@ config B43_PHY_G
bool "Support for G-PHY (802.11g) devices"
depends on B43 && B43_SSB
default y
- ---help---
+ help
This PHY type can be found in the following chipsets:
PCI: BCM4306, BCM4311, BCM4318
SoC: BCM4712, BCM5352E
@@ -117,7 +117,7 @@ config B43_PHY_N
bool "Support for N-PHY (the main 802.11n series) devices"
depends on B43
default y
- ---help---
+ help
This PHY type can be found in the following chipsets:
PCI: BCM4321, BCM4322,
BCM43222, BCM43224, BCM43225,
@@ -128,7 +128,7 @@ config B43_PHY_LP
bool "Support for LP-PHY (low-power 802.11g) devices"
depends on B43 && B43_SSB
default y
- ---help---
+ help
The LP-PHY is a low-power PHY built into some notebooks
and embedded devices. It supports 802.11a/b/g
(802.11a support is optional, and currently disabled).
@@ -137,13 +137,13 @@ config B43_PHY_HT
bool "Support for HT-PHY (high throughput 802.11n) devices"
depends on B43 && B43_BCMA
default y
- ---help---
+ help
This PHY type with 3x3:3 MIMO can be found in the BCM4331 PCI chipset.
config B43_PHY_LCN
bool "Support for LCN-PHY devices (BROKEN)"
depends on B43 && BROKEN
- ---help---
+ help
Support for the LCN-PHY.
Say N, this is BROKEN and crashes driver.
@@ -151,7 +151,7 @@ config B43_PHY_LCN
config B43_PHY_AC
bool "Support for AC-PHY (802.11ac) devices (BROKEN)"
depends on B43 && B43_BCMA && BROKEN
- ---help---
+ help
This PHY type can be found in the following chipsets:
PCI: BCM4352, BCM4360
@@ -174,7 +174,7 @@ config B43_HWRNG
config B43_DEBUG
bool "Broadcom 43xx debugging"
depends on B43
- ---help---
+ help
Broadcom 43xx debugging.
This adds additional runtime sanity checks and statistics to the driver.
diff --git a/drivers/net/wireless/broadcom/b43legacy/Kconfig b/drivers/net/wireless/broadcom/b43legacy/Kconfig
index bfac34142ab5..e4da34ec4f5b 100644
--- a/drivers/net/wireless/broadcom/b43legacy/Kconfig
+++ b/drivers/net/wireless/broadcom/b43legacy/Kconfig
@@ -4,7 +4,7 @@ config B43LEGACY
depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
select SSB
select FW_LOADER
- ---help---
+ help
b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and
BCM4303) and early model 802.11g chips (BCM4306 Ver. 2) used in the
Linksys WPC54G V1 PCMCIA devices.
@@ -54,7 +54,7 @@ config B43LEGACY_DEBUG
bool "Broadcom 43xx-legacy debugging"
depends on B43LEGACY
default y
- ---help---
+ help
Say Y, because this information will help you get the driver running.
This option generates a minimum of log output.
@@ -75,7 +75,7 @@ config B43LEGACY_DMA_AND_PIO_MODE
bool "DMA + PIO"
select B43LEGACY_DMA
select B43LEGACY_PIO
- ---help---
+ help
Include both, Direct Memory Access (DMA) and Programmed I/O (PIO)
data transfer modes. The mode actually used is selectable through
the module parameter "pio". With pio=0 as a module parameter, the
@@ -86,14 +86,14 @@ config B43LEGACY_DMA_AND_PIO_MODE
config B43LEGACY_DMA_MODE
bool "DMA (Direct Memory Access) only"
select B43LEGACY_DMA
- ---help---
+ help
Only include Direct Memory Access (DMA).
This reduces the size of the driver module, by omitting the PIO code.
config B43LEGACY_PIO_MODE
bool "PIO (Programmed I/O) only"
select B43LEGACY_PIO
- ---help---
+ help
Only include Programmed I/O (PIO).
This reduces the size of the driver module, by omitting the DMA code.
Please note that PIO transfers are slow (compared to DMA).
diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
index a5bf16c4f495..5bf2318763c5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -12,7 +12,7 @@ config BRCMSMAC
select BRCMUTIL
select FW_LOADER
select CORDIC
- ---help---
+ help
This module adds support for PCIe wireless adapters based on Broadcom
IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will
be available if you select BCMA_DRIVER_GPIO. If you choose to build a
@@ -23,7 +23,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
config BRCM_TRACING
bool "Broadcom device tracing"
depends on BRCMSMAC || BRCMFMAC
- ---help---
+ help
If you say Y here, the Broadcom wireless drivers will register
with ftrace to dump event information into the trace ringbuffer.
Tracing can be enabled at runtime to aid in debugging wireless
@@ -35,5 +35,5 @@ config BRCMDBG
bool "Broadcom driver debug functions"
depends on BRCMSMAC || BRCMFMAC
select WANT_DEV_COREDUMP if BRCMFMAC
- ---help---
+ help
Selecting this enables additional code for debug purposes.
diff --git a/drivers/net/wireless/cisco/Kconfig b/drivers/net/wireless/cisco/Kconfig
index 7a3b3bb2ce15..681bfc2d740a 100644
--- a/drivers/net/wireless/cisco/Kconfig
+++ b/drivers/net/wireless/cisco/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_CISCO
bool "Cisco devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -20,7 +20,7 @@ config AIRO
select CRYPTO_SKCIPHER
select WEXT_SPY
select WEXT_PRIV
- ---help---
+ help
This is the standard Linux driver to support Cisco/Aironet ISA and
PCI 802.11 wireless cards.
It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
@@ -42,7 +42,7 @@ config AIRO_CS
select CRYPTO
select CRYPTO_AES
select CRYPTO_CTR
- ---help---
+ help
This is the standard Linux driver to support Cisco/Aironet PCMCIA
802.11 wireless cards. This driver is the same as the Aironet
driver part of the Linux Pcmcia package.
diff --git a/drivers/net/wireless/intel/Kconfig b/drivers/net/wireless/intel/Kconfig
index 6ec42f67d0f2..3d1d7d11a396 100644
--- a/drivers/net/wireless/intel/Kconfig
+++ b/drivers/net/wireless/intel/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_INTEL
bool "Intel devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index f42b3cdce611..d00386915a9d 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -12,7 +12,7 @@ config IPW2100
select FW_LOADER
select LIB80211
select LIBIPW
- ---help---
+ help
A driver for the Intel PRO/Wireless 2100 Network
Connection 802.11b wireless network adapter.
@@ -41,7 +41,7 @@ config IPW2100
config IPW2100_MONITOR
bool "Enable promiscuous mode"
depends on IPW2100
- ---help---
+ help
Enables promiscuous/monitor mode support for the ipw2100 driver.
With this feature compiled into the driver, you can switch to
promiscuous mode via the Wireless Tool's Monitor mode. While in this
@@ -50,7 +50,7 @@ config IPW2100_MONITOR
config IPW2100_DEBUG
bool "Enable full debugging output in IPW2100 module."
depends on IPW2100
- ---help---
+ help
This option will enable debug tracing output for the IPW2100.
This will result in the kernel module being ~60k larger. You can
@@ -74,7 +74,7 @@ config IPW2200
select FW_LOADER
select LIB80211
select LIBIPW
- ---help---
+ help
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
Connection adapters.
@@ -103,7 +103,7 @@ config IPW2200
config IPW2200_MONITOR
bool "Enable promiscuous mode"
depends on IPW2200
- ---help---
+ help
Enables promiscuous/monitor mode support for the ipw2200 driver.
With this feature compiled into the driver, you can switch to
promiscuous mode via the Wireless Tool's Monitor mode. While in this
@@ -117,7 +117,7 @@ config IPW2200_PROMISCUOUS
bool "Enable creation of a RF radiotap promiscuous interface"
depends on IPW2200_MONITOR
select IPW2200_RADIOTAP
- ---help---
+ help
Enables the creation of a second interface prefixed 'rtap'.
This second interface will provide every received in radiotap
format.
@@ -144,7 +144,7 @@ config IPW2200_QOS
config IPW2200_DEBUG
bool "Enable full debugging output in IPW2200 module."
depends on IPW2200
- ---help---
+ help
This option will enable low level debug tracing output for IPW2200.
Note, normal debug code is already compiled in. This low level
@@ -170,7 +170,7 @@ config LIBIPW
select LIB80211_CRYPT_WEP
select LIB80211_CRYPT_TKIP
select LIB80211_CRYPT_CCMP
- ---help---
+ help
This option enables the hardware independent IEEE 802.11
networking stack. This component is deprecated in favor of the
mac80211 component.
@@ -178,7 +178,7 @@ config LIBIPW
config LIBIPW_DEBUG
bool "Full debugging output for the LIBIPW component"
depends on LIBIPW
- ---help---
+ help
This option will enable debug tracing output for the
libipw component.
diff --git a/drivers/net/wireless/intel/iwlegacy/Kconfig b/drivers/net/wireless/intel/iwlegacy/Kconfig
index 100f55858b13..24fe3f63c321 100644
--- a/drivers/net/wireless/intel/iwlegacy/Kconfig
+++ b/drivers/net/wireless/intel/iwlegacy/Kconfig
@@ -11,7 +11,7 @@ config IWL4965
tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
depends on PCI && MAC80211
select IWLEGACY
- ---help---
+ help
This option enables support for
Select to build the driver supporting the:
@@ -39,7 +39,7 @@ config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
depends on PCI && MAC80211
select IWLEGACY
- ---help---
+ help
Select to build the driver supporting the:
Intel PRO/Wireless 3945ABG/BG Network Connection
@@ -67,7 +67,7 @@ menu "iwl3945 / iwl4965 Debugging Options"
config IWLEGACY_DEBUG
bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
depends on IWLEGACY
- ---help---
+ help
This option will enable debug tracing output for the iwlegacy
drivers.
@@ -93,7 +93,7 @@ config IWLEGACY_DEBUG
config IWLEGACY_DEBUGFS
bool "iwlegacy (iwl 3945/4965) debugfs support"
depends on IWLEGACY && MAC80211_DEBUGFS
- ---help---
+ help
Enable creation of debugfs files for the iwlegacy drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig
index 091d621ad25f..36153fa5f96a 100644
--- a/drivers/net/wireless/intel/iwlwifi/Kconfig
+++ b/drivers/net/wireless/intel/iwlwifi/Kconfig
@@ -3,7 +3,7 @@ config IWLWIFI
tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
depends on PCI && HAS_IOMEM && CFG80211
select FW_LOADER
- ---help---
+ help
Select to build the driver supporting the:
Intel Wireless WiFi Link Next-Gen AGN
@@ -96,7 +96,7 @@ menu "Debugging Options"
config IWLWIFI_DEBUG
bool "Enable full debugging output in the iwlwifi driver"
- ---help---
+ help
This option will enable debug tracing output for the iwlwifi drivers
This will result in the kernel module being ~100k larger. You can
@@ -121,7 +121,7 @@ config IWLWIFI_DEBUG
config IWLWIFI_DEBUGFS
bool "iwlwifi debugfs support"
depends on MAC80211_DEBUGFS
- ---help---
+ help
Enable creation of debugfs files for the iwlwifi drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
diff --git a/drivers/net/wireless/intersil/Kconfig b/drivers/net/wireless/intersil/Kconfig
index 4e968912e27c..6a6ce9d4aeee 100644
--- a/drivers/net/wireless/intersil/Kconfig
+++ b/drivers/net/wireless/intersil/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_INTERSIL
bool "Intersil devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -23,7 +23,7 @@ config PRISM54
select WEXT_SPY
select WEXT_PRIV
select FW_LOADER
- ---help---
+ help
This enables support for FullMAC PCI/Cardbus prism54 devices. This
driver is now deprecated in favor for the SoftMAC driver, p54pci.
p54pci supports FullMAC PCI/Cardbus devices as well.
diff --git a/drivers/net/wireless/intersil/hostap/Kconfig b/drivers/net/wireless/intersil/hostap/Kconfig
index c70dc168dc63..6ad88299432f 100644
--- a/drivers/net/wireless/intersil/hostap/Kconfig
+++ b/drivers/net/wireless/intersil/hostap/Kconfig
@@ -15,7 +15,7 @@ config HOSTAP
select LIB80211_CRYPT_WEP
select LIB80211_CRYPT_TKIP
select LIB80211_CRYPT_CCMP
- ---help---
+ help
Shared driver code for IEEE 802.11b wireless cards based on
Intersil Prism2/2.5/3 chipset. This driver supports so called
Host AP mode that allows the card to act as an IEEE 802.11
@@ -36,7 +36,7 @@ config HOSTAP
config HOSTAP_FIRMWARE
bool "Support downloading firmware images with Host AP driver"
depends on HOSTAP
- ---help---
+ help
Configure Host AP driver to include support for firmware image
download. This option by itself only enables downloading to the
volatile memory, i.e. the card RAM. This option is required to
@@ -49,7 +49,7 @@ config HOSTAP_FIRMWARE
config HOSTAP_FIRMWARE_NVRAM
bool "Support for non-volatile firmware download"
depends on HOSTAP_FIRMWARE
- ---help---
+ help
Allow Host AP driver to write firmware images to the non-volatile
card memory, i.e. flash memory that survives power cycling.
Enable this option if you want to be able to change card firmware
@@ -61,7 +61,7 @@ config HOSTAP_FIRMWARE_NVRAM
config HOSTAP_PLX
tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
depends on PCI && HOSTAP
- ---help---
+ help
Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based
PCI adaptors.
@@ -75,7 +75,7 @@ config HOSTAP_PLX
config HOSTAP_PCI
tristate "Host AP driver for Prism2.5 PCI adaptors"
depends on PCI && HOSTAP
- ---help---
+ help
Host AP driver's version for Prism2.5 PCI adaptors.
"Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
@@ -88,7 +88,7 @@ config HOSTAP_PCI
config HOSTAP_CS
tristate "Host AP driver for Prism2/2.5/3 PC Cards"
depends on PCMCIA && HOSTAP
- ---help---
+ help
Host AP driver's version for Prism2/2.5/3 PC Cards.
"Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
diff --git a/drivers/net/wireless/intersil/orinoco/Kconfig b/drivers/net/wireless/intersil/orinoco/Kconfig
index c430d7a46730..c470ee23673f 100644
--- a/drivers/net/wireless/intersil/orinoco/Kconfig
+++ b/drivers/net/wireless/intersil/orinoco/Kconfig
@@ -10,7 +10,7 @@ config HERMES
select FW_LOADER
select CRYPTO
select CRYPTO_MICHAEL_MIC
- ---help---
+ help
A driver for 802.11b wireless cards based on the "Hermes" or
Intersil HFA384x (Prism 2) MAC controller. This includes the vast
majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
@@ -32,7 +32,7 @@ config HERMES
config HERMES_PRISM
bool "Support Prism 2/2.5 chipset"
depends on HERMES
- ---help---
+ help
Say Y to enable support for Prism 2 and 2.5 chipsets. These
chipsets are better handled by the hostap driver. This driver
@@ -44,7 +44,7 @@ config HERMES_CACHE_FW_ON_INIT
bool "Cache Hermes firmware on driver initialisation"
depends on HERMES
default y
- ---help---
+ help
Say Y to cache any firmware required by the Hermes drivers
on startup. The firmware will remain cached until the
driver is unloaded. The cache uses 64K of RAM.
@@ -110,7 +110,7 @@ config PCI_HERMES
config PCMCIA_HERMES
tristate "Hermes PCMCIA card support"
depends on PCMCIA && HERMES && HAS_IOPORT_MAP
- ---help---
+ help
A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
@@ -125,7 +125,7 @@ config PCMCIA_HERMES
config PCMCIA_SPECTRUM
tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
depends on PCMCIA && HERMES && HAS_IOPORT_MAP
- ---help---
+ help
This is a driver for 802.11b cards using RAM-loadable Symbol
firmware, such as Symbol Wireless Networker LA4100, CompactFlash
@@ -139,5 +139,5 @@ config ORINOCO_USB
tristate "Agere Orinoco USB support"
depends on USB && HERMES
select FW_LOADER
- ---help---
+ help
This driver is for USB versions of the Agere Orinoco card.
diff --git a/drivers/net/wireless/intersil/p54/Kconfig b/drivers/net/wireless/intersil/p54/Kconfig
index 26cd80732afa..024be5507daf 100644
--- a/drivers/net/wireless/intersil/p54/Kconfig
+++ b/drivers/net/wireless/intersil/p54/Kconfig
@@ -4,7 +4,7 @@ config P54_COMMON
depends on MAC80211
select FW_LOADER
select CRC_CCITT
- ---help---
+ help
This is common code for isl38xx/stlc45xx based modules.
This module does nothing by itself - the USB/PCI/SPI front-ends
also need to be enabled in order to support any devices.
@@ -18,7 +18,7 @@ config P54_USB
tristate "Prism54 USB support"
depends on P54_COMMON && USB
select CRC32
- ---help---
+ help
This driver is for USB isl38xx based wireless cards.
These devices require softmac firmware which can be found at
@@ -29,7 +29,7 @@ config P54_USB
config P54_PCI
tristate "Prism54 PCI support"
depends on P54_COMMON && PCI
- ---help---
+ help
This driver is for PCI isl38xx based wireless cards.
This driver supports most devices that are supported by the
fullmac prism54 driver plus many devices which are not
@@ -43,7 +43,7 @@ config P54_PCI
config P54_SPI
tristate "Prism54 SPI (stlc45xx) support"
depends on P54_COMMON && SPI_MASTER
- ---help---
+ help
This driver is for stlc4550 or stlc4560 based wireless chips
such as Nokia's N800/N810 Portable Internet Tablet.
@@ -53,7 +53,7 @@ config P54_SPI_DEFAULT_EEPROM
bool "Include fallback EEPROM blob"
depends on P54_SPI
default n
- ---help---
+ help
Unlike the PCI or USB devices, the SPI variants don't have
a dedicated EEPROM chip to store all device specific values
for calibration, country and interface settings.
diff --git a/drivers/net/wireless/marvell/Kconfig b/drivers/net/wireless/marvell/Kconfig
index dff82fdbea78..864bc0f6d4d4 100644
--- a/drivers/net/wireless/marvell/Kconfig
+++ b/drivers/net/wireless/marvell/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_MARVELL
bool "Marvell devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -19,7 +19,7 @@ source "drivers/net/wireless/marvell/mwifiex/Kconfig"
config MWL8K
tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
depends on MAC80211 && PCI
- ---help---
+ help
This driver supports Marvell TOPDOG 802.11 wireless cards.
To compile this driver as a module, choose M here: the module
diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig
index b9fe598130c3..6d62ab49aa8d 100644
--- a/drivers/net/wireless/marvell/libertas/Kconfig
+++ b/drivers/net/wireless/marvell/libertas/Kconfig
@@ -6,37 +6,37 @@ config LIBERTAS
select WEXT_SPY
select LIB80211
select FW_LOADER
- ---help---
+ help
A library for Marvell Libertas 8xxx devices.
config LIBERTAS_USB
tristate "Marvell Libertas 8388 USB 802.11b/g cards"
depends on LIBERTAS && USB
- ---help---
+ help
A driver for Marvell Libertas 8388 USB devices.
config LIBERTAS_CS
tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
depends on LIBERTAS && PCMCIA && HAS_IOPORT_MAP
- ---help---
+ help
A driver for Marvell Libertas 8385 CompactFlash devices.
config LIBERTAS_SDIO
tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
depends on LIBERTAS && MMC
- ---help---
+ help
A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
config LIBERTAS_SPI
tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
depends on LIBERTAS && SPI
- ---help---
+ help
A driver for Marvell Libertas 8686 SPI devices.
config LIBERTAS_DEBUG
bool "Enable full debugging output in the Libertas module."
depends on LIBERTAS
- ---help---
+ help
Debugging support.
config LIBERTAS_MESH
diff --git a/drivers/net/wireless/marvell/libertas_tf/Kconfig b/drivers/net/wireless/marvell/libertas_tf/Kconfig
index aa40d65f611a..345da4a6ee8d 100644
--- a/drivers/net/wireless/marvell/libertas_tf/Kconfig
+++ b/drivers/net/wireless/marvell/libertas_tf/Kconfig
@@ -3,17 +3,17 @@ config LIBERTAS_THINFIRM
tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware"
depends on MAC80211
select FW_LOADER
- ---help---
+ help
A library for Marvell Libertas 8xxx devices using thinfirm.
config LIBERTAS_THINFIRM_DEBUG
bool "Enable full debugging output in the Libertas thin firmware module."
depends on LIBERTAS_THINFIRM
- ---help---
+ help
Debugging support.
config LIBERTAS_THINFIRM_USB
tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware"
depends on LIBERTAS_THINFIRM && USB
- ---help---
+ help
A driver for Marvell Libertas 8388 USB devices using thinfirm.
diff --git a/drivers/net/wireless/marvell/mwifiex/Kconfig b/drivers/net/wireless/marvell/mwifiex/Kconfig
index 64d8a11ad1e7..2b4ff2b78a7e 100644
--- a/drivers/net/wireless/marvell/mwifiex/Kconfig
+++ b/drivers/net/wireless/marvell/mwifiex/Kconfig
@@ -2,7 +2,7 @@
config MWIFIEX
tristate "Marvell WiFi-Ex Driver"
depends on CFG80211
- ---help---
+ help
This adds support for wireless adapters based on Marvell
802.11n/ac chipsets.
@@ -14,7 +14,7 @@ config MWIFIEX_SDIO
depends on MWIFIEX && MMC
select FW_LOADER
select WANT_DEV_COREDUMP
- ---help---
+ help
This adds support for wireless adapters based on Marvell
8786/8787/8797/8887/8897/8977/8987/8997 chipsets with SDIO interface.
@@ -26,7 +26,7 @@ config MWIFIEX_PCIE
depends on MWIFIEX && PCI
select FW_LOADER
select WANT_DEV_COREDUMP
- ---help---
+ help
This adds support for wireless adapters based on Marvell
8766/8897/8997 chipsets with PCIe interface.
@@ -37,7 +37,7 @@ config MWIFIEX_USB
tristate "Marvell WiFi-Ex Driver for USB8766/8797/8997"
depends on MWIFIEX && USB
select FW_LOADER
- ---help---
+ help
This adds support for wireless adapters based on Marvell
8797/8997 chipset with USB interface.
diff --git a/drivers/net/wireless/mediatek/Kconfig b/drivers/net/wireless/mediatek/Kconfig
index 02d1120f148f..bd4db128248e 100644
--- a/drivers/net/wireless/mediatek/Kconfig
+++ b/drivers/net/wireless/mediatek/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_MEDIATEK
bool "MediaTek devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/wireless/mediatek/mt7601u/Kconfig b/drivers/net/wireless/mediatek/mt7601u/Kconfig
index 0b230f303d53..4a8b96280670 100644
--- a/drivers/net/wireless/mediatek/mt7601u/Kconfig
+++ b/drivers/net/wireless/mediatek/mt7601u/Kconfig
@@ -3,5 +3,5 @@ config MT7601U
tristate "MediaTek MT7601U (USB) support"
depends on MAC80211
depends on USB
- ---help---
+ help
This adds support for MT7601U-based wireless USB dongles.
diff --git a/drivers/net/wireless/ralink/Kconfig b/drivers/net/wireless/ralink/Kconfig
index 92eec8fff8fd..135a191c435d 100644
--- a/drivers/net/wireless/ralink/Kconfig
+++ b/drivers/net/wireless/ralink/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_RALINK
bool "Ralink devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/wireless/ralink/rt2x00/Kconfig b/drivers/net/wireless/ralink/rt2x00/Kconfig
index d4969d617822..dcccc290a7f5 100644
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
@@ -2,7 +2,7 @@
menuconfig RT2X00
tristate "Ralink driver support"
depends on MAC80211 && HAS_DMA
- ---help---
+ help
This will enable the support for the Ralink drivers,
developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
@@ -24,7 +24,7 @@ config RT2400PCI
select RT2X00_LIB_MMIO
select RT2X00_LIB_PCI
select EEPROM_93CX6
- ---help---
+ help
This adds support for rt2400 wireless chipset family.
Supported chips: RT2460.
@@ -36,7 +36,7 @@ config RT2500PCI
select RT2X00_LIB_MMIO
select RT2X00_LIB_PCI
select EEPROM_93CX6
- ---help---
+ help
This adds support for rt2500 wireless chipset family.
Supported chips: RT2560.
@@ -51,7 +51,7 @@ config RT61PCI
select RT2X00_LIB_CRYPTO
select CRC_ITU_T
select EEPROM_93CX6
- ---help---
+ help
This adds support for rt2501 wireless chipset family.
Supported chips: RT2561, RT2561S & RT2661.
@@ -68,7 +68,7 @@ config RT2800PCI
select RT2X00_LIB_CRYPTO
select CRC_CCITT
select EEPROM_93CX6
- ---help---
+ help
This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052,
RT3090, RT3091 & RT3092
@@ -80,7 +80,7 @@ if RT2800PCI
config RT2800PCI_RT33XX
bool "rt2800pci - Include support for rt33xx devices"
default y
- ---help---
+ help
This adds support for rt33xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT3390
@@ -88,7 +88,7 @@ config RT2800PCI_RT33XX
config RT2800PCI_RT35XX
bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
default y
- ---help---
+ help
This adds support for rt35xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT3060, RT3062, RT3562, RT3592
@@ -97,7 +97,7 @@ config RT2800PCI_RT35XX
config RT2800PCI_RT53XX
bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
default y
- ---help---
+ help
This adds support for rt53xx wireless chipset family to the
rt2800pci driver.
Supported chips: RT5390
@@ -105,7 +105,7 @@ config RT2800PCI_RT53XX
config RT2800PCI_RT3290
bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)"
default y
- ---help---
+ help
This adds support for rt3290 wireless chipset family to the
rt2800pci driver.
Supported chips: RT3290
@@ -116,7 +116,7 @@ config RT2500USB
depends on USB
select RT2X00_LIB_USB
select RT2X00_LIB_CRYPTO
- ---help---
+ help
This adds support for rt2500 wireless chipset family.
Supported chips: RT2571 & RT2572.
@@ -129,7 +129,7 @@ config RT73USB
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_ITU_T
- ---help---
+ help
This adds support for rt2501 wireless chipset family.
Supported chips: RT2571W, RT2573 & RT2671.
@@ -143,7 +143,7 @@ config RT2800USB
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT
- ---help---
+ help
This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072
@@ -154,7 +154,7 @@ if RT2800USB
config RT2800USB_RT33XX
bool "rt2800usb - Include support for rt33xx devices"
default y
- ---help---
+ help
This adds support for rt33xx wireless chipset family to the
rt2800usb driver.
Supported chips: RT3370
@@ -162,27 +162,27 @@ config RT2800USB_RT33XX
config RT2800USB_RT35XX
bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
default y
- ---help---
+ help
This adds support for rt35xx wireless chipset family to the
rt2800usb driver.
Supported chips: RT3572
config RT2800USB_RT3573
bool "rt2800usb - Include support for rt3573 devices (EXPERIMENTAL)"
- ---help---
+ help
This enables support for RT3573 chipset based wireless USB devices
in the rt2800usb driver.
config RT2800USB_RT53XX
bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
- ---help---
+ help
This adds support for rt53xx wireless chipset family to the
rt2800usb driver.
Supported chips: RT5370
config RT2800USB_RT55XX
bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)"
- ---help---
+ help
This adds support for rt55xx wireless chipset family to the
rt2800usb driver.
Supported chips: RT5572
@@ -190,7 +190,7 @@ config RT2800USB_RT55XX
config RT2800USB_UNKNOWN
bool "rt2800usb - Include support for unknown (USB) devices"
default n
- ---help---
+ help
This adds support for rt2800usb devices that are known to
have a rt28xx family compatible chipset, but for which the exact
chipset is unknown.
@@ -209,7 +209,7 @@ config RT2800SOC
select RT2X00_LIB_FIRMWARE
select RT2800_LIB
select RT2800_LIB_MMIO
- ---help---
+ help
This adds support for Ralink WiSoC devices.
Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352.
@@ -256,7 +256,7 @@ config RT2X00_LIB_LEDS
config RT2X00_LIB_DEBUGFS
bool "Ralink debugfs support"
depends on RT2X00_LIB && MAC80211_DEBUGFS
- ---help---
+ help
Enable creation of debugfs files for the rt2x00 drivers.
These debugfs files support both reading and writing of the
most important register types of the rt2x00 hardware.
@@ -264,7 +264,7 @@ config RT2X00_LIB_DEBUGFS
config RT2X00_DEBUG
bool "Ralink debug output"
depends on RT2X00_LIB
- ---help---
+ help
Enable debugging output for all rt2x00 modules
endif
diff --git a/drivers/net/wireless/realtek/Kconfig b/drivers/net/wireless/realtek/Kconfig
index 8ea2d8d7e356..474843277fa1 100644
--- a/drivers/net/wireless/realtek/Kconfig
+++ b/drivers/net/wireless/realtek/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_REALTEK
bool "Realtek devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/wireless/realtek/rtl818x/Kconfig b/drivers/net/wireless/realtek/rtl818x/Kconfig
index e1aa3fc71e66..603812c9a43e 100644
--- a/drivers/net/wireless/realtek/rtl818x/Kconfig
+++ b/drivers/net/wireless/realtek/rtl818x/Kconfig
@@ -6,7 +6,7 @@ config RTL8180
tristate "Realtek 8180/8185/8187SE PCI support"
depends on MAC80211 && PCI
select EEPROM_93CX6
- ---help---
+ help
This is a driver for RTL8180, RTL8185 and RTL8187SE based cards.
These are PCI based chips found in cards such as:
@@ -62,7 +62,7 @@ config RTL8187
tristate "Realtek 8187 and 8187B USB support"
depends on MAC80211 && USB
select EEPROM_93CX6
- ---help---
+ help
This is a driver for RTL8187 and RTL8187B based cards.
These are USB based chips found in devices such as:
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/Kconfig b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
index 32d151cde618..a263507a77a6 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
+++ b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
@@ -5,7 +5,7 @@
config RTL8XXXU
tristate "RTL8723AU/RTL8188[CR]U/RTL819[12]CU (mac80211) support"
depends on MAC80211 && USB
- ---help---
+ help
This is an alternative driver for various Realtek RTL8XXX
parts written to utilize the Linux mac80211 stack.
The driver is known to work with a number of RTL8723AU,
@@ -27,7 +27,7 @@ config RTL8XXXU
config RTL8XXXU_UNTESTED
bool "Include support for untested Realtek 8xxx USB devices (EXPERIMENTAL)"
depends on RTL8XXXU
- ---help---
+ help
This option enables detection of Realtek 8723/8188/8191/8192 WiFi
USB devices which have not been tested directly by the driver
author or reported to be working by third parties.
diff --git a/drivers/net/wireless/realtek/rtlwifi/Kconfig b/drivers/net/wireless/realtek/rtlwifi/Kconfig
index 28c247f7f6f8..9f6a4e35543c 100644
--- a/drivers/net/wireless/realtek/rtlwifi/Kconfig
+++ b/drivers/net/wireless/realtek/rtlwifi/Kconfig
@@ -3,7 +3,7 @@ menuconfig RTL_CARDS
tristate "Realtek rtlwifi family of devices"
depends on MAC80211 && (PCI || USB)
default y
- ---help---
+ help
This option will enable support for the Realtek mac80211-based
wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de,
rtl8723ae, rtl8723be, rtl8188ee, rtl8192ee, and rtl8821ae share
@@ -17,7 +17,7 @@ config RTL8192CE
select RTL8192C_COMMON
select RTLWIFI
select RTLWIFI_PCI
- ---help---
+ help
This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
wireless network adapters.
@@ -28,7 +28,7 @@ config RTL8192SE
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
- ---help---
+ help
This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
wireless network adapters.
@@ -39,7 +39,7 @@ config RTL8192DE
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
- ---help---
+ help
This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe
wireless network adapters.
@@ -52,7 +52,7 @@ config RTL8723AE
select RTLWIFI_PCI
select RTL8723_COMMON
select RTLBTCOEXIST
- ---help---
+ help
This is the driver for Realtek RTL8723AE 802.11n PCIe
wireless network adapters.
@@ -65,7 +65,7 @@ config RTL8723BE
select RTLWIFI_PCI
select RTL8723_COMMON
select RTLBTCOEXIST
- ---help---
+ help
This is the driver for Realtek RTL8723BE 802.11n PCIe
wireless network adapters.
@@ -76,7 +76,7 @@ config RTL8188EE
depends on PCI
select RTLWIFI
select RTLWIFI_PCI
- ---help---
+ help
This is the driver for Realtek RTL8188EE 802.11n PCIe
wireless network adapters.
@@ -88,7 +88,7 @@ config RTL8192EE
select RTLWIFI
select RTLWIFI_PCI
select RTLBTCOEXIST
- ---help---
+ help
This is the driver for Realtek RTL8192EE 802.11n PCIe
wireless network adapters.
@@ -100,7 +100,7 @@ config RTL8821AE
select RTLWIFI
select RTLWIFI_PCI
select RTLBTCOEXIST
- ---help---
+ help
This is the driver for Realtek RTL8821AE/RTL8812AE 802.11ac PCIe
wireless network adapters.
@@ -112,7 +112,7 @@ config RTL8192CU
select RTLWIFI
select RTLWIFI_USB
select RTL8192C_COMMON
- ---help---
+ help
This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB
wireless network adapters.
@@ -132,7 +132,7 @@ config RTLWIFI_DEBUG
bool "Debugging output for rtlwifi driver family"
depends on RTLWIFI
default y
- ---help---
+ help
To use the module option that sets the dynamic-debugging level for,
the front-end driver, this parameter must be "Y". For memory-limited
systems, choose "N". If in doubt, choose "Y".
diff --git a/drivers/net/wireless/rsi/Kconfig b/drivers/net/wireless/rsi/Kconfig
index ad5d34350cf9..09a592409204 100644
--- a/drivers/net/wireless/rsi/Kconfig
+++ b/drivers/net/wireless/rsi/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_RSI
bool "Redpine Signals Inc devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -16,7 +16,7 @@ config RSI_91X
tristate "Redpine Signals Inc 91x WLAN driver support"
select BT_HCIRSI if RSI_COEX
depends on MAC80211
- ---help---
+ help
This option enabes support for RSI 1x1 devices.
Select M (recommended), if you have a RSI 1x1 wireless module.
@@ -24,7 +24,7 @@ config RSI_DEBUGFS
bool "Redpine Signals Inc debug support"
depends on RSI_91X
default y
- ---help---
+ help
Say Y, if you would like to enable debug support. This option
creates debugfs entries
@@ -32,7 +32,7 @@ config RSI_SDIO
tristate "Redpine Signals SDIO bus support"
depends on MMC && RSI_91X
default m
- ---help---
+ help
This option enables the SDIO bus support in rsi drivers.
Select M (recommended), if you have a RSI 1x1 wireless module.
@@ -40,7 +40,7 @@ config RSI_USB
tristate "Redpine Signals USB bus support"
depends on USB && RSI_91X
default m
- ---help---
+ help
This option enables the USB bus support in rsi drivers.
Select M (recommended), if you have a RSI 1x1 wireless module.
@@ -49,7 +49,7 @@ config RSI_COEX
depends on BT && RSI_91X
depends on !(BT=m && RSI_91X=y)
default y
- ---help---
+ help
This option enables the WLAN BT coex support in rsi drivers.
Select M (recommended), if you have want to use this feature
and you have RS9113 module.
diff --git a/drivers/net/wireless/st/Kconfig b/drivers/net/wireless/st/Kconfig
index 441d1b8e7b80..cd647a533d0e 100644
--- a/drivers/net/wireless/st/Kconfig
+++ b/drivers/net/wireless/st/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_ST
bool "STMicroelectronics devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig
index b81f2e41a63a..7c0b17a76fe2 100644
--- a/drivers/net/wireless/ti/Kconfig
+++ b/drivers/net/wireless/ti/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_TI
bool "Texas Instrument devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -22,7 +22,7 @@ config WILINK_PLATFORM_DATA
bool "TI WiLink platform data"
depends on WLCORE_SDIO || WL1251_SDIO
default y
- ---help---
+ help
Small platform data bit needed to pass data to the sdio modules.
diff --git a/drivers/net/wireless/ti/wl1251/Kconfig b/drivers/net/wireless/ti/wl1251/Kconfig
index 7d39f0a4ba5b..de1c70e10cda 100644
--- a/drivers/net/wireless/ti/wl1251/Kconfig
+++ b/drivers/net/wireless/ti/wl1251/Kconfig
@@ -4,7 +4,7 @@ config WL1251
depends on MAC80211
select FW_LOADER
select CRC7
- ---help---
+ help
This will enable TI wl1251 driver support. The drivers make
use of the mac80211 stack.
@@ -14,7 +14,7 @@ config WL1251
config WL1251_SPI
tristate "TI wl1251 SPI support"
depends on WL1251 && SPI_MASTER
- ---help---
+ help
This module adds support for the SPI interface of adapters using
TI wl1251 chipset. Select this if your platform is using
the SPI bus.
@@ -25,7 +25,7 @@ config WL1251_SPI
config WL1251_SDIO
tristate "TI wl1251 SDIO support"
depends on WL1251 && MMC
- ---help---
+ help
This module adds support for the SDIO interface of adapters using
TI wl1251 chipset. Select this if your platform is using
the SDIO bus.
diff --git a/drivers/net/wireless/ti/wl12xx/Kconfig b/drivers/net/wireless/ti/wl12xx/Kconfig
index 9c4511604b67..786fff288505 100644
--- a/drivers/net/wireless/ti/wl12xx/Kconfig
+++ b/drivers/net/wireless/ti/wl12xx/Kconfig
@@ -3,7 +3,7 @@ config WL12XX
tristate "TI wl12xx support"
depends on MAC80211
select WLCORE
- ---help---
+ help
This module adds support for wireless adapters based on TI wl1271,
wl1273, wl1281 and wl1283 chipsets. This module does *not* include
support for wl1251. For wl1251 support, use the separate homonymous
diff --git a/drivers/net/wireless/ti/wl18xx/Kconfig b/drivers/net/wireless/ti/wl18xx/Kconfig
index e29aa2a3ba8a..98fe188dfb41 100644
--- a/drivers/net/wireless/ti/wl18xx/Kconfig
+++ b/drivers/net/wireless/ti/wl18xx/Kconfig
@@ -3,6 +3,6 @@ config WL18XX
tristate "TI wl18xx support"
depends on MAC80211
select WLCORE
- ---help---
+ help
This module adds support for wireless adapters based on TI
WiLink 8 chipsets.
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig
index a9db1288221c..8094323256fb 100644
--- a/drivers/net/wireless/ti/wlcore/Kconfig
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -3,7 +3,7 @@ config WLCORE
tristate "TI wlcore support"
depends on MAC80211
select FW_LOADER
- ---help---
+ help
This module contains the main code for TI WLAN chips. It abstracts
hardware-specific differences among different chipset families.
Each chipset family needs to implement its own lower-level module
@@ -16,7 +16,7 @@ config WLCORE_SPI
tristate "TI wlcore SPI support"
depends on WLCORE && SPI_MASTER && OF
select CRC7
- ---help---
+ help
This module adds support for the SPI interface of adapters using
TI WLAN chipsets. Select this if your platform is using
the SPI bus.
@@ -27,7 +27,7 @@ config WLCORE_SPI
config WLCORE_SDIO
tristate "TI wlcore SDIO support"
depends on WLCORE && MMC
- ---help---
+ help
This module adds support for the SDIO interface of adapters using
TI WLAN chipsets. Select this if your platform is using
the SDIO bus.
diff --git a/drivers/net/wireless/zydas/Kconfig b/drivers/net/wireless/zydas/Kconfig
index 78a45cc4c014..08574433df66 100644
--- a/drivers/net/wireless/zydas/Kconfig
+++ b/drivers/net/wireless/zydas/Kconfig
@@ -2,7 +2,7 @@
config WLAN_VENDOR_ZYDAS
bool "ZyDAS devices"
default y
- ---help---
+ help
If you have a wireless card belonging to this class, say Y.
Note that the answer to this question doesn't directly affect the
@@ -18,7 +18,7 @@ config USB_ZD1201
select WIRELESS_EXT
select WEXT_PRIV
select FW_LOADER
- ---help---
+ help
Say Y if you want to use wireless LAN adapters based on the ZyDAS
ZD1201 chip.
diff --git a/drivers/net/wireless/zydas/zd1211rw/Kconfig b/drivers/net/wireless/zydas/zd1211rw/Kconfig
index 0b7f1810f6e2..f9da8c0685d4 100644
--- a/drivers/net/wireless/zydas/zd1211rw/Kconfig
+++ b/drivers/net/wireless/zydas/zd1211rw/Kconfig
@@ -3,7 +3,7 @@ config ZD1211RW
tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
depends on USB && MAC80211
select FW_LOADER
- ---help---
+ help
This is a driver for the ZyDAS ZD1211/ZD1211B wireless
chip, present in many USB-wireless adapters.
@@ -13,7 +13,7 @@ config ZD1211RW
config ZD1211RW_DEBUG
bool "ZyDAS ZD1211 debugging"
depends on ZD1211RW
- ---help---
+ help
ZD1211 debugging messages. Choosing Y will result in additional debug
messages being saved to your kernel logs, which may help debug any
problems.
diff --git a/drivers/nfc/fdp/Kconfig b/drivers/nfc/fdp/Kconfig
index f575d2aec553..6c51f4af4256 100644
--- a/drivers/nfc/fdp/Kconfig
+++ b/drivers/nfc/fdp/Kconfig
@@ -4,7 +4,7 @@ config NFC_FDP
depends on NFC_NCI
select CRC_CCITT
default n
- ---help---
+ help
Intel Fields Peak NFC controller core driver.
This is a driver based on the NCI NFC kernel layers.
@@ -15,7 +15,7 @@ config NFC_FDP
config NFC_FDP_I2C
tristate "NFC FDP i2c support"
depends on NFC_FDP && I2C
- ---help---
+ help
This module adds support for the Intel Fields Peak NFC controller
i2c interface.
Select this if your platform is using the i2c bus.
diff --git a/drivers/nfc/microread/Kconfig b/drivers/nfc/microread/Kconfig
index 07be6d48a644..21a682b19613 100644
--- a/drivers/nfc/microread/Kconfig
+++ b/drivers/nfc/microread/Kconfig
@@ -2,7 +2,7 @@
config NFC_MICROREAD
tristate
select CRC_CCITT
- ---help---
+ help
This module contains the main code for Inside Secure microread
NFC chipsets. It implements the chipset HCI logic and hooks into
the NFC kernel APIs. Physical layers will register against it.
@@ -11,7 +11,7 @@ config NFC_MICROREAD_I2C
tristate "Inside Secure Microread device support (I2C)"
depends on NFC_HCI && I2C && NFC_SHDLC
select NFC_MICROREAD
- ---help---
+ help
This module adds support for the i2c interface of adapters using
Inside microread chipsets. Select this if your platform is using
the i2c bus.
@@ -23,7 +23,7 @@ config NFC_MICROREAD_MEI
tristate "Inside Secure Microread device support (MEI)"
depends on NFC_HCI && NFC_MEI_PHY
select NFC_MICROREAD
- ---help---
+ help
This module adds support for the mei interface of adapters using
Inside microread chipsets. Select this if your microread chipset
is handled by Intel's Management Engine Interface on your platform.
diff --git a/drivers/nfc/nxp-nci/Kconfig b/drivers/nfc/nxp-nci/Kconfig
index e1f71deab6fc..ab6db98b495d 100644
--- a/drivers/nfc/nxp-nci/Kconfig
+++ b/drivers/nfc/nxp-nci/Kconfig
@@ -2,7 +2,7 @@
config NFC_NXP_NCI
tristate "NXP-NCI NFC driver"
depends on NFC_NCI
- ---help---
+ help
Generic core driver for NXP NCI chips such as the NPC100 (PN547),
NPC300 (PN548) or PN7150 families.
This is a driver based on the NCI NFC kernel layers and
@@ -15,7 +15,7 @@ config NFC_NXP_NCI
config NFC_NXP_NCI_I2C
tristate "NXP-NCI I2C support"
depends on NFC_NXP_NCI && I2C
- ---help---
+ help
This module adds support for an I2C interface to the NXP NCI
chips.
Select this if your platform is using the I2C bus.
diff --git a/drivers/nfc/pn533/Kconfig b/drivers/nfc/pn533/Kconfig
index 7fe1bbe26568..31822b432d51 100644
--- a/drivers/nfc/pn533/Kconfig
+++ b/drivers/nfc/pn533/Kconfig
@@ -9,7 +9,7 @@ config NFC_PN533_USB
tristate "NFC PN533 device support (USB)"
depends on USB
select NFC_PN533
- ---help---
+ help
This module adds support for the NXP pn533 USB interface.
Select this if your platform is using the USB bus.
@@ -20,7 +20,7 @@ config NFC_PN533_I2C
tristate "NFC PN533 device support (I2C)"
depends on I2C
select NFC_PN533
- ---help---
+ help
This module adds support for the NXP pn533 I2C interface.
Select this if your platform is using the I2C bus.
@@ -31,7 +31,7 @@ config NFC_PN532_UART
tristate "NFC PN532 device support (UART)"
depends on SERIAL_DEV_BUS
select NFC_PN533
- ---help---
+ help
This module adds support for the NXP pn532 UART interface.
Select this if your platform is using the UART bus.
diff --git a/drivers/nfc/pn544/Kconfig b/drivers/nfc/pn544/Kconfig
index 47ef5e3f25ff..0fdc3108c528 100644
--- a/drivers/nfc/pn544/Kconfig
+++ b/drivers/nfc/pn544/Kconfig
@@ -2,7 +2,7 @@
config NFC_PN544
tristate
select CRC_CCITT
- ---help---
+ help
NXP PN544 core driver.
This is a driver based on the HCI NFC kernel layers and
will thus not work with NXP libnfc library.
@@ -11,7 +11,7 @@ config NFC_PN544_I2C
tristate "NXP PN544 device support (I2C)"
depends on NFC_HCI && I2C && NFC_SHDLC
select NFC_PN544
- ---help---
+ help
This module adds support for the NXP pn544 i2c interface.
Select this if your platform is using the i2c bus.
@@ -22,7 +22,7 @@ config NFC_PN544_MEI
tristate "NXP PN544 device support (MEI)"
depends on NFC_HCI && NFC_MEI_PHY
select NFC_PN544
- ---help---
+ help
This module adds support for the mei interface of adapters using
NXP pn544 chipsets. Select this if your pn544 chipset
is handled by Intel's Management Engine Interface on your platform.
diff --git a/drivers/nfc/s3fwrn5/Kconfig b/drivers/nfc/s3fwrn5/Kconfig
index c4e86df392a4..af9d18690afe 100644
--- a/drivers/nfc/s3fwrn5/Kconfig
+++ b/drivers/nfc/s3fwrn5/Kconfig
@@ -2,7 +2,7 @@
config NFC_S3FWRN5
tristate
select CRYPTO
- ---help---
+ help
Core driver for Samsung S3FWRN5 NFC chip. Contains core utilities
of chip. It's intended to be used by PHYs to avoid duplicating lots
of common code.
@@ -12,7 +12,7 @@ config NFC_S3FWRN5_I2C
depends on NFC_NCI && I2C
select NFC_S3FWRN5
default n
- ---help---
+ help
This module adds support for an I2C interface to the S3FWRN5 chip.
Select this if your platform is using the I2C bus.
diff --git a/drivers/nfc/st-nci/Kconfig b/drivers/nfc/st-nci/Kconfig
index 8fe53da46280..0e6909206999 100644
--- a/drivers/nfc/st-nci/Kconfig
+++ b/drivers/nfc/st-nci/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config NFC_ST_NCI
tristate
- ---help---
+ help
STMicroelectronics NFC NCI chips core driver. It implements the chipset
NCI logic and hooks into the NFC kernel APIs. Physical layers will
register against it.
@@ -10,7 +10,7 @@ config NFC_ST_NCI_I2C
tristate "STMicroelectronics ST NCI NFC driver (I2C)"
depends on NFC_NCI && I2C
select NFC_ST_NCI
- ---help---
+ help
This module adds support for an I2C interface to the
STMicroelectronics NFC NCI chips family.
Select this if your platform is using the i2c bus.
@@ -22,7 +22,7 @@ config NFC_ST_NCI_SPI
tristate "STMicroelectronics ST NCI NFC driver (SPI)"
depends on NFC_NCI && SPI
select NFC_ST_NCI
- ---help---
+ help
This module adds support for an SPI interface to the
STMicroelectronics NFC NCI chips family.
Select this if your platform is using the spi bus.
diff --git a/drivers/nfc/st21nfca/Kconfig b/drivers/nfc/st21nfca/Kconfig
index ab20724afe17..3407e9cfa140 100644
--- a/drivers/nfc/st21nfca/Kconfig
+++ b/drivers/nfc/st21nfca/Kconfig
@@ -2,7 +2,7 @@
config NFC_ST21NFCA
tristate
select CRC_CCITT
- ---help---
+ help
STMicroelectronics ST21NFCA core driver. It implements the chipset
HCI logic and hooks into the NFC kernel APIs. Physical layers will
register against it.
@@ -11,7 +11,7 @@ config NFC_ST21NFCA_I2C
tristate "STMicroelectronics ST21NFCA NFC driver (I2C)"
depends on NFC_HCI && I2C && NFC_SHDLC
select NFC_ST21NFCA
- ---help---
+ help
This module adds support for the STMicroelectronics st21nfca i2c interface.
Select this if your platform is using the i2c bus.
diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c
index 036e23aef9b0..39030a324d7f 100644
--- a/drivers/nvdimm/blk.c
+++ b/drivers/nvdimm/blk.c
@@ -165,7 +165,7 @@ static int nsblk_do_bvec(struct nd_namespace_blk *nsblk,
static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio)
{
struct bio_integrity_payload *bip;
- struct nd_namespace_blk *nsblk;
+ struct nd_namespace_blk *nsblk = bio->bi_disk->private_data;
struct bvec_iter iter;
unsigned long start;
struct bio_vec bvec;
@@ -176,7 +176,6 @@ static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio)
return BLK_QC_T_NONE;
bip = bio_integrity(bio);
- nsblk = q->queuedata;
rw = bio_data_dir(bio);
do_acct = blk_queue_io_stat(bio->bi_disk->queue);
if (do_acct)
@@ -260,7 +259,6 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
blk_queue_max_hw_sectors(q, UINT_MAX);
blk_queue_logical_block_size(q, nsblk_sector_size(nsblk));
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
- q->queuedata = nsblk;
disk = alloc_disk(0);
if (!disk)
@@ -270,6 +268,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
disk->fops = &nd_blk_fops;
disk->queue = q;
disk->flags = GENHD_FL_EXT_DEVT;
+ disk->private_data = nsblk;
nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name);
if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 90c0c4bbe77b..48e9d169b6f9 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1442,7 +1442,7 @@ static int btt_do_bvec(struct btt *btt, struct bio_integrity_payload *bip,
static blk_qc_t btt_make_request(struct request_queue *q, struct bio *bio)
{
struct bio_integrity_payload *bip = bio_integrity(bio);
- struct btt *btt = q->queuedata;
+ struct btt *btt = bio->bi_disk->private_data;
struct bvec_iter iter;
unsigned long start;
struct bio_vec bvec;
@@ -1545,7 +1545,6 @@ static int btt_blk_init(struct btt *btt)
blk_queue_logical_block_size(btt->btt_queue, btt->sector_size);
blk_queue_max_hw_sectors(btt->btt_queue, UINT_MAX);
blk_queue_flag_set(QUEUE_FLAG_NONROT, btt->btt_queue);
- btt->btt_queue->queuedata = btt;
if (btt_meta_size(btt)) {
int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 97f948f8f4e6..d25e66fd942d 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -7,7 +7,6 @@
* Copyright (c) 2015, Boaz Harrosh <boaz@plexistor.com>.
*/
-#include <asm/cacheflush.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/init.h>
@@ -25,6 +24,8 @@
#include <linux/dax.h>
#include <linux/nd.h>
#include <linux/backing-dev.h>
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
#include "pmem.h"
#include "pfn.h"
#include "nd.h"
@@ -196,7 +197,7 @@ static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio)
unsigned long start;
struct bio_vec bvec;
struct bvec_iter iter;
- struct pmem_device *pmem = q->queuedata;
+ struct pmem_device *pmem = bio->bi_disk->private_data;
struct nd_region *nd_region = to_region(pmem);
if (bio->bi_opf & REQ_PREFLUSH)
@@ -233,7 +234,7 @@ static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio)
static int pmem_rw_page(struct block_device *bdev, sector_t sector,
struct page *page, unsigned int op)
{
- struct pmem_device *pmem = bdev->bd_queue->queuedata;
+ struct pmem_device *pmem = bdev->bd_disk->private_data;
blk_status_t rc;
if (op_is_write(op))
@@ -466,7 +467,6 @@ static int pmem_attach_disk(struct device *dev,
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
if (pmem->pfn_flags & PFN_MAP)
blk_queue_flag_set(QUEUE_FLAG_DAX, q);
- q->queuedata = pmem;
disk = alloc_disk_node(0, nid);
if (!disk)
@@ -476,6 +476,7 @@ static int pmem_attach_disk(struct device *dev,
disk->fops = &pmem_fops;
disk->queue = q;
disk->flags = GENHD_FL_EXT_DEVT;
+ disk->private_data = pmem;
disk->queue->backing_dev_info->capabilities |= BDI_CAP_SYNCHRONOUS_IO;
nvdimm_namespace_disk_name(ndns, disk->disk_name);
set_capacity(disk, (pmem->size - pmem->pfn_pad - pmem->data_offset)
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index 9c17ed32be64..3ed9786b88d8 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -7,7 +7,7 @@ config BLK_DEV_NVME
tristate "NVM Express block device"
depends on PCI && BLOCK
select NVME_CORE
- ---help---
+ help
The NVM Express driver is for solid state drives directly
connected to the PCI or PCI Express bus. If you know you
don't have one of these, it is safe to answer N.
@@ -18,7 +18,7 @@ config BLK_DEV_NVME
config NVME_MULTIPATH
bool "NVMe multipath support"
depends on NVME_CORE
- ---help---
+ 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 namespaces,
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 0585efa47d8f..c2c5bc4fb702 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3669,7 +3669,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
ns->disk = disk;
if (__nvme_revalidate_disk(disk, id))
- goto out_free_disk;
+ goto out_put_disk;
if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) {
ret = nvme_nvm_register(ns, disk_name, node);
@@ -3696,8 +3696,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
/* prevent double queue cleanup */
ns->disk->queue = NULL;
put_disk(ns->disk);
- out_free_disk:
- del_gendisk(ns->disk);
out_unlink_ns:
mutex_lock(&ctrl->subsys->lock);
list_del_rcu(&ns->siblings);
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index cb0007592c12..e999a8c4b7e8 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -2634,10 +2634,11 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE);
__nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate);
- if (!(op->flags & FCOP_FLAGS_AEN))
+ if (!(op->flags & FCOP_FLAGS_AEN)) {
nvme_fc_unmap_data(ctrl, op->rq, op);
+ nvme_cleanup_cmd(op->rq);
+ }
- nvme_cleanup_cmd(op->rq);
nvme_fc_ctrl_put(ctrl);
if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE &&
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index fa5c75501049..c0f4226d3299 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -599,8 +599,7 @@ static inline void nvme_trace_bio_complete(struct request *req,
struct nvme_ns *ns = req->q->queuedata;
if (req->cmd_flags & REQ_NVME_MPATH)
- trace_block_bio_complete(ns->head->disk->queue,
- req->bio, status);
+ trace_block_bio_complete(ns->head->disk->queue, req->bio);
}
extern struct device_attribute dev_attr_ana_grpid;
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d690d5593a80..e2bacd369a88 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2950,9 +2950,15 @@ static int nvme_suspend(struct device *dev)
* the PCI bus layer to put it into D3 in order to take the PCIe link
* down, so as to allow the platform to achieve its minimum low-power
* state (which may not be possible if the link is up).
+ *
+ * If a host memory buffer is enabled, shut down the device as the NVMe
+ * specification allows the device to access the host memory buffer in
+ * host DRAM from all power states, but hosts will fail access to DRAM
+ * during S3.
*/
if (pm_suspend_via_firmware() || !ctrl->npss ||
!pcie_aspm_enabled(pdev) ||
+ ndev->nr_host_mem_descs ||
(ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND))
return nvme_disable_prepare_reset(ndev, true);
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 1843110ec34f..3345ec7efaff 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -131,8 +131,8 @@ struct nvme_tcp_ctrl {
static LIST_HEAD(nvme_tcp_ctrl_list);
static DEFINE_MUTEX(nvme_tcp_ctrl_mutex);
static struct workqueue_struct *nvme_tcp_wq;
-static struct blk_mq_ops nvme_tcp_mq_ops;
-static struct blk_mq_ops nvme_tcp_admin_mq_ops;
+static const struct blk_mq_ops nvme_tcp_mq_ops;
+static const struct blk_mq_ops nvme_tcp_admin_mq_ops;
static int nvme_tcp_try_send(struct nvme_tcp_queue *queue);
static inline struct nvme_tcp_ctrl *to_tcp_ctrl(struct nvme_ctrl *ctrl)
@@ -2301,7 +2301,7 @@ static int nvme_tcp_poll(struct blk_mq_hw_ctx *hctx)
return queue->nr_cqe;
}
-static struct blk_mq_ops nvme_tcp_mq_ops = {
+static const struct blk_mq_ops nvme_tcp_mq_ops = {
.queue_rq = nvme_tcp_queue_rq,
.complete = nvme_complete_rq,
.init_request = nvme_tcp_init_request,
@@ -2312,7 +2312,7 @@ static struct blk_mq_ops nvme_tcp_mq_ops = {
.poll = nvme_tcp_poll,
};
-static struct blk_mq_ops nvme_tcp_admin_mq_ops = {
+static const struct blk_mq_ops nvme_tcp_admin_mq_ops = {
.queue_rq = nvme_tcp_queue_rq,
.complete = nvme_complete_rq,
.init_request = nvme_tcp_init_request,
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 6392bcd30bd7..6e2f623e472e 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -129,7 +129,22 @@ static u32 nvmet_async_event_result(struct nvmet_async_event *aen)
return aen->event_type | (aen->event_info << 8) | (aen->log_page << 16);
}
-static void nvmet_async_events_process(struct nvmet_ctrl *ctrl, u16 status)
+static void nvmet_async_events_failall(struct nvmet_ctrl *ctrl)
+{
+ u16 status = NVME_SC_INTERNAL | NVME_SC_DNR;
+ struct nvmet_req *req;
+
+ mutex_lock(&ctrl->lock);
+ while (ctrl->nr_async_event_cmds) {
+ req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds];
+ mutex_unlock(&ctrl->lock);
+ nvmet_req_complete(req, status);
+ mutex_lock(&ctrl->lock);
+ }
+ mutex_unlock(&ctrl->lock);
+}
+
+static void nvmet_async_events_process(struct nvmet_ctrl *ctrl)
{
struct nvmet_async_event *aen;
struct nvmet_req *req;
@@ -139,15 +154,14 @@ static void nvmet_async_events_process(struct nvmet_ctrl *ctrl, u16 status)
aen = list_first_entry(&ctrl->async_events,
struct nvmet_async_event, entry);
req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds];
- if (status == 0)
- nvmet_set_result(req, nvmet_async_event_result(aen));
+ nvmet_set_result(req, nvmet_async_event_result(aen));
list_del(&aen->entry);
kfree(aen);
mutex_unlock(&ctrl->lock);
trace_nvmet_async_event(ctrl, req->cqe->result.u32);
- nvmet_req_complete(req, status);
+ nvmet_req_complete(req, 0);
mutex_lock(&ctrl->lock);
}
mutex_unlock(&ctrl->lock);
@@ -170,7 +184,7 @@ static void nvmet_async_event_work(struct work_struct *work)
struct nvmet_ctrl *ctrl =
container_of(work, struct nvmet_ctrl, async_event_work);
- nvmet_async_events_process(ctrl, 0);
+ nvmet_async_events_process(ctrl);
}
void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
@@ -779,7 +793,6 @@ static void nvmet_confirm_sq(struct percpu_ref *ref)
void nvmet_sq_destroy(struct nvmet_sq *sq)
{
- u16 status = NVME_SC_INTERNAL | NVME_SC_DNR;
struct nvmet_ctrl *ctrl = sq->ctrl;
/*
@@ -787,7 +800,7 @@ void nvmet_sq_destroy(struct nvmet_sq *sq)
* queue doesn't have outstanding requests on it.
*/
if (ctrl && ctrl->sqs && ctrl->sqs[0] == sq)
- nvmet_async_events_process(ctrl, status);
+ nvmet_async_events_failall(ctrl);
percpu_ref_kill_and_confirm(&sq->ref, nvmet_confirm_sq);
wait_for_completion(&sq->confirm_done);
wait_for_completion(&sq->free_done);
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 1669177cd26c..de9217cfd22d 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -153,7 +153,7 @@ static LIST_HEAD(nvmet_tcp_queue_list);
static DEFINE_MUTEX(nvmet_tcp_queue_mutex);
static struct workqueue_struct *nvmet_tcp_wq;
-static struct nvmet_fabrics_ops nvmet_tcp_ops;
+static const struct nvmet_fabrics_ops nvmet_tcp_ops;
static void nvmet_tcp_free_cmd(struct nvmet_tcp_cmd *c);
static void nvmet_tcp_finish_cmd(struct nvmet_tcp_cmd *cmd);
@@ -1713,7 +1713,7 @@ static void nvmet_tcp_disc_port_addr(struct nvmet_req *req,
}
}
-static struct nvmet_fabrics_ops nvmet_tcp_ops = {
+static const struct nvmet_fabrics_ops nvmet_tcp_ops = {
.owner = THIS_MODULE,
.type = NVMF_TRTYPE_TCP,
.msdbd = 1,
diff --git a/drivers/opp/Kconfig b/drivers/opp/Kconfig
index 35dfc7e80f92..e8ce47b32735 100644
--- a/drivers/opp/Kconfig
+++ b/drivers/opp/Kconfig
@@ -2,7 +2,7 @@
config PM_OPP
bool
select SRCU
- ---help---
+ help
SOCs have a standard set of tuples consisting of frequency and
voltage pairs that the device will support per voltage domain. This
is called Operating Performance Point or OPP. The actual definitions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index e4f01e7771a2..dfbd3d10410c 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -664,7 +664,7 @@ static inline int _generic_set_opp_clk_only(struct device *dev, struct clk *clk,
return ret;
}
-static int _generic_set_opp_regulator(const struct opp_table *opp_table,
+static int _generic_set_opp_regulator(struct opp_table *opp_table,
struct device *dev,
unsigned long old_freq,
unsigned long freq,
@@ -699,6 +699,18 @@ static int _generic_set_opp_regulator(const struct opp_table *opp_table,
goto restore_freq;
}
+ /*
+ * Enable the regulator after setting its voltages, otherwise it breaks
+ * some boot-enabled regulators.
+ */
+ if (unlikely(!opp_table->regulator_enabled)) {
+ ret = regulator_enable(reg);
+ if (ret < 0)
+ dev_warn(dev, "Failed to enable regulator: %d", ret);
+ else
+ opp_table->regulator_enabled = true;
+ }
+
return 0;
restore_freq:
@@ -713,6 +725,34 @@ restore_voltage:
return ret;
}
+static int _set_opp_bw(const struct opp_table *opp_table,
+ struct dev_pm_opp *opp, struct device *dev, bool remove)
+{
+ u32 avg, peak;
+ int i, ret;
+
+ if (!opp_table->paths)
+ return 0;
+
+ for (i = 0; i < opp_table->path_count; i++) {
+ if (remove) {
+ avg = 0;
+ peak = 0;
+ } else {
+ avg = opp->bandwidth[i].avg;
+ peak = opp->bandwidth[i].peak;
+ }
+ ret = icc_set_bw(opp_table->paths[i], avg, peak);
+ if (ret) {
+ dev_err(dev, "Failed to %s bandwidth[%d]: %d\n",
+ remove ? "remove" : "set", i, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int _set_opp_custom(const struct opp_table *opp_table,
struct device *dev, unsigned long old_freq,
unsigned long freq,
@@ -817,15 +857,31 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
}
if (unlikely(!target_freq)) {
- if (opp_table->required_opp_tables) {
- ret = _set_required_opps(dev, opp_table, NULL);
- } else if (!_get_opp_count(opp_table)) {
+ /*
+ * Some drivers need to support cases where some platforms may
+ * have OPP table for the device, while others don't and
+ * opp_set_rate() just needs to behave like clk_set_rate().
+ */
+ if (!_get_opp_count(opp_table))
return 0;
- } else {
+
+ if (!opp_table->required_opp_tables && !opp_table->regulators &&
+ !opp_table->paths) {
dev_err(dev, "target frequency can't be 0\n");
ret = -EINVAL;
+ goto put_opp_table;
+ }
+
+ ret = _set_opp_bw(opp_table, NULL, dev, true);
+ if (ret)
+ return ret;
+
+ if (opp_table->regulator_enabled) {
+ regulator_disable(opp_table->regulators[0]);
+ opp_table->regulator_enabled = false;
}
+ ret = _set_required_opps(dev, opp_table, NULL);
goto put_opp_table;
}
@@ -909,6 +965,9 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
dev_err(dev, "Failed to set required opps: %d\n", ret);
}
+ if (!ret)
+ ret = _set_opp_bw(opp_table, opp, dev, false);
+
put_opp:
dev_pm_opp_put(opp);
put_old_opp:
@@ -999,6 +1058,12 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index)
ret);
}
+ /* Find interconnect path(s) for the device */
+ ret = dev_pm_opp_of_find_icc_paths(dev, opp_table);
+ if (ret)
+ dev_warn(dev, "%s: Error finding interconnect paths: %d\n",
+ __func__, ret);
+
BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head);
INIT_LIST_HEAD(&opp_table->opp_list);
kref_init(&opp_table->kref);
@@ -1057,6 +1122,7 @@ static void _opp_table_kref_release(struct kref *kref)
{
struct opp_table *opp_table = container_of(kref, struct opp_table, kref);
struct opp_device *opp_dev, *temp;
+ int i;
_of_clear_opp_table(opp_table);
@@ -1064,6 +1130,12 @@ static void _opp_table_kref_release(struct kref *kref)
if (!IS_ERR(opp_table->clk))
clk_put(opp_table->clk);
+ if (opp_table->paths) {
+ for (i = 0; i < opp_table->path_count; i++)
+ icc_put(opp_table->paths[i]);
+ kfree(opp_table->paths);
+ }
+
WARN_ON(!list_empty(&opp_table->opp_list));
list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) {
@@ -1243,19 +1315,23 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_remove_all_dynamic);
struct dev_pm_opp *_opp_allocate(struct opp_table *table)
{
struct dev_pm_opp *opp;
- int count, supply_size;
+ int supply_count, supply_size, icc_size;
/* Allocate space for at least one supply */
- count = table->regulator_count > 0 ? table->regulator_count : 1;
- supply_size = sizeof(*opp->supplies) * count;
+ supply_count = table->regulator_count > 0 ? table->regulator_count : 1;
+ supply_size = sizeof(*opp->supplies) * supply_count;
+ icc_size = sizeof(*opp->bandwidth) * table->path_count;
/* allocate new OPP node and supplies structures */
- opp = kzalloc(sizeof(*opp) + supply_size, GFP_KERNEL);
+ opp = kzalloc(sizeof(*opp) + supply_size + icc_size, GFP_KERNEL);
+
if (!opp)
return NULL;
/* Put the supplies at the end of the OPP structure as an empty array */
opp->supplies = (struct dev_pm_opp_supply *)(opp + 1);
+ if (icc_size)
+ opp->bandwidth = (struct dev_pm_opp_icc_bw *)(opp->supplies + supply_count);
INIT_LIST_HEAD(&opp->node);
return opp;
@@ -1286,11 +1362,24 @@ static bool _opp_supported_by_regulators(struct dev_pm_opp *opp,
return true;
}
+int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2)
+{
+ if (opp1->rate != opp2->rate)
+ return opp1->rate < opp2->rate ? -1 : 1;
+ if (opp1->bandwidth && opp2->bandwidth &&
+ opp1->bandwidth[0].peak != opp2->bandwidth[0].peak)
+ return opp1->bandwidth[0].peak < opp2->bandwidth[0].peak ? -1 : 1;
+ if (opp1->level != opp2->level)
+ return opp1->level < opp2->level ? -1 : 1;
+ return 0;
+}
+
static int _opp_is_duplicate(struct device *dev, struct dev_pm_opp *new_opp,
struct opp_table *opp_table,
struct list_head **head)
{
struct dev_pm_opp *opp;
+ int opp_cmp;
/*
* Insert new OPP in order of increasing frequency and discard if
@@ -1301,12 +1390,13 @@ static int _opp_is_duplicate(struct device *dev, struct dev_pm_opp *new_opp,
* loop.
*/
list_for_each_entry(opp, &opp_table->opp_list, node) {
- if (new_opp->rate > opp->rate) {
+ opp_cmp = _opp_compare_key(new_opp, opp);
+ if (opp_cmp > 0) {
*head = &opp->node;
continue;
}
- if (new_opp->rate < opp->rate)
+ if (opp_cmp < 0)
return 0;
/* Duplicate OPPs */
@@ -1670,6 +1760,13 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
/* Make sure there are no concurrent readers while updating opp_table */
WARN_ON(!list_empty(&opp_table->opp_list));
+ if (opp_table->regulator_enabled) {
+ for (i = opp_table->regulator_count - 1; i >= 0; i--)
+ regulator_disable(opp_table->regulators[i]);
+
+ opp_table->regulator_enabled = false;
+ }
+
for (i = opp_table->regulator_count - 1; i >= 0; i--)
regulator_put(opp_table->regulators[i]);
diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
index 609665e339b6..596c185b5dda 100644
--- a/drivers/opp/debugfs.c
+++ b/drivers/opp/debugfs.c
@@ -32,6 +32,47 @@ void opp_debug_remove_one(struct dev_pm_opp *opp)
debugfs_remove_recursive(opp->dentry);
}
+static ssize_t bw_name_read(struct file *fp, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct icc_path *path = fp->private_data;
+ char buf[64];
+ int i;
+
+ i = scnprintf(buf, sizeof(buf), "%.62s\n", icc_get_name(path));
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, i);
+}
+
+static const struct file_operations bw_name_fops = {
+ .open = simple_open,
+ .read = bw_name_read,
+ .llseek = default_llseek,
+};
+
+static void opp_debug_create_bw(struct dev_pm_opp *opp,
+ struct opp_table *opp_table,
+ struct dentry *pdentry)
+{
+ struct dentry *d;
+ char name[11];
+ int i;
+
+ for (i = 0; i < opp_table->path_count; i++) {
+ snprintf(name, sizeof(name), "icc-path-%.1d", i);
+
+ /* Create per-path directory */
+ d = debugfs_create_dir(name, pdentry);
+
+ debugfs_create_file("name", S_IRUGO, d, opp_table->paths[i],
+ &bw_name_fops);
+ debugfs_create_u32("peak_bw", S_IRUGO, d,
+ &opp->bandwidth[i].peak);
+ debugfs_create_u32("avg_bw", S_IRUGO, d,
+ &opp->bandwidth[i].avg);
+ }
+}
+
static void opp_debug_create_supplies(struct dev_pm_opp *opp,
struct opp_table *opp_table,
struct dentry *pdentry)
@@ -94,6 +135,7 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
&opp->clock_latency_ns);
opp_debug_create_supplies(opp, opp_table, d);
+ opp_debug_create_bw(opp, opp_table, d);
opp->dentry = d;
}
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index 9cd8f0adacae..9a5873591a40 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -332,6 +332,105 @@ free_required_opps:
return ret;
}
+static int _bandwidth_supported(struct device *dev, struct opp_table *opp_table)
+{
+ struct device_node *np, *opp_np;
+ struct property *prop;
+
+ if (!opp_table) {
+ np = of_node_get(dev->of_node);
+ if (!np)
+ return -ENODEV;
+
+ opp_np = _opp_of_get_opp_desc_node(np, 0);
+ of_node_put(np);
+ } else {
+ opp_np = of_node_get(opp_table->np);
+ }
+
+ /* Lets not fail in case we are parsing opp-v1 bindings */
+ if (!opp_np)
+ return 0;
+
+ /* Checking only first OPP is sufficient */
+ np = of_get_next_available_child(opp_np, NULL);
+ if (!np) {
+ dev_err(dev, "OPP table empty\n");
+ return -EINVAL;
+ }
+ of_node_put(opp_np);
+
+ prop = of_find_property(np, "opp-peak-kBps", NULL);
+ of_node_put(np);
+
+ if (!prop || !prop->length)
+ return 0;
+
+ return 1;
+}
+
+int dev_pm_opp_of_find_icc_paths(struct device *dev,
+ struct opp_table *opp_table)
+{
+ struct device_node *np;
+ int ret, i, count, num_paths;
+ struct icc_path **paths;
+
+ ret = _bandwidth_supported(dev, opp_table);
+ if (ret <= 0)
+ return ret;
+
+ ret = 0;
+
+ np = of_node_get(dev->of_node);
+ if (!np)
+ return 0;
+
+ count = of_count_phandle_with_args(np, "interconnects",
+ "#interconnect-cells");
+ of_node_put(np);
+ if (count < 0)
+ return 0;
+
+ /* two phandles when #interconnect-cells = <1> */
+ if (count % 2) {
+ dev_err(dev, "%s: Invalid interconnects values\n", __func__);
+ return -EINVAL;
+ }
+
+ num_paths = count / 2;
+ paths = kcalloc(num_paths, sizeof(*paths), GFP_KERNEL);
+ if (!paths)
+ return -ENOMEM;
+
+ for (i = 0; i < num_paths; i++) {
+ paths[i] = of_icc_get_by_index(dev, i);
+ if (IS_ERR(paths[i])) {
+ ret = PTR_ERR(paths[i]);
+ if (ret != -EPROBE_DEFER) {
+ dev_err(dev, "%s: Unable to get path%d: %d\n",
+ __func__, i, ret);
+ }
+ goto err;
+ }
+ }
+
+ if (opp_table) {
+ opp_table->paths = paths;
+ opp_table->path_count = num_paths;
+ return 0;
+ }
+
+err:
+ while (i--)
+ icc_put(paths[i]);
+
+ kfree(paths);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_of_find_icc_paths);
+
static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
struct device_node *np)
{
@@ -521,6 +620,90 @@ void dev_pm_opp_of_remove_table(struct device *dev)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
+static int _read_bw(struct dev_pm_opp *new_opp, struct opp_table *table,
+ struct device_node *np, bool peak)
+{
+ const char *name = peak ? "opp-peak-kBps" : "opp-avg-kBps";
+ struct property *prop;
+ int i, count, ret;
+ u32 *bw;
+
+ prop = of_find_property(np, name, NULL);
+ if (!prop)
+ return -ENODEV;
+
+ count = prop->length / sizeof(u32);
+ if (table->path_count != count) {
+ pr_err("%s: Mismatch between %s and paths (%d %d)\n",
+ __func__, name, count, table->path_count);
+ return -EINVAL;
+ }
+
+ bw = kmalloc_array(count, sizeof(*bw), GFP_KERNEL);
+ if (!bw)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(np, name, bw, count);
+ if (ret) {
+ pr_err("%s: Error parsing %s: %d\n", __func__, name, ret);
+ goto out;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (peak)
+ new_opp->bandwidth[i].peak = kBps_to_icc(bw[i]);
+ else
+ new_opp->bandwidth[i].avg = kBps_to_icc(bw[i]);
+ }
+
+out:
+ kfree(bw);
+ return ret;
+}
+
+static int _read_opp_key(struct dev_pm_opp *new_opp, struct opp_table *table,
+ struct device_node *np, bool *rate_not_available)
+{
+ bool found = false;
+ u64 rate;
+ int ret;
+
+ ret = of_property_read_u64(np, "opp-hz", &rate);
+ if (!ret) {
+ /*
+ * Rate is defined as an unsigned long in clk API, and so
+ * casting explicitly to its type. Must be fixed once rate is 64
+ * bit guaranteed in clk API.
+ */
+ new_opp->rate = (unsigned long)rate;
+ found = true;
+ }
+ *rate_not_available = !!ret;
+
+ /*
+ * Bandwidth consists of peak and average (optional) values:
+ * opp-peak-kBps = <path1_value path2_value>;
+ * opp-avg-kBps = <path1_value path2_value>;
+ */
+ ret = _read_bw(new_opp, table, np, true);
+ if (!ret) {
+ found = true;
+ ret = _read_bw(new_opp, table, np, false);
+ }
+
+ /* The properties were found but we failed to parse them */
+ if (ret && ret != -ENODEV)
+ return ret;
+
+ if (!of_property_read_u32(np, "opp-level", &new_opp->level))
+ found = true;
+
+ if (found)
+ return 0;
+
+ return ret;
+}
+
/**
* _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
* @opp_table: OPP table
@@ -558,26 +741,12 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
if (!new_opp)
return ERR_PTR(-ENOMEM);
- ret = of_property_read_u64(np, "opp-hz", &rate);
- if (ret < 0) {
- /* "opp-hz" is optional for devices like power domains. */
- if (!opp_table->is_genpd) {
- dev_err(dev, "%s: opp-hz not found\n", __func__);
- goto free_opp;
- }
-
- rate_not_available = true;
- } else {
- /*
- * Rate is defined as an unsigned long in clk API, and so
- * casting explicitly to its type. Must be fixed once rate is 64
- * bit guaranteed in clk API.
- */
- new_opp->rate = (unsigned long)rate;
+ ret = _read_opp_key(new_opp, opp_table, np, &rate_not_available);
+ if (ret < 0 && !opp_table->is_genpd) {
+ dev_err(dev, "%s: opp key field not found\n", __func__);
+ goto free_opp;
}
- of_property_read_u32(np, "opp-level", &new_opp->level);
-
/* Check if the OPP supports hardware's hierarchy of versions or not */
if (!_opp_is_supported(dev, opp_table, np)) {
dev_dbg(dev, "OPP not supported by hardware: %llu\n", rate);
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index d14e27102730..e51646ff279e 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h
@@ -12,6 +12,7 @@
#define __DRIVER_OPP_H__
#include <linux/device.h>
+#include <linux/interconnect.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
@@ -59,6 +60,7 @@ extern struct list_head opp_tables;
* @rate: Frequency in hertz
* @level: Performance level
* @supplies: Power supplies voltage/current values
+ * @bandwidth: Interconnect bandwidth values
* @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's
* frequency from any other OPP's frequency.
* @required_opps: List of OPPs that are required by this OPP.
@@ -81,6 +83,7 @@ struct dev_pm_opp {
unsigned int level;
struct dev_pm_opp_supply *supplies;
+ struct dev_pm_opp_icc_bw *bandwidth;
unsigned long clock_latency_ns;
@@ -144,8 +147,11 @@ enum opp_table_access {
* @clk: Device's clock handle
* @regulators: Supply regulators
* @regulator_count: Number of power supply regulators. Its value can be -1
+ * @regulator_enabled: Set to true if regulators were previously enabled.
* (uninitialized), 0 (no opp-microvolt property) or > 0 (has opp-microvolt
* property).
+ * @paths: Interconnect path handles
+ * @path_count: Number of interconnect paths
* @genpd_performance_state: Device's power domain support performance state.
* @is_genpd: Marks if the OPP table belongs to a genpd.
* @set_opp: Platform specific set_opp callback
@@ -189,6 +195,9 @@ struct opp_table {
struct clk *clk;
struct regulator **regulators;
int regulator_count;
+ bool regulator_enabled;
+ struct icc_path **paths;
+ unsigned int path_count;
bool genpd_performance_state;
bool is_genpd;
@@ -211,6 +220,7 @@ struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_
void _dev_pm_opp_find_and_remove_table(struct device *dev);
struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);
void _opp_free(struct dev_pm_opp *opp);
+int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2);
int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table, bool rate_not_available);
int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic);
void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int last_cpu);
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index ac27f3d3fbb4..4d7695289eda 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -91,11 +91,11 @@ munmap_notify(struct notifier_block *self, unsigned long val, void *data)
struct mm_struct *mm = current->mm;
struct vm_area_struct *mpnt;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
mpnt = find_vma(mm, addr);
if (mpnt && mpnt->vm_file && (mpnt->vm_flags & VM_EXEC)) {
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
/* To avoid latency problems, we only process the current CPU,
* hoping that most samples for the task are on this CPU
*/
@@ -103,7 +103,7 @@ munmap_notify(struct notifier_block *self, unsigned long val, void *data)
return 0;
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return 0;
}
@@ -256,7 +256,7 @@ lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset)
unsigned long cookie = NO_COOKIE;
struct vm_area_struct *vma;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
if (addr < vma->vm_start || addr >= vma->vm_end)
@@ -276,7 +276,7 @@ lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset)
if (!vma)
cookie = INVALID_COOKIE;
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return cookie;
}
@@ -486,7 +486,7 @@ typedef enum {
/* Sync one of the CPU's buffers into the global event buffer.
* Here we need to go through each batch of samples punctuated
- * by context switch notes, taking the task's mmap_sem and doing
+ * by context switch notes, taking the task's mmap_lock and doing
* lookup in task->mm->mmap to convert EIP into dcookie/offset
* value.
*/
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index 1791830e7a71..e78a9f0302c7 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -15,7 +15,7 @@ config ARCH_MIGHT_HAVE_PC_PARPORT
menuconfig PARPORT
tristate "Parallel port support"
depends on HAS_IOMEM
- ---help---
+ help
If you want to use devices connected to your machine's parallel port
(the connector at the computer with 25 holes), e.g. printer, ZIP
drive, PLIP link (Parallel Line Internet Protocol is mainly used to
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index 390e92f2d8d1..b761c1f72f67 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -31,6 +31,22 @@ void pci_ats_init(struct pci_dev *dev)
}
/**
+ * pci_ats_supported - check if the device can use ATS
+ * @dev: the PCI device
+ *
+ * Returns true if the device supports ATS and is allowed to use it, false
+ * otherwise.
+ */
+bool pci_ats_supported(struct pci_dev *dev)
+{
+ if (!dev->ats_cap)
+ return false;
+
+ return (dev->untrusted == 0);
+}
+EXPORT_SYMBOL_GPL(pci_ats_supported);
+
+/**
* pci_enable_ats - enable the ATS capability
* @dev: the PCI device
* @ps: the IOMMU page shift
@@ -42,7 +58,7 @@ int pci_enable_ats(struct pci_dev *dev, int ps)
u16 ctrl;
struct pci_dev *pdev;
- if (!dev->ats_cap)
+ if (!pci_ats_supported(dev))
return -EINVAL;
if (WARN_ON(dev->ats_enabled))
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index b08efea39496..adddf21fa381 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -248,7 +248,7 @@ config PCIE_TANGO_SMP8759
config VMD
depends on PCI_MSI && X86_64 && SRCU
tristate "Intel Volume Management Device Driver"
- ---help---
+ help
Adds support for the Intel Volume Management Device (VMD). VMD is a
secondary PCI host bridge that allows PCI Express root ports,
and devices attached to them, to be removed from the default
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 32455a79372d..840a84bb5ee2 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -6,7 +6,7 @@
menuconfig HOTPLUG_PCI
bool "Support for PCI Hotplug"
depends on PCI && SYSFS
- ---help---
+ help
Say Y here if you have a motherboard with a PCI Hotplug controller.
This allows you to add and remove PCI cards while the machine is
powered up and running.
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 39295d88f670..b59f84918fe0 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -52,6 +52,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
{
struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
hotplug_slot);
+ struct zpci_bus *zbus = zdev->zbus;
int rc;
if (zdev->state != ZPCI_FN_STATE_STANDBY)
@@ -65,9 +66,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
if (rc)
goto out_deconfigure;
- pci_scan_slot(zdev->bus, ZPCI_DEVFN);
+ pci_scan_slot(zbus->bus, zdev->devfn);
pci_lock_rescan_remove();
- pci_bus_add_devices(zdev->bus);
+ pci_bus_add_devices(zbus->bus);
pci_unlock_rescan_remove();
return rc;
@@ -82,13 +83,17 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
hotplug_slot);
struct pci_dev *pdev;
+ struct zpci_bus *zbus = zdev->zbus;
int rc;
if (!zpci_fn_configured(zdev->state))
return -EIO;
- pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
+ pdev = pci_get_slot(zbus->bus, zdev->devfn);
if (pdev) {
+ if (pci_num_vf(pdev))
+ return -EBUSY;
+
pci_stop_and_remove_bus_device_locked(pdev);
pci_dev_put(pdev);
}
@@ -133,12 +138,13 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = {
int zpci_init_slot(struct zpci_dev *zdev)
{
char name[SLOT_NAME_SIZE];
+ struct zpci_bus *zbus = zdev->zbus;
zdev->hotplug_slot.ops = &s390_hotplug_slot_ops;
snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
- return pci_hp_register(&zdev->hotplug_slot, zdev->bus,
- ZPCI_DEVFN, name);
+ return pci_hp_register(&zdev->hotplug_slot, zbus->bus,
+ zdev->devfn, name);
}
void zpci_exit_slot(struct zpci_dev *zdev)
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 4d1f392b05f9..b37e08c4f9d1 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -133,12 +133,35 @@ static void pci_read_vf_config_common(struct pci_dev *virtfn)
&physfn->sriov->subsystem_device);
}
+int pci_iov_sysfs_link(struct pci_dev *dev,
+ struct pci_dev *virtfn, int id)
+{
+ char buf[VIRTFN_ID_LEN];
+ int rc;
+
+ sprintf(buf, "virtfn%u", id);
+ rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+ if (rc)
+ goto failed;
+ rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
+ if (rc)
+ goto failed1;
+
+ kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
+
+ return 0;
+
+failed1:
+ sysfs_remove_link(&dev->dev.kobj, buf);
+failed:
+ return rc;
+}
+
int pci_iov_add_virtfn(struct pci_dev *dev, int id)
{
int i;
int rc = -ENOMEM;
u64 size;
- char buf[VIRTFN_ID_LEN];
struct pci_dev *virtfn;
struct resource *res;
struct pci_sriov *iov = dev->sriov;
@@ -182,23 +205,14 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id)
}
pci_device_add(virtfn, virtfn->bus);
-
- sprintf(buf, "virtfn%u", id);
- rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+ rc = pci_iov_sysfs_link(dev, virtfn, id);
if (rc)
goto failed1;
- rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
- if (rc)
- goto failed2;
-
- kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
pci_bus_add_device(virtfn);
return 0;
-failed2:
- sysfs_remove_link(&dev->dev.kobj, buf);
failed1:
pci_stop_and_remove_bus_device(virtfn);
pci_dev_put(dev);
@@ -557,9 +571,6 @@ static void sriov_del_vfs(struct pci_dev *dev)
struct pci_sriov *iov = dev->sriov;
int i;
- if (dev->no_vf_scan)
- return;
-
for (i = 0; i < iov->num_VFs; i++)
pci_iov_remove_virtfn(dev, i);
}
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index d1b16cf3403f..fab267e359e7 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -77,9 +77,6 @@ static inline void pcifront_init_sd(struct pcifront_sd *sd,
static DEFINE_SPINLOCK(pcifront_dev_lock);
static struct pcifront_device *pcifront_dev;
-static int verbose_request;
-module_param(verbose_request, int, 0644);
-
static int errno_to_pcibios_err(int errno)
{
switch (errno) {
@@ -190,18 +187,16 @@ static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
struct pcifront_sd *sd = bus->sysdata;
struct pcifront_device *pdev = pcifront_get_pdev(sd);
- if (verbose_request)
- dev_info(&pdev->xdev->dev,
- "read dev=%04x:%02x:%02x.%d - offset %x size %d\n",
- pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
- PCI_FUNC(devfn), where, size);
+ dev_dbg(&pdev->xdev->dev,
+ "read dev=%04x:%02x:%02x.%d - offset %x size %d\n",
+ pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where, size);
err = do_pci_op(pdev, &op);
if (likely(!err)) {
- if (verbose_request)
- dev_info(&pdev->xdev->dev, "read got back value %x\n",
- op.value);
+ dev_dbg(&pdev->xdev->dev, "read got back value %x\n",
+ op.value);
*val = op.value;
} else if (err == -ENODEV) {
@@ -229,12 +224,10 @@ static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
struct pcifront_sd *sd = bus->sysdata;
struct pcifront_device *pdev = pcifront_get_pdev(sd);
- if (verbose_request)
- dev_info(&pdev->xdev->dev,
- "write dev=%04x:%02x:%02x.%d - "
- "offset %x size %d val %x\n",
- pci_domain_nr(bus), bus->number,
- PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
+ dev_dbg(&pdev->xdev->dev,
+ "write dev=%04x:%02x:%02x.%d - offset %x size %d val %x\n",
+ pci_domain_nr(bus), bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
return errno_to_pcibios_err(do_pci_op(pdev, &op));
}
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index e004d8da03dc..82d10b6661c7 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -6,7 +6,7 @@
menuconfig PCCARD
tristate "PCCard (PCMCIA/CardBus) support"
depends on !UML
- ---help---
+ help
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
computer. These are credit-card size devices such as network cards,
modems or hard drives often used with laptops computers. There are
@@ -22,7 +22,7 @@ config PCMCIA
tristate "16-bit PCMCIA support"
select CRC32
default y
- ---help---
+ help
This option enables support for 16-bit PCMCIA cards. Most older
PC-cards are such 16-bit PCMCIA cards, so unless you know you're
only using 32-bit CardBus cards, say Y or M here.
@@ -54,7 +54,7 @@ config CARDBUS
bool "32-bit CardBus support"
depends on PCI
default y
- ---help---
+ help
CardBus is a bus mastering architecture for PC-cards, which allows
for 32 bit PC-cards (the original PCMCIA standard specifies only
a 16 bit wide bus). Many newer PC-cards are actually CardBus cards.
@@ -75,7 +75,7 @@ config YENTA
depends on PCI
select CARDBUS if !EXPERT
select PCCARD_NONSTATIC if PCMCIA != n
- ---help---
+ help
This option enables support for CardBus host bridges. Virtually
all modern PCMCIA bridges are CardBus compatible. A "bridge" is
the hardware inside your computer that PCMCIA cards are plugged
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index 8dd1278bec04..7719ae4e2c56 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -35,7 +35,7 @@
/* L3C has 8-counters */
#define L3C_NR_COUNTERS 0x8
-#define L3C_PERF_CTRL_EN 0x20000
+#define L3C_PERF_CTRL_EN 0x10000
#define L3C_EVTYPE_NONE 0xff
/*
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index a484ab2c91ff..cf072153bdc5 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -16,7 +16,7 @@ config MFD_CROS_EC
menuconfig CHROME_PLATFORMS
bool "Platform support for Chrome hardware"
depends on X86 || ARM || ARM64 || COMPILE_TEST
- ---help---
+ help
Say Y here to get to see options for platform support for
various Chromebooks and Chromeboxes. This option alone does
not add any kernel code.
@@ -28,7 +28,7 @@ if CHROME_PLATFORMS
config CHROMEOS_LAPTOP
tristate "Chrome OS Laptop"
depends on I2C && DMI && X86
- ---help---
+ help
This driver instantiates i2c and smbus devices such as
light sensors and touchpads.
@@ -38,7 +38,7 @@ config CHROMEOS_LAPTOP
config CHROMEOS_PSTORE
tristate "Chrome OS pstore support"
depends on X86
- ---help---
+ help
This module instantiates the persistent storage on x86 ChromeOS
devices. It can be used to store away console logs and crash
information across reboots.
@@ -112,7 +112,7 @@ config CROS_EC_SPI
tristate "ChromeOS Embedded Controller (SPI)"
depends on CROS_EC && SPI
- ---help---
+ help
If you say Y here, you get support for talking to the ChromeOS EC
through a SPI bus, using a byte-level protocol. Since the EC's
response time cannot be guaranteed, we support ignoring
diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig
index 56e037623b29..916b39dc11bc 100644
--- a/drivers/platform/mellanox/Kconfig
+++ b/drivers/platform/mellanox/Kconfig
@@ -6,7 +6,7 @@
menuconfig MELLANOX_PLATFORM
bool "Platform support for Mellanox hardware"
depends on X86 || ARM || ARM64 || COMPILE_TEST
- ---help---
+ help
Say Y here to get to see options for platform support for
Mellanox systems. This option alone does not add any kernel code.
@@ -19,7 +19,7 @@ config MLXREG_HOTPLUG
depends on REGMAP
depends on HWMON
depends on I2C
- ---help---
+ help
This driver handles hot-plug events for the power suppliers, power
cables and fans on the wide range Mellanox IB and Ethernet systems.
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
index 77be37a1fbcf..ed48917af162 100644
--- a/drivers/platform/mellanox/mlxreg-hotplug.c
+++ b/drivers/platform/mellanox/mlxreg-hotplug.c
@@ -101,6 +101,7 @@ static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
struct mlxreg_core_data *data)
{
struct mlxreg_core_hotplug_platform_data *pdata;
+ struct i2c_client *client;
/* Notify user by sending hwmon uevent. */
kobject_uevent(&priv->hwmon->kobj, KOBJ_CHANGE);
@@ -121,18 +122,20 @@ static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
return -EFAULT;
}
- data->hpdev.client = i2c_new_device(data->hpdev.adapter,
- data->hpdev.brdinfo);
- if (!data->hpdev.client) {
+ client = i2c_new_client_device(data->hpdev.adapter,
+ data->hpdev.brdinfo);
+ if (IS_ERR(client)) {
dev_err(priv->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
data->hpdev.brdinfo->type, data->hpdev.nr +
pdata->shift_nr, data->hpdev.brdinfo->addr);
i2c_put_adapter(data->hpdev.adapter);
data->hpdev.adapter = NULL;
- return -EFAULT;
+ return PTR_ERR(client);
}
+ data->hpdev.client = client;
+
return 0;
}
diff --git a/drivers/platform/olpc/olpc-xo175-ec.c b/drivers/platform/olpc/olpc-xo175-ec.c
index 83ed1fbf73cf..5e1d14e35f20 100644
--- a/drivers/platform/olpc/olpc-xo175-ec.c
+++ b/drivers/platform/olpc/olpc-xo175-ec.c
@@ -410,7 +410,7 @@ static void olpc_xo175_ec_complete(void *arg)
dev_dbg(dev, "got event %.2x\n", byte);
switch (byte) {
case EVENT_AC_CHANGE:
- psy = power_supply_get_by_name("olpc-ac");
+ psy = power_supply_get_by_name("olpc_ac");
if (psy) {
power_supply_changed(psy);
power_supply_put(psy);
@@ -420,7 +420,7 @@ static void olpc_xo175_ec_complete(void *arg)
case EVENT_BATTERY_CRITICAL:
case EVENT_BATTERY_SOC_CHANGE:
case EVENT_BATTERY_ERROR:
- psy = power_supply_get_by_name("olpc-battery");
+ psy = power_supply_get_by_name("olpc_battery");
if (psy) {
power_supply_changed(psy);
power_supply_put(psy);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index ee93dcd065b8..0581a54cf562 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -7,7 +7,7 @@ menuconfig X86_PLATFORM_DEVICES
bool "X86 Platform Specific Device Drivers"
default y
depends on X86
- ---help---
+ help
Say Y here to get to see options for device drivers for various
x86 platforms, including vendor-specific laptop extension drivers.
This option alone does not add any kernel code.
@@ -41,7 +41,7 @@ config WMI_BMOF
tristate "WMI embedded Binary MOF driver"
depends on ACPI_WMI
default ACPI_WMI
- ---help---
+ help
Say Y here if you want to be able to read a firmware-embedded
WMI Binary MOF data. Using this requires userspace tools and may be
rather tedious.
@@ -55,7 +55,7 @@ config ALIENWARE_WMI
depends on LEDS_CLASS
depends on NEW_LEDS
depends on ACPI_WMI
- ---help---
+ help
This is a driver for controlling Alienware BIOS driven
features. It exposes an interface for controlling the AlienFX
zones on Alienware machines that don't contain a dedicated AlienFX
@@ -91,7 +91,7 @@ config INTEL_WMI_SBL_FW_UPDATE
config INTEL_WMI_THUNDERBOLT
tristate "Intel WMI thunderbolt force power driver"
depends on ACPI_WMI
- ---help---
+ help
Say Y here if you want to be able to use the WMI interface on select
systems to force the power control of Intel Thunderbolt controllers.
This is useful for updating the firmware when devices are not plugged
@@ -103,7 +103,7 @@ config INTEL_WMI_THUNDERBOLT
config MXM_WMI
tristate "WMI support for MXM Laptop Graphics"
depends on ACPI_WMI
- ---help---
+ help
MXM is a standard for laptop graphics cards, the WMI interface
is required for switchable nvidia graphics machines
@@ -128,7 +128,7 @@ config ACERHDF
tristate "Acer Aspire One temperature and fan driver"
depends on ACPI && THERMAL
select THERMAL_GOV_BANG_BANG
- ---help---
+ help
This is a driver for Acer Aspire One netbooks. It allows to access
the temperature sensor and to control the fan.
@@ -149,7 +149,7 @@ config ACER_WIRELESS
tristate "Acer Wireless Radio Control Driver"
depends on ACPI
depends on INPUT
- ---help---
+ help
The Acer Wireless Radio Control handles the airplane mode hotkey
present on new Acer laptops.
@@ -172,7 +172,7 @@ config ACER_WMI
select INPUT_SPARSEKMAP
# Acer WMI depends on ACPI_VIDEO when ACPI is enabled
select ACPI_VIDEO if ACPI
- ---help---
+ help
This is a driver for newer Acer (and Wistron) laptops. It adds
wireless radio and bluetooth control, and on some laptops,
exposes the mail LED and LCD backlight.
@@ -187,7 +187,7 @@ config APPLE_GMUX
depends on BACKLIGHT_CLASS_DEVICE
depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE
depends on ACPI_VIDEO=n || ACPI_VIDEO
- ---help---
+ help
This driver provides support for the gmux device found on many
Apple laptops, which controls the display mux for the hybrid
graphics as well as the backlight. Currently only backlight
@@ -203,7 +203,7 @@ config ASUS_LAPTOP
depends on RFKILL || RFKILL = n
depends on ACPI_VIDEO || ACPI_VIDEO = n
select INPUT_SPARSEKMAP
- ---help---
+ help
This is a driver for Asus laptops, Lenovo SL and the Pegatron
Lucid tablet. It may also support some MEDION, JVC or VICTOR
laptops. It makes all the extra buttons generate standard
@@ -223,7 +223,7 @@ config ASUS_WIRELESS
depends on INPUT
select NEW_LEDS
select LEDS_CLASS
- ---help---
+ help
The Asus Wireless Radio Control handles the airplane mode hotkey
present on some Asus laptops.
@@ -246,7 +246,7 @@ config ASUS_WMI
select INPUT_SPARSEKMAP
select LEDS_CLASS
select NEW_LEDS
- ---help---
+ help
Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new
Asus Notebooks).
@@ -257,7 +257,7 @@ config ASUS_NB_WMI
tristate "Asus Notebook WMI Driver"
depends on ASUS_WMI
depends on SERIO_I8042 || SERIO_I8042 = n
- ---help---
+ help
This is a driver for newer Asus notebooks. It adds extra features
like wireless radio and bluetooth control, leds, hotkeys, backlight...
@@ -279,7 +279,7 @@ config EEEPC_LAPTOP
select LEDS_CLASS
select NEW_LEDS
select INPUT_SPARSEKMAP
- ---help---
+ help
This driver supports the Fn-Fx keys on Eee PC laptops.
It also gives access to some extra laptop functionalities like
@@ -292,7 +292,7 @@ config EEEPC_LAPTOP
config EEEPC_WMI
tristate "Eee PC WMI Driver"
depends on ASUS_WMI
- ---help---
+ help
This is a driver for newer Eee PC laptops. It adds extra features
like wireless radio and bluetooth control, leds, hotkeys, backlight...
@@ -327,7 +327,7 @@ config DELL_SMBIOS
tristate "Dell SMBIOS driver"
depends on DCDBAS || DCDBAS=n
depends on ACPI_WMI || ACPI_WMI=n
- ---help---
+ help
This provides support for the Dell SMBIOS calling interface.
If you have a Dell computer you should enable this option.
@@ -339,7 +339,7 @@ config DELL_SMBIOS_WMI
depends on ACPI_WMI
select DELL_WMI_DESCRIPTOR
depends on DELL_SMBIOS
- ---help---
+ help
This provides an implementation for the Dell SMBIOS calling interface
communicated over ACPI-WMI.
@@ -352,7 +352,7 @@ config DELL_SMBIOS_SMM
default y
depends on DCDBAS
depends on DELL_SMBIOS
- ---help---
+ help
This provides an implementation for the Dell SMBIOS calling interface
communicated over SMI/SMM.
@@ -373,7 +373,7 @@ config DELL_LAPTOP
select NEW_LEDS
select LEDS_TRIGGERS
select LEDS_TRIGGER_AUDIO
- ---help---
+ help
This driver adds support for rfkill and backlight control to Dell
laptops (except for some models covered by the Compal driver).
@@ -382,7 +382,7 @@ config DELL_RBTN
depends on ACPI
depends on INPUT
depends on RFKILL
- ---help---
+ help
Say Y here if you want to support Dell Airplane Mode Switch ACPI
device on Dell laptops. Sometimes it has names: DELLABCE or DELRBTN.
This driver register rfkill device or input hotkey device depending
@@ -408,7 +408,7 @@ config DELL_RBU
config DELL_SMO8800
tristate "Dell Latitude freefall driver (ACPI SMO88XX)"
depends on ACPI
- ---help---
+ help
Say Y here if you want to support SMO88XX freefall devices
on Dell Latitude laptops.
@@ -424,7 +424,7 @@ config DELL_WMI
depends on DELL_SMBIOS
select DELL_WMI_DESCRIPTOR
select INPUT_SPARSEKMAP
- ---help---
+ help
Say Y here if you want to support WMI-based hotkeys on Dell laptops.
To compile this driver as a module, choose M here: the module will
@@ -439,7 +439,7 @@ config DELL_WMI_AIO
depends on ACPI_WMI
depends on INPUT
select INPUT_SPARSEKMAP
- ---help---
+ help
Say Y here if you want to support WMI-based hotkeys on Dell
All-In-One machines.
@@ -458,7 +458,7 @@ config AMILO_RFKILL
tristate "Fujitsu-Siemens Amilo rfkill support"
depends on RFKILL
depends on SERIO_I8042
- ---help---
+ help
This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
laptops.
@@ -470,7 +470,7 @@ config FUJITSU_LAPTOP
depends on ACPI_VIDEO || ACPI_VIDEO = n
select INPUT_SPARSEKMAP
select LEDS_CLASS
- ---help---
+ help
This is a driver for laptops built by Fujitsu:
* P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
@@ -485,7 +485,7 @@ config FUJITSU_TABLET
tristate "Fujitsu Tablet Extras"
depends on ACPI
depends on INPUT
- ---help---
+ help
This is a driver for tablets built by Fujitsu:
* Lifebook P1510/P1610/P1620/Txxxx
@@ -502,7 +502,7 @@ config GPD_POCKET_FAN
tristate "GPD Pocket Fan Controller support"
depends on ACPI
depends on THERMAL
- ---help---
+ help
Driver for the GPD Pocket vendor specific FAN02501 ACPI device
which controls the fan speed on the GPD Pocket.
@@ -558,14 +558,14 @@ config TC1100_WMI
depends on !X86_64
depends on ACPI
depends on ACPI_WMI
- ---help---
+ help
This is a driver for the WMI extensions (wireless and bluetooth power
control) of the HP Compaq TC1100 tablet.
config IBM_RTL
tristate "Device driver to enable PRTL support"
depends on PCI
- ---help---
+ help
Enable support for IBM Premium Real Time Mode (PRTM).
This module will allow you the enter and exit PRTM in the BIOS via
sysfs on platforms that support this feature. System in PRTM will
@@ -623,7 +623,7 @@ config THINKPAD_ACPI
select LEDS_CLASS
select LEDS_TRIGGERS
select LEDS_TRIGGER_AUDIO
- ---help---
+ help
This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
output switching, ThinkLight control, UltraBay eject and more.
@@ -646,7 +646,7 @@ config THINKPAD_ACPI_ALSA_SUPPORT
depends on SND
depends on SND = y || THINKPAD_ACPI = SND
default y
- ---help---
+ help
Enables monitoring of the built-in console audio output control
(headphone and speakers), which is operated by the mute and (in
some ThinkPad models) volume hotkeys.
@@ -666,7 +666,7 @@ config THINKPAD_ACPI_ALSA_SUPPORT
config THINKPAD_ACPI_DEBUGFACILITIES
bool "Maintainer debug facilities"
depends on THINKPAD_ACPI
- ---help---
+ help
Enables extra stuff in the thinkpad-acpi which is completely useless
for normal use. Read the driver source to find out what it does.
@@ -676,7 +676,7 @@ config THINKPAD_ACPI_DEBUGFACILITIES
config THINKPAD_ACPI_DEBUG
bool "Verbose debug mode"
depends on THINKPAD_ACPI
- ---help---
+ help
Enables extra debugging information, at the expense of a slightly
increase in driver size.
@@ -685,7 +685,7 @@ config THINKPAD_ACPI_DEBUG
config THINKPAD_ACPI_UNSAFE_LEDS
bool "Allow control of important LEDs (unsafe)"
depends on THINKPAD_ACPI
- ---help---
+ help
Overriding LED state on ThinkPads can mask important
firmware alerts (like critical battery condition), or misled
the user into damaging the hardware (undocking or ejecting
@@ -709,7 +709,7 @@ config THINKPAD_ACPI_VIDEO
bool "Video output control support"
depends on THINKPAD_ACPI
default y
- ---help---
+ help
Allows the thinkpad_acpi driver to provide an interface to control
the various video output ports.
@@ -732,7 +732,7 @@ config THINKPAD_ACPI_HOTKEY_POLL
bool "Support NVRAM polling for hot keys"
depends on THINKPAD_ACPI
default y
- ---help---
+ help
Some thinkpad models benefit from NVRAM polling to detect a few of
the hot key press events. If you know your ThinkPad model does not
need to do NVRAM polling to support any of the hot keys you use,
@@ -767,7 +767,7 @@ config INTEL_CHT_INT33FE
depends on CHARGER_BQ24190=y || (CHARGER_BQ24190=m && m)
depends on USB_ROLES_INTEL_XHCI=y || (USB_ROLES_INTEL_XHCI=m && m)
depends on TYPEC_MUX_PI3USB30532=y || (TYPEC_MUX_PI3USB30532=m && m)
- ---help---
+ help
This driver add support for the INT33FE ACPI device found on
some Intel Cherry Trail devices.
@@ -801,7 +801,7 @@ config INTEL_INT0002_VGPIO
tristate "Intel ACPI INT0002 Virtual GPIO driver"
depends on GPIOLIB && ACPI
select GPIOLIB_IRQCHIP
- ---help---
+ help
Some peripherals on Bay Trail and Cherry Trail platforms signal a
Power Management Event (PME) to the Power Management Controller (PMC)
to wakeup the system. When this happens software needs to explicitly
@@ -820,7 +820,7 @@ config INTEL_MENLOW
tristate "Thermal Management driver for Intel menlow platform"
depends on ACPI_THERMAL
select THERMAL
- ---help---
+ help
ACPI thermal management enhancement driver on
Intel Menlow platform.
@@ -831,7 +831,7 @@ config INTEL_OAKTRAIL
depends on ACPI
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI
- ---help---
+ help
Intel Oaktrail platform need this driver to provide interfaces to
enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
here; it will only load on supported platforms.
@@ -854,7 +854,7 @@ config SURFACE3_WMI
depends on DMI
depends on INPUT
depends on SPI
- ---help---
+ help
Say Y here if you have a Surface 3.
To compile this driver as a module, choose M here: the module will
@@ -863,7 +863,7 @@ config SURFACE3_WMI
config SURFACE_3_BUTTON
tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet"
depends on ACPI && KEYBOARD_GPIO && I2C
- ---help---
+ help
This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
config SURFACE_3_POWER_OPREGION
@@ -876,7 +876,7 @@ config SURFACE_3_POWER_OPREGION
config SURFACE_PRO3_BUTTON
tristate "Power/home/volume buttons driver for Microsoft Surface Pro 3/4 tablet"
depends on ACPI && INPUT
- ---help---
+ help
This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet.
config MSI_LAPTOP
@@ -887,7 +887,7 @@ config MSI_LAPTOP
depends on RFKILL
depends on INPUT && SERIO_I8042
select INPUT_SPARSEKMAP
- ---help---
+ help
This is a driver for laptops built by MSI (MICRO-STAR
INTERNATIONAL):
@@ -918,7 +918,7 @@ config XO15_EBOOK
tristate "OLPC XO-1.5 ebook switch"
depends on OLPC || COMPILE_TEST
depends on ACPI && INPUT
- ---help---
+ help
Support for the ebook switch on the OLPC XO-1.5 laptop.
This switch is triggered as the screen is rotated and folded down to
@@ -928,7 +928,7 @@ config XO1_RFKILL
tristate "OLPC XO-1 software RF kill switch"
depends on OLPC || COMPILE_TEST
depends on RFKILL
- ---help---
+ help
Support for enabling/disabling the WLAN interface on the OLPC XO-1
laptop.
@@ -953,7 +953,7 @@ config SAMSUNG_LAPTOP
depends on BACKLIGHT_CLASS_DEVICE
select LEDS_CLASS
select NEW_LEDS
- ---help---
+ help
This module implements a driver for a wide range of different
Samsung laptops. It offers control over the different
function keys, wireless LED, LCD backlight level.
@@ -968,7 +968,7 @@ config SAMSUNG_Q10
tristate "Samsung Q10 Extras"
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
- ---help---
+ help
This driver provides support for backlight control on Samsung Q10
and related laptops, including Dell Latitude X200.
@@ -985,7 +985,7 @@ config ACPI_TOSHIBA
depends on RFKILL || RFKILL = n
depends on IIO
select INPUT_SPARSEKMAP
- ---help---
+ help
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
their lack of a BIOS setup menu and APM support.
@@ -1012,7 +1012,7 @@ config TOSHIBA_BT_RFKILL
tristate "Toshiba Bluetooth RFKill switch support"
depends on ACPI
depends on RFKILL || RFKILL = n
- ---help---
+ help
This driver adds support for Bluetooth events for the RFKill
switch on modern Toshiba laptops with full ACPI support and
an RFKill switch.
@@ -1027,7 +1027,7 @@ config TOSHIBA_BT_RFKILL
config TOSHIBA_HAPS
tristate "Toshiba HDD Active Protection Sensor"
depends on ACPI
- ---help---
+ help
This driver adds support for the built-in accelerometer
found on recent Toshiba laptops equipped with HID TOS620A
device.
@@ -1048,7 +1048,7 @@ config TOSHIBA_WMI
depends on ACPI_WMI
depends on INPUT
select INPUT_SPARSEKMAP
- ---help---
+ help
This driver adds hotkey monitoring support to some Toshiba models
that manage the hotkeys via WMI events.
@@ -1078,7 +1078,7 @@ config COMPAL_LAPTOP
depends on RFKILL
depends on HWMON
depends on POWER_SUPPLY
- ---help---
+ help
This is a driver for laptops built by Compal, and some models by
other brands (e.g. Dell, Toshiba).
@@ -1104,7 +1104,7 @@ config PANASONIC_LAPTOP
depends on INPUT && ACPI
depends on BACKLIGHT_CLASS_DEVICE
select INPUT_SPARSEKMAP
- ---help---
+ help
This driver adds support for access to backlight control and hotkeys
on Panasonic Let's Note laptops.
@@ -1118,7 +1118,7 @@ config SONY_LAPTOP
depends on BACKLIGHT_CLASS_DEVICE
depends on INPUT
depends on RFKILL
- ---help---
+ help
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
@@ -1131,7 +1131,7 @@ config SONY_LAPTOP
config SONYPI_COMPAT
bool "Sonypi compatibility"
depends on SONY_LAPTOP
- ---help---
+ help
Build the sonypi driver compatibility code into the sony-laptop driver.
config SYSTEM76_ACPI
@@ -1154,7 +1154,7 @@ config TOPSTAR_LAPTOP
select INPUT_SPARSEKMAP
select LEDS_CLASS
select NEW_LEDS
- ---help---
+ help
This driver adds support for hotkeys found on Topstar laptops.
If you have a Topstar laptop, say Y or M here.
@@ -1173,7 +1173,7 @@ config I2C_MULTI_INSTANTIATE
config MLX_PLATFORM
tristate "Mellanox Technologies platform support"
depends on I2C && REGMAP
- ---help---
+ help
This option enables system support for the Mellanox Technologies
platform. The Mellanox systems provide data center networking
solutions based on Virtual Protocol Interconnect (VPI) technology
@@ -1186,7 +1186,7 @@ config TOUCHSCREEN_DMI
bool "DMI based touchscreen configuration info"
depends on ACPI && DMI && I2C=y && TOUCHSCREEN_SILEAD
select EFI_EMBEDDED_FIRMWARE if EFI
- ---help---
+ help
Certain ACPI based tablets with e.g. Silead or Chipone touchscreens
do not have enough data in ACPI tables for the touchscreen driver to
handle the touchscreen properly, as OEMs expect the data to be baked
@@ -1197,7 +1197,7 @@ config TOUCHSCREEN_DMI
config INTEL_IMR
bool "Intel Isolated Memory Region support"
depends on X86_INTEL_QUARK && IOSF_MBI
- ---help---
+ help
This option provides a means to manipulate Isolated Memory Regions.
IMRs are a set of registers that define read and write access masks
to prohibit certain system agents from accessing memory with 1 KiB
@@ -1221,7 +1221,7 @@ config INTEL_IMR
config INTEL_IPS
tristate "Intel Intelligent Power Sharing"
depends on ACPI && PCI
- ---help---
+ help
Intel Calpella platforms support dynamic power sharing between the
CPU and GPU, maximizing performance in a given TDP. This driver,
along with the CPU frequency and i915 drivers, provides that
@@ -1231,7 +1231,7 @@ config INTEL_IPS
config INTEL_RST
tristate "Intel Rapid Start Technology Driver"
depends on ACPI
- ---help---
+ help
This driver provides support for modifying parameters on systems
equipped with Intel's Rapid Start Technology. When put in an ACPI
sleep state, these devices will wake after either a configured
@@ -1243,7 +1243,7 @@ config INTEL_RST
config INTEL_SMARTCONNECT
tristate "Intel Smart Connect disabling driver"
depends on ACPI
- ---help---
+ help
Intel Smart Connect is a technology intended to permit devices to
update state by resuming for a short period of time at regular
intervals. If a user enables this functionality under Windows and
@@ -1259,7 +1259,7 @@ source "drivers/platform/x86/intel_speed_select_if/Kconfig"
config INTEL_TURBO_MAX_3
bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
depends on X86_64 && SCHED_MC_PRIO
- ---help---
+ help
This driver reads maximum performance ratio of each CPU and set up
the scheduler priority metrics. In this way scheduler can prefer
CPU with higher performance to schedule tasks.
@@ -1282,7 +1282,7 @@ config INTEL_BXTWC_PMIC_TMU
depends on REGMAP
depends on MFD_INTEL_PMC_BXT
depends on INTEL_SOC_PMIC_BXTWC
- ---help---
+ help
Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature.
This driver enables the alarm wakeup functionality in the TMU unit
of Whiskey Cove PMIC.
@@ -1291,7 +1291,7 @@ config INTEL_CHTDC_TI_PWRBTN
tristate "Intel Cherry Trail Dollar Cove TI power button driver"
depends on INTEL_SOC_PMIC_CHTDC_TI
depends on INPUT
- ---help---
+ help
This option adds a power button driver driver for Dollar Cove TI
PMIC on Intel Cherry Trail devices.
@@ -1317,7 +1317,7 @@ config INTEL_MRFLD_PWRBTN
tristate "Intel Merrifield Basin Cove power button driver"
depends on INTEL_SOC_PMIC_MRFLD
depends on INPUT
- ---help---
+ help
This option adds a power button driver for Basin Cove PMIC
on Intel Merrifield devices.
@@ -1327,7 +1327,7 @@ config INTEL_MRFLD_PWRBTN
config INTEL_PMC_CORE
tristate "Intel PMC Core driver"
depends on PCI
- ---help---
+ help
The Intel Platform Controller Hub for Intel Core SoCs provides access
to Power Management Controller registers via a PCI interface. This
driver can utilize debugging capabilities and supported features as
@@ -1341,7 +1341,7 @@ config INTEL_PMC_CORE
config INTEL_PUNIT_IPC
tristate "Intel P-Unit IPC Driver"
- ---help---
+ help
This driver provides support for Intel P-Unit Mailbox IPC mechanism,
which is used to bridge the communications between kernel and P-Unit.
@@ -1379,7 +1379,7 @@ config INTEL_SCU_PLATFORM
config INTEL_SCU_IPC_UTIL
tristate "Intel SCU IPC utility driver"
depends on INTEL_SCU
- ---help---
+ help
The IPC Util driver provides an interface with the SCU enabling
low level access for debug work and updating the firmware. Say
N unless you will be doing this on an Intel MID platform.
@@ -1389,7 +1389,7 @@ config INTEL_TELEMETRY
depends on X86_64
depends on MFD_INTEL_PMC_BXT
depends on INTEL_PUNIT_IPC
- ---help---
+ help
This driver provides interfaces to configure and use
telemetry for INTEL SoC from APL onwards. It is also
used to get various SoC events and parameters
diff --git a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
index 39191bebcb28..a72141dffa29 100644
--- a/drivers/pnp/Kconfig
+++ b/drivers/pnp/Kconfig
@@ -7,7 +7,7 @@ menuconfig PNP
bool "Plug and Play support"
depends on HAS_IOMEM
depends on ISA || ACPI
- ---help---
+ help
Plug and Play (PnP) is a standard for peripherals which allows those
peripherals to be configured by software, e.g. assign IRQ's or other
parameters. No jumpers on the cards are needed, instead the values
diff --git a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig
index 7da992b70945..bcdac269af33 100644
--- a/drivers/pnp/pnpbios/Kconfig
+++ b/drivers/pnp/pnpbios/Kconfig
@@ -6,7 +6,7 @@ config PNPBIOS
bool "Plug and Play BIOS support"
depends on ISA && X86_32
default n
- ---help---
+ help
Linux uses the PNPBIOS as defined in "Plug and Play BIOS
Specification Version 1.0A May 5, 1994" to autodetect built-in
mainboard resources (e.g. parallel port resources).
@@ -26,7 +26,7 @@ config PNPBIOS
config PNPBIOS_PROC_FS
bool "Plug and Play BIOS /proc interface"
depends on PNPBIOS && PROC_FS
- ---help---
+ help
If you say Y here and to "/proc file system support", you will be
able to directly access the PNPBIOS. This includes resource
allocation, ESCD, and other PNPBIOS services. Using this
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index df479c49be49..f07b982c8dff 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -123,6 +123,13 @@ config POWER_RESET_OCELOT_RESET
help
This driver supports restart for Microsemi Ocelot SoC.
+config POWER_RESET_OXNAS
+ bool "OXNAS SoC restart driver"
+ depends on ARCH_OXNAS
+ default MACH_OX820
+ help
+ Restart support for OXNAS/PLXTECH OX820 SoC.
+
config POWER_RESET_PIIX4_POWEROFF
tristate "Intel PIIX4 power-off driver"
depends on PCI
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index da37f8b851dc..5710ca469517 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o
+obj-$(CONFIG_POWER_RESET_OXNAS) += oxnas-restart.o
obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
index 6a4bbb506551..c5067eb75370 100644
--- a/drivers/power/reset/gpio-poweroff.c
+++ b/drivers/power/reset/gpio-poweroff.c
@@ -54,7 +54,7 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
/* If a pm_power_off function has already been added, leave it alone */
if (pm_power_off != NULL) {
dev_err(&pdev->dev,
- "%s: pm_power_off function already registered",
+ "%s: pm_power_off function already registered\n",
__func__);
return -EBUSY;
}
diff --git a/drivers/power/reset/ltc2952-poweroff.c b/drivers/power/reset/ltc2952-poweroff.c
index e4a0cc45b3d1..318927938b05 100644
--- a/drivers/power/reset/ltc2952-poweroff.c
+++ b/drivers/power/reset/ltc2952-poweroff.c
@@ -94,7 +94,6 @@ static enum hrtimer_restart ltc2952_poweroff_timer_wde(struct hrtimer *timer)
{
ktime_t now;
int state;
- unsigned long overruns;
struct ltc2952_poweroff *data = to_ltc2952(timer, timer_wde);
if (data->kernel_panic)
@@ -104,7 +103,7 @@ static enum hrtimer_restart ltc2952_poweroff_timer_wde(struct hrtimer *timer)
gpiod_set_value(data->gpio_watchdog, !state);
now = hrtimer_cb_get_time(timer);
- overruns = hrtimer_forward(timer, now, data->wde_interval);
+ hrtimer_forward(timer, now, data->wde_interval);
return HRTIMER_RESTART;
}
diff --git a/drivers/power/reset/oxnas-restart.c b/drivers/power/reset/oxnas-restart.c
new file mode 100644
index 000000000000..13090bec058a
--- /dev/null
+++ b/drivers/power/reset/oxnas-restart.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/*
+ * oxnas SoC reset driver
+ * based on:
+ * Microsemi MIPS SoC reset driver
+ * and ox820_assert_system_reset() written by Ma Hajun <mahaijuns@gmail.com>
+ *
+ * Copyright (c) 2013 Ma Hajun <mahaijuns@gmail.com>
+ * Copyright (c) 2017 Microsemi Corporation
+ * Copyright (c) 2020 Daniel Golle <daniel@makrotopia.org>
+ */
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/notifier.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+
+/* bit numbers of reset control register */
+#define OX820_SYS_CTRL_RST_SCU 0
+#define OX820_SYS_CTRL_RST_COPRO 1
+#define OX820_SYS_CTRL_RST_ARM0 2
+#define OX820_SYS_CTRL_RST_ARM1 3
+#define OX820_SYS_CTRL_RST_USBHS 4
+#define OX820_SYS_CTRL_RST_USBHSPHYA 5
+#define OX820_SYS_CTRL_RST_MACA 6
+#define OX820_SYS_CTRL_RST_MAC OX820_SYS_CTRL_RST_MACA
+#define OX820_SYS_CTRL_RST_PCIEA 7
+#define OX820_SYS_CTRL_RST_SGDMA 8
+#define OX820_SYS_CTRL_RST_CIPHER 9
+#define OX820_SYS_CTRL_RST_DDR 10
+#define OX820_SYS_CTRL_RST_SATA 11
+#define OX820_SYS_CTRL_RST_SATA_LINK 12
+#define OX820_SYS_CTRL_RST_SATA_PHY 13
+#define OX820_SYS_CTRL_RST_PCIEPHY 14
+#define OX820_SYS_CTRL_RST_STATIC 15
+#define OX820_SYS_CTRL_RST_GPIO 16
+#define OX820_SYS_CTRL_RST_UART1 17
+#define OX820_SYS_CTRL_RST_UART2 18
+#define OX820_SYS_CTRL_RST_MISC 19
+#define OX820_SYS_CTRL_RST_I2S 20
+#define OX820_SYS_CTRL_RST_SD 21
+#define OX820_SYS_CTRL_RST_MACB 22
+#define OX820_SYS_CTRL_RST_PCIEB 23
+#define OX820_SYS_CTRL_RST_VIDEO 24
+#define OX820_SYS_CTRL_RST_DDR_PHY 25
+#define OX820_SYS_CTRL_RST_USBHSPHYB 26
+#define OX820_SYS_CTRL_RST_USBDEV 27
+#define OX820_SYS_CTRL_RST_ARMDBG 29
+#define OX820_SYS_CTRL_RST_PLLA 30
+#define OX820_SYS_CTRL_RST_PLLB 31
+
+/* bit numbers of clock control register */
+#define OX820_SYS_CTRL_CLK_COPRO 0
+#define OX820_SYS_CTRL_CLK_DMA 1
+#define OX820_SYS_CTRL_CLK_CIPHER 2
+#define OX820_SYS_CTRL_CLK_SD 3
+#define OX820_SYS_CTRL_CLK_SATA 4
+#define OX820_SYS_CTRL_CLK_I2S 5
+#define OX820_SYS_CTRL_CLK_USBHS 6
+#define OX820_SYS_CTRL_CLK_MACA 7
+#define OX820_SYS_CTRL_CLK_MAC OX820_SYS_CTRL_CLK_MACA
+#define OX820_SYS_CTRL_CLK_PCIEA 8
+#define OX820_SYS_CTRL_CLK_STATIC 9
+#define OX820_SYS_CTRL_CLK_MACB 10
+#define OX820_SYS_CTRL_CLK_PCIEB 11
+#define OX820_SYS_CTRL_CLK_REF600 12
+#define OX820_SYS_CTRL_CLK_USBDEV 13
+#define OX820_SYS_CTRL_CLK_DDR 14
+#define OX820_SYS_CTRL_CLK_DDRPHY 15
+#define OX820_SYS_CTRL_CLK_DDRCK 16
+
+/* Regmap offsets */
+#define OX820_CLK_SET_REGOFFSET 0x2c
+#define OX820_CLK_CLR_REGOFFSET 0x30
+#define OX820_RST_SET_REGOFFSET 0x34
+#define OX820_RST_CLR_REGOFFSET 0x38
+#define OX820_SECONDARY_SEL_REGOFFSET 0x14
+#define OX820_TERTIARY_SEL_REGOFFSET 0x8c
+#define OX820_QUATERNARY_SEL_REGOFFSET 0x94
+#define OX820_DEBUG_SEL_REGOFFSET 0x9c
+#define OX820_ALTERNATIVE_SEL_REGOFFSET 0xa4
+#define OX820_PULLUP_SEL_REGOFFSET 0xac
+#define OX820_SEC_SECONDARY_SEL_REGOFFSET 0x100014
+#define OX820_SEC_TERTIARY_SEL_REGOFFSET 0x10008c
+#define OX820_SEC_QUATERNARY_SEL_REGOFFSET 0x100094
+#define OX820_SEC_DEBUG_SEL_REGOFFSET 0x10009c
+#define OX820_SEC_ALTERNATIVE_SEL_REGOFFSET 0x1000a4
+#define OX820_SEC_PULLUP_SEL_REGOFFSET 0x1000ac
+
+struct oxnas_restart_context {
+ struct regmap *sys_ctrl;
+ struct notifier_block restart_handler;
+};
+
+static int ox820_restart_handle(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+ struct oxnas_restart_context *ctx = container_of(this, struct
+ oxnas_restart_context,
+ restart_handler);
+ u32 value;
+
+ /*
+ * Assert reset to cores as per power on defaults
+ * Don't touch the DDR interface as things will come to an impromptu
+ * stop NB Possibly should be asserting reset for PLLB, but there are
+ * timing concerns here according to the docs
+ */
+ value = BIT(OX820_SYS_CTRL_RST_COPRO) |
+ BIT(OX820_SYS_CTRL_RST_USBHS) |
+ BIT(OX820_SYS_CTRL_RST_USBHSPHYA) |
+ BIT(OX820_SYS_CTRL_RST_MACA) |
+ BIT(OX820_SYS_CTRL_RST_PCIEA) |
+ BIT(OX820_SYS_CTRL_RST_SGDMA) |
+ BIT(OX820_SYS_CTRL_RST_CIPHER) |
+ BIT(OX820_SYS_CTRL_RST_SATA) |
+ BIT(OX820_SYS_CTRL_RST_SATA_LINK) |
+ BIT(OX820_SYS_CTRL_RST_SATA_PHY) |
+ BIT(OX820_SYS_CTRL_RST_PCIEPHY) |
+ BIT(OX820_SYS_CTRL_RST_STATIC) |
+ BIT(OX820_SYS_CTRL_RST_UART1) |
+ BIT(OX820_SYS_CTRL_RST_UART2) |
+ BIT(OX820_SYS_CTRL_RST_MISC) |
+ BIT(OX820_SYS_CTRL_RST_I2S) |
+ BIT(OX820_SYS_CTRL_RST_SD) |
+ BIT(OX820_SYS_CTRL_RST_MACB) |
+ BIT(OX820_SYS_CTRL_RST_PCIEB) |
+ BIT(OX820_SYS_CTRL_RST_VIDEO) |
+ BIT(OX820_SYS_CTRL_RST_USBHSPHYB) |
+ BIT(OX820_SYS_CTRL_RST_USBDEV);
+
+ regmap_write(ctx->sys_ctrl, OX820_RST_SET_REGOFFSET, value);
+
+ /* Release reset to cores as per power on defaults */
+ regmap_write(ctx->sys_ctrl, OX820_RST_CLR_REGOFFSET,
+ BIT(OX820_SYS_CTRL_RST_GPIO));
+
+ /*
+ * Disable clocks to cores as per power-on defaults - must leave DDR
+ * related clocks enabled otherwise we'll stop rather abruptly.
+ */
+ value = BIT(OX820_SYS_CTRL_CLK_COPRO) |
+ BIT(OX820_SYS_CTRL_CLK_DMA) |
+ BIT(OX820_SYS_CTRL_CLK_CIPHER) |
+ BIT(OX820_SYS_CTRL_CLK_SD) |
+ BIT(OX820_SYS_CTRL_CLK_SATA) |
+ BIT(OX820_SYS_CTRL_CLK_I2S) |
+ BIT(OX820_SYS_CTRL_CLK_USBHS) |
+ BIT(OX820_SYS_CTRL_CLK_MAC) |
+ BIT(OX820_SYS_CTRL_CLK_PCIEA) |
+ BIT(OX820_SYS_CTRL_CLK_STATIC) |
+ BIT(OX820_SYS_CTRL_CLK_MACB) |
+ BIT(OX820_SYS_CTRL_CLK_PCIEB) |
+ BIT(OX820_SYS_CTRL_CLK_REF600) |
+ BIT(OX820_SYS_CTRL_CLK_USBDEV);
+
+ regmap_write(ctx->sys_ctrl, OX820_CLK_CLR_REGOFFSET, value);
+
+ /* Enable clocks to cores as per power-on defaults */
+
+ /* Set sys-control pin mux'ing as per power-on defaults */
+ regmap_write(ctx->sys_ctrl, OX820_SECONDARY_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_TERTIARY_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_QUATERNARY_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_DEBUG_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_ALTERNATIVE_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_PULLUP_SEL_REGOFFSET, 0);
+
+ regmap_write(ctx->sys_ctrl, OX820_SEC_SECONDARY_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_SEC_TERTIARY_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_SEC_QUATERNARY_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_SEC_DEBUG_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_SEC_ALTERNATIVE_SEL_REGOFFSET, 0);
+ regmap_write(ctx->sys_ctrl, OX820_SEC_PULLUP_SEL_REGOFFSET, 0);
+
+ /*
+ * No need to save any state, as the ROM loader can determine whether
+ * reset is due to power cycling or programatic action, just hit the
+ * (self-clearing) CPU reset bit of the block reset register
+ */
+ value =
+ BIT(OX820_SYS_CTRL_RST_SCU) |
+ BIT(OX820_SYS_CTRL_RST_ARM0) |
+ BIT(OX820_SYS_CTRL_RST_ARM1);
+
+ regmap_write(ctx->sys_ctrl, OX820_RST_SET_REGOFFSET, value);
+
+ pr_emerg("Unable to restart system\n");
+ return NOTIFY_DONE;
+}
+
+static int ox820_restart_probe(struct platform_device *pdev)
+{
+ struct oxnas_restart_context *ctx;
+ struct regmap *sys_ctrl;
+ struct device *dev = &pdev->dev;
+ int err = 0;
+
+ sys_ctrl = syscon_node_to_regmap(pdev->dev.of_node);
+ if (IS_ERR(sys_ctrl))
+ return PTR_ERR(sys_ctrl);
+
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->sys_ctrl = sys_ctrl;
+ ctx->restart_handler.notifier_call = ox820_restart_handle;
+ ctx->restart_handler.priority = 192;
+ err = register_restart_handler(&ctx->restart_handler);
+ if (err)
+ dev_err(dev, "can't register restart notifier (err=%d)\n", err);
+
+ return err;
+}
+
+static const struct of_device_id ox820_restart_of_match[] = {
+ { .compatible = "oxsemi,ox820-sys-ctrl" },
+ {}
+};
+
+static struct platform_driver ox820_restart_driver = {
+ .probe = ox820_restart_probe,
+ .driver = {
+ .name = "ox820-chip-reset",
+ .of_match_table = ox820_restart_of_match,
+ },
+};
+builtin_platform_driver(ox820_restart_driver);
diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c
index 22a743a0bf28..4a688741a88a 100644
--- a/drivers/power/reset/qcom-pon.c
+++ b/drivers/power/reset/qcom-pon.c
@@ -34,7 +34,8 @@ static int pm8916_reboot_mode_write(struct reboot_mode_driver *reboot,
ret = regmap_update_bits(pon->regmap,
pon->baseaddr + PON_SOFT_RB_SPARE,
- 0xfc, magic << pon->reason_shift);
+ GENMASK(7, pon->reason_shift),
+ magic << pon->reason_shift);
if (ret < 0)
dev_err(pon->dev, "update reboot mode bits failed\n");
diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c
index 62fbba0df971..510e363381ca 100644
--- a/drivers/power/reset/syscon-reboot.c
+++ b/drivers/power/reset/syscon-reboot.c
@@ -51,8 +51,11 @@ static int syscon_reboot_probe(struct platform_device *pdev)
return -ENOMEM;
ctx->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
- if (IS_ERR(ctx->map))
- return PTR_ERR(ctx->map);
+ if (IS_ERR(ctx->map)) {
+ ctx->map = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(ctx->map))
+ return PTR_ERR(ctx->map);
+ }
if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset))
return -EINVAL;
diff --git a/drivers/power/supply/88pm860x_battery.c b/drivers/power/supply/88pm860x_battery.c
index 5ca047b3f58f..1308f3a185f3 100644
--- a/drivers/power/supply/88pm860x_battery.c
+++ b/drivers/power/supply/88pm860x_battery.c
@@ -919,16 +919,12 @@ static int pm860x_battery_probe(struct platform_device *pdev)
return -ENOMEM;
info->irq_cc = platform_get_irq(pdev, 0);
- if (info->irq_cc <= 0) {
- dev_err(&pdev->dev, "No IRQ resource!\n");
+ if (info->irq_cc <= 0)
return -EINVAL;
- }
info->irq_batt = platform_get_irq(pdev, 1);
- if (info->irq_batt <= 0) {
- dev_err(&pdev->dev, "No IRQ resource!\n");
+ if (info->irq_batt <= 0)
return -EINVAL;
- }
info->chip = chip;
info->i2c =
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index a46643f5e2fb..44d3c8512fb8 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -116,6 +116,17 @@ config BATTERY_CPCAP
Say Y here to enable support for battery on Motorola
phones and tablets such as droid 4.
+config BATTERY_CW2015
+ tristate "CW2015 Battery driver"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say Y here to enable support for the cellwise cw2015
+ battery fuel gauge (used in the Pinebook Pro & others)
+
+ This driver can also be built as a module. If so, the module will be
+ called cw2015_battery.
+
config BATTERY_DS2760
tristate "DS2760 battery driver (HP iPAQ & others)"
depends on W1
@@ -415,7 +426,7 @@ config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
help
- Say Y to include support for NXP PCF50633 Main Battery Charger.
+ Say Y to include support for NXP PCF50633 Main Battery Charger.
config BATTERY_RX51
tristate "Nokia RX-51 (N900) battery driver"
@@ -587,7 +598,7 @@ config CHARGER_BQ24257
tristate "TI BQ24250/24251/24257 battery charger driver"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
- depends on REGMAP_I2C
+ select REGMAP_I2C
help
Say Y to enable support for the TI BQ24250, BQ24251, and BQ24257 battery
chargers.
@@ -619,15 +630,15 @@ config CHARGER_TPS65090
tristate "TPS65090 battery charger driver"
depends on MFD_TPS65090
help
- Say Y here to enable support for battery charging with TPS65090
- PMIC chips.
+ Say Y here to enable support for battery charging with TPS65090
+ PMIC chips.
config CHARGER_TPS65217
tristate "TPS65217 battery charger driver"
depends on MFD_TPS65217
help
- Say Y here to enable support for battery charging with TPS65217
- PMIC chips.
+ Say Y here to enable support for battery charging with TPS65217
+ PMIC chips.
config BATTERY_GAUGE_LTC2941
tristate "LTC2941/LTC2943 Battery Gauge Driver"
@@ -670,7 +681,6 @@ config CHARGER_RT9455
config CHARGER_CROS_USBPD
tristate "ChromeOS EC based USBPD charger"
depends on CROS_USBPD_NOTIFY
- default n
help
Say Y here to enable ChromeOS EC based USBPD charger
driver. This driver gets various bits of information about
@@ -681,16 +691,16 @@ config CHARGER_SC2731
tristate "Spreadtrum SC2731 charger driver"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
help
- Say Y here to enable support for battery charging with SC2731
- PMIC chips.
+ Say Y here to enable support for battery charging with SC2731
+ PMIC chips.
config FUEL_GAUGE_SC27XX
tristate "Spreadtrum SC27XX fuel gauge driver"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
depends on IIO
help
- Say Y here to enable support for fuel gauge with SC27XX
- PMIC chips.
+ Say Y here to enable support for fuel gauge with SC27XX
+ PMIC chips.
config CHARGER_UCS1002
tristate "Microchip UCS1002 USB Port Power Controller"
@@ -705,11 +715,20 @@ config CHARGER_UCS1002
config CHARGER_BD70528
tristate "ROHM bd70528 charger driver"
depends on MFD_ROHM_BD70528
- default n
+ select LINEAR_RANGES
+ help
+ Say Y here to enable support for getting battery status
+ information and altering charger configurations from charger
+ block of the ROHM BD70528 Power Management IC.
+
+config CHARGER_BD99954
+ tristate "ROHM bd99954 charger driver"
+ depends on I2C
+ select LINEAR_RANGES
help
- Say Y here to enable support for getting battery status
- information and altering charger configurations from charger
- block of the ROHM BD70528 Power Management IC.
+ Say Y here to enable support for getting battery and charger
+ information and altering charger configurations from the ROHM
+ BD99954 charger IC.
config CHARGER_WILCO
tristate "Wilco EC based charger for ChromeOS"
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 41cb64f09e49..b9644663e435 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
obj-$(CONFIG_BATTERY_AXP20X) += axp20x_battery.o
obj-$(CONFIG_CHARGER_AXP20X) += axp20x_ac_power.o
obj-$(CONFIG_BATTERY_CPCAP) += cpcap-battery.o
+obj-$(CONFIG_BATTERY_CW2015) += cw2015_battery.o
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
@@ -92,4 +93,5 @@ obj-$(CONFIG_CHARGER_SC2731) += sc2731_charger.o
obj-$(CONFIG_FUEL_GAUGE_SC27XX) += sc27xx_fuel_gauge.o
obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o
obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o
+obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o
obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
index b96f90a82ecf..751c4f6c7487 100644
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -2399,7 +2399,7 @@ static void ab8500_fg_reinit_work(struct work_struct *work)
struct ab8500_fg *di = container_of(work, struct ab8500_fg,
fg_reinit_work.work);
- if (di->flags.calibrate == false) {
+ if (!di->flags.calibrate) {
dev_dbg(di->dev, "Resetting FG state machine to init.\n");
ab8500_fg_clear_cap_samples(di);
ab8500_fg_calc_cap_discharge_voltage(di, true);
diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c
index cf4c67b2d235..9d981b76c1e7 100644
--- a/drivers/power/supply/axp288_charger.c
+++ b/drivers/power/supply/axp288_charger.c
@@ -880,10 +880,9 @@ static int axp288_charger_probe(struct platform_device *pdev)
/* Register charger interrupts */
for (i = 0; i < CHRG_INTR_END; i++) {
pirq = platform_get_irq(info->pdev, i);
- if (pirq < 0) {
- dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pirq);
+ if (pirq < 0)
return pirq;
- }
+
info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
if (info->irq[i] < 0) {
dev_warn(&info->pdev->dev,
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c
index f40fa0e63b6e..148eb8105803 100644
--- a/drivers/power/supply/axp288_fuel_gauge.c
+++ b/drivers/power/supply/axp288_fuel_gauge.c
@@ -718,6 +718,12 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = {
},
},
{
+ /* Meegopad T02 */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "MEEGOPAD T02"),
+ },
+ },
+ {
/* Meegopad T08 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
diff --git a/drivers/power/supply/bd70528-charger.c b/drivers/power/supply/bd70528-charger.c
index 3b820110ecfa..7c1f0b99c71b 100644
--- a/drivers/power/supply/bd70528-charger.c
+++ b/drivers/power/supply/bd70528-charger.c
@@ -72,6 +72,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
+#include <linux/linear_range.h>
#define CHG_STAT_SUSPEND 0x0
#define CHG_STAT_TRICKLE 0x1
@@ -335,38 +336,37 @@ static int bd70528_get_present(struct bd70528_psy *bdpsy, int *val)
return 0;
}
-struct bd70528_linear_range {
- int min;
- int step;
- int vals;
- int low_sel;
-};
-
-static const struct bd70528_linear_range current_limit_ranges[] = {
+static const struct linear_range current_limit_ranges[] = {
{
.min = 5,
.step = 1,
- .vals = 36,
- .low_sel = 0,
+ .min_sel = 0,
+ .max_sel = 0x22,
},
{
.min = 40,
.step = 5,
- .vals = 5,
- .low_sel = 0x23,
+ .min_sel = 0x23,
+ .max_sel = 0x26,
},
{
.min = 60,
.step = 20,
- .vals = 8,
- .low_sel = 0x27,
+ .min_sel = 0x27,
+ .max_sel = 0x2d,
},
{
.min = 200,
.step = 50,
- .vals = 7,
- .low_sel = 0x2e,
- }
+ .min_sel = 0x2e,
+ .max_sel = 0x34,
+ },
+ {
+ .min = 500,
+ .step = 0,
+ .min_sel = 0x35,
+ .max_sel = 0x3f,
+ },
};
/*
@@ -374,18 +374,18 @@ static const struct bd70528_linear_range current_limit_ranges[] = {
* voltage for low temperatures. The driver currently only reads
* the charge current at room temperature. We do set both though.
*/
-static const struct bd70528_linear_range warm_charge_curr[] = {
+static const struct linear_range warm_charge_curr[] = {
{
.min = 10,
.step = 10,
- .vals = 20,
- .low_sel = 0,
+ .min_sel = 0,
+ .max_sel = 0x12,
},
{
.min = 200,
.step = 25,
- .vals = 13,
- .low_sel = 0x13,
+ .min_sel = 0x13,
+ .max_sel = 0x1f,
},
};
@@ -398,56 +398,6 @@ static const struct bd70528_linear_range warm_charge_curr[] = {
#define MAX_WARM_CHG_CURR_SEL 0x1f
#define MIN_CHG_CURR_SEL 0x0
-static int find_value_for_selector_low(const struct bd70528_linear_range *r,
- int selectors, unsigned int sel,
- unsigned int *val)
-{
- int i;
-
- for (i = 0; i < selectors; i++) {
- if (r[i].low_sel <= sel && r[i].low_sel + r[i].vals >= sel) {
- *val = r[i].min + (sel - r[i].low_sel) * r[i].step;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-/*
- * For BD70528 voltage/current limits we happily accept any value which
- * belongs the range. We could check if value matching the selector is
- * desired by computing the range min + (sel - sel_low) * range step - but
- * I guess it is enough if we use voltage/current which is closest (below)
- * the requested?
- */
-static int find_selector_for_value_low(const struct bd70528_linear_range *r,
- int selectors, unsigned int val,
- unsigned int *sel, bool *found)
-{
- int i;
- int ret = -EINVAL;
-
- *found = false;
- for (i = 0; i < selectors; i++) {
- if (r[i].min <= val) {
- if (r[i].min + r[i].step * r[i].vals >= val) {
- *found = true;
- *sel = r[i].low_sel + (val - r[i].min) /
- r[i].step;
- ret = 0;
- break;
- }
- /*
- * If the range max is smaller than requested
- * we can set the max supported value from range
- */
- *sel = r[i].low_sel + r[i].vals;
- ret = 0;
- }
- }
- return ret;
-}
-
static int get_charge_current(struct bd70528_psy *bdpsy, int *ma)
{
unsigned int sel;
@@ -463,9 +413,9 @@ static int get_charge_current(struct bd70528_psy *bdpsy, int *ma)
sel &= BD70528_MASK_CHG_CHG_CURR;
- ret = find_value_for_selector_low(&warm_charge_curr[0],
- ARRAY_SIZE(warm_charge_curr), sel,
- ma);
+ ret = linear_range_get_value_array(&warm_charge_curr[0],
+ ARRAY_SIZE(warm_charge_curr),
+ sel, ma);
if (ret) {
dev_err(bdpsy->dev,
"Unknown charge current value 0x%x\n",
@@ -491,10 +441,9 @@ static int get_current_limit(struct bd70528_psy *bdpsy, int *ma)
sel &= BD70528_MASK_CHG_DCIN_ILIM;
- ret = find_value_for_selector_low(&current_limit_ranges[0],
- ARRAY_SIZE(current_limit_ranges), sel,
- ma);
-
+ ret = linear_range_get_value_array(&current_limit_ranges[0],
+ ARRAY_SIZE(current_limit_ranges),
+ sel, ma);
if (ret) {
/* Unspecified values mean 500 mA */
*ma = 500;
@@ -588,15 +537,28 @@ static int set_charge_current(struct bd70528_psy *bdpsy, int ma)
goto set;
}
- ret = find_selector_for_value_low(&warm_charge_curr[0],
- ARRAY_SIZE(warm_charge_curr), ma,
- &reg, &found);
+/*
+ * For BD70528 voltage/current limits we happily accept any value which
+ * belongs the range. We could check if value matching the selector is
+ * desired by computing the range min + (sel - sel_low) * range step - but
+ * I guess it is enough if we use voltage/current which is closest (below)
+ * the requested?
+ */
+
+ ret = linear_range_get_selector_low_array(warm_charge_curr,
+ ARRAY_SIZE(warm_charge_curr),
+ ma, &reg, &found);
if (ret) {
+ dev_err(bdpsy->dev,
+ "Unsupported charge current %u mA\n", ma);
reg = MIN_CHG_CURR_SEL;
goto set;
}
if (!found) {
- /* There was a gap in supported values and we hit it */
+ /*
+ * There was a gap in supported values and we hit it.
+ * Yet a smaller value was found so we use it.
+ */
dev_warn(bdpsy->dev,
"Unsupported charge current %u mA\n", ma);
}
@@ -648,17 +610,21 @@ static int set_current_limit(struct bd70528_psy *bdpsy, int ma)
goto set;
}
- ret = find_selector_for_value_low(&current_limit_ranges[0],
- ARRAY_SIZE(current_limit_ranges), ma,
- &reg, &found);
+ ret = linear_range_get_selector_low_array(current_limit_ranges,
+ ARRAY_SIZE(current_limit_ranges),
+ ma, &reg, &found);
if (ret) {
+ dev_err(bdpsy->dev, "Unsupported current limit %umA\n", ma);
reg = MIN_CURR_LIMIT_SEL;
goto set;
}
if (!found) {
- /* There was a gap in supported values and we hit it ?*/
- dev_warn(bdpsy->dev, "Unsupported current limit %umA\n",
- ma);
+ /*
+ * There was a gap in supported values and we hit it.
+ * We found a smaller value from ranges and use it.
+ * Warn user though.
+ */
+ dev_warn(bdpsy->dev, "Unsupported current limit %umA\n", ma);
}
set:
diff --git a/drivers/power/supply/bd99954-charger.c b/drivers/power/supply/bd99954-charger.c
new file mode 100644
index 000000000000..ffd8bfa08179
--- /dev/null
+++ b/drivers/power/supply/bd99954-charger.c
@@ -0,0 +1,1142 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ROHM BD99954 charger driver
+ *
+ * Copyright (C) 2020 Rohm Semiconductors
+ * Originally written by:
+ * Mikko Mutanen <mikko.mutanen@fi.rohmeurope.com>
+ * Markus Laine <markus.laine@fi.rohmeurope.com>
+ * Bugs added by:
+ * Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+ */
+
+/*
+ * The battery charging profile of BD99954.
+ *
+ * Curve (1) represents charging current.
+ * Curve (2) represents battery voltage.
+ *
+ * The BD99954 data sheet divides charging to three phases.
+ * a) Trickle-charge with constant current (8).
+ * b) pre-charge with constant current (6)
+ * c) fast-charge, first with constant current (5) phase. After
+ * the battery voltage has reached target level (4) we have constant
+ * voltage phase until charging current has dropped to termination
+ * level (7)
+ *
+ * V ^ ^ I
+ * . .
+ * . .
+ *(4)` `.` ` ` ` ` ` ` ` ` ` ` ` ` ` ----------------------------.
+ * . :/ .
+ * . o----+/:/ ` ` ` ` ` ` ` ` ` ` ` ` `.` ` (5)
+ * . + :: + .
+ * . + /- -- .
+ * . +`/- + .
+ * . o/- -: .
+ * . .s. +` .
+ * . .--+ `/ .
+ * . ..`` + .: .
+ * . -` + -- .
+ * . (2) ...`` + :- .
+ * . ...`` + -: .
+ *(3)` `.`."" ` ` ` `+-------- ` ` ` ` ` ` `.:` ` ` ` ` ` ` ` ` .` ` (6)
+ * . + `:. .
+ * . + -: .
+ * . + -:. .
+ * . + .--. .
+ * . (1) + `.+` ` ` `.` ` (7)
+ * -..............` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` + ` ` ` .` ` (8)
+ * . + -
+ * -------------------------------------------------+++++++++-->
+ * | trickle | pre | fast |
+ *
+ * Details of DT properties for different limits can be found from BD99954
+ * device tree binding documentation.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/linear_range.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/power_supply.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include "bd99954-charger.h"
+
+struct battery_data {
+ u16 precharge_current; /* Trickle-charge Current */
+ u16 fc_reg_voltage; /* Fast Charging Regulation Voltage */
+ u16 voltage_min;
+ u16 voltage_max;
+};
+
+/* Initial field values, converted to initial register values */
+struct bd9995x_init_data {
+ u16 vsysreg_set; /* VSYS Regulation Setting */
+ u16 ibus_lim_set; /* VBUS input current limitation */
+ u16 icc_lim_set; /* VCC/VACP Input Current Limit Setting */
+ u16 itrich_set; /* Trickle-charge Current Setting */
+ u16 iprech_set; /* Pre-Charge Current Setting */
+ u16 ichg_set; /* Fast-Charge constant current */
+ u16 vfastchg_reg_set1; /* Fast Charging Regulation Voltage */
+ u16 vprechg_th_set; /* Pre-charge Voltage Threshold Setting */
+ u16 vrechg_set; /* Re-charge Battery Voltage Setting */
+ u16 vbatovp_set; /* Battery Over Voltage Threshold Setting */
+ u16 iterm_set; /* Charging termination current */
+};
+
+struct bd9995x_state {
+ u8 online;
+ u16 chgstm_status;
+ u16 vbat_vsys_status;
+ u16 vbus_vcc_status;
+};
+
+struct bd9995x_device {
+ struct i2c_client *client;
+ struct device *dev;
+ struct power_supply *charger;
+
+ struct regmap *rmap;
+ struct regmap_field *rmap_fields[F_MAX_FIELDS];
+
+ int chip_id;
+ int chip_rev;
+ struct bd9995x_init_data init_data;
+ struct bd9995x_state state;
+
+ struct mutex lock; /* Protect state data */
+};
+
+static const struct regmap_range bd9995x_readonly_reg_ranges[] = {
+ regmap_reg_range(CHGSTM_STATUS, SEL_ILIM_VAL),
+ regmap_reg_range(IOUT_DACIN_VAL, IOUT_DACIN_VAL),
+ regmap_reg_range(VCC_UCD_STATUS, VCC_IDD_STATUS),
+ regmap_reg_range(VBUS_UCD_STATUS, VBUS_IDD_STATUS),
+ regmap_reg_range(CHIP_ID, CHIP_REV),
+ regmap_reg_range(SYSTEM_STATUS, SYSTEM_STATUS),
+ regmap_reg_range(IBATP_VAL, VBAT_AVE_VAL),
+ regmap_reg_range(VTH_VAL, EXTIADP_AVE_VAL),
+};
+
+static const struct regmap_access_table bd9995x_writeable_regs = {
+ .no_ranges = bd9995x_readonly_reg_ranges,
+ .n_no_ranges = ARRAY_SIZE(bd9995x_readonly_reg_ranges),
+};
+
+static const struct regmap_range bd9995x_volatile_reg_ranges[] = {
+ regmap_reg_range(CHGSTM_STATUS, WDT_STATUS),
+ regmap_reg_range(VCC_UCD_STATUS, VCC_IDD_STATUS),
+ regmap_reg_range(VBUS_UCD_STATUS, VBUS_IDD_STATUS),
+ regmap_reg_range(INT0_STATUS, INT7_STATUS),
+ regmap_reg_range(SYSTEM_STATUS, SYSTEM_CTRL_SET),
+ regmap_reg_range(IBATP_VAL, EXTIADP_AVE_VAL), /* Measurement regs */
+};
+
+static const struct regmap_access_table bd9995x_volatile_regs = {
+ .yes_ranges = bd9995x_volatile_reg_ranges,
+ .n_yes_ranges = ARRAY_SIZE(bd9995x_volatile_reg_ranges),
+};
+
+static const struct regmap_range_cfg regmap_range_cfg[] = {
+ {
+ .selector_reg = MAP_SET,
+ .selector_mask = 0xFFFF,
+ .selector_shift = 0,
+ .window_start = 0,
+ .window_len = 0x100,
+ .range_min = 0 * 0x100,
+ .range_max = 3 * 0x100,
+ },
+};
+
+static const struct regmap_config bd9995x_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .reg_stride = 1,
+
+ .max_register = 3 * 0x100,
+ .cache_type = REGCACHE_RBTREE,
+
+ .ranges = regmap_range_cfg,
+ .num_ranges = ARRAY_SIZE(regmap_range_cfg),
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+ .wr_table = &bd9995x_writeable_regs,
+ .volatile_table = &bd9995x_volatile_regs,
+};
+
+enum bd9995x_chrg_fault {
+ CHRG_FAULT_NORMAL,
+ CHRG_FAULT_INPUT,
+ CHRG_FAULT_THERMAL_SHUTDOWN,
+ CHRG_FAULT_TIMER_EXPIRED,
+};
+
+static int bd9995x_get_prop_batt_health(struct bd9995x_device *bd)
+{
+ int ret, tmp;
+
+ ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp);
+ if (ret)
+ return POWER_SUPPLY_HEALTH_UNKNOWN;
+
+ /* TODO: Check these against datasheet page 34 */
+
+ switch (tmp) {
+ case ROOM:
+ return POWER_SUPPLY_HEALTH_GOOD;
+ case HOT1:
+ case HOT2:
+ case HOT3:
+ return POWER_SUPPLY_HEALTH_OVERHEAT;
+ case COLD1:
+ case COLD2:
+ return POWER_SUPPLY_HEALTH_COLD;
+ case TEMP_DIS:
+ case BATT_OPEN:
+ default:
+ return POWER_SUPPLY_HEALTH_UNKNOWN;
+ }
+}
+
+static int bd9995x_get_prop_charge_type(struct bd9995x_device *bd)
+{
+ int ret, tmp;
+
+ ret = regmap_field_read(bd->rmap_fields[F_CHGSTM_STATE], &tmp);
+ if (ret)
+ return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+
+ switch (tmp) {
+ case CHGSTM_TRICKLE_CHARGE:
+ case CHGSTM_PRE_CHARGE:
+ return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ case CHGSTM_FAST_CHARGE:
+ return POWER_SUPPLY_CHARGE_TYPE_FAST;
+ case CHGSTM_TOP_OFF:
+ case CHGSTM_DONE:
+ case CHGSTM_SUSPEND:
+ return POWER_SUPPLY_CHARGE_TYPE_NONE;
+ default: /* Rest of the states are error related, no charging */
+ return POWER_SUPPLY_CHARGE_TYPE_NONE;
+ }
+}
+
+static bool bd9995x_get_prop_batt_present(struct bd9995x_device *bd)
+{
+ int ret, tmp;
+
+ ret = regmap_field_read(bd->rmap_fields[F_BATTEMP], &tmp);
+ if (ret)
+ return false;
+
+ return tmp != BATT_OPEN;
+}
+
+static int bd9995x_get_prop_batt_voltage(struct bd9995x_device *bd)
+{
+ int ret, tmp;
+
+ ret = regmap_field_read(bd->rmap_fields[F_VBAT_VAL], &tmp);
+ if (ret)
+ return 0;
+
+ tmp = min(tmp, 19200);
+
+ return tmp * 1000;
+}
+
+static int bd9995x_get_prop_batt_current(struct bd9995x_device *bd)
+{
+ int ret, tmp;
+
+ ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp);
+ if (ret)
+ return 0;
+
+ return tmp * 1000;
+}
+
+#define DEFAULT_BATTERY_TEMPERATURE 250
+
+static int bd9995x_get_prop_batt_temp(struct bd9995x_device *bd)
+{
+ int ret, tmp;
+
+ ret = regmap_field_read(bd->rmap_fields[F_THERM_VAL], &tmp);
+ if (ret)
+ return DEFAULT_BATTERY_TEMPERATURE;
+
+ return (200 - tmp) * 10;
+}
+
+static int bd9995x_power_supply_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret, tmp;
+ struct bd9995x_device *bd = power_supply_get_drvdata(psy);
+ struct bd9995x_state state;
+
+ mutex_lock(&bd->lock);
+ state = bd->state;
+ mutex_unlock(&bd->lock);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ switch (state.chgstm_status) {
+ case CHGSTM_TRICKLE_CHARGE:
+ case CHGSTM_PRE_CHARGE:
+ case CHGSTM_FAST_CHARGE:
+ case CHGSTM_TOP_OFF:
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+
+ case CHGSTM_DONE:
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ break;
+
+ case CHGSTM_SUSPEND:
+ case CHGSTM_TEMPERATURE_ERROR_1:
+ case CHGSTM_TEMPERATURE_ERROR_2:
+ case CHGSTM_TEMPERATURE_ERROR_3:
+ case CHGSTM_TEMPERATURE_ERROR_4:
+ case CHGSTM_TEMPERATURE_ERROR_5:
+ case CHGSTM_TEMPERATURE_ERROR_6:
+ case CHGSTM_TEMPERATURE_ERROR_7:
+ case CHGSTM_THERMAL_SHUT_DOWN_1:
+ case CHGSTM_THERMAL_SHUT_DOWN_2:
+ case CHGSTM_THERMAL_SHUT_DOWN_3:
+ case CHGSTM_THERMAL_SHUT_DOWN_4:
+ case CHGSTM_THERMAL_SHUT_DOWN_5:
+ case CHGSTM_THERMAL_SHUT_DOWN_6:
+ case CHGSTM_THERMAL_SHUT_DOWN_7:
+ case CHGSTM_BATTERY_ERROR:
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+
+ default:
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ break;
+ }
+ break;
+
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = BD9995X_MANUFACTURER;
+ break;
+
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = state.online;
+ break;
+
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+ ret = regmap_field_read(bd->rmap_fields[F_IBATP_VAL], &tmp);
+ if (ret)
+ return ret;
+ val->intval = tmp * 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_CHARGE_AVG:
+ ret = regmap_field_read(bd->rmap_fields[F_IBATP_AVE_VAL], &tmp);
+ if (ret)
+ return ret;
+ val->intval = tmp * 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ /*
+ * Currently the DT uses this property to give the
+ * target current for fast-charging constant current phase.
+ * I think it is correct in a sense.
+ *
+ * Yet, this prop we read and return here is the programmed
+ * safety limit for combined input currents. This feels
+ * also correct in a sense.
+ *
+ * However, this results a mismatch to DT value and value
+ * read from sysfs.
+ */
+ ret = regmap_field_read(bd->rmap_fields[F_SEL_ILIM_VAL], &tmp);
+ if (ret)
+ return ret;
+ val->intval = tmp * 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
+ if (!state.online) {
+ val->intval = 0;
+ break;
+ }
+
+ ret = regmap_field_read(bd->rmap_fields[F_VFASTCHG_REG_SET1],
+ &tmp);
+ if (ret)
+ return ret;
+
+ /*
+ * The actual range : 2560 to 19200 mV. No matter what the
+ * register says
+ */
+ val->intval = clamp_val(tmp << 4, 2560, 19200);
+ val->intval *= 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+ ret = regmap_field_read(bd->rmap_fields[F_ITERM_SET], &tmp);
+ if (ret)
+ return ret;
+ /* Start step is 64 mA */
+ val->intval = tmp << 6;
+ /* Maximum is 1024 mA - no matter what register says */
+ val->intval = min(val->intval, 1024);
+ val->intval *= 1000;
+ break;
+
+ /* Battery properties which we access through charger */
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = bd9995x_get_prop_batt_present(bd);
+ break;
+
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = bd9995x_get_prop_batt_voltage(bd);
+ break;
+
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = bd9995x_get_prop_batt_current(bd);
+ break;
+
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ val->intval = bd9995x_get_prop_charge_type(bd);
+ break;
+
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = bd9995x_get_prop_batt_health(bd);
+ break;
+
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = bd9995x_get_prop_batt_temp(bd);
+ break;
+
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = "bd99954";
+ break;
+
+ default:
+ return -EINVAL;
+
+ }
+
+ return 0;
+}
+
+static int bd9995x_get_chip_state(struct bd9995x_device *bd,
+ struct bd9995x_state *state)
+{
+ int i, ret, tmp;
+ struct {
+ struct regmap_field *id;
+ u16 *data;
+ } state_fields[] = {
+ {
+ bd->rmap_fields[F_CHGSTM_STATE], &state->chgstm_status,
+ }, {
+ bd->rmap_fields[F_VBAT_VSYS_STATUS],
+ &state->vbat_vsys_status,
+ }, {
+ bd->rmap_fields[F_VBUS_VCC_STATUS],
+ &state->vbus_vcc_status,
+ },
+ };
+
+
+ for (i = 0; i < ARRAY_SIZE(state_fields); i++) {
+ ret = regmap_field_read(state_fields[i].id, &tmp);
+ if (ret)
+ return ret;
+
+ *state_fields[i].data = tmp;
+ }
+
+ if (state->vbus_vcc_status & STATUS_VCC_DET ||
+ state->vbus_vcc_status & STATUS_VBUS_DET)
+ state->online = 1;
+ else
+ state->online = 0;
+
+ return 0;
+}
+
+static irqreturn_t bd9995x_irq_handler_thread(int irq, void *private)
+{
+ struct bd9995x_device *bd = private;
+ int ret, status, mask, i;
+ unsigned long tmp;
+ struct bd9995x_state state;
+
+ /*
+ * The bd9995x does not seem to generate big amount of interrupts.
+ * The logic regarding which interrupts can cause relevant
+ * status changes seem to be pretty complex.
+ *
+ * So lets implement really simple and hopefully bullet-proof handler:
+ * It does not really matter which IRQ we handle, we just go and
+ * re-read all interesting statuses + give the framework a nudge.
+ *
+ * Other option would be building a _complex_ and error prone logic
+ * trying to decide what could have been changed (resulting this IRQ
+ * we are now handling). During the normal operation the BD99954 does
+ * not seem to be generating much of interrupts so benefit from such
+ * logic would probably be minimal.
+ */
+
+ ret = regmap_read(bd->rmap, INT0_STATUS, &status);
+ if (ret) {
+ dev_err(bd->dev, "Failed to read IRQ status\n");
+ return IRQ_NONE;
+ }
+
+ ret = regmap_field_read(bd->rmap_fields[F_INT0_SET], &mask);
+ if (ret) {
+ dev_err(bd->dev, "Failed to read IRQ mask\n");
+ return IRQ_NONE;
+ }
+
+ /* Handle only IRQs that are not masked */
+ status &= mask;
+ tmp = status;
+
+ /* Lowest bit does not represent any sub-registers */
+ tmp >>= 1;
+
+ /*
+ * Mask and ack IRQs we will handle (+ the idiot bit)
+ */
+ ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], 0);
+ if (ret) {
+ dev_err(bd->dev, "Failed to mask F_INT0\n");
+ return IRQ_NONE;
+ }
+
+ ret = regmap_write(bd->rmap, INT0_STATUS, status);
+ if (ret) {
+ dev_err(bd->dev, "Failed to ack F_INT0\n");
+ goto err_umask;
+ }
+
+ for_each_set_bit(i, &tmp, 7) {
+ int sub_status, sub_mask;
+ int sub_status_reg[] = {
+ INT1_STATUS, INT2_STATUS, INT3_STATUS, INT4_STATUS,
+ INT5_STATUS, INT6_STATUS, INT7_STATUS,
+ };
+ struct regmap_field *sub_mask_f[] = {
+ bd->rmap_fields[F_INT1_SET],
+ bd->rmap_fields[F_INT2_SET],
+ bd->rmap_fields[F_INT3_SET],
+ bd->rmap_fields[F_INT4_SET],
+ bd->rmap_fields[F_INT5_SET],
+ bd->rmap_fields[F_INT6_SET],
+ bd->rmap_fields[F_INT7_SET],
+ };
+
+ /* Clear sub IRQs */
+ ret = regmap_read(bd->rmap, sub_status_reg[i], &sub_status);
+ if (ret) {
+ dev_err(bd->dev, "Failed to read IRQ sub-status\n");
+ goto err_umask;
+ }
+
+ ret = regmap_field_read(sub_mask_f[i], &sub_mask);
+ if (ret) {
+ dev_err(bd->dev, "Failed to read IRQ sub-mask\n");
+ goto err_umask;
+ }
+
+ /* Ack active sub-statuses */
+ sub_status &= sub_mask;
+
+ ret = regmap_write(bd->rmap, sub_status_reg[i], sub_status);
+ if (ret) {
+ dev_err(bd->dev, "Failed to ack sub-IRQ\n");
+ goto err_umask;
+ }
+ }
+
+ ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask);
+ if (ret)
+ /* May as well retry once */
+ goto err_umask;
+
+ /* Read whole chip state */
+ ret = bd9995x_get_chip_state(bd, &state);
+ if (ret < 0) {
+ dev_err(bd->dev, "Failed to read chip state\n");
+ } else {
+ mutex_lock(&bd->lock);
+ bd->state = state;
+ mutex_unlock(&bd->lock);
+
+ power_supply_changed(bd->charger);
+ }
+
+ return IRQ_HANDLED;
+
+err_umask:
+ ret = regmap_field_write(bd->rmap_fields[F_INT0_SET], mask);
+ if (ret)
+ dev_err(bd->dev,
+ "Failed to un-mask F_INT0 - IRQ permanently disabled\n");
+
+ return IRQ_NONE;
+}
+
+static int __bd9995x_chip_reset(struct bd9995x_device *bd)
+{
+ int ret, state;
+ int rst_check_counter = 10;
+ u16 tmp = ALLRST | OTPLD;
+
+ ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2);
+ if (ret < 0)
+ return ret;
+
+ do {
+ ret = regmap_field_read(bd->rmap_fields[F_OTPLD_STATE], &state);
+ if (ret)
+ return ret;
+
+ msleep(10);
+ } while (state == 0 && --rst_check_counter);
+
+ if (!rst_check_counter) {
+ dev_err(bd->dev, "chip reset not completed\n");
+ return -ETIMEDOUT;
+ }
+
+ tmp = 0;
+ ret = regmap_raw_write(bd->rmap, SYSTEM_CTRL_SET, &tmp, 2);
+
+ return ret;
+}
+
+static int bd9995x_hw_init(struct bd9995x_device *bd)
+{
+ int ret;
+ int i;
+ struct bd9995x_state state;
+ struct bd9995x_init_data *id = &bd->init_data;
+
+ const struct {
+ enum bd9995x_fields id;
+ u16 value;
+ } init_data[] = {
+ /* Enable the charging trigger after SDP charger attached */
+ {F_SDP_CHG_TRIG_EN, 1},
+ /* Enable charging trigger after SDP charger attached */
+ {F_SDP_CHG_TRIG, 1},
+ /* Disable charging trigger by BC1.2 detection */
+ {F_VBUS_BC_DISEN, 1},
+ /* Disable charging trigger by BC1.2 detection */
+ {F_VCC_BC_DISEN, 1},
+ /* Disable automatic limitation of the input current */
+ {F_ILIM_AUTO_DISEN, 1},
+ /* Select current limitation when SDP charger attached*/
+ {F_SDP_500_SEL, 1},
+ /* Select current limitation when DCP charger attached */
+ {F_DCP_2500_SEL, 1},
+ {F_VSYSREG_SET, id->vsysreg_set},
+ /* Activate USB charging and DC/DC converter */
+ {F_USB_SUS, 0},
+ /* DCDC clock: 1200 kHz*/
+ {F_DCDC_CLK_SEL, 3},
+ /* Enable charging */
+ {F_CHG_EN, 1},
+ /* Disable Input current Limit setting voltage measurement */
+ {F_EXTIADPEN, 0},
+ /* Disable input current limiting */
+ {F_VSYS_PRIORITY, 1},
+ {F_IBUS_LIM_SET, id->ibus_lim_set},
+ {F_ICC_LIM_SET, id->icc_lim_set},
+ /* Charge Termination Current Setting to 0*/
+ {F_ITERM_SET, id->iterm_set},
+ /* Trickle-charge Current Setting */
+ {F_ITRICH_SET, id->itrich_set},
+ /* Pre-charge Current setting */
+ {F_IPRECH_SET, id->iprech_set},
+ /* Fast Charge Current for constant current phase */
+ {F_ICHG_SET, id->ichg_set},
+ /* Fast Charge Voltage Regulation Setting */
+ {F_VFASTCHG_REG_SET1, id->vfastchg_reg_set1},
+ /* Set Pre-charge Voltage Threshold for trickle charging. */
+ {F_VPRECHG_TH_SET, id->vprechg_th_set},
+ {F_VRECHG_SET, id->vrechg_set},
+ {F_VBATOVP_SET, id->vbatovp_set},
+ /* Reverse buck boost voltage Setting */
+ {F_VRBOOST_SET, 0},
+ /* Disable fast-charging watchdog */
+ {F_WDT_FST, 0},
+ /* Disable pre-charging watchdog */
+ {F_WDT_PRE, 0},
+ /* Power save off */
+ {F_POWER_SAVE_MODE, 0},
+ {F_INT1_SET, INT1_ALL},
+ {F_INT2_SET, INT2_ALL},
+ {F_INT3_SET, INT3_ALL},
+ {F_INT4_SET, INT4_ALL},
+ {F_INT5_SET, INT5_ALL},
+ {F_INT6_SET, INT6_ALL},
+ {F_INT7_SET, INT7_ALL},
+ };
+
+ /*
+ * Currently we initialize charger to a known state at startup.
+ * If we want to allow for example the boot code to initialize
+ * charger we should get rid of this.
+ */
+ ret = __bd9995x_chip_reset(bd);
+ if (ret < 0)
+ return ret;
+
+ /* Initialize currents/voltages and other parameters */
+ for (i = 0; i < ARRAY_SIZE(init_data); i++) {
+ ret = regmap_field_write(bd->rmap_fields[init_data[i].id],
+ init_data[i].value);
+ if (ret) {
+ dev_err(bd->dev, "failed to initialize charger (%d)\n",
+ ret);
+ return ret;
+ }
+ }
+
+ ret = bd9995x_get_chip_state(bd, &state);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&bd->lock);
+ bd->state = state;
+ mutex_unlock(&bd->lock);
+
+ return 0;
+}
+
+static enum power_supply_property bd9995x_power_supply_props[] = {
+ POWER_SUPPLY_PROP_MANUFACTURER,
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
+ POWER_SUPPLY_PROP_CHARGE_AVG,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
+ POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
+ /* Battery props we access through charger */
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+};
+
+static const struct power_supply_desc bd9995x_power_supply_desc = {
+ .name = "bd9995x-charger",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .properties = bd9995x_power_supply_props,
+ .num_properties = ARRAY_SIZE(bd9995x_power_supply_props),
+ .get_property = bd9995x_power_supply_get_property,
+};
+
+/*
+ * Limit configurations for vbus-input-current and vcc-vacp-input-current
+ * Minimum limit is 0 uA. Max is 511 * 32000 uA = 16352000 uA. This is
+ * configured by writing a register so that each increment in register
+ * value equals to 32000 uA limit increment.
+ *
+ * Eg, value 0x0 is limit 0, value 0x1 is limit 32000, ...
+ * Describe the setting in linear_range table.
+ */
+static const struct linear_range input_current_limit_ranges[] = {
+ {
+ .min = 0,
+ .step = 32000,
+ .min_sel = 0x0,
+ .max_sel = 0x1ff,
+ },
+};
+
+/* Possible trickle, pre-charging and termination current values */
+static const struct linear_range charging_current_ranges[] = {
+ {
+ .min = 0,
+ .step = 64000,
+ .min_sel = 0x0,
+ .max_sel = 0x10,
+ }, {
+ .min = 1024000,
+ .step = 0,
+ .min_sel = 0x11,
+ .max_sel = 0x1f,
+ },
+};
+
+/*
+ * Fast charging voltage regulation, starting re-charging limit
+ * and battery over voltage protection have same possible values
+ */
+static const struct linear_range charge_voltage_regulation_ranges[] = {
+ {
+ .min = 2560000,
+ .step = 0,
+ .min_sel = 0,
+ .max_sel = 0xA0,
+ }, {
+ .min = 2560000,
+ .step = 16000,
+ .min_sel = 0xA0,
+ .max_sel = 0x4B0,
+ }, {
+ .min = 19200000,
+ .step = 0,
+ .min_sel = 0x4B0,
+ .max_sel = 0x7FF,
+ },
+};
+
+/* Possible VSYS voltage regulation values */
+static const struct linear_range vsys_voltage_regulation_ranges[] = {
+ {
+ .min = 2560000,
+ .step = 0,
+ .min_sel = 0,
+ .max_sel = 0x28,
+ }, {
+ .min = 2560000,
+ .step = 64000,
+ .min_sel = 0x28,
+ .max_sel = 0x12C,
+ }, {
+ .min = 19200000,
+ .step = 0,
+ .min_sel = 0x12C,
+ .max_sel = 0x1FF,
+ },
+};
+
+/* Possible settings for switching from trickle to pre-charging limits */
+static const struct linear_range trickle_to_pre_threshold_ranges[] = {
+ {
+ .min = 2048000,
+ .step = 0,
+ .min_sel = 0,
+ .max_sel = 0x20,
+ }, {
+ .min = 2048000,
+ .step = 64000,
+ .min_sel = 0x20,
+ .max_sel = 0x12C,
+ }, {
+ .min = 19200000,
+ .step = 0,
+ .min_sel = 0x12C,
+ .max_sel = 0x1FF
+ }
+};
+
+/* Possible current values for fast-charging constant current phase */
+static const struct linear_range fast_charge_current_ranges[] = {
+ {
+ .min = 0,
+ .step = 64000,
+ .min_sel = 0,
+ .max_sel = 0xFF,
+ }
+};
+
+struct battery_init {
+ const char *name;
+ int *info_data;
+ const struct linear_range *range;
+ int ranges;
+ u16 *data;
+};
+
+struct dt_init {
+ char *prop;
+ const struct linear_range *range;
+ int ranges;
+ u16 *data;
+};
+
+static int bd9995x_fw_probe(struct bd9995x_device *bd)
+{
+ int ret;
+ struct power_supply_battery_info info;
+ u32 property;
+ int i;
+ int regval;
+ bool found;
+ struct bd9995x_init_data *init = &bd->init_data;
+ struct battery_init battery_inits[] = {
+ {
+ .name = "trickle-charging current",
+ .info_data = &info.tricklecharge_current_ua,
+ .range = &charging_current_ranges[0],
+ .ranges = 2,
+ .data = &init->itrich_set,
+ }, {
+ .name = "pre-charging current",
+ .info_data = &info.precharge_current_ua,
+ .range = &charging_current_ranges[0],
+ .ranges = 2,
+ .data = &init->iprech_set,
+ }, {
+ .name = "pre-to-trickle charge voltage threshold",
+ .info_data = &info.precharge_voltage_max_uv,
+ .range = &trickle_to_pre_threshold_ranges[0],
+ .ranges = 2,
+ .data = &init->vprechg_th_set,
+ }, {
+ .name = "charging termination current",
+ .info_data = &info.charge_term_current_ua,
+ .range = &charging_current_ranges[0],
+ .ranges = 2,
+ .data = &init->iterm_set,
+ }, {
+ .name = "charging re-start voltage",
+ .info_data = &info.charge_restart_voltage_uv,
+ .range = &charge_voltage_regulation_ranges[0],
+ .ranges = 2,
+ .data = &init->vrechg_set,
+ }, {
+ .name = "battery overvoltage limit",
+ .info_data = &info.overvoltage_limit_uv,
+ .range = &charge_voltage_regulation_ranges[0],
+ .ranges = 2,
+ .data = &init->vbatovp_set,
+ }, {
+ .name = "fast-charging max current",
+ .info_data = &info.constant_charge_current_max_ua,
+ .range = &fast_charge_current_ranges[0],
+ .ranges = 1,
+ .data = &init->ichg_set,
+ }, {
+ .name = "fast-charging voltage",
+ .info_data = &info.constant_charge_voltage_max_uv,
+ .range = &charge_voltage_regulation_ranges[0],
+ .ranges = 2,
+ .data = &init->vfastchg_reg_set1,
+ },
+ };
+ struct dt_init props[] = {
+ {
+ .prop = "rohm,vsys-regulation-microvolt",
+ .range = &vsys_voltage_regulation_ranges[0],
+ .ranges = 2,
+ .data = &init->vsysreg_set,
+ }, {
+ .prop = "rohm,vbus-input-current-limit-microamp",
+ .range = &input_current_limit_ranges[0],
+ .ranges = 1,
+ .data = &init->ibus_lim_set,
+ }, {
+ .prop = "rohm,vcc-input-current-limit-microamp",
+ .range = &input_current_limit_ranges[0],
+ .ranges = 1,
+ .data = &init->icc_lim_set,
+ },
+ };
+
+ /*
+ * The power_supply_get_battery_info() does not support getting values
+ * from ACPI. Let's fix it if ACPI is required here.
+ */
+ ret = power_supply_get_battery_info(bd->charger, &info);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(battery_inits); i++) {
+ int val = *battery_inits[i].info_data;
+ const struct linear_range *range = battery_inits[i].range;
+ int ranges = battery_inits[i].ranges;
+
+ if (val == -EINVAL)
+ continue;
+
+ ret = linear_range_get_selector_low_array(range, ranges, val,
+ &regval, &found);
+ if (ret) {
+ dev_err(bd->dev, "Unsupported value for %s\n",
+ battery_inits[i].name);
+
+ power_supply_put_battery_info(bd->charger, &info);
+ return -EINVAL;
+ }
+ if (!found) {
+ dev_warn(bd->dev,
+ "Unsupported value for %s - using smaller\n",
+ battery_inits[i].name);
+ }
+ *(battery_inits[i].data) = regval;
+ }
+
+ power_supply_put_battery_info(bd->charger, &info);
+
+ for (i = 0; i < ARRAY_SIZE(props); i++) {
+ ret = device_property_read_u32(bd->dev, props[i].prop,
+ &property);
+ if (ret < 0) {
+ dev_err(bd->dev, "failed to read %s", props[i].prop);
+
+ return ret;
+ }
+
+ ret = linear_range_get_selector_low_array(props[i].range,
+ props[i].ranges,
+ property, &regval,
+ &found);
+ if (ret) {
+ dev_err(bd->dev, "Unsupported value for '%s'\n",
+ props[i].prop);
+
+ return -EINVAL;
+ }
+
+ if (!found) {
+ dev_warn(bd->dev,
+ "Unsupported value for '%s' - using smaller\n",
+ props[i].prop);
+ }
+
+ *(props[i].data) = regval;
+ }
+
+ return 0;
+}
+
+static void bd9995x_chip_reset(void *bd)
+{
+ __bd9995x_chip_reset(bd);
+}
+
+static int bd9995x_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct bd9995x_device *bd;
+ struct power_supply_config psy_cfg = {};
+ int ret;
+ int i;
+
+ bd = devm_kzalloc(dev, sizeof(*bd), GFP_KERNEL);
+ if (!bd)
+ return -ENOMEM;
+
+ bd->client = client;
+ bd->dev = dev;
+ psy_cfg.drv_data = bd;
+ psy_cfg.of_node = dev->of_node;
+
+ mutex_init(&bd->lock);
+
+ bd->rmap = devm_regmap_init_i2c(client, &bd9995x_regmap_config);
+ if (IS_ERR(bd->rmap)) {
+ dev_err(dev, "Failed to setup register access via i2c\n");
+ return PTR_ERR(bd->rmap);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(bd9995x_reg_fields); i++) {
+ const struct reg_field *reg_fields = bd9995x_reg_fields;
+
+ bd->rmap_fields[i] = devm_regmap_field_alloc(dev, bd->rmap,
+ reg_fields[i]);
+ if (IS_ERR(bd->rmap_fields[i])) {
+ dev_err(dev, "cannot allocate regmap field\n");
+ return PTR_ERR(bd->rmap_fields[i]);
+ }
+ }
+
+ i2c_set_clientdata(client, bd);
+
+ ret = regmap_field_read(bd->rmap_fields[F_CHIP_ID], &bd->chip_id);
+ if (ret) {
+ dev_err(dev, "Cannot read chip ID.\n");
+ return ret;
+ }
+
+ if (bd->chip_id != BD99954_ID) {
+ dev_err(dev, "Chip with ID=0x%x, not supported!\n",
+ bd->chip_id);
+ return -ENODEV;
+ }
+
+ ret = regmap_field_read(bd->rmap_fields[F_CHIP_REV], &bd->chip_rev);
+ if (ret) {
+ dev_err(dev, "Cannot read revision.\n");
+ return ret;
+ }
+
+ dev_info(bd->dev, "Found BD99954 chip rev %d\n", bd->chip_rev);
+
+ /*
+ * We need to init the psy before we can call
+ * power_supply_get_battery_info() for it
+ */
+ bd->charger = devm_power_supply_register(bd->dev,
+ &bd9995x_power_supply_desc,
+ &psy_cfg);
+ if (IS_ERR(bd->charger)) {
+ dev_err(dev, "Failed to register power supply\n");
+ return PTR_ERR(bd->charger);
+ }
+
+ ret = bd9995x_fw_probe(bd);
+ if (ret < 0) {
+ dev_err(dev, "Cannot read device properties.\n");
+ return ret;
+ }
+
+ ret = bd9995x_hw_init(bd);
+ if (ret < 0) {
+ dev_err(dev, "Cannot initialize the chip.\n");
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(dev, bd9995x_chip_reset, bd);
+ if (ret)
+ return ret;
+
+ return devm_request_threaded_irq(dev, client->irq, NULL,
+ bd9995x_irq_handler_thread,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ BD9995X_IRQ_PIN, bd);
+}
+
+static const struct of_device_id bd9995x_of_match[] = {
+ { .compatible = "rohm,bd99954", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, bd9995x_of_match);
+
+static struct i2c_driver bd9995x_driver = {
+ .driver = {
+ .name = "bd9995x-charger",
+ .of_match_table = bd9995x_of_match,
+ },
+ .probe_new = bd9995x_probe,
+};
+module_i2c_driver(bd9995x_driver);
+
+MODULE_AUTHOR("Laine Markus <markus.laine@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("ROHM BD99954 charger driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/supply/bd99954-charger.h b/drivers/power/supply/bd99954-charger.h
new file mode 100644
index 000000000000..f58897925383
--- /dev/null
+++ b/drivers/power/supply/bd99954-charger.h
@@ -0,0 +1,1075 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2020 ROHM Semiconductors */
+#ifndef BD99954_CHARGER_H
+#define BD99954_CHARGER_H
+
+#include <linux/regmap.h>
+
+#define BD9995X_MANUFACTURER "Rohm Semiconductor"
+#define BD9995X_IRQ_PIN "bd9995x_irq"
+
+#define BD9995X_VSYS_PRECHARGE_OFFSET_MV 200
+
+#define BD99954_ID 0x346
+#define BD99955_ID 0x221
+#define BD99956_ID 0x331
+
+/* Battery Charger Commands */
+#define CHARGING_CURRENT 0x14
+#define CHARGING_VOLTAGE 0x15
+#define PROTECT_SET 0x3E
+#define MAP_SET 0x3F
+
+/* Extended commands */
+#define CHGSTM_STATUS 0x100
+#define VBAT_VSYS_STATUS 0x101
+#define VBUS_VCC_STATUS 0x102
+#define CHGOP_STATUS 0x103
+#define WDT_STATUS 0x104
+#define CUR_ILIM_VAL 0x105
+#define SEL_ILIM_VAL 0x106
+#define IBUS_LIM_SET 0x107
+#define ICC_LIM_SET 0x108
+#define IOTG_LIM_SET 0x109
+#define VIN_CTRL_SET 0x10A
+#define CHGOP_SET1 0x10B
+#define CHGOP_SET2 0x10C
+#define VBUSCLPS_TH_SET 0x10D
+#define VCCCLPS_TH_SET 0x10E
+#define CHGWDT_SET 0x10F
+#define BATTWDT_SET 0x110
+#define VSYSREG_SET 0x111
+#define VSYSVAL_THH_SET 0x112
+#define VSYSVAL_THL_SET 0x113
+#define ITRICH_SET 0x114
+#define IPRECH_SET 0x115
+#define ICHG_SET 0x116
+#define ITERM_SET 0x117
+#define VPRECHG_TH_SET 0x118
+#define VRBOOST_SET 0x119
+#define VFASTCHG_REG_SET1 0x11A
+#define VFASTCHG_REG_SET2 0x11B
+#define VFASTCHG_REG_SET3 0x11C
+#define VRECHG_SET 0x11D
+#define VBATOVP_SET 0x11E
+#define IBATSHORT_SET 0x11F
+#define PROCHOT_CTRL_SET 0x120
+#define PROCHOT_ICRIT_SET 0x121
+#define PROCHOT_INORM_SET 0x122
+#define PROCHOT_IDCHG_SET 0x123
+#define PROCHOT_VSYS_SET 0x124
+#define PMON_IOUT_CTRL_SET 0x125
+#define PMON_DACIN_VAL 0x126
+#define IOUT_DACIN_VAL 0x127
+#define VCC_UCD_SET 0x128
+#define VCC_UCD_STATUS 0x129
+#define VCC_IDD_STATUS 0x12A
+#define VCC_UCD_FCTRL_SET 0x12B
+#define VCC_UCD_FCTRL_EN 0x12C
+#define VBUS_UCD_SET 0x130
+#define VBUS_UCD_STATUS 0x131
+#define VBUS_IDD_STATUS 0x132
+#define VBUS_UCD_FCTRL_SET 0x133
+#define VBUS_UCD_FCTRL_EN 0x134
+#define CHIP_ID 0x138
+#define CHIP_REV 0x139
+#define IC_SET1 0x13A
+#define IC_SET2 0x13B
+#define SYSTEM_STATUS 0x13C
+#define SYSTEM_CTRL_SET 0x13D
+#define VM_CTRL_SET 0x140
+#define THERM_WINDOW_SET1 0x141
+#define THERM_WINDOW_SET2 0x142
+#define THERM_WINDOW_SET3 0x143
+#define THERM_WINDOW_SET4 0x144
+#define THERM_WINDOW_SET5 0x145
+#define IBATP_TH_SET 0x146
+#define IBATM_TH_SET 0x147
+#define VBAT_TH_SET 0x148
+#define THERM_TH_SET 0x149
+#define IACP_TH_SET 0x14A
+#define VACP_TH_SET 0x14B
+#define VBUS_TH_SET 0x14C
+#define VCC_TH_SET 0x14D
+#define VSYS_TH_SET 0x14E
+#define EXTIADP_TH_SET 0x14F
+#define IBATP_VAL 0x150
+#define IBATP_AVE_VAL 0x151
+#define IBATM_VAL 0x152
+#define IBATM_AVE_VAL 0x153
+#define VBAT_VAL 0x154
+#define VBAT_AVE_VAL 0x155
+#define THERM_VAL 0x156
+#define VTH_VAL 0x157
+#define IACP_VAL 0x158
+#define IACP_AVE_VAL 0x159
+#define VACP_VAL 0x15A
+#define VACP_AVE_VAL 0x15B
+#define VBUS_VAL 0x15C
+#define VBUS_AVE_VAL 0x15D
+#define VCC_VAL 0x15E
+#define VCC_AVE_VAL 0x15F
+#define VSYS_VAL 0x160
+#define VSYS_AVE_VAL 0x161
+#define EXTIADP_VAL 0x162
+#define EXTIADP_AVE_VAL 0x163
+#define VACPCLPS_TH_SET 0x164
+#define INT0_SET 0x168
+#define INT1_SET 0x169
+#define INT2_SET 0x16A
+#define INT3_SET 0x16B
+#define INT4_SET 0x16C
+#define INT5_SET 0x16D
+#define INT6_SET 0x16E
+#define INT7_SET 0x16F
+#define INT0_STATUS 0x170
+#define INT1_STATUS 0x171
+#define INT2_STATUS 0x172
+#define INT3_STATUS 0x173
+#define INT4_STATUS 0x174
+#define INT5_STATUS 0x175
+#define INT6_STATUS 0x176
+#define INT7_STATUS 0x177
+#define OTPREG0 0x17A
+#define OTPREG1 0x17B
+#define SMBREG 0x17C
+#define DEBUG_MODE_SET 0x17F
+#define DEBUG0x14 0x214
+#define DEBUG0x1A 0x21A
+
+enum bd9995x_fields {
+ F_PREV_CHGSTM_STATE, F_CHGSTM_STATE,
+ F_VBAT_VSYS_STATUS,
+ F_VBUS_VCC_STATUS,
+ F_BATTEMP, F_VRECHG_DET, F_RBOOST_UV, F_RBOOSTS,
+ F_THERMWDT_VAL, F_CHGWDT_VAL,
+ F_CUR_ILIM_VAL,
+ F_SEL_ILIM_VAL,
+ F_IBUS_LIM_SET,
+ F_ICC_LIM_SET,
+ F_IOTG_LIM_SET,
+ F_OTG_BOTH_EN,
+ F_VRBOOST_TRIG,
+ F_VRBOOST_EN,
+ F_PP_BOTH_THRU,
+ F_VIN_ORD,
+ F_VBUS_EN,
+ F_VCC_EN,
+ F_VSYS_PRIORITY,
+ F_PPC_SUB_CAP,
+ F_PPC_CAP,
+ F_DCP_2500_SEL,
+ F_SDP_500_SEL,
+ F_ILIM_AUTO_DISEN,
+ F_VCC_BC_DISEN,
+ F_VBUS_BC_DISEN,
+ F_SDP_CHG_TRIG_EN,
+ F_SDP_CHG_TRIG,
+ F_AUTO_TOF,
+ F_AUTO_FST,
+ F_AUTO_RECH,
+ F_ILIM_RESET_EN,
+ F_DCDC_1MS_SEL,
+ F_SEL_ILIM_DIV,
+ F_BATT_LEARN,
+ F_CHG_EN,
+ F_USB_SUS,
+ F_CHOP_SS_INIT,
+ F_CHOP_ALL_INIT,
+ F_DCDC_CLK_SEL,
+ F_CHOP_SS,
+ F_CHOP_ALL,
+ F_VBUSCLPS_TH_SET,
+ F_VCCCLPS_TH_SET,
+ F_WDT_FST,
+ F_WDT_PRE,
+ F_WDT_IBAT_SHORT,
+ F_WDT_THERM,
+ F_VSYSREG_SET,
+ F_VSYSVAL_THH_SET,
+ F_VSYSVAL_THL_SET,
+ F_ITRICH_SET,
+ F_IPRECH_SET,
+ F_ICHG_SET,
+ F_ITERM_SET,
+ F_VPRECHG_TH_SET,
+ F_VRBOOST_SET,
+ F_VFASTCHG_REG_SET1,
+ F_VFASTCHG_REG_SET2,
+ F_VFASTCHG_REG_SET3,
+ F_VRECHG_SET,
+ F_VBATOVP_SET,
+ F_IBATM_SHORT_SET,
+ F_PROCHOT_DG_SET,
+ F_PROCHOT_ICRIT_DG_SET,
+ F_PROCHOT_IDCHG_DG_SET,
+ F_PROCHOT_EN,
+ F_PROCHOT_ICRIT_SET,
+ F_PROCHOT_INORM_SET,
+ F_PROCHOT_IDCHG_SET,
+ F_PROCHOT_VSYS_SET,
+ F_IMON_INSEL,
+ F_PMON_INSEL,
+ F_IOUT_OUT_EN,
+ F_IOUT_SOURCE_SEL,
+ F_IOUT_GAIN_SET,
+ F_PMON_OUT_EN,
+ F_PMON_GAIN_SET,
+ F_PMON_DACIN_VAL,
+ F_IOUT_DACIN_VAL,
+ F_VCC_BCSRETRY,
+ F_VCC_ADCRTRY,
+ F_VCC_USBDETEN,
+ F_VCC_IDRDETEN,
+ F_VCC_ENUMRDY,
+ F_VCC_ADCPOLEN,
+ F_VCC_DCDMODE,
+ F_VCC_USB_SW_EN,
+ F_VCC_USB_SW,
+ F_VCC_DCDFAIL,
+ F_VCC_CHGPORT,
+ F_VCC_PUPDET,
+ F_VCC_VBUS_VLD,
+ F_VCC_CHGDET,
+ F_VCC_OTGDET,
+ F_VCC_VBINOP,
+ F_VCC_EXTID,
+ F_VCC_IDRDET,
+ F_VCC_INDO,
+ F_VCC_UCDSWEN,
+ F_VCC_RREF_EN,
+ F_VCC_DPPU_EN,
+ F_VCC_DPREF_EN,
+ F_VCC_DMREF_EN,
+ F_VCC_DPDET_EN,
+ F_VCC_DMDET_EN,
+ F_VCC_DPSINK_EN,
+ F_VCC_DMSINK_EN,
+ F_VCC_DP_BUFF_EN,
+ F_VCC_DM_BUFF_EN,
+ F_VCC_EXTCLKENBL,
+ F_VCC_PLSTESTEN,
+ F_VCC_UCDSWEN_TSTENB,
+ F_VCC_RREF_EN_TSTENB,
+ F_VCC_DPPU_EN_TSTENB,
+ F_VCC_DPREF_EN_TSTENB,
+ F_VCC_DMREF_EN_TSTENB,
+ F_VCC_DPDET_EN_TSTENB,
+ F_VCC_DMDET_EN_TSTENB,
+ F_VCC_DPSINK_EN_TSTENB,
+ F_VCC_DMSINK_EN_TSTENB,
+ F_VCC_DP_BUFF_EN_TSTENB,
+ F_VCC_DM_BUFF_EN_TSTENB,
+ F_VBUS_BCSRETRY,
+ F_VBUS_ADCRTRY,
+ F_VBUS_USBDETEN,
+ F_VBUS_IDRDETEN,
+ F_VBUS_ENUMRDY,
+ F_VBUS_ADCPOLEN,
+ F_VBUS_DCDMODE,
+ F_VBUS_USB_SW_EN,
+ F_VBUS_USB_SW,
+ F_VBUS_DCDFAIL,
+ F_VBUS_CHGPORT,
+ F_VBUS_PUPDET,
+ F_VBUS_VBUS_VLD,
+ F_VBUS_CHGDET,
+ F_VBUS_OTGDET,
+ F_VBUS_VBINOP,
+ F_VBUS_EXTID,
+ F_VBUS_IDRDET,
+ F_VBUS_INDO,
+ F_VBUS_UCDSWEN,
+ F_VBUS_RREF_EN,
+ F_VBUS_DPPU_EN,
+ F_VBUS_DPREF_EN,
+ F_VBUS_DMREF_EN,
+ F_VBUS_DPDET_EN,
+ F_VBUS_DMDET_EN,
+ F_VBUS_DPSINK_EN,
+ F_VBUS_DMSINK_EN,
+ F_VBUS_DP_BUFF_EN,
+ F_VBUS_DM_BUFF_EN,
+ F_VBUS_EXTCLKENBL,
+ F_VBUS_PLSTESTEN,
+ F_VBUS_UCDSWEN_TSTENB,
+ F_VBUS_RREF_EN_TSTENB,
+ F_VBUS_DPPU_EN_TSTENB,
+ F_VBUS_DPREF_EN_TSTENB,
+ F_VBUS_DMREF_EN_TSTENB,
+ F_VBUS_DPDET_EN_TSTENB,
+ F_VBUS_DMDET_EN_TSTENB,
+ F_VBUS_DPSINK_EN_TSTENB,
+ F_VBUS_DMSINK_EN_TSTENB,
+ F_VBUS_DP_BUFF_EN_TSTENB,
+ F_VBUS_DM_BUFF_EN_TSTENB,
+ F_CHIP_ID,
+ F_CHIP_REV,
+ F_ONE_CELL_MODE,
+ F_cell,
+ F_VACP_AUTO_DISCHG,
+ F_VACP_LOAD,
+ F_ACOK_POL,
+ F_ACOK_DISEN,
+ F_DEBUG_SET1,
+ F_DEBUG_SET0,
+ F_MONRST_STATE,
+ F_ALMRST_STATE,
+ F_CHGRST_STATE,
+ F_OTPLD_STATE,
+ F_ALLRST_STATE,
+ F_PROTECT_SET,
+ F_MAP_SET,
+ F_ADCINTERVAL,
+ F_ADCMOD,
+ F_ADCTMOD,
+ F_EXTIADPEN,
+ F_VSYSENB,
+ F_VCCENB,
+ F_VBUSENB,
+ F_VACPENB,
+ F_IACPENB,
+ F_THERMENB,
+ F_VBATENB,
+ F_IBATMENB,
+ F_IBATPENB,
+ F_TMPTHR1B,
+ F_TMPTHR1A,
+ F_TMPTHR2B,
+ F_TMPTHR2A,
+ F_TMPTHR3B,
+ F_TMPTHR3A,
+ F_TMPTHR4B,
+ F_TMPTHR4A,
+ F_TMPTHR5B,
+ F_TMPTHR5A,
+ F_IBATP_TH_SET,
+ F_IBATM_TH_SET,
+ F_VBAT_TH_SET,
+ F_THERM_TH_SET,
+ F_IACP_TH_SET,
+ F_VACP_TH_SET,
+ F_VBUS_TH_SET,
+ F_VCC_TH_SET,
+ F_VSYS_TH_SET,
+ F_EXTIADP_TH_SET,
+ F_IBATP_VAL,
+ F_IBATP_AVE_VAL,
+ F_IBATM_VAL,
+ F_IBATM_AVE_VAL,
+ F_VBAT_VAL,
+ F_VBAT_AVE_VAL,
+ F_THERM_VAL,
+ F_VTH_VAL,
+ F_IACP_VAL,
+ F_IACP_AVE_VAL,
+ F_VACP_VAL,
+ F_VACP_AVE_VAL,
+ F_VBUS_VAL,
+ F_VBUS_AVE_VAL,
+ F_VCC_VAL,
+ F_VCC_AVE_VAL,
+ F_VSYS_VAL,
+ F_VSYS_AVE_VAL,
+ F_EXTIADP_VAL,
+ F_EXTIADP_AVE_VAL,
+ F_VACPCLPS_TH_SET,
+ F_INT7_SET,
+ F_INT6_SET,
+ F_INT5_SET,
+ F_INT4_SET,
+ F_INT3_SET,
+ F_INT2_SET,
+ F_INT1_SET,
+ F_INT0_SET,
+ F_VBUS_RBUV_DET,
+ F_VBUS_RBUV_RES,
+ F_VBUS_TH_DET,
+ F_VBUS_TH_RES,
+ F_VBUS_IIN_MOD,
+ F_VBUS_OV_DET,
+ F_VBUS_OV_RES,
+ F_VBUS_CLPS_DET,
+ F_VBUS_CLPS,
+ F_VBUS_DET,
+ F_VBUS_RES,
+ F_VCC_RBUV_DET,
+ F_VCC_RBUV_RES,
+ F_VCC_TH_DET,
+ F_VCC_TH_RES,
+ F_VCC_IIN_MOD,
+ F_VCC_OVP_DET,
+ F_VCC_OVP_RES,
+ F_VCC_CLPS_DET,
+ F_VCC_CLPS_RES,
+ F_VCC_DET,
+ F_VCC_RES,
+ F_TH_DET,
+ F_TH_RMV,
+ F_TMP_OUT_DET,
+ F_TMP_OUT_RES,
+ F_VBAT_TH_DET,
+ F_VBAT_TH_RES,
+ F_IBAT_SHORT_DET,
+ F_IBAT_SHORT_RES,
+ F_VBAT_OV_DET,
+ F_VBAT_OV_RES,
+ F_BAT_ASSIST_DET,
+ F_BAT_ASSIST_RES,
+ F_VSYS_TH_DET,
+ F_VSYS_TH_RES,
+ F_VSYS_OV_DET,
+ F_VSYS_OV_RES,
+ F_VSYS_SHT_DET,
+ F_VSYS_SHT_RES,
+ F_VSYS_UV_DET,
+ F_VSYS_UV_RES,
+ F_OTP_LOAD_DONE,
+ F_PWR_ON,
+ F_EXTIADP_TRNS,
+ F_EXTIADP_TH_DET,
+ F_EXIADP_TH_RES,
+ F_BAT_MNT_DET,
+ F_BAT_MNT_RES,
+ F_TSD_DET,
+ F_TSD_RES,
+ F_CHGWDT_EXP,
+ F_THERMWDT_EXP,
+ F_TMP_TRNS,
+ F_CHG_TRNS,
+ F_VBUS_UCD_PORT_DET,
+ F_VBUS_UCD_UCHG_DET,
+ F_VBUS_UCD_URID_RMV,
+ F_VBUS_UCD_OTG_DET,
+ F_VBUS_UCD_URID_MOD,
+ F_VCC_UCD_PORT_DET,
+ F_VCC_UCD_UCHG_DET,
+ F_VCC_UCD_URID_RMV,
+ F_VCC_UCD_OTG_DET,
+ F_VCC_UCD_URID_MOD,
+ F_PROCHOT_DET,
+ F_PROCHOT_RES,
+ F_VACP_DET,
+ F_VACP_RES,
+ F_VACP_TH_DET,
+ F_VACP_TH_RES,
+ F_IACP_TH_DET,
+ F_IACP_THE_RES,
+ F_THERM_TH_DET,
+ F_THERM_TH_RES,
+ F_IBATM_TH_DET,
+ F_IBATM_TH_RES,
+ F_IBATP_TH_DET,
+ F_IBATP_TH_RES,
+ F_INT7_STATUS,
+ F_INT6_STATUS,
+ F_INT5_STATUS,
+ F_INT4_STATUS,
+ F_INT3_STATUS,
+ F_INT2_STATUS,
+ F_INT1_STATUS,
+ F_INT0_STATUS,
+ F_ILIM_DECREASE,
+ F_RESERVE_OTPREG1,
+ F_POWER_SAVE_MODE,
+ F_DEBUG_MODE_SET,
+ F_DEBUG0x14,
+ F_DEBUG0x1A,
+ F_MAX_FIELDS
+};
+
+static const struct reg_field bd9995x_reg_fields[] = {
+ [F_PREV_CHGSTM_STATE] = REG_FIELD(CHGSTM_STATUS, 8, 14),
+ [F_CHGSTM_STATE] = REG_FIELD(CHGSTM_STATUS, 0, 6),
+ [F_VBAT_VSYS_STATUS] = REG_FIELD(VBAT_VSYS_STATUS, 0, 15),
+ [F_VBUS_VCC_STATUS] = REG_FIELD(VBUS_VCC_STATUS, 0, 12),
+ [F_BATTEMP] = REG_FIELD(CHGOP_STATUS, 8, 10),
+ [F_VRECHG_DET] = REG_FIELD(CHGOP_STATUS, 6, 6),
+ [F_RBOOST_UV] = REG_FIELD(CHGOP_STATUS, 1, 1),
+ [F_RBOOSTS] = REG_FIELD(CHGOP_STATUS, 0, 0),
+ [F_THERMWDT_VAL] = REG_FIELD(WDT_STATUS, 8, 15),
+ [F_CHGWDT_VAL] = REG_FIELD(WDT_STATUS, 0, 7),
+ [F_CUR_ILIM_VAL] = REG_FIELD(CUR_ILIM_VAL, 0, 13),
+ [F_SEL_ILIM_VAL] = REG_FIELD(SEL_ILIM_VAL, 0, 13),
+ [F_IBUS_LIM_SET] = REG_FIELD(IBUS_LIM_SET, 5, 13),
+ [F_ICC_LIM_SET] = REG_FIELD(ICC_LIM_SET, 5, 13),
+ [F_IOTG_LIM_SET] = REG_FIELD(IOTG_LIM_SET, 5, 13),
+ [F_OTG_BOTH_EN] = REG_FIELD(VIN_CTRL_SET, 15, 15),
+ [F_VRBOOST_TRIG] = REG_FIELD(VIN_CTRL_SET, 14, 14),
+ [F_VRBOOST_EN] = REG_FIELD(VIN_CTRL_SET, 12, 13),
+ [F_PP_BOTH_THRU] = REG_FIELD(VIN_CTRL_SET, 11, 11),
+ [F_VIN_ORD] = REG_FIELD(VIN_CTRL_SET, 7, 7),
+ [F_VBUS_EN] = REG_FIELD(VIN_CTRL_SET, 6, 6),
+ [F_VCC_EN] = REG_FIELD(VIN_CTRL_SET, 5, 5),
+ [F_VSYS_PRIORITY] = REG_FIELD(VIN_CTRL_SET, 4, 4),
+ [F_PPC_SUB_CAP] = REG_FIELD(VIN_CTRL_SET, 2, 3),
+ [F_PPC_CAP] = REG_FIELD(VIN_CTRL_SET, 0, 1),
+ [F_DCP_2500_SEL] = REG_FIELD(CHGOP_SET1, 15, 15),
+ [F_SDP_500_SEL] = REG_FIELD(CHGOP_SET1, 14, 14),
+ [F_ILIM_AUTO_DISEN] = REG_FIELD(CHGOP_SET1, 13, 13),
+ [F_VCC_BC_DISEN] = REG_FIELD(CHGOP_SET1, 11, 11),
+ [F_VBUS_BC_DISEN] = REG_FIELD(CHGOP_SET1, 10, 10),
+ [F_SDP_CHG_TRIG_EN] = REG_FIELD(CHGOP_SET1, 9, 9),
+ [F_SDP_CHG_TRIG] = REG_FIELD(CHGOP_SET1, 8, 8),
+ [F_AUTO_TOF] = REG_FIELD(CHGOP_SET1, 6, 6),
+ [F_AUTO_FST] = REG_FIELD(CHGOP_SET1, 5, 5),
+ [F_AUTO_RECH] = REG_FIELD(CHGOP_SET1, 3, 3),
+ [F_ILIM_RESET_EN] = REG_FIELD(CHGOP_SET2, 14, 14),
+ [F_DCDC_1MS_SEL] = REG_FIELD(CHGOP_SET2, 12, 13),
+ [F_SEL_ILIM_DIV] = REG_FIELD(CHGOP_SET2, 10, 10),
+ [F_BATT_LEARN] = REG_FIELD(CHGOP_SET2, 8, 8),
+ [F_CHG_EN] = REG_FIELD(CHGOP_SET2, 7, 7),
+ [F_USB_SUS] = REG_FIELD(CHGOP_SET2, 6, 6),
+ [F_CHOP_SS_INIT] = REG_FIELD(CHGOP_SET2, 5, 5),
+ [F_CHOP_ALL_INIT] = REG_FIELD(CHGOP_SET2, 4, 4),
+ [F_DCDC_CLK_SEL] = REG_FIELD(CHGOP_SET2, 2, 3),
+ [F_CHOP_SS] = REG_FIELD(CHGOP_SET2, 1, 1),
+ [F_CHOP_ALL] = REG_FIELD(CHGOP_SET2, 0, 0),
+ [F_VBUSCLPS_TH_SET] = REG_FIELD(VBUSCLPS_TH_SET, 7, 14),
+ [F_VCCCLPS_TH_SET] = REG_FIELD(VCCCLPS_TH_SET, 7, 14),
+ [F_WDT_FST] = REG_FIELD(CHGWDT_SET, 8, 15),
+ [F_WDT_PRE] = REG_FIELD(CHGWDT_SET, 0, 7),
+ [F_WDT_IBAT_SHORT] = REG_FIELD(BATTWDT_SET, 8, 15),
+ [F_WDT_THERM] = REG_FIELD(BATTWDT_SET, 0, 7),
+ [F_VSYSREG_SET] = REG_FIELD(VSYSREG_SET, 6, 14),
+ [F_VSYSVAL_THH_SET] = REG_FIELD(VSYSVAL_THH_SET, 6, 14),
+ [F_VSYSVAL_THL_SET] = REG_FIELD(VSYSVAL_THL_SET, 6, 14),
+ [F_ITRICH_SET] = REG_FIELD(ITRICH_SET, 6, 10),
+ [F_IPRECH_SET] = REG_FIELD(IPRECH_SET, 6, 10),
+ [F_ICHG_SET] = REG_FIELD(ICHG_SET, 6, 13),
+ [F_ITERM_SET] = REG_FIELD(ITERM_SET, 6, 10),
+ [F_VPRECHG_TH_SET] = REG_FIELD(VPRECHG_TH_SET, 6, 14),
+ [F_VRBOOST_SET] = REG_FIELD(VRBOOST_SET, 6, 14),
+ [F_VFASTCHG_REG_SET1] = REG_FIELD(VFASTCHG_REG_SET1, 4, 14),
+ [F_VFASTCHG_REG_SET2] = REG_FIELD(VFASTCHG_REG_SET2, 4, 14),
+ [F_VFASTCHG_REG_SET3] = REG_FIELD(VFASTCHG_REG_SET3, 4, 14),
+ [F_VRECHG_SET] = REG_FIELD(VRECHG_SET, 4, 14),
+ [F_VBATOVP_SET] = REG_FIELD(VBATOVP_SET, 4, 14),
+ [F_IBATM_SHORT_SET] = REG_FIELD(IBATSHORT_SET, 0, 14),
+ [F_PROCHOT_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 14, 15),
+ [F_PROCHOT_ICRIT_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 10, 11),
+ [F_PROCHOT_IDCHG_DG_SET] = REG_FIELD(PROCHOT_CTRL_SET, 8, 9),
+ [F_PROCHOT_EN] = REG_FIELD(PROCHOT_CTRL_SET, 0, 4),
+ [F_PROCHOT_ICRIT_SET] = REG_FIELD(PROCHOT_ICRIT_SET, 0, 14),
+ [F_PROCHOT_INORM_SET] = REG_FIELD(PROCHOT_INORM_SET, 0, 14),
+ [F_PROCHOT_IDCHG_SET] = REG_FIELD(PROCHOT_IDCHG_SET, 0, 14),
+ [F_PROCHOT_VSYS_SET] = REG_FIELD(PROCHOT_VSYS_SET, 0, 14),
+ [F_IMON_INSEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 9, 9),
+ [F_PMON_INSEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 8, 8),
+ [F_IOUT_OUT_EN] = REG_FIELD(PMON_IOUT_CTRL_SET, 7, 7),
+ [F_IOUT_SOURCE_SEL] = REG_FIELD(PMON_IOUT_CTRL_SET, 6, 6),
+ [F_IOUT_GAIN_SET] = REG_FIELD(PMON_IOUT_CTRL_SET, 4, 5),
+ [F_PMON_OUT_EN] = REG_FIELD(PMON_IOUT_CTRL_SET, 3, 3),
+ [F_PMON_GAIN_SET] = REG_FIELD(PMON_IOUT_CTRL_SET, 0, 2),
+ [F_PMON_DACIN_VAL] = REG_FIELD(PMON_DACIN_VAL, 0, 9),
+ [F_IOUT_DACIN_VAL] = REG_FIELD(IOUT_DACIN_VAL, 0, 11),
+ [F_VCC_BCSRETRY] = REG_FIELD(VCC_UCD_SET, 12, 12),
+ [F_VCC_ADCRTRY] = REG_FIELD(VCC_UCD_SET, 8, 8),
+ [F_VCC_USBDETEN] = REG_FIELD(VCC_UCD_SET, 7, 7),
+ [F_VCC_IDRDETEN] = REG_FIELD(VCC_UCD_SET, 6, 6),
+ [F_VCC_ENUMRDY] = REG_FIELD(VCC_UCD_SET, 5, 5),
+ [F_VCC_ADCPOLEN] = REG_FIELD(VCC_UCD_SET, 4, 4),
+ [F_VCC_DCDMODE] = REG_FIELD(VCC_UCD_SET, 3, 3),
+ [F_VCC_USB_SW_EN] = REG_FIELD(VCC_UCD_SET, 1, 1),
+ [F_VCC_USB_SW] = REG_FIELD(VCC_UCD_SET, 0, 0),
+ [F_VCC_DCDFAIL] = REG_FIELD(VCC_UCD_STATUS, 15, 15),
+ [F_VCC_CHGPORT] = REG_FIELD(VCC_UCD_STATUS, 12, 13),
+ [F_VCC_PUPDET] = REG_FIELD(VCC_UCD_STATUS, 11, 11),
+ [F_VCC_VBUS_VLD] = REG_FIELD(VCC_UCD_STATUS, 7, 7),
+ [F_VCC_CHGDET] = REG_FIELD(VCC_UCD_STATUS, 6, 6),
+ [F_VCC_OTGDET] = REG_FIELD(VCC_UCD_STATUS, 3, 3),
+ [F_VCC_VBINOP] = REG_FIELD(VCC_IDD_STATUS, 6, 6),
+ [F_VCC_EXTID] = REG_FIELD(VCC_IDD_STATUS, 5, 5),
+ [F_VCC_IDRDET] = REG_FIELD(VCC_IDD_STATUS, 4, 4),
+ [F_VCC_INDO] = REG_FIELD(VCC_IDD_STATUS, 0, 3),
+ [F_VCC_UCDSWEN] = REG_FIELD(VCC_UCD_FCTRL_SET, 10, 10),
+ [F_VCC_RREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 9, 9),
+ [F_VCC_DPPU_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 8, 8),
+ [F_VCC_DPREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 7, 7),
+ [F_VCC_DMREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 6, 6),
+ [F_VCC_DPDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 5, 5),
+ [F_VCC_DMDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 4, 4),
+ [F_VCC_DPSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 3, 3),
+ [F_VCC_DMSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 2, 2),
+ [F_VCC_DP_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 1, 1),
+ [F_VCC_DM_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 0, 0),
+ [F_VCC_EXTCLKENBL] = REG_FIELD(VCC_UCD_FCTRL_EN, 15, 15),
+ [F_VCC_PLSTESTEN] = REG_FIELD(VCC_UCD_FCTRL_EN, 14, 14),
+ [F_VCC_UCDSWEN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 10, 10),
+ [F_VCC_RREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 9, 9),
+ [F_VCC_DPPU_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 8, 8),
+ [F_VCC_DPREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 7, 7),
+ [F_VCC_DMREF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 6, 6),
+ [F_VCC_DPDET_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 5, 5),
+ [F_VCC_DMDET_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 4, 4),
+ [F_VCC_DPSINK_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 3, 3),
+ [F_VCC_DMSINK_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 2, 2),
+ [F_VCC_DP_BUFF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 1, 1),
+ [F_VCC_DM_BUFF_EN_TSTENB] = REG_FIELD(VCC_UCD_FCTRL_EN, 0, 0),
+
+ [F_VBUS_BCSRETRY] = REG_FIELD(VBUS_UCD_SET, 12, 12),
+ [F_VBUS_ADCRTRY] = REG_FIELD(VBUS_UCD_SET, 8, 8),
+ [F_VBUS_USBDETEN] = REG_FIELD(VBUS_UCD_SET, 7, 7),
+ [F_VBUS_IDRDETEN] = REG_FIELD(VBUS_UCD_SET, 6, 6),
+ [F_VBUS_ENUMRDY] = REG_FIELD(VBUS_UCD_SET, 5, 5),
+ [F_VBUS_ADCPOLEN] = REG_FIELD(VBUS_UCD_SET, 4, 4),
+ [F_VBUS_DCDMODE] = REG_FIELD(VBUS_UCD_SET, 3, 3),
+ [F_VBUS_USB_SW_EN] = REG_FIELD(VBUS_UCD_SET, 1, 1),
+ [F_VBUS_USB_SW] = REG_FIELD(VBUS_UCD_SET, 0, 0),
+ [F_VBUS_DCDFAIL] = REG_FIELD(VBUS_UCD_STATUS, 15, 15),
+ [F_VBUS_CHGPORT] = REG_FIELD(VBUS_UCD_STATUS, 12, 13),
+ [F_VBUS_PUPDET] = REG_FIELD(VBUS_UCD_STATUS, 11, 11),
+ [F_VBUS_VBUS_VLD] = REG_FIELD(VBUS_UCD_STATUS, 7, 7),
+ [F_VBUS_CHGDET] = REG_FIELD(VBUS_UCD_STATUS, 6, 6),
+ [F_VBUS_OTGDET] = REG_FIELD(VBUS_UCD_STATUS, 3, 3),
+ [F_VBUS_VBINOP] = REG_FIELD(VBUS_IDD_STATUS, 6, 6),
+ [F_VBUS_EXTID] = REG_FIELD(VBUS_IDD_STATUS, 5, 5),
+ [F_VBUS_IDRDET] = REG_FIELD(VBUS_IDD_STATUS, 4, 4),
+ [F_VBUS_INDO] = REG_FIELD(VBUS_IDD_STATUS, 0, 3),
+ [F_VBUS_UCDSWEN] = REG_FIELD(VCC_UCD_FCTRL_SET, 10, 10),
+ [F_VBUS_RREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 9, 9),
+ [F_VBUS_DPPU_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 8, 8),
+ [F_VBUS_DPREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 7, 7),
+ [F_VBUS_DMREF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 6, 6),
+ [F_VBUS_DPDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 5, 5),
+ [F_VBUS_DMDET_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 4, 4),
+ [F_VBUS_DPSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 3, 3),
+ [F_VBUS_DMSINK_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 2, 2),
+ [F_VBUS_DP_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 1, 1),
+ [F_VBUS_DM_BUFF_EN] = REG_FIELD(VCC_UCD_FCTRL_SET, 0, 0),
+
+ [F_VBUS_EXTCLKENBL] = REG_FIELD(VBUS_UCD_FCTRL_EN, 15, 15),
+ [F_VBUS_PLSTESTEN] = REG_FIELD(VBUS_UCD_FCTRL_EN, 14, 14),
+ [F_VBUS_UCDSWEN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 10, 10),
+ [F_VBUS_RREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 9, 9),
+ [F_VBUS_DPPU_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 8, 8),
+ [F_VBUS_DPREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 7, 7),
+ [F_VBUS_DMREF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 6, 6),
+ [F_VBUS_DPDET_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 5, 5),
+ [F_VBUS_DMDET_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 4, 4),
+ [F_VBUS_DPSINK_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 3, 3),
+ [F_VBUS_DMSINK_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 2, 2),
+ [F_VBUS_DP_BUFF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 1, 1),
+ [F_VBUS_DM_BUFF_EN_TSTENB] = REG_FIELD(VBUS_UCD_FCTRL_EN, 0, 0),
+
+ [F_CHIP_ID] = REG_FIELD(CHIP_ID, 0, 15),
+ [F_CHIP_REV] = REG_FIELD(CHIP_REV, 0, 15),
+ [F_ONE_CELL_MODE] = REG_FIELD(IC_SET1, 11, 11),
+ [F_cell] = REG_FIELD(IC_SET1, 1, 1),
+ [F_VACP_AUTO_DISCHG] = REG_FIELD(IC_SET1, 9, 9),
+ [F_VACP_LOAD] = REG_FIELD(IC_SET1, 8, 8),
+ [F_ACOK_POL] = REG_FIELD(IC_SET1, 1, 1),
+ [F_ACOK_DISEN] = REG_FIELD(IC_SET1, 0, 0),
+ [F_DEBUG_SET1] = REG_FIELD(IC_SET2, 4, 8),
+ [F_DEBUG_SET0] = REG_FIELD(IC_SET2, 0, 0),
+ [F_MONRST_STATE] = REG_FIELD(SYSTEM_STATUS, 6, 6),
+ [F_ALMRST_STATE] = REG_FIELD(SYSTEM_STATUS, 5, 5),
+ [F_CHGRST_STATE] = REG_FIELD(SYSTEM_STATUS, 4, 4),
+ [F_OTPLD_STATE] = REG_FIELD(SYSTEM_STATUS, 1, 1),
+ [F_ALLRST_STATE] = REG_FIELD(SYSTEM_STATUS, 0, 0),
+ [F_PROTECT_SET] = REG_FIELD(PROTECT_SET, 0, 15),
+ [F_MAP_SET] = REG_FIELD(MAP_SET, 0, 15),
+ [F_ADCINTERVAL] = REG_FIELD(VM_CTRL_SET, 14, 15),
+ [F_ADCMOD] = REG_FIELD(VM_CTRL_SET, 12, 13),
+ [F_ADCTMOD] = REG_FIELD(VM_CTRL_SET, 10, 11),
+ [F_EXTIADPEN] = REG_FIELD(VM_CTRL_SET, 9, 9),
+ [F_VSYSENB] = REG_FIELD(VM_CTRL_SET, 8, 8),
+ [F_VCCENB] = REG_FIELD(VM_CTRL_SET, 7, 7),
+ [F_VBUSENB] = REG_FIELD(VM_CTRL_SET, 6, 6),
+ [F_VACPENB] = REG_FIELD(VM_CTRL_SET, 5, 5),
+ [F_IACPENB] = REG_FIELD(VM_CTRL_SET, 4, 4),
+ [F_THERMENB] = REG_FIELD(VM_CTRL_SET, 3, 3),
+ [F_VBATENB] = REG_FIELD(VM_CTRL_SET, 2, 2),
+ [F_IBATMENB] = REG_FIELD(VM_CTRL_SET, 1, 1),
+ [F_IBATPENB] = REG_FIELD(VM_CTRL_SET, 0, 0),
+ [F_TMPTHR1B] = REG_FIELD(THERM_WINDOW_SET1, 8, 15),
+ [F_TMPTHR1A] = REG_FIELD(THERM_WINDOW_SET1, 0, 7),
+ [F_TMPTHR2B] = REG_FIELD(THERM_WINDOW_SET2, 8, 15),
+ [F_TMPTHR2A] = REG_FIELD(THERM_WINDOW_SET2, 0, 7),
+ [F_TMPTHR3B] = REG_FIELD(THERM_WINDOW_SET3, 8, 15),
+ [F_TMPTHR3A] = REG_FIELD(THERM_WINDOW_SET3, 0, 7),
+ [F_TMPTHR4B] = REG_FIELD(THERM_WINDOW_SET4, 8, 15),
+ [F_TMPTHR4A] = REG_FIELD(THERM_WINDOW_SET4, 0, 7),
+ [F_TMPTHR5B] = REG_FIELD(THERM_WINDOW_SET5, 8, 15),
+ [F_TMPTHR5A] = REG_FIELD(THERM_WINDOW_SET5, 0, 7),
+ [F_IBATP_TH_SET] = REG_FIELD(IBATP_TH_SET, 0, 14),
+ [F_IBATM_TH_SET] = REG_FIELD(IBATM_TH_SET, 0, 14),
+ [F_VBAT_TH_SET] = REG_FIELD(VBAT_TH_SET, 0, 14),
+ [F_THERM_TH_SET] = REG_FIELD(THERM_TH_SET, 0, 7),
+ [F_IACP_TH_SET] = REG_FIELD(IACP_TH_SET, 0, 14),
+ [F_VACP_TH_SET] = REG_FIELD(VACP_TH_SET, 0, 14),
+ [F_VBUS_TH_SET] = REG_FIELD(VBUS_TH_SET, 0, 14),
+ [F_VCC_TH_SET] = REG_FIELD(VCC_TH_SET, 0, 14),
+ [F_VSYS_TH_SET] = REG_FIELD(VSYS_TH_SET, 0, 14),
+ [F_EXTIADP_TH_SET] = REG_FIELD(EXTIADP_TH_SET, 0, 11),
+ [F_IBATP_VAL] = REG_FIELD(IBATP_VAL, 0, 14),
+ [F_IBATP_AVE_VAL] = REG_FIELD(IBATP_AVE_VAL, 0, 14),
+ [F_IBATM_VAL] = REG_FIELD(IBATM_VAL, 0, 14),
+ [F_IBATM_AVE_VAL] = REG_FIELD(IBATM_AVE_VAL, 0, 14),
+ [F_VBAT_VAL] = REG_FIELD(VBAT_VAL, 0, 14),
+ [F_VBAT_AVE_VAL] = REG_FIELD(VBAT_AVE_VAL, 0, 14),
+ [F_THERM_VAL] = REG_FIELD(THERM_VAL, 0, 7),
+ [F_VTH_VAL] = REG_FIELD(VTH_VAL, 0, 11),
+ [F_IACP_VAL] = REG_FIELD(IACP_VAL, 0, 14),
+ [F_IACP_AVE_VAL] = REG_FIELD(IACP_AVE_VAL, 0, 14),
+ [F_VACP_VAL] = REG_FIELD(VACP_VAL, 0, 14),
+ [F_VACP_AVE_VAL] = REG_FIELD(VACP_AVE_VAL, 0, 14),
+ [F_VBUS_VAL] = REG_FIELD(VBUS_VAL, 0, 14),
+ [F_VBUS_AVE_VAL] = REG_FIELD(VBUS_AVE_VAL, 0, 14),
+ [F_VCC_VAL] = REG_FIELD(VCC_VAL, 0, 14),
+ [F_VCC_AVE_VAL] = REG_FIELD(VCC_AVE_VAL, 0, 14),
+ [F_VSYS_VAL] = REG_FIELD(VSYS_VAL, 0, 14),
+ [F_VSYS_AVE_VAL] = REG_FIELD(VSYS_AVE_VAL, 0, 14),
+ [F_EXTIADP_VAL] = REG_FIELD(EXTIADP_VAL, 0, 11),
+ [F_EXTIADP_AVE_VAL] = REG_FIELD(EXTIADP_AVE_VAL, 0, 11),
+ [F_VACPCLPS_TH_SET] = REG_FIELD(VACPCLPS_TH_SET, 7, 14),
+ [F_INT7_SET] = REG_FIELD(INT7_SET, 0, 15),
+ [F_INT6_SET] = REG_FIELD(INT6_SET, 0, 13),
+ [F_INT5_SET] = REG_FIELD(INT5_SET, 0, 13),
+ [F_INT4_SET] = REG_FIELD(INT4_SET, 0, 9),
+ [F_INT3_SET] = REG_FIELD(INT3_SET, 0, 15),
+ [F_INT2_SET] = REG_FIELD(INT2_SET, 0, 15),
+ [F_INT1_SET] = REG_FIELD(INT1_SET, 0, 15),
+ [F_INT0_SET] = REG_FIELD(INT0_SET, 0, 7),
+ [F_VBUS_RBUV_DET] = REG_FIELD(INT1_SET, 15, 15),
+ [F_VBUS_RBUV_RES] = REG_FIELD(INT1_SET, 14, 14),
+ [F_VBUS_TH_DET] = REG_FIELD(INT1_SET, 9, 9),
+ [F_VBUS_TH_RES] = REG_FIELD(INT1_SET, 8, 8),
+ [F_VBUS_IIN_MOD] = REG_FIELD(INT1_SET, 6, 6),
+ [F_VBUS_OV_DET] = REG_FIELD(INT1_SET, 5, 5),
+ [F_VBUS_OV_RES] = REG_FIELD(INT1_SET, 4, 4),
+ [F_VBUS_CLPS_DET] = REG_FIELD(INT1_SET, 3, 3),
+ [F_VBUS_CLPS] = REG_FIELD(INT1_SET, 2, 2),
+ [F_VBUS_DET] = REG_FIELD(INT1_SET, 1, 1),
+ [F_VBUS_RES] = REG_FIELD(INT1_SET, 0, 0),
+ [F_VCC_RBUV_DET] = REG_FIELD(INT2_SET, 15, 15),
+ [F_VCC_RBUV_RES] = REG_FIELD(INT2_SET, 14, 14),
+ [F_VCC_TH_DET] = REG_FIELD(INT2_SET, 9, 9),
+ [F_VCC_TH_RES] = REG_FIELD(INT2_SET, 8, 8),
+ [F_VCC_IIN_MOD] = REG_FIELD(INT2_SET, 6, 6),
+ [F_VCC_OVP_DET] = REG_FIELD(INT2_SET, 5, 5),
+ [F_VCC_OVP_RES] = REG_FIELD(INT2_SET, 4, 4),
+ [F_VCC_CLPS_DET] = REG_FIELD(INT2_SET, 3, 3),
+ [F_VCC_CLPS_RES] = REG_FIELD(INT2_SET, 2, 2),
+ [F_VCC_DET] = REG_FIELD(INT2_SET, 1, 1),
+ [F_VCC_RES] = REG_FIELD(INT2_SET, 0, 0),
+ [F_TH_DET] = REG_FIELD(INT3_SET, 15, 15),
+ [F_TH_RMV] = REG_FIELD(INT3_SET, 14, 14),
+ [F_TMP_OUT_DET] = REG_FIELD(INT3_SET, 11, 11),
+ [F_TMP_OUT_RES] = REG_FIELD(INT3_SET, 10, 10),
+ [F_VBAT_TH_DET] = REG_FIELD(INT3_SET, 9, 9),
+ [F_VBAT_TH_RES] = REG_FIELD(INT3_SET, 8, 8),
+ [F_IBAT_SHORT_DET] = REG_FIELD(INT3_SET, 7, 7),
+ [F_IBAT_SHORT_RES] = REG_FIELD(INT3_SET, 6, 6),
+ [F_VBAT_OV_DET] = REG_FIELD(INT3_SET, 5, 5),
+ [F_VBAT_OV_RES] = REG_FIELD(INT3_SET, 4, 4),
+ [F_BAT_ASSIST_DET] = REG_FIELD(INT3_SET, 3, 3),
+ [F_BAT_ASSIST_RES] = REG_FIELD(INT3_SET, 2, 2),
+ [F_VSYS_TH_DET] = REG_FIELD(INT4_SET, 9, 9),
+ [F_VSYS_TH_RES] = REG_FIELD(INT4_SET, 8, 8),
+ [F_VSYS_OV_DET] = REG_FIELD(INT4_SET, 5, 5),
+ [F_VSYS_OV_RES] = REG_FIELD(INT4_SET, 4, 4),
+ [F_VSYS_SHT_DET] = REG_FIELD(INT4_SET, 3, 3),
+ [F_VSYS_SHT_RES] = REG_FIELD(INT4_SET, 2, 2),
+ [F_VSYS_UV_DET] = REG_FIELD(INT4_SET, 1, 1),
+ [F_VSYS_UV_RES] = REG_FIELD(INT4_SET, 0, 0),
+ [F_OTP_LOAD_DONE] = REG_FIELD(INT5_SET, 13, 13),
+ [F_PWR_ON] = REG_FIELD(INT5_SET, 12, 12),
+ [F_EXTIADP_TRNS] = REG_FIELD(INT5_SET, 11, 11),
+ [F_EXTIADP_TH_DET] = REG_FIELD(INT5_SET, 9, 9),
+ [F_EXIADP_TH_RES] = REG_FIELD(INT5_SET, 8, 8),
+ [F_BAT_MNT_DET] = REG_FIELD(INT5_SET, 7, 7),
+ [F_BAT_MNT_RES] = REG_FIELD(INT5_SET, 6, 6),
+ [F_TSD_DET] = REG_FIELD(INT5_SET, 5, 5),
+ [F_TSD_RES] = REG_FIELD(INT5_SET, 4, 4),
+ [F_CHGWDT_EXP] = REG_FIELD(INT5_SET, 3, 3),
+ [F_THERMWDT_EXP] = REG_FIELD(INT5_SET, 2, 2),
+ [F_TMP_TRNS] = REG_FIELD(INT5_SET, 1, 1),
+ [F_CHG_TRNS] = REG_FIELD(INT5_SET, 0, 0),
+ [F_VBUS_UCD_PORT_DET] = REG_FIELD(INT6_SET, 13, 13),
+ [F_VBUS_UCD_UCHG_DET] = REG_FIELD(INT6_SET, 12, 12),
+ [F_VBUS_UCD_URID_RMV] = REG_FIELD(INT6_SET, 11, 11),
+ [F_VBUS_UCD_OTG_DET] = REG_FIELD(INT6_SET, 10, 10),
+ [F_VBUS_UCD_URID_MOD] = REG_FIELD(INT6_SET, 8, 8),
+ [F_VCC_UCD_PORT_DET] = REG_FIELD(INT6_SET, 5, 5),
+ [F_VCC_UCD_UCHG_DET] = REG_FIELD(INT6_SET, 4, 4),
+ [F_VCC_UCD_URID_RMV] = REG_FIELD(INT6_SET, 3, 3),
+ [F_VCC_UCD_OTG_DET] = REG_FIELD(INT6_SET, 2, 2),
+ [F_VCC_UCD_URID_MOD] = REG_FIELD(INT6_SET, 0, 0),
+ [F_PROCHOT_DET] = REG_FIELD(INT7_SET, 15, 15),
+ [F_PROCHOT_RES] = REG_FIELD(INT7_SET, 14, 14),
+ [F_VACP_DET] = REG_FIELD(INT7_SET, 11, 11),
+ [F_VACP_RES] = REG_FIELD(INT7_SET, 10, 10),
+ [F_VACP_TH_DET] = REG_FIELD(INT7_SET, 9, 9),
+ [F_VACP_TH_RES] = REG_FIELD(INT7_SET, 8, 8),
+ [F_IACP_TH_DET] = REG_FIELD(INT7_SET, 7, 7),
+ [F_IACP_THE_RES] = REG_FIELD(INT7_SET, 6, 6),
+ [F_THERM_TH_DET] = REG_FIELD(INT7_SET, 5, 5),
+ [F_THERM_TH_RES] = REG_FIELD(INT7_SET, 4, 4),
+ [F_IBATM_TH_DET] = REG_FIELD(INT7_SET, 3, 3),
+ [F_IBATM_TH_RES] = REG_FIELD(INT7_SET, 2, 2),
+ [F_IBATP_TH_DET] = REG_FIELD(INT7_SET, 1, 1),
+ [F_IBATP_TH_RES] = REG_FIELD(INT7_SET, 0, 0),
+ [F_INT7_STATUS] = REG_FIELD(INT7_STATUS, 0, 15),
+ [F_INT6_STATUS] = REG_FIELD(INT6_STATUS, 0, 13),
+ [F_INT5_STATUS] = REG_FIELD(INT5_STATUS, 0, 13),
+ [F_INT4_STATUS] = REG_FIELD(INT4_STATUS, 0, 9),
+ [F_INT3_STATUS] = REG_FIELD(INT3_STATUS, 0, 15),
+ [F_INT2_STATUS] = REG_FIELD(INT2_STATUS, 0, 15),
+ [F_INT1_STATUS] = REG_FIELD(INT1_STATUS, 0, 15),
+ [F_INT0_STATUS] = REG_FIELD(INT0_STATUS, 0, 7),
+ [F_ILIM_DECREASE] = REG_FIELD(OTPREG0, 0, 15),
+ [F_RESERVE_OTPREG1] = REG_FIELD(OTPREG1, 0, 15),
+ [F_POWER_SAVE_MODE] = REG_FIELD(SMBREG, 0, 15),
+ [F_DEBUG_MODE_SET] = REG_FIELD(DEBUG_MODE_SET, 0, 15),
+ [F_DEBUG0x14] = REG_FIELD(DEBUG0x14, 0, 15),
+ [F_DEBUG0x1A] = REG_FIELD(DEBUG0x1A, 0, 15),
+};
+
+/* CHGSTM_STATEs */
+#define CHGSTM_SUSPEND 0x00
+#define CHGSTM_TRICKLE_CHARGE 0x01
+#define CHGSTM_PRE_CHARGE 0x02
+#define CHGSTM_FAST_CHARGE 0x03
+#define CHGSTM_TOP_OFF 0x04
+#define CHGSTM_DONE 0x05
+#define CHGSTM_OTG 0x08
+#define CHGSTM_OTG_DONE 0x09
+#define CHGSTM_TEMPERATURE_ERROR_1 0x10
+#define CHGSTM_TEMPERATURE_ERROR_2 0x11
+#define CHGSTM_TEMPERATURE_ERROR_3 0x12
+#define CHGSTM_TEMPERATURE_ERROR_4 0x13
+#define CHGSTM_TEMPERATURE_ERROR_5 0x14
+#define CHGSTM_TEMPERATURE_ERROR_6 0x15
+#define CHGSTM_TEMPERATURE_ERROR_7 0x18
+#define CHGSTM_THERMAL_SHUT_DOWN_1 0x20
+#define CHGSTM_THERMAL_SHUT_DOWN_2 0x21
+#define CHGSTM_THERMAL_SHUT_DOWN_3 0x22
+#define CHGSTM_THERMAL_SHUT_DOWN_4 0x23
+#define CHGSTM_THERMAL_SHUT_DOWN_5 0x24
+#define CHGSTM_THERMAL_SHUT_DOWN_6 0x25
+#define CHGSTM_THERMAL_SHUT_DOWN_7 0x28
+#define CHGSTM_BATTERY_ERROR 0x40
+
+/* VBAT_VSYS_STATUS */
+#define STATUS_VSYS_OV BIT(15)
+#define STATUS_VSYS_SSD BIT(14)
+#define STATUS_VSYS_SCP BIT(13)
+#define STATUS_VSYS_UVN BIT(12)
+#define STATUS_IBAT_SHORT BIT(6)
+#define STATUS_VBAT_OV BIT(3)
+#define STATUS_DEAD_BAT BIT(0)
+
+/* VBUS_VCC_STATUS */
+#define STATUS_VACP_DET BIT(12)
+#define STATUS_VCC_OVP BIT(11)
+#define STATUS_ILIM_VCC_MOD BIT(10)
+#define STATUS_VCC_CLPS BIT(9)
+#define STATUS_VCC_DET BIT(8)
+#define STATUS_VBUS_OVP BIT(3)
+#define STATUS_ILIM_VBUS_MOD BIT(2)
+#define STATUS_VBUS_CLPS BIT(1)
+#define STATUS_VBUS_DET BIT(0)
+
+/* Interrupt set/status definitions */
+
+/* INT 0 */
+#define INT0_INT7_STATUS BIT(7)
+#define INT0_INT6_STATUS BIT(6)
+#define INT0_INT5_STATUS BIT(5)
+#define INT0_INT4_STATUS BIT(4)
+#define INT0_INT3_STATUS BIT(3)
+#define INT0_INT2_STATUS BIT(2)
+#define INT0_INT1_STATUS BIT(1)
+#define INT0_INT0_STATUS BIT(0)
+#define INT0_ALL 0xff
+
+/* INT 1 */
+#define VBUS_RBUV_DET BIT(15)
+#define VBUS_RBUV_RES BIT(14)
+#define VBUS_TH_DET BIT(9)
+#define VBUS_TH_RES BIT(8)
+#define VBUS_IIN_MOD BIT(6)
+#define VBUS_OV_DET BIT(5)
+#define VBUS_OV_RES BIT(4)
+#define VBUS_CLPS_DET BIT(3)
+#define VBUS_CLPS BIT(2)
+#define VBUS_DET BIT(1)
+#define VBUS_RES BIT(0)
+#define INT1_ALL (VBUS_RBUV_DET|\
+ VBUS_RBUV_RES|\
+ VBUS_TH_DET |\
+ VBUS_TH_RES |\
+ VBUS_IIN_MOD|\
+ VBUS_OV_DET |\
+ VBUS_OV_RES |\
+ VBUS_CLPS_DET |\
+ VBUS_CLPS |\
+ VBUS_DET |\
+ VBUS_RES)
+
+/* INT 2 */
+#define VCC_RBUV_DET BIT(15)
+#define VCC_RBUV_RES BIT(14)
+#define VCC_TH_DET BIT(9)
+#define VCC_TH_RES BIT(8)
+#define VCC_IIN_MOD BIT(6)
+#define VCC_OVP_DET BIT(5)
+#define VCC_OVP_RES BIT(4)
+#define VCC_CLPS_DET BIT(3)
+#define VCC_CLPS_RES BIT(2)
+#define VCC_DET BIT(1)
+#define VCC_RES BIT(0)
+#define INT2_ALL (VCC_RBUV_DET |\
+ VCC_RBUV_RES |\
+ VCC_TH_DET |\
+ VCC_TH_RES |\
+ VCC_IIN_MOD |\
+ VCC_OVP_DET |\
+ VCC_OVP_RES |\
+ VCC_CLPS_DET |\
+ VCC_CLPS_RES |\
+ VCC_DET |\
+ VCC_RES)
+/* INT 3 */
+#define TH_DET BIT(15)
+#define TH_RMV BIT(14)
+#define TMP_OUT_DET BIT(11)
+#define TMP_OUT_RES BIT(10)
+#define VBAT_TH_DET BIT(9)
+#define VBAT_TH_RES BIT(8)
+#define IBAT_SHORT_DET BIT(7)
+#define IBAT_SHORT_RES BIT(6)
+#define VBAT_OV_DET BIT(5)
+#define VBAT_OV_RES BIT(4)
+#define BAT_ASSIST_DET BIT(3)
+#define BAT_ASSIST_RES BIT(2)
+#define INT3_ALL (TH_DET |\
+ TH_RMV |\
+ TMP_OUT_DET |\
+ TMP_OUT_RES |\
+ VBAT_TH_DET |\
+ VBAT_TH_RES |\
+ IBAT_SHORT_DET |\
+ IBAT_SHORT_RES |\
+ VBAT_OV_DET |\
+ VBAT_OV_RES |\
+ BAT_ASSIST_DET |\
+ BAT_ASSIST_RES)
+
+/* INT 4 */
+#define VSYS_TH_DET BIT(9)
+#define VSYS_TH_RES BIT(8)
+#define VSYS_OV_DET BIT(5)
+#define VSYS_OV_RES BIT(4)
+#define VSYS_SHT_DET BIT(3)
+#define VSYS_SHT_RES BIT(2)
+#define VSYS_UV_DET BIT(1)
+#define VSYS_UV_RES BIT(0)
+#define INT4_ALL (VSYS_TH_DET |\
+ VSYS_TH_RES |\
+ VSYS_OV_DET |\
+ VSYS_OV_RES |\
+ VSYS_SHT_DET |\
+ VSYS_SHT_RES |\
+ VSYS_UV_DET |\
+ VSYS_UV_RES)
+
+/* INT 5*/
+#define OTP_LOAD_DONE BIT(13)
+#define PWR_ON BIT(12)
+#define EXTIADP_TRNS BIT(11)
+#define EXTIADP_TH_DET BIT(9)
+#define EXIADP_TH_RES BIT(8)
+#define BAT_MNT_DET BIT(7)
+#define BAT_MNT_RES BIT(6)
+#define TSD_DET BIT(5)
+#define TSD_RES BIT(4)
+#define CHGWDT_EXP BIT(3)
+#define THERMWDT_EXP BIT(2)
+#define TMP_TRNS BIT(1)
+#define CHG_TRNS BIT(0)
+#define INT5_ALL (OTP_LOAD_DONE |\
+ PWR_ON |\
+ EXTIADP_TRNS |\
+ EXTIADP_TH_DET |\
+ EXIADP_TH_RES |\
+ BAT_MNT_DET |\
+ BAT_MNT_RES |\
+ TSD_DET |\
+ TSD_RES |\
+ CHGWDT_EXP |\
+ THERMWDT_EXP |\
+ TMP_TRNS |\
+ CHG_TRNS)
+
+/* INT 6*/
+#define VBUS_UCD_PORT_DET BIT(13)
+#define VBUS_UCD_UCHG_DET BIT(12)
+#define VBUS_UCD_URID_RMV BIT(11)
+#define VBUS_UCD_OTG_DET BIT(10)
+#define VBUS_UCD_URID_MOD BIT(8)
+#define VCC_UCD_PORT_DET BIT(5)
+#define VCC_UCD_UCHG_DET BIT(4)
+#define VCC_UCD_URID_RMV BIT(3)
+#define VCC_UCD_OTG_DET BIT(2)
+#define VCC_UCD_URID_MOD BIT(0)
+#define INT6_ALL (VBUS_UCD_PORT_DET |\
+ VBUS_UCD_UCHG_DET |\
+ VBUS_UCD_URID_RMV |\
+ VBUS_UCD_OTG_DET |\
+ VBUS_UCD_URID_MOD |\
+ VCC_UCD_PORT_DET |\
+ VCC_UCD_UCHG_DET |\
+ VCC_UCD_URID_RMV |\
+ VCC_UCD_OTG_DET |\
+ VCC_UCD_URID_MOD)
+
+/* INT 7 */
+#define PROCHOT_DET BIT(15)
+#define PROCHOT_RES BIT(14)
+#define VACP_DET BIT(11)
+#define VACP_RES BIT(10)
+#define VACP_TH_DET BIT(9)
+#define VACP_TH_RES BIT(8)
+#define IACP_TH_DET BIT(7)
+#define IACP_THE_RES BIT(6)
+#define THERM_TH_DET BIT(5)
+#define THERM_TH_RES BIT(4)
+#define IBATM_TH_DET BIT(3)
+#define IBATM_TH_RES BIT(2)
+#define IBATP_TH_DET BIT(1)
+#define IBATP_TH_RES BIT(0)
+#define INT7_ALL (PROCHOT_DET |\
+ PROCHOT_RES |\
+ VACP_DET |\
+ VACP_RES |\
+ VACP_TH_DET |\
+ VACP_TH_RES |\
+ IACP_TH_DET |\
+ IACP_THE_RES |\
+ THERM_TH_DET |\
+ THERM_TH_RES |\
+ IBATM_TH_DET |\
+ IBATM_TH_RES |\
+ IBATP_TH_DET |\
+ IBATP_TH_RES)
+
+/* SYSTEM_CTRL_SET*/
+#define MONRST BIT(6)
+#define ALMRST BIT(5)
+#define CHGRST BIT(4)
+#define OTPLD BIT(1)
+#define ALLRST BIT(0)
+
+/* F_BATTEMP */
+#define ROOM 0x0
+#define HOT1 0x1
+#define HOT2 0x2
+#define HOT3 0x3
+#define COLD1 0x4
+#define COLD2 0x5
+#define TEMP_DIS 0x6
+#define BATT_OPEN 0x7
+
+#endif
diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
index 453d6332d43a..4540e913057f 100644
--- a/drivers/power/supply/bq24190_charger.c
+++ b/drivers/power/supply/bq24190_charger.c
@@ -673,7 +673,7 @@ static int bq24190_register_reset(struct bq24190_dev_info *bdi)
* { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
* struct i2c_adapter ad = { ... };
* i2c_add_adapter(&ad);
- * i2c_new_device(&ad, &bi);
+ * i2c_new_client_device(&ad, &bi);
*/
if (device_property_read_bool(bdi->dev, "disable-reset"))
return 0;
diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
index aebd1253dbc9..77150667e36b 100644
--- a/drivers/power/supply/bq25890_charger.c
+++ b/drivers/power/supply/bq25890_charger.c
@@ -32,6 +32,13 @@ enum bq25890_chip_version {
BQ25896,
};
+static const char *const bq25890_chip_name[] = {
+ "BQ25890",
+ "BQ25892",
+ "BQ25895",
+ "BQ25896",
+};
+
enum bq25890_fields {
F_EN_HIZ, F_EN_ILIM, F_IILIM, /* Reg00 */
F_BHOT, F_BCOLD, F_VINDPM_OFS, /* Reg01 */
@@ -119,6 +126,7 @@ static const struct regmap_access_table bq25890_writeable_regs = {
static const struct regmap_range bq25890_volatile_reg_ranges[] = {
regmap_reg_range(0x00, 0x00),
+ regmap_reg_range(0x02, 0x02),
regmap_reg_range(0x09, 0x09),
regmap_reg_range(0x0b, 0x14),
};
@@ -246,6 +254,7 @@ enum bq25890_table_ids {
/* range tables */
TBL_ICHG,
TBL_ITERM,
+ TBL_IILIM,
TBL_VREG,
TBL_BOOSTV,
TBL_SYSVMIN,
@@ -286,6 +295,7 @@ static const union {
/* TODO: BQ25896 has max ICHG 3008 mA */
[TBL_ICHG] = { .rt = {0, 5056000, 64000} }, /* uA */
[TBL_ITERM] = { .rt = {64000, 1024000, 64000} }, /* uA */
+ [TBL_IILIM] = { .rt = {50000, 3200000, 50000} }, /* uA */
[TBL_VREG] = { .rt = {3840000, 4608000, 16000} }, /* uV */
[TBL_BOOSTV] = { .rt = {4550000, 5510000, 64000} }, /* uV */
[TBL_SYSVMIN] = { .rt = {3000000, 3700000, 100000} }, /* uV */
@@ -367,18 +377,42 @@ enum bq25890_chrg_fault {
CHRG_FAULT_TIMER_EXPIRED,
};
+static bool bq25890_is_adc_property(enum power_supply_property psp)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static irqreturn_t __bq25890_handle_irq(struct bq25890_device *bq);
+
static int bq25890_power_supply_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
- int ret;
struct bq25890_device *bq = power_supply_get_drvdata(psy);
struct bq25890_state state;
+ bool do_adc_conv;
+ int ret;
mutex_lock(&bq->lock);
+ /* update state in case we lost an interrupt */
+ __bq25890_handle_irq(bq);
state = bq->state;
+ do_adc_conv = !state.online && bq25890_is_adc_property(psp);
+ if (do_adc_conv)
+ bq25890_field_write(bq, F_CONV_START, 1);
mutex_unlock(&bq->lock);
+ if (do_adc_conv)
+ regmap_field_read_poll_timeout(bq->rmap_fields[F_CONV_START],
+ ret, !ret, 25000, 1000000);
+
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (!state.online)
@@ -395,22 +429,24 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ if (!state.online || state.chrg_status == STATUS_NOT_CHARGING ||
+ state.chrg_status == STATUS_TERMINATION_DONE)
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ else if (state.chrg_status == STATUS_PRE_CHARGING)
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
+ else if (state.chrg_status == STATUS_FAST_CHARGING)
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ else /* unreachable */
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+ break;
+
case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = BQ25890_MANUFACTURER;
break;
case POWER_SUPPLY_PROP_MODEL_NAME:
- if (bq->chip_version == BQ25890)
- val->strval = "BQ25890";
- else if (bq->chip_version == BQ25892)
- val->strval = "BQ25892";
- else if (bq->chip_version == BQ25895)
- val->strval = "BQ25895";
- else if (bq->chip_version == BQ25896)
- val->strval = "BQ25896";
- else
- val->strval = "UNKNOWN";
-
+ val->strval = bq25890_chip_name[bq->chip_version];
break;
case POWER_SUPPLY_PROP_ONLINE:
@@ -430,15 +466,6 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
break;
- case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
- ret = bq25890_field_read(bq, F_ICHGR); /* read measured value */
- if (ret < 0)
- return ret;
-
- /* converted_val = ADC_val * 50mA (table 10.3.19) */
- val->intval = ret * 50000;
- break;
-
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
val->intval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG);
break;
@@ -461,10 +488,22 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
break;
+ case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+ val->intval = bq25890_find_val(bq->init_data.iprechg, TBL_ITERM);
+ break;
+
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
val->intval = bq25890_find_val(bq->init_data.iterm, TBL_ITERM);
break;
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+ ret = bq25890_field_read(bq, F_IILIM);
+ if (ret < 0)
+ return ret;
+
+ val->intval = bq25890_find_val(ret, TBL_IILIM);
+ break;
+
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = bq25890_field_read(bq, F_SYSV); /* read measured value */
if (ret < 0)
@@ -474,6 +513,15 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = 2304000 + ret * 20000;
break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ ret = bq25890_field_read(bq, F_ICHGR); /* read measured value */
+ if (ret < 0)
+ return ret;
+
+ /* converted_val = ADC_val * 50mA (table 10.3.19) */
+ val->intval = ret * -50000;
+ break;
+
default:
return -EINVAL;
}
@@ -513,74 +561,50 @@ static int bq25890_get_chip_state(struct bq25890_device *bq,
return 0;
}
-static bool bq25890_state_changed(struct bq25890_device *bq,
- struct bq25890_state *new_state)
-{
- struct bq25890_state old_state;
-
- mutex_lock(&bq->lock);
- old_state = bq->state;
- mutex_unlock(&bq->lock);
-
- return (old_state.chrg_status != new_state->chrg_status ||
- old_state.chrg_fault != new_state->chrg_fault ||
- old_state.online != new_state->online ||
- old_state.bat_fault != new_state->bat_fault ||
- old_state.boost_fault != new_state->boost_fault ||
- old_state.vsys_status != new_state->vsys_status);
-}
-
-static void bq25890_handle_state_change(struct bq25890_device *bq,
- struct bq25890_state *new_state)
+static irqreturn_t __bq25890_handle_irq(struct bq25890_device *bq)
{
+ struct bq25890_state new_state;
int ret;
- struct bq25890_state old_state;
- mutex_lock(&bq->lock);
- old_state = bq->state;
- mutex_unlock(&bq->lock);
+ ret = bq25890_get_chip_state(bq, &new_state);
+ if (ret < 0)
+ return IRQ_NONE;
+
+ if (!memcmp(&bq->state, &new_state, sizeof(new_state)))
+ return IRQ_NONE;
- if (!new_state->online) { /* power removed */
+ if (!new_state.online && bq->state.online) { /* power removed */
/* disable ADC */
ret = bq25890_field_write(bq, F_CONV_START, 0);
if (ret < 0)
goto error;
- } else if (!old_state.online) { /* power inserted */
+ } else if (new_state.online && !bq->state.online) { /* power inserted */
/* enable ADC, to have control of charge current/voltage */
ret = bq25890_field_write(bq, F_CONV_START, 1);
if (ret < 0)
goto error;
}
- return;
+ bq->state = new_state;
+ power_supply_changed(bq->charger);
+ return IRQ_HANDLED;
error:
- dev_err(bq->dev, "Error communicating with the chip.\n");
+ dev_err(bq->dev, "Error communicating with the chip: %pe\n",
+ ERR_PTR(ret));
+ return IRQ_HANDLED;
}
static irqreturn_t bq25890_irq_handler_thread(int irq, void *private)
{
struct bq25890_device *bq = private;
- int ret;
- struct bq25890_state state;
-
- ret = bq25890_get_chip_state(bq, &state);
- if (ret < 0)
- goto handled;
-
- if (!bq25890_state_changed(bq, &state))
- goto handled;
-
- bq25890_handle_state_change(bq, &state);
+ irqreturn_t ret;
mutex_lock(&bq->lock);
- bq->state = state;
+ ret = __bq25890_handle_irq(bq);
mutex_unlock(&bq->lock);
- power_supply_changed(bq->charger);
-
-handled:
- return IRQ_HANDLED;
+ return ret;
}
static int bq25890_chip_reset(struct bq25890_device *bq)
@@ -610,7 +634,6 @@ static int bq25890_hw_init(struct bq25890_device *bq)
{
int ret;
int i;
- struct bq25890_state state;
const struct {
enum bq25890_fields id;
@@ -651,38 +674,37 @@ static int bq25890_hw_init(struct bq25890_device *bq)
}
}
- /* Configure ADC for continuous conversions. This does not enable it. */
- ret = bq25890_field_write(bq, F_CONV_RATE, 1);
+ /* Configure ADC for continuous conversions when charging */
+ ret = bq25890_field_write(bq, F_CONV_RATE, !!bq->state.online);
if (ret < 0) {
dev_dbg(bq->dev, "Config ADC failed %d\n", ret);
return ret;
}
- ret = bq25890_get_chip_state(bq, &state);
+ ret = bq25890_get_chip_state(bq, &bq->state);
if (ret < 0) {
dev_dbg(bq->dev, "Get state failed %d\n", ret);
return ret;
}
- mutex_lock(&bq->lock);
- bq->state = state;
- mutex_unlock(&bq->lock);
-
return 0;
}
-static enum power_supply_property bq25890_power_supply_props[] = {
+static const enum power_supply_property bq25890_power_supply_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
};
static char *bq25890_charger_supplied_to[] = {
@@ -881,17 +903,11 @@ static int bq25890_fw_probe(struct bq25890_device *bq)
static int bq25890_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
struct bq25890_device *bq;
int ret;
int i;
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
- return -ENODEV;
- }
-
bq = devm_kzalloc(dev, sizeof(*bq), GFP_KERNEL);
if (!bq)
return -ENOMEM;
@@ -1004,34 +1020,34 @@ static int bq25890_suspend(struct device *dev)
* If charger is removed, while in suspend, make sure ADC is diabled
* since it consumes slightly more power.
*/
- return bq25890_field_write(bq, F_CONV_START, 0);
+ return bq25890_field_write(bq, F_CONV_RATE, 0);
}
static int bq25890_resume(struct device *dev)
{
int ret;
- struct bq25890_state state;
struct bq25890_device *bq = dev_get_drvdata(dev);
- ret = bq25890_get_chip_state(bq, &state);
- if (ret < 0)
- return ret;
-
mutex_lock(&bq->lock);
- bq->state = state;
- mutex_unlock(&bq->lock);
+
+ ret = bq25890_get_chip_state(bq, &bq->state);
+ if (ret < 0)
+ goto unlock;
/* Re-enable ADC only if charger is plugged in. */
- if (state.online) {
- ret = bq25890_field_write(bq, F_CONV_START, 1);
+ if (bq->state.online) {
+ ret = bq25890_field_write(bq, F_CONV_RATE, 1);
if (ret < 0)
- return ret;
+ goto unlock;
}
/* signal userspace, maybe state changed while suspended */
power_supply_changed(bq->charger);
- return 0;
+unlock:
+ mutex_unlock(&bq->lock);
+
+ return ret;
}
#endif
diff --git a/drivers/power/supply/charger-manager.c b/drivers/power/supply/charger-manager.c
index a21e1a2673f8..2ef53dc1f2fb 100644
--- a/drivers/power/supply/charger-manager.c
+++ b/drivers/power/supply/charger-manager.c
@@ -1422,7 +1422,9 @@ static int charger_manager_prepare_sysfs(struct charger_manager *cm)
}
static int cm_init_thermal_data(struct charger_manager *cm,
- struct power_supply *fuel_gauge)
+ struct power_supply *fuel_gauge,
+ enum power_supply_property *properties,
+ size_t *num_properties)
{
struct charger_desc *desc = cm->desc;
union power_supply_propval val;
@@ -1433,9 +1435,8 @@ static int cm_init_thermal_data(struct charger_manager *cm,
POWER_SUPPLY_PROP_TEMP, &val);
if (!ret) {
- cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
- POWER_SUPPLY_PROP_TEMP;
- cm->charger_psy_desc.num_properties++;
+ properties[*num_properties] = POWER_SUPPLY_PROP_TEMP;
+ (*num_properties)++;
cm->desc->measure_battery_temp = true;
}
#ifdef CONFIG_THERMAL
@@ -1446,9 +1447,8 @@ static int cm_init_thermal_data(struct charger_manager *cm,
return PTR_ERR(cm->tzd_batt);
/* Use external thermometer */
- cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
- POWER_SUPPLY_PROP_TEMP_AMBIENT;
- cm->charger_psy_desc.num_properties++;
+ properties[*num_properties] = POWER_SUPPLY_PROP_TEMP_AMBIENT;
+ (*num_properties)++;
cm->desc->measure_battery_temp = true;
ret = 0;
}
@@ -1621,6 +1621,8 @@ static int charger_manager_probe(struct platform_device *pdev)
int j = 0;
union power_supply_propval val;
struct power_supply *fuel_gauge;
+ enum power_supply_property *properties;
+ size_t num_properties;
struct power_supply_config psy_cfg = {};
if (IS_ERR(desc)) {
@@ -1717,18 +1719,17 @@ static int charger_manager_probe(struct platform_device *pdev)
cm->charger_psy_desc.name = cm->psy_name_buf;
/* Allocate for psy properties because they may vary */
- cm->charger_psy_desc.properties =
- devm_kcalloc(&pdev->dev,
+ properties = devm_kcalloc(&pdev->dev,
ARRAY_SIZE(default_charger_props) +
NUM_CHARGER_PSY_OPTIONAL,
- sizeof(enum power_supply_property), GFP_KERNEL);
- if (!cm->charger_psy_desc.properties)
+ sizeof(*properties), GFP_KERNEL);
+ if (!properties)
return -ENOMEM;
- memcpy(cm->charger_psy_desc.properties, default_charger_props,
+ memcpy(properties, default_charger_props,
sizeof(enum power_supply_property) *
ARRAY_SIZE(default_charger_props));
- cm->charger_psy_desc.num_properties = psy_default.num_properties;
+ num_properties = ARRAY_SIZE(default_charger_props);
/* Find which optional psy-properties are available */
fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
@@ -1739,25 +1740,28 @@ static int charger_manager_probe(struct platform_device *pdev)
}
if (!power_supply_get_property(fuel_gauge,
POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
- cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
+ properties[num_properties] =
POWER_SUPPLY_PROP_CHARGE_NOW;
- cm->charger_psy_desc.num_properties++;
+ num_properties++;
}
if (!power_supply_get_property(fuel_gauge,
POWER_SUPPLY_PROP_CURRENT_NOW,
&val)) {
- cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
+ properties[num_properties] =
POWER_SUPPLY_PROP_CURRENT_NOW;
- cm->charger_psy_desc.num_properties++;
+ num_properties++;
}
- ret = cm_init_thermal_data(cm, fuel_gauge);
+ ret = cm_init_thermal_data(cm, fuel_gauge, properties, &num_properties);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize thermal data\n");
cm->desc->measure_battery_temp = false;
}
power_supply_put(fuel_gauge);
+ cm->charger_psy_desc.properties = properties;
+ cm->charger_psy_desc.num_properties = num_properties;
+
INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
/* Register sysfs entry for charger(regulator) */
diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c
new file mode 100644
index 000000000000..0146f1bfc29b
--- /dev/null
+++ b/drivers/power/supply/cw2015_battery.c
@@ -0,0 +1,750 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Fuel gauge driver for CellWise 2013 / 2015
+ *
+ * Copyright (C) 2012, RockChip
+ * Copyright (C) 2020, Tobias Schramm
+ *
+ * Authors: xuhuicong <xhc@rock-chips.com>
+ * Authors: Tobias Schramm <t.schramm@manjaro.org>
+ */
+
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/gfp.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/power_supply.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+
+#define CW2015_SIZE_BATINFO 64
+
+#define CW2015_RESET_TRIES 5
+
+#define CW2015_REG_VERSION 0x00
+#define CW2015_REG_VCELL 0x02
+#define CW2015_REG_SOC 0x04
+#define CW2015_REG_RRT_ALERT 0x06
+#define CW2015_REG_CONFIG 0x08
+#define CW2015_REG_MODE 0x0A
+#define CW2015_REG_BATINFO 0x10
+
+#define CW2015_MODE_SLEEP_MASK GENMASK(7, 6)
+#define CW2015_MODE_SLEEP (0x03 << 6)
+#define CW2015_MODE_NORMAL (0x00 << 6)
+#define CW2015_MODE_QUICK_START (0x03 << 4)
+#define CW2015_MODE_RESTART (0x0f << 0)
+
+#define CW2015_CONFIG_UPDATE_FLG (0x01 << 1)
+#define CW2015_ATHD(x) ((x) << 3)
+#define CW2015_MASK_ATHD GENMASK(7, 3)
+#define CW2015_MASK_SOC GENMASK(12, 0)
+
+/* reset gauge of no valid state of charge could be polled for 40s */
+#define CW2015_BAT_SOC_ERROR_MS (40 * MSEC_PER_SEC)
+/* reset gauge if state of charge stuck for half an hour during charging */
+#define CW2015_BAT_CHARGING_STUCK_MS (1800 * MSEC_PER_SEC)
+
+/* poll interval from CellWise GPL Android driver example */
+#define CW2015_DEFAULT_POLL_INTERVAL_MS 8000
+
+#define CW2015_AVERAGING_SAMPLES 3
+
+struct cw_battery {
+ struct device *dev;
+ struct workqueue_struct *battery_workqueue;
+ struct delayed_work battery_delay_work;
+ struct regmap *regmap;
+ struct power_supply *rk_bat;
+ struct power_supply_battery_info battery;
+ u8 *bat_profile;
+
+ bool charger_attached;
+ bool battery_changed;
+
+ int soc;
+ int voltage_mv;
+ int status;
+ int time_to_empty;
+ int charge_count;
+
+ u32 poll_interval_ms;
+ u8 alert_level;
+
+ unsigned int read_errors;
+ unsigned int charge_stuck_cnt;
+};
+
+static int cw_read_word(struct cw_battery *cw_bat, u8 reg, u16 *val)
+{
+ __be16 value;
+ int ret;
+
+ ret = regmap_bulk_read(cw_bat->regmap, reg, &value, sizeof(value));
+ if (ret)
+ return ret;
+
+ *val = be16_to_cpu(value);
+ return 0;
+}
+
+static int cw_update_profile(struct cw_battery *cw_bat)
+{
+ int ret;
+ unsigned int reg_val;
+ u8 reset_val;
+
+ /* make sure gauge is not in sleep mode */
+ ret = regmap_read(cw_bat->regmap, CW2015_REG_MODE, &reg_val);
+ if (ret)
+ return ret;
+
+ reset_val = reg_val;
+ if ((reg_val & CW2015_MODE_SLEEP_MASK) == CW2015_MODE_SLEEP) {
+ dev_err(cw_bat->dev,
+ "Gauge is in sleep mode, can't update battery info\n");
+ return -EINVAL;
+ }
+
+ /* write new battery info */
+ ret = regmap_raw_write(cw_bat->regmap, CW2015_REG_BATINFO,
+ cw_bat->bat_profile,
+ CW2015_SIZE_BATINFO);
+ if (ret)
+ return ret;
+
+ /* set config update flag */
+ reg_val |= CW2015_CONFIG_UPDATE_FLG;
+ reg_val &= ~CW2015_MASK_ATHD;
+ reg_val |= CW2015_ATHD(cw_bat->alert_level);
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_CONFIG, reg_val);
+ if (ret)
+ return ret;
+
+ /* reset gauge to apply new battery profile */
+ reset_val &= ~CW2015_MODE_RESTART;
+ reg_val = reset_val | CW2015_MODE_RESTART;
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reg_val);
+ if (ret)
+ return ret;
+
+ /* wait for gauge to reset */
+ msleep(20);
+
+ /* clear reset flag */
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reset_val);
+ if (ret)
+ return ret;
+
+ /* wait for gauge to become ready */
+ ret = regmap_read_poll_timeout(cw_bat->regmap, CW2015_REG_SOC,
+ reg_val, reg_val <= 100,
+ 10 * USEC_PER_MSEC, 10 * USEC_PER_SEC);
+ if (ret)
+ dev_err(cw_bat->dev,
+ "Gauge did not become ready after profile upload\n");
+ else
+ dev_dbg(cw_bat->dev, "Battery profile updated\n");
+
+ return ret;
+}
+
+static int cw_init(struct cw_battery *cw_bat)
+{
+ int ret;
+ unsigned int reg_val = CW2015_MODE_SLEEP;
+
+ if ((reg_val & CW2015_MODE_SLEEP_MASK) == CW2015_MODE_SLEEP) {
+ reg_val = CW2015_MODE_NORMAL;
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reg_val);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_read(cw_bat->regmap, CW2015_REG_CONFIG, &reg_val);
+ if (ret)
+ return ret;
+
+ if ((reg_val & CW2015_MASK_ATHD) != CW2015_ATHD(cw_bat->alert_level)) {
+ dev_dbg(cw_bat->dev, "Setting new alert level\n");
+ reg_val &= ~CW2015_MASK_ATHD;
+ reg_val |= ~CW2015_ATHD(cw_bat->alert_level);
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_CONFIG, reg_val);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_read(cw_bat->regmap, CW2015_REG_CONFIG, &reg_val);
+ if (ret)
+ return ret;
+
+ if (!(reg_val & CW2015_CONFIG_UPDATE_FLG)) {
+ dev_dbg(cw_bat->dev,
+ "Battery profile not present, uploading battery profile\n");
+ if (cw_bat->bat_profile) {
+ ret = cw_update_profile(cw_bat);
+ if (ret) {
+ dev_err(cw_bat->dev,
+ "Failed to upload battery profile\n");
+ return ret;
+ }
+ } else {
+ dev_warn(cw_bat->dev,
+ "No profile specified, continuing without profile\n");
+ }
+ } else if (cw_bat->bat_profile) {
+ u8 bat_info[CW2015_SIZE_BATINFO];
+
+ ret = regmap_raw_read(cw_bat->regmap, CW2015_REG_BATINFO,
+ bat_info, CW2015_SIZE_BATINFO);
+ if (ret) {
+ dev_err(cw_bat->dev,
+ "Failed to read stored battery profile\n");
+ return ret;
+ }
+
+ if (memcmp(bat_info, cw_bat->bat_profile, CW2015_SIZE_BATINFO)) {
+ dev_warn(cw_bat->dev, "Replacing stored battery profile\n");
+ ret = cw_update_profile(cw_bat);
+ if (ret)
+ return ret;
+ }
+ } else {
+ dev_warn(cw_bat->dev,
+ "Can't check current battery profile, no profile provided\n");
+ }
+
+ dev_dbg(cw_bat->dev, "Battery profile configured\n");
+ return 0;
+}
+
+static int cw_power_on_reset(struct cw_battery *cw_bat)
+{
+ int ret;
+ unsigned char reset_val;
+
+ reset_val = CW2015_MODE_SLEEP;
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reset_val);
+ if (ret)
+ return ret;
+
+ /* wait for gauge to enter sleep */
+ msleep(20);
+
+ reset_val = CW2015_MODE_NORMAL;
+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reset_val);
+ if (ret)
+ return ret;
+
+ ret = cw_init(cw_bat);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+#define HYSTERESIS(current, previous, up, down) \
+ (((current) < (previous) + (up)) && ((current) > (previous) - (down)))
+
+static int cw_get_soc(struct cw_battery *cw_bat)
+{
+ unsigned int soc;
+ int ret;
+
+ ret = regmap_read(cw_bat->regmap, CW2015_REG_SOC, &soc);
+ if (ret)
+ return ret;
+
+ if (soc > 100) {
+ int max_error_cycles =
+ CW2015_BAT_SOC_ERROR_MS / cw_bat->poll_interval_ms;
+
+ dev_err(cw_bat->dev, "Invalid SoC %d%%\n", soc);
+ cw_bat->read_errors++;
+ if (cw_bat->read_errors > max_error_cycles) {
+ dev_warn(cw_bat->dev,
+ "Too many invalid SoC reports, resetting gauge\n");
+ cw_power_on_reset(cw_bat);
+ cw_bat->read_errors = 0;
+ }
+ return cw_bat->soc;
+ }
+ cw_bat->read_errors = 0;
+
+ /* Reset gauge if stuck while charging */
+ if (cw_bat->status == POWER_SUPPLY_STATUS_CHARGING && soc == cw_bat->soc) {
+ int max_stuck_cycles =
+ CW2015_BAT_CHARGING_STUCK_MS / cw_bat->poll_interval_ms;
+
+ cw_bat->charge_stuck_cnt++;
+ if (cw_bat->charge_stuck_cnt > max_stuck_cycles) {
+ dev_warn(cw_bat->dev,
+ "SoC stuck @%u%%, resetting gauge\n", soc);
+ cw_power_on_reset(cw_bat);
+ cw_bat->charge_stuck_cnt = 0;
+ }
+ } else {
+ cw_bat->charge_stuck_cnt = 0;
+ }
+
+ /* Ignore voltage dips during charge */
+ if (cw_bat->charger_attached && HYSTERESIS(soc, cw_bat->soc, 0, 3))
+ soc = cw_bat->soc;
+
+ /* Ignore voltage spikes during discharge */
+ if (!cw_bat->charger_attached && HYSTERESIS(soc, cw_bat->soc, 3, 0))
+ soc = cw_bat->soc;
+
+ return soc;
+}
+
+static int cw_get_voltage(struct cw_battery *cw_bat)
+{
+ int ret, i, voltage_mv;
+ u16 reg_val;
+ u32 avg = 0;
+
+ for (i = 0; i < CW2015_AVERAGING_SAMPLES; i++) {
+ ret = cw_read_word(cw_bat, CW2015_REG_VCELL, &reg_val);
+ if (ret)
+ return ret;
+
+ avg += reg_val;
+ }
+ avg /= CW2015_AVERAGING_SAMPLES;
+
+ /*
+ * 305 uV per ADC step
+ * Use 312 / 1024 as efficient approximation of 305 / 1000
+ * Negligible error of 0.1%
+ */
+ voltage_mv = avg * 312 / 1024;
+
+ dev_dbg(cw_bat->dev, "Read voltage: %d mV, raw=0x%04x\n",
+ voltage_mv, reg_val);
+ return voltage_mv;
+}
+
+static int cw_get_time_to_empty(struct cw_battery *cw_bat)
+{
+ int ret;
+ u16 value16;
+
+ ret = cw_read_word(cw_bat, CW2015_REG_RRT_ALERT, &value16);
+ if (ret)
+ return ret;
+
+ return value16 & CW2015_MASK_SOC;
+}
+
+static void cw_update_charge_status(struct cw_battery *cw_bat)
+{
+ int ret;
+
+ ret = power_supply_am_i_supplied(cw_bat->rk_bat);
+ if (ret < 0) {
+ dev_warn(cw_bat->dev, "Failed to get supply state: %d\n", ret);
+ } else {
+ bool charger_attached;
+
+ charger_attached = !!ret;
+ if (cw_bat->charger_attached != charger_attached) {
+ cw_bat->battery_changed = true;
+ if (charger_attached)
+ cw_bat->charge_count++;
+ }
+ cw_bat->charger_attached = charger_attached;
+ }
+}
+
+static void cw_update_soc(struct cw_battery *cw_bat)
+{
+ int soc;
+
+ soc = cw_get_soc(cw_bat);
+ if (soc < 0)
+ dev_err(cw_bat->dev, "Failed to get SoC from gauge: %d\n", soc);
+ else if (cw_bat->soc != soc) {
+ cw_bat->soc = soc;
+ cw_bat->battery_changed = true;
+ }
+}
+
+static void cw_update_voltage(struct cw_battery *cw_bat)
+{
+ int voltage_mv;
+
+ voltage_mv = cw_get_voltage(cw_bat);
+ if (voltage_mv < 0)
+ dev_err(cw_bat->dev, "Failed to get voltage from gauge: %d\n",
+ voltage_mv);
+ else
+ cw_bat->voltage_mv = voltage_mv;
+}
+
+static void cw_update_status(struct cw_battery *cw_bat)
+{
+ int status = POWER_SUPPLY_STATUS_DISCHARGING;
+
+ if (cw_bat->charger_attached) {
+ if (cw_bat->soc >= 100)
+ status = POWER_SUPPLY_STATUS_FULL;
+ else
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ }
+
+ if (cw_bat->status != status)
+ cw_bat->battery_changed = true;
+ cw_bat->status = status;
+}
+
+static void cw_update_time_to_empty(struct cw_battery *cw_bat)
+{
+ int time_to_empty;
+
+ time_to_empty = cw_get_time_to_empty(cw_bat);
+ if (time_to_empty < 0)
+ dev_err(cw_bat->dev, "Failed to get time to empty from gauge: %d\n",
+ time_to_empty);
+ else if (cw_bat->time_to_empty != time_to_empty) {
+ cw_bat->time_to_empty = time_to_empty;
+ cw_bat->battery_changed = true;
+ }
+}
+
+static void cw_bat_work(struct work_struct *work)
+{
+ struct delayed_work *delay_work;
+ struct cw_battery *cw_bat;
+ int ret;
+ unsigned int reg_val;
+
+ delay_work = to_delayed_work(work);
+ cw_bat = container_of(delay_work, struct cw_battery, battery_delay_work);
+ ret = regmap_read(cw_bat->regmap, CW2015_REG_MODE, &reg_val);
+ if (ret) {
+ dev_err(cw_bat->dev, "Failed to read mode from gauge: %d\n", ret);
+ } else {
+ if ((reg_val & CW2015_MODE_SLEEP_MASK) == CW2015_MODE_SLEEP) {
+ int i;
+
+ for (i = 0; i < CW2015_RESET_TRIES; i++) {
+ if (!cw_power_on_reset(cw_bat))
+ break;
+ }
+ }
+ cw_update_soc(cw_bat);
+ cw_update_voltage(cw_bat);
+ cw_update_charge_status(cw_bat);
+ cw_update_status(cw_bat);
+ cw_update_time_to_empty(cw_bat);
+ }
+ dev_dbg(cw_bat->dev, "charger_attached = %d\n", cw_bat->charger_attached);
+ dev_dbg(cw_bat->dev, "status = %d\n", cw_bat->status);
+ dev_dbg(cw_bat->dev, "soc = %d%%\n", cw_bat->soc);
+ dev_dbg(cw_bat->dev, "voltage = %dmV\n", cw_bat->voltage_mv);
+
+ if (cw_bat->battery_changed)
+ power_supply_changed(cw_bat->rk_bat);
+ cw_bat->battery_changed = false;
+
+ queue_delayed_work(cw_bat->battery_workqueue,
+ &cw_bat->battery_delay_work,
+ msecs_to_jiffies(cw_bat->poll_interval_ms));
+}
+
+static bool cw_battery_valid_time_to_empty(struct cw_battery *cw_bat)
+{
+ return cw_bat->time_to_empty > 0 &&
+ cw_bat->time_to_empty < CW2015_MASK_SOC &&
+ cw_bat->status == POWER_SUPPLY_STATUS_DISCHARGING;
+}
+
+static int cw_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct cw_battery *cw_bat;
+
+ cw_bat = power_supply_get_drvdata(psy);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = cw_bat->soc;
+ break;
+
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = cw_bat->status;
+ break;
+
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = !!cw_bat->voltage_mv;
+ break;
+
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = cw_bat->voltage_mv * 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+ if (cw_battery_valid_time_to_empty(cw_bat))
+ val->intval = cw_bat->time_to_empty;
+ else
+ val->intval = 0;
+ break;
+
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+
+ case POWER_SUPPLY_PROP_CHARGE_COUNTER:
+ val->intval = cw_bat->charge_count;
+ break;
+
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ if (cw_bat->battery.charge_full_design_uah > 0)
+ val->intval = cw_bat->battery.charge_full_design_uah;
+ else
+ val->intval = 0;
+ break;
+
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ if (cw_battery_valid_time_to_empty(cw_bat) &&
+ cw_bat->battery.charge_full_design_uah > 0) {
+ /* calculate remaining capacity */
+ val->intval = cw_bat->battery.charge_full_design_uah;
+ val->intval = val->intval * cw_bat->soc / 100;
+
+ /* estimate current based on time to empty */
+ val->intval = 60 * val->intval / cw_bat->time_to_empty;
+ } else {
+ val->intval = 0;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static enum power_supply_property cw_battery_properties[] = {
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CHARGE_COUNTER,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+};
+
+static const struct power_supply_desc cw2015_bat_desc = {
+ .name = "cw2015-battery",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = cw_battery_properties,
+ .num_properties = ARRAY_SIZE(cw_battery_properties),
+ .get_property = cw_battery_get_property,
+};
+
+static int cw2015_parse_properties(struct cw_battery *cw_bat)
+{
+ struct device *dev = cw_bat->dev;
+ int length;
+ int ret;
+
+ length = device_property_count_u8(dev, "cellwise,battery-profile");
+ if (length < 0) {
+ dev_warn(cw_bat->dev,
+ "No battery-profile found, using current flash contents\n");
+ } else if (length != CW2015_SIZE_BATINFO) {
+ dev_err(cw_bat->dev, "battery-profile must be %d bytes\n",
+ CW2015_SIZE_BATINFO);
+ return -EINVAL;
+ } else {
+ cw_bat->bat_profile = devm_kzalloc(dev, length, GFP_KERNEL);
+ if (!cw_bat->bat_profile)
+ return -ENOMEM;
+
+ ret = device_property_read_u8_array(dev,
+ "cellwise,battery-profile",
+ cw_bat->bat_profile,
+ length);
+ if (ret)
+ return ret;
+ }
+
+ ret = device_property_read_u32(dev, "cellwise,monitor-interval-ms",
+ &cw_bat->poll_interval_ms);
+ if (ret) {
+ dev_dbg(cw_bat->dev, "Using default poll interval\n");
+ cw_bat->poll_interval_ms = CW2015_DEFAULT_POLL_INTERVAL_MS;
+ }
+
+ return 0;
+}
+
+static const struct regmap_range regmap_ranges_rd_yes[] = {
+ regmap_reg_range(CW2015_REG_VERSION, CW2015_REG_VERSION),
+ regmap_reg_range(CW2015_REG_VCELL, CW2015_REG_CONFIG),
+ regmap_reg_range(CW2015_REG_MODE, CW2015_REG_MODE),
+ regmap_reg_range(CW2015_REG_BATINFO,
+ CW2015_REG_BATINFO + CW2015_SIZE_BATINFO - 1),
+};
+
+static const struct regmap_access_table regmap_rd_table = {
+ .yes_ranges = regmap_ranges_rd_yes,
+ .n_yes_ranges = 4,
+};
+
+static const struct regmap_range regmap_ranges_wr_yes[] = {
+ regmap_reg_range(CW2015_REG_RRT_ALERT, CW2015_REG_CONFIG),
+ regmap_reg_range(CW2015_REG_MODE, CW2015_REG_MODE),
+ regmap_reg_range(CW2015_REG_BATINFO,
+ CW2015_REG_BATINFO + CW2015_SIZE_BATINFO - 1),
+};
+
+static const struct regmap_access_table regmap_wr_table = {
+ .yes_ranges = regmap_ranges_wr_yes,
+ .n_yes_ranges = 3,
+};
+
+static const struct regmap_range regmap_ranges_vol_yes[] = {
+ regmap_reg_range(CW2015_REG_VCELL, CW2015_REG_SOC + 1),
+};
+
+static const struct regmap_access_table regmap_vol_table = {
+ .yes_ranges = regmap_ranges_vol_yes,
+ .n_yes_ranges = 1,
+};
+
+static const struct regmap_config cw2015_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .rd_table = &regmap_rd_table,
+ .wr_table = &regmap_wr_table,
+ .volatile_table = &regmap_vol_table,
+ .max_register = CW2015_REG_BATINFO + CW2015_SIZE_BATINFO - 1,
+};
+
+static int cw_bat_probe(struct i2c_client *client)
+{
+ int ret;
+ struct cw_battery *cw_bat;
+ struct power_supply_config psy_cfg = { 0 };
+
+ cw_bat = devm_kzalloc(&client->dev, sizeof(*cw_bat), GFP_KERNEL);
+ if (!cw_bat)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, cw_bat);
+ cw_bat->dev = &client->dev;
+ cw_bat->soc = 1;
+
+ ret = cw2015_parse_properties(cw_bat);
+ if (ret) {
+ dev_err(cw_bat->dev, "Failed to parse cw2015 properties\n");
+ return ret;
+ }
+
+ cw_bat->regmap = devm_regmap_init_i2c(client, &cw2015_regmap_config);
+ if (IS_ERR(cw_bat->regmap)) {
+ dev_err(cw_bat->dev, "Failed to allocate regmap: %ld\n",
+ PTR_ERR(cw_bat->regmap));
+ return PTR_ERR(cw_bat->regmap);
+ }
+
+ ret = cw_init(cw_bat);
+ if (ret) {
+ dev_err(cw_bat->dev, "Init failed: %d\n", ret);
+ return ret;
+ }
+
+ psy_cfg.drv_data = cw_bat;
+ psy_cfg.fwnode = dev_fwnode(cw_bat->dev);
+
+ cw_bat->rk_bat = devm_power_supply_register(&client->dev,
+ &cw2015_bat_desc,
+ &psy_cfg);
+ if (IS_ERR(cw_bat->rk_bat)) {
+ dev_err(cw_bat->dev, "Failed to register power supply\n");
+ return PTR_ERR(cw_bat->rk_bat);
+ }
+
+ ret = power_supply_get_battery_info(cw_bat->rk_bat, &cw_bat->battery);
+ if (ret) {
+ dev_warn(cw_bat->dev,
+ "No monitored battery, some properties will be missing\n");
+ }
+
+ cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery");
+ INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work);
+ queue_delayed_work(cw_bat->battery_workqueue,
+ &cw_bat->battery_delay_work, msecs_to_jiffies(10));
+ return 0;
+}
+
+static int __maybe_unused cw_bat_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cw_battery *cw_bat = i2c_get_clientdata(client);
+
+ cancel_delayed_work_sync(&cw_bat->battery_delay_work);
+ return 0;
+}
+
+static int __maybe_unused cw_bat_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cw_battery *cw_bat = i2c_get_clientdata(client);
+
+ queue_delayed_work(cw_bat->battery_workqueue,
+ &cw_bat->battery_delay_work, 0);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(cw_bat_pm_ops, cw_bat_suspend, cw_bat_resume);
+
+static int cw_bat_remove(struct i2c_client *client)
+{
+ struct cw_battery *cw_bat = i2c_get_clientdata(client);
+
+ cancel_delayed_work_sync(&cw_bat->battery_delay_work);
+ power_supply_put_battery_info(cw_bat->rk_bat, &cw_bat->battery);
+ return 0;
+}
+
+static const struct i2c_device_id cw_bat_id_table[] = {
+ { "cw2015", 0 },
+ { }
+};
+
+static const struct of_device_id cw2015_of_match[] = {
+ { .compatible = "cellwise,cw2015" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cw2015_of_match);
+
+static struct i2c_driver cw_bat_driver = {
+ .driver = {
+ .name = "cw2015",
+ .of_match_table = cw2015_of_match,
+ .pm = &cw_bat_pm_ops,
+ },
+ .probe_new = cw_bat_probe,
+ .remove = cw_bat_remove,
+ .id_table = cw_bat_id_table,
+};
+
+module_i2c_driver(cw_bat_driver);
+
+MODULE_AUTHOR("xhc<xhc@rock-chips.com>");
+MODULE_AUTHOR("Tobias Schramm <t.schramm@manjaro.org>");
+MODULE_DESCRIPTION("cw2015/cw2013 battery driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c
index bc462d1ec963..caa829738ef7 100644
--- a/drivers/power/supply/generic-adc-battery.c
+++ b/drivers/power/supply/generic-adc-battery.c
@@ -241,6 +241,7 @@ static int gab_probe(struct platform_device *pdev)
struct power_supply_desc *psy_desc;
struct power_supply_config psy_cfg = {};
struct gab_platform_data *pdata = pdev->dev.platform_data;
+ enum power_supply_property *properties;
int ret = 0;
int chan;
int index = ARRAY_SIZE(gab_props);
@@ -268,16 +269,16 @@ static int gab_probe(struct platform_device *pdev)
* copying the static properties and allocating extra memory for holding
* the extra configurable properties received from platform data.
*/
- psy_desc->properties = kcalloc(ARRAY_SIZE(gab_props) +
- ARRAY_SIZE(gab_chan_name),
- sizeof(*psy_desc->properties),
- GFP_KERNEL);
- if (!psy_desc->properties) {
+ properties = kcalloc(ARRAY_SIZE(gab_props) +
+ ARRAY_SIZE(gab_chan_name),
+ sizeof(*properties),
+ GFP_KERNEL);
+ if (!properties) {
ret = -ENOMEM;
goto first_mem_fail;
}
- memcpy(psy_desc->properties, gab_props, sizeof(gab_props));
+ memcpy(properties, gab_props, sizeof(gab_props));
/*
* getting channel from iio and copying the battery properties
@@ -294,13 +295,11 @@ static int gab_probe(struct platform_device *pdev)
int index2;
for (index2 = 0; index2 < index; index2++) {
- if (psy_desc->properties[index2] ==
- gab_dyn_props[chan])
+ if (properties[index2] == gab_dyn_props[chan])
break; /* already known */
}
if (index2 == index) /* really new */
- psy_desc->properties[index++] =
- gab_dyn_props[chan];
+ properties[index++] = gab_dyn_props[chan];
any = true;
}
}
@@ -317,6 +316,7 @@ static int gab_probe(struct platform_device *pdev)
* as come channels may be not be supported by the device.So
* we need to take care of that.
*/
+ psy_desc->properties = properties;
psy_desc->num_properties = index;
adc_bat->psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg);
@@ -358,7 +358,7 @@ err_reg_fail:
iio_channel_release(adc_bat->channel[chan]);
}
second_mem_fail:
- kfree(psy_desc->properties);
+ kfree(properties);
first_mem_fail:
return ret;
}
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
index 84a206f42a8e..e7931ffb7151 100644
--- a/drivers/power/supply/lp8788-charger.c
+++ b/drivers/power/supply/lp8788-charger.c
@@ -572,27 +572,14 @@ static void lp8788_setup_adc_channel(struct device *dev,
return;
/* ADC channel for battery voltage */
- chan = iio_channel_get(dev, pdata->adc_vbatt);
+ chan = devm_iio_channel_get(dev, pdata->adc_vbatt);
pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan;
/* ADC channel for battery temperature */
- chan = iio_channel_get(dev, pdata->adc_batt_temp);
+ chan = devm_iio_channel_get(dev, pdata->adc_batt_temp);
pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan;
}
-static void lp8788_release_adc_channel(struct lp8788_charger *pchg)
-{
- int i;
-
- for (i = 0; i < LP8788_NUM_CHG_ADC; i++) {
- if (!pchg->chan[i])
- continue;
-
- iio_channel_release(pchg->chan[i]);
- pchg->chan[i] = NULL;
- }
-}
-
static ssize_t lp8788_show_charger_status(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -735,7 +722,6 @@ static int lp8788_charger_remove(struct platform_device *pdev)
flush_work(&pchg->charger_work);
lp8788_irq_unregister(pdev, pchg);
lp8788_psy_unregister(pchg);
- lp8788_release_adc_channel(pchg);
return 0;
}
diff --git a/drivers/power/supply/max14577_charger.c b/drivers/power/supply/max14577_charger.c
index 8a59feac6468..dcedae18d7be 100644
--- a/drivers/power/supply/max14577_charger.c
+++ b/drivers/power/supply/max14577_charger.c
@@ -623,9 +623,19 @@ static const struct platform_device_id max14577_charger_id[] = {
};
MODULE_DEVICE_TABLE(platform, max14577_charger_id);
+static const struct of_device_id of_max14577_charger_dt_match[] = {
+ { .compatible = "maxim,max14577-charger",
+ .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, },
+ { .compatible = "maxim,max77836-charger",
+ .data = (void *)MAXIM_DEVICE_TYPE_MAX77836, },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_max14577_charger_dt_match);
+
static struct platform_driver max14577_charger_driver = {
.driver = {
.name = "max14577-charger",
+ .of_match_table = of_max14577_charger_dt_match,
},
.probe = max14577_charger_probe,
.remove = max14577_charger_remove,
diff --git a/drivers/power/supply/max14656_charger_detector.c b/drivers/power/supply/max14656_charger_detector.c
index 3bbb8b4c8ae7..137f9fafce8c 100644
--- a/drivers/power/supply/max14656_charger_detector.c
+++ b/drivers/power/supply/max14656_charger_detector.c
@@ -139,10 +139,9 @@ static void max14656_irq_worker(struct work_struct *work)
u8 buf[REG_TOTAL_NUM];
u8 chg_type;
- int ret = 0;
- ret = max14656_read_block_reg(chip->client, MAX14656_DEVICE_ID,
- REG_TOTAL_NUM, buf);
+ max14656_read_block_reg(chip->client, MAX14656_DEVICE_ID,
+ REG_TOTAL_NUM, buf);
if ((buf[MAX14656_STATUS_1] & STATUS1_VB_VALID_MASK) &&
(buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK)) {
diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c
index 8a1f0ee493aa..48aa44665e2f 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -126,7 +126,7 @@ static void max17040_get_vcell(struct i2c_client *client)
vcell = max17040_read_reg(client, MAX17040_VCELL);
- chip->vcell = vcell;
+ chip->vcell = (vcell >> 4) * 1250;
}
static void max17040_get_soc(struct i2c_client *client)
diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c
index 69ec4295d55d..f284547913d6 100644
--- a/drivers/power/supply/max17042_battery.c
+++ b/drivers/power/supply/max17042_battery.c
@@ -87,6 +87,7 @@ static enum power_supply_property max17042_battery_props[] = {
POWER_SUPPLY_PROP_SCOPE,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
};
static int max17042_get_temperature(struct max17042_chip *chip, int *temp)
@@ -411,6 +412,13 @@ static int max17042_get_property(struct power_supply *psy,
return -EINVAL;
}
break;
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+ ret = regmap_read(map, MAX17042_TTE, &data);
+ if (ret < 0)
+ return ret;
+
+ val->intval = data * 5625 / 1000;
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/power/supply/olpc_battery.c b/drivers/power/supply/olpc_battery.c
index ad0e9e0edb3f..e0476ec06601 100644
--- a/drivers/power/supply/olpc_battery.c
+++ b/drivers/power/supply/olpc_battery.c
@@ -88,7 +88,7 @@ static enum power_supply_property olpc_ac_props[] = {
};
static const struct power_supply_desc olpc_ac_desc = {
- .name = "olpc-ac",
+ .name = "olpc_ac",
.type = POWER_SUPPLY_TYPE_MAINS,
.properties = olpc_ac_props,
.num_properties = ARRAY_SIZE(olpc_ac_props),
@@ -605,7 +605,7 @@ static const struct attribute_group *olpc_bat_sysfs_groups[] = {
*********************************************************************/
static struct power_supply_desc olpc_bat_desc = {
- .name = "olpc-battery",
+ .name = "olpc_battery",
.get_property = olpc_bat_get_property,
.use_for_apm = 1,
};
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index 1a9a9fae73d3..02b37fe6061c 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -620,10 +620,18 @@ int power_supply_get_battery_info(struct power_supply *psy,
&info->voltage_min_design_uv);
of_property_read_u32(battery_np, "voltage-max-design-microvolt",
&info->voltage_max_design_uv);
+ of_property_read_u32(battery_np, "trickle-charge-current-microamp",
+ &info->tricklecharge_current_ua);
of_property_read_u32(battery_np, "precharge-current-microamp",
&info->precharge_current_ua);
+ of_property_read_u32(battery_np, "precharge-upper-limit-microvolt",
+ &info->precharge_voltage_max_uv);
of_property_read_u32(battery_np, "charge-term-current-microamp",
&info->charge_term_current_ua);
+ of_property_read_u32(battery_np, "re-charge-voltage-microvolt",
+ &info->charge_restart_voltage_uv);
+ of_property_read_u32(battery_np, "over-voltage-threshold-microvolt",
+ &info->overvoltage_limit_uv);
of_property_read_u32(battery_np, "constant-charge-current-max-microamp",
&info->constant_charge_current_max_ua);
of_property_read_u32(battery_np, "constant-charge-voltage-max-microvolt",
diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c
index 75cf861ba492..7fe4b6b6ddc8 100644
--- a/drivers/power/supply/power_supply_hwmon.c
+++ b/drivers/power/supply/power_supply_hwmon.c
@@ -13,6 +13,11 @@ struct power_supply_hwmon {
unsigned long *props;
};
+static const char *const ps_temp_label[] = {
+ "temp",
+ "ambient temp",
+};
+
static int power_supply_hwmon_in_to_property(u32 attr)
{
switch (attr) {
@@ -98,6 +103,39 @@ static bool power_supply_hwmon_is_a_label(enum hwmon_sensor_types type,
return type == hwmon_temp && attr == hwmon_temp_label;
}
+struct hwmon_type_attr_list {
+ const u32 *attrs;
+ size_t n_attrs;
+};
+
+static const u32 ps_temp_attrs[] = {
+ hwmon_temp_input,
+ hwmon_temp_min, hwmon_temp_max,
+ hwmon_temp_min_alarm, hwmon_temp_max_alarm,
+};
+
+static const struct hwmon_type_attr_list ps_type_attrs[hwmon_max] = {
+ [hwmon_temp] = { ps_temp_attrs, ARRAY_SIZE(ps_temp_attrs) },
+};
+
+static bool power_supply_hwmon_has_input(
+ const struct power_supply_hwmon *psyhw,
+ enum hwmon_sensor_types type, int channel)
+{
+ const struct hwmon_type_attr_list *attr_list = &ps_type_attrs[type];
+ size_t i;
+
+ for (i = 0; i < attr_list->n_attrs; ++i) {
+ int prop = power_supply_hwmon_to_property(type,
+ attr_list->attrs[i], channel);
+
+ if (prop >= 0 && test_bit(prop, psyhw->props))
+ return true;
+ }
+
+ return false;
+}
+
static bool power_supply_hwmon_is_writable(enum hwmon_sensor_types type,
u32 attr)
{
@@ -124,9 +162,12 @@ static umode_t power_supply_hwmon_is_visible(const void *data,
const struct power_supply_hwmon *psyhw = data;
int prop;
-
- if (power_supply_hwmon_is_a_label(type, attr))
- return 0444;
+ if (power_supply_hwmon_is_a_label(type, attr)) {
+ if (power_supply_hwmon_has_input(psyhw, type, channel))
+ return 0444;
+ else
+ return 0;
+ }
prop = power_supply_hwmon_to_property(type, attr, channel);
if (prop < 0 || !test_bit(prop, psyhw->props))
@@ -144,7 +185,20 @@ static int power_supply_hwmon_read_string(struct device *dev,
u32 attr, int channel,
const char **str)
{
- *str = channel ? "temp" : "temp ambient";
+ switch (type) {
+ case hwmon_temp:
+ *str = ps_temp_label[channel];
+ break;
+ default:
+ /* unreachable, but see:
+ * gcc bug #51513 [1] and clang bug #978 [2]
+ *
+ * [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51513
+ * [2] https://github.com/ClangBuiltLinux/linux/issues/978
+ */
+ break;
+ }
+
return 0;
}
@@ -304,7 +358,7 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy)
goto error;
}
- ret = devm_add_action(dev, power_supply_hwmon_bitmap_free,
+ ret = devm_add_action_or_reset(dev, power_supply_hwmon_bitmap_free,
psyhw->props);
if (ret)
goto error;
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index f37ad4eae60b..bc79560229b5 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -18,68 +18,211 @@
#include "power_supply.h"
-/*
- * This is because the name "current" breaks the device attr macro.
- * The "current" word resolves to "(get_current())" so instead of
- * "current" "(get_current())" appears in the sysfs.
- *
- * The source of this definition is the device.h which calls __ATTR
- * macro in sysfs.h which calls the __stringify macro.
- *
- * Only modification that the name is not tried to be resolved
- * (as a macro let's say).
- */
+#define MAX_PROP_NAME_LEN 30
+
+struct power_supply_attr {
+ const char *prop_name;
+ char attr_name[MAX_PROP_NAME_LEN + 1];
+ struct device_attribute dev_attr;
+ const char * const *text_values;
+ int text_values_len;
+};
-#define POWER_SUPPLY_ATTR(_name) \
-{ \
- .attr = { .name = #_name }, \
- .show = power_supply_show_property, \
- .store = power_supply_store_property, \
+#define _POWER_SUPPLY_ATTR(_name, _text, _len) \
+[POWER_SUPPLY_PROP_ ## _name] = \
+{ \
+ .prop_name = #_name, \
+ .attr_name = #_name "\0", \
+ .text_values = _text, \
+ .text_values_len = _len, \
}
-static struct device_attribute power_supply_attrs[];
+#define POWER_SUPPLY_ATTR(_name) _POWER_SUPPLY_ATTR(_name, NULL, 0)
+#define _POWER_SUPPLY_ENUM_ATTR(_name, _text) \
+ _POWER_SUPPLY_ATTR(_name, _text, ARRAY_SIZE(_text))
+#define POWER_SUPPLY_ENUM_ATTR(_name) \
+ _POWER_SUPPLY_ENUM_ATTR(_name, POWER_SUPPLY_ ## _name ## _TEXT)
+
+static const char * const POWER_SUPPLY_TYPE_TEXT[] = {
+ [POWER_SUPPLY_TYPE_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_TYPE_BATTERY] = "Battery",
+ [POWER_SUPPLY_TYPE_UPS] = "UPS",
+ [POWER_SUPPLY_TYPE_MAINS] = "Mains",
+ [POWER_SUPPLY_TYPE_USB] = "USB",
+ [POWER_SUPPLY_TYPE_USB_DCP] = "USB_DCP",
+ [POWER_SUPPLY_TYPE_USB_CDP] = "USB_CDP",
+ [POWER_SUPPLY_TYPE_USB_ACA] = "USB_ACA",
+ [POWER_SUPPLY_TYPE_USB_TYPE_C] = "USB_C",
+ [POWER_SUPPLY_TYPE_USB_PD] = "USB_PD",
+ [POWER_SUPPLY_TYPE_USB_PD_DRP] = "USB_PD_DRP",
+ [POWER_SUPPLY_TYPE_APPLE_BRICK_ID] = "BrickID",
+};
-static const char * const power_supply_type_text[] = {
- "Unknown", "Battery", "UPS", "Mains", "USB",
- "USB_DCP", "USB_CDP", "USB_ACA", "USB_C",
- "USB_PD", "USB_PD_DRP", "BrickID"
+static const char * const POWER_SUPPLY_USB_TYPE_TEXT[] = {
+ [POWER_SUPPLY_USB_TYPE_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_USB_TYPE_SDP] = "SDP",
+ [POWER_SUPPLY_USB_TYPE_DCP] = "DCP",
+ [POWER_SUPPLY_USB_TYPE_CDP] = "CDP",
+ [POWER_SUPPLY_USB_TYPE_ACA] = "ACA",
+ [POWER_SUPPLY_USB_TYPE_C] = "C",
+ [POWER_SUPPLY_USB_TYPE_PD] = "PD",
+ [POWER_SUPPLY_USB_TYPE_PD_DRP] = "PD_DRP",
+ [POWER_SUPPLY_USB_TYPE_PD_PPS] = "PD_PPS",
+ [POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID] = "BrickID",
};
-static const char * const power_supply_usb_type_text[] = {
- "Unknown", "SDP", "DCP", "CDP", "ACA", "C",
- "PD", "PD_DRP", "PD_PPS", "BrickID"
+static const char * const POWER_SUPPLY_STATUS_TEXT[] = {
+ [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_STATUS_CHARGING] = "Charging",
+ [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
+ [POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not charging",
+ [POWER_SUPPLY_STATUS_FULL] = "Full",
};
-static const char * const power_supply_status_text[] = {
- "Unknown", "Charging", "Discharging", "Not charging", "Full"
+static const char * const POWER_SUPPLY_CHARGE_TYPE_TEXT[] = {
+ [POWER_SUPPLY_CHARGE_TYPE_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_CHARGE_TYPE_NONE] = "N/A",
+ [POWER_SUPPLY_CHARGE_TYPE_TRICKLE] = "Trickle",
+ [POWER_SUPPLY_CHARGE_TYPE_FAST] = "Fast",
+ [POWER_SUPPLY_CHARGE_TYPE_STANDARD] = "Standard",
+ [POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE] = "Adaptive",
+ [POWER_SUPPLY_CHARGE_TYPE_CUSTOM] = "Custom",
};
-static const char * const power_supply_charge_type_text[] = {
- "Unknown", "N/A", "Trickle", "Fast", "Standard", "Adaptive", "Custom"
+static const char * const POWER_SUPPLY_HEALTH_TEXT[] = {
+ [POWER_SUPPLY_HEALTH_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_HEALTH_GOOD] = "Good",
+ [POWER_SUPPLY_HEALTH_OVERHEAT] = "Overheat",
+ [POWER_SUPPLY_HEALTH_DEAD] = "Dead",
+ [POWER_SUPPLY_HEALTH_OVERVOLTAGE] = "Over voltage",
+ [POWER_SUPPLY_HEALTH_UNSPEC_FAILURE] = "Unspecified failure",
+ [POWER_SUPPLY_HEALTH_COLD] = "Cold",
+ [POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE] = "Watchdog timer expire",
+ [POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE] = "Safety timer expire",
+ [POWER_SUPPLY_HEALTH_OVERCURRENT] = "Over current",
+ [POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED] = "Calibration required",
};
-static const char * const power_supply_health_text[] = {
- "Unknown", "Good", "Overheat", "Dead", "Over voltage",
- "Unspecified failure", "Cold", "Watchdog timer expire",
- "Safety timer expire", "Over current"
+static const char * const POWER_SUPPLY_TECHNOLOGY_TEXT[] = {
+ [POWER_SUPPLY_TECHNOLOGY_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_TECHNOLOGY_NiMH] = "NiMH",
+ [POWER_SUPPLY_TECHNOLOGY_LION] = "Li-ion",
+ [POWER_SUPPLY_TECHNOLOGY_LIPO] = "Li-poly",
+ [POWER_SUPPLY_TECHNOLOGY_LiFe] = "LiFe",
+ [POWER_SUPPLY_TECHNOLOGY_NiCd] = "NiCd",
+ [POWER_SUPPLY_TECHNOLOGY_LiMn] = "LiMn",
};
-static const char * const power_supply_technology_text[] = {
- "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd",
- "LiMn"
+static const char * const POWER_SUPPLY_CAPACITY_LEVEL_TEXT[] = {
+ [POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL] = "Critical",
+ [POWER_SUPPLY_CAPACITY_LEVEL_LOW] = "Low",
+ [POWER_SUPPLY_CAPACITY_LEVEL_NORMAL] = "Normal",
+ [POWER_SUPPLY_CAPACITY_LEVEL_HIGH] = "High",
+ [POWER_SUPPLY_CAPACITY_LEVEL_FULL] = "Full",
};
-static const char * const power_supply_capacity_level_text[] = {
- "Unknown", "Critical", "Low", "Normal", "High", "Full"
+static const char * const POWER_SUPPLY_SCOPE_TEXT[] = {
+ [POWER_SUPPLY_SCOPE_UNKNOWN] = "Unknown",
+ [POWER_SUPPLY_SCOPE_SYSTEM] = "System",
+ [POWER_SUPPLY_SCOPE_DEVICE] = "Device",
};
-static const char * const power_supply_scope_text[] = {
- "Unknown", "System", "Device"
+static struct power_supply_attr power_supply_attrs[] = {
+ /* Properties of type `int' */
+ POWER_SUPPLY_ENUM_ATTR(STATUS),
+ POWER_SUPPLY_ENUM_ATTR(CHARGE_TYPE),
+ POWER_SUPPLY_ENUM_ATTR(HEALTH),
+ POWER_SUPPLY_ATTR(PRESENT),
+ POWER_SUPPLY_ATTR(ONLINE),
+ POWER_SUPPLY_ATTR(AUTHENTIC),
+ POWER_SUPPLY_ENUM_ATTR(TECHNOLOGY),
+ POWER_SUPPLY_ATTR(CYCLE_COUNT),
+ POWER_SUPPLY_ATTR(VOLTAGE_MAX),
+ POWER_SUPPLY_ATTR(VOLTAGE_MIN),
+ POWER_SUPPLY_ATTR(VOLTAGE_MAX_DESIGN),
+ POWER_SUPPLY_ATTR(VOLTAGE_MIN_DESIGN),
+ POWER_SUPPLY_ATTR(VOLTAGE_NOW),
+ POWER_SUPPLY_ATTR(VOLTAGE_AVG),
+ POWER_SUPPLY_ATTR(VOLTAGE_OCV),
+ POWER_SUPPLY_ATTR(VOLTAGE_BOOT),
+ POWER_SUPPLY_ATTR(CURRENT_MAX),
+ POWER_SUPPLY_ATTR(CURRENT_NOW),
+ POWER_SUPPLY_ATTR(CURRENT_AVG),
+ POWER_SUPPLY_ATTR(CURRENT_BOOT),
+ POWER_SUPPLY_ATTR(POWER_NOW),
+ POWER_SUPPLY_ATTR(POWER_AVG),
+ POWER_SUPPLY_ATTR(CHARGE_FULL_DESIGN),
+ POWER_SUPPLY_ATTR(CHARGE_EMPTY_DESIGN),
+ POWER_SUPPLY_ATTR(CHARGE_FULL),
+ POWER_SUPPLY_ATTR(CHARGE_EMPTY),
+ POWER_SUPPLY_ATTR(CHARGE_NOW),
+ POWER_SUPPLY_ATTR(CHARGE_AVG),
+ POWER_SUPPLY_ATTR(CHARGE_COUNTER),
+ POWER_SUPPLY_ATTR(CONSTANT_CHARGE_CURRENT),
+ POWER_SUPPLY_ATTR(CONSTANT_CHARGE_CURRENT_MAX),
+ POWER_SUPPLY_ATTR(CONSTANT_CHARGE_VOLTAGE),
+ POWER_SUPPLY_ATTR(CONSTANT_CHARGE_VOLTAGE_MAX),
+ POWER_SUPPLY_ATTR(CHARGE_CONTROL_LIMIT),
+ POWER_SUPPLY_ATTR(CHARGE_CONTROL_LIMIT_MAX),
+ POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD),
+ POWER_SUPPLY_ATTR(CHARGE_CONTROL_END_THRESHOLD),
+ POWER_SUPPLY_ATTR(INPUT_CURRENT_LIMIT),
+ POWER_SUPPLY_ATTR(INPUT_VOLTAGE_LIMIT),
+ POWER_SUPPLY_ATTR(INPUT_POWER_LIMIT),
+ POWER_SUPPLY_ATTR(ENERGY_FULL_DESIGN),
+ POWER_SUPPLY_ATTR(ENERGY_EMPTY_DESIGN),
+ POWER_SUPPLY_ATTR(ENERGY_FULL),
+ POWER_SUPPLY_ATTR(ENERGY_EMPTY),
+ POWER_SUPPLY_ATTR(ENERGY_NOW),
+ POWER_SUPPLY_ATTR(ENERGY_AVG),
+ POWER_SUPPLY_ATTR(CAPACITY),
+ POWER_SUPPLY_ATTR(CAPACITY_ALERT_MIN),
+ POWER_SUPPLY_ATTR(CAPACITY_ALERT_MAX),
+ POWER_SUPPLY_ATTR(CAPACITY_ERROR_MARGIN),
+ POWER_SUPPLY_ENUM_ATTR(CAPACITY_LEVEL),
+ POWER_SUPPLY_ATTR(TEMP),
+ POWER_SUPPLY_ATTR(TEMP_MAX),
+ POWER_SUPPLY_ATTR(TEMP_MIN),
+ POWER_SUPPLY_ATTR(TEMP_ALERT_MIN),
+ POWER_SUPPLY_ATTR(TEMP_ALERT_MAX),
+ POWER_SUPPLY_ATTR(TEMP_AMBIENT),
+ POWER_SUPPLY_ATTR(TEMP_AMBIENT_ALERT_MIN),
+ POWER_SUPPLY_ATTR(TEMP_AMBIENT_ALERT_MAX),
+ POWER_SUPPLY_ATTR(TIME_TO_EMPTY_NOW),
+ POWER_SUPPLY_ATTR(TIME_TO_EMPTY_AVG),
+ POWER_SUPPLY_ATTR(TIME_TO_FULL_NOW),
+ POWER_SUPPLY_ATTR(TIME_TO_FULL_AVG),
+ POWER_SUPPLY_ENUM_ATTR(TYPE),
+ POWER_SUPPLY_ATTR(USB_TYPE),
+ POWER_SUPPLY_ENUM_ATTR(SCOPE),
+ POWER_SUPPLY_ATTR(PRECHARGE_CURRENT),
+ POWER_SUPPLY_ATTR(CHARGE_TERM_CURRENT),
+ POWER_SUPPLY_ATTR(CALIBRATE),
+ POWER_SUPPLY_ATTR(MANUFACTURE_YEAR),
+ POWER_SUPPLY_ATTR(MANUFACTURE_MONTH),
+ POWER_SUPPLY_ATTR(MANUFACTURE_DAY),
+ /* Properties of type `const char *' */
+ POWER_SUPPLY_ATTR(MODEL_NAME),
+ POWER_SUPPLY_ATTR(MANUFACTURER),
+ POWER_SUPPLY_ATTR(SERIAL_NUMBER),
};
+static struct attribute *
+__power_supply_attrs[ARRAY_SIZE(power_supply_attrs) + 1];
+
+static struct power_supply_attr *to_ps_attr(struct device_attribute *attr)
+{
+ return container_of(attr, struct power_supply_attr, dev_attr);
+}
+
+static enum power_supply_property dev_attr_psp(struct device_attribute *attr)
+{
+ return to_ps_attr(attr) - power_supply_attrs;
+}
+
static ssize_t power_supply_show_usb_type(struct device *dev,
- enum power_supply_usb_type *usb_types,
- ssize_t num_usb_types,
+ const struct power_supply_desc *desc,
union power_supply_propval *value,
char *buf)
{
@@ -88,16 +231,16 @@ static ssize_t power_supply_show_usb_type(struct device *dev,
bool match = false;
int i;
- for (i = 0; i < num_usb_types; ++i) {
- usb_type = usb_types[i];
+ for (i = 0; i < desc->num_usb_types; ++i) {
+ usb_type = desc->usb_types[i];
if (value->intval == usb_type) {
count += sprintf(buf + count, "[%s] ",
- power_supply_usb_type_text[usb_type]);
+ POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
match = true;
} else {
count += sprintf(buf + count, "%s ",
- power_supply_usb_type_text[usb_type]);
+ POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
}
}
@@ -117,7 +260,8 @@ static ssize_t power_supply_show_property(struct device *dev,
char *buf) {
ssize_t ret;
struct power_supply *psy = dev_get_drvdata(dev);
- enum power_supply_property psp = attr - power_supply_attrs;
+ struct power_supply_attr *ps_attr = to_ps_attr(attr);
+ enum power_supply_property psp = dev_attr_psp(attr);
union power_supply_propval value;
if (psp == POWER_SUPPLY_PROP_TYPE) {
@@ -137,39 +281,15 @@ static ssize_t power_supply_show_property(struct device *dev,
}
}
+ if (ps_attr->text_values_len > 0 &&
+ value.intval < ps_attr->text_values_len && value.intval >= 0) {
+ return sprintf(buf, "%s\n", ps_attr->text_values[value.intval]);
+ }
+
switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- ret = sprintf(buf, "%s\n",
- power_supply_status_text[value.intval]);
- break;
- case POWER_SUPPLY_PROP_CHARGE_TYPE:
- ret = sprintf(buf, "%s\n",
- power_supply_charge_type_text[value.intval]);
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- ret = sprintf(buf, "%s\n",
- power_supply_health_text[value.intval]);
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- ret = sprintf(buf, "%s\n",
- power_supply_technology_text[value.intval]);
- break;
- case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
- ret = sprintf(buf, "%s\n",
- power_supply_capacity_level_text[value.intval]);
- break;
- case POWER_SUPPLY_PROP_TYPE:
- ret = sprintf(buf, "%s\n",
- power_supply_type_text[value.intval]);
- break;
case POWER_SUPPLY_PROP_USB_TYPE:
- ret = power_supply_show_usb_type(dev, psy->desc->usb_types,
- psy->desc->num_usb_types,
- &value, buf);
- break;
- case POWER_SUPPLY_PROP_SCOPE:
- ret = sprintf(buf, "%s\n",
- power_supply_scope_text[value.intval]);
+ ret = power_supply_show_usb_type(dev, psy->desc,
+ &value, buf);
break;
case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
ret = sprintf(buf, "%s\n", value.strval);
@@ -186,30 +306,14 @@ static ssize_t power_supply_store_property(struct device *dev,
const char *buf, size_t count) {
ssize_t ret;
struct power_supply *psy = dev_get_drvdata(dev);
- enum power_supply_property psp = attr - power_supply_attrs;
+ struct power_supply_attr *ps_attr = to_ps_attr(attr);
+ enum power_supply_property psp = dev_attr_psp(attr);
union power_supply_propval value;
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- ret = sysfs_match_string(power_supply_status_text, buf);
- break;
- case POWER_SUPPLY_PROP_CHARGE_TYPE:
- ret = sysfs_match_string(power_supply_charge_type_text, buf);
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- ret = sysfs_match_string(power_supply_health_text, buf);
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- ret = sysfs_match_string(power_supply_technology_text, buf);
- break;
- case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
- ret = sysfs_match_string(power_supply_capacity_level_text, buf);
- break;
- case POWER_SUPPLY_PROP_SCOPE:
- ret = sysfs_match_string(power_supply_scope_text, buf);
- break;
- default:
- ret = -EINVAL;
+ ret = -EINVAL;
+ if (ps_attr->text_values_len > 0) {
+ ret = __sysfs_match_string(ps_attr->text_values,
+ ps_attr->text_values_len, buf);
}
/*
@@ -235,86 +339,6 @@ static ssize_t power_supply_store_property(struct device *dev,
return count;
}
-/* Must be in the same order as POWER_SUPPLY_PROP_* */
-static struct device_attribute power_supply_attrs[] = {
- /* Properties of type `int' */
- POWER_SUPPLY_ATTR(status),
- POWER_SUPPLY_ATTR(charge_type),
- POWER_SUPPLY_ATTR(health),
- POWER_SUPPLY_ATTR(present),
- POWER_SUPPLY_ATTR(online),
- POWER_SUPPLY_ATTR(authentic),
- POWER_SUPPLY_ATTR(technology),
- POWER_SUPPLY_ATTR(cycle_count),
- POWER_SUPPLY_ATTR(voltage_max),
- POWER_SUPPLY_ATTR(voltage_min),
- POWER_SUPPLY_ATTR(voltage_max_design),
- POWER_SUPPLY_ATTR(voltage_min_design),
- POWER_SUPPLY_ATTR(voltage_now),
- POWER_SUPPLY_ATTR(voltage_avg),
- POWER_SUPPLY_ATTR(voltage_ocv),
- POWER_SUPPLY_ATTR(voltage_boot),
- POWER_SUPPLY_ATTR(current_max),
- POWER_SUPPLY_ATTR(current_now),
- POWER_SUPPLY_ATTR(current_avg),
- POWER_SUPPLY_ATTR(current_boot),
- POWER_SUPPLY_ATTR(power_now),
- POWER_SUPPLY_ATTR(power_avg),
- POWER_SUPPLY_ATTR(charge_full_design),
- POWER_SUPPLY_ATTR(charge_empty_design),
- POWER_SUPPLY_ATTR(charge_full),
- POWER_SUPPLY_ATTR(charge_empty),
- POWER_SUPPLY_ATTR(charge_now),
- POWER_SUPPLY_ATTR(charge_avg),
- POWER_SUPPLY_ATTR(charge_counter),
- POWER_SUPPLY_ATTR(constant_charge_current),
- POWER_SUPPLY_ATTR(constant_charge_current_max),
- POWER_SUPPLY_ATTR(constant_charge_voltage),
- POWER_SUPPLY_ATTR(constant_charge_voltage_max),
- POWER_SUPPLY_ATTR(charge_control_limit),
- POWER_SUPPLY_ATTR(charge_control_limit_max),
- POWER_SUPPLY_ATTR(charge_control_start_threshold),
- POWER_SUPPLY_ATTR(charge_control_end_threshold),
- POWER_SUPPLY_ATTR(input_current_limit),
- POWER_SUPPLY_ATTR(input_voltage_limit),
- POWER_SUPPLY_ATTR(input_power_limit),
- POWER_SUPPLY_ATTR(energy_full_design),
- POWER_SUPPLY_ATTR(energy_empty_design),
- POWER_SUPPLY_ATTR(energy_full),
- POWER_SUPPLY_ATTR(energy_empty),
- POWER_SUPPLY_ATTR(energy_now),
- POWER_SUPPLY_ATTR(energy_avg),
- POWER_SUPPLY_ATTR(capacity),
- POWER_SUPPLY_ATTR(capacity_alert_min),
- POWER_SUPPLY_ATTR(capacity_alert_max),
- POWER_SUPPLY_ATTR(capacity_level),
- POWER_SUPPLY_ATTR(temp),
- POWER_SUPPLY_ATTR(temp_max),
- POWER_SUPPLY_ATTR(temp_min),
- POWER_SUPPLY_ATTR(temp_alert_min),
- POWER_SUPPLY_ATTR(temp_alert_max),
- POWER_SUPPLY_ATTR(temp_ambient),
- POWER_SUPPLY_ATTR(temp_ambient_alert_min),
- POWER_SUPPLY_ATTR(temp_ambient_alert_max),
- POWER_SUPPLY_ATTR(time_to_empty_now),
- POWER_SUPPLY_ATTR(time_to_empty_avg),
- POWER_SUPPLY_ATTR(time_to_full_now),
- POWER_SUPPLY_ATTR(time_to_full_avg),
- POWER_SUPPLY_ATTR(type),
- POWER_SUPPLY_ATTR(usb_type),
- POWER_SUPPLY_ATTR(scope),
- POWER_SUPPLY_ATTR(precharge_current),
- POWER_SUPPLY_ATTR(charge_term_current),
- POWER_SUPPLY_ATTR(calibrate),
- /* Properties of type `const char *' */
- POWER_SUPPLY_ATTR(model_name),
- POWER_SUPPLY_ATTR(manufacturer),
- POWER_SUPPLY_ATTR(serial_number),
-};
-
-static struct attribute *
-__power_supply_attrs[ARRAY_SIZE(power_supply_attrs) + 1];
-
static umode_t power_supply_attr_is_visible(struct kobject *kobj,
struct attribute *attr,
int attrno)
@@ -324,6 +348,9 @@ static umode_t power_supply_attr_is_visible(struct kobject *kobj,
umode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
int i;
+ if (!power_supply_attrs[attrno].prop_name)
+ return 0;
+
if (attrno == POWER_SUPPLY_PROP_TYPE)
return mode;
@@ -352,31 +379,69 @@ static const struct attribute_group *power_supply_attr_groups[] = {
NULL,
};
+static void str_to_lower(char *str)
+{
+ while (*str) {
+ *str = tolower(*str);
+ str++;
+ }
+}
+
void power_supply_init_attrs(struct device_type *dev_type)
{
int i;
dev_type->groups = power_supply_attr_groups;
- for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++)
- __power_supply_attrs[i] = &power_supply_attrs[i].attr;
-}
+ for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++) {
+ struct device_attribute *attr;
-static char *kstruprdup(const char *str, gfp_t gfp)
-{
- char *ret, *ustr;
+ if (!power_supply_attrs[i].prop_name) {
+ pr_warn("%s: Property %d skipped because is is missing from power_supply_attrs\n",
+ __func__, i);
+ sprintf(power_supply_attrs[i].attr_name, "_err_%d", i);
+ } else {
+ str_to_lower(power_supply_attrs[i].attr_name);
+ }
- ustr = ret = kmalloc(strlen(str) + 1, gfp);
+ attr = &power_supply_attrs[i].dev_attr;
- if (!ret)
- return NULL;
+ attr->attr.name = power_supply_attrs[i].attr_name;
+ attr->show = power_supply_show_property;
+ attr->store = power_supply_store_property;
+ __power_supply_attrs[i] = &attr->attr;
+ }
+}
+
+static int add_prop_uevent(struct device *dev, struct kobj_uevent_env *env,
+ enum power_supply_property prop, char *prop_buf)
+{
+ int ret = 0;
+ struct power_supply_attr *pwr_attr;
+ struct device_attribute *dev_attr;
+ char *line;
+
+ pwr_attr = &power_supply_attrs[prop];
+ dev_attr = &pwr_attr->dev_attr;
+
+ ret = power_supply_show_property(dev, dev_attr, prop_buf);
+ if (ret == -ENODEV || ret == -ENODATA) {
+ /*
+ * When a battery is absent, we expect -ENODEV. Don't abort;
+ * send the uevent with at least the the PRESENT=0 property
+ */
+ return 0;
+ }
- while (*str)
- *ustr++ = toupper(*str++);
+ if (ret < 0)
+ return ret;
- *ustr = 0;
+ line = strchr(prop_buf, '\n');
+ if (line)
+ *line = 0;
- return ret;
+ return add_uevent_var(env, "POWER_SUPPLY_%s=%s",
+ pwr_attr->prop_name, prop_buf);
}
int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -384,7 +449,6 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
struct power_supply *psy = dev_get_drvdata(dev);
int ret = 0, j;
char *prop_buf;
- char *attrname;
if (!psy || !psy->desc) {
dev_dbg(dev, "No power supply yet\n");
@@ -399,35 +463,13 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
if (!prop_buf)
return -ENOMEM;
- for (j = 0; j < psy->desc->num_properties; j++) {
- struct device_attribute *attr;
- char *line;
-
- attr = &power_supply_attrs[psy->desc->properties[j]];
-
- ret = power_supply_show_property(dev, attr, prop_buf);
- if (ret == -ENODEV || ret == -ENODATA) {
- /* When a battery is absent, we expect -ENODEV. Don't abort;
- send the uevent with at least the the PRESENT=0 property */
- ret = 0;
- continue;
- }
-
- if (ret < 0)
- goto out;
-
- line = strchr(prop_buf, '\n');
- if (line)
- *line = 0;
-
- attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
- if (!attrname) {
- ret = -ENOMEM;
- goto out;
- }
+ ret = add_prop_uevent(dev, env, POWER_SUPPLY_PROP_TYPE, prop_buf);
+ if (ret)
+ goto out;
- ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
- kfree(attrname);
+ for (j = 0; j < psy->desc->num_properties; j++) {
+ ret = add_prop_uevent(dev, env, psy->desc->properties[j],
+ prop_buf);
if (ret)
goto out;
}
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
index 6acd242eed48..83b9924033bd 100644
--- a/drivers/power/supply/sbs-battery.c
+++ b/drivers/power/supply/sbs-battery.c
@@ -14,7 +14,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
#include <linux/of_device.h>
#include <linux/power/sbs-battery.h>
#include <linux/power_supply.h>
@@ -23,9 +23,12 @@
enum {
REG_MANUFACTURER_DATA,
+ REG_BATTERY_MODE,
REG_TEMPERATURE,
REG_VOLTAGE,
- REG_CURRENT,
+ REG_CURRENT_NOW,
+ REG_CURRENT_AVG,
+ REG_MAX_ERR,
REG_CAPACITY,
REG_TIME_TO_EMPTY,
REG_TIME_TO_FULL,
@@ -41,10 +44,15 @@ enum {
REG_DESIGN_CAPACITY_CHARGE,
REG_DESIGN_VOLTAGE_MIN,
REG_DESIGN_VOLTAGE_MAX,
+ REG_CHEMISTRY,
REG_MANUFACTURER,
REG_MODEL_NAME,
+ REG_CHARGE_CURRENT,
+ REG_CHARGE_VOLTAGE,
};
+#define REG_ADDR_MANUFACTURE_DATE 0x1B
+
/* Battery Mode defines */
#define BATTERY_MODE_OFFSET 0x03
#define BATTERY_MODE_CAPACITY_MASK BIT(15)
@@ -52,6 +60,7 @@ enum sbs_capacity_mode {
CAPACITY_MODE_AMPS = 0,
CAPACITY_MODE_WATTS = BATTERY_MODE_CAPACITY_MASK
};
+#define BATTERY_MODE_CHARGER_MASK (1<<14)
/* manufacturer access defines */
#define MANUFACTURER_ACCESS_STATUS 0x0006
@@ -79,12 +88,18 @@ static const struct chip_data {
} sbs_data[] = {
[REG_MANUFACTURER_DATA] =
SBS_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
+ [REG_BATTERY_MODE] =
+ SBS_DATA(-1, 0x03, 0, 65535),
[REG_TEMPERATURE] =
SBS_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
[REG_VOLTAGE] =
SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
- [REG_CURRENT] =
+ [REG_CURRENT_NOW] =
SBS_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 32767),
+ [REG_CURRENT_AVG] =
+ SBS_DATA(POWER_SUPPLY_PROP_CURRENT_AVG, 0x0B, -32768, 32767),
+ [REG_MAX_ERR] =
+ SBS_DATA(POWER_SUPPLY_PROP_CAPACITY_ERROR_MARGIN, 0x0c, 0, 100),
[REG_CAPACITY] =
SBS_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0D, 0, 100),
[REG_REMAINING_CAPACITY] =
@@ -99,6 +114,10 @@ static const struct chip_data {
SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 65535),
[REG_TIME_TO_FULL] =
SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 65535),
+ [REG_CHARGE_CURRENT] =
+ SBS_DATA(POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 0x14, 0, 65535),
+ [REG_CHARGE_VOLTAGE] =
+ SBS_DATA(POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 0x15, 0, 65535),
[REG_STATUS] =
SBS_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
[REG_CAPACITY_LEVEL] =
@@ -119,10 +138,12 @@ static const struct chip_data {
[REG_MANUFACTURER] =
SBS_DATA(POWER_SUPPLY_PROP_MANUFACTURER, 0x20, 0, 65535),
[REG_MODEL_NAME] =
- SBS_DATA(POWER_SUPPLY_PROP_MODEL_NAME, 0x21, 0, 65535)
+ SBS_DATA(POWER_SUPPLY_PROP_MODEL_NAME, 0x21, 0, 65535),
+ [REG_CHEMISTRY] =
+ SBS_DATA(POWER_SUPPLY_PROP_TECHNOLOGY, 0x22, 0, 65535)
};
-static enum power_supply_property sbs_properties[] = {
+static const enum power_supply_property sbs_properties[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_HEALTH,
@@ -131,7 +152,9 @@ static enum power_supply_property sbs_properties[] = {
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CAPACITY_ERROR_MARGIN,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
@@ -144,13 +167,18 @@ static enum power_supply_property sbs_properties[] = {
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_MANUFACTURE_YEAR,
+ POWER_SUPPLY_PROP_MANUFACTURE_MONTH,
+ POWER_SUPPLY_PROP_MANUFACTURE_DAY,
/* Properties of type `const char *' */
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_MODEL_NAME
};
-/* Supports special manufacturer commands from TI BQ20Z75 IC. */
-#define SBS_FLAGS_TI_BQ20Z75 BIT(0)
+/* Supports special manufacturer commands from TI BQ20Z65 and BQ20Z75 IC. */
+#define SBS_FLAGS_TI_BQ20ZX5 BIT(0)
struct sbs_info {
struct i2c_client *client;
@@ -158,6 +186,7 @@ struct sbs_info {
bool is_present;
struct gpio_desc *gpio_detect;
bool enable_detection;
+ bool charger_broadcasts;
int last_state;
int poll_time;
u32 i2c_retry_count;
@@ -169,8 +198,48 @@ struct sbs_info {
static char model_name[I2C_SMBUS_BLOCK_MAX + 1];
static char manufacturer[I2C_SMBUS_BLOCK_MAX + 1];
+static char chemistry[I2C_SMBUS_BLOCK_MAX + 1];
static bool force_load;
+static int sbs_read_word_data(struct i2c_client *client, u8 address);
+static int sbs_write_word_data(struct i2c_client *client, u8 address, u16 value);
+
+static void sbs_disable_charger_broadcasts(struct sbs_info *chip)
+{
+ int val = sbs_read_word_data(chip->client, BATTERY_MODE_OFFSET);
+ if (val < 0)
+ goto exit;
+
+ val |= BATTERY_MODE_CHARGER_MASK;
+
+ val = sbs_write_word_data(chip->client, BATTERY_MODE_OFFSET, val);
+
+exit:
+ if (val < 0)
+ dev_err(&chip->client->dev,
+ "Failed to disable charger broadcasting: %d\n", val);
+ else
+ dev_dbg(&chip->client->dev, "%s\n", __func__);
+}
+
+static int sbs_update_presence(struct sbs_info *chip, bool is_present)
+{
+ if (chip->is_present == is_present)
+ return 0;
+
+ if (!is_present) {
+ chip->is_present = false;
+ return 0;
+ }
+
+ if (!chip->is_present && is_present && !chip->charger_broadcasts)
+ sbs_disable_charger_broadcasts(chip);
+
+ chip->is_present = true;
+
+ return 0;
+}
+
static int sbs_read_word_data(struct i2c_client *client, u8 address)
{
struct sbs_info *chip = i2c_get_clientdata(client);
@@ -288,15 +357,15 @@ static int sbs_status_correct(struct i2c_client *client, int *intval)
{
int ret;
- ret = sbs_read_word_data(client, sbs_data[REG_CURRENT].addr);
+ ret = sbs_read_word_data(client, sbs_data[REG_CURRENT_NOW].addr);
if (ret < 0)
return ret;
ret = (s16)ret;
- /* Not drawing current means full (cannot be not charging) */
- if (ret == 0)
- *intval = POWER_SUPPLY_STATUS_FULL;
+ /* Not drawing current -> not charging (i.e. idle) */
+ if (*intval != POWER_SUPPLY_STATUS_FULL && ret == 0)
+ *intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
if (*intval == POWER_SUPPLY_STATUS_FULL) {
/* Drawing or providing current when full */
@@ -309,6 +378,17 @@ static int sbs_status_correct(struct i2c_client *client, int *intval)
return 0;
}
+static bool sbs_bat_needs_calibration(struct i2c_client *client)
+{
+ int ret;
+
+ ret = sbs_read_word_data(client, sbs_data[REG_BATTERY_MODE].addr);
+ if (ret < 0)
+ return false;
+
+ return !!(ret & BIT(7));
+}
+
static int sbs_get_battery_presence_and_health(
struct i2c_client *client, enum power_supply_property psp,
union power_supply_propval *val)
@@ -328,9 +408,14 @@ static int sbs_get_battery_presence_and_health(
if (psp == POWER_SUPPLY_PROP_PRESENT)
val->intval = 1; /* battery present */
- else /* POWER_SUPPLY_PROP_HEALTH */
- /* SBS spec doesn't have a general health command. */
- val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+ else { /* POWER_SUPPLY_PROP_HEALTH */
+ if (sbs_bat_needs_calibration(client)) {
+ val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
+ } else {
+ /* SBS spec doesn't have a general health command. */
+ val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+ }
+ }
return 0;
}
@@ -384,6 +469,8 @@ static int sbs_get_ti_battery_presence_and_health(
val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
else if (ret == 0x0C)
val->intval = POWER_SUPPLY_HEALTH_DEAD;
+ else if (sbs_bat_needs_calibration(client))
+ val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
else
val->intval = POWER_SUPPLY_HEALTH_GOOD;
}
@@ -492,7 +579,10 @@ static void sbs_unit_adjustment(struct i2c_client *client,
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
case POWER_SUPPLY_PROP_CURRENT_NOW:
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
case POWER_SUPPLY_PROP_CHARGE_NOW:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
case POWER_SUPPLY_PROP_CHARGE_FULL:
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
val->intval *= BASE_UNIT_CONVERSION;
@@ -602,6 +692,70 @@ static int sbs_get_property_index(struct i2c_client *client,
return -EINVAL;
}
+static int sbs_get_chemistry(struct i2c_client *client,
+ union power_supply_propval *val)
+{
+ enum power_supply_property psp = POWER_SUPPLY_PROP_TECHNOLOGY;
+ int ret;
+
+ ret = sbs_get_property_index(client, psp);
+ if (ret < 0)
+ return ret;
+
+ ret = sbs_get_battery_string_property(client, ret, psp,
+ chemistry);
+ if (ret < 0)
+ return ret;
+
+ if (!strncasecmp(chemistry, "LION", 4))
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ else if (!strncasecmp(chemistry, "LiP", 3))
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
+ else if (!strncasecmp(chemistry, "NiCd", 4))
+ val->intval = POWER_SUPPLY_TECHNOLOGY_NiCd;
+ else if (!strncasecmp(chemistry, "NiMH", 4))
+ val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
+ else
+ val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+
+ if (val->intval == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)
+ dev_warn(&client->dev, "Unknown chemistry: %s\n", chemistry);
+
+ return 0;
+}
+
+static int sbs_get_battery_manufacture_date(struct i2c_client *client,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int ret;
+ u16 day, month, year;
+
+ ret = sbs_read_word_data(client, REG_ADDR_MANUFACTURE_DATE);
+ if (ret < 0)
+ return ret;
+
+ day = ret & GENMASK(4, 0);
+ month = (ret & GENMASK(8, 5)) >> 5;
+ year = ((ret & GENMASK(15, 9)) >> 9) + 1980;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
+ val->intval = year;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
+ val->intval = month;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
+ val->intval = day;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int sbs_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -616,7 +770,7 @@ static int sbs_get_property(struct power_supply *psy,
return ret;
if (psp == POWER_SUPPLY_PROP_PRESENT) {
val->intval = ret;
- chip->is_present = val->intval;
+ sbs_update_presence(chip, ret);
return 0;
}
if (ret == 0)
@@ -626,7 +780,7 @@ static int sbs_get_property(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_HEALTH:
- if (chip->flags & SBS_FLAGS_TI_BQ20Z75)
+ if (chip->flags & SBS_FLAGS_TI_BQ20ZX5)
ret = sbs_get_ti_battery_presence_and_health(client,
psp, val);
else
@@ -639,7 +793,10 @@ static int sbs_get_property(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ ret = sbs_get_chemistry(client, val);
+ if (ret < 0)
+ break;
+
goto done; /* don't trigger power_supply_changed()! */
case POWER_SUPPLY_PROP_ENERGY_NOW:
@@ -670,12 +827,16 @@ static int sbs_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CYCLE_COUNT:
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
case POWER_SUPPLY_PROP_CURRENT_NOW:
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
case POWER_SUPPLY_PROP_TEMP:
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
case POWER_SUPPLY_PROP_CAPACITY:
+ case POWER_SUPPLY_PROP_CAPACITY_ERROR_MARGIN:
ret = sbs_get_property_index(client, psp);
if (ret < 0)
break;
@@ -703,6 +864,12 @@ static int sbs_get_property(struct power_supply *psy,
val->strval = manufacturer;
break;
+ case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
+ case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
+ case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
+ ret = sbs_get_battery_manufacture_date(client, psp, val);
+ break;
+
default:
dev_err(&client->dev,
"%s: INVALID property\n", __func__);
@@ -714,7 +881,7 @@ static int sbs_get_property(struct power_supply *psy,
if (!chip->gpio_detect &&
chip->is_present != (ret >= 0)) {
- chip->is_present = (ret >= 0);
+ sbs_update_presence(chip, (ret >= 0));
power_supply_changed(chip->power_supply);
}
@@ -745,7 +912,7 @@ static void sbs_supply_changed(struct sbs_info *chip)
ret = gpiod_get_value_cansleep(chip->gpio_detect);
if (ret < 0)
return;
- chip->is_present = ret;
+ sbs_update_presence(chip, ret);
power_supply_changed(battery);
}
@@ -815,8 +982,7 @@ static const struct power_supply_desc sbs_default_desc = {
.external_power_changed = sbs_external_power_changed,
};
-static int sbs_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int sbs_probe(struct i2c_client *client)
{
struct sbs_info *chip;
struct power_supply_desc *sbs_desc;
@@ -839,7 +1005,7 @@ static int sbs_probe(struct i2c_client *client,
if (!chip)
return -ENOMEM;
- chip->flags = (u32)(uintptr_t)of_device_get_match_data(&client->dev);
+ chip->flags = (u32)(uintptr_t)device_get_match_data(&client->dev);
chip->client = client;
chip->enable_detection = false;
psy_cfg.of_node = client->dev.of_node;
@@ -850,13 +1016,13 @@ static int sbs_probe(struct i2c_client *client,
/* use pdata if available, fall back to DT properties,
* or hardcoded defaults if not
*/
- rc = of_property_read_u32(client->dev.of_node, "sbs,i2c-retry-count",
- &chip->i2c_retry_count);
+ rc = device_property_read_u32(&client->dev, "sbs,i2c-retry-count",
+ &chip->i2c_retry_count);
if (rc)
chip->i2c_retry_count = 0;
- rc = of_property_read_u32(client->dev.of_node, "sbs,poll-retry-count",
- &chip->poll_retry_count);
+ rc = device_property_read_u32(&client->dev, "sbs,poll-retry-count",
+ &chip->poll_retry_count);
if (rc)
chip->poll_retry_count = 0;
@@ -866,6 +1032,9 @@ static int sbs_probe(struct i2c_client *client,
}
chip->i2c_retry_count = chip->i2c_retry_count + 1;
+ chip->charger_broadcasts = !device_property_read_bool(&client->dev,
+ "sbs,disable-charger-broadcasts");
+
chip->gpio_detect = devm_gpiod_get_optional(&client->dev,
"sbs,battery-detect", GPIOD_IN);
if (IS_ERR(chip->gpio_detect)) {
@@ -950,7 +1119,7 @@ static int sbs_suspend(struct device *dev)
if (chip->poll_time > 0)
cancel_delayed_work_sync(&chip->work);
- if (chip->flags & SBS_FLAGS_TI_BQ20Z75) {
+ if (chip->flags & SBS_FLAGS_TI_BQ20ZX5) {
/* Write to manufacturer access with sleep command. */
ret = sbs_write_word_data(client,
sbs_data[REG_MANUFACTURER_DATA].addr,
@@ -970,6 +1139,7 @@ static SIMPLE_DEV_PM_OPS(sbs_pm_ops, sbs_suspend, NULL);
#endif
static const struct i2c_device_id sbs_id[] = {
+ { "bq20z65", 0 },
{ "bq20z75", 0 },
{ "sbs-battery", 1 },
{}
@@ -979,15 +1149,19 @@ MODULE_DEVICE_TABLE(i2c, sbs_id);
static const struct of_device_id sbs_dt_ids[] = {
{ .compatible = "sbs,sbs-battery" },
{
+ .compatible = "ti,bq20z65",
+ .data = (void *)SBS_FLAGS_TI_BQ20ZX5,
+ },
+ {
.compatible = "ti,bq20z75",
- .data = (void *)SBS_FLAGS_TI_BQ20Z75,
+ .data = (void *)SBS_FLAGS_TI_BQ20ZX5,
},
{ }
};
MODULE_DEVICE_TABLE(of, sbs_dt_ids);
static struct i2c_driver sbs_battery_driver = {
- .probe = sbs_probe,
+ .probe_new = sbs_probe,
.remove = sbs_remove,
.alert = sbs_alert,
.id_table = sbs_id,
diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
index a7c8a8453db1..be42e814ea34 100644
--- a/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -42,6 +42,8 @@
#define SC27XX_FGU_USER_AREA_SET 0xa0
#define SC27XX_FGU_USER_AREA_CLEAR 0xa4
#define SC27XX_FGU_USER_AREA_STATUS 0xa8
+#define SC27XX_FGU_VOLTAGE_BUF 0xd0
+#define SC27XX_FGU_CURRENT_BUF 0xf0
#define SC27XX_WRITE_SELCLB_EN BIT(0)
#define SC27XX_FGU_CLBCNT_MASK GENMASK(15, 0)
@@ -82,6 +84,7 @@
* @init_clbcnt: the initial coulomb counter
* @max_volt: the maximum constant input voltage in millivolt
* @min_volt: the minimum drained battery voltage in microvolt
+ * @boot_volt: the voltage measured during boot in microvolt
* @table_len: the capacity table length
* @resist_table_len: the resistance table length
* @cur_1000ma_adc: ADC value corresponding to 1000 mA
@@ -107,6 +110,7 @@ struct sc27xx_fgu_data {
int init_clbcnt;
int max_volt;
int min_volt;
+ int boot_volt;
int table_len;
int resist_table_len;
int cur_1000ma_adc;
@@ -319,6 +323,7 @@ static int sc27xx_fgu_get_boot_capacity(struct sc27xx_fgu_data *data, int *cap)
volt = sc27xx_fgu_adc_to_voltage(data, volt);
ocv = volt * 1000 - oci * data->internal_resist;
+ data->boot_volt = ocv;
/*
* Parse the capacity table to look up the correct capacity percent
@@ -376,6 +381,44 @@ static int sc27xx_fgu_get_clbcnt(struct sc27xx_fgu_data *data, int *clb_cnt)
return 0;
}
+static int sc27xx_fgu_get_vol_now(struct sc27xx_fgu_data *data, int *val)
+{
+ int ret;
+ u32 vol;
+
+ ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE_BUF,
+ &vol);
+ if (ret)
+ return ret;
+
+ /*
+ * It is ADC values reading from registers which need to convert to
+ * corresponding voltage values.
+ */
+ *val = sc27xx_fgu_adc_to_voltage(data, vol);
+
+ return 0;
+}
+
+static int sc27xx_fgu_get_cur_now(struct sc27xx_fgu_data *data, int *val)
+{
+ int ret;
+ u32 cur;
+
+ ret = regmap_read(data->regmap, data->base + SC27XX_FGU_CURRENT_BUF,
+ &cur);
+ if (ret)
+ return ret;
+
+ /*
+ * It is ADC values reading from registers which need to convert to
+ * corresponding current values.
+ */
+ *val = sc27xx_fgu_adc_to_current(data, cur - SC27XX_FGU_CUR_BASIC_ADC);
+
+ return 0;
+}
+
static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap)
{
int ret, cur_clbcnt, delta_clbcnt, delta_cap, temp;
@@ -577,7 +620,7 @@ static int sc27xx_fgu_get_property(struct power_supply *psy,
val->intval = value;
break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_VOLTAGE_AVG:
ret = sc27xx_fgu_get_vbat_vol(data, &value);
if (ret)
goto error;
@@ -601,7 +644,6 @@ static int sc27xx_fgu_get_property(struct power_supply *psy,
val->intval = value;
break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
case POWER_SUPPLY_PROP_CURRENT_AVG:
ret = sc27xx_fgu_get_current(data, &value);
if (ret)
@@ -625,6 +667,26 @@ static int sc27xx_fgu_get_property(struct power_supply *psy,
break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ ret = sc27xx_fgu_get_vol_now(data, &value);
+ if (ret)
+ goto error;
+
+ val->intval = value * 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ ret = sc27xx_fgu_get_cur_now(data, &value);
+ if (ret)
+ goto error;
+
+ val->intval = value * 1000;
+ break;
+
+ case POWER_SUPPLY_PROP_VOLTAGE_BOOT:
+ val->intval = data->boot_volt;
+ break;
+
default:
ret = -EINVAL;
break;
@@ -656,6 +718,11 @@ static int sc27xx_fgu_set_property(struct power_supply *psy,
ret = 0;
break;
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ data->total_cap = val->intval / 1000;
+ ret = 0;
+ break;
+
default:
ret = -EINVAL;
}
@@ -676,7 +743,8 @@ static int sc27xx_fgu_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
return psp == POWER_SUPPLY_PROP_CAPACITY ||
- psp == POWER_SUPPLY_PROP_CALIBRATE;
+ psp == POWER_SUPPLY_PROP_CALIBRATE ||
+ psp == POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
}
static enum power_supply_property sc27xx_fgu_props[] = {
@@ -688,6 +756,8 @@ static enum power_supply_property sc27xx_fgu_props[] = {
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_OCV,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_VOLTAGE_BOOT,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
@@ -705,6 +775,7 @@ static const struct power_supply_desc sc27xx_fgu_desc = {
.set_property = sc27xx_fgu_set_property,
.external_power_changed = sc27xx_fgu_external_power_changed,
.property_is_writeable = sc27xx_fgu_property_is_writeable,
+ .no_thermal = true,
};
static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap)
diff --git a/drivers/power/supply/smb347-charger.c b/drivers/power/supply/smb347-charger.c
index c1d124b8be0c..f99026d81f2a 100644
--- a/drivers/power/supply/smb347-charger.c
+++ b/drivers/power/supply/smb347-charger.c
@@ -8,6 +8,7 @@
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
@@ -708,6 +709,9 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
bool handled = false;
int ret;
+ /* SMB347 it needs at least 20ms for setting IRQSTAT_E_*IN_UV_IRQ */
+ usleep_range(25000, 35000);
+
ret = regmap_read(smb->regmap, STAT_C, &stat_c);
if (ret < 0) {
dev_warn(smb->dev, "reading STAT_C failed\n");
@@ -1138,6 +1142,7 @@ static bool smb347_volatile_reg(struct device *dev, unsigned int reg)
switch (reg) {
case IRQSTAT_A:
case IRQSTAT_C:
+ case IRQSTAT_D:
case IRQSTAT_E:
case IRQSTAT_F:
case STAT_A:
diff --git a/drivers/powercap/Kconfig b/drivers/powercap/Kconfig
index dc1c1381d7fa..ebc4d4578339 100644
--- a/drivers/powercap/Kconfig
+++ b/drivers/powercap/Kconfig
@@ -23,7 +23,7 @@ config INTEL_RAPL
tristate "Intel RAPL Support via MSR Interface"
depends on X86 && IOSF_MBI
select INTEL_RAPL_CORE
- ---help---
+ help
This enables support for the Intel Running Average Power Limit (RAPL)
technology via MSR interface, which allows power limits to be enforced
and monitored on modern Intel processors (Sandy Bridge and later).
diff --git a/drivers/powercap/idle_inject.c b/drivers/powercap/idle_inject.c
index e9bbd3c42eef..c90f0990968b 100644
--- a/drivers/powercap/idle_inject.c
+++ b/drivers/powercap/idle_inject.c
@@ -61,12 +61,14 @@ struct idle_inject_thread {
* @timer: idle injection period timer
* @idle_duration_us: duration of CPU idle time to inject
* @run_duration_us: duration of CPU run time to allow
+ * @latency_us: max allowed latency
* @cpumask: mask of CPUs affected by idle injection
*/
struct idle_inject_device {
struct hrtimer timer;
unsigned int idle_duration_us;
unsigned int run_duration_us;
+ unsigned int latency_us;
unsigned long cpumask[];
};
@@ -138,7 +140,8 @@ static void idle_inject_fn(unsigned int cpu)
*/
iit->should_run = 0;
- play_idle(READ_ONCE(ii_dev->idle_duration_us));
+ play_idle_precise(READ_ONCE(ii_dev->idle_duration_us) * NSEC_PER_USEC,
+ READ_ONCE(ii_dev->latency_us) * NSEC_PER_USEC);
}
/**
@@ -170,6 +173,16 @@ void idle_inject_get_duration(struct idle_inject_device *ii_dev,
}
/**
+ * idle_inject_set_latency - set the maximum latency allowed
+ * @latency_us: set the latency requirement for the idle state
+ */
+void idle_inject_set_latency(struct idle_inject_device *ii_dev,
+ unsigned int latency_us)
+{
+ WRITE_ONCE(ii_dev->latency_us, latency_us);
+}
+
+/**
* idle_inject_start - start idle injections
* @ii_dev: idle injection control device structure
*
@@ -297,6 +310,7 @@ struct idle_inject_device *idle_inject_register(struct cpumask *cpumask)
cpumask_copy(to_cpumask(ii_dev->cpumask), cpumask);
hrtimer_init(&ii_dev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ii_dev->timer.function = idle_inject_timer_fn;
+ ii_dev->latency_us = UINT_MAX;
for_each_cpu(cpu, to_cpumask(ii_dev->cpumask)) {
diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig
index afbf5e2b06b7..e1651d51cfc9 100644
--- a/drivers/pps/Kconfig
+++ b/drivers/pps/Kconfig
@@ -5,7 +5,7 @@
menuconfig PPS
tristate "PPS support"
- ---help---
+ help
PPS (Pulse Per Second) is a special pulse provided by some GPS
antennae. Userland can use it to get a high-precision time
reference.
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index 86400c708150..942f72d8151d 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -64,7 +64,7 @@ config DP83640_PHY
depends on NETWORK_PHY_TIMESTAMPING
depends on PHYLIB
depends on PTP_1588_CLOCK
- ---help---
+ help
Supports the DP83640 PHYTER with IEEE 1588 features.
This driver adds support for using the DP83640 as a PTP
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index eebbc917ac97..cb8d739067d2 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -232,9 +232,19 @@ config PWM_IMX_TPM
To compile this driver as a module, choose M here: the module
will be called pwm-imx-tpm.
+config PWM_IQS620A
+ tristate "Azoteq IQS620A PWM support"
+ depends on MFD_IQS62X || COMPILE_TEST
+ help
+ Generic PWM framework driver for the Azoteq IQS620A multi-function
+ sensor.
+
+ To compile this driver as a module, choose M here: the module will
+ be called pwm-iqs620a.
+
config PWM_JZ4740
tristate "Ingenic JZ47xx PWM support"
- depends on MACH_INGENIC
+ depends on MIPS
depends on COMMON_CLK
select MFD_SYSCON
help
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 9a475073dafc..a59c710e98c7 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PWM_IMG) += pwm-img.o
obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o
obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o
obj-$(CONFIG_PWM_IMX_TPM) += pwm-imx-tpm.o
+obj-$(CONFIG_PWM_IQS620A) += pwm-iqs620a.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 9973c442b455..004b2ea9b5fd 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -121,7 +121,7 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
pwm->chip->ops->get_state(pwm->chip, pwm, &pwm->state);
trace_pwm_get(pwm, &pwm->state);
- if (IS_ENABLED(PWM_DEBUG))
+ if (IS_ENABLED(CONFIG_PWM_DEBUG))
pwm->last = pwm->state;
}
@@ -537,7 +537,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
if (!state->enabled && s2.enabled && s2.duty_cycle > 0)
dev_warn(chip->dev,
- "requested disabled, but yielded enabled with duty > 0");
+ "requested disabled, but yielded enabled with duty > 0\n");
/* reapply the state that the driver reported being configured. */
err = chip->ops->apply(chip, pwm, &s1);
diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c
index c9e57bd109fb..599a0f66a384 100644
--- a/drivers/pwm/pwm-img.c
+++ b/drivers/pwm/pwm-img.c
@@ -129,8 +129,10 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
duty = DIV_ROUND_UP(timebase * duty_ns, period_ns);
ret = pm_runtime_get_sync(chip->dev);
- if (ret < 0)
+ if (ret < 0) {
+ pm_runtime_put_autosuspend(chip->dev);
return ret;
+ }
val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
val &= ~(PWM_CTRL_CFG_DIV_MASK << PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm));
@@ -331,8 +333,10 @@ static int img_pwm_remove(struct platform_device *pdev)
int ret;
ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0)
+ if (ret < 0) {
+ pm_runtime_put(&pdev->dev);
return ret;
+ }
for (i = 0; i < pwm_chip->chip.npwm; i++) {
val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index a6e40d4c485f..732a6f3701e8 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -150,13 +150,12 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
prescaler = MX3_PWMCR_PRESCALER_GET(val);
pwm_clk = clk_get_rate(imx->clk_per);
- pwm_clk = DIV_ROUND_CLOSEST_ULL(pwm_clk, prescaler);
val = readl(imx->mmio_base + MX3_PWMPR);
period = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
/* PWMOUT (Hz) = PWMCLK / (PWMPR + 2) */
- tmp = NSEC_PER_SEC * (u64)(period + 2);
- state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
+ tmp = NSEC_PER_SEC * (u64)(period + 2) * prescaler;
+ state->period = DIV_ROUND_UP_ULL(tmp, pwm_clk);
/*
* PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
@@ -167,8 +166,8 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
else
val = imx->duty_cycle;
- tmp = NSEC_PER_SEC * (u64)(val);
- state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
+ tmp = NSEC_PER_SEC * (u64)(val) * prescaler;
+ state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk);
pwm_imx27_clk_disable_unprepare(imx);
}
@@ -220,22 +219,23 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
struct pwm_state cstate;
unsigned long long c;
+ unsigned long long clkrate;
int ret;
u32 cr;
pwm_get_state(pwm, &cstate);
- c = clk_get_rate(imx->clk_per);
- c *= state->period;
+ clkrate = clk_get_rate(imx->clk_per);
+ c = clkrate * state->period;
- do_div(c, 1000000000);
+ do_div(c, NSEC_PER_SEC);
period_cycles = c;
prescale = period_cycles / 0x10000 + 1;
period_cycles /= prescale;
- c = (unsigned long long)period_cycles * state->duty_cycle;
- do_div(c, state->period);
+ c = clkrate * state->duty_cycle;
+ do_div(c, NSEC_PER_SEC * prescale);
duty_cycles = c;
/*
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
new file mode 100644
index 000000000000..674f0e238ba0
--- /dev/null
+++ b/drivers/pwm/pwm-iqs620a.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS620A PWM Generator
+ *
+ * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com>
+ *
+ * Limitations:
+ * - The period is fixed to 1 ms and is generated continuously despite changes
+ * to the duty cycle or enable/disable state.
+ * - Changes to the duty cycle or enable/disable state take effect immediately
+ * and may result in a glitch during the period in which the change is made.
+ * - The device cannot generate a 0% duty cycle. For duty cycles below 1 / 256
+ * ms, the output is disabled and relies upon an external pull-down resistor
+ * to hold the GPIO3/LTX pin low.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mfd/iqs62x.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define IQS620_PWR_SETTINGS 0xD2
+#define IQS620_PWR_SETTINGS_PWM_OUT BIT(7)
+
+#define IQS620_PWM_DUTY_CYCLE 0xD8
+
+#define IQS620_PWM_PERIOD_NS 1000000
+
+struct iqs620_pwm_private {
+ struct iqs62x_core *iqs62x;
+ struct pwm_chip chip;
+ struct notifier_block notifier;
+ struct mutex lock;
+ bool out_en;
+ u8 duty_val;
+};
+
+static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ struct iqs620_pwm_private *iqs620_pwm;
+ struct iqs62x_core *iqs62x;
+ int duty_scale, ret;
+
+ if (state->polarity != PWM_POLARITY_NORMAL)
+ return -ENOTSUPP;
+
+ if (state->period < IQS620_PWM_PERIOD_NS)
+ return -EINVAL;
+
+ iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
+ iqs62x = iqs620_pwm->iqs62x;
+
+ /*
+ * The duty cycle generated by the device is calculated as follows:
+ *
+ * duty_cycle = (IQS620_PWM_DUTY_CYCLE + 1) / 256 * 1 ms
+ *
+ * ...where IQS620_PWM_DUTY_CYCLE is a register value between 0 and 255
+ * (inclusive). Therefore the lowest duty cycle the device can generate
+ * while the output is enabled is 1 / 256 ms.
+ *
+ * For lower duty cycles (e.g. 0), the PWM output is simply disabled to
+ * allow an external pull-down resistor to hold the GPIO3/LTX pin low.
+ */
+ duty_scale = state->duty_cycle * 256 / IQS620_PWM_PERIOD_NS;
+
+ mutex_lock(&iqs620_pwm->lock);
+
+ if (!state->enabled || !duty_scale) {
+ ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+ IQS620_PWR_SETTINGS_PWM_OUT, 0);
+ if (ret)
+ goto err_mutex;
+ }
+
+ if (duty_scale) {
+ u8 duty_val = min(duty_scale - 1, 0xFF);
+
+ ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
+ duty_val);
+ if (ret)
+ goto err_mutex;
+
+ iqs620_pwm->duty_val = duty_val;
+ }
+
+ if (state->enabled && duty_scale) {
+ ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+ IQS620_PWR_SETTINGS_PWM_OUT, 0xFF);
+ if (ret)
+ goto err_mutex;
+ }
+
+ iqs620_pwm->out_en = state->enabled;
+
+err_mutex:
+ mutex_unlock(&iqs620_pwm->lock);
+
+ return ret;
+}
+
+static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct iqs620_pwm_private *iqs620_pwm;
+
+ iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
+
+ mutex_lock(&iqs620_pwm->lock);
+
+ /*
+ * Since the device cannot generate a 0% duty cycle, requests to do so
+ * cause subsequent calls to iqs620_pwm_get_state to report the output
+ * as disabled with duty cycle equal to that which was in use prior to
+ * the request. This is not ideal, but is the best compromise based on
+ * the capabilities of the device.
+ */
+ state->enabled = iqs620_pwm->out_en;
+ state->duty_cycle = DIV_ROUND_UP((iqs620_pwm->duty_val + 1) *
+ IQS620_PWM_PERIOD_NS, 256);
+
+ mutex_unlock(&iqs620_pwm->lock);
+
+ state->period = IQS620_PWM_PERIOD_NS;
+}
+
+static int iqs620_pwm_notifier(struct notifier_block *notifier,
+ unsigned long event_flags, void *context)
+{
+ struct iqs620_pwm_private *iqs620_pwm;
+ struct iqs62x_core *iqs62x;
+ int ret;
+
+ if (!(event_flags & BIT(IQS62X_EVENT_SYS_RESET)))
+ return NOTIFY_DONE;
+
+ iqs620_pwm = container_of(notifier, struct iqs620_pwm_private,
+ notifier);
+ iqs62x = iqs620_pwm->iqs62x;
+
+ mutex_lock(&iqs620_pwm->lock);
+
+ /*
+ * The parent MFD driver already prints an error message in the event
+ * of a device reset, so nothing else is printed here unless there is
+ * an additional failure.
+ */
+ ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
+ iqs620_pwm->duty_val);
+ if (ret)
+ goto err_mutex;
+
+ ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
+ IQS620_PWR_SETTINGS_PWM_OUT,
+ iqs620_pwm->out_en ? 0xFF : 0);
+
+err_mutex:
+ mutex_unlock(&iqs620_pwm->lock);
+
+ if (ret) {
+ dev_err(iqs620_pwm->chip.dev,
+ "Failed to re-initialize device: %d\n", ret);
+ return NOTIFY_BAD;
+ }
+
+ return NOTIFY_OK;
+}
+
+static const struct pwm_ops iqs620_pwm_ops = {
+ .apply = iqs620_pwm_apply,
+ .get_state = iqs620_pwm_get_state,
+ .owner = THIS_MODULE,
+};
+
+static void iqs620_pwm_notifier_unregister(void *context)
+{
+ struct iqs620_pwm_private *iqs620_pwm = context;
+ int ret;
+
+ ret = blocking_notifier_chain_unregister(&iqs620_pwm->iqs62x->nh,
+ &iqs620_pwm->notifier);
+ if (ret)
+ dev_err(iqs620_pwm->chip.dev,
+ "Failed to unregister notifier: %d\n", ret);
+}
+
+static int iqs620_pwm_probe(struct platform_device *pdev)
+{
+ struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent);
+ struct iqs620_pwm_private *iqs620_pwm;
+ unsigned int val;
+ int ret;
+
+ iqs620_pwm = devm_kzalloc(&pdev->dev, sizeof(*iqs620_pwm), GFP_KERNEL);
+ if (!iqs620_pwm)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, iqs620_pwm);
+ iqs620_pwm->iqs62x = iqs62x;
+
+ ret = regmap_read(iqs62x->regmap, IQS620_PWR_SETTINGS, &val);
+ if (ret)
+ return ret;
+ iqs620_pwm->out_en = val & IQS620_PWR_SETTINGS_PWM_OUT;
+
+ ret = regmap_read(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE, &val);
+ if (ret)
+ return ret;
+ iqs620_pwm->duty_val = val;
+
+ iqs620_pwm->chip.dev = &pdev->dev;
+ iqs620_pwm->chip.ops = &iqs620_pwm_ops;
+ iqs620_pwm->chip.base = -1;
+ iqs620_pwm->chip.npwm = 1;
+
+ mutex_init(&iqs620_pwm->lock);
+
+ iqs620_pwm->notifier.notifier_call = iqs620_pwm_notifier;
+ ret = blocking_notifier_chain_register(&iqs620_pwm->iqs62x->nh,
+ &iqs620_pwm->notifier);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(&pdev->dev,
+ iqs620_pwm_notifier_unregister,
+ iqs620_pwm);
+ if (ret)
+ return ret;
+
+ ret = pwmchip_add(&iqs620_pwm->chip);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to add device: %d\n", ret);
+
+ return ret;
+}
+
+static int iqs620_pwm_remove(struct platform_device *pdev)
+{
+ struct iqs620_pwm_private *iqs620_pwm = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = pwmchip_remove(&iqs620_pwm->chip);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to remove device: %d\n", ret);
+
+ return ret;
+}
+
+static struct platform_driver iqs620_pwm_platform_driver = {
+ .driver = {
+ .name = "iqs620a-pwm",
+ },
+ .probe = iqs620_pwm_probe,
+ .remove = iqs620_pwm_remove,
+};
+module_platform_driver(iqs620_pwm_platform_driver);
+
+MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
+MODULE_DESCRIPTION("Azoteq IQS620A PWM Generator");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:iqs620a-pwm");
diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
index 3cd5c054ad9a..5830ac2bdf6a 100644
--- a/drivers/pwm/pwm-jz4740.c
+++ b/drivers/pwm/pwm-jz4740.c
@@ -6,7 +6,6 @@
* Limitations:
* - The .apply callback doesn't complete the currently running period before
* reconfiguring the hardware.
- * - Each period starts with the inactive part.
*/
#include <linux/clk.h>
@@ -21,7 +20,9 @@
#include <linux/pwm.h>
#include <linux/regmap.h>
-#define NUM_PWM 8
+struct soc_info {
+ unsigned int num_pwms;
+};
struct jz4740_pwm_chip {
struct pwm_chip chip;
@@ -37,7 +38,7 @@ static bool jz4740_pwm_can_use_chn(struct jz4740_pwm_chip *jz,
unsigned int channel)
{
/* Enable all TCU channels for PWM use by default except channels 0/1 */
- u32 pwm_channels_mask = GENMASK(NUM_PWM - 1, 2);
+ u32 pwm_channels_mask = GENMASK(jz->chip.npwm - 1, 2);
device_property_read_u32(jz->chip.dev->parent,
"ingenic,pwm-channels-mask",
@@ -158,12 +159,12 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
/* Calculate period value */
tmp = (unsigned long long)rate * state->period;
do_div(tmp, NSEC_PER_SEC);
- period = (unsigned long)tmp;
+ period = tmp;
/* Calculate duty value */
- tmp = (unsigned long long)period * state->duty_cycle;
- do_div(tmp, state->period);
- duty = period - tmp;
+ tmp = (unsigned long long)rate * state->duty_cycle;
+ do_div(tmp, NSEC_PER_SEC);
+ duty = tmp;
if (duty >= period)
duty = period - 1;
@@ -189,18 +190,26 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
TCU_TCSR_PWM_SD, TCU_TCSR_PWM_SD);
- /* Set polarity */
- switch (state->polarity) {
- case PWM_POLARITY_NORMAL:
+ /*
+ * Set polarity.
+ *
+ * The PWM starts in inactive state until the internal timer reaches the
+ * duty value, then becomes active until the timer reaches the period
+ * value. In theory, we should then use (period - duty) as the real duty
+ * value, as a high duty value would otherwise result in the PWM pin
+ * being inactive most of the time.
+ *
+ * Here, we don't do that, and instead invert the polarity of the PWM
+ * when it is active. This trick makes the PWM start with its active
+ * state instead of its inactive state.
+ */
+ if ((state->polarity == PWM_POLARITY_NORMAL) ^ state->enabled)
regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
TCU_TCSR_PWM_INITL_HIGH, 0);
- break;
- case PWM_POLARITY_INVERSED:
+ else
regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
TCU_TCSR_PWM_INITL_HIGH,
TCU_TCSR_PWM_INITL_HIGH);
- break;
- }
if (state->enabled)
jz4740_pwm_enable(chip, pwm);
@@ -219,6 +228,11 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct jz4740_pwm_chip *jz4740;
+ const struct soc_info *info;
+
+ info = device_get_match_data(dev);
+ if (!info)
+ return -EINVAL;
jz4740 = devm_kzalloc(dev, sizeof(*jz4740), GFP_KERNEL);
if (!jz4740)
@@ -232,7 +246,7 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
jz4740->chip.dev = dev;
jz4740->chip.ops = &jz4740_pwm_ops;
- jz4740->chip.npwm = NUM_PWM;
+ jz4740->chip.npwm = info->num_pwms;
jz4740->chip.base = -1;
jz4740->chip.of_xlate = of_pwm_xlate_with_flags;
jz4740->chip.of_pwm_n_cells = 3;
@@ -249,9 +263,18 @@ static int jz4740_pwm_remove(struct platform_device *pdev)
return pwmchip_remove(&jz4740->chip);
}
+static const struct soc_info __maybe_unused jz4740_soc_info = {
+ .num_pwms = 8,
+};
+
+static const struct soc_info __maybe_unused jz4725b_soc_info = {
+ .num_pwms = 6,
+};
+
#ifdef CONFIG_OF
static const struct of_device_id jz4740_pwm_dt_ids[] = {
- { .compatible = "ingenic,jz4740-pwm", },
+ { .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
+ { .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
{},
};
MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 75bbfe5f3bc2..9d965ffe66d1 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -158,7 +158,6 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
-/* This function gets called once from pwmchip_add to get the initial state */
static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
@@ -167,6 +166,8 @@ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long long base_unit, freq, on_time_div;
u32 ctrl;
+ pm_runtime_get_sync(chip->dev);
+
base_unit_range = BIT(lpwm->info->base_unit_bits);
ctrl = pwm_lpss_read(pwm);
@@ -187,8 +188,7 @@ static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->polarity = PWM_POLARITY_NORMAL;
state->enabled = !!(ctrl & PWM_ENABLE);
- if (state->enabled)
- pm_runtime_get(chip->dev);
+ pm_runtime_put(chip->dev);
}
static const struct pwm_ops pwm_lpss_ops = {
@@ -202,7 +202,8 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
{
struct pwm_lpss_chip *lpwm;
unsigned long c;
- int ret;
+ int i, ret;
+ u32 ctrl;
if (WARN_ON(info->npwm > MAX_PWMS))
return ERR_PTR(-ENODEV);
@@ -232,6 +233,12 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
return ERR_PTR(ret);
}
+ for (i = 0; i < lpwm->info->npwm; i++) {
+ ctrl = pwm_lpss_read(&lpwm->chip.pwms[i]);
+ if (ctrl & PWM_ENABLE)
+ pm_runtime_get(dev);
+ }
+
return lpwm;
}
EXPORT_SYMBOL_GPL(pwm_lpss_probe);
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 73352e6fbccb..eb8c9cb645a6 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -83,12 +83,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
val = readl_relaxed(pc->base + pc->data->regs.ctrl);
- if (pc->data->supports_polarity)
- state->enabled = ((val & enable_conf) != enable_conf) ?
- false : true;
- else
- state->enabled = ((val & enable_conf) == enable_conf) ?
- true : false;
+ state->enabled = (val & enable_conf) == enable_conf;
if (pc->data->supports_polarity && !(val & PWM_DUTY_POSITIVE))
state->polarity = PWM_POLARITY_INVERSED;
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 5c677c563349..18fbbe3277d0 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -352,6 +352,12 @@ static const struct sun4i_pwm_data sun4i_pwm_single_bypass = {
.npwm = 1,
};
+static const struct sun4i_pwm_data sun50i_a64_pwm_data = {
+ .has_prescaler_bypass = true,
+ .has_direct_mod_clk_output = true,
+ .npwm = 1,
+};
+
static const struct sun4i_pwm_data sun50i_h6_pwm_data = {
.has_prescaler_bypass = true,
.has_direct_mod_clk_output = true,
@@ -375,6 +381,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
.compatible = "allwinner,sun8i-h3-pwm",
.data = &sun4i_pwm_single_bypass,
}, {
+ .compatible = "allwinner,sun50i-a64-pwm",
+ .data = &sun50i_a64_pwm_data,
+ }, {
.compatible = "allwinner,sun50i-h6-pwm",
.data = &sun50i_h6_pwm_data,
}, {
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index d26ed8f579ff..1daf591025c0 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -4,8 +4,36 @@
*
* Tegra pulse-width-modulation controller driver
*
- * Copyright (c) 2010, NVIDIA Corporation.
+ * Copyright (c) 2010-2020, NVIDIA Corporation.
* Based on arch/arm/plat-mxc/pwm.c by Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Overview of Tegra Pulse Width Modulator Register:
+ * 1. 13-bit: Frequency division (SCALE)
+ * 2. 8-bit : Pulse division (DUTY)
+ * 3. 1-bit : Enable bit
+ *
+ * The PWM clock frequency is divided by 256 before subdividing it based
+ * on the programmable frequency division value to generate the required
+ * frequency for PWM output. The maximum output frequency that can be
+ * achieved is (max rate of source clock) / 256.
+ * e.g. if source clock rate is 408 MHz, maximum output frequency can be:
+ * 408 MHz/256 = 1.6 MHz.
+ * This 1.6 MHz frequency can further be divided using SCALE value in PWM.
+ *
+ * PWM pulse width: 8 bits are usable [23:16] for varying pulse width.
+ * To achieve 100% duty cycle, program Bit [24] of this register to
+ * 1’b1. In which case the other bits [23:16] are set to don't care.
+ *
+ * Limitations:
+ * - When PWM is disabled, the output is driven to inactive.
+ * - It does not allow the current PWM period to complete and
+ * stops abruptly.
+ *
+ * - If the register is reconfigured while PWM is running,
+ * it does not complete the currently running period.
+ *
+ * - If the user input duty is beyond acceptible limits,
+ * -EINVAL is returned.
*/
#include <linux/clk.h>
@@ -41,6 +69,7 @@ struct tegra_pwm_chip {
struct reset_control*rst;
unsigned long clk_rate;
+ unsigned long min_period_ns;
void __iomem *regs;
@@ -68,7 +97,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
{
struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
unsigned long long c = duty_ns, hz;
- unsigned long rate;
+ unsigned long rate, required_clk_rate;
u32 val = 0;
int err;
@@ -83,9 +112,47 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
val = (u32)c << PWM_DUTY_SHIFT;
/*
+ * min period = max clock limit >> PWM_DUTY_WIDTH
+ */
+ if (period_ns < pc->min_period_ns)
+ return -EINVAL;
+
+ /*
* Compute the prescaler value for which (1 << PWM_DUTY_WIDTH)
* cycles at the PWM clock rate will take period_ns nanoseconds.
+ *
+ * num_channels: If single instance of PWM controller has multiple
+ * channels (e.g. Tegra210 or older) then it is not possible to
+ * configure separate clock rates to each of the channels, in such
+ * case the value stored during probe will be referred.
+ *
+ * If every PWM controller instance has one channel respectively, i.e.
+ * nums_channels == 1 then only the clock rate can be modified
+ * dynamically (e.g. Tegra186 or Tegra194).
*/
+ if (pc->soc->num_channels == 1) {
+ /*
+ * Rate is multiplied with 2^PWM_DUTY_WIDTH so that it matches
+ * with the maximum possible rate that the controller can
+ * provide. Any further lower value can be derived by setting
+ * PFM bits[0:12].
+ *
+ * required_clk_rate is a reference rate for source clock and
+ * it is derived based on user requested period. By setting the
+ * source clock rate as required_clk_rate, PWM controller will
+ * be able to configure the requested period.
+ */
+ required_clk_rate =
+ (NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
+
+ err = clk_set_rate(pc->clk, required_clk_rate);
+ if (err < 0)
+ return -EINVAL;
+
+ /* Store the new rate for further references */
+ pc->clk_rate = clk_get_rate(pc->clk);
+ }
+
rate = pc->clk_rate >> PWM_DUTY_WIDTH;
/* Consider precision in PWM_SCALE_WIDTH rate calculation */
@@ -94,7 +161,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
/*
* Since the actual PWM divider is the register's frequency divider
- * field minus 1, we need to decrement to get the correct value to
+ * field plus 1, we need to decrement to get the correct value to
* write to the register.
*/
if (rate > 0)
@@ -205,6 +272,10 @@ static int tegra_pwm_probe(struct platform_device *pdev)
*/
pwm->clk_rate = clk_get_rate(pwm->clk);
+ /* Set minimum limit of PWM period for the IP */
+ pwm->min_period_ns =
+ (NSEC_PER_SEC / (pwm->soc->max_frequency >> PWM_DUTY_WIDTH)) + 1;
+
pwm->rst = devm_reset_control_get_exclusive(&pdev->dev, "pwm");
if (IS_ERR(pwm->rst)) {
ret = PTR_ERR(pwm->rst);
@@ -312,5 +383,6 @@ static struct platform_driver tegra_pwm_driver = {
module_platform_driver(tegra_pwm_driver);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("NVIDIA Corporation");
+MODULE_AUTHOR("Sandipan Patra <spatra@nvidia.com>");
+MODULE_DESCRIPTION("Tegra PWM controller driver");
MODULE_ALIAS("platform:tegra-pwm");
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 677d1aff61b7..e4c422d806be 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -19,14 +19,14 @@ config RAPIDIO_DISC_TIMEOUT
int "Discovery timeout duration (seconds)"
depends on RAPIDIO
default "30"
- ---help---
+ help
Amount of time a discovery node waits for a host to complete
enumeration before giving up.
config RAPIDIO_ENABLE_RX_TX_PORTS
bool "Enable RapidIO Input/Output Ports"
depends on RAPIDIO
- ---help---
+ help
The RapidIO specification describes a Output port transmit
enable and a Input port receive enable. The recommended state
for Input ports and Output ports should be disabled. When
diff --git a/drivers/rapidio/devices/Kconfig b/drivers/rapidio/devices/Kconfig
index 9a195654b0ca..c416531ad7c8 100644
--- a/drivers/rapidio/devices/Kconfig
+++ b/drivers/rapidio/devices/Kconfig
@@ -7,5 +7,5 @@ config RAPIDIO_TSI721
tristate "IDT Tsi721 PCI Express SRIO Controller support"
depends on RAPIDIO && PCIEPORTBUS
default "n"
- ---help---
+ help
Include support for IDT Tsi721 PCI Express Serial RapidIO controller.
diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig
index c1eb9cb899b1..3e18f9c51e29 100644
--- a/drivers/rapidio/switches/Kconfig
+++ b/drivers/rapidio/switches/Kconfig
@@ -4,28 +4,28 @@
#
config RAPIDIO_TSI57X
tristate "IDT Tsi57x SRIO switches support"
- ---help---
+ help
Includes support for IDT Tsi57x family of serial RapidIO switches.
config RAPIDIO_CPS_XX
tristate "IDT CPS-xx SRIO switches support"
- ---help---
+ help
Includes support for IDT CPS-16/12/10/8 serial RapidIO switches.
config RAPIDIO_TSI568
tristate "Tsi568 SRIO switch support"
default n
- ---help---
+ help
Includes support for IDT Tsi568 serial RapidIO switch.
config RAPIDIO_CPS_GEN2
tristate "IDT CPS Gen.2 SRIO switch support"
default n
- ---help---
+ help
Includes support for ITD CPS Gen.2 serial RapidIO switches.
config RAPIDIO_RXS_GEN3
tristate "IDT RXS Gen.3 SRIO switch support"
default n
- ---help---
+ help
Includes support for ITD RXS Gen.3 serial RapidIO switches.
diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index c09cf55e2d20..569d9ad2c594 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -309,7 +309,7 @@ static bool sanity_check(struct ce_array *ca)
return ret;
}
-int cec_add_elem(u64 pfn)
+static int cec_add_elem(u64 pfn)
{
struct ce_array *ca = &ce_arr;
unsigned int to = 0;
@@ -527,7 +527,33 @@ err:
return 1;
}
-void __init cec_init(void)
+static int cec_notifier(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ struct mce *m = (struct mce *)data;
+
+ if (!m)
+ return NOTIFY_DONE;
+
+ /* We eat only correctable DRAM errors with usable addresses. */
+ if (mce_is_memory_error(m) &&
+ mce_is_correctable(m) &&
+ mce_usable_address(m)) {
+ if (!cec_add_elem(m->addr >> PAGE_SHIFT)) {
+ m->kflags |= MCE_HANDLED_CEC;
+ return NOTIFY_OK;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block cec_nb = {
+ .notifier_call = cec_notifier,
+ .priority = MCE_PRIO_CEC,
+};
+
+static void __init cec_init(void)
{
if (ce_arr.disabled)
return;
@@ -546,8 +572,11 @@ void __init cec_init(void)
INIT_DELAYED_WORK(&cec_work, cec_work_fn);
schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL);
+ mce_register_decode_chain(&cec_nb);
+
pr_info("Correctable Errors collector initialized.\n");
}
+late_initcall(cec_init);
int __init parse_cec_param(char *str)
{
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index fbaed079b299..c4d1731295eb 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -23,6 +23,15 @@ config IMX_REMOTEPROC
It's safe to say N here.
+config INGENIC_VPU_RPROC
+ tristate "Ingenic JZ47xx VPU remoteproc support"
+ depends on MIPS || COMPILE_TEST
+ help
+ Say y or m here to support the VPU in the JZ47xx SoCs from Ingenic.
+
+ This can be either built-in or a loadable module.
+ If unsure say N.
+
config MTK_SCP
tristate "Mediatek SCP support"
depends on ARCH_MEDIATEK
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 0effd3825035..e8b886e511f0 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -10,6 +10,7 @@ remoteproc-y += remoteproc_sysfs.o
remoteproc-y += remoteproc_virtio.o
remoteproc-y += remoteproc_elf_loader.o
obj-$(CONFIG_IMX_REMOTEPROC) += imx_rproc.o
+obj-$(CONFIG_INGENIC_VPU_RPROC) += ingenic_rproc.o
obj-$(CONFIG_MTK_SCP) += mtk_scp.o mtk_scp_ipi.o
obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o
diff --git a/drivers/remoteproc/ingenic_rproc.c b/drivers/remoteproc/ingenic_rproc.c
new file mode 100644
index 000000000000..189020d77b25
--- /dev/null
+++ b/drivers/remoteproc/ingenic_rproc.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Ingenic JZ47xx remoteproc driver
+ * Copyright 2019, Paul Cercueil <paul@crapouillou.net>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/remoteproc.h>
+
+#include "remoteproc_internal.h"
+
+#define REG_AUX_CTRL 0x0
+#define REG_AUX_MSG_ACK 0x10
+#define REG_AUX_MSG 0x14
+#define REG_CORE_MSG_ACK 0x18
+#define REG_CORE_MSG 0x1C
+
+#define AUX_CTRL_SLEEP BIT(31)
+#define AUX_CTRL_MSG_IRQ_EN BIT(3)
+#define AUX_CTRL_NMI_RESETS BIT(2)
+#define AUX_CTRL_NMI BIT(1)
+#define AUX_CTRL_SW_RESET BIT(0)
+
+struct vpu_mem_map {
+ const char *name;
+ unsigned int da;
+};
+
+struct vpu_mem_info {
+ const struct vpu_mem_map *map;
+ unsigned long len;
+ void __iomem *base;
+};
+
+static const struct vpu_mem_map vpu_mem_map[] = {
+ { "tcsm0", 0x132b0000 },
+ { "tcsm1", 0xf4000000 },
+ { "sram", 0x132f0000 },
+};
+
+/**
+ * struct vpu - Ingenic VPU remoteproc private structure
+ * @irq: interrupt number
+ * @clks: pointers to the VPU and AUX clocks
+ * @aux_base: raw pointer to the AUX interface registers
+ * @mem_info: array of struct vpu_mem_info, which contain the mapping info of
+ * each of the external memories
+ * @dev: private pointer to the device
+ */
+struct vpu {
+ int irq;
+ struct clk_bulk_data clks[2];
+ void __iomem *aux_base;
+ struct vpu_mem_info mem_info[ARRAY_SIZE(vpu_mem_map)];
+ struct device *dev;
+};
+
+static int ingenic_rproc_start(struct rproc *rproc)
+{
+ struct vpu *vpu = rproc->priv;
+ u32 ctrl;
+
+ enable_irq(vpu->irq);
+
+ /* Reset the AUX and enable message IRQ */
+ ctrl = AUX_CTRL_NMI_RESETS | AUX_CTRL_NMI | AUX_CTRL_MSG_IRQ_EN;
+ writel(ctrl, vpu->aux_base + REG_AUX_CTRL);
+
+ return 0;
+}
+
+static int ingenic_rproc_stop(struct rproc *rproc)
+{
+ struct vpu *vpu = rproc->priv;
+
+ disable_irq(vpu->irq);
+
+ /* Keep AUX in reset mode */
+ writel(AUX_CTRL_SW_RESET, vpu->aux_base + REG_AUX_CTRL);
+
+ return 0;
+}
+
+static void ingenic_rproc_kick(struct rproc *rproc, int vqid)
+{
+ struct vpu *vpu = rproc->priv;
+
+ writel(vqid, vpu->aux_base + REG_CORE_MSG);
+}
+
+static void *ingenic_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
+{
+ struct vpu *vpu = rproc->priv;
+ void __iomem *va = NULL;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(vpu_mem_map); i++) {
+ const struct vpu_mem_info *info = &vpu->mem_info[i];
+ const struct vpu_mem_map *map = info->map;
+
+ if (da >= map->da && (da + len) < (map->da + info->len)) {
+ va = info->base + (da - map->da);
+ break;
+ }
+ }
+
+ return (__force void *)va;
+}
+
+static struct rproc_ops ingenic_rproc_ops = {
+ .start = ingenic_rproc_start,
+ .stop = ingenic_rproc_stop,
+ .kick = ingenic_rproc_kick,
+ .da_to_va = ingenic_rproc_da_to_va,
+};
+
+static irqreturn_t vpu_interrupt(int irq, void *data)
+{
+ struct rproc *rproc = data;
+ struct vpu *vpu = rproc->priv;
+ u32 vring;
+
+ vring = readl(vpu->aux_base + REG_AUX_MSG);
+
+ /* Ack the interrupt */
+ writel(0, vpu->aux_base + REG_AUX_MSG_ACK);
+
+ return rproc_vq_interrupt(rproc, vring);
+}
+
+static void ingenic_rproc_disable_clks(void *data)
+{
+ struct vpu *vpu = data;
+
+ pm_runtime_resume(vpu->dev);
+ pm_runtime_disable(vpu->dev);
+
+ clk_bulk_disable_unprepare(ARRAY_SIZE(vpu->clks), vpu->clks);
+}
+
+static int ingenic_rproc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *mem;
+ struct rproc *rproc;
+ struct vpu *vpu;
+ unsigned int i;
+ int ret;
+
+ rproc = devm_rproc_alloc(dev, "ingenic-vpu",
+ &ingenic_rproc_ops, NULL, sizeof(*vpu));
+ if (!rproc)
+ return -ENOMEM;
+
+ vpu = rproc->priv;
+ vpu->dev = &pdev->dev;
+ platform_set_drvdata(pdev, vpu);
+
+ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aux");
+ vpu->aux_base = devm_ioremap_resource(dev, mem);
+ if (IS_ERR(vpu->aux_base)) {
+ dev_err(dev, "Failed to ioremap\n");
+ return PTR_ERR(vpu->aux_base);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vpu_mem_map); i++) {
+ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ vpu_mem_map[i].name);
+
+ vpu->mem_info[i].base = devm_ioremap_resource(dev, mem);
+ if (IS_ERR(vpu->mem_info[i].base)) {
+ ret = PTR_ERR(vpu->mem_info[i].base);
+ dev_err(dev, "Failed to ioremap\n");
+ return ret;
+ }
+
+ vpu->mem_info[i].len = resource_size(mem);
+ vpu->mem_info[i].map = &vpu_mem_map[i];
+ }
+
+ vpu->clks[0].id = "vpu";
+ vpu->clks[1].id = "aux";
+
+ ret = devm_clk_bulk_get(dev, ARRAY_SIZE(vpu->clks), vpu->clks);
+ if (ret) {
+ dev_err(dev, "Failed to get clocks\n");
+ return ret;
+ }
+
+ vpu->irq = platform_get_irq(pdev, 0);
+ if (vpu->irq < 0)
+ return vpu->irq;
+
+ ret = devm_request_irq(dev, vpu->irq, vpu_interrupt, 0, "VPU", rproc);
+ if (ret < 0) {
+ dev_err(dev, "Failed to request IRQ\n");
+ return ret;
+ }
+
+ disable_irq(vpu->irq);
+
+ /* The clocks must be enabled for the firmware to be loaded in TCSM */
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(vpu->clks), vpu->clks);
+ if (ret) {
+ dev_err(dev, "Unable to start clocks\n");
+ return ret;
+ }
+
+ pm_runtime_irq_safe(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+ pm_runtime_use_autosuspend(dev);
+
+ ret = devm_add_action_or_reset(dev, ingenic_rproc_disable_clks, vpu);
+ if (ret) {
+ dev_err(dev, "Unable to register action\n");
+ goto out_pm_put;
+ }
+
+ ret = devm_rproc_add(dev, rproc);
+ if (ret) {
+ dev_err(dev, "Failed to register remote processor\n");
+ goto out_pm_put;
+ }
+
+out_pm_put:
+ pm_runtime_put_autosuspend(dev);
+
+ return ret;
+}
+
+static const struct of_device_id ingenic_rproc_of_matches[] = {
+ { .compatible = "ingenic,jz4770-vpu-rproc", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ingenic_rproc_of_matches);
+
+static int __maybe_unused ingenic_rproc_suspend(struct device *dev)
+{
+ struct vpu *vpu = dev_get_drvdata(dev);
+
+ clk_bulk_disable(ARRAY_SIZE(vpu->clks), vpu->clks);
+
+ return 0;
+}
+
+static int __maybe_unused ingenic_rproc_resume(struct device *dev)
+{
+ struct vpu *vpu = dev_get_drvdata(dev);
+
+ return clk_bulk_enable(ARRAY_SIZE(vpu->clks), vpu->clks);
+}
+
+static const struct dev_pm_ops __maybe_unused ingenic_rproc_pm = {
+ SET_RUNTIME_PM_OPS(ingenic_rproc_suspend, ingenic_rproc_resume, NULL)
+};
+
+static struct platform_driver ingenic_rproc_driver = {
+ .probe = ingenic_rproc_probe,
+ .driver = {
+ .name = "ingenic-vpu",
+#ifdef CONFIG_PM
+ .pm = &ingenic_rproc_pm,
+#endif
+ .of_match_table = ingenic_rproc_of_matches,
+ },
+};
+module_platform_driver(ingenic_rproc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
+MODULE_DESCRIPTION("Ingenic JZ47xx Remote Processor control driver");
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 2bead57c9cf9..ac13e7b046a6 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -132,8 +132,8 @@ static int scp_ipi_init(struct mtk_scp *scp)
(struct mtk_share_obj __iomem *)(scp->sram_base + recv_offset);
scp->send_buf =
(struct mtk_share_obj __iomem *)(scp->sram_base + send_offset);
- memset_io(scp->recv_buf, 0, sizeof(scp->recv_buf));
- memset_io(scp->send_buf, 0, sizeof(scp->send_buf));
+ memset_io(scp->recv_buf, 0, sizeof(*scp->recv_buf));
+ memset_io(scp->send_buf, 0, sizeof(*scp->send_buf));
return 0;
}
diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c
index 60650bcc8c67..9028cea2d81e 100644
--- a/drivers/remoteproc/qcom_common.c
+++ b/drivers/remoteproc/qcom_common.c
@@ -42,12 +42,21 @@ static void glink_subdev_stop(struct rproc_subdev *subdev, bool crashed)
glink->edge = NULL;
}
+static void glink_subdev_unprepare(struct rproc_subdev *subdev)
+{
+ struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
+
+ qcom_glink_ssr_notify(glink->ssr_name);
+}
+
/**
* qcom_add_glink_subdev() - try to add a GLINK subdevice to rproc
* @rproc: rproc handle to parent the subdevice
* @glink: reference to a GLINK subdev context
+ * @ssr_name: identifier of the associated remoteproc for ssr notifications
*/
-void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink)
+void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink,
+ const char *ssr_name)
{
struct device *dev = &rproc->dev;
@@ -55,9 +64,14 @@ void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink)
if (!glink->node)
return;
+ glink->ssr_name = kstrdup_const(ssr_name, GFP_KERNEL);
+ if (!glink->ssr_name)
+ return;
+
glink->dev = dev;
glink->subdev.start = glink_subdev_start;
glink->subdev.stop = glink_subdev_stop;
+ glink->subdev.unprepare = glink_subdev_unprepare;
rproc_add_subdev(rproc, &glink->subdev);
}
@@ -74,6 +88,7 @@ void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glin
return;
rproc_remove_subdev(rproc, &glink->subdev);
+ kfree_const(glink->ssr_name);
of_node_put(glink->node);
}
EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev);
diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h
index 58de71e4781c..34e5188187dc 100644
--- a/drivers/remoteproc/qcom_common.h
+++ b/drivers/remoteproc/qcom_common.h
@@ -11,6 +11,8 @@ struct qcom_sysmon;
struct qcom_rproc_glink {
struct rproc_subdev subdev;
+ const char *ssr_name;
+
struct device *dev;
struct device_node *node;
struct qcom_glink *edge;
@@ -30,7 +32,8 @@ struct qcom_rproc_ssr {
const char *name;
};
-void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
+void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink,
+ const char *ssr_name);
void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
int qcom_register_dump_segments(struct rproc *rproc, const struct firmware *fw);
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index 24a3db961d5e..d2a2574dcf35 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -431,6 +431,7 @@ static int adsp_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
}
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
adsp = (struct qcom_adsp *)rproc->priv;
adsp->dev = &pdev->dev;
@@ -460,7 +461,7 @@ static int adsp_probe(struct platform_device *pdev)
if (ret)
goto disable_pm;
- qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
+ qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
adsp->sysmon = qcom_add_sysmon_subdev(rproc,
desc->sysmon_name,
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index 5475d4f808a8..feb70283b6a2 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -69,13 +69,9 @@
#define AXI_HALTREQ_REG 0x0
#define AXI_HALTACK_REG 0x4
#define AXI_IDLE_REG 0x8
-#define NAV_AXI_HALTREQ_BIT BIT(0)
-#define NAV_AXI_HALTACK_BIT BIT(1)
-#define NAV_AXI_IDLE_BIT BIT(2)
#define AXI_GATING_VALID_OVERRIDE BIT(0)
#define HALT_ACK_TIMEOUT_US 100000
-#define NAV_HALT_ACK_TIMEOUT_US 200
/* QDSP6SS_RESET */
#define Q6SS_STOP_CORE BIT(0)
@@ -143,7 +139,7 @@ struct rproc_hexagon_res {
int version;
bool need_mem_protection;
bool has_alt_reset;
- bool has_halt_nav;
+ bool has_spare_reg;
};
struct q6v5 {
@@ -154,13 +150,11 @@ struct q6v5 {
void __iomem *rmb_base;
struct regmap *halt_map;
- struct regmap *halt_nav_map;
struct regmap *conn_map;
u32 halt_q6;
u32 halt_modem;
u32 halt_nc;
- u32 halt_nav;
u32 conn_box;
struct reset_control *mss_restart;
@@ -196,7 +190,6 @@ struct q6v5 {
phys_addr_t mpss_phys;
phys_addr_t mpss_reloc;
- void *mpss_region;
size_t mpss_size;
struct qcom_rproc_glink glink_subdev;
@@ -206,7 +199,7 @@ struct q6v5 {
struct qcom_sysmon *sysmon;
bool need_mem_protection;
bool has_alt_reset;
- bool has_halt_nav;
+ bool has_spare_reg;
int mpss_perm;
int mba_perm;
const char *hexagon_mdt_image;
@@ -427,21 +420,19 @@ static int q6v5_reset_assert(struct q6v5 *qproc)
reset_control_assert(qproc->pdc_reset);
ret = reset_control_reset(qproc->mss_restart);
reset_control_deassert(qproc->pdc_reset);
- } else if (qproc->has_halt_nav) {
+ } else if (qproc->has_spare_reg) {
/*
* When the AXI pipeline is being reset with the Q6 modem partly
* operational there is possibility of AXI valid signal to
* glitch, leading to spurious transactions and Q6 hangs. A work
* around is employed by asserting the AXI_GATING_VALID_OVERRIDE
- * BIT before triggering Q6 MSS reset. Both the HALTREQ and
- * AXI_GATING_VALID_OVERRIDE are withdrawn post MSS assert
- * followed by a MSS deassert, while holding the PDC reset.
+ * BIT before triggering Q6 MSS reset. AXI_GATING_VALID_OVERRIDE
+ * is withdrawn post MSS assert followed by a MSS deassert,
+ * while holding the PDC reset.
*/
reset_control_assert(qproc->pdc_reset);
regmap_update_bits(qproc->conn_map, qproc->conn_box,
AXI_GATING_VALID_OVERRIDE, 1);
- regmap_update_bits(qproc->halt_nav_map, qproc->halt_nav,
- NAV_AXI_HALTREQ_BIT, 0);
reset_control_assert(qproc->mss_restart);
reset_control_deassert(qproc->pdc_reset);
regmap_update_bits(qproc->conn_map, qproc->conn_box,
@@ -464,7 +455,7 @@ static int q6v5_reset_deassert(struct q6v5 *qproc)
ret = reset_control_reset(qproc->mss_restart);
writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
reset_control_deassert(qproc->pdc_reset);
- } else if (qproc->has_halt_nav) {
+ } else if (qproc->has_spare_reg) {
ret = reset_control_reset(qproc->mss_restart);
} else {
ret = reset_control_deassert(qproc->mss_restart);
@@ -761,32 +752,6 @@ static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
}
-static void q6v5proc_halt_nav_axi_port(struct q6v5 *qproc,
- struct regmap *halt_map,
- u32 offset)
-{
- unsigned int val;
- int ret;
-
- /* Check if we're already idle */
- ret = regmap_read(halt_map, offset, &val);
- if (!ret && (val & NAV_AXI_IDLE_BIT))
- return;
-
- /* Assert halt request */
- regmap_update_bits(halt_map, offset, NAV_AXI_HALTREQ_BIT,
- NAV_AXI_HALTREQ_BIT);
-
- /* Wait for halt ack*/
- regmap_read_poll_timeout(halt_map, offset, val,
- (val & NAV_AXI_HALTACK_BIT),
- 5, NAV_HALT_ACK_TIMEOUT_US);
-
- ret = regmap_read(halt_map, offset, &val);
- if (ret || !(val & NAV_AXI_IDLE_BIT))
- dev_err(qproc->dev, "port failed halt\n");
-}
-
static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
{
unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
@@ -951,9 +916,6 @@ static int q6v5_mba_load(struct q6v5 *qproc)
halt_axi_ports:
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
- if (qproc->has_halt_nav)
- q6v5proc_halt_nav_axi_port(qproc, qproc->halt_nav_map,
- qproc->halt_nav);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
reclaim_mba:
@@ -1001,9 +963,6 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
- if (qproc->has_halt_nav)
- q6v5proc_halt_nav_axi_port(qproc, qproc->halt_nav_map,
- qproc->halt_nav);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
if (qproc->version == MSS_MSM8996) {
/*
@@ -1156,7 +1115,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
goto release_firmware;
}
- ptr = qproc->mpss_region + offset;
+ ptr = ioremap_wc(qproc->mpss_phys + offset, phdr->p_memsz);
+ if (!ptr) {
+ dev_err(qproc->dev,
+ "unable to map memory region: %pa+%zx-%x\n",
+ &qproc->mpss_phys, offset, phdr->p_memsz);
+ goto release_firmware;
+ }
if (phdr->p_filesz && phdr->p_offset < fw->size) {
/* Firmware is large enough to be non-split */
@@ -1165,6 +1130,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
"failed to load segment %d from truncated file %s\n",
i, fw_name);
ret = -EINVAL;
+ iounmap(ptr);
goto release_firmware;
}
@@ -1175,6 +1141,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
ret = request_firmware(&seg_fw, fw_name, qproc->dev);
if (ret) {
dev_err(qproc->dev, "failed to load %s\n", fw_name);
+ iounmap(ptr);
goto release_firmware;
}
@@ -1187,6 +1154,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
memset(ptr + phdr->p_filesz, 0,
phdr->p_memsz - phdr->p_filesz);
}
+ iounmap(ptr);
size += phdr->p_memsz;
code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
@@ -1236,7 +1204,8 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
int ret = 0;
struct q6v5 *qproc = rproc->priv;
unsigned long mask = BIT((unsigned long)segment->priv);
- void *ptr = rproc_da_to_va(rproc, segment->da, segment->size);
+ int offset = segment->da - qproc->mpss_reloc;
+ void *ptr = NULL;
/* Unlock mba before copying segments */
if (!qproc->dump_mba_loaded) {
@@ -1250,10 +1219,15 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
}
}
- if (!ptr || ret)
- memset(dest, 0xff, segment->size);
- else
+ if (!ret)
+ ptr = ioremap_wc(qproc->mpss_phys + offset, segment->size);
+
+ if (ptr) {
memcpy(dest, ptr, segment->size);
+ iounmap(ptr);
+ } else {
+ memset(dest, 0xff, segment->size);
+ }
qproc->dump_segment_mask |= mask;
@@ -1327,18 +1301,6 @@ static int q6v5_stop(struct rproc *rproc)
return 0;
}
-static void *q6v5_da_to_va(struct rproc *rproc, u64 da, size_t len)
-{
- struct q6v5 *qproc = rproc->priv;
- int offset;
-
- offset = da - qproc->mpss_reloc;
- if (offset < 0 || offset + len > qproc->mpss_size)
- return NULL;
-
- return qproc->mpss_region + offset;
-}
-
static int qcom_q6v5_register_dump_segments(struct rproc *rproc,
const struct firmware *mba_fw)
{
@@ -1357,6 +1319,8 @@ static int qcom_q6v5_register_dump_segments(struct rproc *rproc,
return ret;
}
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
+
ehdr = (struct elf32_hdr *)fw->data;
phdrs = (struct elf32_phdr *)(ehdr + 1);
qproc->dump_complete_mask = 0;
@@ -1384,7 +1348,6 @@ static int qcom_q6v5_register_dump_segments(struct rproc *rproc,
static const struct rproc_ops q6v5_ops = {
.start = q6v5_start,
.stop = q6v5_stop,
- .da_to_va = q6v5_da_to_va,
.parse_fw = qcom_q6v5_register_dump_segments,
.load = q6v5_load,
};
@@ -1432,36 +1395,12 @@ static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
qproc->halt_modem = args.args[1];
qproc->halt_nc = args.args[2];
- if (qproc->has_halt_nav) {
- struct platform_device *nav_pdev;
-
+ if (qproc->has_spare_reg) {
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
- "qcom,halt-nav-regs",
+ "qcom,spare-regs",
1, 0, &args);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to parse halt-nav-regs\n");
- return -EINVAL;
- }
-
- nav_pdev = of_find_device_by_node(args.np);
- of_node_put(args.np);
- if (!nav_pdev) {
- dev_err(&pdev->dev, "failed to get mss clock device\n");
- return -EPROBE_DEFER;
- }
-
- qproc->halt_nav_map = dev_get_regmap(&nav_pdev->dev, NULL);
- if (!qproc->halt_nav_map) {
- dev_err(&pdev->dev, "failed to get map from device\n");
- return -EINVAL;
- }
- qproc->halt_nav = args.args[0];
-
- ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
- "qcom,halt-nav-regs",
- 1, 1, &args);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to parse halt-nav-regs\n");
+ dev_err(&pdev->dev, "failed to parse spare-regs\n");
return -EINVAL;
}
@@ -1547,7 +1486,7 @@ static int q6v5_init_reset(struct q6v5 *qproc)
return PTR_ERR(qproc->mss_restart);
}
- if (qproc->has_alt_reset || qproc->has_halt_nav) {
+ if (qproc->has_alt_reset || qproc->has_spare_reg) {
qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev,
"pdc_reset");
if (IS_ERR(qproc->pdc_reset)) {
@@ -1566,8 +1505,17 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)
struct resource r;
int ret;
+ /*
+ * In the absence of mba/mpss sub-child, extract the mba and mpss
+ * reserved memory regions from device's memory-region property.
+ */
child = of_get_child_by_name(qproc->dev->of_node, "mba");
- node = of_parse_phandle(child, "memory-region", 0);
+ if (!child)
+ node = of_parse_phandle(qproc->dev->of_node,
+ "memory-region", 0);
+ else
+ node = of_parse_phandle(child, "memory-region", 0);
+
ret = of_address_to_resource(node, 0, &r);
if (ret) {
dev_err(qproc->dev, "unable to resolve mba region\n");
@@ -1584,8 +1532,14 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)
return -EBUSY;
}
- child = of_get_child_by_name(qproc->dev->of_node, "mpss");
- node = of_parse_phandle(child, "memory-region", 0);
+ if (!child) {
+ node = of_parse_phandle(qproc->dev->of_node,
+ "memory-region", 1);
+ } else {
+ child = of_get_child_by_name(qproc->dev->of_node, "mpss");
+ node = of_parse_phandle(child, "memory-region", 0);
+ }
+
ret = of_address_to_resource(node, 0, &r);
if (ret) {
dev_err(qproc->dev, "unable to resolve mpss region\n");
@@ -1595,12 +1549,6 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)
qproc->mpss_phys = qproc->mpss_reloc = r.start;
qproc->mpss_size = resource_size(&r);
- qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size);
- if (!qproc->mpss_region) {
- dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
- &r.start, qproc->mpss_size);
- return -EBUSY;
- }
return 0;
}
@@ -1667,6 +1615,7 @@ static int q6v5_probe(struct platform_device *pdev)
}
rproc->auto_boot = false;
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
qproc = (struct q6v5 *)rproc->priv;
qproc->dev = &pdev->dev;
@@ -1679,7 +1628,7 @@ static int q6v5_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, qproc);
- qproc->has_halt_nav = desc->has_halt_nav;
+ qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
goto free_rproc;
@@ -1759,7 +1708,7 @@ static int q6v5_probe(struct platform_device *pdev)
qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
- qcom_add_glink_subdev(rproc, &qproc->glink_subdev);
+ qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss");
qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
qcom_add_ipa_notify_subdev(rproc, &qproc->ipa_notify_subdev);
@@ -1828,8 +1777,6 @@ static const struct rproc_hexagon_res sc7180_mss = {
.active_clk_names = (char*[]){
"mnoc_axi",
"nav",
- "mss_nav",
- "mss_crypto",
NULL
},
.active_pd_names = (char*[]){
@@ -1844,7 +1791,7 @@ static const struct rproc_hexagon_res sc7180_mss = {
},
.need_mem_protection = true,
.has_alt_reset = false,
- .has_halt_nav = true,
+ .has_spare_reg = true,
.version = MSS_SC7180,
};
@@ -1879,7 +1826,7 @@ static const struct rproc_hexagon_res sdm845_mss = {
},
.need_mem_protection = true,
.has_alt_reset = true,
- .has_halt_nav = false,
+ .has_spare_reg = false,
.version = MSS_SDM845,
};
@@ -1906,7 +1853,7 @@ static const struct rproc_hexagon_res msm8998_mss = {
},
.need_mem_protection = true,
.has_alt_reset = false,
- .has_halt_nav = false,
+ .has_spare_reg = false,
.version = MSS_MSM8998,
};
@@ -1936,7 +1883,7 @@ static const struct rproc_hexagon_res msm8996_mss = {
},
.need_mem_protection = true,
.has_alt_reset = false,
- .has_halt_nav = false,
+ .has_spare_reg = false,
.version = MSS_MSM8996,
};
@@ -1969,7 +1916,7 @@ static const struct rproc_hexagon_res msm8916_mss = {
},
.need_mem_protection = false,
.has_alt_reset = false,
- .has_halt_nav = false,
+ .has_spare_reg = false,
.version = MSS_MSM8916,
};
@@ -2010,7 +1957,7 @@ static const struct rproc_hexagon_res msm8974_mss = {
},
.need_mem_protection = false,
.has_alt_reset = false,
- .has_halt_nav = false,
+ .has_spare_reg = false,
.version = MSS_MSM8974,
};
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 7a63efb85405..61791a03f648 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -398,6 +398,7 @@ static int adsp_probe(struct platform_device *pdev)
}
rproc->auto_boot = desc->auto_boot;
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
adsp = (struct qcom_adsp *)rproc->priv;
adsp->dev = &pdev->dev;
@@ -406,6 +407,8 @@ static int adsp_probe(struct platform_device *pdev)
adsp->has_aggre2_clk = desc->has_aggre2_clk;
platform_set_drvdata(pdev, adsp);
+ device_wakeup_enable(adsp->dev);
+
ret = adsp_alloc_memory_region(adsp);
if (ret)
goto free_rproc;
@@ -435,7 +438,7 @@ static int adsp_probe(struct platform_device *pdev)
if (ret)
goto detach_proxy_pds;
- qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
+ qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
adsp->sysmon = qcom_add_sysmon_subdev(rproc,
@@ -507,6 +510,26 @@ static const struct adsp_data sm8150_adsp_resource = {
.ssctl_id = 0x14,
};
+static const struct adsp_data sm8250_adsp_resource = {
+ .crash_reason_smem = 423,
+ .firmware_name = "adsp.mdt",
+ .pas_id = 1,
+ .has_aggre2_clk = false,
+ .auto_boot = true,
+ .active_pd_names = (char*[]){
+ "load_state",
+ NULL
+ },
+ .proxy_pd_names = (char*[]){
+ "lcx",
+ "lmx",
+ NULL
+ },
+ .ssr_name = "lpass",
+ .sysmon_name = "adsp",
+ .ssctl_id = 0x14,
+};
+
static const struct adsp_data msm8998_adsp_resource = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
@@ -552,6 +575,25 @@ static const struct adsp_data sm8150_cdsp_resource = {
.ssctl_id = 0x17,
};
+static const struct adsp_data sm8250_cdsp_resource = {
+ .crash_reason_smem = 601,
+ .firmware_name = "cdsp.mdt",
+ .pas_id = 18,
+ .has_aggre2_clk = false,
+ .auto_boot = true,
+ .active_pd_names = (char*[]){
+ "load_state",
+ NULL
+ },
+ .proxy_pd_names = (char*[]){
+ "cx",
+ NULL
+ },
+ .ssr_name = "cdsp",
+ .sysmon_name = "cdsp",
+ .ssctl_id = 0x17,
+};
+
static const struct adsp_data mpss_resource_init = {
.crash_reason_smem = 421,
.firmware_name = "modem.mdt",
@@ -603,6 +645,26 @@ static const struct adsp_data sm8150_slpi_resource = {
.ssctl_id = 0x16,
};
+static const struct adsp_data sm8250_slpi_resource = {
+ .crash_reason_smem = 424,
+ .firmware_name = "slpi.mdt",
+ .pas_id = 12,
+ .has_aggre2_clk = false,
+ .auto_boot = true,
+ .active_pd_names = (char*[]){
+ "load_state",
+ NULL
+ },
+ .proxy_pd_names = (char*[]){
+ "lcx",
+ "lmx",
+ NULL
+ },
+ .ssr_name = "dsps",
+ .sysmon_name = "slpi",
+ .ssctl_id = 0x16,
+};
+
static const struct adsp_data msm8998_slpi_resource = {
.crash_reason_smem = 424,
.firmware_name = "slpi.mdt",
@@ -637,12 +699,16 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
+ { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
{ .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
{ .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
{ .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
{ .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
{ .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
{ .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
+ { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
+ { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
+ { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
{ },
};
MODULE_DEVICE_TABLE(of, adsp_of_match);
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index f1924b740a10..88c76b9417fa 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -91,6 +91,9 @@ struct q6v5_wcss {
phys_addr_t mem_reloc;
void *mem_region;
size_t mem_size;
+
+ struct qcom_rproc_glink glink_subdev;
+ struct qcom_rproc_ssr ssr_subdev;
};
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -557,6 +560,9 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
+ qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
+ qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
+
ret = rproc_add(rproc);
if (ret)
goto free_rproc;
diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
index faf3822d8791..8d8996d714f0 100644
--- a/drivers/remoteproc/qcom_sysmon.c
+++ b/drivers/remoteproc/qcom_sysmon.c
@@ -46,6 +46,25 @@ struct qcom_sysmon {
struct sockaddr_qrtr ssctl;
};
+enum {
+ SSCTL_SSR_EVENT_BEFORE_POWERUP,
+ SSCTL_SSR_EVENT_AFTER_POWERUP,
+ SSCTL_SSR_EVENT_BEFORE_SHUTDOWN,
+ SSCTL_SSR_EVENT_AFTER_SHUTDOWN,
+};
+
+static const char * const sysmon_state_string[] = {
+ [SSCTL_SSR_EVENT_BEFORE_POWERUP] = "before_powerup",
+ [SSCTL_SSR_EVENT_AFTER_POWERUP] = "after_powerup",
+ [SSCTL_SSR_EVENT_BEFORE_SHUTDOWN] = "before_shutdown",
+ [SSCTL_SSR_EVENT_AFTER_SHUTDOWN] = "after_shutdown",
+};
+
+struct sysmon_event {
+ const char *subsys_name;
+ u32 ssr_event;
+};
+
static DEFINE_MUTEX(sysmon_lock);
static LIST_HEAD(sysmon_list);
@@ -54,13 +73,15 @@ static LIST_HEAD(sysmon_list);
* @sysmon: sysmon context
* @name: other remote's name
*/
-static void sysmon_send_event(struct qcom_sysmon *sysmon, const char *name)
+static void sysmon_send_event(struct qcom_sysmon *sysmon,
+ const struct sysmon_event *event)
{
char req[50];
int len;
int ret;
- len = snprintf(req, sizeof(req), "ssr:%s:before_shutdown", name);
+ len = snprintf(req, sizeof(req), "ssr:%s:%s", event->subsys_name,
+ sysmon_state_string[event->ssr_event]);
if (len >= sizeof(req))
return;
@@ -149,13 +170,6 @@ static int sysmon_callback(struct rpmsg_device *rpdev, void *data, int count,
#define SSCTL_SUBSYS_NAME_LENGTH 15
enum {
- SSCTL_SSR_EVENT_BEFORE_POWERUP,
- SSCTL_SSR_EVENT_AFTER_POWERUP,
- SSCTL_SSR_EVENT_BEFORE_SHUTDOWN,
- SSCTL_SSR_EVENT_AFTER_SHUTDOWN,
-};
-
-enum {
SSCTL_SSR_EVENT_FORCED,
SSCTL_SSR_EVENT_GRACEFUL,
};
@@ -331,7 +345,8 @@ static void ssctl_request_shutdown(struct qcom_sysmon *sysmon)
* @sysmon: sysmon context
* @name: other remote's name
*/
-static void ssctl_send_event(struct qcom_sysmon *sysmon, const char *name)
+static void ssctl_send_event(struct qcom_sysmon *sysmon,
+ const struct sysmon_event *event)
{
struct ssctl_subsys_event_resp resp;
struct ssctl_subsys_event_req req;
@@ -346,9 +361,9 @@ static void ssctl_send_event(struct qcom_sysmon *sysmon, const char *name)
}
memset(&req, 0, sizeof(req));
- strlcpy(req.subsys_name, name, sizeof(req.subsys_name));
+ strlcpy(req.subsys_name, event->subsys_name, sizeof(req.subsys_name));
req.subsys_name_len = strlen(req.subsys_name);
- req.event = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN;
+ req.event = event->ssr_event;
req.evt_driven_valid = true;
req.evt_driven = SSCTL_SSR_EVENT_FORCED;
@@ -424,16 +439,68 @@ static const struct qmi_ops ssctl_ops = {
.del_server = ssctl_del_server,
};
+static int sysmon_prepare(struct rproc_subdev *subdev)
+{
+ struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon,
+ subdev);
+ struct sysmon_event event = {
+ .subsys_name = sysmon->name,
+ .ssr_event = SSCTL_SSR_EVENT_BEFORE_POWERUP
+ };
+
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
+
+ return 0;
+}
+
+/**
+ * sysmon_start() - start callback for the sysmon remoteproc subdevice
+ * @subdev: instance of the sysmon subdevice
+ *
+ * Inform all the listners of sysmon notifications that the rproc associated
+ * to @subdev has booted up. The rproc that booted up also needs to know
+ * which rprocs are already up and running, so send start notifications
+ * on behalf of all the online rprocs.
+ */
static int sysmon_start(struct rproc_subdev *subdev)
{
+ struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon,
+ subdev);
+ struct qcom_sysmon *target;
+ struct sysmon_event event = {
+ .subsys_name = sysmon->name,
+ .ssr_event = SSCTL_SSR_EVENT_AFTER_POWERUP
+ };
+
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
+
+ mutex_lock(&sysmon_lock);
+ list_for_each_entry(target, &sysmon_list, node) {
+ if (target == sysmon ||
+ target->rproc->state != RPROC_RUNNING)
+ continue;
+
+ event.subsys_name = target->name;
+
+ if (sysmon->ssctl_version == 2)
+ ssctl_send_event(sysmon, &event);
+ else if (sysmon->ept)
+ sysmon_send_event(sysmon, &event);
+ }
+ mutex_unlock(&sysmon_lock);
+
return 0;
}
static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
{
struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon, subdev);
+ struct sysmon_event event = {
+ .subsys_name = sysmon->name,
+ .ssr_event = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN
+ };
- blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)sysmon->name);
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
/* Don't request graceful shutdown if we've crashed */
if (crashed)
@@ -445,6 +512,18 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
sysmon_request_shutdown(sysmon);
}
+static void sysmon_unprepare(struct rproc_subdev *subdev)
+{
+ struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon,
+ subdev);
+ struct sysmon_event event = {
+ .subsys_name = sysmon->name,
+ .ssr_event = SSCTL_SSR_EVENT_AFTER_SHUTDOWN
+ };
+
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
+}
+
/**
* sysmon_notify() - notify sysmon target of another's SSR
* @nb: notifier_block associated with sysmon instance
@@ -456,19 +535,20 @@ static int sysmon_notify(struct notifier_block *nb, unsigned long event,
{
struct qcom_sysmon *sysmon = container_of(nb, struct qcom_sysmon, nb);
struct rproc *rproc = sysmon->rproc;
- const char *ssr_name = data;
+ struct sysmon_event *sysmon_event = data;
/* Skip non-running rprocs and the originating instance */
- if (rproc->state != RPROC_RUNNING || !strcmp(data, sysmon->name)) {
+ if (rproc->state != RPROC_RUNNING ||
+ !strcmp(sysmon_event->subsys_name, sysmon->name)) {
dev_dbg(sysmon->dev, "not notifying %s\n", sysmon->name);
return NOTIFY_DONE;
}
/* Only SSCTL version 2 supports SSR events */
if (sysmon->ssctl_version == 2)
- ssctl_send_event(sysmon, ssr_name);
+ ssctl_send_event(sysmon, sysmon_event);
else if (sysmon->ept)
- sysmon_send_event(sysmon, ssr_name);
+ sysmon_send_event(sysmon, sysmon_event);
return NOTIFY_DONE;
}
@@ -543,8 +623,10 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
qmi_add_lookup(&sysmon->qmi, 43, 0, 0);
+ sysmon->subdev.prepare = sysmon_prepare;
sysmon->subdev.start = sysmon_start;
sysmon->subdev.stop = sysmon_stop;
+ sysmon->subdev.unprepare = sysmon_unprepare;
rproc_add_subdev(rproc, &sysmon->subdev);
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
index 0c7afd038f0d..5d65e1a9329a 100644
--- a/drivers/remoteproc/qcom_wcnss.c
+++ b/drivers/remoteproc/qcom_wcnss.c
@@ -480,6 +480,7 @@ static int wcnss_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
}
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
wcnss = (struct qcom_wcnss *)rproc->priv;
wcnss->dev = &pdev->dev;
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index e12a54e67588..9f04c30c4aaf 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -29,6 +29,7 @@
#include <linux/devcoredump.h>
#include <linux/rculist.h>
#include <linux/remoteproc.h>
+#include <linux/pm_runtime.h>
#include <linux/iommu.h>
#include <linux/idr.h>
#include <linux/elf.h>
@@ -517,7 +518,7 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
/* Initialise vdev subdevice */
snprintf(name, sizeof(name), "vdev%dbuffer", rvdev->index);
- rvdev->dev.parent = rproc->dev.parent;
+ rvdev->dev.parent = &rproc->dev;
rvdev->dev.dma_pfn_offset = rproc->dev.parent->dma_pfn_offset;
rvdev->dev.release = rproc_rvdev_release;
dev_set_name(&rvdev->dev, "%s#%s", dev_name(rvdev->dev.parent), name);
@@ -1382,6 +1383,12 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
if (ret)
return ret;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync failed: %d\n", ret);
+ return ret;
+ }
+
dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
/*
@@ -1391,7 +1398,14 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
ret = rproc_enable_iommu(rproc);
if (ret) {
dev_err(dev, "can't enable iommu: %d\n", ret);
- return ret;
+ goto put_pm_runtime;
+ }
+
+ /* Prepare rproc for firmware loading if needed */
+ ret = rproc_prepare_device(rproc);
+ if (ret) {
+ dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
+ goto disable_iommu;
}
rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
@@ -1399,7 +1413,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
/* Load resource table, core dump segment list etc from the firmware */
ret = rproc_parse_fw(rproc, fw);
if (ret)
- goto disable_iommu;
+ goto unprepare_rproc;
/* reset max_notifyid */
rproc->max_notifyid = -1;
@@ -1433,8 +1447,13 @@ clean_up_resources:
kfree(rproc->cached_table);
rproc->cached_table = NULL;
rproc->table_ptr = NULL;
+unprepare_rproc:
+ /* release HW resources if needed */
+ rproc_unprepare_device(rproc);
disable_iommu:
rproc_disable_iommu(rproc);
+put_pm_runtime:
+ pm_runtime_put(dev);
return ret;
}
@@ -1566,6 +1585,28 @@ int rproc_coredump_add_custom_segment(struct rproc *rproc,
EXPORT_SYMBOL(rproc_coredump_add_custom_segment);
/**
+ * rproc_coredump_set_elf_info() - set coredump elf information
+ * @rproc: handle of a remote processor
+ * @class: elf class for coredump elf file
+ * @machine: elf machine for coredump elf file
+ *
+ * Set elf information which will be used for coredump elf file.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int rproc_coredump_set_elf_info(struct rproc *rproc, u8 class, u16 machine)
+{
+ if (class != ELFCLASS64 && class != ELFCLASS32)
+ return -EINVAL;
+
+ rproc->elf_class = class;
+ rproc->elf_machine = machine;
+
+ return 0;
+}
+EXPORT_SYMBOL(rproc_coredump_set_elf_info);
+
+/**
* rproc_coredump() - perform coredump
* @rproc: rproc handle
*
@@ -1587,6 +1628,11 @@ static void rproc_coredump(struct rproc *rproc)
if (list_empty(&rproc->dump_segments))
return;
+ if (class == ELFCLASSNONE) {
+ dev_err(&rproc->dev, "Elf class is not set\n");
+ return;
+ }
+
data_size = elf_size_of_hdr(class);
list_for_each_entry(segment, &rproc->dump_segments, node) {
data_size += elf_size_of_phdr(class) + segment->size;
@@ -1605,7 +1651,7 @@ static void rproc_coredump(struct rproc *rproc)
elf_hdr_init_ident(ehdr, class);
elf_hdr_set_e_type(class, ehdr, ET_CORE);
- elf_hdr_set_e_machine(class, ehdr, EM_NONE);
+ elf_hdr_set_e_machine(class, ehdr, rproc->elf_machine);
elf_hdr_set_e_version(class, ehdr, EV_CURRENT);
elf_hdr_set_e_entry(class, ehdr, rproc->bootaddr);
elf_hdr_set_e_phoff(class, ehdr, elf_size_of_hdr(class));
@@ -1729,6 +1775,8 @@ static void rproc_crash_handler_work(struct work_struct *work)
if (!rproc->recovery_disabled)
rproc_trigger_recovery(rproc);
+
+ pm_relax(rproc->dev.parent);
}
/**
@@ -1838,8 +1886,13 @@ void rproc_shutdown(struct rproc *rproc)
/* clean up all acquired resources */
rproc_resource_cleanup(rproc);
+ /* release HW resources if needed */
+ rproc_unprepare_device(rproc);
+
rproc_disable_iommu(rproc);
+ pm_runtime_put(dev);
+
/* Free the copy of the resource table */
kfree(rproc->cached_table);
rproc->cached_table = NULL;
@@ -1949,6 +2002,33 @@ int rproc_add(struct rproc *rproc)
}
EXPORT_SYMBOL(rproc_add);
+static void devm_rproc_remove(void *rproc)
+{
+ rproc_del(rproc);
+}
+
+/**
+ * devm_rproc_add() - resource managed rproc_add()
+ * @dev: the underlying device
+ * @rproc: the remote processor handle to register
+ *
+ * This function performs like rproc_add() but the registered rproc device will
+ * automatically be removed on driver detach.
+ *
+ * Returns: 0 on success, negative errno on failure
+ */
+int devm_rproc_add(struct device *dev, struct rproc *rproc)
+{
+ int err;
+
+ err = rproc_add(rproc);
+ if (err)
+ return err;
+
+ return devm_add_action_or_reset(dev, devm_rproc_remove, rproc);
+}
+EXPORT_SYMBOL(devm_rproc_add);
+
/**
* rproc_type_release() - release a remote processor instance
* @dev: the rproc's device
@@ -1969,7 +2049,8 @@ static void rproc_type_release(struct device *dev)
if (rproc->index >= 0)
ida_simple_remove(&rproc_dev_index, rproc->index);
- kfree(rproc->firmware);
+ kfree_const(rproc->firmware);
+ kfree_const(rproc->name);
kfree(rproc->ops);
kfree(rproc);
}
@@ -1979,6 +2060,47 @@ static const struct device_type rproc_type = {
.release = rproc_type_release,
};
+static int rproc_alloc_firmware(struct rproc *rproc,
+ const char *name, const char *firmware)
+{
+ const char *p;
+
+ /*
+ * Allocate a firmware name if the caller gave us one to work
+ * with. Otherwise construct a new one using a default pattern.
+ */
+ if (firmware)
+ p = kstrdup_const(firmware, GFP_KERNEL);
+ else
+ p = kasprintf(GFP_KERNEL, "rproc-%s-fw", name);
+
+ if (!p)
+ return -ENOMEM;
+
+ rproc->firmware = p;
+
+ return 0;
+}
+
+static int rproc_alloc_ops(struct rproc *rproc, const struct rproc_ops *ops)
+{
+ rproc->ops = kmemdup(ops, sizeof(*ops), GFP_KERNEL);
+ if (!rproc->ops)
+ return -ENOMEM;
+
+ if (rproc->ops->load)
+ return 0;
+
+ /* Default to ELF loader if no load function is specified */
+ rproc->ops->load = rproc_elf_load_segments;
+ rproc->ops->parse_fw = rproc_elf_load_rsc_table;
+ rproc->ops->find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table;
+ rproc->ops->sanity_check = rproc_elf_sanity_check;
+ rproc->ops->get_boot_addr = rproc_elf_get_boot_addr;
+
+ return 0;
+}
+
/**
* rproc_alloc() - allocate a remote processor handle
* @dev: the underlying device
@@ -2007,79 +2129,49 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
const char *firmware, int len)
{
struct rproc *rproc;
- char *p, *template = "rproc-%s-fw";
- int name_len;
if (!dev || !name || !ops)
return NULL;
- if (!firmware) {
- /*
- * If the caller didn't pass in a firmware name then
- * construct a default name.
- */
- name_len = strlen(name) + strlen(template) - 2 + 1;
- p = kmalloc(name_len, GFP_KERNEL);
- if (!p)
- return NULL;
- snprintf(p, name_len, template, name);
- } else {
- p = kstrdup(firmware, GFP_KERNEL);
- if (!p)
- return NULL;
- }
-
rproc = kzalloc(sizeof(struct rproc) + len, GFP_KERNEL);
- if (!rproc) {
- kfree(p);
- return NULL;
- }
-
- rproc->ops = kmemdup(ops, sizeof(*ops), GFP_KERNEL);
- if (!rproc->ops) {
- kfree(p);
- kfree(rproc);
+ if (!rproc)
return NULL;
- }
- rproc->firmware = p;
- rproc->name = name;
rproc->priv = &rproc[1];
rproc->auto_boot = true;
- rproc->elf_class = ELFCLASS32;
+ rproc->elf_class = ELFCLASSNONE;
+ rproc->elf_machine = EM_NONE;
device_initialize(&rproc->dev);
rproc->dev.parent = dev;
rproc->dev.type = &rproc_type;
rproc->dev.class = &rproc_class;
rproc->dev.driver_data = rproc;
+ idr_init(&rproc->notifyids);
+
+ rproc->name = kstrdup_const(name, GFP_KERNEL);
+ if (!rproc->name)
+ goto put_device;
+
+ if (rproc_alloc_firmware(rproc, name, firmware))
+ goto put_device;
+
+ if (rproc_alloc_ops(rproc, ops))
+ goto put_device;
/* Assign a unique device index and name */
rproc->index = ida_simple_get(&rproc_dev_index, 0, 0, GFP_KERNEL);
if (rproc->index < 0) {
dev_err(dev, "ida_simple_get failed: %d\n", rproc->index);
- put_device(&rproc->dev);
- return NULL;
+ goto put_device;
}
dev_set_name(&rproc->dev, "remoteproc%d", rproc->index);
atomic_set(&rproc->power, 0);
- /* Default to ELF loader if no load function is specified */
- if (!rproc->ops->load) {
- rproc->ops->load = rproc_elf_load_segments;
- rproc->ops->parse_fw = rproc_elf_load_rsc_table;
- rproc->ops->find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table;
- if (!rproc->ops->sanity_check)
- rproc->ops->sanity_check = rproc_elf32_sanity_check;
- rproc->ops->get_boot_addr = rproc_elf_get_boot_addr;
- }
-
mutex_init(&rproc->lock);
- idr_init(&rproc->notifyids);
-
INIT_LIST_HEAD(&rproc->carveouts);
INIT_LIST_HEAD(&rproc->mappings);
INIT_LIST_HEAD(&rproc->traces);
@@ -2091,7 +2183,14 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
rproc->state = RPROC_OFFLINE;
+ pm_runtime_no_callbacks(&rproc->dev);
+ pm_runtime_enable(&rproc->dev);
+
return rproc;
+
+put_device:
+ put_device(&rproc->dev);
+ return NULL;
}
EXPORT_SYMBOL(rproc_alloc);
@@ -2106,6 +2205,7 @@ EXPORT_SYMBOL(rproc_alloc);
*/
void rproc_free(struct rproc *rproc)
{
+ pm_runtime_disable(&rproc->dev);
put_device(&rproc->dev);
}
EXPORT_SYMBOL(rproc_free);
@@ -2171,6 +2271,46 @@ int rproc_del(struct rproc *rproc)
}
EXPORT_SYMBOL(rproc_del);
+static void devm_rproc_free(struct device *dev, void *res)
+{
+ rproc_free(*(struct rproc **)res);
+}
+
+/**
+ * devm_rproc_alloc() - resource managed rproc_alloc()
+ * @dev: the underlying device
+ * @name: name of this remote processor
+ * @ops: platform-specific handlers (mainly start/stop)
+ * @firmware: name of firmware file to load, can be NULL
+ * @len: length of private data needed by the rproc driver (in bytes)
+ *
+ * This function performs like rproc_alloc() but the acquired rproc device will
+ * automatically be released on driver detach.
+ *
+ * Returns: new rproc instance, or NULL on failure
+ */
+struct rproc *devm_rproc_alloc(struct device *dev, const char *name,
+ const struct rproc_ops *ops,
+ const char *firmware, int len)
+{
+ struct rproc **ptr, *rproc;
+
+ ptr = devres_alloc(devm_rproc_free, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ rproc = rproc_alloc(dev, name, ops, firmware, len);
+ if (rproc) {
+ *ptr = rproc;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return rproc;
+}
+EXPORT_SYMBOL(devm_rproc_alloc);
+
/**
* rproc_add_subdev() - add a subdevice to a remoteproc
* @rproc: rproc handle to add the subdevice to
@@ -2230,6 +2370,9 @@ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type)
return;
}
+ /* Prevent suspend while the remoteproc is being recovered */
+ pm_stay_awake(rproc->dev.parent);
+
dev_err(&rproc->dev, "crash detected in %s: type %s\n",
rproc->name, rproc_crash_to_string(type));
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index d734cadb16e3..732770e92b99 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -269,17 +269,7 @@ static int rproc_rsc_table_show(struct seq_file *seq, void *p)
return 0;
}
-static int rproc_rsc_table_open(struct inode *inode, struct file *file)
-{
- return single_open(file, rproc_rsc_table_show, inode->i_private);
-}
-
-static const struct file_operations rproc_rsc_table_ops = {
- .open = rproc_rsc_table_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(rproc_rsc_table);
/* Expose carveout content via debugfs */
static int rproc_carveouts_show(struct seq_file *seq, void *p)
@@ -299,17 +289,7 @@ static int rproc_carveouts_show(struct seq_file *seq, void *p)
return 0;
}
-static int rproc_carveouts_open(struct inode *inode, struct file *file)
-{
- return single_open(file, rproc_carveouts_show, inode->i_private);
-}
-
-static const struct file_operations rproc_carveouts_ops = {
- .open = rproc_carveouts_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(rproc_carveouts);
void rproc_remove_trace_file(struct dentry *tfile)
{
@@ -354,9 +334,9 @@ void rproc_create_debug_dir(struct rproc *rproc)
debugfs_create_file("crash", 0200, rproc->dbg_dir,
rproc, &rproc_crash_ops);
debugfs_create_file("resource_table", 0400, rproc->dbg_dir,
- rproc, &rproc_rsc_table_ops);
+ rproc, &rproc_rsc_table_fops);
debugfs_create_file("carveout_memories", 0400, rproc->dbg_dir,
- rproc, &rproc_carveouts_ops);
+ rproc, &rproc_carveouts_fops);
}
void __init rproc_init_debugfs(void)
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index 16e2c496fd45..df68d87752e4 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -113,27 +113,6 @@ int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
EXPORT_SYMBOL(rproc_elf_sanity_check);
/**
- * rproc_elf_sanity_check() - Sanity Check ELF32 firmware image
- * @rproc: the remote processor handle
- * @fw: the ELF32 firmware image
- *
- * Make sure this fw image is sane.
- */
-int rproc_elf32_sanity_check(struct rproc *rproc, const struct firmware *fw)
-{
- int ret = rproc_elf_sanity_check(rproc, fw);
-
- if (ret)
- return ret;
-
- if (fw_elf_get_class(fw) == ELFCLASS32)
- return 0;
-
- return -EINVAL;
-}
-EXPORT_SYMBOL(rproc_elf32_sanity_check);
-
-/**
* rproc_elf_get_boot_addr() - Get rproc's boot address.
* @rproc: the remote processor handle
* @fw: the ELF firmware image
@@ -248,9 +227,6 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
memset(ptr + filesz, 0, memsz - filesz);
}
- if (ret == 0)
- rproc->elf_class = class;
-
return ret;
}
EXPORT_SYMBOL(rproc_elf_load_segments);
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index b389dc79da81..4ba7cb59d3e8 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -54,7 +54,6 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len);
phys_addr_t rproc_va_to_pa(void *cpu_addr);
int rproc_trigger_recovery(struct rproc *rproc);
-int rproc_elf32_sanity_check(struct rproc *rproc, const struct firmware *fw);
int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw);
u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw);
int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw);
@@ -64,6 +63,22 @@ struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
struct rproc_mem_entry *
rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);
+static inline int rproc_prepare_device(struct rproc *rproc)
+{
+ if (rproc->ops->prepare)
+ return rproc->ops->prepare(rproc);
+
+ return 0;
+}
+
+static inline int rproc_unprepare_device(struct rproc *rproc)
+{
+ if (rproc->ops->unprepare)
+ return rproc->ops->unprepare(rproc);
+
+ return 0;
+}
+
static inline
int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
{
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index e61d738d9b47..dfd3808c34fd 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -337,8 +337,7 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
if (rproc->ops->kick == NULL) {
ret = -EINVAL;
- dev_err(dev, ".kick method not defined for %s",
- rproc->name);
+ dev_err(dev, ".kick method not defined for %s\n", rproc->name);
goto out;
}
@@ -376,6 +375,18 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
goto out;
}
}
+ } else {
+ struct device_node *np = rproc->dev.parent->of_node;
+
+ /*
+ * If we don't have dedicated buffer, just attempt to re-assign
+ * the reserved memory from our parent. A default memory-region
+ * at index 0 from the parent's memory-regions is assigned for
+ * the rvdev dev to allocate from. Failure is non-critical and
+ * the allocations will fall back to global pools, so don't
+ * check return value either.
+ */
+ of_reserved_mem_device_init_by_idx(dev, np, 0);
}
/* Allocate virtio device */
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
index a6cbfa452764..a3268d95a50e 100644
--- a/drivers/remoteproc/st_remoteproc.c
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -233,7 +233,7 @@ static const struct rproc_ops st_rproc_ops = {
.parse_fw = st_rproc_parse_fw,
.load = rproc_elf_load_segments,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
- .sanity_check = rproc_elf32_sanity_check,
+ .sanity_check = rproc_elf_sanity_check,
.get_boot_addr = rproc_elf_get_boot_addr,
};
diff --git a/drivers/remoteproc/st_slim_rproc.c b/drivers/remoteproc/st_slim_rproc.c
index 3cca8b65a8db..09bcb4d8b9e0 100644
--- a/drivers/remoteproc/st_slim_rproc.c
+++ b/drivers/remoteproc/st_slim_rproc.c
@@ -203,7 +203,7 @@ static const struct rproc_ops slim_rproc_ops = {
.da_to_va = slim_rproc_da_to_va,
.get_boot_addr = rproc_elf_get_boot_addr,
.load = rproc_elf_load_segments,
- .sanity_check = rproc_elf32_sanity_check,
+ .sanity_check = rproc_elf_sanity_check,
};
/**
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 0bdd56f02f18..062797a447c6 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -506,7 +506,7 @@ static struct rproc_ops st_rproc_ops = {
.load = rproc_elf_load_segments,
.parse_fw = stm32_rproc_parse_fw,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
- .sanity_check = rproc_elf32_sanity_check,
+ .sanity_check = rproc_elf_sanity_check,
.get_boot_addr = rproc_elf_get_boot_addr,
};
@@ -626,6 +626,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (!rproc)
return -ENOMEM;
+ rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
rproc->has_iommu = false;
ddata = rproc->priv;
ddata->workqueue = create_workqueue(dev_name(dev));
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index a9108ff563dc..f96716893c2a 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -24,13 +24,13 @@ config RPMSG_MTK_SCP
remote processors in MediaTek platforms.
This use IPI and IPC to communicate with remote processors.
-config RPMSG_QCOM_GLINK_NATIVE
+config RPMSG_QCOM_GLINK
tristate
select RPMSG
config RPMSG_QCOM_GLINK_RPM
tristate "Qualcomm RPM Glink driver"
- select RPMSG_QCOM_GLINK_NATIVE
+ select RPMSG_QCOM_GLINK
depends on HAS_IOMEM
depends on MAILBOX
help
@@ -40,7 +40,7 @@ config RPMSG_QCOM_GLINK_RPM
config RPMSG_QCOM_GLINK_SMEM
tristate "Qualcomm SMEM Glink driver"
- select RPMSG_QCOM_GLINK_NATIVE
+ select RPMSG_QCOM_GLINK
depends on MAILBOX
depends on QCOM_SMEM
help
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
index ae92a7fb08f6..ffe932ef6050 100644
--- a/drivers/rpmsg/Makefile
+++ b/drivers/rpmsg/Makefile
@@ -2,8 +2,9 @@
obj-$(CONFIG_RPMSG) += rpmsg_core.o
obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o
+qcom_glink-objs := qcom_glink_native.o qcom_glink_ssr.o
+obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
-obj-$(CONFIG_RPMSG_QCOM_GLINK_NATIVE) += qcom_glink_native.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o
diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/rpmsg/qcom_glink_ssr.c
index d7babe3d67bc..dcd1ce616974 100644
--- a/drivers/soc/qcom/glink_ssr.c
+++ b/drivers/rpmsg/qcom_glink_ssr.c
@@ -54,6 +54,19 @@ struct glink_ssr {
struct completion completion;
};
+/* Notifier list for all registered glink_ssr instances */
+static BLOCKING_NOTIFIER_HEAD(ssr_notifiers);
+
+/**
+ * qcom_glink_ssr_notify() - notify GLINK SSR about stopped remoteproc
+ * @ssr_name: name of the remoteproc that has been stopped
+ */
+void qcom_glink_ssr_notify(const char *ssr_name)
+{
+ blocking_notifier_call_chain(&ssr_notifiers, 0, (void *)ssr_name);
+}
+EXPORT_SYMBOL_GPL(qcom_glink_ssr_notify);
+
static int qcom_glink_ssr_callback(struct rpmsg_device *rpdev,
void *data, int len, void *priv, u32 addr)
{
@@ -81,8 +94,9 @@ static int qcom_glink_ssr_callback(struct rpmsg_device *rpdev,
return 0;
}
-static int qcom_glink_ssr_notify(struct notifier_block *nb, unsigned long event,
- void *data)
+static int qcom_glink_ssr_notifier_call(struct notifier_block *nb,
+ unsigned long event,
+ void *data)
{
struct glink_ssr *ssr = container_of(nb, struct glink_ssr, nb);
struct do_cleanup_msg msg;
@@ -121,18 +135,18 @@ static int qcom_glink_ssr_probe(struct rpmsg_device *rpdev)
ssr->dev = &rpdev->dev;
ssr->ept = rpdev->ept;
- ssr->nb.notifier_call = qcom_glink_ssr_notify;
+ ssr->nb.notifier_call = qcom_glink_ssr_notifier_call;
dev_set_drvdata(&rpdev->dev, ssr);
- return qcom_register_ssr_notifier(&ssr->nb);
+ return blocking_notifier_chain_register(&ssr_notifiers, &ssr->nb);
}
static void qcom_glink_ssr_remove(struct rpmsg_device *rpdev)
{
struct glink_ssr *ssr = dev_get_drvdata(&rpdev->dev);
- qcom_unregister_ssr_notifier(&ssr->nb);
+ blocking_notifier_chain_unregister(&ssr_notifiers, &ssr->nb);
}
static const struct rpmsg_device_id qcom_glink_ssr_match[] = {
@@ -150,7 +164,3 @@ static struct rpmsg_driver qcom_glink_ssr_driver = {
},
};
module_rpmsg_driver(qcom_glink_ssr_driver);
-
-MODULE_ALIAS("rpmsg:glink_ssr");
-MODULE_DESCRIPTION("Qualcomm GLINK SSR notifier");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index e330ec4dfc33..a6361cad608b 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -284,7 +284,7 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
EXPORT_SYMBOL(rpmsg_trysend_offchannel);
/*
- * match an rpmsg channel with a channel info struct.
+ * match a rpmsg channel with a channel info struct.
* this is used to make sure we're not creating rpmsg devices for channels
* that already exist.
*/
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 376ebbf880d6..07d4f3374098 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -89,7 +89,7 @@ struct rpmsg_hdr {
u32 reserved;
u16 len;
u16 flags;
- u8 data[0];
+ u8 data[];
} __packed;
/**
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
index 23eae4188876..a9235f111e79 100644
--- a/drivers/s390/cio/Makefile
+++ b/drivers/s390/cio/Makefile
@@ -21,5 +21,5 @@ qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_setup.o
obj-$(CONFIG_QDIO) += qdio.o
vfio_ccw-objs += vfio_ccw_drv.o vfio_ccw_cp.o vfio_ccw_ops.o vfio_ccw_fsm.o \
- vfio_ccw_async.o vfio_ccw_trace.o
+ vfio_ccw_async.o vfio_ccw_trace.o vfio_ccw_chp.o
obj-$(CONFIG_VFIO_CCW) += vfio_ccw.o
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 1ca73c2e5a8f..c314e9495c1b 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -57,6 +57,7 @@ int chsc_error_from_response(int response)
case 0x0104:
return -EINVAL;
case 0x0004:
+ case 0x0106: /* "Wrong Channel Parm" for the op 0x003d */
return -EOPNOTSUPP;
case 0x000b:
case 0x0107: /* "Channel busy" for the op 0x003d */
@@ -1336,36 +1337,35 @@ out:
EXPORT_SYMBOL_GPL(chsc_scm_info);
/**
- * chsc_pnso_brinfo() - Perform Network-Subchannel Operation, Bridge Info.
+ * chsc_pnso() - Perform Network-Subchannel Operation
* @schid: id of the subchannel on which PNSO is performed
- * @brinfo_area: request and response block for the operation
+ * @pnso_area: request and response block for the operation
* @resume_token: resume token for multiblock response
* @cnc: Boolean change-notification control
*
- * brinfo_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)
+ * pnso_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)
*
* Returns 0 on success.
*/
-int chsc_pnso_brinfo(struct subchannel_id schid,
- struct chsc_pnso_area *brinfo_area,
- struct chsc_brinfo_resume_token resume_token,
- int cnc)
+int chsc_pnso(struct subchannel_id schid,
+ struct chsc_pnso_area *pnso_area,
+ struct chsc_pnso_resume_token resume_token,
+ int cnc)
{
- memset(brinfo_area, 0, sizeof(*brinfo_area));
- brinfo_area->request.length = 0x0030;
- brinfo_area->request.code = 0x003d; /* network-subchannel operation */
- brinfo_area->m = schid.m;
- brinfo_area->ssid = schid.ssid;
- brinfo_area->sch = schid.sch_no;
- brinfo_area->cssid = schid.cssid;
- brinfo_area->oc = 0; /* Store-network-bridging-information list */
- brinfo_area->resume_token = resume_token;
- brinfo_area->n = (cnc != 0);
- if (chsc(brinfo_area))
+ memset(pnso_area, 0, sizeof(*pnso_area));
+ pnso_area->request.length = 0x0030;
+ pnso_area->request.code = 0x003d; /* network-subchannel operation */
+ pnso_area->m = schid.m;
+ pnso_area->ssid = schid.ssid;
+ pnso_area->sch = schid.sch_no;
+ pnso_area->cssid = schid.cssid;
+ pnso_area->oc = 0; /* Store-network-bridging-information list */
+ pnso_area->resume_token = resume_token;
+ pnso_area->n = (cnc != 0);
+ if (chsc(pnso_area))
return -EIO;
- return chsc_error_from_response(brinfo_area->response.code);
+ return chsc_error_from_response(pnso_area->response.code);
}
-EXPORT_SYMBOL_GPL(chsc_pnso_brinfo);
int chsc_sgib(u32 origin)
{
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index 34de6d77442c..7ecf7e4c402e 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -205,52 +205,10 @@ struct chsc_scm_info {
int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token);
-struct chsc_brinfo_resume_token {
- u64 t1;
- u64 t2;
-} __packed;
-
-struct chsc_brinfo_naihdr {
- struct chsc_brinfo_resume_token resume_token;
- u32:32;
- u32 instance;
- u32:24;
- u8 naids;
- u32 reserved[3];
-} __packed;
-
-struct chsc_pnso_area {
- struct chsc_header request;
- u8:2;
- u8 m:1;
- u8:5;
- u8:2;
- u8 ssid:2;
- u8 fmt:4;
- u16 sch;
- u8:8;
- u8 cssid;
- u16:16;
- u8 oc;
- u32:24;
- struct chsc_brinfo_resume_token resume_token;
- u32 n:1;
- u32:31;
- u32 reserved[3];
- struct chsc_header response;
- u32:32;
- struct chsc_brinfo_naihdr naihdr;
- union {
- struct qdio_brinfo_entry_l3_ipv6 l3_ipv6[0];
- struct qdio_brinfo_entry_l3_ipv4 l3_ipv4[0];
- struct qdio_brinfo_entry_l2 l2[0];
- } entries;
-} __packed __aligned(PAGE_SIZE);
-
-int chsc_pnso_brinfo(struct subchannel_id schid,
- struct chsc_pnso_area *brinfo_area,
- struct chsc_brinfo_resume_token resume_token,
- int cnc);
+int chsc_pnso(struct subchannel_id schid,
+ struct chsc_pnso_area *pnso_area,
+ struct chsc_pnso_resume_token resume_token,
+ int cnc);
int __init chsc_get_cssid(int idx);
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index ccecf6b9504e..963fcc9054c6 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -710,6 +710,29 @@ void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid)
}
EXPORT_SYMBOL_GPL(ccw_device_get_schid);
+/**
+ * ccw_device_pnso() - Perform Network-Subchannel Operation
+ * @cdev: device on which PNSO is performed
+ * @pnso_area: request and response block for the operation
+ * @resume_token: resume token for multiblock response
+ * @cnc: Boolean change-notification control
+ *
+ * pnso_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)
+ *
+ * Returns 0 on success.
+ */
+int ccw_device_pnso(struct ccw_device *cdev,
+ struct chsc_pnso_area *pnso_area,
+ struct chsc_pnso_resume_token resume_token,
+ int cnc)
+{
+ struct subchannel_id schid;
+
+ ccw_device_get_schid(cdev, &schid);
+ return chsc_pnso(schid, pnso_area, resume_token, cnc);
+}
+EXPORT_SYMBOL_GPL(ccw_device_pnso);
+
/*
* Allocate zeroed dma coherent 31 bit addressable memory using
* the subchannels dma pool. Maximal size of allocation supported
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index 77d0ea7b381b..45f9c0736be4 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -59,18 +59,6 @@ static inline int idset_contains(struct idset *set, int ssid, int id)
return test_bit(ssid * set->num_id + id, set->bitmap);
}
-static inline int idset_get_first(struct idset *set, int *ssid, int *id)
-{
- int bitnum;
-
- bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id);
- if (bitnum >= set->num_ssid * set->num_id)
- return 0;
- *ssid = bitnum / set->num_id;
- *id = bitnum % set->num_id;
- return 1;
-}
-
struct idset *idset_sch_new(void)
{
return idset_new(max_ssid + 1, __MAX_SUBCHANNEL + 1);
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index b8453b594679..eb13c479e11d 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -221,9 +221,6 @@ struct qdio_q {
*/
int first_to_check;
- /* beginning position for calling the program */
- int first_to_kick;
-
/* number of buffers in use by the adapter */
atomic_t nr_buf_used;
@@ -292,6 +289,8 @@ struct qdio_irq {
struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ];
+ unsigned int max_input_qs;
+ unsigned int max_output_qs;
void (*irq_poll)(struct ccw_device *cdev, unsigned long data);
unsigned long poll_state;
@@ -364,16 +363,13 @@ static inline int multicast_outbound(struct qdio_q *q)
extern u64 last_ai_time;
/* prototypes for thin interrupt */
-void qdio_setup_thinint(struct qdio_irq *irq_ptr);
int qdio_establish_thinint(struct qdio_irq *irq_ptr);
void qdio_shutdown_thinint(struct qdio_irq *irq_ptr);
void tiqdio_add_device(struct qdio_irq *irq_ptr);
void tiqdio_remove_device(struct qdio_irq *irq_ptr);
void tiqdio_inbound_processing(unsigned long q);
-int tiqdio_allocate_memory(void);
-void tiqdio_free_memory(void);
-int tiqdio_register_thinints(void);
-void tiqdio_unregister_thinints(void);
+int qdio_thinint_init(void);
+void qdio_thinint_exit(void);
int test_nonshared_ind(struct qdio_irq *);
/* prototypes for setup */
@@ -389,8 +385,10 @@ int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr,
struct subchannel_id *schid,
struct qdio_ssqd_desc *data);
int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
+void qdio_shutdown_irq(struct qdio_irq *irq);
void qdio_print_subchannel_info(struct qdio_irq *irq_ptr);
-void qdio_release_memory(struct qdio_irq *irq_ptr);
+void qdio_free_queues(struct qdio_irq *irq_ptr);
+void qdio_free_async_data(struct qdio_irq *irq_ptr);
int qdio_setup_init(void);
void qdio_setup_exit(void);
int qdio_enable_async_operation(struct qdio_output_q *q);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index bcc3ab14e72d..610c05f59589 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -143,7 +143,7 @@ again:
DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE, q->nr,
- q->first_to_kick, count, q->irq_ptr->int_parm);
+ q->first_to_check, count, q->irq_ptr->int_parm);
return 0;
}
}
@@ -191,7 +191,7 @@ again:
DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE, q->nr,
- q->first_to_kick, count, q->irq_ptr->int_parm);
+ q->first_to_check, count, q->irq_ptr->int_parm);
return 0;
}
}
@@ -438,15 +438,12 @@ static void process_buffer_error(struct qdio_q *q, unsigned int start,
q->sbal[start]->element[15].sflags);
}
-static inline void inbound_primed(struct qdio_q *q, unsigned int start,
- int count)
+static inline void inbound_handle_work(struct qdio_q *q, unsigned int start,
+ int count, bool auto_ack)
{
int new;
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim:%1d %02x", q->nr, count);
-
- /* for QEBSM the ACK was already set by EQBS */
- if (is_qebsm(q)) {
+ if (auto_ack) {
if (!q->u.in.ack_count) {
q->u.in.ack_count = count;
q->u.in.ack_start = start;
@@ -466,15 +463,14 @@ static inline void inbound_primed(struct qdio_q *q, unsigned int start,
* or by the next inbound run.
*/
new = add_buf(start, count - 1);
- if (q->u.in.ack_count) {
- /* reset the previous ACK but first set the new one */
- set_buf_state(q, new, SLSB_P_INPUT_ACK);
- set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
- } else {
- q->u.in.ack_count = 1;
- set_buf_state(q, new, SLSB_P_INPUT_ACK);
- }
+ set_buf_state(q, new, SLSB_P_INPUT_ACK);
+
+ /* delete the previous ACKs */
+ if (q->u.in.ack_count)
+ set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
+ q->u.in.ack_count);
+ q->u.in.ack_count = 1;
q->u.in.ack_start = new;
count--;
if (!count)
@@ -508,19 +504,21 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
switch (state) {
case SLSB_P_INPUT_PRIMED:
- inbound_primed(q, start, count);
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim:%1d %02x", q->nr,
+ count);
+
+ inbound_handle_work(q, start, count, is_qebsm(q));
if (atomic_sub_return(count, &q->nr_buf_used) == 0)
qperf_inc(q, inbound_queue_full);
if (q->irq_ptr->perf_stat_enabled)
account_sbals(q, count);
return count;
case SLSB_P_INPUT_ERROR:
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in err:%1d %02x", q->nr,
+ count);
+
process_buffer_error(q, start, count);
- /*
- * Interrupts may be avoided as long as the error is present
- * so change the buffer state immediately to avoid starvation.
- */
- set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count);
+ inbound_handle_work(q, start, count, false);
if (atomic_sub_return(count, &q->nr_buf_used) == 0)
qperf_inc(q, inbound_queue_full);
if (q->irq_ptr->perf_stat_enabled)
@@ -624,10 +622,9 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
return phys_aob;
}
-static void qdio_kick_handler(struct qdio_q *q, unsigned int count)
+static void qdio_kick_handler(struct qdio_q *q, unsigned int start,
+ unsigned int count)
{
- int start = q->first_to_kick;
-
if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return;
@@ -644,7 +641,6 @@ static void qdio_kick_handler(struct qdio_q *q, unsigned int count)
q->irq_ptr->int_parm);
/* for the next time */
- q->first_to_kick = add_buf(start, count);
q->qdio_error = 0;
}
@@ -668,9 +664,9 @@ static void __qdio_inbound_processing(struct qdio_q *q)
if (count == 0)
return;
+ qdio_kick_handler(q, start, count);
start = add_buf(start, count);
q->first_to_check = start;
- qdio_kick_handler(q, count);
if (!qdio_inbound_q_done(q, start)) {
/* means poll time is not yet over */
@@ -826,7 +822,7 @@ static void __qdio_outbound_processing(struct qdio_q *q)
count = qdio_outbound_q_moved(q, start);
if (count) {
q->first_to_check = add_buf(start, count);
- qdio_kick_handler(q, count);
+ qdio_kick_handler(q, start, count);
}
if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) &&
@@ -880,47 +876,17 @@ static inline void qdio_check_outbound_pci_queues(struct qdio_irq *irq)
qdio_tasklet_schedule(out);
}
-static void __tiqdio_inbound_processing(struct qdio_q *q)
+void tiqdio_inbound_processing(unsigned long data)
{
- unsigned int start = q->first_to_check;
- int count;
+ struct qdio_q *q = (struct qdio_q *)data;
- qperf_inc(q, tasklet_inbound);
if (need_siga_sync(q) && need_siga_sync_after_ai(q))
qdio_sync_queues(q);
/* The interrupt could be caused by a PCI request: */
qdio_check_outbound_pci_queues(q->irq_ptr);
- count = qdio_inbound_q_moved(q, start);
- if (count == 0)
- return;
-
- start = add_buf(start, count);
- q->first_to_check = start;
- qdio_kick_handler(q, count);
-
- if (!qdio_inbound_q_done(q, start)) {
- qperf_inc(q, tasklet_inbound_resched);
- if (!qdio_tasklet_schedule(q))
- return;
- }
-
- qdio_stop_polling(q);
- /*
- * We need to check again to not lose initiative after
- * resetting the ACK state.
- */
- if (!qdio_inbound_q_done(q, start)) {
- qperf_inc(q, tasklet_inbound_resched2);
- qdio_tasklet_schedule(q);
- }
-}
-
-void tiqdio_inbound_processing(unsigned long data)
-{
- struct qdio_q *q = (struct qdio_q *)data;
- __tiqdio_inbound_processing(q);
+ __qdio_inbound_processing(q);
}
static inline void qdio_set_state(struct qdio_irq *irq_ptr,
@@ -977,7 +943,6 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
{
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
struct qdio_q *q;
- int count;
DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no);
DBF_ERROR("intp :%lx", intparm);
@@ -992,9 +957,8 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
goto no_handler;
}
- count = sub_buf(q->first_to_check, q->first_to_kick);
q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE,
- q->nr, q->first_to_kick, count, irq_ptr->int_parm);
+ q->nr, q->first_to_check, 0, irq_ptr->int_parm);
no_handler:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
/*
@@ -1154,35 +1118,27 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
/* cleanup subchannel */
spin_lock_irq(get_ccwdev_lock(cdev));
-
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
if (how & QDIO_FLAG_CLEANUP_USING_CLEAR)
rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP);
else
/* default behaviour is halt */
rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP);
+ spin_unlock_irq(get_ccwdev_lock(cdev));
if (rc) {
DBF_ERROR("%4x SHUTD ERR", irq_ptr->schid.sch_no);
DBF_ERROR("rc:%4d", rc);
goto no_cleanup;
}
- qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
- spin_unlock_irq(get_ccwdev_lock(cdev));
wait_event_interruptible_timeout(cdev->private->wait_q,
irq_ptr->state == QDIO_IRQ_STATE_INACTIVE ||
irq_ptr->state == QDIO_IRQ_STATE_ERR,
10 * HZ);
- spin_lock_irq(get_ccwdev_lock(cdev));
no_cleanup:
qdio_shutdown_thinint(irq_ptr);
-
- /* restore interrupt handler */
- if ((void *)cdev->handler == (void *)qdio_int_handler) {
- cdev->handler = irq_ptr->orig_handler;
- cdev->private->intparm = 0;
- }
- spin_unlock_irq(get_ccwdev_lock(cdev));
+ qdio_shutdown_irq(irq_ptr);
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
mutex_unlock(&irq_ptr->setup_mutex);
@@ -1213,7 +1169,11 @@ int qdio_free(struct ccw_device *cdev)
cdev->private->qdio_data = NULL;
mutex_unlock(&irq_ptr->setup_mutex);
- qdio_release_memory(irq_ptr);
+ qdio_free_async_data(irq_ptr);
+ qdio_free_queues(irq_ptr);
+ free_page((unsigned long) irq_ptr->qdr);
+ free_page(irq_ptr->chsc_page);
+ free_page((unsigned long) irq_ptr);
return 0;
}
EXPORT_SYMBOL_GPL(qdio_free);
@@ -1229,6 +1189,7 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
{
struct subchannel_id schid;
struct qdio_irq *irq_ptr;
+ int rc = -ENOMEM;
ccw_device_get_schid(cdev, &schid);
DBF_EVENT("qallocate:%4x", schid.sch_no);
@@ -1240,12 +1201,12 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
/* irq_ptr must be in GFP_DMA since it contains ccw1.cda */
irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!irq_ptr)
- goto out_err;
+ return -ENOMEM;
irq_ptr->cdev = cdev;
mutex_init(&irq_ptr->setup_mutex);
if (qdio_allocate_dbf(irq_ptr))
- goto out_rel;
+ goto err_dbf;
DBF_DEV_EVENT(DBF_ERR, irq_ptr, "alloc niq:%1u noq:%1u", no_input_qs,
no_output_qs);
@@ -1258,24 +1219,30 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
*/
irq_ptr->chsc_page = get_zeroed_page(GFP_KERNEL);
if (!irq_ptr->chsc_page)
- goto out_rel;
+ goto err_chsc;
/* qdr is used in ccw1.cda which is u32 */
irq_ptr->qdr = (struct qdr *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!irq_ptr->qdr)
- goto out_rel;
+ goto err_qdr;
- if (qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs))
- goto out_rel;
+ rc = qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs);
+ if (rc)
+ goto err_queues;
INIT_LIST_HEAD(&irq_ptr->entry);
cdev->private->qdio_data = irq_ptr;
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
return 0;
-out_rel:
- qdio_release_memory(irq_ptr);
-out_err:
- return -ENOMEM;
+
+err_queues:
+ free_page((unsigned long) irq_ptr->qdr);
+err_qdr:
+ free_page(irq_ptr->chsc_page);
+err_chsc:
+err_dbf:
+ free_page((unsigned long) irq_ptr);
+ return rc;
}
EXPORT_SYMBOL_GPL(qdio_allocate);
@@ -1338,6 +1305,10 @@ int qdio_establish(struct ccw_device *cdev,
if (!irq_ptr)
return -ENODEV;
+ if (init_data->no_input_qs > irq_ptr->max_input_qs ||
+ init_data->no_output_qs > irq_ptr->max_output_qs)
+ return -EINVAL;
+
if ((init_data->no_input_qs && !init_data->input_handler) ||
(init_data->no_output_qs && !init_data->output_handler))
return -EINVAL;
@@ -1352,8 +1323,8 @@ int qdio_establish(struct ccw_device *cdev,
rc = qdio_establish_thinint(irq_ptr);
if (rc) {
+ qdio_shutdown_irq(irq_ptr);
mutex_unlock(&irq_ptr->setup_mutex);
- qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
return rc;
}
@@ -1371,8 +1342,9 @@ int qdio_establish(struct ccw_device *cdev,
if (rc) {
DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no);
DBF_ERROR("rc:%4x", rc);
+ qdio_shutdown_thinint(irq_ptr);
+ qdio_shutdown_irq(irq_ptr);
mutex_unlock(&irq_ptr->setup_mutex);
- qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
return rc;
}
@@ -1460,25 +1432,6 @@ out:
}
EXPORT_SYMBOL_GPL(qdio_activate);
-static inline int buf_in_between(int bufnr, int start, int count)
-{
- int end = add_buf(start, count);
-
- if (end > start) {
- if (bufnr >= start && bufnr < end)
- return 1;
- else
- return 0;
- }
-
- /* wrap-around case */
- if ((bufnr >= start && bufnr <= QDIO_MAX_BUFFERS_PER_Q) ||
- (bufnr < end))
- return 1;
- else
- return 0;
-}
-
/**
* handle_inbound - reset processed input buffers
* @q: queue containing the buffers
@@ -1489,36 +1442,18 @@ static inline int buf_in_between(int bufnr, int start, int count)
static int handle_inbound(struct qdio_q *q, unsigned int callflags,
int bufnr, int count)
{
- int diff;
+ int overlap;
qperf_inc(q, inbound_call);
- if (!q->u.in.ack_count)
- goto set;
-
- /* protect against stop polling setting an ACK for an emptied slsb */
- if (count == QDIO_MAX_BUFFERS_PER_Q) {
- /* overwriting everything, just delete polling status */
- q->u.in.ack_count = 0;
- goto set;
- } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
- if (is_qebsm(q)) {
- /* partial overwrite, just update ack_start */
- diff = add_buf(bufnr, count);
- diff = sub_buf(diff, q->u.in.ack_start);
- q->u.in.ack_count -= diff;
- if (q->u.in.ack_count <= 0) {
- q->u.in.ack_count = 0;
- goto set;
- }
- q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
- } else {
- /* the only ACK will be deleted */
- q->u.in.ack_count = 0;
- }
+ /* If any ACKed SBALs are returned to HW, adjust ACK tracking: */
+ overlap = min(count - sub_buf(q->u.in.ack_start, bufnr),
+ q->u.in.ack_count);
+ if (overlap > 0) {
+ q->u.in.ack_start = add_buf(q->u.in.ack_start, overlap);
+ q->u.in.ack_count -= overlap;
}
-set:
count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
atomic_add(count, &q->nr_buf_used);
@@ -1627,7 +1562,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
EXPORT_SYMBOL_GPL(do_QDIO);
/**
- * qdio_start_irq - process input buffers
+ * qdio_start_irq - enable interrupt processing for the device
* @cdev: associated ccw_device for the qdio subchannel
*
* Return codes
@@ -1770,94 +1705,6 @@ int qdio_stop_irq(struct ccw_device *cdev)
}
EXPORT_SYMBOL(qdio_stop_irq);
-/**
- * qdio_pnso_brinfo() - perform network subchannel op #0 - bridge info.
- * @schid: Subchannel ID.
- * @cnc: Boolean Change-Notification Control
- * @response: Response code will be stored at this address
- * @cb: Callback function will be executed for each element
- * of the address list
- * @priv: Pointer to pass to the callback function.
- *
- * Performs "Store-network-bridging-information list" operation and calls
- * the callback function for every entry in the list. If "change-
- * notification-control" is set, further changes in the address list
- * will be reported via the IPA command.
- */
-int qdio_pnso_brinfo(struct subchannel_id schid,
- int cnc, u16 *response,
- void (*cb)(void *priv, enum qdio_brinfo_entry_type type,
- void *entry),
- void *priv)
-{
- struct chsc_pnso_area *rr;
- int rc;
- u32 prev_instance = 0;
- int isfirstblock = 1;
- int i, size, elems;
-
- rr = (struct chsc_pnso_area *)get_zeroed_page(GFP_KERNEL);
- if (rr == NULL)
- return -ENOMEM;
- do {
- /* on the first iteration, naihdr.resume_token will be zero */
- rc = chsc_pnso_brinfo(schid, rr, rr->naihdr.resume_token, cnc);
- if (rc != 0 && rc != -EBUSY)
- goto out;
- if (rr->response.code != 1) {
- rc = -EIO;
- continue;
- } else
- rc = 0;
-
- if (cb == NULL)
- continue;
-
- size = rr->naihdr.naids;
- elems = (rr->response.length -
- sizeof(struct chsc_header) -
- sizeof(struct chsc_brinfo_naihdr)) /
- size;
-
- if (!isfirstblock && (rr->naihdr.instance != prev_instance)) {
- /* Inform the caller that they need to scrap */
- /* the data that was already reported via cb */
- rc = -EAGAIN;
- break;
- }
- isfirstblock = 0;
- prev_instance = rr->naihdr.instance;
- for (i = 0; i < elems; i++)
- switch (size) {
- case sizeof(struct qdio_brinfo_entry_l3_ipv6):
- (*cb)(priv, l3_ipv6_addr,
- &rr->entries.l3_ipv6[i]);
- break;
- case sizeof(struct qdio_brinfo_entry_l3_ipv4):
- (*cb)(priv, l3_ipv4_addr,
- &rr->entries.l3_ipv4[i]);
- break;
- case sizeof(struct qdio_brinfo_entry_l2):
- (*cb)(priv, l2_addr_lnid,
- &rr->entries.l2[i]);
- break;
- default:
- WARN_ON_ONCE(1);
- rc = -EIO;
- goto out;
- }
- } while (rr->response.code == 0x0107 || /* channel busy */
- (rr->response.code == 1 && /* list stored */
- /* resume token is non-zero => list incomplete */
- (rr->naihdr.resume_token.t1 || rr->naihdr.resume_token.t2)));
- (*response) = rr->response.code;
-
-out:
- free_page((unsigned long)rr);
- return rc;
-}
-EXPORT_SYMBOL_GPL(qdio_pnso_brinfo);
-
static int __init init_QDIO(void)
{
int rc;
@@ -1868,16 +1715,11 @@ static int __init init_QDIO(void)
rc = qdio_setup_init();
if (rc)
goto out_debug;
- rc = tiqdio_allocate_memory();
+ rc = qdio_thinint_init();
if (rc)
goto out_cache;
- rc = tiqdio_register_thinints();
- if (rc)
- goto out_ti;
return 0;
-out_ti:
- tiqdio_free_memory();
out_cache:
qdio_setup_exit();
out_debug:
@@ -1887,8 +1729,7 @@ out_debug:
static void __exit exit_QDIO(void)
{
- tiqdio_unregister_thinints();
- tiqdio_free_memory();
+ qdio_thinint_exit();
qdio_setup_exit();
qdio_debug_exit();
}
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 3083edd61f0c..2c5cc6ec668e 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -135,6 +135,27 @@ output:
}
}
+static void __qdio_free_queues(struct qdio_q **queues, unsigned int count)
+{
+ struct qdio_q *q;
+ unsigned int i;
+
+ for (i = 0; i < count; i++) {
+ q = queues[i];
+ free_page((unsigned long) q->slib);
+ kmem_cache_free(qdio_q_cache, q);
+ }
+}
+
+void qdio_free_queues(struct qdio_irq *irq_ptr)
+{
+ __qdio_free_queues(irq_ptr->input_qs, irq_ptr->max_input_qs);
+ irq_ptr->max_input_qs = 0;
+
+ __qdio_free_queues(irq_ptr->output_qs, irq_ptr->max_output_qs);
+ irq_ptr->max_output_qs = 0;
+}
+
static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
{
struct qdio_q *q;
@@ -142,12 +163,15 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
for (i = 0; i < nr_queues; i++) {
q = kmem_cache_zalloc(qdio_q_cache, GFP_KERNEL);
- if (!q)
+ if (!q) {
+ __qdio_free_queues(irq_ptr_qs, i);
return -ENOMEM;
+ }
q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
if (!q->slib) {
kmem_cache_free(qdio_q_cache, q);
+ __qdio_free_queues(irq_ptr_qs, i);
return -ENOMEM;
}
irq_ptr_qs[i] = q;
@@ -162,8 +186,16 @@ int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, int nr_output_qs
rc = __qdio_allocate_qs(irq_ptr->input_qs, nr_input_qs);
if (rc)
return rc;
+
rc = __qdio_allocate_qs(irq_ptr->output_qs, nr_output_qs);
- return rc;
+ if (rc) {
+ __qdio_free_queues(irq_ptr->input_qs, nr_input_qs);
+ return rc;
+ }
+
+ irq_ptr->max_input_qs = nr_input_qs;
+ irq_ptr->max_output_qs = nr_output_qs;
+ return 0;
}
static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
@@ -347,45 +379,28 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac);
}
-void qdio_release_memory(struct qdio_irq *irq_ptr)
+void qdio_free_async_data(struct qdio_irq *irq_ptr)
{
struct qdio_q *q;
int i;
- /*
- * Must check queue array manually since irq_ptr->nr_input_queues /
- * irq_ptr->nr_input_queues may not yet be set.
- */
- for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) {
- q = irq_ptr->input_qs[i];
- if (q) {
- free_page((unsigned long) q->slib);
- kmem_cache_free(qdio_q_cache, q);
- }
- }
- for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) {
+ for (i = 0; i < irq_ptr->max_output_qs; i++) {
q = irq_ptr->output_qs[i];
- if (q) {
- if (q->u.out.use_cq) {
- int n;
-
- for (n = 0; n < QDIO_MAX_BUFFERS_PER_Q; ++n) {
- struct qaob *aob = q->u.out.aobs[n];
- if (aob) {
- qdio_release_aob(aob);
- q->u.out.aobs[n] = NULL;
- }
- }
+ if (q->u.out.use_cq) {
+ unsigned int n;
+
+ for (n = 0; n < QDIO_MAX_BUFFERS_PER_Q; n++) {
+ struct qaob *aob = q->u.out.aobs[n];
- qdio_disable_async_operation(&q->u.out);
+ if (aob) {
+ qdio_release_aob(aob);
+ q->u.out.aobs[n] = NULL;
+ }
}
- free_page((unsigned long) q->slib);
- kmem_cache_free(qdio_q_cache, q);
+
+ qdio_disable_async_operation(&q->u.out);
}
}
- free_page((unsigned long) irq_ptr->qdr);
- free_page(irq_ptr->chsc_page);
- free_page((unsigned long) irq_ptr);
}
static void __qdio_allocate_fill_qdr(struct qdio_irq *irq_ptr,
@@ -480,7 +495,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
}
setup_qib(irq_ptr, init_data);
- qdio_setup_thinint(irq_ptr);
set_impl_params(irq_ptr, init_data->qib_param_field_format,
init_data->qib_param_field,
init_data->input_slib_elements,
@@ -491,6 +505,12 @@ int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
/* qdr, qib, sls, slsbs, slibs, sbales are filled now */
+ /* set our IRQ handler */
+ spin_lock_irq(get_ccwdev_lock(cdev));
+ irq_ptr->orig_handler = cdev->handler;
+ cdev->handler = qdio_int_handler;
+ spin_unlock_irq(get_ccwdev_lock(cdev));
+
/* get qdio commands */
ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE);
if (!ciw) {
@@ -506,12 +526,18 @@ int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
}
irq_ptr->aqueue = *ciw;
- /* set new interrupt handler */
+ return 0;
+}
+
+void qdio_shutdown_irq(struct qdio_irq *irq)
+{
+ struct ccw_device *cdev = irq->cdev;
+
+ /* restore IRQ handler */
spin_lock_irq(get_ccwdev_lock(cdev));
- irq_ptr->orig_handler = cdev->handler;
- cdev->handler = qdio_int_handler;
+ cdev->handler = irq->orig_handler;
+ cdev->private->intparm = 0;
spin_unlock_irq(get_ccwdev_lock(cdev));
- return 0;
}
void qdio_print_subchannel_info(struct qdio_irq *irq_ptr)
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index ae50373617cd..7a440e4328cd 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -197,47 +197,21 @@ out:
return rc;
}
-/* allocate non-shared indicators and shared indicator */
-int __init tiqdio_allocate_memory(void)
-{
- q_indicators = kcalloc(TIQDIO_NR_INDICATORS,
- sizeof(struct indicator_t),
- GFP_KERNEL);
- if (!q_indicators)
- return -ENOMEM;
- return 0;
-}
-
-void tiqdio_free_memory(void)
-{
- kfree(q_indicators);
-}
-
-int __init tiqdio_register_thinints(void)
+int qdio_establish_thinint(struct qdio_irq *irq_ptr)
{
int rc;
- rc = register_adapter_interrupt(&tiqdio_airq);
- if (rc) {
- DBF_EVENT("RTI:%x", rc);
- return rc;
- }
- return 0;
-}
-
-int qdio_establish_thinint(struct qdio_irq *irq_ptr)
-{
if (!is_thinint_irq(irq_ptr))
return 0;
- return set_subchannel_ind(irq_ptr, 0);
-}
-void qdio_setup_thinint(struct qdio_irq *irq_ptr)
-{
- if (!is_thinint_irq(irq_ptr))
- return;
irq_ptr->dsci = get_indicator();
DBF_HEX(&irq_ptr->dsci, sizeof(void *));
+
+ rc = set_subchannel_ind(irq_ptr, 0);
+ if (rc)
+ put_indicator(irq_ptr->dsci);
+
+ return rc;
}
void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
@@ -250,8 +224,27 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
put_indicator(irq_ptr->dsci);
}
-void __exit tiqdio_unregister_thinints(void)
+int __init qdio_thinint_init(void)
+{
+ int rc;
+
+ q_indicators = kcalloc(TIQDIO_NR_INDICATORS, sizeof(struct indicator_t),
+ GFP_KERNEL);
+ if (!q_indicators)
+ return -ENOMEM;
+
+ rc = register_adapter_interrupt(&tiqdio_airq);
+ if (rc) {
+ DBF_EVENT("RTI:%x", rc);
+ kfree(q_indicators);
+ return rc;
+ }
+ return 0;
+}
+
+void __exit qdio_thinint_exit(void)
{
WARN_ON(!list_empty(&tiq_list));
unregister_adapter_interrupt(&tiqdio_airq);
+ kfree(q_indicators);
}
diff --git a/drivers/s390/cio/vfio_ccw_chp.c b/drivers/s390/cio/vfio_ccw_chp.c
new file mode 100644
index 000000000000..a646fc81c872
--- /dev/null
+++ b/drivers/s390/cio/vfio_ccw_chp.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Channel path related status regions for vfio_ccw
+ *
+ * Copyright IBM Corp. 2020
+ *
+ * Author(s): Farhan Ali <alifm@linux.ibm.com>
+ * Eric Farman <farman@linux.ibm.com>
+ */
+
+#include <linux/vfio.h>
+#include "vfio_ccw_private.h"
+
+static ssize_t vfio_ccw_schib_region_read(struct vfio_ccw_private *private,
+ char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS;
+ loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
+ struct ccw_schib_region *region;
+ int ret;
+
+ if (pos + count > sizeof(*region))
+ return -EINVAL;
+
+ mutex_lock(&private->io_mutex);
+ region = private->region[i].data;
+
+ if (cio_update_schib(private->sch)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ memcpy(region, &private->sch->schib, sizeof(*region));
+
+ if (copy_to_user(buf, (void *)region + pos, count)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = count;
+
+out:
+ mutex_unlock(&private->io_mutex);
+ return ret;
+}
+
+static ssize_t vfio_ccw_schib_region_write(struct vfio_ccw_private *private,
+ const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+
+static void vfio_ccw_schib_region_release(struct vfio_ccw_private *private,
+ struct vfio_ccw_region *region)
+{
+
+}
+
+static const struct vfio_ccw_regops vfio_ccw_schib_region_ops = {
+ .read = vfio_ccw_schib_region_read,
+ .write = vfio_ccw_schib_region_write,
+ .release = vfio_ccw_schib_region_release,
+};
+
+int vfio_ccw_register_schib_dev_regions(struct vfio_ccw_private *private)
+{
+ return vfio_ccw_register_dev_region(private,
+ VFIO_REGION_SUBTYPE_CCW_SCHIB,
+ &vfio_ccw_schib_region_ops,
+ sizeof(struct ccw_schib_region),
+ VFIO_REGION_INFO_FLAG_READ,
+ private->schib_region);
+}
+
+static ssize_t vfio_ccw_crw_region_read(struct vfio_ccw_private *private,
+ char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS;
+ loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
+ struct ccw_crw_region *region;
+ struct vfio_ccw_crw *crw;
+ int ret;
+
+ if (pos + count > sizeof(*region))
+ return -EINVAL;
+
+ crw = list_first_entry_or_null(&private->crw,
+ struct vfio_ccw_crw, next);
+
+ if (crw)
+ list_del(&crw->next);
+
+ mutex_lock(&private->io_mutex);
+ region = private->region[i].data;
+
+ if (crw)
+ memcpy(&region->crw, &crw->crw, sizeof(region->crw));
+
+ if (copy_to_user(buf, (void *)region + pos, count))
+ ret = -EFAULT;
+ else
+ ret = count;
+
+ region->crw = 0;
+
+ mutex_unlock(&private->io_mutex);
+
+ kfree(crw);
+
+ /* Notify the guest if more CRWs are on our queue */
+ if (!list_empty(&private->crw) && private->crw_trigger)
+ eventfd_signal(private->crw_trigger, 1);
+
+ return ret;
+}
+
+static ssize_t vfio_ccw_crw_region_write(struct vfio_ccw_private *private,
+ const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static void vfio_ccw_crw_region_release(struct vfio_ccw_private *private,
+ struct vfio_ccw_region *region)
+{
+
+}
+
+static const struct vfio_ccw_regops vfio_ccw_crw_region_ops = {
+ .read = vfio_ccw_crw_region_read,
+ .write = vfio_ccw_crw_region_write,
+ .release = vfio_ccw_crw_region_release,
+};
+
+int vfio_ccw_register_crw_dev_regions(struct vfio_ccw_private *private)
+{
+ return vfio_ccw_register_dev_region(private,
+ VFIO_REGION_SUBTYPE_CCW_CRW,
+ &vfio_ccw_crw_region_ops,
+ sizeof(struct ccw_crw_region),
+ VFIO_REGION_INFO_FLAG_READ,
+ private->crw_region);
+}
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index 3645d1720c4b..b9febc581b1f 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -8,6 +8,7 @@
* Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
*/
+#include <linux/ratelimit.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/iommu.h>
@@ -625,23 +626,27 @@ static int ccwchain_fetch_one(struct ccwchain *chain,
* the target channel program from @orb->cmd.iova to the new ccwchain(s).
*
* Limitations:
- * 1. Supports only prefetch enabled mode.
- * 2. Supports idal(c64) ccw chaining.
- * 3. Supports 4k idaw.
+ * 1. Supports idal(c64) ccw chaining.
+ * 2. Supports 4k idaw.
*
* Returns:
* %0 on success and a negative error value on failure.
*/
int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
{
+ /* custom ratelimit used to avoid flood during guest IPL */
+ static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 1);
int ret;
/*
- * XXX:
- * Only support prefetch enable mode now.
+ * We only support prefetching the channel program. We assume all channel
+ * programs executed by supported guests likewise support prefetching.
+ * Executing a channel program that does not specify prefetching will
+ * typically not cause an error, but a warning is issued to help identify
+ * the problem if something does break.
*/
- if (!orb->cmd.pfch)
- return -EOPNOTSUPP;
+ if (!orb->cmd.pfch && __ratelimit(&ratelimit_state))
+ dev_warn(mdev, "Prefetching channel program even though prefetch not specified in ORB");
INIT_LIST_HEAD(&cp->ccwchain_list);
memcpy(&cp->orb, orb, sizeof(*orb));
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 339a6bc0339b..8c625b530035 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -19,6 +19,7 @@
#include <asm/isc.h>
+#include "chp.h"
#include "ioasm.h"
#include "css.h"
#include "vfio_ccw_private.h"
@@ -26,6 +27,8 @@
struct workqueue_struct *vfio_ccw_work_q;
static struct kmem_cache *vfio_ccw_io_region;
static struct kmem_cache *vfio_ccw_cmd_region;
+static struct kmem_cache *vfio_ccw_schib_region;
+static struct kmem_cache *vfio_ccw_crw_region;
debug_info_t *vfio_ccw_debug_msg_id;
debug_info_t *vfio_ccw_debug_trace_id;
@@ -105,6 +108,16 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
eventfd_signal(private->io_trigger, 1);
}
+static void vfio_ccw_crw_todo(struct work_struct *work)
+{
+ struct vfio_ccw_private *private;
+
+ private = container_of(work, struct vfio_ccw_private, crw_work);
+
+ if (!list_empty(&private->crw) && private->crw_trigger)
+ eventfd_signal(private->crw_trigger, 1);
+}
+
/*
* Css driver callbacks
*/
@@ -116,6 +129,18 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
}
+static void vfio_ccw_free_regions(struct vfio_ccw_private *private)
+{
+ if (private->crw_region)
+ kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
+ if (private->schib_region)
+ kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
+ if (private->cmd_region)
+ kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
+ if (private->io_region)
+ kmem_cache_free(vfio_ccw_io_region, private->io_region);
+}
+
static int vfio_ccw_sch_probe(struct subchannel *sch)
{
struct pmcw *pmcw = &sch->schib.pmcw;
@@ -147,6 +172,18 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
if (!private->cmd_region)
goto out_free;
+ private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,
+ GFP_KERNEL | GFP_DMA);
+
+ if (!private->schib_region)
+ goto out_free;
+
+ private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region,
+ GFP_KERNEL | GFP_DMA);
+
+ if (!private->crw_region)
+ goto out_free;
+
private->sch = sch;
dev_set_drvdata(&sch->dev, private);
mutex_init(&private->io_mutex);
@@ -159,7 +196,9 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
if (ret)
goto out_free;
+ INIT_LIST_HEAD(&private->crw);
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
+ INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
atomic_set(&private->avail, 1);
private->state = VFIO_CCW_STATE_STANDBY;
@@ -181,10 +220,7 @@ out_disable:
cio_disable_subchannel(sch);
out_free:
dev_set_drvdata(&sch->dev, NULL);
- if (private->cmd_region)
- kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
- if (private->io_region)
- kmem_cache_free(vfio_ccw_io_region, private->io_region);
+ vfio_ccw_free_regions(private);
kfree(private->cp.guest_cp);
kfree(private);
return ret;
@@ -193,15 +229,20 @@ out_free:
static int vfio_ccw_sch_remove(struct subchannel *sch)
{
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
+ struct vfio_ccw_crw *crw, *temp;
vfio_ccw_sch_quiesce(sch);
+ list_for_each_entry_safe(crw, temp, &private->crw, next) {
+ list_del(&crw->next);
+ kfree(crw);
+ }
+
vfio_ccw_mdev_unreg(sch);
dev_set_drvdata(&sch->dev, NULL);
- kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
- kmem_cache_free(vfio_ccw_io_region, private->io_region);
+ vfio_ccw_free_regions(private);
kfree(private->cp.guest_cp);
kfree(private);
@@ -258,6 +299,83 @@ out_unlock:
return rc;
}
+static void vfio_ccw_queue_crw(struct vfio_ccw_private *private,
+ unsigned int rsc,
+ unsigned int erc,
+ unsigned int rsid)
+{
+ struct vfio_ccw_crw *crw;
+
+ /*
+ * If unable to allocate a CRW, just drop the event and
+ * carry on. The guest will either see a later one or
+ * learn when it issues its own store subchannel.
+ */
+ crw = kzalloc(sizeof(*crw), GFP_ATOMIC);
+ if (!crw)
+ return;
+
+ /*
+ * Build the CRW based on the inputs given to us.
+ */
+ crw->crw.rsc = rsc;
+ crw->crw.erc = erc;
+ crw->crw.rsid = rsid;
+
+ list_add_tail(&crw->next, &private->crw);
+ queue_work(vfio_ccw_work_q, &private->crw_work);
+}
+
+static int vfio_ccw_chp_event(struct subchannel *sch,
+ struct chp_link *link, int event)
+{
+ struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
+ int mask = chp_ssd_get_mask(&sch->ssd_info, link);
+ int retry = 255;
+
+ if (!private || !mask)
+ return 0;
+
+ trace_vfio_ccw_chp_event(private->sch->schid, mask, event);
+ VFIO_CCW_MSG_EVENT(2, "%pUl (%x.%x.%04x): mask=0x%x event=%d\n",
+ mdev_uuid(private->mdev), sch->schid.cssid,
+ sch->schid.ssid, sch->schid.sch_no,
+ mask, event);
+
+ if (cio_update_schib(sch))
+ return -ENODEV;
+
+ switch (event) {
+ case CHP_VARY_OFF:
+ /* Path logically turned off */
+ sch->opm &= ~mask;
+ sch->lpm &= ~mask;
+ if (sch->schib.pmcw.lpum & mask)
+ cio_cancel_halt_clear(sch, &retry);
+ break;
+ case CHP_OFFLINE:
+ /* Path is gone */
+ if (sch->schib.pmcw.lpum & mask)
+ cio_cancel_halt_clear(sch, &retry);
+ vfio_ccw_queue_crw(private, CRW_RSC_CPATH, CRW_ERC_PERRN,
+ link->chpid.id);
+ break;
+ case CHP_VARY_ON:
+ /* Path logically turned on */
+ sch->opm |= mask;
+ sch->lpm |= mask;
+ break;
+ case CHP_ONLINE:
+ /* Path became available */
+ sch->lpm |= mask & sch->opm;
+ vfio_ccw_queue_crw(private, CRW_RSC_CPATH, CRW_ERC_INIT,
+ link->chpid.id);
+ break;
+ }
+
+ return 0;
+}
+
static struct css_device_id vfio_ccw_sch_ids[] = {
{ .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
{ /* end of list */ },
@@ -275,6 +393,7 @@ static struct css_driver vfio_ccw_sch_driver = {
.remove = vfio_ccw_sch_remove,
.shutdown = vfio_ccw_sch_shutdown,
.sch_event = vfio_ccw_sch_event,
+ .chp_event = vfio_ccw_chp_event,
};
static int __init vfio_ccw_debug_init(void)
@@ -304,6 +423,14 @@ static void vfio_ccw_debug_exit(void)
debug_unregister(vfio_ccw_debug_trace_id);
}
+static void vfio_ccw_destroy_regions(void)
+{
+ kmem_cache_destroy(vfio_ccw_crw_region);
+ kmem_cache_destroy(vfio_ccw_schib_region);
+ kmem_cache_destroy(vfio_ccw_cmd_region);
+ kmem_cache_destroy(vfio_ccw_io_region);
+}
+
static int __init vfio_ccw_sch_init(void)
{
int ret;
@@ -336,6 +463,26 @@ static int __init vfio_ccw_sch_init(void)
goto out_err;
}
+ vfio_ccw_schib_region = kmem_cache_create_usercopy("vfio_ccw_schib_region",
+ sizeof(struct ccw_schib_region), 0,
+ SLAB_ACCOUNT, 0,
+ sizeof(struct ccw_schib_region), NULL);
+
+ if (!vfio_ccw_schib_region) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ vfio_ccw_crw_region = kmem_cache_create_usercopy("vfio_ccw_crw_region",
+ sizeof(struct ccw_crw_region), 0,
+ SLAB_ACCOUNT, 0,
+ sizeof(struct ccw_crw_region), NULL);
+
+ if (!vfio_ccw_crw_region) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
isc_register(VFIO_CCW_ISC);
ret = css_driver_register(&vfio_ccw_sch_driver);
if (ret) {
@@ -346,8 +493,7 @@ static int __init vfio_ccw_sch_init(void)
return ret;
out_err:
- kmem_cache_destroy(vfio_ccw_cmd_region);
- kmem_cache_destroy(vfio_ccw_io_region);
+ vfio_ccw_destroy_regions();
destroy_workqueue(vfio_ccw_work_q);
vfio_ccw_debug_exit();
return ret;
@@ -357,8 +503,7 @@ static void __exit vfio_ccw_sch_exit(void)
{
css_driver_unregister(&vfio_ccw_sch_driver);
isc_unregister(VFIO_CCW_ISC);
- kmem_cache_destroy(vfio_ccw_io_region);
- kmem_cache_destroy(vfio_ccw_cmd_region);
+ vfio_ccw_destroy_regions();
destroy_workqueue(vfio_ccw_work_q);
vfio_ccw_debug_exit();
}
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index f0d71ab77c50..8b3ed5b45277 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -172,8 +172,22 @@ static int vfio_ccw_mdev_open(struct mdev_device *mdev)
ret = vfio_ccw_register_async_dev_regions(private);
if (ret)
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
- &private->nb);
+ goto out_unregister;
+
+ ret = vfio_ccw_register_schib_dev_regions(private);
+ if (ret)
+ goto out_unregister;
+
+ ret = vfio_ccw_register_crw_dev_regions(private);
+ if (ret)
+ goto out_unregister;
+
+ return ret;
+
+out_unregister:
+ vfio_ccw_unregister_dev_regions(private);
+ vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+ &private->nb);
return ret;
}
@@ -181,7 +195,6 @@ static void vfio_ccw_mdev_release(struct mdev_device *mdev)
{
struct vfio_ccw_private *private =
dev_get_drvdata(mdev_parent_dev(mdev));
- int i;
if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
(private->state != VFIO_CCW_STATE_STANDBY)) {
@@ -191,15 +204,9 @@ static void vfio_ccw_mdev_release(struct mdev_device *mdev)
}
cp_free(&private->cp);
+ vfio_ccw_unregister_dev_regions(private);
vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
&private->nb);
-
- for (i = 0; i < private->num_regions; i++)
- private->region[i].ops->release(private, &private->region[i]);
-
- private->num_regions = 0;
- kfree(private->region);
- private->region = NULL;
}
static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
@@ -384,17 +391,22 @@ static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
{
- if (info->index != VFIO_CCW_IO_IRQ_INDEX)
+ switch (info->index) {
+ case VFIO_CCW_IO_IRQ_INDEX:
+ case VFIO_CCW_CRW_IRQ_INDEX:
+ info->count = 1;
+ info->flags = VFIO_IRQ_INFO_EVENTFD;
+ break;
+ default:
return -EINVAL;
-
- info->count = 1;
- info->flags = VFIO_IRQ_INFO_EVENTFD;
+ }
return 0;
}
static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
uint32_t flags,
+ uint32_t index,
void __user *data)
{
struct vfio_ccw_private *private;
@@ -404,7 +416,17 @@ static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
return -EINVAL;
private = dev_get_drvdata(mdev_parent_dev(mdev));
- ctx = &private->io_trigger;
+
+ switch (index) {
+ case VFIO_CCW_IO_IRQ_INDEX:
+ ctx = &private->io_trigger;
+ break;
+ case VFIO_CCW_CRW_IRQ_INDEX:
+ ctx = &private->crw_trigger;
+ break;
+ default:
+ return -EINVAL;
+ }
switch (flags & VFIO_IRQ_SET_DATA_TYPE_MASK) {
case VFIO_IRQ_SET_DATA_NONE:
@@ -482,6 +504,17 @@ int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
return 0;
}
+void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private)
+{
+ int i;
+
+ for (i = 0; i < private->num_regions; i++)
+ private->region[i].ops->release(private, &private->region[i]);
+ private->num_regions = 0;
+ kfree(private->region);
+ private->region = NULL;
+}
+
static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
unsigned int cmd,
unsigned long arg)
@@ -565,7 +598,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
return ret;
data = (void __user *)(arg + minsz);
- return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, data);
+ return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, hdr.index, data);
}
case VFIO_DEVICE_RESET:
return vfio_ccw_mdev_reset(mdev);
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index 9b9bb4982972..8723156b29ea 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -17,6 +17,7 @@
#include <linux/eventfd.h>
#include <linux/workqueue.h>
#include <linux/vfio_ccw.h>
+#include <asm/crw.h>
#include <asm/debug.h>
#include "css.h"
@@ -53,8 +54,16 @@ int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
unsigned int subtype,
const struct vfio_ccw_regops *ops,
size_t size, u32 flags, void *data);
+void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private);
int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private);
+int vfio_ccw_register_schib_dev_regions(struct vfio_ccw_private *private);
+int vfio_ccw_register_crw_dev_regions(struct vfio_ccw_private *private);
+
+struct vfio_ccw_crw {
+ struct list_head next;
+ struct crw crw;
+};
/**
* struct vfio_ccw_private
@@ -68,6 +77,8 @@ int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private);
* @io_mutex: protect against concurrent update of I/O regions
* @region: additional regions for other subchannel operations
* @cmd_region: MMIO region for asynchronous I/O commands other than START
+ * @schib_region: MMIO region for SCHIB information
+ * @crw_region: MMIO region for getting channel report words
* @num_regions: number of additional regions
* @cp: channel program for the current I/O operation
* @irb: irb info received from interrupt
@@ -86,14 +97,19 @@ struct vfio_ccw_private {
struct mutex io_mutex;
struct vfio_ccw_region *region;
struct ccw_cmd_region *cmd_region;
+ struct ccw_schib_region *schib_region;
+ struct ccw_crw_region *crw_region;
int num_regions;
struct channel_program cp;
struct irb irb;
union scsw scsw;
+ struct list_head crw;
struct eventfd_ctx *io_trigger;
+ struct eventfd_ctx *crw_trigger;
struct work_struct io_work;
+ struct work_struct crw_work;
} __aligned(8);
extern int vfio_ccw_mdev_reg(struct subchannel *sch);
diff --git a/drivers/s390/cio/vfio_ccw_trace.c b/drivers/s390/cio/vfio_ccw_trace.c
index 8c671d2519f6..4a0205905afc 100644
--- a/drivers/s390/cio/vfio_ccw_trace.c
+++ b/drivers/s390/cio/vfio_ccw_trace.c
@@ -9,6 +9,7 @@
#define CREATE_TRACE_POINTS
#include "vfio_ccw_trace.h"
+EXPORT_TRACEPOINT_SYMBOL(vfio_ccw_chp_event);
EXPORT_TRACEPOINT_SYMBOL(vfio_ccw_fsm_async_request);
EXPORT_TRACEPOINT_SYMBOL(vfio_ccw_fsm_event);
EXPORT_TRACEPOINT_SYMBOL(vfio_ccw_fsm_io_request);
diff --git a/drivers/s390/cio/vfio_ccw_trace.h b/drivers/s390/cio/vfio_ccw_trace.h
index f5d31887d413..62fb30598d47 100644
--- a/drivers/s390/cio/vfio_ccw_trace.h
+++ b/drivers/s390/cio/vfio_ccw_trace.h
@@ -17,6 +17,36 @@
#include <linux/tracepoint.h>
+TRACE_EVENT(vfio_ccw_chp_event,
+ TP_PROTO(struct subchannel_id schid,
+ int mask,
+ int event),
+ TP_ARGS(schid, mask, event),
+
+ TP_STRUCT__entry(
+ __field(u8, cssid)
+ __field(u8, ssid)
+ __field(u16, sch_no)
+ __field(int, mask)
+ __field(int, event)
+ ),
+
+ TP_fast_assign(
+ __entry->cssid = schid.cssid;
+ __entry->ssid = schid.ssid;
+ __entry->sch_no = schid.sch_no;
+ __entry->mask = mask;
+ __entry->event = event;
+ ),
+
+ TP_printk("schid=%x.%x.%04x mask=0x%x event=%d",
+ __entry->cssid,
+ __entry->ssid,
+ __entry->sch_no,
+ __entry->mask,
+ __entry->event)
+);
+
TRACE_EVENT(vfio_ccw_fsm_async_request,
TP_PROTO(struct subchannel_id schid,
int command,
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 35064443e748..e71ca4a719a5 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -62,8 +62,10 @@ MODULE_PARM_DESC(aqmask, "AP bus domain mask.");
static struct device *ap_root_device;
-DEFINE_SPINLOCK(ap_list_lock);
-LIST_HEAD(ap_card_list);
+/* Hashtable of all queue devices on the AP bus */
+DEFINE_HASHTABLE(ap_queues, 8);
+/* lock used for the ap_queues hashtable */
+DEFINE_SPINLOCK(ap_queues_lock);
/* Default permissions (ioctl, card and domain masking) */
struct ap_perms ap_perms;
@@ -414,7 +416,7 @@ static void ap_interrupt_handler(struct airq_struct *airq, bool floating)
*/
static void ap_tasklet_fn(unsigned long dummy)
{
- struct ap_card *ac;
+ int bkt;
struct ap_queue *aq;
enum ap_wait wait = AP_WAIT_NONE;
@@ -425,34 +427,30 @@ static void ap_tasklet_fn(unsigned long dummy)
if (ap_using_interrupts())
xchg(ap_airq.lsi_ptr, 0);
- spin_lock_bh(&ap_list_lock);
- for_each_ap_card(ac) {
- for_each_ap_queue(aq, ac) {
- spin_lock_bh(&aq->lock);
- wait = min(wait, ap_sm_event_loop(aq, AP_EVENT_POLL));
- spin_unlock_bh(&aq->lock);
- }
+ spin_lock_bh(&ap_queues_lock);
+ hash_for_each(ap_queues, bkt, aq, hnode) {
+ spin_lock_bh(&aq->lock);
+ wait = min(wait, ap_sm_event_loop(aq, AP_EVENT_POLL));
+ spin_unlock_bh(&aq->lock);
}
- spin_unlock_bh(&ap_list_lock);
+ spin_unlock_bh(&ap_queues_lock);
ap_wait(wait);
}
static int ap_pending_requests(void)
{
- struct ap_card *ac;
+ int bkt;
struct ap_queue *aq;
- spin_lock_bh(&ap_list_lock);
- for_each_ap_card(ac) {
- for_each_ap_queue(aq, ac) {
- if (aq->queue_count == 0)
- continue;
- spin_unlock_bh(&ap_list_lock);
- return 1;
- }
+ spin_lock_bh(&ap_queues_lock);
+ hash_for_each(ap_queues, bkt, aq, hnode) {
+ if (aq->queue_count == 0)
+ continue;
+ spin_unlock_bh(&ap_queues_lock);
+ return 1;
}
- spin_unlock_bh(&ap_list_lock);
+ spin_unlock_bh(&ap_queues_lock);
return 0;
}
@@ -683,24 +681,20 @@ static int ap_device_probe(struct device *dev)
}
/* Add queue/card to list of active queues/cards */
- spin_lock_bh(&ap_list_lock);
- if (is_card_dev(dev))
- list_add(&to_ap_card(dev)->list, &ap_card_list);
- else
- list_add(&to_ap_queue(dev)->list,
- &to_ap_queue(dev)->card->queues);
- spin_unlock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
+ if (is_queue_dev(dev))
+ hash_add(ap_queues, &to_ap_queue(dev)->hnode,
+ to_ap_queue(dev)->qid);
+ spin_unlock_bh(&ap_queues_lock);
ap_dev->drv = ap_drv;
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
if (rc) {
- spin_lock_bh(&ap_list_lock);
- if (is_card_dev(dev))
- list_del_init(&to_ap_card(dev)->list);
- else
- list_del_init(&to_ap_queue(dev)->list);
- spin_unlock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
+ if (is_queue_dev(dev))
+ hash_del(&to_ap_queue(dev)->hnode);
+ spin_unlock_bh(&ap_queues_lock);
ap_dev->drv = NULL;
}
@@ -725,16 +719,33 @@ static int ap_device_remove(struct device *dev)
ap_queue_remove(to_ap_queue(dev));
/* Remove queue/card from list of active queues/cards */
- spin_lock_bh(&ap_list_lock);
- if (is_card_dev(dev))
- list_del_init(&to_ap_card(dev)->list);
- else
- list_del_init(&to_ap_queue(dev)->list);
- spin_unlock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
+ if (is_queue_dev(dev))
+ hash_del(&to_ap_queue(dev)->hnode);
+ spin_unlock_bh(&ap_queues_lock);
return 0;
}
+struct ap_queue *ap_get_qdev(ap_qid_t qid)
+{
+ int bkt;
+ struct ap_queue *aq;
+
+ spin_lock_bh(&ap_queues_lock);
+ hash_for_each(ap_queues, bkt, aq, hnode) {
+ if (aq->qid == qid) {
+ get_device(&aq->ap_dev.device);
+ spin_unlock_bh(&ap_queues_lock);
+ return aq;
+ }
+ }
+ spin_unlock_bh(&ap_queues_lock);
+
+ return NULL;
+}
+EXPORT_SYMBOL(ap_get_qdev);
+
int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
char *name)
{
@@ -1506,6 +1517,9 @@ static int __init ap_module_init(void)
return -ENODEV;
}
+ /* init ap_queue hashtable */
+ hash_init(ap_queues);
+
/* set up the AP permissions (ioctls, ap and aq masks) */
ap_perms_init();
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 8e8e37b6c0ee..053cc34d2ca2 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/types.h>
+#include <linux/hashtable.h>
#include <asm/isc.h>
#include <asm/ap.h>
@@ -27,8 +28,8 @@
extern int ap_domain_index;
-extern spinlock_t ap_list_lock;
-extern struct list_head ap_card_list;
+extern DECLARE_HASHTABLE(ap_queues, 8);
+extern spinlock_t ap_queues_lock;
static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)
{
@@ -152,8 +153,6 @@ struct ap_device {
struct ap_card {
struct ap_device ap_dev;
- struct list_head list; /* Private list of AP cards. */
- struct list_head queues; /* List of assoc. AP queues */
void *private; /* ap driver private pointer. */
int raw_hwtype; /* AP raw hardware type. */
unsigned int functions; /* AP device function bitfield. */
@@ -166,7 +165,7 @@ struct ap_card {
struct ap_queue {
struct ap_device ap_dev;
- struct list_head list; /* Private list of AP queues. */
+ struct hlist_node hnode; /* Node for the ap_queues hashtable */
struct ap_card *card; /* Ptr to assoc. AP card. */
spinlock_t lock; /* Per device lock. */
void *private; /* ap driver private pointer. */
@@ -223,12 +222,6 @@ static inline void ap_release_message(struct ap_message *ap_msg)
kzfree(ap_msg->private);
}
-#define for_each_ap_card(_ac) \
- list_for_each_entry(_ac, &ap_card_list, list)
-
-#define for_each_ap_queue(_aq, _ac) \
- list_for_each_entry(_aq, &(_ac)->queues, list)
-
/*
* Note: don't use ap_send/ap_recv after using ap_queue_message
* for the first time. Otherwise the ap message queue will get
@@ -270,6 +263,16 @@ extern struct ap_perms ap_perms;
extern struct mutex ap_perms_mutex;
/*
+ * Get ap_queue device for this qid.
+ * Returns ptr to the struct ap_queue device or NULL if there
+ * was no ap_queue device with this qid found. When something is
+ * found, the reference count of the embedded device is increased.
+ * So the caller has to decrease the reference count after use
+ * with a call to put_device(&aq->ap_dev.device).
+ */
+struct ap_queue *ap_get_qdev(ap_qid_t qid);
+
+/*
* check APQN for owned/reserved by ap bus and default driver(s).
* Checks if this APQN is or will be in use by the ap bus
* and the default set of drivers.
diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c
index 0a39dfdb6a1d..6588713319ba 100644
--- a/drivers/s390/crypto/ap_card.c
+++ b/drivers/s390/crypto/ap_card.c
@@ -66,9 +66,9 @@ static ssize_t request_count_show(struct device *dev,
u64 req_cnt;
req_cnt = 0;
- spin_lock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
req_cnt = atomic64_read(&ac->total_request_count);
- spin_unlock_bh(&ap_list_lock);
+ spin_unlock_bh(&ap_queues_lock);
return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
}
@@ -76,13 +76,15 @@ static ssize_t request_count_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ap_card *ac = to_ap_card(dev);
+ int bkt;
struct ap_queue *aq;
+ struct ap_card *ac = to_ap_card(dev);
- spin_lock_bh(&ap_list_lock);
- for_each_ap_queue(aq, ac)
- aq->total_request_count = 0;
- spin_unlock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
+ hash_for_each(ap_queues, bkt, aq, hnode)
+ if (ac == aq->card)
+ aq->total_request_count = 0;
+ spin_unlock_bh(&ap_queues_lock);
atomic64_set(&ac->total_request_count, 0);
return count;
@@ -93,15 +95,17 @@ static DEVICE_ATTR_RW(request_count);
static ssize_t requestq_count_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct ap_card *ac = to_ap_card(dev);
+ int bkt;
struct ap_queue *aq;
unsigned int reqq_cnt;
+ struct ap_card *ac = to_ap_card(dev);
reqq_cnt = 0;
- spin_lock_bh(&ap_list_lock);
- for_each_ap_queue(aq, ac)
- reqq_cnt += aq->requestq_count;
- spin_unlock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
+ hash_for_each(ap_queues, bkt, aq, hnode)
+ if (ac == aq->card)
+ reqq_cnt += aq->requestq_count;
+ spin_unlock_bh(&ap_queues_lock);
return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
}
@@ -110,15 +114,17 @@ static DEVICE_ATTR_RO(requestq_count);
static ssize_t pendingq_count_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct ap_card *ac = to_ap_card(dev);
+ int bkt;
struct ap_queue *aq;
unsigned int penq_cnt;
+ struct ap_card *ac = to_ap_card(dev);
penq_cnt = 0;
- spin_lock_bh(&ap_list_lock);
- for_each_ap_queue(aq, ac)
- penq_cnt += aq->pendingq_count;
- spin_unlock_bh(&ap_list_lock);
+ spin_lock_bh(&ap_queues_lock);
+ hash_for_each(ap_queues, bkt, aq, hnode)
+ if (ac == aq->card)
+ penq_cnt += aq->pendingq_count;
+ spin_unlock_bh(&ap_queues_lock);
return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
}
@@ -163,11 +169,6 @@ static void ap_card_device_release(struct device *dev)
{
struct ap_card *ac = to_ap_card(dev);
- if (!list_empty(&ac->list)) {
- spin_lock_bh(&ap_list_lock);
- list_del_init(&ac->list);
- spin_unlock_bh(&ap_list_lock);
- }
kfree(ac);
}
@@ -179,8 +180,6 @@ struct ap_card *ap_card_create(int id, int queue_depth, int raw_type,
ac = kzalloc(sizeof(*ac), GFP_KERNEL);
if (!ac)
return NULL;
- INIT_LIST_HEAD(&ac->list);
- INIT_LIST_HEAD(&ac->queues);
ac->ap_dev.device.release = ap_card_device_release;
ac->ap_dev.device.type = &ap_card_type;
ac->ap_dev.device_type = comp_type;
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index 0eaf1d04e8df..73b077dca3e6 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -568,11 +568,10 @@ static void ap_queue_device_release(struct device *dev)
{
struct ap_queue *aq = to_ap_queue(dev);
- if (!list_empty(&aq->list)) {
- spin_lock_bh(&ap_list_lock);
- list_del_init(&aq->list);
- spin_unlock_bh(&ap_list_lock);
- }
+ spin_lock_bh(&ap_queues_lock);
+ hash_del(&aq->hnode);
+ spin_unlock_bh(&ap_queues_lock);
+
kfree(aq);
}
@@ -590,7 +589,6 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type)
aq->state = AP_STATE_UNBOUND;
aq->interrupt = AP_INTR_DISABLED;
spin_lock_init(&aq->lock);
- INIT_LIST_HEAD(&aq->list);
INIT_LIST_HEAD(&aq->pendingq);
INIT_LIST_HEAD(&aq->requestq);
timer_setup(&aq->timeout, ap_request_timeout, 0);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index da47e423e1b1..2d3bca3c0141 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/hash.h>
#include <linux/hashtable.h>
+#include <asm/chsc.h>
#include <asm/setup.h>
#include "qeth_core.h"
#include "qeth_l2.h"
@@ -27,8 +28,8 @@
static void qeth_bridgeport_query_support(struct qeth_card *card);
static void qeth_bridge_state_change(struct qeth_card *card,
struct qeth_ipa_cmd *cmd);
-static void qeth_bridge_host_event(struct qeth_card *card,
- struct qeth_ipa_cmd *cmd);
+static void qeth_addr_change_event(struct qeth_card *card,
+ struct qeth_ipa_cmd *cmd);
static void qeth_l2_vnicc_set_defaults(struct qeth_card *card);
static void qeth_l2_vnicc_init(struct qeth_card *card);
static bool qeth_l2_vnicc_recover_timeout(struct qeth_card *card, u32 vnicc,
@@ -629,6 +630,72 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
schedule_work(&card->rx_mode_work);
}
+/**
+ * qeth_l2_pnso() - perform network subchannel operation
+ * @card: qeth_card structure pointer
+ * @cnc: Boolean Change-Notification Control
+ * @cb: Callback function will be executed for each element
+ * of the address list
+ * @priv: Pointer to pass to the callback function.
+ *
+ * Collects network information in a network address list and calls the
+ * callback function for every entry in the list. If "change-notification-
+ * control" is set, further changes in the address list will be reported
+ * via the IPA command.
+ */
+static int qeth_l2_pnso(struct qeth_card *card, int cnc,
+ void (*cb)(void *priv, struct chsc_pnso_naid_l2 *entry),
+ void *priv)
+{
+ struct ccw_device *ddev = CARD_DDEV(card);
+ struct chsc_pnso_area *rr;
+ u32 prev_instance = 0;
+ int isfirstblock = 1;
+ int i, size, elems;
+ int rc;
+
+ QETH_CARD_TEXT(card, 2, "PNSO");
+ rr = (struct chsc_pnso_area *)get_zeroed_page(GFP_KERNEL);
+ if (rr == NULL)
+ return -ENOMEM;
+ do {
+ /* on the first iteration, naihdr.resume_token will be zero */
+ rc = ccw_device_pnso(ddev, rr, rr->naihdr.resume_token, cnc);
+ if (rc)
+ continue;
+ if (cb == NULL)
+ continue;
+
+ size = rr->naihdr.naids;
+ if (size != sizeof(struct chsc_pnso_naid_l2)) {
+ WARN_ON_ONCE(1);
+ continue;
+ }
+
+ elems = (rr->response.length - sizeof(struct chsc_header) -
+ sizeof(struct chsc_pnso_naihdr)) / size;
+
+ if (!isfirstblock && (rr->naihdr.instance != prev_instance)) {
+ /* Inform the caller that they need to scrap */
+ /* the data that was already reported via cb */
+ rc = -EAGAIN;
+ break;
+ }
+ isfirstblock = 0;
+ prev_instance = rr->naihdr.instance;
+ for (i = 0; i < elems; i++)
+ (*cb)(priv, &rr->entries[i]);
+ } while ((rc == -EBUSY) || (!rc && /* list stored */
+ /* resume token is non-zero => list incomplete */
+ (rr->naihdr.resume_token.t1 || rr->naihdr.resume_token.t2)));
+
+ if (rc)
+ QETH_CARD_TEXT_(card, 2, "PNrp%04x", rr->response.code);
+
+ free_page((unsigned long)rr);
+ return rc;
+}
+
static const struct net_device_ops qeth_l2_netdev_ops = {
.ndo_open = qeth_open,
.ndo_stop = qeth_stop,
@@ -856,7 +923,7 @@ static int qeth_l2_control_event(struct qeth_card *card,
} else
return 1;
case IPA_CMD_ADDRESS_CHANGE_NOTIF:
- qeth_bridge_host_event(card, cmd);
+ qeth_addr_change_event(card, cmd);
return 0;
default:
return 1;
@@ -973,8 +1040,10 @@ enum qeth_an_event_type {anev_reg_unreg, anev_abort, anev_reset};
* for all currently registered addresses.
*/
static void qeth_bridge_emit_host_event(struct qeth_card *card,
- enum qeth_an_event_type evtype,
- u8 code, struct net_if_token *token, struct mac_addr_lnid *addr_lnid)
+ enum qeth_an_event_type evtype,
+ u8 code,
+ struct net_if_token *token,
+ struct mac_addr_lnid *addr_lnid)
{
char str[7][32];
char *env[8];
@@ -1091,74 +1160,76 @@ static void qeth_bridge_state_change(struct qeth_card *card,
queue_work(card->event_wq, &data->worker);
}
-struct qeth_bridge_host_data {
+struct qeth_addr_change_data {
struct work_struct worker;
struct qeth_card *card;
- struct qeth_ipacmd_addr_change hostevs;
+ struct qeth_ipacmd_addr_change ac_event;
};
-static void qeth_bridge_host_event_worker(struct work_struct *work)
+static void qeth_addr_change_event_worker(struct work_struct *work)
{
- struct qeth_bridge_host_data *data =
- container_of(work, struct qeth_bridge_host_data, worker);
+ struct qeth_addr_change_data *data =
+ container_of(work, struct qeth_addr_change_data, worker);
int i;
- if (data->hostevs.lost_event_mask) {
+ QETH_CARD_TEXT(data->card, 4, "adrchgew");
+ if (data->ac_event.lost_event_mask) {
dev_info(&data->card->gdev->dev,
-"Address notification from the Bridge Port stopped %s (%s)\n",
- data->card->dev->name,
- (data->hostevs.lost_event_mask == 0x01)
+ "Address change notification stopped on %s (%s)\n",
+ data->card->dev->name,
+ (data->ac_event.lost_event_mask == 0x01)
? "Overflow"
- : (data->hostevs.lost_event_mask == 0x02)
+ : (data->ac_event.lost_event_mask == 0x02)
? "Bridge port state change"
: "Unknown reason");
mutex_lock(&data->card->sbp_lock);
data->card->options.sbp.hostnotification = 0;
mutex_unlock(&data->card->sbp_lock);
qeth_bridge_emit_host_event(data->card, anev_abort,
- 0, NULL, NULL);
+ 0, NULL, NULL);
} else
- for (i = 0; i < data->hostevs.num_entries; i++) {
+ for (i = 0; i < data->ac_event.num_entries; i++) {
struct qeth_ipacmd_addr_change_entry *entry =
- &data->hostevs.entry[i];
+ &data->ac_event.entry[i];
qeth_bridge_emit_host_event(data->card,
- anev_reg_unreg,
- entry->change_code,
- &entry->token, &entry->addr_lnid);
+ anev_reg_unreg,
+ entry->change_code,
+ &entry->token,
+ &entry->addr_lnid);
}
kfree(data);
}
-static void qeth_bridge_host_event(struct qeth_card *card,
- struct qeth_ipa_cmd *cmd)
+static void qeth_addr_change_event(struct qeth_card *card,
+ struct qeth_ipa_cmd *cmd)
{
struct qeth_ipacmd_addr_change *hostevs =
&cmd->data.addrchange;
- struct qeth_bridge_host_data *data;
+ struct qeth_addr_change_data *data;
int extrasize;
- QETH_CARD_TEXT(card, 2, "brhostev");
+ QETH_CARD_TEXT(card, 4, "adrchgev");
if (cmd->hdr.return_code != 0x0000) {
if (cmd->hdr.return_code == 0x0010) {
if (hostevs->lost_event_mask == 0x00)
hostevs->lost_event_mask = 0xff;
} else {
- QETH_CARD_TEXT_(card, 2, "BPHe%04x",
+ QETH_CARD_TEXT_(card, 2, "ACHN%04x",
cmd->hdr.return_code);
return;
}
}
extrasize = sizeof(struct qeth_ipacmd_addr_change_entry) *
hostevs->num_entries;
- data = kzalloc(sizeof(struct qeth_bridge_host_data) + extrasize,
- GFP_ATOMIC);
+ data = kzalloc(sizeof(struct qeth_addr_change_data) + extrasize,
+ GFP_ATOMIC);
if (!data) {
- QETH_CARD_TEXT(card, 2, "BPHalloc");
+ QETH_CARD_TEXT(card, 2, "ACNalloc");
return;
}
- INIT_WORK(&data->worker, qeth_bridge_host_event_worker);
+ INIT_WORK(&data->worker, qeth_addr_change_event_worker);
data->card = card;
- memcpy(&data->hostevs, hostevs,
+ memcpy(&data->ac_event, hostevs,
sizeof(struct qeth_ipacmd_addr_change) + extrasize);
queue_work(card->event_wq, &data->worker);
}
@@ -1448,63 +1519,18 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role)
return qeth_send_ipa_cmd(card, iob, qeth_bridgeport_set_cb, NULL);
}
-/**
- * qeth_anset_makerc() - derive "traditional" error from hardware codes.
- * @card: qeth_card structure pointer, for debug messages.
- *
- * Returns negative errno-compatible error indication or 0 on success.
- */
-static int qeth_anset_makerc(struct qeth_card *card, int pnso_rc, u16 response)
-{
- int rc;
-
- if (pnso_rc == 0)
- switch (response) {
- case 0x0001:
- rc = 0;
- break;
- case 0x0004:
- case 0x0100:
- case 0x0106:
- rc = -EOPNOTSUPP;
- dev_err(&card->gdev->dev,
- "Setting address notification failed\n");
- break;
- case 0x0107:
- rc = -EAGAIN;
- break;
- default:
- rc = -EIO;
- }
- else
- rc = -EIO;
-
- if (rc) {
- QETH_CARD_TEXT_(card, 2, "SBPp%04x", pnso_rc);
- QETH_CARD_TEXT_(card, 2, "SBPr%04x", response);
- }
- return rc;
-}
-
static void qeth_bridgeport_an_set_cb(void *priv,
- enum qdio_brinfo_entry_type type, void *entry)
+ struct chsc_pnso_naid_l2 *entry)
{
struct qeth_card *card = (struct qeth_card *)priv;
- struct qdio_brinfo_entry_l2 *l2entry;
u8 code;
- if (type != l2_addr_lnid) {
- WARN_ON_ONCE(1);
- return;
- }
-
- l2entry = (struct qdio_brinfo_entry_l2 *)entry;
code = IPA_ADDR_CHANGE_CODE_MACADDR;
- if (l2entry->addr_lnid.lnid < VLAN_N_VID)
+ if (entry->addr_lnid.lnid < VLAN_N_VID)
code |= IPA_ADDR_CHANGE_CODE_VLANID;
qeth_bridge_emit_host_event(card, anev_reg_unreg, code,
- (struct net_if_token *)&l2entry->nit,
- (struct mac_addr_lnid *)&l2entry->addr_lnid);
+ (struct net_if_token *)&entry->nit,
+ (struct mac_addr_lnid *)&entry->addr_lnid);
}
/**
@@ -1520,22 +1546,16 @@ static void qeth_bridgeport_an_set_cb(void *priv,
int qeth_bridgeport_an_set(struct qeth_card *card, int enable)
{
int rc;
- u16 response;
- struct ccw_device *ddev;
- struct subchannel_id schid;
if (!card->options.sbp.supported_funcs)
return -EOPNOTSUPP;
- ddev = CARD_DDEV(card);
- ccw_device_get_schid(ddev, &schid);
if (enable) {
qeth_bridge_emit_host_event(card, anev_reset, 0, NULL, NULL);
- rc = qdio_pnso_brinfo(schid, 1, &response,
- qeth_bridgeport_an_set_cb, card);
+ rc = qeth_l2_pnso(card, 1, qeth_bridgeport_an_set_cb, card);
} else
- rc = qdio_pnso_brinfo(schid, 0, &response, NULL, NULL);
- return qeth_anset_makerc(card, rc, response);
+ rc = qeth_l2_pnso(card, 0, NULL, NULL);
+ return rc;
}
static bool qeth_bridgeport_is_in_use(struct qeth_card *card)
diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
index cebfbbb643a2..7c0a308e4959 100644
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -53,7 +53,7 @@ config ENVCTRL
config DISPLAY7SEG
tristate "7-Segment Display support"
depends on PCI && SPARC64
- ---help---
+ help
This is the driver for the 7-segment display and LED present on
Sun Microsystems CompactPCI models CP1400 and CP1500.
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 4147d22fd448..3adfef210d8e 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -17,7 +17,6 @@
#include <linux/of_device.h>
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/upa.h>
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 37d252f2548d..05de0ce79cb9 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -21,7 +21,6 @@
#include <asm/oplib.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#define DEBUG 1
#ifdef DEBUG
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 0068963bb933..461b3babb601 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -116,9 +116,9 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/device.h>
+#include <linux/pgtable.h>
#include <asm/dma.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/byteorder.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 2017c43dac1b..e9ff4cd5fbe9 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -11,7 +11,7 @@ config RAID_ATTRS
default n
depends on BLOCK
depends on SCSI_MOD
- ---help---
+ help
Provides RAID
config SCSI
@@ -20,7 +20,7 @@ config SCSI
select SCSI_DMA if HAS_DMA
select SG_POOL
select BLK_SCSI_REQUEST
- ---help---
+ help
If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
any other SCSI device under Linux, say Y and make sure that you know
the name of your SCSI host adapter (the card inside your computer
@@ -55,7 +55,7 @@ config SCSI_PROC_FS
bool "legacy /proc/scsi/ support"
depends on SCSI && PROC_FS
default y
- ---help---
+ help
This option enables support for the various files in
/proc/scsi. In Linux 2.6 this has been superseded by
files in sysfs but many legacy applications rely on this.
@@ -69,7 +69,7 @@ config BLK_DEV_SD
tristate "SCSI disk support"
depends on SCSI
select BLK_DEV_INTEGRITY_T10 if BLK_DEV_INTEGRITY
- ---help---
+ help
If you want to use SCSI hard disks, Fibre Channel disks,
Serial ATA (SATA) or Parallel ATA (PATA) hard disks,
USB storage or the SCSI or parallel port version of
@@ -90,7 +90,7 @@ config BLK_DEV_SD
config CHR_DEV_ST
tristate "SCSI tape support"
depends on SCSI
- ---help---
+ help
If you want to use a SCSI tape drive under Linux, say Y and read the
SCSI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, and
@@ -104,7 +104,7 @@ config BLK_DEV_SR
tristate "SCSI CDROM support"
depends on SCSI && BLK_DEV
select CDROM
- ---help---
+ help
If you want to use a CD or DVD drive attached to your computer
by SCSI, FireWire, USB or ATAPI, say Y and read the SCSI-HOWTO
and the CDROM-HOWTO at <http://www.tldp.org/docs.html#howto>.
@@ -118,7 +118,7 @@ config BLK_DEV_SR
config CHR_DEV_SG
tristate "SCSI generic support"
depends on SCSI
- ---help---
+ help
If you want to use SCSI scanners, synthesizers or CD-writers or just
about anything having "SCSI" in its name other than hard disks,
CD-ROMs or tapes, say Y here. These won't be supported by the kernel
@@ -143,7 +143,7 @@ config CHR_DEV_SG
config CHR_DEV_SCH
tristate "SCSI media changer support"
depends on SCSI
- ---help---
+ help
This is a driver for SCSI media changers. Most common devices are
tape libraries and MOD/CDROM jukeboxes. *Real* jukeboxes, you
don't need this for those tiny 6-slot cdrom changers. Media
@@ -178,7 +178,7 @@ config SCSI_CONSTANTS
config SCSI_LOGGING
bool "SCSI logging facility"
depends on SCSI
- ---help---
+ help
This turns on a logging facility that can be used to debug a number
of SCSI related problems.
@@ -376,7 +376,7 @@ config SCSI_AHA152X
depends on ISA && SCSI
select SCSI_SPI_ATTRS
select CHECK_SIGNATURE
- ---help---
+ help
This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
SCSI host adapters. It also works for the AVA-1505, but the IRQ etc.
must be manually specified in this case.
@@ -391,7 +391,7 @@ config SCSI_AHA152X
config SCSI_AHA1542
tristate "Adaptec AHA1542 support"
depends on ISA && SCSI && ISA_DMA_API
- ---help---
+ help
This is support for a SCSI host adapter. It is explained in section
3.4 of the SCSI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>. Note that Trantor was
@@ -405,7 +405,7 @@ config SCSI_AHA1542
config SCSI_AHA1740
tristate "Adaptec AHA1740 support"
depends on EISA && SCSI
- ---help---
+ help
This is support for a SCSI host adapter. It is explained in section
3.5 of the SCSI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>. If it doesn't work out
@@ -498,7 +498,7 @@ config SCSI_HPTIOP
config SCSI_BUSLOGIC
tristate "BusLogic SCSI support"
depends on (PCI || ISA) && SCSI && ISA_DMA_API && VIRT_TO_BUS
- ---help---
+ help
This is support for BusLogic MultiMaster and FlashPoint SCSI Host
Adapters. Consult the SCSI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, and the files
@@ -580,20 +580,20 @@ config LIBFC
tristate "LibFC module"
depends on SCSI_FC_ATTRS
select CRC32
- ---help---
+ help
Fibre Channel library module
config LIBFCOE
tristate "LibFCoE module"
depends on LIBFC
- ---help---
+ help
Library for Fibre Channel over Ethernet module
config FCOE
tristate "FCoE module"
depends on PCI
depends on LIBFCOE
- ---help---
+ help
Fibre Channel over Ethernet module
config FCOE_FNIC
@@ -672,7 +672,7 @@ config SCSI_FDOMAIN_ISA
config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
depends on PCI && SCSI
- ---help---
+ help
Formerly called GDT SCSI Disk Array Controller Support.
This is a driver for RAID/SCSI Disk Array Controllers (EISA/ISA/PCI)
@@ -688,7 +688,7 @@ config SCSI_ISCI
depends on PCI && SCSI
depends on X86
select SCSI_SAS_LIBSAS
- ---help---
+ help
This driver supports the 6Gb/s SAS capabilities of the storage
control unit found in the Intel(R) C600 series chipset.
@@ -696,7 +696,7 @@ config SCSI_GENERIC_NCR5380
tristate "Generic NCR5380/53c400 SCSI ISA card support"
depends on ISA && SCSI && HAS_IOPORT_MAP
select SCSI_SPI_ATTRS
- ---help---
+ help
This is a driver for old ISA card SCSI controllers based on a
NCR 5380, 53C80, 53C400, 53C400A, or DTC 436 device.
Most boards such as the Trantor T130 fit this category, as do
@@ -708,7 +708,7 @@ config SCSI_GENERIC_NCR5380
config SCSI_IPS
tristate "IBM ServeRAID support"
depends on PCI && SCSI
- ---help---
+ help
This is support for the IBM ServeRAID hardware RAID controllers.
See <http://www.developer.ibm.com/welcome/netfinity/serveraid.html>
and <http://www-947.ibm.com/support/entry/portal/docdisplay?brand=5000008&lndocid=SERV-RAID>
@@ -790,7 +790,7 @@ config SCSI_INIA100
config SCSI_PPA
tristate "IOMEGA parallel port (ppa - older drives)"
depends on SCSI && PARPORT_PC
- ---help---
+ help
This driver supports older versions of IOMEGA's parallel port ZIP
drive (a 100 MB removable media device).
@@ -817,7 +817,7 @@ config SCSI_PPA
config SCSI_IMM
tristate "IOMEGA parallel port (imm - newer drives)"
depends on SCSI && PARPORT_PC
- ---help---
+ help
This driver supports newer versions of IOMEGA's parallel port ZIP
drive (a 100 MB removable media device).
@@ -844,7 +844,7 @@ config SCSI_IMM
config SCSI_IZIP_EPP16
bool "ppa/imm option - Use slow (but safe) EPP-16"
depends on SCSI_PPA || SCSI_IMM
- ---help---
+ help
EPP (Enhanced Parallel Port) is a standard for parallel ports which
allows them to act as expansion buses that can handle up to 64
peripheral devices.
@@ -896,7 +896,7 @@ config 53C700_LE_ON_BE
config SCSI_STEX
tristate "Promise SuperTrak EX Series support"
depends on PCI && SCSI
- ---help---
+ help
This driver supports Promise SuperTrak EX series storage controllers.
Promise provides Linux RAID configuration utility for these
@@ -914,7 +914,7 @@ config SCSI_SYM53C8XX_2
tristate "SYM53C8XX Version 2 SCSI support"
depends on PCI && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
This driver supports the whole NCR53C8XX/SYM53C8XX family of
PCI-SCSI controllers. It also supports the subset of LSI53C10XX
Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS
@@ -928,7 +928,7 @@ config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
int "DMA addressing mode"
depends on SCSI_SYM53C8XX_2
default "1"
- ---help---
+ help
This option only applies to PCI-SCSI chips that are PCI DAC
capable (875A, 895A, 896, 1010-33, 1010-66, 1000).
@@ -984,7 +984,7 @@ config SCSI_IPR
select FW_LOADER
select IRQ_POLL
select SGL_ALLOC
- ---help---
+ help
This driver supports the IBM Power Linux family RAID adapters.
This includes IBM pSeries 5712, 5703, 5709, and 570A, as well
as IBM iSeries 5702, 5703, 5709, and 570A.
@@ -1022,7 +1022,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
int "default tagged command queue depth"
depends on SCSI_ZALON
default "8"
- ---help---
+ help
"Tagged command queuing" is a feature of SCSI-2 which improves
performance: the host adapter can send several SCSI commands to a
device's queue even if previous commands haven't finished yet.
@@ -1048,7 +1048,7 @@ config SCSI_NCR53C8XX_MAX_TAGS
int "maximum number of queued commands"
depends on SCSI_ZALON
default "32"
- ---help---
+ help
This option allows you to specify the maximum number of commands
that can be queued to any device, when tagged command queuing is
possible. The default value is 32. Minimum is 2, maximum is 64.
@@ -1065,7 +1065,7 @@ config SCSI_NCR53C8XX_SYNC
int "synchronous transfers frequency in MHz"
depends on SCSI_ZALON
default "20"
- ---help---
+ help
The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
rates: FAST-5, FAST-10, FAST-20, FAST-40 and FAST-80. The numbers
are respectively the maximum data transfer rates in mega-transfers
@@ -1108,7 +1108,7 @@ config SCSI_NCR53C8XX_NO_DISCONNECT
config SCSI_QLOGIC_FAS
tristate "Qlogic FAS SCSI support"
depends on ISA && SCSI
- ---help---
+ help
This is a driver for the ISA, VLB, and PCMCIA versions of the Qlogic
FastSCSI! cards as well as any other card based on the FASXX chip
(including the Control Concepts SCSI/IDE/SIO/PIO/FDC cards).
@@ -1158,14 +1158,14 @@ config SCSI_LPFC
depends on NVME_TARGET_FC || NVME_TARGET_FC=n
depends on NVME_FC || NVME_FC=n
select CRC_T10DIF
- ---help---
+ help
This lpfc driver supports the Emulex LightPulse
Family of Fibre Channel PCI host adapters.
config SCSI_LPFC_DEBUG_FS
bool "Emulex LightPulse Fibre Channel debugfs Support"
depends on SCSI_LPFC && DEBUG_FS
- ---help---
+ help
This makes debugging information from the lpfc driver
available via the debugfs filesystem.
@@ -1173,7 +1173,7 @@ config SCSI_SIM710
tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
depends on EISA && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
This driver is for NCR53c710 based SCSI host adapters.
It currently supports Compaq EISA cards.
@@ -1181,7 +1181,7 @@ config SCSI_SIM710
config SCSI_DC395x
tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support"
depends on PCI && SCSI
- ---help---
+ help
This driver supports PCI SCSI host adapters based on the ASIC
TRM-S1040 chip, e.g Tekram DC395(U/UW/F) and DC315(U) variants.
@@ -1197,7 +1197,7 @@ config SCSI_AM53C974
tristate "Tekram DC390(T) and Am53/79C974 SCSI support (new driver)"
depends on PCI && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
This driver supports PCI SCSI host adapters based on the Am53C974A
chip, e.g. Tekram DC390(T), DawiControl 2974 and some onboard
PCscsi/PCnet (Am53/79C974) solutions.
@@ -1224,7 +1224,7 @@ config SCSI_WD719X
tristate "Western Digital WD7193/7197/7296 support"
depends on PCI && SCSI
select EEPROM_93CX6
- ---help---
+ help
This is a driver for Western Digital WD7193, WD7197 and WD7296 PCI
SCSI controllers (based on WD33C296A chip).
@@ -1318,7 +1318,7 @@ config A2091_SCSI
config GVP11_SCSI
tristate "GVP Series II WD33C93A support"
depends on ZORRO && SCSI
- ---help---
+ help
If you have a Great Valley Products Series II SCSI controller,
answer Y. Also say Y if you have a later model of GVP SCSI
controller (such as the GVP A4008 or a Combo board). Otherwise,
@@ -1374,7 +1374,7 @@ config ATARI_SCSI
tristate "Atari native SCSI support"
depends on ATARI && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
If you have an Atari with built-in NCR5380 SCSI controller (TT,
Falcon, ...) say Y to get it supported. Of course also, if you have
a compatible SCSI controller (e.g. for Medusa).
@@ -1486,7 +1486,7 @@ config SCSI_PMCRAID
tristate "PMC SIERRA Linux MaxRAID adapter support"
depends on PCI && SCSI && NET
select SGL_ALLOC
- ---help---
+ help
This driver supports the PMC SIERRA MaxRAID adapters.
config SCSI_PM8001
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 564b35473672..5853db36eceb 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index b6a0432f305a..86f1da22aaa5 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx
index d4c50b8fce29..a47dbd500e9a 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic79xx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx
@@ -15,7 +15,7 @@ config AIC79XX_CMDS_PER_DEVICE
int "Maximum number of TCQ commands per device"
depends on SCSI_AIC79XX
default "32"
- ---help---
+ help
Specify the number of commands you would like to allocate per SCSI
device when Tagged Command Queueing (TCQ) is enabled on that device.
@@ -38,7 +38,7 @@ config AIC79XX_RESET_DELAY_MS
int "Initial bus reset delay in milli-seconds"
depends on SCSI_AIC79XX
default "5000"
- ---help---
+ help
The number of milliseconds to delay after an initial bus reset.
The bus settle delay following all error recovery actions is
dictated by the SCSI layer and is not affected by this value.
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
index 9d027549d698..0cfd92ce750a 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
@@ -7,7 +7,7 @@ config SCSI_AIC7XXX
tristate "Adaptec AIC7xxx Fast -> U160 support"
depends on (PCI || EISA) && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
This driver supports all of Adaptec's Fast through Ultra 160 PCI
based SCSI controllers as well as the aic7770 based EISA and VLB
SCSI controllers (the 274x and 284x series). For AAA and ARO based
@@ -20,7 +20,7 @@ config AIC7XXX_CMDS_PER_DEVICE
int "Maximum number of TCQ commands per device"
depends on SCSI_AIC7XXX
default "32"
- ---help---
+ help
Specify the number of commands you would like to allocate per SCSI
device when Tagged Command Queueing (TCQ) is enabled on that device.
@@ -43,7 +43,7 @@ config AIC7XXX_RESET_DELAY_MS
int "Initial bus reset delay in milli-seconds"
depends on SCSI_AIC7XXX
default "5000"
- ---help---
+ help
The number of milliseconds to delay after an initial bus reset.
The bus settle delay following all error recovery actions is
dictated by the SCSI layer and is not affected by this value.
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index ddb52e7ba622..9a912fd0f70b 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -2911,8 +2911,10 @@ static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
- if (!ashost->base || !ashost->fast)
+ if (!ashost->base || !ashost->fast) {
+ ret = -ENOMEM;
goto out_put;
+ }
host->irq = ec->irq;
ashost->host = host;
diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
index a1f3e9ee4e63..65691c21f133 100644
--- a/drivers/scsi/arm/cumana_2.c
+++ b/drivers/scsi/arm/cumana_2.c
@@ -23,11 +23,11 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/pgtable.h>
#include <asm/dma.h>
#include <asm/ecard.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include "../scsi.h"
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index 134f040d58e2..6e204a2e0c8d 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -29,11 +29,11 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/pgtable.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/ecard.h>
-#include <asm/pgtable.h>
#include "../scsi.h"
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index c795537a671c..772a13e5fd91 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -14,11 +14,11 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/pgtable.h>
#include <asm/dma.h>
#include <asm/ecard.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include "../scsi.h"
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/bnx2fc/Kconfig b/drivers/scsi/bnx2fc/Kconfig
index e0ccb48ec961..3cf7e08df809 100644
--- a/drivers/scsi/bnx2fc/Kconfig
+++ b/drivers/scsi/bnx2fc/Kconfig
@@ -9,5 +9,5 @@ config SCSI_BNX2X_FCOE
select ETHERNET
select NET_VENDOR_BROADCOM
select CNIC
- ---help---
+ help
This driver supports FCoE offload for the QLogic devices.
diff --git a/drivers/scsi/bnx2i/Kconfig b/drivers/scsi/bnx2i/Kconfig
index 702dc82c9501..75ace2302fed 100644
--- a/drivers/scsi/bnx2i/Kconfig
+++ b/drivers/scsi/bnx2i/Kconfig
@@ -9,6 +9,6 @@ config SCSI_BNX2_ISCSI
select ETHERNET
select NET_VENDOR_BROADCOM
select CNIC
- ---help---
+ help
This driver supports iSCSI offload for the QLogic NetXtreme II
devices.
diff --git a/drivers/scsi/cxgbi/cxgb3i/Kconfig b/drivers/scsi/cxgbi/cxgb3i/Kconfig
index 3e4b644249cb..e20e6f3bfe64 100644
--- a/drivers/scsi/cxgbi/cxgb3i/Kconfig
+++ b/drivers/scsi/cxgbi/cxgb3i/Kconfig
@@ -8,5 +8,5 @@ config SCSI_CXGB3_ISCSI
select CHELSIO_T3
select CHELSIO_LIB
select SCSI_ISCSI_ATTRS
- ---help---
+ help
This driver supports iSCSI offload for the Chelsio T3 devices.
diff --git a/drivers/scsi/cxgbi/cxgb4i/Kconfig b/drivers/scsi/cxgbi/cxgb4i/Kconfig
index d1f1baba3285..b206e266b4e7 100644
--- a/drivers/scsi/cxgbi/cxgb4i/Kconfig
+++ b/drivers/scsi/cxgbi/cxgb4i/Kconfig
@@ -8,5 +8,5 @@ config SCSI_CXGB4_ISCSI
select CHELSIO_T4
select CHELSIO_LIB
select SCSI_ISCSI_ATTRS
- ---help---
+ help
This driver supports iSCSI offload for the Chelsio T4 devices.
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
index fcc5aa9f6014..94250ebe9e80 100644
--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -47,9 +47,6 @@ static void process_cmd_err(struct afu_cmd *cmd, struct scsi_cmnd *scp)
struct sisl_ioasa *ioasa;
u32 resid;
- if (unlikely(!cmd))
- return;
-
ioasa = &(cmd->sa);
if (ioasa->rc.flags & SISL_RC_FLAGS_UNDERRUN) {
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 2cf889512ece..0497ef6a9453 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -27,6 +27,7 @@
/*#define UARTDELAY 1 */
#include <linux/module.h>
+#include <linux/pgtable.h>
MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
@@ -55,7 +56,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/mutex.h>
#include <asm/processor.h> /* for boot_cpu_data */
-#include <asm/pgtable.h>
#include <asm/io.h> /* for virt_to_bus, etc. */
#include <scsi/scsi.h>
diff --git a/drivers/scsi/esas2r/Kconfig b/drivers/scsi/esas2r/Kconfig
index 19f6d3029658..c9b43f7fce31 100644
--- a/drivers/scsi/esas2r/Kconfig
+++ b/drivers/scsi/esas2r/Kconfig
@@ -2,5 +2,5 @@
config SCSI_ESAS2R
tristate "ATTO Technology's ExpressSAS RAID adapter driver"
depends on PCI && SCSI
- ---help---
+ help
This driver supports the ATTO ExpressSAS R6xx SAS/SATA RAID controllers.
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index 11df0eca0293..727f8c8f30b5 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 1e9302e99d05..81d0414e2117 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -254,6 +254,10 @@ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id);
static int hpsa_ioctl(struct scsi_device *dev, unsigned int cmd,
void __user *arg);
+static int hpsa_passthru_ioctl(struct ctlr_info *h,
+ IOCTL_Command_struct *iocommand);
+static int hpsa_big_passthru_ioctl(struct ctlr_info *h,
+ BIG_IOCTL_Command_struct *ioc);
#ifdef CONFIG_COMPAT
static int hpsa_compat_ioctl(struct scsi_device *dev, unsigned int cmd,
@@ -6217,75 +6221,63 @@ static void cmd_free(struct ctlr_info *h, struct CommandList *c)
static int hpsa_ioctl32_passthru(struct scsi_device *dev, unsigned int cmd,
void __user *arg)
{
- IOCTL32_Command_struct __user *arg32 =
- (IOCTL32_Command_struct __user *) arg;
+ struct ctlr_info *h = sdev_to_hba(dev);
+ IOCTL32_Command_struct __user *arg32 = arg;
IOCTL_Command_struct arg64;
- IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64));
int err;
u32 cp;
- memset(&arg64, 0, sizeof(arg64));
- err = 0;
- err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
- sizeof(arg64.LUN_info));
- err |= copy_from_user(&arg64.Request, &arg32->Request,
- sizeof(arg64.Request));
- err |= copy_from_user(&arg64.error_info, &arg32->error_info,
- sizeof(arg64.error_info));
- err |= get_user(arg64.buf_size, &arg32->buf_size);
- err |= get_user(cp, &arg32->buf);
- arg64.buf = compat_ptr(cp);
- err |= copy_to_user(p, &arg64, sizeof(arg64));
+ if (!arg)
+ return -EINVAL;
- if (err)
+ memset(&arg64, 0, sizeof(arg64));
+ if (copy_from_user(&arg64, arg32, offsetof(IOCTL_Command_struct, buf)))
+ return -EFAULT;
+ if (get_user(cp, &arg32->buf))
return -EFAULT;
+ arg64.buf = compat_ptr(cp);
- err = hpsa_ioctl(dev, CCISS_PASSTHRU, p);
+ if (atomic_dec_if_positive(&h->passthru_cmds_avail) < 0)
+ return -EAGAIN;
+ err = hpsa_passthru_ioctl(h, &arg64);
+ atomic_inc(&h->passthru_cmds_avail);
if (err)
return err;
- err |= copy_in_user(&arg32->error_info, &p->error_info,
- sizeof(arg32->error_info));
- if (err)
+ if (copy_to_user(&arg32->error_info, &arg64.error_info,
+ sizeof(arg32->error_info)))
return -EFAULT;
- return err;
+ return 0;
}
static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
unsigned int cmd, void __user *arg)
{
- BIG_IOCTL32_Command_struct __user *arg32 =
- (BIG_IOCTL32_Command_struct __user *) arg;
+ struct ctlr_info *h = sdev_to_hba(dev);
+ BIG_IOCTL32_Command_struct __user *arg32 = arg;
BIG_IOCTL_Command_struct arg64;
- BIG_IOCTL_Command_struct __user *p =
- compat_alloc_user_space(sizeof(arg64));
int err;
u32 cp;
+ if (!arg)
+ return -EINVAL;
memset(&arg64, 0, sizeof(arg64));
- err = 0;
- err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
- sizeof(arg64.LUN_info));
- err |= copy_from_user(&arg64.Request, &arg32->Request,
- sizeof(arg64.Request));
- err |= copy_from_user(&arg64.error_info, &arg32->error_info,
- sizeof(arg64.error_info));
- err |= get_user(arg64.buf_size, &arg32->buf_size);
- err |= get_user(arg64.malloc_size, &arg32->malloc_size);
- err |= get_user(cp, &arg32->buf);
- arg64.buf = compat_ptr(cp);
- err |= copy_to_user(p, &arg64, sizeof(arg64));
-
- if (err)
+ if (copy_from_user(&arg64, arg32,
+ offsetof(BIG_IOCTL32_Command_struct, buf)))
+ return -EFAULT;
+ if (get_user(cp, &arg32->buf))
return -EFAULT;
+ arg64.buf = compat_ptr(cp);
- err = hpsa_ioctl(dev, CCISS_BIG_PASSTHRU, p);
+ if (atomic_dec_if_positive(&h->passthru_cmds_avail) < 0)
+ return -EAGAIN;
+ err = hpsa_big_passthru_ioctl(h, &arg64);
+ atomic_inc(&h->passthru_cmds_avail);
if (err)
return err;
- err |= copy_in_user(&arg32->error_info, &p->error_info,
- sizeof(arg32->error_info));
- if (err)
+ if (copy_to_user(&arg32->error_info, &arg64.error_info,
+ sizeof(arg32->error_info)))
return -EFAULT;
- return err;
+ return 0;
}
static int hpsa_compat_ioctl(struct scsi_device *dev, unsigned int cmd,
@@ -6358,37 +6350,33 @@ static int hpsa_getdrivver_ioctl(struct ctlr_info *h, void __user *argp)
return 0;
}
-static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+static int hpsa_passthru_ioctl(struct ctlr_info *h,
+ IOCTL_Command_struct *iocommand)
{
- IOCTL_Command_struct iocommand;
struct CommandList *c;
char *buff = NULL;
u64 temp64;
int rc = 0;
- if (!argp)
- return -EINVAL;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
- if (copy_from_user(&iocommand, argp, sizeof(iocommand)))
- return -EFAULT;
- if ((iocommand.buf_size < 1) &&
- (iocommand.Request.Type.Direction != XFER_NONE)) {
+ if ((iocommand->buf_size < 1) &&
+ (iocommand->Request.Type.Direction != XFER_NONE)) {
return -EINVAL;
}
- if (iocommand.buf_size > 0) {
- buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
+ if (iocommand->buf_size > 0) {
+ buff = kmalloc(iocommand->buf_size, GFP_KERNEL);
if (buff == NULL)
return -ENOMEM;
- if (iocommand.Request.Type.Direction & XFER_WRITE) {
+ if (iocommand->Request.Type.Direction & XFER_WRITE) {
/* Copy the data into the buffer we created */
- if (copy_from_user(buff, iocommand.buf,
- iocommand.buf_size)) {
+ if (copy_from_user(buff, iocommand->buf,
+ iocommand->buf_size)) {
rc = -EFAULT;
goto out_kfree;
}
} else {
- memset(buff, 0, iocommand.buf_size);
+ memset(buff, 0, iocommand->buf_size);
}
}
c = cmd_alloc(h);
@@ -6398,23 +6386,23 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
c->scsi_cmd = SCSI_CMD_BUSY;
/* Fill in Command Header */
c->Header.ReplyQueue = 0; /* unused in simple mode */
- if (iocommand.buf_size > 0) { /* buffer to fill */
+ if (iocommand->buf_size > 0) { /* buffer to fill */
c->Header.SGList = 1;
c->Header.SGTotal = cpu_to_le16(1);
} else { /* no buffers to fill */
c->Header.SGList = 0;
c->Header.SGTotal = cpu_to_le16(0);
}
- memcpy(&c->Header.LUN, &iocommand.LUN_info, sizeof(c->Header.LUN));
+ memcpy(&c->Header.LUN, &iocommand->LUN_info, sizeof(c->Header.LUN));
/* Fill in Request block */
- memcpy(&c->Request, &iocommand.Request,
+ memcpy(&c->Request, &iocommand->Request,
sizeof(c->Request));
/* Fill in the scatter gather information */
- if (iocommand.buf_size > 0) {
+ if (iocommand->buf_size > 0) {
temp64 = dma_map_single(&h->pdev->dev, buff,
- iocommand.buf_size, DMA_BIDIRECTIONAL);
+ iocommand->buf_size, DMA_BIDIRECTIONAL);
if (dma_mapping_error(&h->pdev->dev, (dma_addr_t) temp64)) {
c->SG[0].Addr = cpu_to_le64(0);
c->SG[0].Len = cpu_to_le32(0);
@@ -6422,12 +6410,12 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
goto out;
}
c->SG[0].Addr = cpu_to_le64(temp64);
- c->SG[0].Len = cpu_to_le32(iocommand.buf_size);
+ c->SG[0].Len = cpu_to_le32(iocommand->buf_size);
c->SG[0].Ext = cpu_to_le32(HPSA_SG_LAST); /* not chaining */
}
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
NO_TIMEOUT);
- if (iocommand.buf_size > 0)
+ if (iocommand->buf_size > 0)
hpsa_pci_unmap(h->pdev, c, 1, DMA_BIDIRECTIONAL);
check_ioctl_unit_attention(h, c);
if (rc) {
@@ -6436,16 +6424,12 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
}
/* Copy the error information out */
- memcpy(&iocommand.error_info, c->err_info,
- sizeof(iocommand.error_info));
- if (copy_to_user(argp, &iocommand, sizeof(iocommand))) {
- rc = -EFAULT;
- goto out;
- }
- if ((iocommand.Request.Type.Direction & XFER_READ) &&
- iocommand.buf_size > 0) {
+ memcpy(&iocommand->error_info, c->err_info,
+ sizeof(iocommand->error_info));
+ if ((iocommand->Request.Type.Direction & XFER_READ) &&
+ iocommand->buf_size > 0) {
/* Copy the data out of the buffer we created */
- if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
+ if (copy_to_user(iocommand->buf, buff, iocommand->buf_size)) {
rc = -EFAULT;
goto out;
}
@@ -6457,9 +6441,9 @@ out_kfree:
return rc;
}
-static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+static int hpsa_big_passthru_ioctl(struct ctlr_info *h,
+ BIG_IOCTL_Command_struct *ioc)
{
- BIG_IOCTL_Command_struct *ioc;
struct CommandList *c;
unsigned char **buff = NULL;
int *buff_size = NULL;
@@ -6470,29 +6454,17 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
u32 sz;
BYTE __user *data_ptr;
- if (!argp)
- return -EINVAL;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
- ioc = vmemdup_user(argp, sizeof(*ioc));
- if (IS_ERR(ioc)) {
- status = PTR_ERR(ioc);
- goto cleanup1;
- }
+
if ((ioc->buf_size < 1) &&
- (ioc->Request.Type.Direction != XFER_NONE)) {
- status = -EINVAL;
- goto cleanup1;
- }
+ (ioc->Request.Type.Direction != XFER_NONE))
+ return -EINVAL;
/* Check kmalloc limits using all SGs */
- if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
- status = -EINVAL;
- goto cleanup1;
- }
- if (ioc->buf_size > ioc->malloc_size * SG_ENTRIES_IN_CMD) {
- status = -EINVAL;
- goto cleanup1;
- }
+ if (ioc->malloc_size > MAX_KMALLOC_SIZE)
+ return -EINVAL;
+ if (ioc->buf_size > ioc->malloc_size * SG_ENTRIES_IN_CMD)
+ return -EINVAL;
buff = kcalloc(SG_ENTRIES_IN_CMD, sizeof(char *), GFP_KERNEL);
if (!buff) {
status = -ENOMEM;
@@ -6565,10 +6537,6 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
/* Copy the error information out */
memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
- if (copy_to_user(argp, ioc, sizeof(*ioc))) {
- status = -EFAULT;
- goto cleanup0;
- }
if ((ioc->Request.Type.Direction & XFER_READ) && ioc->buf_size > 0) {
int i;
@@ -6594,7 +6562,6 @@ cleanup1:
kfree(buff);
}
kfree(buff_size);
- kvfree(ioc);
return status;
}
@@ -6610,14 +6577,11 @@ static void check_ioctl_unit_attention(struct ctlr_info *h,
* ioctl
*/
static int hpsa_ioctl(struct scsi_device *dev, unsigned int cmd,
- void __user *arg)
+ void __user *argp)
{
- struct ctlr_info *h;
- void __user *argp = (void __user *)arg;
+ struct ctlr_info *h = sdev_to_hba(dev);
int rc;
- h = sdev_to_hba(dev);
-
switch (cmd) {
case CCISS_DEREGDISK:
case CCISS_REGNEWDISK:
@@ -6628,18 +6592,35 @@ static int hpsa_ioctl(struct scsi_device *dev, unsigned int cmd,
return hpsa_getpciinfo_ioctl(h, argp);
case CCISS_GETDRIVVER:
return hpsa_getdrivver_ioctl(h, argp);
- case CCISS_PASSTHRU:
+ case CCISS_PASSTHRU: {
+ IOCTL_Command_struct iocommand;
+
+ if (!argp)
+ return -EINVAL;
+ if (copy_from_user(&iocommand, argp, sizeof(iocommand)))
+ return -EFAULT;
if (atomic_dec_if_positive(&h->passthru_cmds_avail) < 0)
return -EAGAIN;
- rc = hpsa_passthru_ioctl(h, argp);
+ rc = hpsa_passthru_ioctl(h, &iocommand);
atomic_inc(&h->passthru_cmds_avail);
+ if (!rc && copy_to_user(argp, &iocommand, sizeof(iocommand)))
+ rc = -EFAULT;
return rc;
- case CCISS_BIG_PASSTHRU:
+ }
+ case CCISS_BIG_PASSTHRU: {
+ BIG_IOCTL_Command_struct ioc;
+ if (!argp)
+ return -EINVAL;
+ if (copy_from_user(&ioc, argp, sizeof(ioc)))
+ return -EFAULT;
if (atomic_dec_if_positive(&h->passthru_cmds_avail) < 0)
return -EAGAIN;
- rc = hpsa_big_passthru_ioctl(h, argp);
+ rc = hpsa_big_passthru_ioctl(h, &ioc);
atomic_inc(&h->passthru_cmds_avail);
+ if (!rc && copy_to_user(argp, &ioc, sizeof(ioc)))
+ rc = -EFAULT;
return rc;
+ }
default:
return -ENOTTY;
}
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 44e64aa21194..14f687e9b1f4 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -415,6 +415,8 @@ static int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
int rc = 0;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+ set_adapter_info(hostdata);
+
/* Re-enable the CRQ */
do {
if (rc)
diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index e4857b728033..a64abe38db2d 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -352,7 +352,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(&boot_kobj->kobj, &iscsi_boot_ktype,
NULL, name, index)) {
- kfree(boot_kobj);
+ kobject_put(&boot_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index c48a73a0f517..de71d240a56f 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -31,7 +31,6 @@
#include <linux/slab.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/parisc-device.h>
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 35d3e322d6d5..43edf83fdb62 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -20,9 +20,9 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/pgtable.h>
#include <asm/dbdma.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/macio.h>
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 74fb50644678..f9f8f4921654 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -31,9 +31,9 @@
#include <linux/reboot.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
+#include <linux/pgtable.h>
#include <asm/dbdma.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/irq.h>
#include <asm/hydra.h>
diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig
index a072187875df..86209455172d 100644
--- a/drivers/scsi/mpt3sas/Kconfig
+++ b/drivers/scsi/mpt3sas/Kconfig
@@ -46,7 +46,7 @@ config SCSI_MPT3SAS
select SCSI_SAS_ATTRS
select RAID_ATTRS
select IRQ_POLL
- ---help---
+ help
This driver supports PCI-Express SAS 12Gb/s Host Adapters.
config SCSI_MPT2SAS_MAX_SGE
@@ -54,7 +54,7 @@ config SCSI_MPT2SAS_MAX_SGE
depends on PCI && SCSI && SCSI_MPT3SAS
default "128"
range 16 256
- ---help---
+ help
This option allows you to specify the maximum number of scatter-
gather entries per I/O. The driver default is 128, which matches
MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this
@@ -66,7 +66,7 @@ config SCSI_MPT3SAS_MAX_SGE
depends on PCI && SCSI && SCSI_MPT3SAS
default "128"
range 16 256
- ---help---
+ help
This option allows you to specify the maximum number of scatter-
gather entries per I/O. The driver default is 128, which matches
MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this
@@ -78,6 +78,6 @@ config SCSI_MPT2SAS
default n
select SCSI_MPT3SAS
depends on PCI && SCSI
- ---help---
+ help
Dummy config option for backwards compatiblity: configure the MPT3SAS
driver instead.
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index beaea1933f5c..96b78fdc6b8a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4984,7 +4984,7 @@ base_alloc_rdpq_dma_pool(struct MPT3SAS_ADAPTER *ioc, int sz)
for (i = 0; i < count; i++) {
if ((i % RDPQ_MAX_INDEX_IN_ONE_CHUNK == 0) && dma_alloc_count) {
ioc->reply_post[i].reply_post_free =
- dma_pool_alloc(ioc->reply_post_free_dma_pool,
+ dma_pool_zalloc(ioc->reply_post_free_dma_pool,
GFP_KERNEL,
&ioc->reply_post[i].reply_post_free_dma);
if (!ioc->reply_post[i].reply_post_free)
@@ -5008,9 +5008,6 @@ base_alloc_rdpq_dma_pool(struct MPT3SAS_ADAPTER *ioc, int sz)
ioc->reply_post[i].reply_post_free_dma));
return -EAGAIN;
}
- memset(ioc->reply_post[i].reply_post_free, 0,
- RDPQ_MAX_INDEX_IN_ONE_CHUNK *
- reply_post_free_sz);
dma_alloc_count--;
} else {
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index ca96d6d9c350..869b8b058a43 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/mvme147hw.h>
#include <asm/irq.h>
diff --git a/drivers/scsi/qedf/Kconfig b/drivers/scsi/qedf/Kconfig
index 7cd993be4e57..eb81a1b0374a 100644
--- a/drivers/scsi/qedf/Kconfig
+++ b/drivers/scsi/qedf/Kconfig
@@ -7,6 +7,6 @@ config QEDF
depends on LIBFCOE
select QED_LL2
select QED_FCOE
- ---help---
+ help
This driver supports FCoE offload for the QLogic FastLinQ
41000 Series Converged Network Adapters.
diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c
index bb82f0875eca..ad6a56ce72a8 100644
--- a/drivers/scsi/qedf/qedf_fip.c
+++ b/drivers/scsi/qedf/qedf_fip.c
@@ -20,7 +20,7 @@ void qedf_fcoe_send_vlan_req(struct qedf_ctx *qedf)
#define MY_FIP_ALL_FCF_MACS ((__u8[6]) { 1, 0x10, 0x18, 1, 0, 2 })
static u8 my_fcoe_all_fcfs[ETH_ALEN] = MY_FIP_ALL_FCF_MACS;
unsigned long flags = 0;
- int rc = -1;
+ int rc;
skb = dev_alloc_skb(sizeof(struct fip_vlan));
if (!skb) {
diff --git a/drivers/scsi/qedi/Kconfig b/drivers/scsi/qedi/Kconfig
index 7ab07f3b453f..2091d883a584 100644
--- a/drivers/scsi/qedi/Kconfig
+++ b/drivers/scsi/qedi/Kconfig
@@ -8,6 +8,6 @@ config QEDI
select QED_OOO
select QED_ISCSI
select ISCSI_BOOT_SYSFS
- ---help---
+ help
This driver supports iSCSI offload for the QLogic FastLinQ
41000 Series Converged Network Adapters.
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index 764501838e21..802c373fd6d9 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -6,7 +6,7 @@ config SCSI_QLA_FC
depends on NVME_FC || !NVME_FC
select FW_LOADER
select BTREE
- ---help---
+ help
This qla2xxx driver supports all QLogic Fibre Channel
PCI and PCIe host adapters.
@@ -37,14 +37,14 @@ config TCM_QLA2XXX
depends on LIBFC
select BTREE
default n
- ---help---
+ help
Say Y here to enable the TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs
if TCM_QLA2XXX
config TCM_QLA2XXX_DEBUG
bool "TCM_QLA2XXX fabric module DEBUG mode for QLogic 24xx+ series target mode HBAs"
default n
- ---help---
+ help
Say Y here to enable the TCM_QLA2XXX fabric module DEBUG for QLogic 24xx+ series target mode HBAs
This will include code to enable the SCSI command jammer
endif
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
index 4bdf31b1407a..2fa249db6656 100644
--- a/drivers/scsi/qla4xxx/Kconfig
+++ b/drivers/scsi/qla4xxx/Kconfig
@@ -4,6 +4,6 @@ config SCSI_QLA_ISCSI
depends on PCI && SCSI && NET
select SCSI_ISCSI_ATTRS
select ISCSI_BOOT_SYSFS
- ---help---
+ help
This driver supports the QLogic 40xx (ISP4XXX), 8022 (ISP82XX)
and 8032 (ISP83XX) iSCSI host adapter family.
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index d539beef3ce8..3790e8b70bba 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -30,6 +30,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/firmware.h>
+#include <linux/pgtable.h>
#include <asm/byteorder.h>
@@ -37,7 +38,6 @@
#include <asm/dma.h>
#include <asm/ptrace.h>
-#include <asm/pgtable.h>
#include <asm/oplib.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/scsi/smartpqi/Kconfig b/drivers/scsi/smartpqi/Kconfig
index d3311c014863..8eec241f074b 100644
--- a/drivers/scsi/smartpqi/Kconfig
+++ b/drivers/scsi/smartpqi/Kconfig
@@ -42,7 +42,7 @@ config SCSI_SMARTPQI
depends on PCI && SCSI && !S390
select SCSI_SAS_ATTRS
select RAID_ATTRS
- ---help---
+ help
This driver supports Microsemi PQI controllers.
<http://www.microsemi.com>
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
index f8397978f8ab..03d43f016397 100644
--- a/drivers/scsi/sni_53c710.c
+++ b/drivers/scsi/sni_53c710.c
@@ -28,7 +28,6 @@
#include <linux/platform_device.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/delay.h>
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 4dcd735ea49e..0c4aa4665a2f 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -792,7 +792,7 @@ static int sr_probe(struct device *dev)
disk->queue = sdev->request_queue;
if (register_cdrom(disk, &cd->cdi))
- goto fail_put;
+ goto fail_minor;
/*
* Initialize block layer runtime PM stuffs before the
@@ -810,8 +810,13 @@ static int sr_probe(struct device *dev)
return 0;
+fail_minor:
+ spin_lock(&sr_index_lock);
+ clear_bit(minor, sr_index_bits);
+ spin_unlock(&sr_index_lock);
fail_put:
put_disk(disk);
+ mutex_destroy(&cd->lock);
fail_free:
kfree(cd);
fail:
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 4bf4ab3b70f4..87fbc0ea350b 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4921,7 +4921,7 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
unsigned long start = uaddr >> PAGE_SHIFT;
const int nr_pages = end - start;
- int res, i, j;
+ int res, i;
struct page **pages;
struct rq_map_data *mdata = &STbp->map_data;
@@ -4943,7 +4943,7 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
/* Try to fault in all of the necessary pages */
/* rw==READ means read from drive, write into memory area */
- res = get_user_pages_fast(uaddr, nr_pages, rw == READ ? FOLL_WRITE : 0,
+ res = pin_user_pages_fast(uaddr, nr_pages, rw == READ ? FOLL_WRITE : 0,
pages);
/* Errors and no page mapped should return here */
@@ -4963,8 +4963,7 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
return nr_pages;
out_unmap:
if (res > 0) {
- for (j=0; j < res; j++)
- put_page(pages[j]);
+ unpin_user_pages(pages, res);
res = 0;
}
kfree(pages);
@@ -4976,18 +4975,9 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
static int sgl_unmap_user_pages(struct st_buffer *STbp,
const unsigned int nr_pages, int dirtied)
{
- int i;
-
- for (i=0; i < nr_pages; i++) {
- struct page *page = STbp->mapped_pages[i];
+ /* FIXME: cache flush missing for rw==READ */
+ unpin_user_pages_dirty_lock(STbp->mapped_pages, nr_pages, dirtied);
- if (dirtied)
- SetPageDirty(page);
- /* FIXME: cache flush missing for rw==READ
- * FIXME: call the correct reference counting function
- */
- put_page(page);
- }
kfree(STbp->mapped_pages);
STbp->mapped_pages = NULL;
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 072ed8728657..2d90cddd8ac2 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -2035,9 +2035,6 @@ static int storvsc_suspend(struct hv_device *hv_dev)
vmbus_close(hv_dev->channel);
- memset(stor_device->stor_chns, 0,
- num_possible_cpus() * sizeof(void *));
-
kfree(stor_device->stor_chns);
stor_device->stor_chns = NULL;
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e2005aeddc2d..d35378be89e8 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -38,7 +38,7 @@ config SCSI_UFSHCD
select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select NLS
- ---help---
+ help
This selects the support for UFS devices in Linux, say Y and make
sure that you know the name of your UFS host adapter (the card
inside your computer that "speaks" the UFS protocol, also
@@ -53,7 +53,7 @@ config SCSI_UFSHCD
config SCSI_UFSHCD_PCI
tristate "PCI bus based UFS Controller support"
depends on SCSI_UFSHCD && PCI
- ---help---
+ help
This selects the PCI UFS Host Controller Interface. Select this if
you have UFS Host Controller with PCI Interface.
@@ -64,7 +64,7 @@ config SCSI_UFSHCD_PCI
config SCSI_UFS_DWC_TC_PCI
tristate "DesignWare pci support using a G210 Test Chip"
depends on SCSI_UFSHCD_PCI
- ---help---
+ help
Synopsys Test Chip is a PHY for prototyping purposes.
If unsure, say N.
@@ -72,7 +72,7 @@ config SCSI_UFS_DWC_TC_PCI
config SCSI_UFSHCD_PLATFORM
tristate "Platform bus based UFS Controller support"
depends on SCSI_UFSHCD
- ---help---
+ help
This selects the UFS host controller support. Select this if
you have an UFS controller on Platform bus.
@@ -91,7 +91,7 @@ config SCSI_UFS_CDNS_PLATFORM
config SCSI_UFS_DWC_TC_PLATFORM
tristate "DesignWare platform support using a G210 Test Chip"
depends on SCSI_UFSHCD_PLATFORM
- ---help---
+ help
Synopsys Test Chip is a PHY for prototyping purposes.
If unsure, say N.
@@ -126,7 +126,7 @@ config SCSI_UFS_MEDIATEK
config SCSI_UFS_HISI
tristate "Hisilicon specific hooks to UFS controller platform driver"
depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
- ---help---
+ help
This selects the Hisilicon specific additions to UFSHCD platform driver.
Select this if you have UFS controller on Hisilicon chipset.
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 5db18f444ea9..ad4fc829cbb2 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5076,6 +5076,7 @@ static void ufshcd_force_reset_auto_bkops(struct ufs_hba *hba)
hba->ee_ctrl_mask &= ~MASK_EE_URGENT_BKOPS;
ufshcd_disable_auto_bkops(hba);
}
+ hba->urgent_bkops_lvl = BKOPS_STATUS_PERF_IMPACT;
hba->is_urgent_bkops_lvl_checked = false;
}
@@ -5123,7 +5124,6 @@ static int ufshcd_bkops_ctrl(struct ufs_hba *hba,
err = ufshcd_enable_auto_bkops(hba);
else
err = ufshcd_disable_auto_bkops(hba);
- hba->urgent_bkops_lvl = curr_status;
out:
return err;
}
@@ -7373,10 +7373,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
if (ret)
goto out;
- /* set the default level for urgent bkops */
- hba->urgent_bkops_lvl = BKOPS_STATUS_PERF_IMPACT;
- hba->is_urgent_bkops_lvl_checked = false;
-
/* Debug counters initialization */
ufshcd_clear_dbg_ufs_stats(hba);
diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c
index c6727bcbc2e3..928c8adf5cb3 100644
--- a/drivers/scsi/zorro_esp.c
+++ b/drivers/scsi/zorro_esp.c
@@ -34,9 +34,9 @@
#include <linux/delay.h>
#include <linux/zorro.h>
#include <linux/slab.h>
+#include <linux/pgtable.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
diff --git a/drivers/sfi/Kconfig b/drivers/sfi/Kconfig
index 1878d378869a..3d0b64db214e 100644
--- a/drivers/sfi/Kconfig
+++ b/drivers/sfi/Kconfig
@@ -5,7 +5,7 @@
menuconfig SFI
bool "SFI (Simple Firmware Interface) Support"
- ---help---
+ help
The Simple Firmware Interface (SFI) provides a lightweight method
for platform firmware to pass information to the operating system
via static tables in memory. Kernel SFI support is required to
diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 323e177aa74d..c95fa30f1a76 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -8,7 +8,7 @@ config SOC_ASPEED
config ASPEED_LPC_CTRL
depends on SOC_ASPEED && REGMAP && MFD_SYSCON
tristate "Aspeed ast2400/2500 HOST LPC to BMC bridge control"
- ---help---
+ help
Control Aspeed ast2400/2500 HOST LPC to BMC mappings through
ioctl()s, the driver also provides a read/write interface to a BMC ram
region where the host LPC read/write region can be buffered.
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 250a393f255d..07bb261a63d2 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -35,15 +35,6 @@ config QCOM_GENI_SE
driver is also used to manage the common aspects of multiple Serial
Engines present in the QUP.
-config QCOM_GLINK_SSR
- tristate "Qualcomm Glink SSR driver"
- depends on RPMSG
- depends on QCOM_RPROC_COMMON
- help
- Say y here to enable GLINK SSR support. The GLINK SSR driver
- implements the SSR protocol for notifying the remote processor about
- neighboring subsystems going up or down.
-
config QCOM_GSBI
tristate "QCOM General Serial Bus Interface"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 92cc4232d72c..7d7e2ecbdce6 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -3,7 +3,6 @@ CFLAGS_rpmh-rsc.o := -I$(src)
obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
-obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
obj-$(CONFIG_QCOM_OCMEM) += ocmem.o
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index a9939ff9490e..4ec5528f89fa 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig STAGING
bool "Staging drivers"
- ---help---
+ help
This option allows you to select a number of drivers that are
not of the "normal" Linux kernel quality level. These drivers
are placed here in order to get a wider audience to make use of
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 8044510d8ec6..c05a214191da 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -555,7 +555,7 @@ static int set_name(struct ashmem_area *asma, void __user *name)
/*
* Holding the ashmem_mutex while doing a copy_from_user might cause
- * an data abort which would try to access mmap_sem. If another
+ * an data abort which would try to access mmap_lock. If another
* thread has invoked ashmem_mmap then it will be holding the
* semaphore and will be waiting for ashmem_mutex, there by leading to
* deadlock. We'll release the mutex and take the name to a local
@@ -586,7 +586,7 @@ static int get_name(struct ashmem_area *asma, void __user *name)
* Have a local variable to which we'll copy the content
* from asma with the lock held. Later we can copy this to the user
* space safely without holding any locks. So even if we proceed to
- * wait for mmap_sem, it won't lead to deadlock.
+ * wait for mmap_lock, it won't lead to deadlock.
*/
char local_name[ASHMEM_NAME_LEN];
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index a56c8f74a27b..e85a99b68f31 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2325,7 +2325,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
int retval = 0;
/*
- * 'trylock' avoids circular dependency with current->mm->mmap_sem
+ * 'trylock' avoids circular dependency with current->mm->mmap_lock
* and down-reading &dev->attach_lock should normally succeed without
* contention unless the device is in the process of being attached
* or detached.
diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig
index d4777f5a8b90..9389e7a922fa 100644
--- a/drivers/staging/greybus/Kconfig
+++ b/drivers/staging/greybus/Kconfig
@@ -4,7 +4,7 @@ if GREYBUS
config GREYBUS_AUDIO
tristate "Greybus Audio Class driver"
depends on SOUND
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Audio Class specification.
@@ -13,7 +13,7 @@ config GREYBUS_AUDIO
config GREYBUS_BOOTROM
tristate "Greybus Bootrom Class driver"
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Bootrom Class specification.
@@ -23,7 +23,7 @@ config GREYBUS_BOOTROM
config GREYBUS_CAMERA
tristate "Greybus Camera Class driver"
depends on MEDIA_SUPPORT && LEDS_CLASS_FLASH && BROKEN
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Camera Class specification.
@@ -33,7 +33,7 @@ config GREYBUS_CAMERA
config GREYBUS_FIRMWARE
tristate "Greybus Firmware Download Class driver"
depends on SPI
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Firmware Download Class specification.
@@ -43,7 +43,7 @@ config GREYBUS_FIRMWARE
config GREYBUS_HID
tristate "Greybus HID Class driver"
depends on HID && INPUT
- ---help---
+ help
Select this option if you have a device that follows the
Greybus HID Class specification.
@@ -53,7 +53,7 @@ config GREYBUS_HID
config GREYBUS_LIGHT
tristate "Greybus LED Class driver"
depends on LEDS_CLASS
- ---help---
+ help
Select this option if you have a device that follows the
Greybus LED Class specification.
@@ -62,7 +62,7 @@ config GREYBUS_LIGHT
config GREYBUS_LOG
tristate "Greybus Debug Log Class driver"
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Debug Log Class specification.
@@ -71,7 +71,7 @@ config GREYBUS_LOG
config GREYBUS_LOOPBACK
tristate "Greybus Loopback Class driver"
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Debug Log Class specification.
@@ -81,7 +81,7 @@ config GREYBUS_LOOPBACK
config GREYBUS_POWER
tristate "Greybus Powersupply Class driver"
depends on POWER_SUPPLY
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Powersupply Class specification.
@@ -90,7 +90,7 @@ config GREYBUS_POWER
config GREYBUS_RAW
tristate "Greybus Raw Class driver"
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Raw Class specification.
@@ -99,7 +99,7 @@ config GREYBUS_RAW
config GREYBUS_VIBRATOR
tristate "Greybus Vibrator Motor Class driver"
- ---help---
+ help
Select this option if you have a device that follows the
Greybus Vibrator Motor Class specification.
@@ -108,7 +108,7 @@ config GREYBUS_VIBRATOR
menuconfig GREYBUS_BRIDGED_PHY
tristate "Greybus Bridged PHY Class drivers"
- ---help---
+ help
Select this option to pick from a variety of Greybus Bridged
PHY class drivers. These drivers emulate a number of
different "traditional" busses by tunneling them over Greybus.
@@ -123,7 +123,7 @@ config GREYBUS_GPIO
tristate "Greybus GPIO Bridged PHY driver"
depends on GPIOLIB
select GPIOLIB_IRQCHIP
- ---help---
+ help
Select this option if you have a device that follows the
Greybus GPIO Bridged PHY Class specification.
@@ -133,7 +133,7 @@ config GREYBUS_GPIO
config GREYBUS_I2C
tristate "Greybus I2C Bridged PHY driver"
depends on I2C
- ---help---
+ help
Select this option if you have a device that follows the
Greybus I2C Bridged PHY Class specification.
@@ -143,7 +143,7 @@ config GREYBUS_I2C
config GREYBUS_PWM
tristate "Greybus PWM Bridged PHY driver"
depends on PWM
- ---help---
+ help
Select this option if you have a device that follows the
Greybus PWM Bridged PHY Class specification.
@@ -153,7 +153,7 @@ config GREYBUS_PWM
config GREYBUS_SDIO
tristate "Greybus SDIO Bridged PHY driver"
depends on MMC
- ---help---
+ help
Select this option if you have a device that follows the
Greybus SDIO Bridged PHY Class specification.
@@ -163,7 +163,7 @@ config GREYBUS_SDIO
config GREYBUS_SPI
tristate "Greybus SPI Bridged PHY driver"
depends on SPI
- ---help---
+ help
Select this option if you have a device that follows the
Greybus SPI Bridged PHY Class specification.
@@ -173,7 +173,7 @@ config GREYBUS_SPI
config GREYBUS_UART
tristate "Greybus UART Bridged PHY driver"
depends on TTY
- ---help---
+ help
Select this option if you have a device that follows the
Greybus UART Bridged PHY Class specification.
@@ -183,7 +183,7 @@ config GREYBUS_UART
config GREYBUS_USB
tristate "Greybus USB Host Bridged PHY driver"
depends on USB
- ---help---
+ help
Select this option if you have a device that follows the
Greybus USB Host Bridged PHY Class specification.
@@ -195,7 +195,7 @@ endif # GREYBUS_BRIDGED_PHY
config GREYBUS_ARCHE
tristate "Greybus Arche Platform driver"
depends on USB_HSIC_USB3613 || COMPILE_TEST
- ---help---
+ help
Select this option if you have an Arche device.
To compile this code as a module, chose M here: the module
diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
index 7caabdd77bbf..89753463e926 100644
--- a/drivers/staging/kpc2000/kpc_dma/fileops.c
+++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
@@ -75,9 +75,9 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
}
// Lock the user buffer pages in memory, and hold on to the page pointers (for the sglist)
- down_read(&current->mm->mmap_sem); /* get memory map semaphore */
+ mmap_read_lock(current->mm); /* get memory map semaphore */
rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL);
- up_read(&current->mm->mmap_sem); /* release the semaphore */
+ mmap_read_unlock(current->mm); /* release the semaphore */
if (rv != acd->page_count) {
dev_err(&priv->ldev->pldev->dev, "Couldn't get_user_pages (%ld)\n", rv);
goto err_get_user_pages;
diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig
index c4f3049b0706..fea06cb0eb48 100644
--- a/drivers/staging/media/atomisp/Kconfig
+++ b/drivers/staging/media/atomisp/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
menuconfig INTEL_ATOMISP
bool "Enable support to Intel Atom ISP camera drivers"
depends on X86 && EFI && PCI && ACPI
@@ -11,9 +12,10 @@ menuconfig INTEL_ATOMISP
config VIDEO_ATOMISP
tristate "Intel Atom Image Signal Processor Driver"
depends on VIDEO_V4L2 && INTEL_ATOMISP
+ depends on PMIC_OPREGION
select IOSF_MBI
select VIDEOBUF_VMALLOC
- ---help---
+ help
Say Y here if your platform supports Intel Atom SoC
camera imaging subsystem.
To compile this driver as a module, choose M here: the
diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile
index eedecd49bbf4..9dc8072799e3 100644
--- a/drivers/staging/media/atomisp/Makefile
+++ b/drivers/staging/media/atomisp/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for camera drivers.
#
@@ -36,7 +37,6 @@ atomisp-objs += \
pci/sh_css_param_dvs.o \
pci/sh_css_param_shading.o \
pci/sh_css_params.o \
- pci/sh_css_pipe.o \
pci/sh_css_properties.o \
pci/sh_css_shading.o \
pci/sh_css_sp.o \
@@ -53,10 +53,7 @@ atomisp-objs += \
pci/hmm/hmm_dynamic_pool.o \
pci/hmm/hmm.o \
pci/hmm/hmm_reserved_pool.o \
- pci/hmm/hmm_vm.o \
- pci/hrt/hive_isp_css_mm_hrt.o \
pci/ia_css_device_access.o \
- pci/ia_css_memory_access.o \
pci/isp/kernels/aa/aa_2/ia_css_aa2.host.o \
pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.o \
pci/isp/kernels/anr/anr_2/ia_css_anr2.host.o \
@@ -117,7 +114,6 @@ atomisp-objs += \
pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.o \
pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.o \
pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.o \
- pci/memory_realloc.o \
pci/mmu/isp_mmu.o \
pci/mmu/sh_mmu_mrfld.o \
pci/runtime/binary/src/binary.o \
@@ -328,11 +324,6 @@ INCLUDES_cht += \
# -I$(atomisp)/pci/css_2401_system/hrt/ \
# -I$(atomisp)/pci/css_2401_system/hive_isp_css_2401_system_generated/ \
-
-ifeq ($(CONFIG_ION),y)
-INCLUDES += -I$(srctree)/drivers/staging/android/ion
-endif
-
DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__
#DEFINES += -DUSE_DYNAMIC_BIN
#DEFINES += -DISP_POWER_GATING
@@ -352,12 +343,3 @@ DEFINES += -DISP2400 -DSYSTEM_hive_isp_css_2400_system
endif
ccflags-y += $(INCLUDES) $(DEFINES) -fno-common
-
-# HACK! While this driver is in bad shape, don't enable several warnings
-# that would be otherwise enabled with W=1
-ccflags-y += $(call cc-disable-warning, implicit-fallthrough)
-ccflags-y += $(call cc-disable-warning, missing-prototypes)
-ccflags-y += $(call cc-disable-warning, missing-declarations)
-ccflags-y += $(call cc-disable-warning, suggest-attribute=format)
-ccflags-y += $(call cc-disable-warning, unused-const-variable)
-ccflags-y += $(call cc-disable-warning, unused-but-set-variable)
diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO
index 52683a704223..6987bb2d32cf 100644
--- a/drivers/staging/media/atomisp/TODO
+++ b/drivers/staging/media/atomisp/TODO
@@ -1,71 +1,127 @@
-1. A single AtomISP driver needs to be implemented to support both
- Baytrail (BYT and Cherrytail (CHT) platforms at the same time.
+NOTE:
+=====
+
+While the driver probes the hardware and reports itself as a
+V4L2 driver, there are still some issues preventing it to
+stream (at least it doesn't with the standard V4L2 applications.
+Didn't test yet with some custom-made app for this driver).
+Solving the related bugs and issues preventing it to work is
+needed (items 6 and 7 from the list below).
+
+TODO
+====
+
+1. The atomisp doesn't rely at the usual i2c stuff to discover the
+ sensors. Instead, it calls a function from atomisp_gmin_platform.c.
+ There are some hacks added there for it to wait for sensors to be
+ probed (with a timeout of 2 seconds or so).
+ This should be converted to the usual way, using V4L2 async subdev
+ framework to wait for cameras to be probed;
+
+2. Use ACPI _DSM table - DONE!
+
+3. Switch the driver to use pm_runtime stuff. Right now, it probes the
+ existing PMIC code and sensors call it directly.
+
+4. There's a problem at the sensor drivers: when trying to set a video
+ format, the atomisp main driver calls the sensor drivers with the
+ sensor turned off. This causes them to fail.
+
+ The only exception is the atomisp-ov2880, which has a hack inside it
+ to turn it on when VIDIOC_S_FMT is called.
+
+ The right fix seems to power on the sensor when a video device is
+ opened (or at the first VIDIOC_ ioctl - except for VIDIOC_QUERYCAP),
+ powering it down at close() syscall.
+
+ Such kind of control would need to be done inside the atomisp driver,
+ not at the sensors code.
+
+5. There are several issues related to memory management, causing
+ crashes. The atomisp splits the memory management on three separate
+ regions:
+
+ - dynamic pool;
+ - reserved pool;
+ - generic pool
+
+ The code implementing it is at:
+
+ drivers/staging/media/atomisp/pci/hmm/
+
+ It also has a separate code for managing DMA buffers at:
+
+ drivers/staging/media/atomisp/pci/mmu/
+
+ The code there is really dirty, ugly and probably wrong. I fixed
+ one bug there already, but the best would be to just trash it and use
+ something else. Maybe the code from the newer intel driver could
+ serve as a model:
+
+ drivers/staging/media/ipu3/ipu3-mmu.c
+
+ But converting it to use something like that is painful and may
+ cause some breakages.
+
+6. There is some issues at the frame receive logic, causing the
+ DQBUF ioctls to fail.
+
+7. A single AtomISP driver needs to be implemented to support both
+ Baytrail (BYT) and Cherrytail (CHT) platforms at the same time.
The current driver is a mechanical and hand combined merge of the
two using several runtime macros, plus some ifdef ISP2401 to select the
CHT version. Yet, there are some ISP-specific headers that change the
driver's behavior during compile time.
-2. The file structure needs to get tidied up to resemble a normal Linux
+8. The file structure needs to get tidied up to resemble a normal Linux
driver.
-3. Lots of the midlayer glue. unused code and abstraction needs removing.
+9. Lots of the midlayer glue. unused code and abstraction needs removing.
-3. The sensor drivers read MIPI settings from EFI variables or default to the
- settings hard-coded in the platform data file for different platforms.
- It should be possible to improve it, by adding support for _DSM tables.
+10. The AtomISP driver includes some special IOCTLS (ATOMISP_IOC_XXXX_XXXX)
+ and controls that require some cleanup. Some of those code may have
+ been removed during the cleanups. They could be needed in order to
+ properly support 3A algorithms
-4. The sensor drivers use PMIC and the regulator framework API. In the ideal
- world it would be using ACPI but that's not how the existing devices work.
+ Such IOCTL interface needs more documentation. The better would
+ be to use something close to the interface used by the IPU3 IMGU driver.
-5. The AtomISP driver includes some special IOCTLS (ATOMISP_IOC_XXXX_XXXX)
- and controls that require some cleanup.
+11. The ISP code has some dependencies of the exact FW version.
+ The version defined in pci/sh_css_firmware.c:
-6. Correct Coding Style. Please don't send coding style patches for this
- driver until the other work is done.
+ BYT (isp2400): "irci_stable_candrpv_0415_20150521_0458"
-7. The ISP code has some dependencies of the exact FW version.
- The version defined in pci/sh_css_firmware.c:
- BYT:
- static const char *isp2400_release_version = STR(irci_stable_candrpv_0415_20150521_0458);
+ CHT (isp2401): "irci_ecr - master_20150911_0724"
- CHT:
- static const char *isp2401_release_version = STR(irci_ecr - master_20150911_0724);
+ Those versions don't seem to be available anymore. On the tests we've
+ done so far, this version also seems to work for CHT:
- Those versions don't seem to be available anymore. On the tests we've
- done so far, this version also seems to work for isp2401:
+ "irci_stable_candrpv_0415_20150521_0458"
- irci_stable_candrpv_0415_20150521_0458
+ Which can be obtainable from Yocto Atom ISP respository.
- At some point we may need to round up a few driver versions and see if
- there are any specific things that can be done to fold in support for
- multiple firmware versions.
+ but this was not thoroughly tested.
-8. Switch to V4L2 async API to set up sensor, lens and flash devices.
- Control those devices using V4L2 sub-device API without custom
- extensions.
+ At some point we may need to round up a few driver versions and see if
+ there are any specific things that can be done to fold in support for
+ multiple firmware versions.
-9. Switch to standard V4L2 sub-device API for sensor and lens. In
- particular, the user space API needs to support V4L2 controls as
- defined in the V4L2 spec and references to atomisp must be removed from
- these drivers.
+12. Switch to standard V4L2 sub-device API for sensor and lens. In
+ particular, the user space API needs to support V4L2 controls as
+ defined in the V4L2 spec and references to atomisp must be removed from
+ these drivers.
-10. Use LED flash API for flash LED drivers such as LM3554 (which already
+13. Use LED flash API for flash LED drivers such as LM3554 (which already
has a LED class driver).
-11. Switch from videobuf1 to videobuf2. Videobuf1 is being removed!
-
-12. There are some memory management code that seems to be
- forked from Kernel 3.10 inside hmm/ directory. Get rid of it,
- making the driver to use a more standard memory management module.
+14. Switch from videobuf1 to videobuf2. Videobuf1 is being removed!
-13. While the driver probes the hardware and reports itself as a
- V4L2 driver, there are still some issues preventing it to
- stream (at least it doesn't with the standard V4L2 applications.
- Didn't test yet with some custom-made app for this driver).
- Solving the related bugs and issues preventing it to work is
- needed.
+15. Correct Coding Style. Please refrain sending coding style patches
+ for this driver until the other work is done, as there will be a lot
+ of code churn until this driver becomes functional again.
-Limitations:
+Limitations
+===========
1. To test the patches, you also need the ISP firmware
@@ -76,14 +132,16 @@ Limitations:
device but can also be extracted from the upgrade kit if you've managed
to lose them somehow.
-2. Without a 3A libary the capture behaviour is not very good. To take a good
- picture, you need tune ISP parameters by IOCTL functions or use a 3A libary
+2. Without a 3A library the capture behaviour is not very good. To take a good
+ picture, you need tune ISP parameters by IOCTL functions or use a 3A library
such as libxcam.
3. The driver is intended to drive the PCI exposed versions of the device.
It will not detect those devices enumerated via ACPI as a field of the
i915 GPU driver.
+ There are some patches adding i915 GPU support floating at the Yocto's
+ Aero repository (so far, untested upstream).
+
4. The driver supports only v2 of the IPU/Camera. It will not work with the
versions of the hardware in other SoCs.
-
diff --git a/drivers/staging/media/atomisp/i2c/Kconfig b/drivers/staging/media/atomisp/i2c/Kconfig
index f7f7177b9b37..7c7f0fc090b3 100644
--- a/drivers/staging/media/atomisp/i2c/Kconfig
+++ b/drivers/staging/media/atomisp/i2c/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Kconfig for sensor drivers
#
@@ -8,7 +9,7 @@ config VIDEO_ATOMISP_OV2722
tristate "OVT ov2722 sensor support"
depends on ACPI
depends on I2C && VIDEO_V4L2
- ---help---
+ help
This is a Video4Linux2 sensor-level driver for the OVT
OV2722 raw camera.
@@ -20,7 +21,7 @@ config VIDEO_ATOMISP_GC2235
tristate "Galaxy gc2235 sensor support"
depends on ACPI
depends on I2C && VIDEO_V4L2
- ---help---
+ help
This is a Video4Linux2 sensor-level driver for the OVT
GC2235 raw camera.
@@ -31,7 +32,7 @@ config VIDEO_ATOMISP_GC2235
config VIDEO_ATOMISP_MSRLIST_HELPER
tristate "Helper library to load, parse and apply large register lists."
depends on I2C
- ---help---
+ help
This is a helper library to be used from a sensor driver to load, parse
and apply large register lists.
@@ -42,7 +43,7 @@ config VIDEO_ATOMISP_MT9M114
tristate "Aptina mt9m114 sensor support"
depends on ACPI
depends on I2C && VIDEO_V4L2
- ---help---
+ help
This is a Video4Linux2 sensor-level driver for the Micron
mt9m114 1.3 Mpixel camera.
@@ -54,15 +55,15 @@ config VIDEO_ATOMISP_GC0310
tristate "GC0310 sensor support"
depends on ACPI
depends on I2C && VIDEO_V4L2
- ---help---
+ help
This is a Video4Linux2 sensor-level driver for the Galaxycore
GC0310 0.3MP sensor.
-
+
config VIDEO_ATOMISP_OV2680
tristate "Omnivision OV2680 sensor support"
depends on ACPI
depends on I2C && VIDEO_V4L2
- ---help---
+ help
This is a Video4Linux2 sensor-level driver for the Omnivision
OV2680 raw camera.
@@ -78,7 +79,7 @@ config VIDEO_ATOMISP_LM3554
tristate "LM3554 flash light driver"
depends on ACPI
depends on VIDEO_V4L2 && I2C
- ---help---
+ help
This is a Video4Linux2 sub-dev driver for the LM3554
flash light driver.
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index ad1bd7d6a02b..2b71de722ec3 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for GalaxyCore GC0310 VGA camera sensor.
*
@@ -1309,18 +1310,6 @@ static int gc0310_probe(struct i2c_client *client)
int ret;
void *pdata;
unsigned int i;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- pr_info("%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
-
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index a12dd0e858bc..78147ffb6099 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for GalaxyCore GC2235 2M camera sensor.
*
@@ -1051,17 +1052,6 @@ static int gc2235_probe(struct i2c_client *client)
void *gcpdev;
int ret;
unsigned int i;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- pr_info("%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c b/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c
index 33ab884f7352..b93c80471f22 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2013 Intel Corporation. All Rights Reserved.
*
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
index a899145265ff..809010af7855 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* LED flash driver for LM3554
*
@@ -850,17 +851,6 @@ static int lm3554_probe(struct i2c_client *client)
struct lm3554 *flash;
unsigned int i;
int ret;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- pr_info("%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
flash = kzalloc(sizeof(*flash), GFP_KERNEL);
if (!flash)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index ac61b391e3f9..0d60918a9b19 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for mt9m114 Camera Sensor.
*
@@ -1816,17 +1817,6 @@ static int mt9m114_probe(struct i2c_client *client)
int ret = 0;
unsigned int i;
void *pdata;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- pr_info("%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
/* Setup sensor configuration structure */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 1b60f6a9c0e0..90d125ba080f 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for OmniVision OV2680 1080p HD camera sensor.
*
@@ -703,7 +704,7 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag)
if (!dev || !dev->platform_data)
return -ENODEV;
- dev_dbg(&client->dev, "%s: %s", __func__, flag? "on" : "off");
+ dev_dbg(&client->dev, "%s: %s", __func__, flag ? "on" : "off");
if (flag) {
ret |= dev->platform_data->v1p8_ctrl(sd, 1);
@@ -1243,17 +1244,6 @@ static int ov2680_probe(struct i2c_client *client)
int ret;
void *pdata;
unsigned int i;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- dev_info(&client->dev, "%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 718d10f89d5a..eecefcd734d0 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for OmniVision OV2722 1080p HD camera sensor.
*
@@ -1214,17 +1215,6 @@ static int ov2722_probe(struct i2c_client *client)
struct ov2722_device *dev;
void *ovpdev;
int ret;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- pr_info("%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
index 12f746e7828b..2fe3de115083 100644
--- a/drivers/staging/media/atomisp/i2c/gc0310.h
+++ b/drivers/staging/media/atomisp/i2c/gc0310.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for GalaxyCore GC0310 VGA camera sensor.
*
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index bb104de61af9..68252b8f516d 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for GalaxyCore GC2235 2M camera sensor.
*
diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h
index 172cec0bb398..787bbf59e895 100644
--- a/drivers/staging/media/atomisp/i2c/mt9m114.h
+++ b/drivers/staging/media/atomisp/i2c/mt9m114.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for mt9m114 Camera Sensor.
*
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 034e1032f6c0..49920245e064 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for OmniVision OV2680 5M camera sensor.
*
@@ -456,6 +457,7 @@ static struct ov2680_reg const ov2680_656x496_30fps[] = {
// {0x5090, 0x0c},
{}
};
+
/*
* 800x600 30fps VBlanking 1lane 10Bit (binning)
*/
@@ -500,6 +502,7 @@ static struct ov2680_reg const ov2680_720x592_30fps[] = {
{0x5081, 0x41},
{}
};
+
/*
* 800x600 30fps VBlanking 1lane 10Bit (binning)
*/
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index 1110d723968e..7b0debb6c53d 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for OmniVision OV2722 1080p HD camera sensor.
*
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/Kconfig b/drivers/staging/media/atomisp/i2c/ov5693/Kconfig
index 3f527f2047a7..c8d09f416c35 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/Kconfig
+++ b/drivers/staging/media/atomisp/i2c/ov5693/Kconfig
@@ -1,8 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
config VIDEO_ATOMISP_OV5693
tristate "Omnivision ov5693 sensor support"
depends on ACPI
depends on I2C && VIDEO_V4L2
- ---help---
+ help
This is a Video4Linux2 sensor-level driver for the Micron
ov5693 5 Mpixel camera.
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h b/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h
index c97ab24c5d2b..f1362cd69f6e 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for AD5823 VCM.
*
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
index 2be0ef14d53e..97ab10bc45ca 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for OmniVision OV5693 1080p HD camera sensor.
*
@@ -1087,7 +1088,7 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_VCM_SLEW:
ret = ov5693_t_vcm_slew(&dev->sd, ctrl->val);
break;
- case V4L2_CID_VCM_TIMEING:
+ case V4L2_CID_VCM_TIMING:
ret = ov5693_t_vcm_timing(&dev->sd, ctrl->val);
break;
default:
@@ -1230,7 +1231,7 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
},
{
.ops = &ctrl_ops,
- .id = V4L2_CID_VCM_TIMEING,
+ .id = V4L2_CID_VCM_TIMING,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "vcm step time",
.min = 0,
@@ -1901,17 +1902,6 @@ static int ov5693_probe(struct i2c_client *client)
int ret = 0;
void *pdata;
unsigned int i;
- acpi_handle handle;
- struct acpi_device *adev;
-
- handle = ACPI_HANDLE(&client->dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_err(&client->dev, "Error could not get ACPI device\n");
- return -ENODEV;
- }
- pr_info("%s: ACPI detected it on bus ID=%s, HID=%s\n",
- __func__, acpi_device_bid(adev), acpi_device_hid(adev));
- // FIXME: may need to release resources allocated by acpi_bus_get_device()
/*
* Firmware workaround: Some modules use a "secondary default"
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index 0189907969c6..79df07bd69b6 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for OmniVision OV5693 5M camera sensor.
*
diff --git a/drivers/staging/media/atomisp/include/hmm/hmm.h b/drivers/staging/media/atomisp/include/hmm/hmm.h
index 254a71442451..b48bdf5c274c 100644
--- a/drivers/staging/media/atomisp/include/hmm/hmm.h
+++ b/drivers/staging/media/atomisp/include/hmm/hmm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -28,8 +29,8 @@
#include "hmm/hmm_pool.h"
#include "ia_css_types.h"
-#define HMM_CACHED true
-#define HMM_UNCACHED false
+#define mmgr_NULL ((ia_css_ptr)0)
+#define mmgr_EXCEPTION ((ia_css_ptr) - 1)
int hmm_pool_register(unsigned int pool_size, enum hmm_pool_type pool_type);
void hmm_pool_unregister(enum hmm_pool_type pool_type);
@@ -38,7 +39,8 @@ int hmm_init(void);
void hmm_cleanup(void);
ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type,
- int from_highmem, const void __user *userptr, bool cached);
+ int from_highmem, const void __user *userptr,
+ const uint16_t attrs);
void hmm_free(ia_css_ptr ptr);
int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes);
int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes);
diff --git a/drivers/staging/media/atomisp/include/hmm/hmm_bo.h b/drivers/staging/media/atomisp/include/hmm/hmm_bo.h
index f847d1de860e..8c78a5d87b65 100644
--- a/drivers/staging/media/atomisp/include/hmm/hmm_bo.h
+++ b/drivers/staging/media/atomisp/include/hmm/hmm_bo.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -77,9 +78,6 @@ enum hmm_bo_type {
HMM_BO_PRIVATE,
HMM_BO_SHARE,
HMM_BO_USER,
-#ifdef CONFIG_ION
- HMM_BO_ION,
-#endif
HMM_BO_LAST,
};
@@ -111,9 +109,6 @@ struct hmm_bo_device {
/* list lock is used to protect the entire_bo_list */
spinlock_t list_lock;
-#ifdef CONFIG_ION
- struct ion_client *iclient;
-#endif
int flag;
/* linked list for entire buffer object */
@@ -136,15 +131,14 @@ struct hmm_buffer_object {
struct list_head list;
struct kref kref;
+ struct page **pages;
+
/* mutex protecting this BO */
struct mutex mutex;
enum hmm_bo_type type;
struct hmm_page_object *page_obj; /* physical pages */
int from_highmem;
int mmap_count;
-#ifdef CONFIG_ION
- struct ion_handle *ihandle;
-#endif
int status;
int mem_type;
void *vmap_addr; /* kernel virtual address by vmap */
diff --git a/drivers/staging/media/atomisp/include/hmm/hmm_common.h b/drivers/staging/media/atomisp/include/hmm/hmm_common.h
index 00885203fb14..7152e9b52ba4 100644
--- a/drivers/staging/media/atomisp/include/hmm/hmm_common.h
+++ b/drivers/staging/media/atomisp/include/hmm/hmm_common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/include/hmm/hmm_pool.h b/drivers/staging/media/atomisp/include/hmm/hmm_pool.h
index 8caf00502d74..3fef57de973c 100644
--- a/drivers/staging/media/atomisp/include/hmm/hmm_pool.h
+++ b/drivers/staging/media/atomisp/include/hmm/hmm_pool.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/include/hmm/hmm_vm.h b/drivers/staging/media/atomisp/include/hmm/hmm_vm.h
deleted file mode 100644
index 93ac5e445137..000000000000
--- a/drivers/staging/media/atomisp/include/hmm/hmm_vm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Support for Medifield PNW Camera Imaging ISP subsystem.
- *
- * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
- *
- * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- *
- */
-
-#ifndef __HMM_VM_H__
-#define __HMM_VM_H__
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include <linux/list.h>
-
-struct hmm_vm {
- unsigned int start;
- unsigned int pgnr;
- unsigned int size;
- struct list_head vm_node_list;
- spinlock_t lock;
- struct kmem_cache *cache;
-};
-
-struct hmm_vm_node {
- struct list_head list;
- unsigned int start;
- unsigned int pgnr;
- unsigned int size;
- struct hmm_vm *vm;
-};
-
-#define ISP_VM_START 0x0
-#define ISP_VM_SIZE (0x7FFFFFFF) /* 2G address space */
-#define ISP_PTR_NULL NULL
-
-int hmm_vm_init(struct hmm_vm *vm, unsigned int start,
- unsigned int size);
-
-void hmm_vm_clean(struct hmm_vm *vm);
-
-struct hmm_vm_node *hmm_vm_alloc_node(struct hmm_vm *vm,
- unsigned int pgnr);
-
-void hmm_vm_free_node(struct hmm_vm_node *node);
-
-struct hmm_vm_node *hmm_vm_find_node_start(struct hmm_vm *vm,
- unsigned int addr);
-
-struct hmm_vm_node *hmm_vm_find_node_in_range(struct hmm_vm *vm,
- unsigned int addr);
-
-#endif
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index e9670749bae0..22c4103b0385 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -69,9 +70,6 @@
#define V4L2_MBUS_FMT_CUSTOM_M10MO_RAW 0x800b
#endif
-/* FIXME: for now, let's use a boolean to identify the type of atomisp chipset */
-extern bool atomisp_hw_is_isp2401;
-
/* Configuration used by Bayer noise reduction and YCC noise reduction */
struct atomisp_nr_config {
/* [gain] Strength of noise reduction for Bayer NR (Used by Bayer NR) */
@@ -509,7 +507,7 @@ struct atomisp_parameters {
struct atomisp_shading_table *shading_table;
struct atomisp_morph_table *morph_table;
struct atomisp_dvs_coefficients *dvs_coefs; /* DVS 1.0 coefficients */
- struct atomisp_dvs2_coefficients *dvs2_coefs; /* DVS 2.0 coefficients */
+ struct atomisp_dis_coefficients *dvs2_coefs; /* DVS 2.0 coefficients */
struct atomisp_capture_config *capture_config;
struct atomisp_anr_thres *anr_thres;
@@ -917,6 +915,8 @@ struct atomisp_acc_map {
#define ATOMISP_MAP_FLAG_NOFLUSH 0x0001 /* Do not flush cache */
#define ATOMISP_MAP_FLAG_CACHED 0x0002 /* Enable cache */
+#define ATOMISP_MAP_FLAG_CONTIGUOUS 0x0004
+#define ATOMISP_MAP_FLAG_CLEARED 0x0008
struct atomisp_acc_state {
__u32 flags; /* Flags, see list below */
@@ -1272,7 +1272,7 @@ struct atomisp_sensor_ae_bracketing_lut {
/* VCM slew control */
#define V4L2_CID_VCM_SLEW (V4L2_CID_CAMERA_LASTP1 + 11)
/* VCM step time */
-#define V4L2_CID_VCM_TIMEING (V4L2_CID_CAMERA_LASTP1 + 12)
+#define V4L2_CID_VCM_TIMING (V4L2_CID_CAMERA_LASTP1 + 12)
/* Query Focus Status */
#define V4L2_CID_FOCUS_STATUS (V4L2_CID_CAMERA_LASTP1 + 14)
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
index 8700ffd32bdb..58e0ea5355a3 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel MID SoC Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
index 9cf46325a696..873344a02ccf 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -17,6 +18,9 @@
#ifndef ATOMISP_PLATFORM_H_
#define ATOMISP_PLATFORM_H_
+#include <asm/intel-family.h>
+#include <asm/processor.h>
+
#include <linux/i2c.h>
#include <linux/sfi.h>
#include <media/v4l2-subdev.h>
@@ -237,11 +241,19 @@ const struct atomisp_camera_caps *atomisp_get_default_camera_caps(void);
/* API from old platform_camera.h, new CPUID implementation */
#define __IS_SOC(x) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \
boot_cpu_data.x86 == 6 && \
- boot_cpu_data.x86_model == x)
+ boot_cpu_data.x86_model == (x))
+#define __IS_SOCS(x,y) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \
+ boot_cpu_data.x86 == 6 && \
+ (boot_cpu_data.x86_model == (x) || \
+ boot_cpu_data.x86_model == (y)))
+
+#define IS_MFLD __IS_SOC(INTEL_FAM6_ATOM_SALTWELL_MID)
+#define IS_BYT __IS_SOC(INTEL_FAM6_ATOM_SILVERMONT)
+#define IS_CHT __IS_SOC(INTEL_FAM6_ATOM_AIRMONT)
+#define IS_MOFD __IS_SOC(INTEL_FAM6_ATOM_AIRMONT_MID)
-#define IS_MFLD __IS_SOC(0x27)
-#define IS_BYT __IS_SOC(0x37)
-#define IS_CHT __IS_SOC(0x4C)
-#define IS_MOFD __IS_SOC(0x5A)
+/* Both CHT and MOFD come with ISP2401 */
+#define IS_ISP2401 __IS_SOCS(INTEL_FAM6_ATOM_AIRMONT, \
+ INTEL_FAM6_ATOM_AIRMONT_MID)
#endif /* ATOMISP_PLATFORM_H_ */
diff --git a/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h b/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h
index 1b5111ad9415..abc8fa809bce 100644
--- a/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h
+++ b/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2013 Intel Corporation. All Rights Reserved.
*
diff --git a/drivers/staging/media/atomisp/include/media/lm3554.h b/drivers/staging/media/atomisp/include/media/lm3554.h
index 03a916ade531..812ce74f0635 100644
--- a/drivers/staging/media/atomisp/include/media/lm3554.h
+++ b/drivers/staging/media/atomisp/include/media/lm3554.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/media/lm3554.h
*
diff --git a/drivers/staging/media/atomisp/include/mmu/isp_mmu.h b/drivers/staging/media/atomisp/include/mmu/isp_mmu.h
index d9662c515236..268560954792 100644
--- a/drivers/staging/media/atomisp/include/mmu/isp_mmu.h
+++ b/drivers/staging/media/atomisp/include/mmu/isp_mmu.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/include/mmu/sh_mmu_mrfld.h b/drivers/staging/media/atomisp/include/mmu/sh_mmu_mrfld.h
index 662e98f41da2..84fe7a368c14 100644
--- a/drivers/staging/media/atomisp/include/mmu/sh_mmu_mrfld.h
+++ b/drivers/staging/media/atomisp/include/mmu/sh_mmu_mrfld.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Merrifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp-regs.h b/drivers/staging/media/atomisp/pci/atomisp-regs.h
index cc489a331a7c..de34ee28e390 100644
--- a/drivers/staging/media/atomisp/pci/atomisp-regs.h
+++ b/drivers/staging/media/atomisp/pci/atomisp-regs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_acc.c b/drivers/staging/media/atomisp/pci/atomisp_acc.c
index 8d575eb0a73f..76861396ba86 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_acc.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_acc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Clovertrail PNW Camera Imaging ISP subsystem.
*
@@ -23,24 +24,24 @@
#include <linux/init.h>
#include <media/v4l2-event.h>
+#include "hmm.h"
+
#include "atomisp_acc.h"
#include "atomisp_internal.h"
#include "atomisp_compat.h"
#include "atomisp_cmd.h"
-#include "hrt/hive_isp_css_mm_hrt.h"
-#include "memory_access/memory_access.h"
#include "ia_css.h"
static const struct {
unsigned int flag;
- enum atomisp_css_pipe_id pipe_id;
+ enum ia_css_pipe_id pipe_id;
} acc_flag_to_pipe[] = {
- { ATOMISP_ACC_FW_LOAD_FL_PREVIEW, CSS_PIPE_ID_PREVIEW },
- { ATOMISP_ACC_FW_LOAD_FL_COPY, CSS_PIPE_ID_COPY },
- { ATOMISP_ACC_FW_LOAD_FL_VIDEO, CSS_PIPE_ID_VIDEO },
- { ATOMISP_ACC_FW_LOAD_FL_CAPTURE, CSS_PIPE_ID_CAPTURE },
- { ATOMISP_ACC_FW_LOAD_FL_ACC, CSS_PIPE_ID_ACC }
+ { ATOMISP_ACC_FW_LOAD_FL_PREVIEW, IA_CSS_PIPE_ID_PREVIEW },
+ { ATOMISP_ACC_FW_LOAD_FL_COPY, IA_CSS_PIPE_ID_COPY },
+ { ATOMISP_ACC_FW_LOAD_FL_VIDEO, IA_CSS_PIPE_ID_VIDEO },
+ { ATOMISP_ACC_FW_LOAD_FL_CAPTURE, IA_CSS_PIPE_ID_CAPTURE },
+ { ATOMISP_ACC_FW_LOAD_FL_ACC, IA_CSS_PIPE_ID_ACC }
};
/*
@@ -353,16 +354,23 @@ int atomisp_acc_map(struct atomisp_sub_device *asd, struct atomisp_acc_map *map)
}
pgnr = DIV_ROUND_UP(map->length, PAGE_SIZE);
- cssptr = hrt_isp_css_mm_alloc_user_ptr(map->length,
- map->user_ptr,
- pgnr, HRT_USR_PTR,
- (map->flags & ATOMISP_MAP_FLAG_CACHED));
+ if (pgnr < ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) {
+ dev_err(atomisp_dev,
+ "user space memory size is less than the expected size..\n");
+ return -ENOMEM;
+ } else if (pgnr > ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) {
+ dev_err(atomisp_dev,
+ "user space memory size is large than the expected size..\n");
+ return -ENOMEM;
+ }
+
+ cssptr = hmm_alloc(map->length, HMM_BO_USER, 0, map->user_ptr,
+ map->flags & ATOMISP_MAP_FLAG_CACHED);
+
} else {
/* Allocate private buffer. */
- if (map->flags & ATOMISP_MAP_FLAG_CACHED)
- cssptr = hrt_isp_css_mm_calloc_cached(map->length);
- else
- cssptr = hrt_isp_css_mm_calloc(map->length);
+ cssptr = hmm_alloc(map->length, HMM_BO_PRIVATE, 0, NULL,
+ map->flags & ATOMISP_MAP_FLAG_CACHED);
}
if (!cssptr)
@@ -552,7 +560,7 @@ int atomisp_acc_set_state(struct atomisp_sub_device *asd,
struct atomisp_acc_fw *acc_fw;
bool enable = (arg->flags & ATOMISP_STATE_FLAG_ENABLE) != 0;
struct ia_css_pipe *pipe;
- enum ia_css_err r;
+ int r;
int i;
if (!asd->acc.extension_mode)
@@ -574,7 +582,7 @@ int atomisp_acc_set_state(struct atomisp_sub_device *asd,
pipes[acc_flag_to_pipe[i].pipe_id];
r = ia_css_pipe_set_qos_ext_state(pipe, acc_fw->handle,
enable);
- if (r != IA_CSS_SUCCESS)
+ if (r)
return -EBADRQC;
}
}
diff --git a/drivers/staging/media/atomisp/pci/atomisp_acc.h b/drivers/staging/media/atomisp/pci/atomisp_acc.h
index ba14181962f8..48d94232229b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_acc.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_acc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Clovertrail PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 5be690f876c1..7b936e5a5f03 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -16,6 +17,7 @@
*
*
*/
+#include <linux/errno.h>
#include <linux/firmware.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
@@ -44,7 +46,7 @@
#include "atomisp_subdev.h"
#include "atomisp_dfs_tables.h"
-#include "hrt/hive_isp_css_mm_hrt.h"
+#include <hmm/hmm.h>
#include "sh_css_hrt.h"
#include "sh_css_defs.h"
@@ -57,7 +59,7 @@
#include "ia_css_types.h"
#include "ia_css_stream.h"
-#include "error_support.h"
+#include "ia_css_debug.h"
#include "bits.h"
/* We should never need to run the flash for more than 2 frames.
@@ -241,8 +243,12 @@ int atomisp_freq_scaling(struct atomisp_device *isp,
}
fps = atomisp_get_sensor_fps(asd);
- if (fps == 0)
- return -EINVAL;
+ if (fps == 0) {
+ dev_info(isp->dev,
+ "Sensor didn't report FPS. Using DFS max mode.\n");
+ new_freq = dfs->highest_freq;
+ goto done;
+ }
curr_rules.width = asd->fmt[asd->capture_pad].fmt.width;
curr_rules.height = asd->fmt[asd->capture_pad].fmt.height;
@@ -445,29 +451,29 @@ static void print_csi_rx_errors(enum mipi_port_id port,
atomisp_css_rx_get_irq_info(port, &infos);
dev_err(isp->dev, "CSI Receiver port %d errors:\n", port);
- if (infos & CSS_RX_IRQ_INFO_BUFFER_OVERRUN)
+ if (infos & IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN)
dev_err(isp->dev, " buffer overrun");
- if (infos & CSS_RX_IRQ_INFO_ERR_SOT)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_SOT)
dev_err(isp->dev, " start-of-transmission error");
- if (infos & CSS_RX_IRQ_INFO_ERR_SOT_SYNC)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC)
dev_err(isp->dev, " start-of-transmission sync error");
- if (infos & CSS_RX_IRQ_INFO_ERR_CONTROL)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_CONTROL)
dev_err(isp->dev, " control error");
- if (infos & CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE)
dev_err(isp->dev, " 2 or more ECC errors");
- if (infos & CSS_RX_IRQ_INFO_ERR_CRC)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_CRC)
dev_err(isp->dev, " CRC mismatch");
- if (infos & CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID)
dev_err(isp->dev, " unknown error");
- if (infos & CSS_RX_IRQ_INFO_ERR_FRAME_SYNC)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC)
dev_err(isp->dev, " frame sync error");
- if (infos & CSS_RX_IRQ_INFO_ERR_FRAME_DATA)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA)
dev_err(isp->dev, " frame data error");
- if (infos & CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT)
dev_err(isp->dev, " data timeout");
- if (infos & CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC)
dev_err(isp->dev, " unknown escape command entry");
- if (infos & CSS_RX_IRQ_INFO_ERR_LINE_SYNC)
+ if (infos & IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC)
dev_err(isp->dev, " line sync error");
}
@@ -526,8 +532,6 @@ irqreturn_t atomisp_isr(int irq, void *dev)
return IRQ_NONE;
}
- dev_dbg(isp->dev, "irq:0x%x\n", irq_infos);
-
clear_irq_reg(isp);
if (!atomisp_streaming_count(isp) && !atomisp_is_acc_enabled(isp))
@@ -542,7 +546,7 @@ irqreturn_t atomisp_isr(int irq, void *dev)
* Current SOF only support one stream, so the SOF only valid
* either solely one stream is running
*/
- if (irq_infos & CSS_IRQ_INFO_CSS_RECEIVER_SOF) {
+ if (irq_infos & IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF) {
atomic_inc(&asd->sof_count);
atomisp_sof_event(asd);
@@ -559,16 +563,20 @@ irqreturn_t atomisp_isr(int irq, void *dev)
atomic_set(&asd->sequence_temp,
atomic_read(&asd->sof_count));
}
- if (irq_infos & CSS_IRQ_INFO_EVENTS_READY)
+ if (irq_infos & IA_CSS_IRQ_INFO_EVENTS_READY)
atomic_set(&asd->sequence,
atomic_read(&asd->sequence_temp));
}
- if (irq_infos & CSS_IRQ_INFO_CSS_RECEIVER_SOF)
- irq_infos &= ~CSS_IRQ_INFO_CSS_RECEIVER_SOF;
+ if (irq_infos & IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF) {
+ dev_dbg_ratelimited(isp->dev,
+ "irq:0x%x (SOF)\n",
+ irq_infos);
+ irq_infos &= ~IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF;
+ }
- if ((irq_infos & CSS_IRQ_INFO_INPUT_SYSTEM_ERROR) ||
- (irq_infos & CSS_IRQ_INFO_IF_ERROR)) {
+ if ((irq_infos & IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR) ||
+ (irq_infos & IA_CSS_IRQ_INFO_IF_ERROR)) {
/* handle mipi receiver error */
u32 rx_infos;
enum mipi_port_id port;
@@ -583,18 +591,20 @@ irqreturn_t atomisp_isr(int irq, void *dev)
if (irq_infos & IA_CSS_IRQ_INFO_ISYS_EVENTS_READY) {
while (ia_css_dequeue_isys_event(&eof_event.event) ==
- IA_CSS_SUCCESS) {
+ 0) {
/* EOF Event does not have the css_pipe returned */
asd = __get_asd_from_port(isp, eof_event.event.port);
if (!asd) {
- dev_err(isp->dev, "%s:no subdev.event:%d", __func__,
- eof_event.event.type);
+ dev_err(isp->dev, "%s: ISYS event, but no subdev.event:%d",
+ __func__, eof_event.event.type);
continue;
}
atomisp_eof_event(asd, eof_event.event.exp_id);
- dev_dbg(isp->dev, "%s EOF exp_id %d, asd %d\n",
- __func__, eof_event.event.exp_id, asd->index);
+ dev_dbg_ratelimited(isp->dev,
+ "%s ISYS event: EOF exp_id %d, asd %d\n",
+ __func__, eof_event.event.exp_id,
+ asd->index);
}
irq_infos &= ~IA_CSS_IRQ_INFO_ISYS_EVENTS_READY;
@@ -604,11 +614,17 @@ irqreturn_t atomisp_isr(int irq, void *dev)
spin_unlock_irqrestore(&isp->lock, flags);
+ dev_dbg_ratelimited(isp->dev, "irq:0x%x (unhandled)\n", irq_infos);
+
return IRQ_WAKE_THREAD;
out_nowake:
spin_unlock_irqrestore(&isp->lock, flags);
+ if (irq_infos)
+ dev_dbg_ratelimited(isp->dev, "irq:0x%x (ignored, as not streaming anymore)\n",
+ irq_infos);
+
return IRQ_HANDLED;
}
@@ -649,6 +665,7 @@ bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe)
void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr,
unsigned int size)
{
+ u32 __iomem *io_virt_addr;
unsigned int data = 0;
unsigned int size32 = DIV_ROUND_UP(size, sizeof(u32));
@@ -661,20 +678,20 @@ void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr,
return;
}
addr += SP_DMEM_BASE;
+ io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
do {
- data = _hrt_master_port_uload_32(addr);
-
+ data = *io_virt_addr;
dev_dbg(isp->dev, "%s, \t [0x%x]:0x%x\n", __func__, addr, data);
- addr += sizeof(unsigned int);
+ io_virt_addr += sizeof(u32);
size32 -= 1;
} while (size32 > 0);
}
static struct videobuf_buffer *atomisp_css_frame_to_vbuf(
- struct atomisp_video_pipe *pipe, struct atomisp_css_frame *frame)
+ struct atomisp_video_pipe *pipe, struct ia_css_frame *frame)
{
struct videobuf_vmalloc_memory *vm_mem;
- struct atomisp_css_frame *handle;
+ struct ia_css_frame *handle;
int i;
for (i = 0; pipe->capq.bufs[i]; i++) {
@@ -756,12 +773,12 @@ static void atomisp_recover_params_queue(struct atomisp_video_pipe *pipe)
static struct atomisp_video_pipe *__atomisp_get_pipe(
struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id,
- enum atomisp_css_buffer_type buf_type)
+ enum ia_css_pipe_id css_pipe_id,
+ enum ia_css_buffer_type buf_type)
{
struct atomisp_device *isp = asd->isp;
- if (css_pipe_id == CSS_PIPE_ID_COPY &&
+ if (css_pipe_id == IA_CSS_PIPE_ID_COPY &&
isp->inputs[asd->input_curr].camera_caps->
sensor[asd->sensor_curr].stream_num > 1) {
switch (stream_id) {
@@ -792,7 +809,7 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
* buffering.
*/
return &asd->video_out_video_capture;
- } else if (css_pipe_id == CSS_PIPE_ID_YUVPP) {
+ } else if (css_pipe_id == IA_CSS_PIPE_ID_YUVPP) {
/*
* to SOC camera, yuvpp pipe is run for capture/video/SDV/ZSL.
*/
@@ -800,11 +817,11 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
/* SDV case */
switch (buf_type) {
- case CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
return &asd->video_out_video_capture;
- case CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
return &asd->video_out_preview;
- case CSS_BUFFER_TYPE_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
return &asd->video_out_capture;
default:
return &asd->video_out_vf;
@@ -812,15 +829,15 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
/* ZSL case */
switch (buf_type) {
- case CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
return &asd->video_out_preview;
- case CSS_BUFFER_TYPE_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
return &asd->video_out_capture;
default:
return &asd->video_out_vf;
}
}
- } else if (buf_type == CSS_BUFFER_TYPE_OUTPUT_FRAME) {
+ } else if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
switch (asd->run_mode->val) {
case ATOMISP_RUN_MODE_VIDEO:
return &asd->video_out_video_capture;
@@ -829,7 +846,7 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
default:
return &asd->video_out_capture;
}
- } else if (buf_type == CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
+ } else if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
return &asd->video_out_preview;
else
@@ -837,20 +854,20 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
}
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
/* For online video or SDV video pipe. */
- if (css_pipe_id == CSS_PIPE_ID_VIDEO ||
- css_pipe_id == CSS_PIPE_ID_COPY) {
- if (buf_type == CSS_BUFFER_TYPE_OUTPUT_FRAME)
+ if (css_pipe_id == IA_CSS_PIPE_ID_VIDEO ||
+ css_pipe_id == IA_CSS_PIPE_ID_COPY) {
+ if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
return &asd->video_out_video_capture;
return &asd->video_out_preview;
}
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
/* For online preview or ZSL preview pipe. */
- if (css_pipe_id == CSS_PIPE_ID_PREVIEW ||
- css_pipe_id == CSS_PIPE_ID_COPY)
+ if (css_pipe_id == IA_CSS_PIPE_ID_PREVIEW ||
+ css_pipe_id == IA_CSS_PIPE_ID_COPY)
return &asd->video_out_preview;
}
/* For capture pipe. */
- if (buf_type == CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
+ if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
return &asd->video_out_vf;
return &asd->video_out_capture;
}
@@ -868,8 +885,8 @@ atomisp_get_metadata_type(struct atomisp_sub_device *asd,
}
void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
- enum atomisp_css_buffer_type buf_type,
- enum atomisp_css_pipe_id css_pipe_id,
+ enum ia_css_buffer_type buf_type,
+ enum ia_css_pipe_id css_pipe_id,
bool q_buffers, enum atomisp_input_stream_id stream_id)
{
struct videobuf_buffer *vb = NULL;
@@ -878,7 +895,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
bool requeue = false;
int err;
unsigned long irqflags;
- struct atomisp_css_frame *frame = NULL;
+ struct ia_css_frame *frame = NULL;
struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf_tmp;
struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf_tmp;
struct atomisp_metadata_buf *md_buf = NULL, *_md_buf_tmp;
@@ -888,14 +905,14 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
bool reset_wdt_timer = false;
if (
- buf_type != CSS_BUFFER_TYPE_METADATA &&
- buf_type != CSS_BUFFER_TYPE_3A_STATISTICS &&
- buf_type != CSS_BUFFER_TYPE_DIS_STATISTICS &&
- buf_type != CSS_BUFFER_TYPE_OUTPUT_FRAME &&
- buf_type != CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME &&
- buf_type != CSS_BUFFER_TYPE_RAW_OUTPUT_FRAME &&
- buf_type != CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME &&
- buf_type != CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
+ buf_type != IA_CSS_BUFFER_TYPE_METADATA &&
+ buf_type != IA_CSS_BUFFER_TYPE_3A_STATISTICS &&
+ buf_type != IA_CSS_BUFFER_TYPE_DIS_STATISTICS &&
+ buf_type != IA_CSS_BUFFER_TYPE_OUTPUT_FRAME &&
+ buf_type != IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME &&
+ buf_type != IA_CSS_BUFFER_TYPE_RAW_OUTPUT_FRAME &&
+ buf_type != IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME &&
+ buf_type != IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
dev_err(isp->dev, "%s, unsupported buffer type: %d\n",
__func__, buf_type);
return;
@@ -919,7 +936,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
}
switch (buf_type) {
- case CSS_BUFFER_TYPE_3A_STATISTICS:
+ case IA_CSS_BUFFER_TYPE_3A_STATISTICS:
list_for_each_entry_safe(s3a_buf, _s3a_buf_tmp,
&asd->s3a_stats_in_css, list) {
if (s3a_buf->s3a_data ==
@@ -936,7 +953,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
dev_dbg(isp->dev, "%s: s3a stat with exp_id %d is ready\n",
__func__, s3a_buf->s3a_data->exp_id);
break;
- case CSS_BUFFER_TYPE_METADATA:
+ case IA_CSS_BUFFER_TYPE_METADATA:
if (error)
break;
@@ -956,7 +973,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
dev_dbg(isp->dev, "%s: metadata with exp_id %d is ready\n",
__func__, md_buf->metadata->exp_id);
break;
- case CSS_BUFFER_TYPE_DIS_STATISTICS:
+ case IA_CSS_BUFFER_TYPE_DIS_STATISTICS:
list_for_each_entry_safe(dis_buf, _dis_buf_tmp,
&asd->dis_stats_in_css, list) {
if (dis_buf->dis_data ==
@@ -975,9 +992,9 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
dev_dbg(isp->dev, "%s: dis stat with exp_id %d is ready\n",
__func__, dis_buf->dis_data->exp_id);
break;
- case CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:
- case CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
- if (atomisp_hw_is_isp2401)
+ case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
+ if (IS_ISP2401)
reset_wdt_timer = true;
pipe->buffers_in_css--;
@@ -993,7 +1010,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
* YUVPP doesn't set postview exp_id correctlly in SDV mode.
* This is a WORKAROUND to set exp_id. see HSDES-1503911606.
*/
- if (IS_BYT && buf_type == CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME &&
+ if (IS_BYT && buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME &&
asd->continuous_mode->val && ATOMISP_USE_YUVPP(asd))
frame->exp_id = (asd->postview_exp_id++) %
(ATOMISP_MAX_EXP_ID + 1);
@@ -1002,11 +1019,11 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
__func__, frame->exp_id);
if (asd->params.flash_state == ATOMISP_FLASH_ONGOING) {
if (frame->flash_state
- == CSS_FRAME_FLASH_STATE_PARTIAL)
+ == IA_CSS_FRAME_FLASH_STATE_PARTIAL)
dev_dbg(isp->dev, "%s thumb partially flashed\n",
__func__);
else if (frame->flash_state
- == CSS_FRAME_FLASH_STATE_FULL)
+ == IA_CSS_FRAME_FLASH_STATE_FULL)
dev_dbg(isp->dev, "%s thumb completely flashed\n",
__func__);
else
@@ -1026,18 +1043,18 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
asd->pending_capture_request--;
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
asd->re_trigger_capture = false;
dev_dbg(isp->dev, "Trigger capture again for new buffer. err=%d\n",
err);
- } else if (atomisp_hw_is_isp2401) {
+ } else if (IS_ISP2401) {
asd->re_trigger_capture = true;
}
break;
- case CSS_BUFFER_TYPE_OUTPUT_FRAME:
- case CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
- if (atomisp_hw_is_isp2401)
+ case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
+ case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
+ if (IS_ISP2401)
reset_wdt_timer = true;
pipe->buffers_in_css--;
@@ -1054,7 +1071,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
* YUVPP doesn't set preview exp_id correctlly in ZSL mode.
* This is a WORKAROUND to set exp_id. see HSDES-1503911606.
*/
- if (IS_BYT && buf_type == CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME &&
+ if (IS_BYT && buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME &&
asd->continuous_mode->val && ATOMISP_USE_YUVPP(asd))
frame->exp_id = (asd->preview_exp_id++) %
(ATOMISP_MAX_EXP_ID + 1);
@@ -1082,13 +1099,13 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
ctrl.id = V4L2_CID_FLASH_MODE;
if (asd->params.flash_state == ATOMISP_FLASH_ONGOING) {
if (frame->flash_state
- == CSS_FRAME_FLASH_STATE_PARTIAL) {
+ == IA_CSS_FRAME_FLASH_STATE_PARTIAL) {
asd->frame_status[vb->i] =
ATOMISP_FRAME_STATUS_FLASH_PARTIAL;
dev_dbg(isp->dev, "%s partially flashed\n",
__func__);
} else if (frame->flash_state
- == CSS_FRAME_FLASH_STATE_FULL) {
+ == IA_CSS_FRAME_FLASH_STATE_FULL) {
asd->frame_status[vb->i] =
ATOMISP_FRAME_STATUS_FLASH_EXPOSED;
asd->params.num_flash_frames--;
@@ -1128,11 +1145,11 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
asd->params.last_frame_status = asd->frame_status[vb->i];
if (asd->continuous_mode->val) {
- if (css_pipe_id == CSS_PIPE_ID_PREVIEW ||
- css_pipe_id == CSS_PIPE_ID_VIDEO) {
+ if (css_pipe_id == IA_CSS_PIPE_ID_PREVIEW ||
+ css_pipe_id == IA_CSS_PIPE_ID_VIDEO) {
asd->latest_preview_exp_id = frame->exp_id;
} else if (css_pipe_id ==
- CSS_PIPE_ID_CAPTURE) {
+ IA_CSS_PIPE_ID_CAPTURE) {
if (asd->run_mode->val ==
ATOMISP_RUN_MODE_VIDEO)
dev_dbg(isp->dev, "SDV capture raw buffer id: %u\n",
@@ -1148,8 +1165,8 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
* in preview/video pipe, each buffer will
* be locked automatically, so record it here.
*/
- if (((css_pipe_id == CSS_PIPE_ID_PREVIEW) ||
- (css_pipe_id == CSS_PIPE_ID_VIDEO)) &&
+ if (((css_pipe_id == IA_CSS_PIPE_ID_PREVIEW) ||
+ (css_pipe_id == IA_CSS_PIPE_ID_VIDEO)) &&
asd->enable_raw_buffer_lock->val &&
asd->continuous_mode->val) {
atomisp_set_raw_buffer_bitmap(asd, frame->exp_id);
@@ -1160,8 +1177,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
atomisp_apply_css_parameters(asd,
&asd->params.css_param);
if (asd->params.css_param.update_flag.dz_config)
- atomisp_css_set_dz_config(asd,
- &asd->params.css_param.dz_config);
+ asd->params.config.dz_config = &asd->params.css_param.dz_config;
/* New global dvs 6axis config should be blocked
* here if there's a buffer with per-frame parameters
* pending in CSS frame buffer queue.
@@ -1208,7 +1224,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
*/
wake_up(&vb->done);
}
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
atomic_set(&pipe->wdt_count, 0);
/*
@@ -1228,7 +1244,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
if (!error && q_buffers)
atomisp_qbuffers_to_css(asd);
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
/* If there are no buffers queued then
* delete wdt timer. */
if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
@@ -1252,9 +1268,15 @@ void atomisp_delayed_init_work(struct work_struct *work)
*/
if (!ATOMISP_USE_YUVPP(asd)) {
struct v4l2_event event = {0};
+ struct ia_css_stream *stream;
+
+ stream = asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream;
+
+
+ if (ia_css_alloc_continuous_frame_remain(stream))
+ return;
- atomisp_css_allocate_continuous_frames(false, asd);
- atomisp_css_update_continuous_frames(asd);
+ ia_css_update_continuous_frames(stream);
event.type = V4L2_EVENT_ATOMISP_RAW_BUFFERS_ALLOC_DONE;
v4l2_event_queue(asd->subdev.devnode, &event);
@@ -1267,14 +1289,14 @@ void atomisp_delayed_init_work(struct work_struct *work)
static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout)
{
- enum atomisp_css_pipe_id css_pipe_id;
+ enum ia_css_pipe_id css_pipe_id;
bool stream_restart[MAX_STREAM_NUM] = {0};
bool depth_mode = false;
int i, ret, depth_cnt = 0;
if (!isp->sw_contex.file_input)
atomisp_css_irq_enable(isp,
- CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
+ IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
BUG_ON(isp->num_of_streams > MAX_STREAM_NUM);
@@ -1292,7 +1314,7 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout)
* By calling acc_done() for all loaded fw_handles,
* HAL will be unblocked.
*/
- acc_pipe = asd->stream_env[i].pipes[CSS_PIPE_ID_ACC];
+ acc_pipe = asd->stream_env[i].pipes[IA_CSS_PIPE_ID_ACC];
if (acc_pipe) {
acc_pipeline = ia_css_pipe_get_pipeline(acc_pipe);
if (acc_pipeline) {
@@ -1373,7 +1395,7 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout)
if (isp->inputs[asd->input_curr].type != FILE_INPUT)
atomisp_css_input_set_mode(asd,
- CSS_INPUT_MODE_SENSOR);
+ IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
css_pipe_id = atomisp_get_css_pipe_id(asd);
if (atomisp_css_start(asd, css_pipe_id, true))
@@ -1386,14 +1408,14 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout)
}
if (!isp->sw_contex.file_input) {
- atomisp_css_irq_enable(isp, CSS_IRQ_INFO_CSS_RECEIVER_SOF,
+ atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
atomisp_css_valid_sof(isp));
if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, true) < 0)
- dev_dbg(isp->dev, "dfs failed!\n");
+ dev_dbg(isp->dev, "DFS auto failed while recovering!\n");
} else {
if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, true) < 0)
- dev_dbg(isp->dev, "dfs failed!\n");
+ dev_dbg(isp->dev, "DFS max failed while recovering!\n");
}
for (i = 0; i < isp->num_of_streams; i++) {
@@ -1458,7 +1480,7 @@ void atomisp_wdt_work(struct work_struct *work)
return;
}
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
dev_err(isp->dev, "timeout %d of %d\n",
atomic_read(&isp->wdt_count) + 1,
ATOMISP_ISP_MAX_TIMEOUT_COUNT);
@@ -1494,11 +1516,8 @@ void atomisp_wdt_work(struct work_struct *work)
}
if (css_recover) {
- unsigned int old_dbglevel = dbg_level;
-
- atomisp_css_debug_dump_sp_sw_debug_info();
- atomisp_css_debug_dump_debug_info(__func__);
- dbg_level = old_dbglevel;
+ ia_css_debug_dump_sp_sw_debug_info();
+ ia_css_debug_dump_debug_info(__func__);
for (i = 0; i < isp->num_of_streams; i++) {
struct atomisp_sub_device *asd = &isp->asd[i];
@@ -1530,15 +1549,15 @@ void atomisp_wdt_work(struct work_struct *work)
dev_err(isp->dev,
"%s, s3a buffers in css preview pipe:%d\n",
__func__,
- asd->s3a_bufs_in_css[CSS_PIPE_ID_PREVIEW]);
+ asd->s3a_bufs_in_css[IA_CSS_PIPE_ID_PREVIEW]);
dev_err(isp->dev,
"%s, s3a buffers in css capture pipe:%d\n",
__func__,
- asd->s3a_bufs_in_css[CSS_PIPE_ID_CAPTURE]);
+ asd->s3a_bufs_in_css[IA_CSS_PIPE_ID_CAPTURE]);
dev_err(isp->dev,
"%s, s3a buffers in css video pipe:%d\n",
__func__,
- asd->s3a_bufs_in_css[CSS_PIPE_ID_VIDEO]);
+ asd->s3a_bufs_in_css[IA_CSS_PIPE_ID_VIDEO]);
dev_err(isp->dev,
"%s, dis buffers in css: %d\n",
__func__, asd->dis_bufs_in_css);
@@ -1547,19 +1566,19 @@ void atomisp_wdt_work(struct work_struct *work)
__func__,
asd->metadata_bufs_in_css
[ATOMISP_INPUT_STREAM_GENERAL]
- [CSS_PIPE_ID_PREVIEW]);
+ [IA_CSS_PIPE_ID_PREVIEW]);
dev_err(isp->dev,
"%s, metadata buffers in css capture pipe:%d\n",
__func__,
asd->metadata_bufs_in_css
[ATOMISP_INPUT_STREAM_GENERAL]
- [CSS_PIPE_ID_CAPTURE]);
+ [IA_CSS_PIPE_ID_CAPTURE]);
dev_err(isp->dev,
"%s, metadata buffers in css video pipe:%d\n",
__func__,
asd->metadata_bufs_in_css
[ATOMISP_INPUT_STREAM_GENERAL]
- [CSS_PIPE_ID_VIDEO]);
+ [IA_CSS_PIPE_ID_VIDEO]);
if (asd->enable_raw_buffer_lock->val) {
unsigned int j;
@@ -1584,11 +1603,11 @@ void atomisp_wdt_work(struct work_struct *work)
atomisp_flush_bufs_and_wakeup(asd);
complete(&asd->init_done);
}
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
atomisp_wdt_stop(asd, false);
}
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
atomic_set(&isp->wdt_count, 0);
} else {
isp->isp_fatal_error = true;
@@ -1600,7 +1619,7 @@ void atomisp_wdt_work(struct work_struct *work)
}
__atomisp_css_recover(isp, true);
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
for (i = 0; i < isp->num_of_streams; i++) {
struct atomisp_sub_device *asd = &isp->asd[i];
@@ -1657,7 +1676,7 @@ void atomisp_wdt(struct timer_list *t)
struct atomisp_sub_device *asd;
struct atomisp_device *isp;
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
asd = from_timer(asd, t, wdt);
isp = asd->isp;
} else {
@@ -1716,7 +1735,7 @@ void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe,
void atomisp_wdt_refresh(struct atomisp_sub_device *asd, unsigned int delay)
{
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
unsigned long next;
if (delay != ATOMISP_WDT_KEEP_CURRENT_DELAY)
@@ -1779,7 +1798,7 @@ void atomisp_wdt_stop(struct atomisp_sub_device *asd, bool sync)
{
dev_dbg(asd->isp->dev, "WDT stop:\n");
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (sync) {
del_timer_sync(&asd->wdt);
cancel_work_sync(&asd->isp->wdt_work);
@@ -1816,7 +1835,8 @@ void atomisp_setup_flash(struct atomisp_sub_device *asd)
return;
}
- atomisp_css_request_flash(asd);
+ ia_css_stream_request_flash(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream);
+
asd->params.flash_state = ATOMISP_FLASH_ONGOING;
} else {
asd->params.flash_state = ATOMISP_FLASH_IDLE;
@@ -1901,7 +1921,7 @@ out:
*/
int atomisp_get_frame_pgnr(struct atomisp_device *isp,
- const struct atomisp_css_frame *frame, u32 *p_pgnr)
+ const struct ia_css_frame *frame, u32 *p_pgnr)
{
if (!frame) {
dev_err(isp->dev, "%s: NULL frame pointer ERROR.\n", __func__);
@@ -1915,39 +1935,39 @@ int atomisp_get_frame_pgnr(struct atomisp_device *isp,
/*
* Get internal fmt according to V4L2 fmt
*/
-static enum atomisp_css_frame_format
+static enum ia_css_frame_format
v4l2_fmt_to_sh_fmt(u32 fmt) {
switch (fmt)
{
case V4L2_PIX_FMT_YUV420:
- return CSS_FRAME_FORMAT_YUV420;
+ return IA_CSS_FRAME_FORMAT_YUV420;
case V4L2_PIX_FMT_YVU420:
- return CSS_FRAME_FORMAT_YV12;
+ return IA_CSS_FRAME_FORMAT_YV12;
case V4L2_PIX_FMT_YUV422P:
- return CSS_FRAME_FORMAT_YUV422;
+ return IA_CSS_FRAME_FORMAT_YUV422;
case V4L2_PIX_FMT_YUV444:
- return CSS_FRAME_FORMAT_YUV444;
+ return IA_CSS_FRAME_FORMAT_YUV444;
case V4L2_PIX_FMT_NV12:
- return CSS_FRAME_FORMAT_NV12;
+ return IA_CSS_FRAME_FORMAT_NV12;
case V4L2_PIX_FMT_NV21:
- return CSS_FRAME_FORMAT_NV21;
+ return IA_CSS_FRAME_FORMAT_NV21;
case V4L2_PIX_FMT_NV16:
- return CSS_FRAME_FORMAT_NV16;
+ return IA_CSS_FRAME_FORMAT_NV16;
case V4L2_PIX_FMT_NV61:
- return CSS_FRAME_FORMAT_NV61;
+ return IA_CSS_FRAME_FORMAT_NV61;
case V4L2_PIX_FMT_UYVY:
- return CSS_FRAME_FORMAT_UYVY;
+ return IA_CSS_FRAME_FORMAT_UYVY;
case V4L2_PIX_FMT_YUYV:
- return CSS_FRAME_FORMAT_YUYV;
+ return IA_CSS_FRAME_FORMAT_YUYV;
case V4L2_PIX_FMT_RGB24:
- return CSS_FRAME_FORMAT_PLANAR_RGB888;
+ return IA_CSS_FRAME_FORMAT_PLANAR_RGB888;
case V4L2_PIX_FMT_RGB32:
- return CSS_FRAME_FORMAT_RGBA888;
+ return IA_CSS_FRAME_FORMAT_RGBA888;
case V4L2_PIX_FMT_RGB565:
- return CSS_FRAME_FORMAT_RGB565;
+ return IA_CSS_FRAME_FORMAT_RGB565;
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_CUSTOM_M10MO_RAW:
- return CSS_FRAME_FORMAT_BINARY_8;
+ return IA_CSS_FRAME_FORMAT_BINARY_8;
case V4L2_PIX_FMT_SBGGR16:
case V4L2_PIX_FMT_SBGGR10:
case V4L2_PIX_FMT_SGBRG10:
@@ -1961,7 +1981,7 @@ v4l2_fmt_to_sh_fmt(u32 fmt) {
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
- return CSS_FRAME_FORMAT_RAW;
+ return IA_CSS_FRAME_FORMAT_RAW;
default:
return -EINVAL;
}
@@ -1972,28 +1992,28 @@ v4l2_fmt_to_sh_fmt(u32 fmt) {
*/
static int raw_output_format_match_input(u32 input, u32 output)
{
- if ((input == CSS_FORMAT_RAW_12) &&
+ if ((input == ATOMISP_INPUT_FORMAT_RAW_12) &&
((output == V4L2_PIX_FMT_SRGGB12) ||
(output == V4L2_PIX_FMT_SGRBG12) ||
(output == V4L2_PIX_FMT_SBGGR12) ||
(output == V4L2_PIX_FMT_SGBRG12)))
return 0;
- if ((input == CSS_FORMAT_RAW_10) &&
+ if ((input == ATOMISP_INPUT_FORMAT_RAW_10) &&
((output == V4L2_PIX_FMT_SRGGB10) ||
(output == V4L2_PIX_FMT_SGRBG10) ||
(output == V4L2_PIX_FMT_SBGGR10) ||
(output == V4L2_PIX_FMT_SGBRG10)))
return 0;
- if ((input == CSS_FORMAT_RAW_8) &&
+ if ((input == ATOMISP_INPUT_FORMAT_RAW_8) &&
((output == V4L2_PIX_FMT_SRGGB8) ||
(output == V4L2_PIX_FMT_SGRBG8) ||
(output == V4L2_PIX_FMT_SBGGR8) ||
(output == V4L2_PIX_FMT_SGBRG8)))
return 0;
- if ((input == CSS_FORMAT_RAW_16) && (output == V4L2_PIX_FMT_SBGGR16))
+ if ((input == ATOMISP_INPUT_FORMAT_RAW_16) && (output == V4L2_PIX_FMT_SBGGR16))
return 0;
return -EINVAL;
@@ -2055,13 +2075,13 @@ bool atomisp_is_mbuscode_raw(uint32_t code)
static void atomisp_update_capture_mode(struct atomisp_sub_device *asd)
{
if (asd->params.gdc_cac_en)
- atomisp_css_capture_set_mode(asd, CSS_CAPTURE_MODE_ADVANCED);
+ atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_ADVANCED);
else if (asd->params.low_light)
- atomisp_css_capture_set_mode(asd, CSS_CAPTURE_MODE_LOW_LIGHT);
- else if (asd->video_out_capture.sh_fmt == CSS_FRAME_FORMAT_RAW)
- atomisp_css_capture_set_mode(asd, CSS_CAPTURE_MODE_RAW);
+ atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_LOW_LIGHT);
+ else if (asd->video_out_capture.sh_fmt == IA_CSS_FRAME_FORMAT_RAW)
+ atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_RAW);
else
- atomisp_css_capture_set_mode(asd, CSS_CAPTURE_MODE_PRIMARY);
+ atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_PRIMARY);
}
/* ISP2401 */
@@ -2100,10 +2120,9 @@ int atomisp_gdc_cac(struct atomisp_sub_device *asd, int flag,
asd->params.gdc_cac_en = !!*value;
if (asd->params.gdc_cac_en) {
- atomisp_css_set_morph_table(asd,
- asd->params.css_param.morph_table);
+ asd->params.config.morph_table = asd->params.css_param.morph_table;
} else {
- atomisp_css_set_morph_table(asd, NULL);
+ asd->params.config.morph_table = NULL;
}
asd->params.css_update_params_needed = true;
atomisp_update_capture_mode(asd);
@@ -2156,8 +2175,8 @@ int atomisp_nr(struct atomisp_sub_device *asd, int flag,
} else {
/* Set nr config to isp parameters */
memcpy(&asd->params.css_param.nr_config, arg,
- sizeof(struct atomisp_css_nr_config));
- atomisp_css_set_nr_config(asd, &asd->params.css_param.nr_config);
+ sizeof(struct ia_css_nr_config));
+ asd->params.config.nr_config = &asd->params.css_param.nr_config;
asd->params.css_update_params_needed = true;
}
return 0;
@@ -2177,8 +2196,8 @@ int atomisp_tnr(struct atomisp_sub_device *asd, int flag,
} else {
/* Set tnr config to isp parameters */
memcpy(&asd->params.css_param.tnr_config, config,
- sizeof(struct atomisp_css_tnr_config));
- atomisp_css_set_tnr_config(asd, &asd->params.css_param.tnr_config);
+ sizeof(struct ia_css_tnr_config));
+ asd->params.config.tnr_config = &asd->params.css_param.tnr_config;
asd->params.css_update_params_needed = true;
}
@@ -2198,8 +2217,8 @@ int atomisp_black_level(struct atomisp_sub_device *asd, int flag,
} else {
/* Set ob config to isp parameters */
memcpy(&asd->params.css_param.ob_config, config,
- sizeof(struct atomisp_css_ob_config));
- atomisp_css_set_ob_config(asd, &asd->params.css_param.ob_config);
+ sizeof(struct ia_css_ob_config));
+ asd->params.config.ob_config = &asd->params.css_param.ob_config;
asd->params.css_update_params_needed = true;
}
@@ -2220,7 +2239,7 @@ int atomisp_ee(struct atomisp_sub_device *asd, int flag,
/* Set ee config to isp parameters */
memcpy(&asd->params.css_param.ee_config, config,
sizeof(asd->params.css_param.ee_config));
- atomisp_css_set_ee_config(asd, &asd->params.css_param.ee_config);
+ asd->params.config.ee_config = &asd->params.css_param.ee_config;
asd->params.css_update_params_needed = true;
}
@@ -2241,7 +2260,7 @@ int atomisp_gamma(struct atomisp_sub_device *asd, int flag,
/* Set gamma table to isp parameters */
memcpy(&asd->params.css_param.gamma_table, config,
sizeof(asd->params.css_param.gamma_table));
- atomisp_css_set_gamma_table(asd, &asd->params.css_param.gamma_table);
+ asd->params.config.gamma_table = &asd->params.css_param.gamma_table;
}
return 0;
@@ -2281,7 +2300,7 @@ int atomisp_gamma_correction(struct atomisp_sub_device *asd, int flag,
/* Set gamma correction params to isp parameters */
memcpy(&asd->params.css_param.gc_config, config,
sizeof(asd->params.css_param.gc_config));
- atomisp_css_set_gc_config(asd, &asd->params.css_param.gc_config);
+ asd->params.config.gc_config = &asd->params.css_param.gc_config;
asd->params.css_update_params_needed = true;
}
@@ -2302,7 +2321,7 @@ int atomisp_formats(struct atomisp_sub_device *asd, int flag,
/* Set narrow gamma flag to isp parameters */
memcpy(&asd->params.css_param.formats_config, config,
sizeof(asd->params.css_param.formats_config));
- atomisp_css_set_formats_config(asd, &asd->params.css_param.formats_config);
+ asd->params.config.formats_config = &asd->params.css_param.formats_config;
}
return 0;
@@ -2313,13 +2332,13 @@ void atomisp_free_internal_buffers(struct atomisp_sub_device *asd)
atomisp_free_css_parameters(&asd->params.css_param);
if (asd->raw_output_frame) {
- atomisp_css_frame_free(asd->raw_output_frame);
+ ia_css_frame_free(asd->raw_output_frame);
asd->raw_output_frame = NULL;
}
}
static void atomisp_update_grid_info(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id,
+ enum ia_css_pipe_id pipe_id,
int source_pad)
{
struct atomisp_device *isp = asd->isp;
@@ -2371,7 +2390,7 @@ static void atomisp_curr_user_grid_info(struct atomisp_sub_device *asd,
struct atomisp_grid_info *info)
{
memcpy(info, &asd->params.curr_grid_info.s3a_grid,
- sizeof(struct atomisp_css_3a_grid_info));
+ sizeof(struct ia_css_3a_grid_info));
}
int atomisp_compare_grid(struct atomisp_sub_device *asd,
@@ -2395,14 +2414,14 @@ int atomisp_gdc_cac_table(struct atomisp_sub_device *asd, int flag,
if (flag == 0) {
/* Get gdc table from current setup */
- struct atomisp_css_morph_table tab = {0};
+ struct ia_css_morph_table tab = {0};
atomisp_css_get_morph_table(asd, &tab);
config->width = tab.width;
config->height = tab.height;
- for (i = 0; i < CSS_MORPH_TABLE_NUM_PLANES; i++) {
+ for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
ret = copy_to_user(config->coordinates_x[i],
tab.coordinates_x[i], tab.height *
tab.width * sizeof(*tab.coordinates_x[i]));
@@ -2421,7 +2440,7 @@ int atomisp_gdc_cac_table(struct atomisp_sub_device *asd, int flag,
}
}
} else {
- struct atomisp_css_morph_table *tab =
+ struct ia_css_morph_table *tab =
asd->params.css_param.morph_table;
/* free first if we have one */
@@ -2439,7 +2458,7 @@ int atomisp_gdc_cac_table(struct atomisp_sub_device *asd, int flag,
return -EINVAL;
}
- for (i = 0; i < CSS_MORPH_TABLE_NUM_PLANES; i++) {
+ for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
ret = copy_from_user(tab->coordinates_x[i],
config->coordinates_x[i],
config->height * config->width *
@@ -2465,7 +2484,7 @@ int atomisp_gdc_cac_table(struct atomisp_sub_device *asd, int flag,
}
asd->params.css_param.morph_table = tab;
if (asd->params.gdc_cac_en)
- atomisp_css_set_morph_table(asd, tab);
+ asd->params.config.morph_table = tab;
}
return 0;
@@ -2474,7 +2493,7 @@ int atomisp_gdc_cac_table(struct atomisp_sub_device *asd, int flag,
int atomisp_macc_table(struct atomisp_sub_device *asd, int flag,
struct atomisp_macc_config *config)
{
- struct atomisp_css_macc_table *macc_table;
+ struct ia_css_macc_table *macc_table;
switch (config->color_effect) {
case V4L2_COLORFX_NONE:
@@ -2502,12 +2521,12 @@ int atomisp_macc_table(struct atomisp_sub_device *asd, int flag,
if (flag == 0) {
/* Get macc table from current setup */
memcpy(&config->table, macc_table,
- sizeof(struct atomisp_css_macc_table));
+ sizeof(struct ia_css_macc_table));
} else {
memcpy(macc_table, &config->table,
- sizeof(struct atomisp_css_macc_table));
+ sizeof(struct ia_css_macc_table));
if (config->color_effect == asd->params.color_effect)
- atomisp_css_set_macc_table(asd, macc_table);
+ asd->params.config.macc_table = macc_table;
}
return 0;
@@ -2567,7 +2586,7 @@ int atomisp_get_dvs2_bq_resolutions(struct atomisp_sub_device *asd,
}
pipe_cfg = &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
- .pipe_configs[CSS_PIPE_ID_VIDEO];
+ .pipe_configs[IA_CSS_PIPE_ID_VIDEO];
stream_cfg = &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
.stream_config;
input_config = &stream_cfg->input_config;
@@ -2951,7 +2970,7 @@ int atomisp_get_metadata_by_type(struct atomisp_sub_device *asd, int flag,
*/
int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd,
struct ia_css_dz_config *dz_config,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_stream_env *stream_env =
@@ -3000,7 +3019,7 @@ int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd,
* map real crop region base on above calculating base max crop region.
*/
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
dz_config->zoom_region.origin.x = dz_config->zoom_region.origin.x
* eff_res.width
/ asd->sensor_array_res.width;
@@ -3144,87 +3163,85 @@ void atomisp_apply_css_parameters(
struct atomisp_css_params *css_param)
{
if (css_param->update_flag.wb_config)
- atomisp_css_set_wb_config(asd, &css_param->wb_config);
+ asd->params.config.wb_config = &css_param->wb_config;
if (css_param->update_flag.ob_config)
- atomisp_css_set_ob_config(asd, &css_param->ob_config);
+ asd->params.config.ob_config = &css_param->ob_config;
if (css_param->update_flag.dp_config)
- atomisp_css_set_dp_config(asd, &css_param->dp_config);
+ asd->params.config.dp_config = &css_param->dp_config;
if (css_param->update_flag.nr_config)
- atomisp_css_set_nr_config(asd, &css_param->nr_config);
+ asd->params.config.nr_config = &css_param->nr_config;
if (css_param->update_flag.ee_config)
- atomisp_css_set_ee_config(asd, &css_param->ee_config);
+ asd->params.config.ee_config = &css_param->ee_config;
if (css_param->update_flag.tnr_config)
- atomisp_css_set_tnr_config(asd, &css_param->tnr_config);
+ asd->params.config.tnr_config = &css_param->tnr_config;
if (css_param->update_flag.a3a_config)
- atomisp_css_set_3a_config(asd, &css_param->s3a_config);
+ asd->params.config.s3a_config = &css_param->s3a_config;
if (css_param->update_flag.ctc_config)
- atomisp_css_set_ctc_config(asd, &css_param->ctc_config);
+ asd->params.config.ctc_config = &css_param->ctc_config;
if (css_param->update_flag.cnr_config)
- atomisp_css_set_cnr_config(asd, &css_param->cnr_config);
+ asd->params.config.cnr_config = &css_param->cnr_config;
if (css_param->update_flag.ecd_config)
- atomisp_css_set_ecd_config(asd, &css_param->ecd_config);
+ asd->params.config.ecd_config = &css_param->ecd_config;
if (css_param->update_flag.ynr_config)
- atomisp_css_set_ynr_config(asd, &css_param->ynr_config);
+ asd->params.config.ynr_config = &css_param->ynr_config;
if (css_param->update_flag.fc_config)
- atomisp_css_set_fc_config(asd, &css_param->fc_config);
+ asd->params.config.fc_config = &css_param->fc_config;
if (css_param->update_flag.macc_config)
- atomisp_css_set_macc_config(asd, &css_param->macc_config);
+ asd->params.config.macc_config = &css_param->macc_config;
if (css_param->update_flag.aa_config)
- atomisp_css_set_aa_config(asd, &css_param->aa_config);
+ asd->params.config.aa_config = &css_param->aa_config;
if (css_param->update_flag.anr_config)
- atomisp_css_set_anr_config(asd, &css_param->anr_config);
+ asd->params.config.anr_config = &css_param->anr_config;
if (css_param->update_flag.xnr_config)
- atomisp_css_set_xnr_config(asd, &css_param->xnr_config);
+ asd->params.config.xnr_config = &css_param->xnr_config;
if (css_param->update_flag.yuv2rgb_cc_config)
- atomisp_css_set_yuv2rgb_cc_config(asd,
- &css_param->yuv2rgb_cc_config);
+ asd->params.config.yuv2rgb_cc_config = &css_param->yuv2rgb_cc_config;
if (css_param->update_flag.rgb2yuv_cc_config)
- atomisp_css_set_rgb2yuv_cc_config(asd,
- &css_param->rgb2yuv_cc_config);
+ asd->params.config.rgb2yuv_cc_config = &css_param->rgb2yuv_cc_config;
if (css_param->update_flag.macc_table)
- atomisp_css_set_macc_table(asd, &css_param->macc_table);
+ asd->params.config.macc_table = &css_param->macc_table;
if (css_param->update_flag.xnr_table)
- atomisp_css_set_xnr_table(asd, &css_param->xnr_table);
+ asd->params.config.xnr_table = &css_param->xnr_table;
if (css_param->update_flag.r_gamma_table)
- atomisp_css_set_r_gamma_table(asd, &css_param->r_gamma_table);
+ asd->params.config.r_gamma_table = &css_param->r_gamma_table;
if (css_param->update_flag.g_gamma_table)
- atomisp_css_set_g_gamma_table(asd, &css_param->g_gamma_table);
+ asd->params.config.g_gamma_table = &css_param->g_gamma_table;
if (css_param->update_flag.b_gamma_table)
- atomisp_css_set_b_gamma_table(asd, &css_param->b_gamma_table);
+ asd->params.config.b_gamma_table = &css_param->b_gamma_table;
if (css_param->update_flag.anr_thres)
atomisp_css_set_anr_thres(asd, &css_param->anr_thres);
if (css_param->update_flag.shading_table)
- atomisp_css_set_shading_table(asd, css_param->shading_table);
+ asd->params.config.shading_table = css_param->shading_table;
if (css_param->update_flag.morph_table && asd->params.gdc_cac_en)
- atomisp_css_set_morph_table(asd, css_param->morph_table);
+ asd->params.config.morph_table = css_param->morph_table;
if (css_param->update_flag.dvs2_coefs) {
- struct atomisp_css_dvs_grid_info *dvs_grid_info =
+ struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(
&asd->params.curr_grid_info);
@@ -3271,7 +3288,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->wb_config && (from_user || !cur_config->wb_config)) {
if (copy_from_compatible(&css_param->wb_config, arg->wb_config,
- sizeof(struct atomisp_css_wb_config),
+ sizeof(struct ia_css_wb_config),
from_user))
return -EFAULT;
css_param->update_flag.wb_config =
@@ -3280,7 +3297,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->ob_config && (from_user || !cur_config->ob_config)) {
if (copy_from_compatible(&css_param->ob_config, arg->ob_config,
- sizeof(struct atomisp_css_ob_config),
+ sizeof(struct ia_css_ob_config),
from_user))
return -EFAULT;
css_param->update_flag.ob_config =
@@ -3289,7 +3306,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->dp_config && (from_user || !cur_config->dp_config)) {
if (copy_from_compatible(&css_param->dp_config, arg->dp_config,
- sizeof(struct atomisp_css_dp_config),
+ sizeof(struct ia_css_dp_config),
from_user))
return -EFAULT;
css_param->update_flag.dp_config =
@@ -3300,7 +3317,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->dz_config && (from_user || !cur_config->dz_config)) {
if (copy_from_compatible(&css_param->dz_config,
arg->dz_config,
- sizeof(struct atomisp_css_dz_config),
+ sizeof(struct ia_css_dz_config),
from_user))
return -EFAULT;
if (!atomisp_check_zoom_region(asd,
@@ -3316,7 +3333,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->nr_config && (from_user || !cur_config->nr_config)) {
if (copy_from_compatible(&css_param->nr_config, arg->nr_config,
- sizeof(struct atomisp_css_nr_config),
+ sizeof(struct ia_css_nr_config),
from_user))
return -EFAULT;
css_param->update_flag.nr_config =
@@ -3325,7 +3342,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->ee_config && (from_user || !cur_config->ee_config)) {
if (copy_from_compatible(&css_param->ee_config, arg->ee_config,
- sizeof(struct atomisp_css_ee_config),
+ sizeof(struct ia_css_ee_config),
from_user))
return -EFAULT;
css_param->update_flag.ee_config =
@@ -3335,7 +3352,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->tnr_config && (from_user || !cur_config->tnr_config)) {
if (copy_from_compatible(&css_param->tnr_config,
arg->tnr_config,
- sizeof(struct atomisp_css_tnr_config),
+ sizeof(struct ia_css_tnr_config),
from_user))
return -EFAULT;
css_param->update_flag.tnr_config =
@@ -3346,7 +3363,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->a3a_config && (from_user || !cur_config->a3a_config)) {
if (copy_from_compatible(&css_param->s3a_config,
arg->a3a_config,
- sizeof(struct atomisp_css_3a_config),
+ sizeof(struct ia_css_3a_config),
from_user))
return -EFAULT;
css_param->update_flag.a3a_config =
@@ -3356,7 +3373,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->ctc_config && (from_user || !cur_config->ctc_config)) {
if (copy_from_compatible(&css_param->ctc_config,
arg->ctc_config,
- sizeof(struct atomisp_css_ctc_config),
+ sizeof(struct ia_css_ctc_config),
from_user))
return -EFAULT;
css_param->update_flag.ctc_config =
@@ -3367,7 +3384,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->cnr_config && (from_user || !cur_config->cnr_config)) {
if (copy_from_compatible(&css_param->cnr_config,
arg->cnr_config,
- sizeof(struct atomisp_css_cnr_config),
+ sizeof(struct ia_css_cnr_config),
from_user))
return -EFAULT;
css_param->update_flag.cnr_config =
@@ -3378,7 +3395,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->ecd_config && (from_user || !cur_config->ecd_config)) {
if (copy_from_compatible(&css_param->ecd_config,
arg->ecd_config,
- sizeof(struct atomisp_css_ecd_config),
+ sizeof(struct ia_css_ecd_config),
from_user))
return -EFAULT;
css_param->update_flag.ecd_config =
@@ -3389,7 +3406,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->ynr_config && (from_user || !cur_config->ynr_config)) {
if (copy_from_compatible(&css_param->ynr_config,
arg->ynr_config,
- sizeof(struct atomisp_css_ynr_config),
+ sizeof(struct ia_css_ynr_config),
from_user))
return -EFAULT;
css_param->update_flag.ynr_config =
@@ -3400,7 +3417,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->fc_config && (from_user || !cur_config->fc_config)) {
if (copy_from_compatible(&css_param->fc_config,
arg->fc_config,
- sizeof(struct atomisp_css_fc_config),
+ sizeof(struct ia_css_fc_config),
from_user))
return -EFAULT;
css_param->update_flag.fc_config =
@@ -3410,7 +3427,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->macc_config && (from_user || !cur_config->macc_config)) {
if (copy_from_compatible(&css_param->macc_config,
arg->macc_config,
- sizeof(struct atomisp_css_macc_config),
+ sizeof(struct ia_css_macc_config),
from_user))
return -EFAULT;
css_param->update_flag.macc_config =
@@ -3420,7 +3437,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->aa_config && (from_user || !cur_config->aa_config)) {
if (copy_from_compatible(&css_param->aa_config, arg->aa_config,
- sizeof(struct atomisp_css_aa_config),
+ sizeof(struct ia_css_aa_config),
from_user))
return -EFAULT;
css_param->update_flag.aa_config =
@@ -3430,7 +3447,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->anr_config && (from_user || !cur_config->anr_config)) {
if (copy_from_compatible(&css_param->anr_config,
arg->anr_config,
- sizeof(struct atomisp_css_anr_config),
+ sizeof(struct ia_css_anr_config),
from_user))
return -EFAULT;
css_param->update_flag.anr_config =
@@ -3441,7 +3458,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->xnr_config && (from_user || !cur_config->xnr_config)) {
if (copy_from_compatible(&css_param->xnr_config,
arg->xnr_config,
- sizeof(struct atomisp_css_xnr_config),
+ sizeof(struct ia_css_xnr_config),
from_user))
return -EFAULT;
css_param->update_flag.xnr_config =
@@ -3453,7 +3470,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
(from_user || !cur_config->yuv2rgb_cc_config)) {
if (copy_from_compatible(&css_param->yuv2rgb_cc_config,
arg->yuv2rgb_cc_config,
- sizeof(struct atomisp_css_cc_config),
+ sizeof(struct ia_css_cc_config),
from_user))
return -EFAULT;
css_param->update_flag.yuv2rgb_cc_config =
@@ -3465,7 +3482,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
(from_user || !cur_config->rgb2yuv_cc_config)) {
if (copy_from_compatible(&css_param->rgb2yuv_cc_config,
arg->rgb2yuv_cc_config,
- sizeof(struct atomisp_css_cc_config),
+ sizeof(struct ia_css_cc_config),
from_user))
return -EFAULT;
css_param->update_flag.rgb2yuv_cc_config =
@@ -3476,7 +3493,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->macc_table && (from_user || !cur_config->macc_table)) {
if (copy_from_compatible(&css_param->macc_table,
arg->macc_table,
- sizeof(struct atomisp_css_macc_table),
+ sizeof(struct ia_css_macc_table),
from_user))
return -EFAULT;
css_param->update_flag.macc_table =
@@ -3487,7 +3504,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->xnr_table && (from_user || !cur_config->xnr_table)) {
if (copy_from_compatible(&css_param->xnr_table,
arg->xnr_table,
- sizeof(struct atomisp_css_xnr_table),
+ sizeof(struct ia_css_xnr_table),
from_user))
return -EFAULT;
css_param->update_flag.xnr_table =
@@ -3497,7 +3514,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->r_gamma_table && (from_user || !cur_config->r_gamma_table)) {
if (copy_from_compatible(&css_param->r_gamma_table,
arg->r_gamma_table,
- sizeof(struct atomisp_css_rgb_gamma_table),
+ sizeof(struct ia_css_rgb_gamma_table),
from_user))
return -EFAULT;
css_param->update_flag.r_gamma_table =
@@ -3508,7 +3525,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->g_gamma_table && (from_user || !cur_config->g_gamma_table)) {
if (copy_from_compatible(&css_param->g_gamma_table,
arg->g_gamma_table,
- sizeof(struct atomisp_css_rgb_gamma_table),
+ sizeof(struct ia_css_rgb_gamma_table),
from_user))
return -EFAULT;
css_param->update_flag.g_gamma_table =
@@ -3519,7 +3536,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->b_gamma_table && (from_user || !cur_config->b_gamma_table)) {
if (copy_from_compatible(&css_param->b_gamma_table,
arg->b_gamma_table,
- sizeof(struct atomisp_css_rgb_gamma_table),
+ sizeof(struct ia_css_rgb_gamma_table),
from_user))
return -EFAULT;
css_param->update_flag.b_gamma_table =
@@ -3529,7 +3546,7 @@ int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
if (arg->anr_thres && (from_user || !cur_config->anr_thres)) {
if (copy_from_compatible(&css_param->anr_thres, arg->anr_thres,
- sizeof(struct atomisp_css_anr_thres),
+ sizeof(struct ia_css_anr_thres),
from_user))
return -EFAULT;
css_param->update_flag.anr_thres =
@@ -3559,8 +3576,8 @@ int atomisp_cp_lsc_table(struct atomisp_sub_device *asd,
{
unsigned int i;
unsigned int len_table;
- struct atomisp_css_shading_table *shading_table;
- struct atomisp_css_shading_table *old_table;
+ struct ia_css_shading_table *shading_table;
+ struct ia_css_shading_table *old_table;
struct atomisp_shading_table *st, dest_st;
if (!source_st)
@@ -3572,7 +3589,7 @@ int atomisp_cp_lsc_table(struct atomisp_sub_device *asd,
if (!from_user && css_param->update_flag.shading_table)
return 0;
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
if (copy_from_compatible(&dest_st, source_st,
sizeof(struct atomisp_shading_table),
from_user)) {
@@ -3605,7 +3622,7 @@ int atomisp_cp_lsc_table(struct atomisp_sub_device *asd,
}
/* Shading table size per color */
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (st->width > ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
st->height > ISP2400_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR) {
dev_err(asd->isp->dev, "shading table w/h validate failed!");
@@ -3677,7 +3694,7 @@ int atomisp_css_cp_dvs2_coefs(struct atomisp_sub_device *asd,
struct atomisp_css_params *css_param,
bool from_user)
{
- struct atomisp_css_dvs_grid_info *cur =
+ struct ia_css_dvs_grid_info *cur =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
int dvs_hor_coef_bytes, dvs_ver_coef_bytes;
struct ia_css_dvs2_coefficients dvs2_coefs;
@@ -3688,7 +3705,7 @@ int atomisp_css_cp_dvs2_coefs(struct atomisp_sub_device *asd,
if (!from_user && css_param->update_flag.dvs2_coefs)
return 0;
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (sizeof(*cur) != sizeof(coefs->grid) ||
memcmp(&coefs->grid, cur, sizeof(coefs->grid))) {
dev_err(asd->isp->dev, "dvs grid mis-match!\n");
@@ -3796,7 +3813,7 @@ int atomisp_css_cp_dvs2_coefs(struct atomisp_sub_device *asd,
}
css_param->update_flag.dvs2_coefs =
- (struct atomisp_dvs2_coefficients *)css_param->dvs2_coeff;
+ (struct atomisp_dis_coefficients *)css_param->dvs2_coeff;
return 0;
}
@@ -3805,11 +3822,11 @@ int atomisp_cp_dvs_6axis_config(struct atomisp_sub_device *asd,
struct atomisp_css_params *css_param,
bool from_user)
{
- struct atomisp_css_dvs_6axis_config *dvs_6axis_config;
- struct atomisp_css_dvs_6axis_config *old_6axis_config;
+ struct ia_css_dvs_6axis_config *dvs_6axis_config;
+ struct ia_css_dvs_6axis_config *old_6axis_config;
struct ia_css_stream *stream =
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream;
- struct atomisp_css_dvs_grid_info *dvs_grid_info =
+ struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
int ret = -EFAULT;
@@ -3831,8 +3848,8 @@ int atomisp_cp_dvs_6axis_config(struct atomisp_sub_device *asd,
old_6axis_config = css_param->dvs_6axis;
dvs_6axis_config = old_6axis_config;
- if (atomisp_hw_is_isp2401) {
- struct atomisp_css_dvs_6axis_config t_6axis_config;
+ if (IS_ISP2401) {
+ struct ia_css_dvs_6axis_config t_6axis_config;
if (copy_from_compatible(&t_6axis_config, source_6axis_config,
sizeof(struct atomisp_dvs_6axis_config),
@@ -3955,8 +3972,8 @@ int atomisp_cp_morph_table(struct atomisp_sub_device *asd,
{
int ret = -EFAULT;
unsigned int i;
- struct atomisp_css_morph_table *morph_table;
- struct atomisp_css_morph_table *old_morph_table;
+ struct ia_css_morph_table *morph_table;
+ struct ia_css_morph_table *old_morph_table;
if (!source_morph_table)
return 0;
@@ -3966,8 +3983,8 @@ int atomisp_cp_morph_table(struct atomisp_sub_device *asd,
old_morph_table = css_param->morph_table;
- if (atomisp_hw_is_isp2401) {
- struct atomisp_css_morph_table mtbl;
+ if (IS_ISP2401) {
+ struct ia_css_morph_table mtbl;
if (copy_from_compatible(&mtbl, source_morph_table,
sizeof(struct atomisp_morph_table),
@@ -3982,7 +3999,7 @@ int atomisp_cp_morph_table(struct atomisp_sub_device *asd,
if (!morph_table)
return -ENOMEM;
- for (i = 0; i < CSS_MORPH_TABLE_NUM_PLANES; i++) {
+ for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
if (copy_from_compatible(morph_table->coordinates_x[i],
(__force void *)source_morph_table->coordinates_x[i],
mtbl.height * mtbl.width *
@@ -4004,7 +4021,7 @@ int atomisp_cp_morph_table(struct atomisp_sub_device *asd,
if (!morph_table)
return -ENOMEM;
- for (i = 0; i < CSS_MORPH_TABLE_NUM_PLANES; i++) {
+ for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
if (copy_from_compatible(morph_table->coordinates_x[i],
(__force void *)source_morph_table->coordinates_x[i],
source_morph_table->height * source_morph_table->width *
@@ -4156,7 +4173,7 @@ void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe)
atomisp_qbuffers_to_css(asd);
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (!atomisp_is_wdt_running(asd) && atomisp_buffers_queued(asd))
atomisp_wdt_start(asd);
} else {
@@ -4192,7 +4209,7 @@ int atomisp_set_parameters(struct video_device *vdev,
__func__, arg->per_frame_setting, asd->index,
arg->isp_config_id, vdev->name);
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
if (atomisp_is_vf_pipe(pipe) && arg->per_frame_setting) {
dev_err(asd->isp->dev, "%s: vf pipe not support per_frame_setting",
__func__);
@@ -4264,21 +4281,16 @@ apply_parameter_failed:
int atomisp_param(struct atomisp_sub_device *asd, int flag,
struct atomisp_parm *config)
{
- struct atomisp_device *isp = asd->isp;
struct ia_css_pipe_config *vp_cfg =
&asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].
pipe_configs[IA_CSS_PIPE_ID_VIDEO];
/* Read parameter for 3A binary info */
if (flag == 0) {
- struct atomisp_css_dvs_grid_info *dvs_grid_info =
+ struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(
&asd->params.curr_grid_info);
- if (!&config->info) {
- dev_err(isp->dev, "ERROR: NULL pointer in grid_info\n");
- return -EINVAL;
- }
atomisp_curr_user_grid_info(asd, &config->info);
/* We always return the resolution and stride even if there is
@@ -4295,7 +4307,7 @@ int atomisp_param(struct atomisp_sub_device *asd, int flag,
if (dvs_grid_info)
memcpy(&config->dvs_grid,
dvs_grid_info,
- sizeof(struct atomisp_css_dvs_grid_info));
+ sizeof(struct ia_css_dvs_grid_info));
if (asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO) {
config->dvs_envelop.width = 0;
@@ -4330,23 +4342,23 @@ int atomisp_param(struct atomisp_sub_device *asd, int flag,
}
memcpy(&asd->params.css_param.wb_config, &config->wb_config,
- sizeof(struct atomisp_css_wb_config));
+ sizeof(struct ia_css_wb_config));
memcpy(&asd->params.css_param.ob_config, &config->ob_config,
- sizeof(struct atomisp_css_ob_config));
+ sizeof(struct ia_css_ob_config));
memcpy(&asd->params.css_param.dp_config, &config->dp_config,
- sizeof(struct atomisp_css_dp_config));
+ sizeof(struct ia_css_dp_config));
memcpy(&asd->params.css_param.de_config, &config->de_config,
- sizeof(struct atomisp_css_de_config));
+ sizeof(struct ia_css_de_config));
memcpy(&asd->params.css_param.dz_config, &config->dz_config,
- sizeof(struct atomisp_css_dz_config));
+ sizeof(struct ia_css_dz_config));
memcpy(&asd->params.css_param.ce_config, &config->ce_config,
- sizeof(struct atomisp_css_ce_config));
+ sizeof(struct ia_css_ce_config));
memcpy(&asd->params.css_param.nr_config, &config->nr_config,
- sizeof(struct atomisp_css_nr_config));
+ sizeof(struct ia_css_nr_config));
memcpy(&asd->params.css_param.ee_config, &config->ee_config,
- sizeof(struct atomisp_css_ee_config));
+ sizeof(struct ia_css_ee_config));
memcpy(&asd->params.css_param.tnr_config, &config->tnr_config,
- sizeof(struct atomisp_css_tnr_config));
+ sizeof(struct ia_css_tnr_config));
if (asd->params.color_effect == V4L2_COLORFX_NEGATIVE) {
asd->params.css_param.cc_config.matrix[3] = -config->cc_config.matrix[3];
@@ -4360,19 +4372,19 @@ int atomisp_param(struct atomisp_sub_device *asd, int flag,
if (asd->params.color_effect != V4L2_COLORFX_SEPIA &&
asd->params.color_effect != V4L2_COLORFX_BW) {
memcpy(&asd->params.css_param.cc_config, &config->cc_config,
- sizeof(struct atomisp_css_cc_config));
- atomisp_css_set_cc_config(asd, &asd->params.css_param.cc_config);
- }
-
- atomisp_css_set_wb_config(asd, &asd->params.css_param.wb_config);
- atomisp_css_set_ob_config(asd, &asd->params.css_param.ob_config);
- atomisp_css_set_de_config(asd, &asd->params.css_param.de_config);
- atomisp_css_set_dz_config(asd, &asd->params.css_param.dz_config);
- atomisp_css_set_ce_config(asd, &asd->params.css_param.ce_config);
- atomisp_css_set_dp_config(asd, &asd->params.css_param.dp_config);
- atomisp_css_set_nr_config(asd, &asd->params.css_param.nr_config);
- atomisp_css_set_ee_config(asd, &asd->params.css_param.ee_config);
- atomisp_css_set_tnr_config(asd, &asd->params.css_param.tnr_config);
+ sizeof(struct ia_css_cc_config));
+ asd->params.config.cc_config = &asd->params.css_param.cc_config;
+ }
+
+ asd->params.config.wb_config = &asd->params.css_param.wb_config;
+ asd->params.config.ob_config = &asd->params.css_param.ob_config;
+ asd->params.config.de_config = &asd->params.css_param.de_config;
+ asd->params.config.dz_config = &asd->params.css_param.dz_config;
+ asd->params.config.ce_config = &asd->params.css_param.ce_config;
+ asd->params.config.dp_config = &asd->params.css_param.dp_config;
+ asd->params.config.nr_config = &asd->params.css_param.nr_config;
+ asd->params.config.ee_config = &asd->params.css_param.ee_config;
+ asd->params.config.tnr_config = &asd->params.css_param.tnr_config;
asd->params.css_update_params_needed = true;
return 0;
@@ -4384,9 +4396,9 @@ int atomisp_param(struct atomisp_sub_device *asd, int flag,
int atomisp_color_effect(struct atomisp_sub_device *asd, int flag,
__s32 *effect)
{
- struct atomisp_css_cc_config *cc_config = NULL;
- struct atomisp_css_macc_table *macc_table = NULL;
- struct atomisp_css_ctc_table *ctc_table = NULL;
+ struct ia_css_cc_config *cc_config = NULL;
+ struct ia_css_macc_table *macc_table = NULL;
+ struct ia_css_ctc_table *ctc_table = NULL;
int ret = 0;
struct v4l2_control control;
struct atomisp_device *isp = asd->isp;
@@ -4461,9 +4473,9 @@ int atomisp_color_effect(struct atomisp_sub_device *asd, int flag,
atomisp_update_capture_mode(asd);
if (cc_config)
- atomisp_css_set_cc_config(asd, cc_config);
+ asd->params.config.cc_config = cc_config;
if (macc_table)
- atomisp_css_set_macc_table(asd, macc_table);
+ asd->params.config.macc_table = macc_table;
if (ctc_table)
atomisp_css_set_ctc_table(asd, ctc_table);
asd->params.color_effect = (u32)*effect;
@@ -4500,7 +4512,7 @@ int atomisp_bad_pixel_param(struct atomisp_sub_device *asd, int flag,
/* Set bad pixel to isp parameters */
memcpy(&asd->params.css_param.dp_config, config,
sizeof(asd->params.css_param.dp_config));
- atomisp_css_set_dp_config(asd, &asd->params.css_param.dp_config);
+ asd->params.config.dp_config = &asd->params.css_param.dp_config;
asd->params.css_update_params_needed = true;
}
@@ -4543,34 +4555,34 @@ int atomisp_fixed_pattern(struct atomisp_sub_device *asd, int flag,
static unsigned int
atomisp_bytesperline_to_padded_width(unsigned int bytesperline,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
switch (format) {
- case CSS_FRAME_FORMAT_UYVY:
- case CSS_FRAME_FORMAT_YUYV:
- case CSS_FRAME_FORMAT_RAW:
- case CSS_FRAME_FORMAT_RGB565:
+ case IA_CSS_FRAME_FORMAT_UYVY:
+ case IA_CSS_FRAME_FORMAT_YUYV:
+ case IA_CSS_FRAME_FORMAT_RAW:
+ case IA_CSS_FRAME_FORMAT_RGB565:
return bytesperline / 2;
- case CSS_FRAME_FORMAT_RGBA888:
+ case IA_CSS_FRAME_FORMAT_RGBA888:
return bytesperline / 4;
/* The following cases could be removed, but we leave them
in to document the formats that are included. */
- case CSS_FRAME_FORMAT_NV11:
- case CSS_FRAME_FORMAT_NV12:
- case CSS_FRAME_FORMAT_NV16:
- case CSS_FRAME_FORMAT_NV21:
- case CSS_FRAME_FORMAT_NV61:
- case CSS_FRAME_FORMAT_YV12:
- case CSS_FRAME_FORMAT_YV16:
- case CSS_FRAME_FORMAT_YUV420:
- case CSS_FRAME_FORMAT_YUV420_16:
- case CSS_FRAME_FORMAT_YUV422:
- case CSS_FRAME_FORMAT_YUV422_16:
- case CSS_FRAME_FORMAT_YUV444:
- case CSS_FRAME_FORMAT_YUV_LINE:
- case CSS_FRAME_FORMAT_PLANAR_RGB888:
- case CSS_FRAME_FORMAT_QPLANE6:
- case CSS_FRAME_FORMAT_BINARY_8:
+ case IA_CSS_FRAME_FORMAT_NV11:
+ case IA_CSS_FRAME_FORMAT_NV12:
+ case IA_CSS_FRAME_FORMAT_NV16:
+ case IA_CSS_FRAME_FORMAT_NV21:
+ case IA_CSS_FRAME_FORMAT_NV61:
+ case IA_CSS_FRAME_FORMAT_YV12:
+ case IA_CSS_FRAME_FORMAT_YV16:
+ case IA_CSS_FRAME_FORMAT_YUV420:
+ case IA_CSS_FRAME_FORMAT_YUV420_16:
+ case IA_CSS_FRAME_FORMAT_YUV422:
+ case IA_CSS_FRAME_FORMAT_YUV422_16:
+ case IA_CSS_FRAME_FORMAT_YUV444:
+ case IA_CSS_FRAME_FORMAT_YUV_LINE:
+ case IA_CSS_FRAME_FORMAT_PLANAR_RGB888:
+ case IA_CSS_FRAME_FORMAT_QPLANE6:
+ case IA_CSS_FRAME_FORMAT_BINARY_8:
default:
return bytesperline;
}
@@ -4578,11 +4590,11 @@ atomisp_bytesperline_to_padded_width(unsigned int bytesperline,
static int
atomisp_v4l2_framebuffer_to_css_frame(const struct v4l2_framebuffer *arg,
- struct atomisp_css_frame **result)
+ struct ia_css_frame **result)
{
- struct atomisp_css_frame *res = NULL;
+ struct ia_css_frame *res = NULL;
unsigned int padded_width;
- enum atomisp_css_frame_format sh_format;
+ enum ia_css_frame_format sh_format;
char *tmp_buf = NULL;
int ret = 0;
@@ -4590,10 +4602,10 @@ atomisp_v4l2_framebuffer_to_css_frame(const struct v4l2_framebuffer *arg,
padded_width = atomisp_bytesperline_to_padded_width(
arg->fmt.bytesperline, sh_format);
- /* Note: the padded width on an atomisp_css_frame is in elements, not in
+ /* Note: the padded width on an ia_css_frame is in elements, not in
bytes. The RAW frame we use here should always be a 16bit RAW
frame. This is why we bytesperline/2 is equal to the padded with */
- if (atomisp_css_frame_allocate(&res, arg->fmt.width, arg->fmt.height,
+ if (ia_css_frame_allocate(&res, arg->fmt.width, arg->fmt.height,
sh_format, padded_width, 0)) {
ret = -ENOMEM;
goto err;
@@ -4617,7 +4629,7 @@ atomisp_v4l2_framebuffer_to_css_frame(const struct v4l2_framebuffer *arg,
err:
if (ret && res)
- atomisp_css_frame_free(res);
+ ia_css_frame_free(res);
if (tmp_buf)
vfree(tmp_buf);
if (ret == 0)
@@ -4631,7 +4643,7 @@ err:
int atomisp_fixed_pattern_table(struct atomisp_sub_device *asd,
struct v4l2_framebuffer *arg)
{
- struct atomisp_css_frame *raw_black_frame = NULL;
+ struct ia_css_frame *raw_black_frame = NULL;
int ret;
if (!arg)
@@ -4640,10 +4652,12 @@ int atomisp_fixed_pattern_table(struct atomisp_sub_device *asd,
ret = atomisp_v4l2_framebuffer_to_css_frame(arg, &raw_black_frame);
if (ret)
return ret;
- if (atomisp_css_set_black_frame(asd, raw_black_frame))
- ret = -ENOMEM;
- atomisp_css_frame_free(raw_black_frame);
+ if (sh_css_set_black_frame(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
+ raw_black_frame) != 0)
+ return -ENOMEM;
+
+ ia_css_frame_free(raw_black_frame);
return ret;
}
@@ -4661,10 +4675,10 @@ int atomisp_false_color(struct atomisp_sub_device *asd, int flag,
/* Set nr config to isp parameters */
if (*value) {
- atomisp_css_set_default_de_config(asd);
+ asd->params.config.de_config = NULL;
} else {
asd->params.css_param.de_config.pixelnoise = 0;
- atomisp_css_set_de_config(asd, &asd->params.css_param.de_config);
+ asd->params.config.de_config = &asd->params.css_param.de_config;
}
asd->params.css_update_params_needed = true;
asd->params.false_color = *value;
@@ -4685,7 +4699,7 @@ int atomisp_false_color_param(struct atomisp_sub_device *asd, int flag,
/* Set false color to isp parameters */
memcpy(&asd->params.css_param.de_config, config,
sizeof(asd->params.css_param.de_config));
- atomisp_css_set_de_config(asd, &asd->params.css_param.de_config);
+ asd->params.config.de_config = &asd->params.css_param.de_config;
asd->params.css_update_params_needed = true;
}
@@ -4706,7 +4720,7 @@ int atomisp_white_balance_param(struct atomisp_sub_device *asd, int flag,
/* Set white balance to isp parameters */
memcpy(&asd->params.css_param.wb_config, config,
sizeof(asd->params.css_param.wb_config));
- atomisp_css_set_wb_config(asd, &asd->params.css_param.wb_config);
+ asd->params.config.wb_config = &asd->params.css_param.wb_config;
asd->params.css_update_params_needed = true;
}
@@ -4728,7 +4742,7 @@ int atomisp_3a_config_param(struct atomisp_sub_device *asd, int flag,
/* Set white balance to isp parameters */
memcpy(&asd->params.css_param.s3a_config, config,
sizeof(asd->params.css_param.s3a_config));
- atomisp_css_set_3a_config(asd, &asd->params.css_param.s3a_config);
+ asd->params.config.s3a_config = &asd->params.css_param.s3a_config;
asd->params.css_update_params_needed = true;
}
@@ -4959,13 +4973,14 @@ enum mipi_port_id __get_mipi_port(struct atomisp_device *isp,
{
switch (port) {
case ATOMISP_CAMERA_PORT_PRIMARY:
- return MIPI_PORT0_ID;
+ return MIPI_PORT0_ID;
case ATOMISP_CAMERA_PORT_SECONDARY:
return MIPI_PORT1_ID;
case ATOMISP_CAMERA_PORT_TERTIARY:
- if (MIPI_PORT1_ID + 1 != N_MIPI_PORT_ID)
+ if (MIPI_PORT1_ID + 1 != N_MIPI_PORT_ID) {
return MIPI_PORT1_ID + 1;
- /* go through down for else case */
+ }
+ /* fall through */
default:
dev_err(isp->dev, "unsupported port: %d\n", port);
return MIPI_PORT0_ID;
@@ -5018,7 +5033,7 @@ static inline int atomisp_set_sensor_mipi_to_isp(
mipi_info->input_format);
if (!fc)
return -EINVAL;
- input_format = fc->css_stream_fmt;
+ input_format = fc->atomisp_in_fmt;
} else {
struct v4l2_mbus_framefmt *sink;
@@ -5028,7 +5043,7 @@ static inline int atomisp_set_sensor_mipi_to_isp(
fc = atomisp_find_in_fmt_conv(sink->code);
if (!fc)
return -EINVAL;
- input_format = fc->css_stream_fmt;
+ input_format = fc->atomisp_in_fmt;
bayer_order = fc->bayer_order;
}
@@ -5039,7 +5054,7 @@ static inline int atomisp_set_sensor_mipi_to_isp(
mipi_info->metadata_format);
if (!fc)
return -EINVAL;
- input_format = fc->css_stream_fmt;
+ input_format = fc->atomisp_in_fmt;
atomisp_css_input_configure_port(asd,
__get_mipi_port(asd->isp, mipi_info->port),
mipi_info->num_lanes,
@@ -5060,8 +5075,8 @@ static int __enable_continuous_mode(struct atomisp_sub_device *asd,
enable, asd->continuous_raw_buffer_size->val,
!asd->continuous_viewfinder->val);
- if (!atomisp_hw_is_isp2401)
- atomisp_css_capture_set_mode(asd, CSS_CAPTURE_MODE_PRIMARY);
+ if (!IS_ISP2401)
+ atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_PRIMARY);
else
atomisp_update_capture_mode(asd);
@@ -5085,7 +5100,7 @@ static int __enable_continuous_mode(struct atomisp_sub_device *asd,
}
if (isp->inputs[asd->input_curr].type != FILE_INPUT)
- atomisp_css_input_set_mode(asd, CSS_INPUT_MODE_SENSOR);
+ atomisp_css_input_set_mode(asd, IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
return atomisp_update_run_mode(asd);
}
@@ -5099,13 +5114,13 @@ static int configure_pp_input_nop(struct atomisp_sub_device *asd,
static int configure_output_nop(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format sh_fmt)
+ enum ia_css_frame_format sh_fmt)
{
return 0;
}
static int get_frame_info_nop(struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *finfo)
+ struct ia_css_frame_info *finfo)
{
return 0;
}
@@ -5164,8 +5179,8 @@ static int css_input_resolution_changed(struct atomisp_sub_device *asd,
}
static int atomisp_set_fmt_to_isp(struct video_device *vdev,
- struct atomisp_css_frame_info *output_info,
- struct atomisp_css_frame_info *raw_output_info,
+ struct ia_css_frame_info *output_info,
+ struct ia_css_frame_info *raw_output_info,
struct v4l2_pix_format *pix,
unsigned int source_pad)
{
@@ -5174,22 +5189,22 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
const struct atomisp_format_bridge *format;
struct v4l2_rect *isp_sink_crop;
- enum atomisp_css_pipe_id pipe_id;
+ enum ia_css_pipe_id pipe_id;
struct v4l2_subdev_fh fh;
int (*configure_output)(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format sh_fmt) =
+ enum ia_css_frame_format sh_fmt) =
configure_output_nop;
int (*get_frame_info)(struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *finfo) =
+ struct ia_css_frame_info *finfo) =
get_frame_info_nop;
int (*configure_pp_input)(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height) =
configure_pp_input_nop;
u16 stream_index = atomisp_source_pad_to_stream_id(asd, source_pad);
const struct atomisp_in_fmt_conv *fc;
- int ret;
+ int ret, i;
v4l2_fh_init(&fh.vfh, vdev);
@@ -5221,8 +5236,8 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
ATOMISP_SUBDEV_PAD_SINK)->code);
if (!fc)
return -EINVAL;
- if (format->sh_fmt == CSS_FRAME_FORMAT_RAW &&
- raw_output_format_match_input(fc->css_stream_fmt,
+ if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW &&
+ raw_output_format_match_input(fc->atomisp_in_fmt,
pix->pixelformat))
return -EINVAL;
}
@@ -5255,7 +5270,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
atomisp_subdev_set_ffmt(&asd->subdev, fh.pad,
V4L2_SUBDEV_FORMAT_ACTIVE,
ATOMISP_SUBDEV_PAD_SOURCE_VF, &vf_ffmt);
- asd->video_out_vf.sh_fmt = CSS_FRAME_FORMAT_NV12;
+ asd->video_out_vf.sh_fmt = IA_CSS_FRAME_FORMAT_NV12;
if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
atomisp_css_video_configure_viewfinder(asd,
@@ -5285,25 +5300,26 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
return -EINVAL;
}
- atomisp_css_input_set_mode(asd, CSS_INPUT_MODE_SENSOR);
- atomisp_css_disable_vf_pp(asd,
- asd->vfpp->val != ATOMISP_VFPP_ENABLE);
+ atomisp_css_input_set_mode(asd, IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
+
+ for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++)
+ asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].pipe_extra_configs[i].disable_vf_pp = asd->vfpp->val != ATOMISP_VFPP_ENABLE;
/* ISP2401 new input system need to use copy pipe */
if (asd->copy_mode) {
- pipe_id = CSS_PIPE_ID_COPY;
+ pipe_id = IA_CSS_PIPE_ID_COPY;
atomisp_css_capture_enable_online(asd, stream_index, false);
} else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
/* video same in continuouscapture and online modes */
configure_output = atomisp_css_video_configure_output;
get_frame_info = atomisp_css_video_get_output_frame_info;
- pipe_id = CSS_PIPE_ID_VIDEO;
+ pipe_id = IA_CSS_PIPE_ID_VIDEO;
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
if (!asd->continuous_mode->val) {
configure_output = atomisp_css_video_configure_output;
get_frame_info =
atomisp_css_video_get_output_frame_info;
- pipe_id = CSS_PIPE_ID_VIDEO;
+ pipe_id = IA_CSS_PIPE_ID_VIDEO;
} else {
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW ||
source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) {
@@ -5313,7 +5329,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
atomisp_css_video_get_output_frame_info;
configure_pp_input =
atomisp_css_video_configure_pp_input;
- pipe_id = CSS_PIPE_ID_VIDEO;
+ pipe_id = IA_CSS_PIPE_ID_VIDEO;
} else {
configure_output =
atomisp_css_capture_configure_output;
@@ -5321,7 +5337,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
atomisp_css_capture_get_output_frame_info;
configure_pp_input =
atomisp_css_capture_configure_pp_input;
- pipe_id = CSS_PIPE_ID_CAPTURE;
+ pipe_id = IA_CSS_PIPE_ID_CAPTURE;
atomisp_update_capture_mode(asd);
atomisp_css_capture_enable_online(asd, stream_index, false);
@@ -5331,7 +5347,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
configure_output = atomisp_css_preview_configure_output;
get_frame_info = atomisp_css_preview_get_output_frame_info;
configure_pp_input = atomisp_css_preview_configure_pp_input;
- pipe_id = CSS_PIPE_ID_PREVIEW;
+ pipe_id = IA_CSS_PIPE_ID_PREVIEW;
} else {
/* CSS doesn't support low light mode on SOC cameras, so disable
* it. FIXME: if this is done elsewhere, it gives corrupted
@@ -5340,8 +5356,8 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
if (isp->inputs[asd->input_curr].type == SOC_CAMERA)
asd->params.low_light = false;
- if (format->sh_fmt == CSS_FRAME_FORMAT_RAW) {
- atomisp_css_capture_set_mode(asd, CSS_CAPTURE_MODE_RAW);
+ if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
+ atomisp_css_capture_set_mode(asd, IA_CSS_CAPTURE_MODE_RAW);
atomisp_css_enable_dz(asd, false);
} else {
atomisp_update_capture_mode(asd);
@@ -5356,7 +5372,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
configure_output = atomisp_css_capture_configure_output;
get_frame_info = atomisp_css_capture_get_output_frame_info;
configure_pp_input = atomisp_css_capture_configure_pp_input;
- pipe_id = CSS_PIPE_ID_CAPTURE;
+ pipe_id = IA_CSS_PIPE_ID_CAPTURE;
if (!asd->params.online_process &&
!asd->continuous_mode->val) {
@@ -5377,7 +5393,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
* to SOC camera, use yuvpp pipe.
*/
if (ATOMISP_USE_YUVPP(asd))
- pipe_id = CSS_PIPE_ID_YUVPP;
+ pipe_id = IA_CSS_PIPE_ID_YUVPP;
if (asd->copy_mode)
ret = atomisp_css_copy_configure_output(asd, stream_index,
@@ -5432,12 +5448,12 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
atomisp_update_grid_info(asd, pipe_id, source_pad);
/* Free the raw_dump buffer first */
- atomisp_css_frame_free(asd->raw_output_frame);
+ ia_css_frame_free(asd->raw_output_frame);
asd->raw_output_frame = NULL;
if (!asd->continuous_mode->val &&
!asd->params.online_process && !isp->sw_contex.file_input &&
- atomisp_css_frame_allocate_from_info(&asd->raw_output_frame,
+ ia_css_frame_allocate_from_info(&asd->raw_output_frame,
raw_output_info))
return -ENOMEM;
@@ -5593,24 +5609,19 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
struct atomisp_sub_device *asd = pipe->asd;
const struct atomisp_format_bridge *format_bridge;
const struct atomisp_format_bridge *snr_format_bridge;
- struct atomisp_css_frame_info output_info, raw_output_info;
+ struct ia_css_frame_info output_info, raw_output_info;
struct v4l2_format snr_fmt = *f;
struct v4l2_format backup_fmt = *f, s_fmt = *f;
unsigned int dvs_env_w = 0, dvs_env_h = 0;
unsigned int padding_w = pad_w, padding_h = pad_h;
bool res_overflow = false, crop_needs_override = false;
- struct v4l2_mbus_framefmt isp_sink_fmt;
+ struct v4l2_mbus_framefmt *isp_sink_fmt;
struct v4l2_mbus_framefmt isp_source_fmt = {0};
struct v4l2_rect isp_sink_crop;
u16 source_pad = atomisp_subdev_source_pad(vdev);
struct v4l2_subdev_fh fh;
int ret;
- dev_dbg(isp->dev,
- "setting resolution %ux%u on pad %u for asd%d, bytesperline %u\n",
- f->fmt.pix.width, f->fmt.pix.height, source_pad,
- asd->index, f->fmt.pix.bytesperline);
-
if (source_pad >= ATOMISP_SUBDEV_PADS_NUM)
return -EINVAL;
@@ -5619,6 +5630,11 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
return -EBUSY;
}
+ dev_dbg(isp->dev,
+ "setting resolution %ux%u on pad %u for asd%d, bytesperline %u\n",
+ f->fmt.pix.width, f->fmt.pix.height, source_pad,
+ asd->index, f->fmt.pix.bytesperline);
+
v4l2_fh_init(&fh.vfh, vdev);
format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
@@ -5765,22 +5781,26 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
/* get sensor resolution and format */
ret = atomisp_try_fmt(vdev, &snr_fmt, &res_overflow);
- if (ret)
+ if (ret) {
+ dev_warn(isp->dev, "Try format failed with error %d\n", ret);
return ret;
+ }
f->fmt.pix.width = snr_fmt.fmt.pix.width;
f->fmt.pix.height = snr_fmt.fmt.pix.height;
snr_format_bridge =
atomisp_get_format_bridge(snr_fmt.fmt.pix.pixelformat);
- if (!snr_format_bridge)
+ if (!snr_format_bridge) {
+ dev_warn(isp->dev, "Can't find bridge format\n");
return -EINVAL;
+ }
atomisp_subdev_get_ffmt(&asd->subdev, NULL,
V4L2_SUBDEV_FORMAT_ACTIVE,
ATOMISP_SUBDEV_PAD_SINK)->code =
snr_format_bridge->mbus_code;
- isp_sink_fmt = *atomisp_subdev_get_ffmt(&asd->subdev, NULL,
+ isp_sink_fmt = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
V4L2_SUBDEV_FORMAT_ACTIVE,
ATOMISP_SUBDEV_PAD_SINK);
@@ -5838,9 +5858,9 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
* capture pipe and usually has lower resolution than capture pipe.
*/
if (!asd->continuous_mode->val ||
- isp_sink_fmt.width < (f->fmt.pix.width + padding_w + dvs_env_w) ||
- isp_sink_fmt.height < (f->fmt.pix.height + padding_h +
- dvs_env_h)) {
+ isp_sink_fmt->width < (f->fmt.pix.width + padding_w + dvs_env_w) ||
+ isp_sink_fmt->height < (f->fmt.pix.height + padding_h +
+ dvs_env_h)) {
/*
* For jpeg or custom raw format the sensor will return constant
* width and height. Because we already had quried try_mbus_fmt,
@@ -5859,8 +5879,11 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
ret = atomisp_set_fmt_to_snr(vdev, &s_fmt,
f->fmt.pix.pixelformat, padding_w,
padding_h, dvs_env_w, dvs_env_h);
- if (ret)
+ if (ret) {
+ dev_warn(isp->dev,
+ "Set format to sensor failed with %d\n", ret);
return -EINVAL;
+ }
atomisp_csi_lane_config(isp);
crop_needs_override = true;
@@ -5943,7 +5966,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
* which appears to be related by a hardware
* performance limitation. It's unclear why this
* particular code triggers the issue. */
- if (!atomisp_hw_is_isp2401 || crop_needs_override) {
+ if (!IS_ISP2401 || crop_needs_override) {
if (isp_sink_crop.width * main_compose.height >
isp_sink_crop.height * main_compose.width) {
sink_crop.height = isp_sink_crop.height;
@@ -5977,8 +6000,10 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
set_fmt_to_isp:
ret = atomisp_set_fmt_to_isp(vdev, &output_info, &raw_output_info,
&f->fmt.pix, source_pad);
- if (ret)
+ if (ret) {
+ dev_warn(isp->dev, "Can't set format on ISP. Error %d\n", ret);
return -EINVAL;
+ }
done:
pipe->pix.width = f->fmt.pix.width;
pipe->pix.height = f->fmt.pix.height;
@@ -5995,6 +6020,9 @@ done:
pipe->pix.sizeimage =
PAGE_ALIGN(f->fmt.pix.height * pipe->pix.bytesperline);
}
+ dev_dbg(isp->dev, "%s: image size: %d, %d bytes per line\n",
+ __func__, pipe->pix.sizeimage, pipe->pix.bytesperline);
+
if (f->fmt.pix.field == V4L2_FIELD_ANY)
f->fmt.pix.field = V4L2_FIELD_NONE;
pipe->pix.field = f->fmt.pix.field;
@@ -6045,7 +6073,7 @@ int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f)
}
pipe->pix = f->fmt.pix;
- atomisp_css_input_set_mode(asd, CSS_INPUT_MODE_FIFO);
+ atomisp_css_input_set_mode(asd, IA_CSS_INPUT_MODE_FIFO);
atomisp_css_input_configure_port(asd,
__get_mipi_port(isp, ATOMISP_CAMERA_PORT_PRIMARY), 2, 0xffff4,
0, 0, 0, 0);
@@ -6062,8 +6090,8 @@ int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f)
int atomisp_set_shading_table(struct atomisp_sub_device *asd,
struct atomisp_shading_table *user_shading_table)
{
- struct atomisp_css_shading_table *shading_table;
- struct atomisp_css_shading_table *free_table;
+ struct ia_css_shading_table *shading_table;
+ struct ia_css_shading_table *free_table;
unsigned int len_table;
int i;
int ret = 0;
@@ -6072,7 +6100,7 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
return -EINVAL;
if (!user_shading_table->enable) {
- atomisp_css_set_shading_table(asd, NULL);
+ asd->params.config.shading_table = NULL;
asd->params.sc_en = false;
return 0;
}
@@ -6084,7 +6112,7 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
}
/* Shading table size per color */
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (user_shading_table->width > ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
user_shading_table->height > ISP2400_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR)
return -EINVAL;
@@ -6117,7 +6145,7 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
free_table = asd->params.css_param.shading_table;
asd->params.css_param.shading_table = shading_table;
- atomisp_css_set_shading_table(asd, shading_table);
+ asd->params.config.shading_table = shading_table;
asd->params.sc_en = true;
out:
@@ -6564,31 +6592,31 @@ static int atomisp_get_pipe_id(struct atomisp_video_pipe *pipe)
struct atomisp_sub_device *asd = pipe->asd;
if (ATOMISP_USE_YUVPP(asd))
- return CSS_PIPE_ID_YUVPP;
+ return IA_CSS_PIPE_ID_YUVPP;
else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
- return CSS_PIPE_ID_VIDEO;
+ return IA_CSS_PIPE_ID_VIDEO;
else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT)
- return CSS_PIPE_ID_CAPTURE;
+ return IA_CSS_PIPE_ID_CAPTURE;
else if (pipe == &asd->video_out_video_capture)
- return CSS_PIPE_ID_VIDEO;
+ return IA_CSS_PIPE_ID_VIDEO;
else if (pipe == &asd->video_out_vf)
- return CSS_PIPE_ID_CAPTURE;
+ return IA_CSS_PIPE_ID_CAPTURE;
else if (pipe == &asd->video_out_preview) {
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
- return CSS_PIPE_ID_VIDEO;
+ return IA_CSS_PIPE_ID_VIDEO;
else
- return CSS_PIPE_ID_PREVIEW;
+ return IA_CSS_PIPE_ID_PREVIEW;
} else if (pipe == &asd->video_out_capture) {
if (asd->copy_mode)
return IA_CSS_PIPE_ID_COPY;
else
- return CSS_PIPE_ID_CAPTURE;
+ return IA_CSS_PIPE_ID_CAPTURE;
}
/* fail through */
dev_warn(asd->isp->dev, "%s failed to find proper pipe\n",
__func__);
- return CSS_PIPE_ID_CAPTURE;
+ return IA_CSS_PIPE_ID_CAPTURE;
}
int atomisp_get_invalid_frame_num(struct video_device *vdev,
@@ -6596,7 +6624,7 @@ int atomisp_get_invalid_frame_num(struct video_device *vdev,
{
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
struct atomisp_sub_device *asd = pipe->asd;
- enum atomisp_css_pipe_id pipe_id;
+ enum ia_css_pipe_id pipe_id;
struct ia_css_pipe_info p_info;
int ret;
@@ -6618,7 +6646,7 @@ int atomisp_get_invalid_frame_num(struct video_device *vdev,
ret = ia_css_pipe_get_info(
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
.pipes[pipe_id], &p_info);
- if (ret == IA_CSS_SUCCESS) {
+ if (!ret) {
*invalid_frame_num = p_info.num_invalid_frames;
return 0;
} else {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
index b5af9da3b0fb..0bde995f1a8d 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -32,7 +33,7 @@
#include "ia_css.h"
struct atomisp_device;
-struct atomisp_css_frame;
+struct ia_css_frame;
#define MSI_ENABLE_BIT 16
#define INTR_DISABLE_BIT 10
@@ -64,16 +65,6 @@ bool atomisp_buffers_queued(struct atomisp_sub_device *asd);
/* ISP2401 */
bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe);
-/* TODO:should be here instead of atomisp_helper.h
-extern void __iomem *atomisp_io_base;
-
-static inline void __iomem *atomisp_get_io_virt_addr(unsigned int address)
-{
- void __iomem *ret = atomisp_io_base + (address & 0x003FFFFF);
- return ret;
-}
-*/
-
/*
* Interrupt functions
*/
@@ -88,7 +79,7 @@ const struct atomisp_format_bridge *get_atomisp_format_bridge_from_mbus(
u32 mbus_code);
bool atomisp_is_mbuscode_raw(uint32_t code);
int atomisp_get_frame_pgnr(struct atomisp_device *isp,
- const struct atomisp_css_frame *frame, u32 *p_pgnr);
+ const struct ia_css_frame *frame, u32 *p_pgnr);
void atomisp_delayed_init_work(struct work_struct *work);
/*
@@ -301,8 +292,8 @@ int atomisp_set_array_res(struct atomisp_sub_device *asd,
* Function to calculate real zoom region for every pipe
*/
int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd,
- struct atomisp_css_dz_config *dz_config,
- enum atomisp_css_pipe_id css_pipe_id);
+ struct ia_css_dz_config *dz_config,
+ enum ia_css_pipe_id css_pipe_id);
int atomisp_cp_general_isp_parameters(struct atomisp_sub_device *asd,
struct atomisp_parameters *arg,
@@ -372,8 +363,8 @@ int atomisp_freq_scaling(struct atomisp_device *vdev,
bool force);
void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
- enum atomisp_css_buffer_type buf_type,
- enum atomisp_css_pipe_id css_pipe_id,
+ enum ia_css_buffer_type buf_type,
+ enum ia_css_pipe_id css_pipe_id,
bool q_buffers, enum atomisp_input_stream_id stream_id);
void atomisp_css_flush(struct atomisp_device *isp);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_common.h b/drivers/staging/media/atomisp/pci/atomisp_common.h
index 65c9caf72b7b..b29874f2bc0f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_common.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -43,15 +44,11 @@ extern int pad_h;
/* ISP2401 */
#define ATOMISP_CSS_ISP_PIPE_VERSION_2_7 1
-#define IS_ISP2401(isp) \
- (((isp)->media_dev.hw_revision & ATOMISP_HW_REVISION_MASK) \
- >= (ATOMISP_HW_REVISION_ISP2401_LEGACY << ATOMISP_HW_REVISION_SHIFT))
-
struct atomisp_format_bridge {
unsigned int pixelformat;
unsigned int depth;
u32 mbus_code;
- enum atomisp_css_frame_format sh_fmt;
+ enum ia_css_frame_format sh_fmt;
unsigned char description[32]; /* the same as struct v4l2_fmtdesc */
bool planar;
};
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat.h b/drivers/staging/media/atomisp/pci/atomisp_compat.h
index 205c530e8090..b2ed83c2f337 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Clovertrail PNW Camera Imaging ISP subsystem.
*
@@ -23,116 +24,20 @@
#include "../../include/linux/atomisp.h"
#include <media/videobuf-vmalloc.h>
-#define CSS_RX_IRQ_INFO_BUFFER_OVERRUN \
- CSS_ID(CSS_RX_IRQ_INFO_BUFFER_OVERRUN)
-#define CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE \
- CSS_ID(CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE)
-#define CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE \
- CSS_ID(CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE)
-#define CSS_RX_IRQ_INFO_ECC_CORRECTED \
- CSS_ID(CSS_RX_IRQ_INFO_ECC_CORRECTED)
-#define CSS_RX_IRQ_INFO_ERR_SOT \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_SOT)
-#define CSS_RX_IRQ_INFO_ERR_SOT_SYNC \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_SOT_SYNC)
-#define CSS_RX_IRQ_INFO_ERR_CONTROL \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_CONTROL)
-#define CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE)
-#define CSS_RX_IRQ_INFO_ERR_CRC \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_CRC)
-#define CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID)
-#define CSS_RX_IRQ_INFO_ERR_FRAME_SYNC \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_FRAME_SYNC)
-#define CSS_RX_IRQ_INFO_ERR_FRAME_DATA \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_FRAME_DATA)
-#define CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT)
-#define CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC)
-#define CSS_RX_IRQ_INFO_ERR_LINE_SYNC \
- CSS_ID(CSS_RX_IRQ_INFO_ERR_LINE_SYNC)
-#define CSS_RX_IRQ_INFO_INIT_TIMEOUT \
- CSS_ID(CSS_RX_IRQ_INFO_INIT_TIMEOUT)
-
-#define CSS_IRQ_INFO_CSS_RECEIVER_SOF CSS_ID(CSS_IRQ_INFO_CSS_RECEIVER_SOF)
-#define CSS_IRQ_INFO_CSS_RECEIVER_EOF CSS_ID(CSS_IRQ_INFO_CSS_RECEIVER_EOF)
-#define CSS_IRQ_INFO_CSS_RECEIVER_FIFO_OVERFLOW \
- CSS_ID(CSS_IRQ_INFO_CSS_RECEIVER_FIFO_OVERFLOW)
-#define CSS_EVENT_OUTPUT_FRAME_DONE CSS_EVENT(OUTPUT_FRAME_DONE)
-#define CSS_EVENT_SEC_OUTPUT_FRAME_DONE CSS_EVENT(SECOND_OUTPUT_FRAME_DONE)
-#define CSS_EVENT_VF_OUTPUT_FRAME_DONE CSS_EVENT(VF_OUTPUT_FRAME_DONE)
-#define CSS_EVENT_SEC_VF_OUTPUT_FRAME_DONE CSS_EVENT(SECOND_VF_OUTPUT_FRAME_DONE)
-#define CSS_EVENT_3A_STATISTICS_DONE CSS_EVENT(3A_STATISTICS_DONE)
-#define CSS_EVENT_DIS_STATISTICS_DONE CSS_EVENT(DIS_STATISTICS_DONE)
-#define CSS_EVENT_PIPELINE_DONE CSS_EVENT(PIPELINE_DONE)
-#define CSS_EVENT_METADATA_DONE CSS_EVENT(METADATA_DONE)
-#define CSS_EVENT_ACC_STAGE_COMPLETE CSS_EVENT(ACC_STAGE_COMPLETE)
-#define CSS_EVENT_TIMER CSS_EVENT(TIMER)
-
-#define CSS_BUFFER_TYPE_METADATA CSS_ID(CSS_BUFFER_TYPE_METADATA)
-#define CSS_BUFFER_TYPE_3A_STATISTICS CSS_ID(CSS_BUFFER_TYPE_3A_STATISTICS)
-#define CSS_BUFFER_TYPE_DIS_STATISTICS CSS_ID(CSS_BUFFER_TYPE_DIS_STATISTICS)
-#define CSS_BUFFER_TYPE_INPUT_FRAME CSS_ID(CSS_BUFFER_TYPE_INPUT_FRAME)
-#define CSS_BUFFER_TYPE_OUTPUT_FRAME CSS_ID(CSS_BUFFER_TYPE_OUTPUT_FRAME)
-#define CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME CSS_ID(CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
-#define CSS_BUFFER_TYPE_VF_OUTPUT_FRAME CSS_ID(CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
-#define CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME CSS_ID(CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)
-#define CSS_BUFFER_TYPE_RAW_OUTPUT_FRAME \
- CSS_ID(CSS_BUFFER_TYPE_RAW_OUTPUT_FRAME)
-
-#define CSS_FORMAT_RAW_8 CSS_FORMAT(RAW_8)
-#define CSS_FORMAT_RAW_10 CSS_FORMAT(RAW_10)
-#define CSS_FORMAT_RAW_12 CSS_FORMAT(RAW_12)
-#define CSS_FORMAT_RAW_16 CSS_FORMAT(RAW_16)
-
-#define CSS_CAPTURE_MODE_RAW CSS_ID(CSS_CAPTURE_MODE_RAW)
-#define CSS_CAPTURE_MODE_BAYER CSS_ID(CSS_CAPTURE_MODE_BAYER)
-#define CSS_CAPTURE_MODE_PRIMARY CSS_ID(CSS_CAPTURE_MODE_PRIMARY)
-#define CSS_CAPTURE_MODE_ADVANCED CSS_ID(CSS_CAPTURE_MODE_ADVANCED)
-#define CSS_CAPTURE_MODE_LOW_LIGHT CSS_ID(CSS_CAPTURE_MODE_LOW_LIGHT)
-
-#define CSS_MORPH_TABLE_NUM_PLANES CSS_ID(CSS_MORPH_TABLE_NUM_PLANES)
-
-#define CSS_FRAME_FORMAT_NV11 CSS_ID(CSS_FRAME_FORMAT_NV11)
-#define CSS_FRAME_FORMAT_NV12 CSS_ID(CSS_FRAME_FORMAT_NV12)
-#define CSS_FRAME_FORMAT_NV16 CSS_ID(CSS_FRAME_FORMAT_NV16)
-#define CSS_FRAME_FORMAT_NV21 CSS_ID(CSS_FRAME_FORMAT_NV21)
-#define CSS_FRAME_FORMAT_NV61 CSS_ID(CSS_FRAME_FORMAT_NV61)
-#define CSS_FRAME_FORMAT_YV12 CSS_ID(CSS_FRAME_FORMAT_YV12)
-#define CSS_FRAME_FORMAT_YV16 CSS_ID(CSS_FRAME_FORMAT_YV16)
-#define CSS_FRAME_FORMAT_YUV420 CSS_ID(CSS_FRAME_FORMAT_YUV420)
-#define CSS_FRAME_FORMAT_YUV420_16 CSS_ID(CSS_FRAME_FORMAT_YUV420_16)
-#define CSS_FRAME_FORMAT_YUV422 CSS_ID(CSS_FRAME_FORMAT_YUV422)
-#define CSS_FRAME_FORMAT_YUV422_16 CSS_ID(CSS_FRAME_FORMAT_YUV422_16)
-#define CSS_FRAME_FORMAT_UYVY CSS_ID(CSS_FRAME_FORMAT_UYVY)
-#define CSS_FRAME_FORMAT_YUYV CSS_ID(CSS_FRAME_FORMAT_YUYV)
-#define CSS_FRAME_FORMAT_YUV444 CSS_ID(CSS_FRAME_FORMAT_YUV444)
-#define CSS_FRAME_FORMAT_YUV_LINE CSS_ID(CSS_FRAME_FORMAT_YUV_LINE)
-#define CSS_FRAME_FORMAT_RAW CSS_ID(CSS_FRAME_FORMAT_RAW)
-#define CSS_FRAME_FORMAT_RGB565 CSS_ID(CSS_FRAME_FORMAT_RGB565)
-#define CSS_FRAME_FORMAT_PLANAR_RGB888 CSS_ID(CSS_FRAME_FORMAT_PLANAR_RGB888)
-#define CSS_FRAME_FORMAT_RGBA888 CSS_ID(CSS_FRAME_FORMAT_RGBA888)
-#define CSS_FRAME_FORMAT_QPLANE6 CSS_ID(CSS_FRAME_FORMAT_QPLANE6)
-#define CSS_FRAME_FORMAT_BINARY_8 CSS_ID(CSS_FRAME_FORMAT_BINARY_8)
-
struct atomisp_device;
struct atomisp_sub_device;
struct video_device;
enum atomisp_input_stream_id;
+extern void __iomem *atomisp_io_base;
+
struct atomisp_metadata_buf {
struct ia_css_metadata *metadata;
void *md_vptr;
struct list_head list;
};
-void atomisp_css_debug_dump_sp_sw_debug_info(void);
-void atomisp_css_debug_dump_debug_info(const char *context);
-void atomisp_css_debug_set_dtrace_level(const unsigned int trace_level);
-
-void atomisp_store_uint32(hrt_address addr, uint32_t data);
+void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data);
void atomisp_load_uint32(hrt_address addr, uint32_t *data);
int atomisp_css_init(struct atomisp_device *isp);
@@ -155,35 +60,35 @@ void atomisp_css_rx_clear_irq_info(enum mipi_port_id port,
unsigned int infos);
int atomisp_css_irq_enable(struct atomisp_device *isp,
- enum atomisp_css_irq_info info, bool enable);
+ enum ia_css_irq_info info, bool enable);
int atomisp_q_video_buffer_to_css(struct atomisp_sub_device *asd,
struct videobuf_vmalloc_memory *vm_mem,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_buffer_type css_buf_type,
- enum atomisp_css_pipe_id css_pipe_id);
+ enum ia_css_buffer_type css_buf_type,
+ enum ia_css_pipe_id css_pipe_id);
int atomisp_q_s3a_buffer_to_css(struct atomisp_sub_device *asd,
struct atomisp_s3a_buf *s3a_buf,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id);
+ enum ia_css_pipe_id css_pipe_id);
int atomisp_q_metadata_buffer_to_css(struct atomisp_sub_device *asd,
struct atomisp_metadata_buf *metadata_buf,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id);
+ enum ia_css_pipe_id css_pipe_id);
int atomisp_q_dis_buffer_to_css(struct atomisp_sub_device *asd,
struct atomisp_dis_buf *dis_buf,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id);
+ enum ia_css_pipe_id css_pipe_id);
-void atomisp_css_mmu_invalidate_cache(void);
+void ia_css_mmu_invalidate_cache(void);
-void atomisp_css_mmu_invalidate_tlb(void);
+void ia_css_mmu_invalidate_cache(void);
int atomisp_css_start(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id, bool in_reset);
+ enum ia_css_pipe_id pipe_id, bool in_reset);
void atomisp_css_update_isp_params(struct atomisp_sub_device *asd);
void atomisp_css_update_isp_params_on_pipe(struct atomisp_sub_device *asd,
@@ -191,14 +96,14 @@ void atomisp_css_update_isp_params_on_pipe(struct atomisp_sub_device *asd,
int atomisp_css_queue_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id pipe_id,
- enum atomisp_css_buffer_type buf_type,
+ enum ia_css_pipe_id pipe_id,
+ enum ia_css_buffer_type buf_type,
struct atomisp_css_buffer *isp_css_buffer);
int atomisp_css_dequeue_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id pipe_id,
- enum atomisp_css_buffer_type buf_type,
+ enum ia_css_pipe_id pipe_id,
+ enum ia_css_buffer_type buf_type,
struct atomisp_css_buffer *isp_css_buffer);
int atomisp_css_allocate_stat_buffers(struct atomisp_sub_device *asd,
@@ -217,7 +122,7 @@ void atomisp_css_free_metadata_buffer(struct atomisp_metadata_buf
*metadata_buf);
int atomisp_css_get_grid_info(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id,
+ enum ia_css_pipe_id pipe_id,
int source_pad);
int atomisp_alloc_3a_output_buf(struct atomisp_sub_device *asd);
@@ -287,7 +192,7 @@ void atomisp_css_input_set_binning_factor(struct atomisp_sub_device *asd,
void atomisp_css_input_set_bayer_order(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_bayer_order bayer_order);
+ enum ia_css_bayer_order bayer_order);
void atomisp_css_input_set_format(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
@@ -312,10 +217,10 @@ void atomisp_css_enable_raw_binning(struct atomisp_sub_device *asd,
void atomisp_css_enable_dz(struct atomisp_sub_device *asd, bool enable);
void atomisp_css_capture_set_mode(struct atomisp_sub_device *asd,
- enum atomisp_css_capture_mode mode);
+ enum ia_css_capture_mode mode);
void atomisp_css_input_set_mode(struct atomisp_sub_device *asd,
- enum atomisp_css_input_mode mode);
+ enum ia_css_input_mode mode);
void atomisp_css_capture_enable_online(struct atomisp_sub_device *asd,
unsigned short stream_index, bool enable);
@@ -341,130 +246,103 @@ int atomisp_css_input_configure_port(struct atomisp_sub_device *asd,
unsigned int metadata_width,
unsigned int metadata_height);
-int atomisp_css_frame_allocate(struct atomisp_css_frame **frame,
- unsigned int width, unsigned int height,
- enum atomisp_css_frame_format format,
- unsigned int padded_width,
- unsigned int raw_bit_depth);
-
-int atomisp_css_frame_allocate_from_info(struct atomisp_css_frame **frame,
- const struct atomisp_css_frame_info *info);
-
-void atomisp_css_frame_free(struct atomisp_css_frame *frame);
-
-int atomisp_css_frame_map(struct atomisp_css_frame **frame,
- const struct atomisp_css_frame_info *info,
- const void __user *data, uint16_t attribute,
- void *context);
-
-int atomisp_css_set_black_frame(struct atomisp_sub_device *asd,
- const struct atomisp_css_frame *raw_black_frame);
-
-int atomisp_css_allocate_continuous_frames(bool init_time,
- struct atomisp_sub_device *asd);
-
-void atomisp_css_update_continuous_frames(struct atomisp_sub_device *asd);
-
void atomisp_create_pipes_stream(struct atomisp_sub_device *asd);
void atomisp_destroy_pipes_stream_force(struct atomisp_sub_device *asd);
int atomisp_css_stop(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id, bool in_reset);
+ enum ia_css_pipe_id pipe_id, bool in_reset);
int atomisp_css_continuous_set_num_raw_frames(
struct atomisp_sub_device *asd,
int num_frames);
-void atomisp_css_disable_vf_pp(struct atomisp_sub_device *asd,
- bool disable);
-
int atomisp_css_copy_configure_output(struct atomisp_sub_device *asd,
unsigned int stream_index,
unsigned int width, unsigned int height,
unsigned int padded_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_yuvpp_configure_output(struct atomisp_sub_device *asd,
unsigned int stream_index,
unsigned int width, unsigned int height,
unsigned int padded_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_yuvpp_configure_viewfinder(
struct atomisp_sub_device *asd,
unsigned int stream_index,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_yuvpp_get_output_frame_info(
struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_yuvpp_get_viewfinder_frame_info(
struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_preview_configure_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_capture_configure_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_video_configure_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_get_css_frame_info(struct atomisp_sub_device *asd,
u16 source_pad,
- struct atomisp_css_frame_info *frame_info);
+ struct ia_css_frame_info *frame_info);
int atomisp_css_video_configure_viewfinder(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_capture_configure_viewfinder(
struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format);
+ enum ia_css_frame_format format);
int atomisp_css_video_get_viewfinder_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_capture_get_viewfinder_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_copy_get_output_frame_info(
struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_capture_get_output_raw_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_preview_get_output_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_capture_get_output_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_video_get_output_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info);
+ struct ia_css_frame_info *info);
int atomisp_css_preview_configure_pp_input(
struct atomisp_sub_device *asd,
@@ -486,60 +364,8 @@ int atomisp_css_exp_id_unlock(struct atomisp_sub_device *asd, int exp_id);
int atomisp_css_capture_enable_xnr(struct atomisp_sub_device *asd,
bool enable);
-void atomisp_css_send_input_frame(struct atomisp_sub_device *asd,
- unsigned short *data, unsigned int width,
- unsigned int height);
-
-bool atomisp_css_isp_has_started(void);
-
-void atomisp_css_request_flash(struct atomisp_sub_device *asd);
-
-void atomisp_css_set_wb_config(struct atomisp_sub_device *asd,
- struct atomisp_css_wb_config *wb_config);
-
-void atomisp_css_set_ob_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ob_config *ob_config);
-
-void atomisp_css_set_dp_config(struct atomisp_sub_device *asd,
- struct atomisp_css_dp_config *dp_config);
-
-void atomisp_css_set_de_config(struct atomisp_sub_device *asd,
- struct atomisp_css_de_config *de_config);
-
-void atomisp_css_set_dz_config(struct atomisp_sub_device *asd,
- struct atomisp_css_dz_config *dz_config);
-
-void atomisp_css_set_default_de_config(struct atomisp_sub_device *asd);
-
-void atomisp_css_set_ce_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ce_config *ce_config);
-
-void atomisp_css_set_nr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_nr_config *nr_config);
-
-void atomisp_css_set_ee_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ee_config *ee_config);
-
-void atomisp_css_set_tnr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_tnr_config *tnr_config);
-
-void atomisp_css_set_cc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cc_config *cc_config);
-
-void atomisp_css_set_macc_table(struct atomisp_sub_device *asd,
- struct atomisp_css_macc_table *macc_table);
-
-void atomisp_css_set_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_gamma_table *gamma_table);
-
void atomisp_css_set_ctc_table(struct atomisp_sub_device *asd,
- struct atomisp_css_ctc_table *ctc_table);
-
-void atomisp_css_set_gc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_gc_config *gc_config);
-
-void atomisp_css_set_3a_config(struct atomisp_sub_device *asd,
- struct atomisp_css_3a_config *s3a_config);
+ struct ia_css_ctc_table *ctc_table);
void atomisp_css_video_set_dis_vector(struct atomisp_sub_device *asd,
struct atomisp_dis_vector *vector);
@@ -590,29 +416,29 @@ int atomisp_css_get_formats_config(struct atomisp_sub_device *asd,
struct atomisp_formats_config *formats_config);
void atomisp_css_set_formats_config(struct atomisp_sub_device *asd,
- struct atomisp_css_formats_config *formats_config);
+ struct ia_css_formats_config *formats_config);
int atomisp_css_get_zoom_factor(struct atomisp_sub_device *asd,
unsigned int *zoom);
-struct atomisp_css_shading_table *atomisp_css_shading_table_alloc(
+struct ia_css_shading_table *atomisp_css_shading_table_alloc(
unsigned int width, unsigned int height);
void atomisp_css_set_shading_table(struct atomisp_sub_device *asd,
- struct atomisp_css_shading_table *table);
+ struct ia_css_shading_table *table);
-void atomisp_css_shading_table_free(struct atomisp_css_shading_table *table);
+void atomisp_css_shading_table_free(struct ia_css_shading_table *table);
-struct atomisp_css_morph_table *atomisp_css_morph_table_allocate(
+struct ia_css_morph_table *atomisp_css_morph_table_allocate(
unsigned int width, unsigned int height);
void atomisp_css_set_morph_table(struct atomisp_sub_device *asd,
- struct atomisp_css_morph_table *table);
+ struct ia_css_morph_table *table);
void atomisp_css_get_morph_table(struct atomisp_sub_device *asd,
- struct atomisp_css_morph_table *table);
+ struct ia_css_morph_table *table);
-void atomisp_css_morph_table_free(struct atomisp_css_morph_table *table);
+void atomisp_css_morph_table_free(struct ia_css_morph_table *table);
void atomisp_css_set_cont_prev_start_time(struct atomisp_device *isp,
unsigned int overlap);
@@ -631,20 +457,20 @@ int atomisp_css_stop_acc_pipe(struct atomisp_sub_device *asd);
void atomisp_css_destroy_acc_pipe(struct atomisp_sub_device *asd);
int atomisp_css_load_acc_extension(struct atomisp_sub_device *asd,
- struct atomisp_css_fw_info *fw,
- enum atomisp_css_pipe_id pipe_id,
+ struct ia_css_fw_info *fw,
+ enum ia_css_pipe_id pipe_id,
unsigned int type);
void atomisp_css_unload_acc_extension(struct atomisp_sub_device *asd,
- struct atomisp_css_fw_info *fw,
- enum atomisp_css_pipe_id pipe_id);
+ struct ia_css_fw_info *fw,
+ enum ia_css_pipe_id pipe_id);
int atomisp_css_wait_acc_finish(struct atomisp_sub_device *asd);
void atomisp_css_acc_done(struct atomisp_sub_device *asd);
int atomisp_css_load_acc_binary(struct atomisp_sub_device *asd,
- struct atomisp_css_fw_info *fw,
+ struct ia_css_fw_info *fw,
unsigned int index);
void atomisp_css_unload_acc_binary(struct atomisp_sub_device *asd);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
index 209bc9954a53..c1e282a974d0 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Clovertrail PNW Camera Imaging ISP subsystem.
*
@@ -32,8 +33,6 @@
#include "atomisp_ioctl.h"
#include "atomisp_acc.h"
-#include "hrt/hive_isp_css_mm_hrt.h"
-
#include <asm/intel-mid.h>
#include "ia_css_debug.h"
@@ -68,82 +67,68 @@ struct bayer_ds_factor {
unsigned int denominator;
};
-void atomisp_css_debug_dump_sp_sw_debug_info(void)
-{
- ia_css_debug_dump_sp_sw_debug_info();
-}
-
-void atomisp_css_debug_dump_debug_info(const char *context)
-{
- ia_css_debug_dump_debug_info(context);
-}
-
-void atomisp_css_debug_set_dtrace_level(const unsigned int trace_level)
-{
- ia_css_debug_set_dtrace_level(trace_level);
-}
-
-unsigned int atomisp_css_debug_get_dtrace_level(void)
-{
- return ia_css_debug_trace_level;
-}
-
static void atomisp_css2_hw_store_8(hrt_address addr, uint8_t data)
{
+ s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
spin_lock_irqsave(&mmio_lock, flags);
- _hrt_master_port_store_8(addr, data);
+ *io_virt_addr = data;
spin_unlock_irqrestore(&mmio_lock, flags);
}
static void atomisp_css2_hw_store_16(hrt_address addr, uint16_t data)
{
+ s16 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
spin_lock_irqsave(&mmio_lock, flags);
- _hrt_master_port_store_16(addr, data);
+ *io_virt_addr = data;
spin_unlock_irqrestore(&mmio_lock, flags);
}
-static void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data)
+void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data)
{
+ s32 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
spin_lock_irqsave(&mmio_lock, flags);
- _hrt_master_port_store_32(addr, data);
+ *io_virt_addr = data;
spin_unlock_irqrestore(&mmio_lock, flags);
}
static uint8_t atomisp_css2_hw_load_8(hrt_address addr)
{
+ s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
u8 ret;
spin_lock_irqsave(&mmio_lock, flags);
- ret = _hrt_master_port_load_8(addr);
+ ret = *io_virt_addr;
spin_unlock_irqrestore(&mmio_lock, flags);
return ret;
}
static uint16_t atomisp_css2_hw_load_16(hrt_address addr)
{
+ s16 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
u16 ret;
spin_lock_irqsave(&mmio_lock, flags);
- ret = _hrt_master_port_load_16(addr);
+ ret = *io_virt_addr;
spin_unlock_irqrestore(&mmio_lock, flags);
return ret;
}
static uint32_t atomisp_css2_hw_load_32(hrt_address addr)
{
+ s32 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
u32 ret;
spin_lock_irqsave(&mmio_lock, flags);
- ret = _hrt_master_port_load_32(addr);
+ ret = *io_virt_addr;
spin_unlock_irqrestore(&mmio_lock, flags);
return ret;
}
@@ -151,27 +136,25 @@ static uint32_t atomisp_css2_hw_load_32(hrt_address addr)
static void atomisp_css2_hw_store(hrt_address addr,
const void *from, uint32_t n)
{
+ s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
unsigned int i;
- unsigned int _to = (unsigned int)addr;
- const char *_from = (const char *)from;
spin_lock_irqsave(&mmio_lock, flags);
- for (i = 0; i < n; i++, _to++, _from++)
- _hrt_master_port_store_8(_to, *_from);
+ for (i = 0; i < n; i++, io_virt_addr++, from++)
+ *io_virt_addr = *(s8 *)from;
spin_unlock_irqrestore(&mmio_lock, flags);
}
static void atomisp_css2_hw_load(hrt_address addr, void *to, uint32_t n)
{
+ s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF);
unsigned long flags;
unsigned int i;
- char *_to = (char *)to;
- unsigned int _from = (unsigned int)addr;
spin_lock_irqsave(&mmio_lock, flags);
- for (i = 0; i < n; i++, _to++, _from++)
- *_to = _hrt_master_port_load_8(_from);
+ for (i = 0; i < n; i++, to++, io_virt_addr++)
+ *(s8 *)to = *io_virt_addr;
spin_unlock_irqrestore(&mmio_lock, flags);
}
@@ -193,11 +176,6 @@ static int atomisp_css2_err_print(const char *fmt, va_list args)
return 0;
}
-void atomisp_store_uint32(hrt_address addr, uint32_t data)
-{
- atomisp_css2_hw_store_32(addr, data);
-}
-
void atomisp_load_uint32(hrt_address addr, uint32_t *data)
{
*data = atomisp_css2_hw_load_32(addr);
@@ -215,16 +193,6 @@ static int hmm_get_mmu_base_addr(unsigned int *mmu_base_addr)
return 0;
}
-static void atomisp_isp_parameters_clean_up(
- struct atomisp_css_isp_config *config)
-{
- /*
- * Set NULL to configs pointer to avoid they are set into isp again when
- * some configs are changed and need to be updated later.
- */
- memset(config, 0, sizeof(*config));
-}
-
static void __dump_pipe_config(struct atomisp_sub_device *asd,
struct atomisp_stream_env *stream_env,
unsigned int pipe_id)
@@ -474,7 +442,7 @@ static int __destroy_stream(struct atomisp_sub_device *asd,
}
if (stream_env->stream_state == CSS_STREAM_STARTED
- && ia_css_stream_stop(stream_env->stream) != IA_CSS_SUCCESS) {
+ && ia_css_stream_stop(stream_env->stream) != 0) {
dev_err(isp->dev, "stop stream failed.\n");
return -EINVAL;
}
@@ -496,7 +464,7 @@ static int __destroy_stream(struct atomisp_sub_device *asd,
stream_env->stream_state = CSS_STREAM_STOPPED;
- if (ia_css_stream_destroy(stream_env->stream) != IA_CSS_SUCCESS) {
+ if (ia_css_stream_destroy(stream_env->stream)) {
dev_err(isp->dev, "destroy stream failed.\n");
return -EINVAL;
}
@@ -540,10 +508,10 @@ static int __create_stream(struct atomisp_sub_device *asd,
__dump_stream_config(asd, stream_env);
if (ia_css_stream_create(&stream_env->stream_config,
- pipe_index, multi_pipes, &stream_env->stream) != IA_CSS_SUCCESS)
+ pipe_index, multi_pipes, &stream_env->stream) != 0)
return -EINVAL;
if (ia_css_stream_get_info(stream_env->stream,
- &stream_env->stream_info) != IA_CSS_SUCCESS) {
+ &stream_env->stream_info) != 0) {
ia_css_stream_destroy(stream_env->stream);
stream_env->stream = NULL;
return -EINVAL;
@@ -583,7 +551,7 @@ static int __destroy_stream_pipes(struct atomisp_sub_device *asd,
!(force || stream_env->update_pipe[i]))
continue;
if (ia_css_pipe_destroy(stream_env->pipes[i])
- != IA_CSS_SUCCESS) {
+ != 0) {
dev_err(isp->dev,
"destroy pipe[%d]failed.cannot recover.\n", i);
ret = -EINVAL;
@@ -645,10 +613,10 @@ static void __apply_additional_pipe_config(
/* enable capture pp/dz manually or digital zoom would
* fail*/
if (stream_env->pipe_configs[pipe_id].
- default_capture_config.mode == CSS_CAPTURE_MODE_RAW)
+ default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW)
stream_env->pipe_configs[pipe_id].enable_dz = false;
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
/* the isp default to use ISP2.2 and the camera hal will
* control whether use isp2.7 */
if (asd->select_isp_version->val == ATOMISP_CSS_ISP_PIPE_VERSION_2_7)
@@ -699,7 +667,7 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
if (!asd)
return false;
- if (pipe_id == CSS_PIPE_ID_ACC || pipe_id == CSS_PIPE_ID_YUVPP)
+ if (pipe_id == IA_CSS_PIPE_ID_ACC || pipe_id == IA_CSS_PIPE_ID_YUVPP)
return true;
if (asd->vfpp) {
@@ -726,22 +694,23 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
case ATOMISP_RUN_MODE_STILL_CAPTURE:
if (pipe_id == IA_CSS_PIPE_ID_CAPTURE)
return true;
- else
- return false;
+
+ return false;
case ATOMISP_RUN_MODE_PREVIEW:
if (!asd->continuous_mode->val) {
if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
return true;
- else
- return false;
+
+ return false;
}
- /* fall through to ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE */
+ /* fall-through */
case ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE:
if (pipe_id == IA_CSS_PIPE_ID_CAPTURE ||
pipe_id == IA_CSS_PIPE_ID_PREVIEW)
return true;
- else
- return false;
+
+ return false;
+ /* fall-through */
case ATOMISP_RUN_MODE_VIDEO:
if (!asd->continuous_mode->val) {
if (pipe_id == IA_CSS_PIPE_ID_VIDEO ||
@@ -750,13 +719,13 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
else
return false;
}
- /* fall through to ATOMISP_RUN_MODE_SDV */
+ /* fall through */
case ATOMISP_RUN_MODE_SDV:
if (pipe_id == IA_CSS_PIPE_ID_CAPTURE ||
pipe_id == IA_CSS_PIPE_ID_VIDEO)
return true;
- else
- return false;
+
+ return false;
}
return false;
@@ -768,16 +737,16 @@ static int __create_pipe(struct atomisp_sub_device *asd,
{
struct atomisp_device *isp = asd->isp;
struct ia_css_pipe_extra_config extra_config;
- enum ia_css_err ret;
+ int ret;
if (pipe_id >= IA_CSS_PIPE_ID_NUM)
return -EINVAL;
- if (pipe_id != CSS_PIPE_ID_ACC &&
+ if (pipe_id != IA_CSS_PIPE_ID_ACC &&
!stream_env->pipe_configs[pipe_id].output_info[0].res.width)
return 0;
- if (pipe_id == CSS_PIPE_ID_ACC &&
+ if (pipe_id == IA_CSS_PIPE_ID_ACC &&
!stream_env->pipe_configs[pipe_id].acc_extension)
return 0;
@@ -798,20 +767,20 @@ static int __create_pipe(struct atomisp_sub_device *asd,
&stream_env->pipe_configs[pipe_id],
&stream_env->pipe_extra_configs[pipe_id],
&stream_env->pipes[pipe_id]);
- if (ret != IA_CSS_SUCCESS)
+ if (ret)
dev_err(isp->dev, "create pipe[%d] error.\n", pipe_id);
return ret;
}
static int __create_pipes(struct atomisp_sub_device *asd)
{
- enum ia_css_err ret;
+ int ret;
int i, j;
for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
for (j = 0; j < IA_CSS_PIPE_ID_NUM; j++) {
ret = __create_pipe(asd, &asd->stream_env[i], j);
- if (ret != IA_CSS_SUCCESS)
+ if (ret)
break;
}
if (j < IA_CSS_PIPE_ID_NUM)
@@ -842,20 +811,20 @@ int atomisp_css_update_stream(struct atomisp_sub_device *asd)
int ret;
struct atomisp_device *isp = asd->isp;
- if (__destroy_streams(asd, true) != IA_CSS_SUCCESS)
+ if (__destroy_streams(asd, true))
dev_warn(isp->dev, "destroy stream failed.\n");
- if (__destroy_pipes(asd, true) != IA_CSS_SUCCESS)
+ if (__destroy_pipes(asd, true))
dev_warn(isp->dev, "destroy pipe failed.\n");
ret = __create_pipes(asd);
- if (ret != IA_CSS_SUCCESS) {
+ if (ret) {
dev_err(isp->dev, "create pipe failed %d.\n", ret);
return -EIO;
}
ret = __create_streams(asd);
- if (ret != IA_CSS_SUCCESS) {
+ if (ret) {
dev_warn(isp->dev, "create stream failed %d.\n", ret);
__destroy_pipes(asd, true);
return -EIO;
@@ -868,7 +837,7 @@ int atomisp_css_init(struct atomisp_device *isp)
{
unsigned int mmu_base_addr;
int ret;
- enum ia_css_err err;
+ int err;
ret = hmm_get_mmu_base_addr(&mmu_base_addr);
if (ret)
@@ -877,7 +846,7 @@ int atomisp_css_init(struct atomisp_device *isp)
/* Init ISP */
err = ia_css_init(isp->dev, &isp->css_env.isp_css_env, NULL,
(uint32_t)mmu_base_addr, IA_CSS_IRQ_TYPE_PULSE);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
dev_err(isp->dev, "css init failed --- bad firmware?\n");
return -EINVAL;
}
@@ -907,17 +876,9 @@ static inline int __set_css_print_env(struct atomisp_device *isp, int opt)
return ret;
}
-int atomisp_css_check_firmware_version(struct atomisp_device *isp)
-{
- if (!sh_css_check_firmware_version(isp->dev, (void *)isp->firmware->data)) {
- return -EINVAL;
- }
- return 0;
-}
-
int atomisp_css_load_firmware(struct atomisp_device *isp)
{
- enum ia_css_err err;
+ int err;
/* set css env */
isp->css_env.isp_css_fw.data = (void *)isp->firmware->data;
@@ -946,7 +907,7 @@ int atomisp_css_load_firmware(struct atomisp_device *isp)
/* load isp fw into ISP memory */
err = ia_css_load_firmware(isp->dev, &isp->css_env.isp_css_env,
&isp->css_env.isp_css_fw);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
dev_err(isp->dev, "css load fw failed.\n");
return -EINVAL;
}
@@ -954,11 +915,6 @@ int atomisp_css_load_firmware(struct atomisp_device *isp)
return 0;
}
-void atomisp_css_unload_firmware(struct atomisp_device *isp)
-{
- ia_css_unload_firmware();
-}
-
void atomisp_css_uninit(struct atomisp_device *isp)
{
struct atomisp_sub_device *asd;
@@ -966,7 +922,7 @@ void atomisp_css_uninit(struct atomisp_device *isp)
for (i = 0; i < isp->num_of_streams; i++) {
asd = &isp->asd[i];
- atomisp_isp_parameters_clean_up(&asd->params.config);
+ memset(&asd->params.config, 0, sizeof(asd->params.config));
asd->params.css_update_params_needed = false;
}
@@ -1009,7 +965,7 @@ int atomisp_css_irq_translate(struct atomisp_device *isp,
int err;
err = ia_css_irq_translate(infos);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
dev_warn(isp->dev,
"%s:failed to translate irq (err = %d,infos = %d)\n",
__func__, err, *infos);
@@ -1038,13 +994,15 @@ void atomisp_css_rx_clear_irq_info(enum mipi_port_id port,
}
int atomisp_css_irq_enable(struct atomisp_device *isp,
- enum atomisp_css_irq_info info, bool enable)
+ enum ia_css_irq_info info, bool enable)
{
- dev_dbg(isp->dev, "%s: css irq info 0x%08x: %s.\n",
+ dev_dbg(isp->dev, "%s: css irq info 0x%08x: %s (%d).\n",
__func__, info,
- enable ? "enable" : "disable");
- if (ia_css_irq_enable(info, enable) != IA_CSS_SUCCESS) {
- dev_warn(isp->dev, "%s:Invalid irq info.\n", __func__);
+ enable ? "enable" : "disable", enable);
+ if (ia_css_irq_enable(info, enable)) {
+ dev_warn(isp->dev, "%s:Invalid irq info: 0x%08x when %s.\n",
+ __func__, info,
+ enable ? "enabling" : "disabling");
return -EINVAL;
}
@@ -1072,19 +1030,19 @@ void atomisp_css_init_struct(struct atomisp_sub_device *asd)
int atomisp_q_video_buffer_to_css(struct atomisp_sub_device *asd,
struct videobuf_vmalloc_memory *vm_mem,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_buffer_type css_buf_type,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_buffer_type css_buf_type,
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
struct ia_css_buffer css_buf = {0};
- enum ia_css_err err;
+ int err;
css_buf.type = css_buf_type;
css_buf.data.frame = vm_mem->vaddr;
err = ia_css_pipe_enqueue_buffer(
stream_env->pipes[css_pipe_id], &css_buf);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return -EINVAL;
return 0;
@@ -1093,7 +1051,7 @@ int atomisp_q_video_buffer_to_css(struct atomisp_sub_device *asd,
int atomisp_q_metadata_buffer_to_css(struct atomisp_sub_device *asd,
struct atomisp_metadata_buf *metadata_buf,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
struct ia_css_buffer buffer = {0};
@@ -1113,7 +1071,7 @@ int atomisp_q_metadata_buffer_to_css(struct atomisp_sub_device *asd,
int atomisp_q_s3a_buffer_to_css(struct atomisp_sub_device *asd,
struct atomisp_s3a_buf *s3a_buf,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
struct ia_css_buffer buffer = {0};
@@ -1134,7 +1092,7 @@ int atomisp_q_s3a_buffer_to_css(struct atomisp_sub_device *asd,
int atomisp_q_dis_buffer_to_css(struct atomisp_sub_device *asd,
struct atomisp_dis_buf *dis_buf,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
struct ia_css_buffer buffer = {0};
@@ -1152,18 +1110,8 @@ int atomisp_q_dis_buffer_to_css(struct atomisp_sub_device *asd,
return 0;
}
-void atomisp_css_mmu_invalidate_cache(void)
-{
- ia_css_mmu_invalidate_cache();
-}
-
-void atomisp_css_mmu_invalidate_tlb(void)
-{
- ia_css_mmu_invalidate_cache();
-}
-
int atomisp_css_start(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id, bool in_reset)
+ enum ia_css_pipe_id pipe_id, bool in_reset)
{
struct atomisp_device *isp = asd->isp;
bool sp_is_started = false;
@@ -1222,7 +1170,7 @@ int atomisp_css_start(struct atomisp_sub_device *asd,
} else {
if (!sh_css_hrt_system_is_idle())
dev_err(isp->dev, "CSS HW not idle before starting SP\n");
- if (ia_css_start_sp() != IA_CSS_SUCCESS) {
+ if (ia_css_start_sp()) {
dev_err(isp->dev, "start sp error.\n");
ret = -EINVAL;
goto start_err;
@@ -1234,7 +1182,7 @@ int atomisp_css_start(struct atomisp_sub_device *asd,
for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
if (asd->stream_env[i].stream) {
if (ia_css_stream_start(asd->stream_env[i]
- .stream) != IA_CSS_SUCCESS) {
+ .stream) != 0) {
dev_err(isp->dev, "stream[%d] start error.\n", i);
ret = -EINVAL;
goto start_err;
@@ -1285,13 +1233,13 @@ void atomisp_css_update_isp_params(struct atomisp_sub_device *asd)
ia_css_stream_set_isp_config(
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
&asd->params.config);
- atomisp_isp_parameters_clean_up(&asd->params.config);
+ memset(&asd->params.config, 0, sizeof(asd->params.config));
}
void atomisp_css_update_isp_params_on_pipe(struct atomisp_sub_device *asd,
struct ia_css_pipe *pipe)
{
- enum ia_css_err ret;
+ int ret;
if (!pipe) {
atomisp_css_update_isp_params(asd);
@@ -1306,22 +1254,22 @@ void atomisp_css_update_isp_params_on_pipe(struct atomisp_sub_device *asd,
ret = ia_css_stream_set_isp_config_on_pipe(
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
&asd->params.config, pipe);
- if (ret != IA_CSS_SUCCESS)
+ if (ret)
dev_warn(asd->isp->dev, "%s: ia_css_stream_set_isp_config_on_pipe failed %d\n",
__func__, ret);
- atomisp_isp_parameters_clean_up(&asd->params.config);
+ memset(&asd->params.config, 0, sizeof(asd->params.config));
}
int atomisp_css_queue_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id pipe_id,
- enum atomisp_css_buffer_type buf_type,
+ enum ia_css_pipe_id pipe_id,
+ enum ia_css_buffer_type buf_type,
struct atomisp_css_buffer *isp_css_buffer)
{
if (ia_css_pipe_enqueue_buffer(
asd->stream_env[stream_id].pipes[pipe_id],
&isp_css_buffer->css_buffer)
- != IA_CSS_SUCCESS)
+ != 0)
return -EINVAL;
return 0;
@@ -1329,17 +1277,17 @@ int atomisp_css_queue_buffer(struct atomisp_sub_device *asd,
int atomisp_css_dequeue_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id pipe_id,
- enum atomisp_css_buffer_type buf_type,
+ enum ia_css_pipe_id pipe_id,
+ enum ia_css_buffer_type buf_type,
struct atomisp_css_buffer *isp_css_buffer)
{
struct atomisp_device *isp = asd->isp;
- enum ia_css_err err;
+ int err;
err = ia_css_pipe_dequeue_buffer(
asd->stream_env[stream_id].pipes[pipe_id],
&isp_css_buffer->css_buffer);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
dev_err(isp->dev,
"ia_css_pipe_dequeue_buffer failed: 0x%x\n", err);
return -EINVAL;
@@ -1355,7 +1303,7 @@ int atomisp_css_allocate_stat_buffers(struct atomisp_sub_device *asd,
struct atomisp_metadata_buf *md_buf)
{
struct atomisp_device *isp = asd->isp;
- struct atomisp_css_dvs_grid_info *dvs_grid_info =
+ struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
if (s3a_buf && asd->params.curr_grid_info.s3a_grid.enable) {
@@ -1442,7 +1390,7 @@ void atomisp_css_free_stat_buffers(struct atomisp_sub_device *asd)
struct atomisp_s3a_buf *s3a_buf, *_s3a_buf;
struct atomisp_dis_buf *dis_buf, *_dis_buf;
struct atomisp_metadata_buf *md_buf, *_md_buf;
- struct atomisp_css_dvs_grid_info *dvs_grid_info =
+ struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
unsigned int i;
@@ -1524,7 +1472,7 @@ void atomisp_css_free_stat_buffers(struct atomisp_sub_device *asd)
}
int atomisp_css_get_grid_info(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id,
+ enum ia_css_pipe_id pipe_id,
int source_pad)
{
struct ia_css_pipe_info p_info;
@@ -1539,7 +1487,7 @@ int atomisp_css_get_grid_info(struct atomisp_sub_device *asd,
if (ia_css_pipe_get_info(
asd->stream_env[stream_index].pipes[pipe_id],
- &p_info) != IA_CSS_SUCCESS) {
+ &p_info) != 0) {
dev_err(isp->dev, "ia_css_pipe_get_info failed\n");
return -EINVAL;
}
@@ -1553,7 +1501,7 @@ int atomisp_css_get_grid_info(struct atomisp_sub_device *asd,
* Currently would have one css pipe that need it
*/
if (asd->params.curr_grid_info.s3a_grid.enable) {
- if (asd->params.s3a_enabled_pipe != CSS_PIPE_ID_NUM)
+ if (asd->params.s3a_enabled_pipe != IA_CSS_PIPE_ID_NUM)
dev_dbg(isp->dev, "css pipe %d enabled s3a grid replaced by: %d.\n",
asd->params.s3a_enabled_pipe, pipe_id);
asd->params.s3a_enabled_pipe = pipe_id;
@@ -1603,7 +1551,7 @@ int atomisp_alloc_3a_output_buf(struct atomisp_sub_device *asd)
int atomisp_alloc_dis_coef_buf(struct atomisp_sub_device *asd)
{
- struct atomisp_css_dvs_grid_info *dvs_grid =
+ struct ia_css_dvs_grid_info *dvs_grid =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
if (!dvs_grid)
@@ -1693,7 +1641,7 @@ void atomisp_css_get_dis_statistics(struct atomisp_sub_device *asd,
int atomisp_css_dequeue_event(struct atomisp_css_event *current_event)
{
- if (ia_css_dequeue_event(&current_event->event) != IA_CSS_SUCCESS)
+ if (ia_css_dequeue_event(&current_event->event))
return -EINVAL;
return 0;
@@ -1753,7 +1701,7 @@ void atomisp_css_input_set_binning_factor(struct atomisp_sub_device *asd,
void atomisp_css_input_set_bayer_order(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_bayer_order bayer_order)
+ enum ia_css_bayer_order bayer_order)
{
struct ia_css_stream_config *s_config =
&asd->stream_env[stream_id].stream_config;
@@ -1959,7 +1907,7 @@ void atomisp_css_enable_dz(struct atomisp_sub_device *asd, bool enable)
}
void atomisp_css_capture_set_mode(struct atomisp_sub_device *asd,
- enum atomisp_css_capture_mode mode)
+ enum ia_css_capture_mode mode)
{
struct atomisp_stream_env *stream_env =
&asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
@@ -1974,7 +1922,7 @@ void atomisp_css_capture_set_mode(struct atomisp_sub_device *asd,
}
void atomisp_css_input_set_mode(struct atomisp_sub_device *asd,
- enum atomisp_css_input_mode mode)
+ enum ia_css_input_mode mode)
{
int i;
struct atomisp_device *isp = asd->isp;
@@ -2017,7 +1965,7 @@ void atomisp_css_input_set_mode(struct atomisp_sub_device *asd,
s_config->input_config.format,
true,
0x13000,
- &size_mem_words) != IA_CSS_SUCCESS) {
+ &size_mem_words) != 0) {
if (intel_mid_identify_cpu() ==
INTEL_MID_CPU_CHIP_TANGIER)
size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_2;
@@ -2157,74 +2105,8 @@ int atomisp_css_input_configure_port(
return 0;
}
-int atomisp_css_frame_allocate(struct atomisp_css_frame **frame,
- unsigned int width, unsigned int height,
- enum atomisp_css_frame_format format,
- unsigned int padded_width,
- unsigned int raw_bit_depth)
-{
- if (ia_css_frame_allocate(frame, width, height, format,
- padded_width, raw_bit_depth) != IA_CSS_SUCCESS)
- return -ENOMEM;
-
- return 0;
-}
-
-int atomisp_css_frame_allocate_from_info(struct atomisp_css_frame **frame,
- const struct atomisp_css_frame_info *info)
-{
- if (ia_css_frame_allocate_from_info(frame, info) != IA_CSS_SUCCESS)
- return -ENOMEM;
-
- return 0;
-}
-
-void atomisp_css_frame_free(struct atomisp_css_frame *frame)
-{
- ia_css_frame_free(frame);
-}
-
-int atomisp_css_frame_map(struct atomisp_css_frame **frame,
- const struct atomisp_css_frame_info *info,
- const void __user *data, uint16_t attribute,
- void *context)
-{
- if (ia_css_frame_map(frame, info, data, attribute, context)
- != IA_CSS_SUCCESS)
- return -ENOMEM;
-
- return 0;
-}
-
-int atomisp_css_set_black_frame(struct atomisp_sub_device *asd,
- const struct atomisp_css_frame *raw_black_frame)
-{
- if (sh_css_set_black_frame(
- asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
- raw_black_frame) != IA_CSS_SUCCESS)
- return -ENOMEM;
-
- return 0;
-}
-
-int atomisp_css_allocate_continuous_frames(bool init_time,
- struct atomisp_sub_device *asd)
-{
- if (ia_css_alloc_continuous_frame_remain(
- asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream)
- != IA_CSS_SUCCESS)
- return -EINVAL;
- return 0;
-}
-
-void atomisp_css_update_continuous_frames(struct atomisp_sub_device *asd)
-{
- ia_css_update_continuous_frames(
- asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream);
-}
-
int atomisp_css_stop(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id, bool in_reset)
+ enum ia_css_pipe_id pipe_id, bool in_reset)
{
struct atomisp_device *isp = asd->isp;
struct atomisp_s3a_buf *s3a_buf;
@@ -2264,7 +2146,7 @@ int atomisp_css_stop(struct atomisp_sub_device *asd,
ia_css_stream_config_defaults(
&stream_env->stream_config);
}
- atomisp_isp_parameters_clean_up(&asd->params.config);
+ memset(&asd->params.config, 0, sizeof(asd->params.config));
asd->params.css_update_params_needed = false;
}
@@ -2345,16 +2227,6 @@ int atomisp_css_continuous_set_num_raw_frames(
return 0;
}
-void atomisp_css_disable_vf_pp(struct atomisp_sub_device *asd,
- bool disable)
-{
- int i;
-
- for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++)
- asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
- .pipe_extra_configs[i].disable_vf_pp = !!disable;
-}
-
static enum ia_css_pipe_mode __pipe_id_to_pipe_mode(
struct atomisp_sub_device *asd,
enum ia_css_pipe_id pipe_id)
@@ -2749,7 +2621,7 @@ done:
static void __configure_vf_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format,
+ enum ia_css_frame_format format,
enum ia_css_pipe_id pipe_id)
{
struct atomisp_device *isp = asd->isp;
@@ -2772,7 +2644,7 @@ static void __configure_vf_output(struct atomisp_sub_device *asd,
static void __configure_video_vf_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format,
+ enum ia_css_frame_format format,
enum ia_css_pipe_id pipe_id)
{
struct atomisp_device *isp = asd->isp;
@@ -2807,12 +2679,12 @@ static void __configure_video_vf_output(struct atomisp_sub_device *asd,
static int __get_frame_info(struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info,
+ struct ia_css_frame_info *info,
enum frame_info_type type,
enum ia_css_pipe_id pipe_id)
{
struct atomisp_device *isp = asd->isp;
- enum ia_css_err ret;
+ int ret;
struct ia_css_pipe_info p_info;
/* FIXME! No need to destroy/recreate all streams */
@@ -2831,7 +2703,7 @@ static int __get_frame_info(struct atomisp_sub_device *asd,
ret = ia_css_pipe_get_info(
asd->stream_env[stream_index]
.pipes[pipe_id], &p_info);
- if (ret == IA_CSS_SUCCESS) {
+ if (!ret) {
switch (type) {
case ATOMISP_CSS_VF_FRAME:
*info = p_info.vf_output_info[0];
@@ -2882,16 +2754,18 @@ static unsigned int atomisp_get_pipe_index(struct atomisp_sub_device *asd,
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO
|| asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
return IA_CSS_PIPE_ID_VIDEO;
- else
- return IA_CSS_PIPE_ID_CAPTURE;
+
+ return IA_CSS_PIPE_ID_CAPTURE;
case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE:
if (asd->copy_mode)
return IA_CSS_PIPE_ID_COPY;
+
return IA_CSS_PIPE_ID_CAPTURE;
case ATOMISP_SUBDEV_PAD_SOURCE_VF:
- if (!atomisp_is_mbuscode_raw(
- asd->fmt[asd->capture_pad].fmt.code))
+ if (!atomisp_is_mbuscode_raw(asd->fmt[asd->capture_pad].fmt.code)) {
return IA_CSS_PIPE_ID_CAPTURE;
+ }
+ /* fall through */
case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW:
if (asd->yuvpp_mode)
return IA_CSS_PIPE_ID_YUVPP;
@@ -2899,8 +2773,8 @@ static unsigned int atomisp_get_pipe_index(struct atomisp_sub_device *asd,
return IA_CSS_PIPE_ID_COPY;
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
return IA_CSS_PIPE_ID_VIDEO;
- else
- return IA_CSS_PIPE_ID_PREVIEW;
+
+ return IA_CSS_PIPE_ID_PREVIEW;
}
dev_warn(isp->dev,
"invalid source pad:%d, return default preview pipe index.\n",
@@ -2910,7 +2784,7 @@ static unsigned int atomisp_get_pipe_index(struct atomisp_sub_device *asd,
int atomisp_get_css_frame_info(struct atomisp_sub_device *asd,
u16 source_pad,
- struct atomisp_css_frame_info *frame_info)
+ struct ia_css_frame_info *frame_info)
{
struct ia_css_pipe_info info;
int pipe_index = atomisp_get_pipe_index(asd, source_pad);
@@ -2925,7 +2799,7 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd,
atomisp_source_pad_to_stream_id(asd, source_pad);
}
- if (IA_CSS_SUCCESS != ia_css_pipe_get_info(asd->stream_env[stream_index]
+ if (0 != ia_css_pipe_get_info(asd->stream_env[stream_index]
.pipes[pipe_index], &info)) {
dev_err(isp->dev, "ia_css_pipe_get_info FAILED");
return -EINVAL;
@@ -2978,11 +2852,11 @@ int atomisp_css_copy_configure_output(struct atomisp_sub_device *asd,
unsigned int stream_index,
unsigned int width, unsigned int height,
unsigned int padded_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
asd->stream_env[stream_index].pipe_configs[IA_CSS_PIPE_ID_COPY].
default_capture_config.mode =
- CSS_CAPTURE_MODE_RAW;
+ IA_CSS_CAPTURE_MODE_RAW;
__configure_output(asd, stream_index, width, height, padded_width,
format, IA_CSS_PIPE_ID_COPY);
@@ -2993,11 +2867,11 @@ int atomisp_css_yuvpp_configure_output(struct atomisp_sub_device *asd,
unsigned int stream_index,
unsigned int width, unsigned int height,
unsigned int padded_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
asd->stream_env[stream_index].pipe_configs[IA_CSS_PIPE_ID_YUVPP].
default_capture_config.mode =
- CSS_CAPTURE_MODE_RAW;
+ IA_CSS_CAPTURE_MODE_RAW;
__configure_output(asd, stream_index, width, height, padded_width,
format, IA_CSS_PIPE_ID_YUVPP);
@@ -3009,7 +2883,7 @@ int atomisp_css_yuvpp_configure_viewfinder(
unsigned int stream_index,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
struct atomisp_stream_env *stream_env =
&asd->stream_env[stream_index];
@@ -3030,7 +2904,7 @@ int atomisp_css_yuvpp_configure_viewfinder(
int atomisp_css_yuvpp_get_output_frame_info(
struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
return __get_frame_info(asd, stream_index, info,
ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_YUVPP);
@@ -3039,7 +2913,7 @@ int atomisp_css_yuvpp_get_output_frame_info(
int atomisp_css_yuvpp_get_viewfinder_frame_info(
struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
return __get_frame_info(asd, stream_index, info,
ATOMISP_CSS_VF_FRAME, IA_CSS_PIPE_ID_YUVPP);
@@ -3048,7 +2922,7 @@ int atomisp_css_yuvpp_get_viewfinder_frame_info(
int atomisp_css_preview_configure_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
/*
* to SOC camera, use yuvpp pipe.
@@ -3066,7 +2940,7 @@ int atomisp_css_preview_configure_output(struct atomisp_sub_device *asd,
int atomisp_css_capture_configure_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
enum ia_css_pipe_id pipe_id;
@@ -3086,7 +2960,7 @@ int atomisp_css_capture_configure_output(struct atomisp_sub_device *asd,
int atomisp_css_video_configure_output(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
/*
* to SOC camera, use yuvpp pipe.
@@ -3105,7 +2979,7 @@ int atomisp_css_video_configure_viewfinder(
struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
/*
* to SOC camera, video will use yuvpp pipe.
@@ -3123,7 +2997,7 @@ int atomisp_css_capture_configure_viewfinder(
struct atomisp_sub_device *asd,
unsigned int width, unsigned int height,
unsigned int min_width,
- enum atomisp_css_frame_format format)
+ enum ia_css_frame_format format)
{
enum ia_css_pipe_id pipe_id;
@@ -3142,7 +3016,7 @@ int atomisp_css_capture_configure_viewfinder(
int atomisp_css_video_get_viewfinder_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
enum ia_css_pipe_id pipe_id;
enum frame_info_type frame_type = ATOMISP_CSS_VF_FRAME;
@@ -3161,7 +3035,7 @@ int atomisp_css_video_get_viewfinder_frame_info(
int atomisp_css_capture_get_viewfinder_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
enum ia_css_pipe_id pipe_id;
@@ -3176,7 +3050,7 @@ int atomisp_css_capture_get_viewfinder_frame_info(
int atomisp_css_capture_get_output_raw_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
if (ATOMISP_USE_YUVPP(asd))
return 0;
@@ -3188,7 +3062,7 @@ int atomisp_css_capture_get_output_raw_frame_info(
int atomisp_css_copy_get_output_frame_info(
struct atomisp_sub_device *asd,
unsigned int stream_index,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
return __get_frame_info(asd, stream_index, info,
ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_COPY);
@@ -3196,7 +3070,7 @@ int atomisp_css_copy_get_output_frame_info(
int atomisp_css_preview_get_output_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
enum ia_css_pipe_id pipe_id;
enum frame_info_type frame_type = ATOMISP_CSS_OUTPUT_FRAME;
@@ -3215,7 +3089,7 @@ int atomisp_css_preview_get_output_frame_info(
int atomisp_css_capture_get_output_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
enum ia_css_pipe_id pipe_id;
@@ -3230,7 +3104,7 @@ int atomisp_css_capture_get_output_frame_info(
int atomisp_css_video_get_output_frame_info(
struct atomisp_sub_device *asd,
- struct atomisp_css_frame_info *info)
+ struct ia_css_frame_info *info)
{
enum ia_css_pipe_id pipe_id;
enum frame_info_type frame_type = ATOMISP_CSS_OUTPUT_FRAME;
@@ -3297,7 +3171,7 @@ int atomisp_css_video_configure_pp_input(
int atomisp_css_offline_capture_configure(struct atomisp_sub_device *asd,
int num_captures, unsigned int skip, int offset)
{
- enum ia_css_err ret;
+ int ret;
dev_dbg(asd->isp->dev, "%s num_capture:%d skip:%d offset:%d\n",
__func__, num_captures, skip, offset);
@@ -3305,7 +3179,7 @@ int atomisp_css_offline_capture_configure(struct atomisp_sub_device *asd,
ret = ia_css_stream_capture(
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
num_captures, skip, offset);
- if (ret != IA_CSS_SUCCESS)
+ if (ret)
return -EINVAL;
return 0;
@@ -3313,15 +3187,15 @@ int atomisp_css_offline_capture_configure(struct atomisp_sub_device *asd,
int atomisp_css_exp_id_capture(struct atomisp_sub_device *asd, int exp_id)
{
- enum ia_css_err ret;
+ int ret;
ret = ia_css_stream_capture_frame(
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
exp_id);
- if (ret == IA_CSS_ERR_QUEUE_IS_FULL) {
+ if (ret == -ENOBUFS) {
/* capture cmd queue is full */
return -EBUSY;
- } else if (ret != IA_CSS_SUCCESS) {
+ } else if (ret) {
return -EIO;
}
@@ -3330,14 +3204,14 @@ int atomisp_css_exp_id_capture(struct atomisp_sub_device *asd, int exp_id)
int atomisp_css_exp_id_unlock(struct atomisp_sub_device *asd, int exp_id)
{
- enum ia_css_err ret;
+ int ret;
ret = ia_css_unlock_raw_frame(
asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
exp_id);
- if (ret == IA_CSS_ERR_QUEUE_IS_FULL)
+ if (ret == -ENOBUFS)
return -EAGAIN;
- else if (ret != IA_CSS_SUCCESS)
+ else if (ret)
return -EIO;
return 0;
@@ -3356,201 +3230,8 @@ int atomisp_css_capture_enable_xnr(struct atomisp_sub_device *asd,
return 0;
}
-void atomisp_css_send_input_frame(struct atomisp_sub_device *asd,
- unsigned short *data, unsigned int width,
- unsigned int height)
-{
- ia_css_stream_send_input_frame(
- asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
- data, width, height);
-}
-
-bool atomisp_css_isp_has_started(void)
-{
- return ia_css_isp_has_started();
-}
-
-void atomisp_css_request_flash(struct atomisp_sub_device *asd)
-{
- ia_css_stream_request_flash(
- asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream);
-}
-
-void atomisp_css_set_wb_config(struct atomisp_sub_device *asd,
- struct atomisp_css_wb_config *wb_config)
-{
- asd->params.config.wb_config = wb_config;
-}
-
-void atomisp_css_set_ob_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ob_config *ob_config)
-{
- asd->params.config.ob_config = ob_config;
-}
-
-void atomisp_css_set_dp_config(struct atomisp_sub_device *asd,
- struct atomisp_css_dp_config *dp_config)
-{
- asd->params.config.dp_config = dp_config;
-}
-
-void atomisp_css_set_de_config(struct atomisp_sub_device *asd,
- struct atomisp_css_de_config *de_config)
-{
- asd->params.config.de_config = de_config;
-}
-
-void atomisp_css_set_dz_config(struct atomisp_sub_device *asd,
- struct atomisp_css_dz_config *dz_config)
-{
- asd->params.config.dz_config = dz_config;
-}
-
-void atomisp_css_set_default_de_config(struct atomisp_sub_device *asd)
-{
- asd->params.config.de_config = NULL;
-}
-
-void atomisp_css_set_ce_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ce_config *ce_config)
-{
- asd->params.config.ce_config = ce_config;
-}
-
-void atomisp_css_set_nr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_nr_config *nr_config)
-{
- asd->params.config.nr_config = nr_config;
-}
-
-void atomisp_css_set_ee_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ee_config *ee_config)
-{
- asd->params.config.ee_config = ee_config;
-}
-
-void atomisp_css_set_tnr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_tnr_config *tnr_config)
-{
- asd->params.config.tnr_config = tnr_config;
-}
-
-void atomisp_css_set_cc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cc_config *cc_config)
-{
- asd->params.config.cc_config = cc_config;
-}
-
-void atomisp_css_set_macc_table(struct atomisp_sub_device *asd,
- struct atomisp_css_macc_table *macc_table)
-{
- asd->params.config.macc_table = macc_table;
-}
-
-void atomisp_css_set_macc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_macc_config *macc_config)
-{
- asd->params.config.macc_config = macc_config;
-}
-
-void atomisp_css_set_ecd_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ecd_config *ecd_config)
-{
- asd->params.config.ecd_config = ecd_config;
-}
-
-void atomisp_css_set_ynr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ynr_config *ynr_config)
-{
- asd->params.config.ynr_config = ynr_config;
-}
-
-void atomisp_css_set_fc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_fc_config *fc_config)
-{
- asd->params.config.fc_config = fc_config;
-}
-
-void atomisp_css_set_ctc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ctc_config *ctc_config)
-{
- asd->params.config.ctc_config = ctc_config;
-}
-
-void atomisp_css_set_cnr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cnr_config *cnr_config)
-{
- asd->params.config.cnr_config = cnr_config;
-}
-
-void atomisp_css_set_aa_config(struct atomisp_sub_device *asd,
- struct atomisp_css_aa_config *aa_config)
-{
- asd->params.config.aa_config = aa_config;
-}
-
-void atomisp_css_set_baa_config(struct atomisp_sub_device *asd,
- struct atomisp_css_baa_config *baa_config)
-{
- asd->params.config.baa_config = baa_config;
-}
-
-void atomisp_css_set_anr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_anr_config *anr_config)
-{
- asd->params.config.anr_config = anr_config;
-}
-
-void atomisp_css_set_xnr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_xnr_config *xnr_config)
-{
- asd->params.config.xnr_config = xnr_config;
-}
-
-void atomisp_css_set_yuv2rgb_cc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cc_config *yuv2rgb_cc_config)
-{
- asd->params.config.yuv2rgb_cc_config = yuv2rgb_cc_config;
-}
-
-void atomisp_css_set_rgb2yuv_cc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cc_config *rgb2yuv_cc_config)
-{
- asd->params.config.rgb2yuv_cc_config = rgb2yuv_cc_config;
-}
-
-void atomisp_css_set_xnr_table(struct atomisp_sub_device *asd,
- struct atomisp_css_xnr_table *xnr_table)
-{
- asd->params.config.xnr_table = xnr_table;
-}
-
-void atomisp_css_set_r_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_rgb_gamma_table *r_gamma_table)
-{
- asd->params.config.r_gamma_table = r_gamma_table;
-}
-
-void atomisp_css_set_g_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_rgb_gamma_table *g_gamma_table)
-{
- asd->params.config.g_gamma_table = g_gamma_table;
-}
-
-void atomisp_css_set_b_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_rgb_gamma_table *b_gamma_table)
-{
- asd->params.config.b_gamma_table = b_gamma_table;
-}
-
-void atomisp_css_set_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_gamma_table *gamma_table)
-{
- asd->params.config.gamma_table = gamma_table;
-}
-
void atomisp_css_set_ctc_table(struct atomisp_sub_device *asd,
- struct atomisp_css_ctc_table *ctc_table)
+ struct ia_css_ctc_table *ctc_table)
{
int i;
u16 *vamem_ptr = ctc_table->data.vamem_1;
@@ -3577,29 +3258,17 @@ void atomisp_css_set_ctc_table(struct atomisp_sub_device *asd,
}
void atomisp_css_set_anr_thres(struct atomisp_sub_device *asd,
- struct atomisp_css_anr_thres *anr_thres)
+ struct ia_css_anr_thres *anr_thres)
{
asd->params.config.anr_thres = anr_thres;
}
void atomisp_css_set_dvs_6axis(struct atomisp_sub_device *asd,
- struct atomisp_css_dvs_6axis *dvs_6axis)
+ struct ia_css_dvs_6axis_config *dvs_6axis)
{
asd->params.config.dvs_6axis_config = dvs_6axis;
}
-void atomisp_css_set_gc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_gc_config *gc_config)
-{
- asd->params.config.gc_config = gc_config;
-}
-
-void atomisp_css_set_3a_config(struct atomisp_sub_device *asd,
- struct atomisp_css_3a_config *s3a_config)
-{
- asd->params.config.s3a_config = s3a_config;
-}
-
void atomisp_css_video_set_dis_vector(struct atomisp_sub_device *asd,
struct atomisp_dis_vector *vector)
{
@@ -3615,7 +3284,7 @@ void atomisp_css_video_set_dis_vector(struct atomisp_sub_device *asd,
static int atomisp_compare_dvs_grid(struct atomisp_sub_device *asd,
struct atomisp_dvs_grid_info *atomgrid)
{
- struct atomisp_css_dvs_grid_info *cur =
+ struct ia_css_dvs_grid_info *cur =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
if (!cur) {
@@ -3696,8 +3365,8 @@ int atomisp_css_set_dis_coefs(struct atomisp_sub_device *asd,
return -EFAULT;
asd->params.css_param.update_flag.dvs2_coefs =
- (struct atomisp_dvs2_coefficients *)
- asd->params.css_param.dvs2_coeff;
+ (struct atomisp_dis_coefficients *)
+ asd->params.css_param.dvs2_coeff;
/* FIXME! */
/* asd->params.dis_proj_data_valid = false; */
asd->params.css_update_params_needed = true;
@@ -3727,7 +3396,7 @@ void atomisp_css_set_zoom_factor(struct atomisp_sub_device *asd,
}
void atomisp_css_set_formats_config(struct atomisp_sub_device *asd,
- struct atomisp_css_formats_config *formats_config)
+ struct ia_css_formats_config *formats_config)
{
asd->params.config.formats_config = formats_config;
}
@@ -3735,7 +3404,7 @@ void atomisp_css_set_formats_config(struct atomisp_sub_device *asd,
int atomisp_css_get_wb_config(struct atomisp_sub_device *asd,
struct atomisp_wb_config *config)
{
- struct atomisp_css_wb_config wb_config;
+ struct ia_css_wb_config wb_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3744,7 +3413,7 @@ int atomisp_css_get_wb_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&wb_config, 0, sizeof(struct atomisp_css_wb_config));
+ memset(&wb_config, 0, sizeof(struct ia_css_wb_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.wb_config = &wb_config;
ia_css_stream_get_isp_config(
@@ -3758,7 +3427,7 @@ int atomisp_css_get_wb_config(struct atomisp_sub_device *asd,
int atomisp_css_get_ob_config(struct atomisp_sub_device *asd,
struct atomisp_ob_config *config)
{
- struct atomisp_css_ob_config ob_config;
+ struct ia_css_ob_config ob_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3767,7 +3436,7 @@ int atomisp_css_get_ob_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&ob_config, 0, sizeof(struct atomisp_css_ob_config));
+ memset(&ob_config, 0, sizeof(struct ia_css_ob_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.ob_config = &ob_config;
ia_css_stream_get_isp_config(
@@ -3781,7 +3450,7 @@ int atomisp_css_get_ob_config(struct atomisp_sub_device *asd,
int atomisp_css_get_dp_config(struct atomisp_sub_device *asd,
struct atomisp_dp_config *config)
{
- struct atomisp_css_dp_config dp_config;
+ struct ia_css_dp_config dp_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3790,7 +3459,7 @@ int atomisp_css_get_dp_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&dp_config, 0, sizeof(struct atomisp_css_dp_config));
+ memset(&dp_config, 0, sizeof(struct ia_css_dp_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.dp_config = &dp_config;
ia_css_stream_get_isp_config(
@@ -3804,7 +3473,7 @@ int atomisp_css_get_dp_config(struct atomisp_sub_device *asd,
int atomisp_css_get_de_config(struct atomisp_sub_device *asd,
struct atomisp_de_config *config)
{
- struct atomisp_css_de_config de_config;
+ struct ia_css_de_config de_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3813,7 +3482,7 @@ int atomisp_css_get_de_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&de_config, 0, sizeof(struct atomisp_css_de_config));
+ memset(&de_config, 0, sizeof(struct ia_css_de_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.de_config = &de_config;
ia_css_stream_get_isp_config(
@@ -3827,7 +3496,7 @@ int atomisp_css_get_de_config(struct atomisp_sub_device *asd,
int atomisp_css_get_nr_config(struct atomisp_sub_device *asd,
struct atomisp_nr_config *config)
{
- struct atomisp_css_nr_config nr_config;
+ struct ia_css_nr_config nr_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3836,7 +3505,7 @@ int atomisp_css_get_nr_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&nr_config, 0, sizeof(struct atomisp_css_nr_config));
+ memset(&nr_config, 0, sizeof(struct ia_css_nr_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.nr_config = &nr_config;
@@ -3851,7 +3520,7 @@ int atomisp_css_get_nr_config(struct atomisp_sub_device *asd,
int atomisp_css_get_ee_config(struct atomisp_sub_device *asd,
struct atomisp_ee_config *config)
{
- struct atomisp_css_ee_config ee_config;
+ struct ia_css_ee_config ee_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3860,7 +3529,7 @@ int atomisp_css_get_ee_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&ee_config, 0, sizeof(struct atomisp_css_ee_config));
+ memset(&ee_config, 0, sizeof(struct ia_css_ee_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.ee_config = &ee_config;
ia_css_stream_get_isp_config(
@@ -3874,7 +3543,7 @@ int atomisp_css_get_ee_config(struct atomisp_sub_device *asd,
int atomisp_css_get_tnr_config(struct atomisp_sub_device *asd,
struct atomisp_tnr_config *config)
{
- struct atomisp_css_tnr_config tnr_config;
+ struct ia_css_tnr_config tnr_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3883,7 +3552,7 @@ int atomisp_css_get_tnr_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&tnr_config, 0, sizeof(struct atomisp_css_tnr_config));
+ memset(&tnr_config, 0, sizeof(struct ia_css_tnr_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.tnr_config = &tnr_config;
ia_css_stream_get_isp_config(
@@ -3897,7 +3566,7 @@ int atomisp_css_get_tnr_config(struct atomisp_sub_device *asd,
int atomisp_css_get_ctc_table(struct atomisp_sub_device *asd,
struct atomisp_ctc_table *config)
{
- struct atomisp_css_ctc_table *tab;
+ struct ia_css_ctc_table *tab;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3907,7 +3576,7 @@ int atomisp_css_get_ctc_table(struct atomisp_sub_device *asd,
return -EINVAL;
}
- tab = vzalloc(sizeof(struct atomisp_css_ctc_table));
+ tab = vzalloc(sizeof(struct ia_css_ctc_table));
if (!tab)
return -ENOMEM;
@@ -3925,7 +3594,7 @@ int atomisp_css_get_ctc_table(struct atomisp_sub_device *asd,
int atomisp_css_get_gamma_table(struct atomisp_sub_device *asd,
struct atomisp_gamma_table *config)
{
- struct atomisp_css_gamma_table *tab;
+ struct ia_css_gamma_table *tab;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3935,7 +3604,7 @@ int atomisp_css_get_gamma_table(struct atomisp_sub_device *asd,
return -EINVAL;
}
- tab = vzalloc(sizeof(struct atomisp_css_gamma_table));
+ tab = vzalloc(sizeof(struct ia_css_gamma_table));
if (!tab)
return -ENOMEM;
@@ -3953,7 +3622,7 @@ int atomisp_css_get_gamma_table(struct atomisp_sub_device *asd,
int atomisp_css_get_gc_config(struct atomisp_sub_device *asd,
struct atomisp_gc_config *config)
{
- struct atomisp_css_gc_config gc_config;
+ struct ia_css_gc_config gc_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3962,7 +3631,7 @@ int atomisp_css_get_gc_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&gc_config, 0, sizeof(struct atomisp_css_gc_config));
+ memset(&gc_config, 0, sizeof(struct ia_css_gc_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.gc_config = &gc_config;
ia_css_stream_get_isp_config(
@@ -3977,7 +3646,7 @@ int atomisp_css_get_gc_config(struct atomisp_sub_device *asd,
int atomisp_css_get_3a_config(struct atomisp_sub_device *asd,
struct atomisp_3a_config *config)
{
- struct atomisp_css_3a_config s3a_config;
+ struct ia_css_3a_config s3a_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -3986,7 +3655,7 @@ int atomisp_css_get_3a_config(struct atomisp_sub_device *asd,
__func__);
return -EINVAL;
}
- memset(&s3a_config, 0, sizeof(struct atomisp_css_3a_config));
+ memset(&s3a_config, 0, sizeof(struct ia_css_3a_config));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.s3a_config = &s3a_config;
ia_css_stream_get_isp_config(
@@ -4001,7 +3670,7 @@ int atomisp_css_get_3a_config(struct atomisp_sub_device *asd,
int atomisp_css_get_formats_config(struct atomisp_sub_device *asd,
struct atomisp_formats_config *config)
{
- struct atomisp_css_formats_config formats_config;
+ struct ia_css_formats_config formats_config;
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -4139,37 +3808,37 @@ int atomisp_css_get_dis_stat(struct atomisp_sub_device *asd,
return 0;
}
-struct atomisp_css_shading_table *atomisp_css_shading_table_alloc(
+struct ia_css_shading_table *atomisp_css_shading_table_alloc(
unsigned int width, unsigned int height)
{
return ia_css_shading_table_alloc(width, height);
}
void atomisp_css_set_shading_table(struct atomisp_sub_device *asd,
- struct atomisp_css_shading_table *table)
+ struct ia_css_shading_table *table)
{
asd->params.config.shading_table = table;
}
-void atomisp_css_shading_table_free(struct atomisp_css_shading_table *table)
+void atomisp_css_shading_table_free(struct ia_css_shading_table *table)
{
ia_css_shading_table_free(table);
}
-struct atomisp_css_morph_table *atomisp_css_morph_table_allocate(
+struct ia_css_morph_table *atomisp_css_morph_table_allocate(
unsigned int width, unsigned int height)
{
return ia_css_morph_table_allocate(width, height);
}
void atomisp_css_set_morph_table(struct atomisp_sub_device *asd,
- struct atomisp_css_morph_table *table)
+ struct ia_css_morph_table *table)
{
asd->params.config.morph_table = table;
}
void atomisp_css_get_morph_table(struct atomisp_sub_device *asd,
- struct atomisp_css_morph_table *table)
+ struct ia_css_morph_table *table)
{
struct ia_css_isp_config isp_config;
struct atomisp_device *isp = asd->isp;
@@ -4179,7 +3848,7 @@ void atomisp_css_get_morph_table(struct atomisp_sub_device *asd,
"%s called after streamoff, skipping.\n", __func__);
return;
}
- memset(table, 0, sizeof(struct atomisp_css_morph_table));
+ memset(table, 0, sizeof(struct ia_css_morph_table));
memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
isp_config.morph_table = table;
ia_css_stream_get_isp_config(
@@ -4187,7 +3856,7 @@ void atomisp_css_get_morph_table(struct atomisp_sub_device *asd,
&isp_config);
}
-void atomisp_css_morph_table_free(struct atomisp_css_morph_table *table)
+void atomisp_css_morph_table_free(struct ia_css_morph_table *table)
{
ia_css_morph_table_free(table);
}
@@ -4215,8 +3884,8 @@ int atomisp_css_wait_acc_finish(struct atomisp_sub_device *asd)
if (wait_for_completion_interruptible_timeout(&asd->acc.acc_done,
ATOMISP_ISP_TIMEOUT_DURATION) == 0) {
dev_err(isp->dev, "<%s: completion timeout\n", __func__);
- atomisp_css_debug_dump_sp_sw_debug_info();
- atomisp_css_debug_dump_debug_info(__func__);
+ ia_css_debug_dump_sp_sw_debug_info();
+ ia_css_debug_dump_debug_info(__func__);
ret = -EIO;
}
rt_mutex_lock(&isp->mutex);
@@ -4244,11 +3913,11 @@ int atomisp_css_set_acc_parameters(struct atomisp_acc_fw *acc_fw)
/* Load acc binary extension */
int atomisp_css_load_acc_extension(struct atomisp_sub_device *asd,
- struct atomisp_css_fw_info *fw,
- enum atomisp_css_pipe_id pipe_id,
+ struct ia_css_fw_info *fw,
+ enum ia_css_pipe_id pipe_id,
unsigned int type)
{
- struct atomisp_css_fw_info **hd;
+ struct ia_css_fw_info **hd;
fw->next = NULL;
hd = &(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
@@ -4264,10 +3933,10 @@ int atomisp_css_load_acc_extension(struct atomisp_sub_device *asd,
/* Unload acc binary extension */
void atomisp_css_unload_acc_extension(struct atomisp_sub_device *asd,
- struct atomisp_css_fw_info *fw,
- enum atomisp_css_pipe_id pipe_id)
+ struct ia_css_fw_info *fw,
+ enum ia_css_pipe_id pipe_id)
{
- struct atomisp_css_fw_info **hd;
+ struct ia_css_fw_info **hd;
hd = &(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
.pipe_configs[pipe_id].acc_extension);
@@ -4294,21 +3963,21 @@ int atomisp_css_create_acc_pipe(struct atomisp_sub_device *asd)
if (stream_env->acc_stream) {
if (stream_env->acc_stream_state == CSS_STREAM_STARTED) {
if (ia_css_stream_stop(stream_env->acc_stream)
- != IA_CSS_SUCCESS) {
+ != 0) {
dev_err(isp->dev, "stop acc_stream failed.\n");
return -EBUSY;
}
}
if (ia_css_stream_destroy(stream_env->acc_stream)
- != IA_CSS_SUCCESS) {
+ != 0) {
dev_err(isp->dev, "destroy acc_stream failed.\n");
return -EBUSY;
}
stream_env->acc_stream = NULL;
}
- pipe_config = &stream_env->pipe_configs[CSS_PIPE_ID_ACC];
+ pipe_config = &stream_env->pipe_configs[IA_CSS_PIPE_ID_ACC];
ia_css_pipe_config_defaults(pipe_config);
asd->acc.acc_stages = kzalloc(MAX_ACC_STAGES *
sizeof(void *), GFP_KERNEL);
@@ -4335,7 +4004,7 @@ int atomisp_css_start_acc_pipe(struct atomisp_sub_device *asd)
&stream_env->pipe_configs[IA_CSS_PIPE_ID_ACC];
if (ia_css_pipe_create(pipe_config,
- &stream_env->pipes[IA_CSS_PIPE_ID_ACC]) != IA_CSS_SUCCESS) {
+ &stream_env->pipes[IA_CSS_PIPE_ID_ACC]) != 0) {
dev_err(isp->dev, "%s: ia_css_pipe_create failed\n",
__func__);
return -EBADE;
@@ -4345,7 +4014,7 @@ int atomisp_css_start_acc_pipe(struct atomisp_sub_device *asd)
sizeof(struct ia_css_stream_config));
if (ia_css_stream_create(&stream_env->acc_stream_config, 1,
&stream_env->pipes[IA_CSS_PIPE_ID_ACC],
- &stream_env->acc_stream) != IA_CSS_SUCCESS) {
+ &stream_env->acc_stream) != 0) {
dev_err(isp->dev, "%s: create acc_stream error.\n", __func__);
return -EINVAL;
}
@@ -4356,13 +4025,13 @@ int atomisp_css_start_acc_pipe(struct atomisp_sub_device *asd)
atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false);
- if (ia_css_start_sp() != IA_CSS_SUCCESS) {
+ if (ia_css_start_sp()) {
dev_err(isp->dev, "start sp error.\n");
return -EIO;
}
if (ia_css_stream_start(stream_env->acc_stream)
- != IA_CSS_SUCCESS) {
+ != 0) {
dev_err(isp->dev, "acc_stream start error.\n");
return -EIO;
}
@@ -4388,7 +4057,7 @@ void atomisp_css_destroy_acc_pipe(struct atomisp_sub_device *asd)
&asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
if (stream_env->acc_stream) {
if (ia_css_stream_destroy(stream_env->acc_stream)
- != IA_CSS_SUCCESS)
+ != 0)
dev_warn(asd->isp->dev,
"destroy acc_stream failed.\n");
stream_env->acc_stream = NULL;
@@ -4396,7 +4065,7 @@ void atomisp_css_destroy_acc_pipe(struct atomisp_sub_device *asd)
if (stream_env->pipes[IA_CSS_PIPE_ID_ACC]) {
if (ia_css_pipe_destroy(stream_env->pipes[IA_CSS_PIPE_ID_ACC])
- != IA_CSS_SUCCESS)
+ != 0)
dev_warn(asd->isp->dev,
"destroy ACC pipe failed.\n");
stream_env->pipes[IA_CSS_PIPE_ID_ACC] = NULL;
@@ -4420,7 +4089,7 @@ void atomisp_css_destroy_acc_pipe(struct atomisp_sub_device *asd)
}
int atomisp_css_load_acc_binary(struct atomisp_sub_device *asd,
- struct atomisp_css_fw_info *fw,
+ struct ia_css_fw_info *fw,
unsigned int index)
{
struct ia_css_pipe_config *pipe_config =
@@ -4494,7 +4163,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
for (i = 0; i < isp->num_of_streams; i++)
atomisp_wdt_stop(&isp->asd[i], 0);
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
atomisp_wdt(&isp->asd[0].wdt);
else
queue_work(isp->wdt_work_queue, &isp->wdt_work);
@@ -4510,7 +4179,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
asd = __get_atomisp_subdev(current_event.event.pipe,
isp, &stream_id);
if (!asd) {
- if (current_event.event.type == CSS_EVENT_TIMER)
+ if (current_event.event.type == IA_CSS_EVENT_TYPE_TIMER)
dev_dbg(isp->dev,
"event: Timer event.");
else
@@ -4522,63 +4191,72 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
atomisp_css_temp_pipe_to_pipe_id(asd, &current_event);
switch (current_event.event.type) {
- case CSS_EVENT_OUTPUT_FRAME_DONE:
+ case IA_CSS_EVENT_TYPE_OUTPUT_FRAME_DONE:
+ dev_dbg(isp->dev, "event: Output frame done");
frame_done_found[asd->index] = true;
- atomisp_buf_done(asd, 0, CSS_BUFFER_TYPE_OUTPUT_FRAME,
+ atomisp_buf_done(asd, 0, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME,
current_event.pipe, true, stream_id);
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
reset_wdt_timer[asd->index] = true; /* ISP running */
break;
- case CSS_EVENT_SEC_OUTPUT_FRAME_DONE:
+ case IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE:
+ dev_dbg(isp->dev, "event: Second output frame done");
frame_done_found[asd->index] = true;
- atomisp_buf_done(asd, 0, CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME,
+ atomisp_buf_done(asd, 0, IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME,
current_event.pipe, true, stream_id);
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
reset_wdt_timer[asd->index] = true; /* ISP running */
break;
- case CSS_EVENT_3A_STATISTICS_DONE:
+ case IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE:
+ dev_dbg(isp->dev, "event: 3A stats frame done");
atomisp_buf_done(asd, 0,
- CSS_BUFFER_TYPE_3A_STATISTICS,
+ IA_CSS_BUFFER_TYPE_3A_STATISTICS,
current_event.pipe,
false, stream_id);
break;
- case CSS_EVENT_METADATA_DONE:
+ case IA_CSS_EVENT_TYPE_METADATA_DONE:
+ dev_dbg(isp->dev, "event: metadata frame done");
atomisp_buf_done(asd, 0,
- CSS_BUFFER_TYPE_METADATA,
+ IA_CSS_BUFFER_TYPE_METADATA,
current_event.pipe,
false, stream_id);
break;
- case CSS_EVENT_VF_OUTPUT_FRAME_DONE:
+ case IA_CSS_EVENT_TYPE_VF_OUTPUT_FRAME_DONE:
+ dev_dbg(isp->dev, "event: VF output frame done");
atomisp_buf_done(asd, 0,
- CSS_BUFFER_TYPE_VF_OUTPUT_FRAME,
+ IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME,
current_event.pipe, true, stream_id);
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
reset_wdt_timer[asd->index] = true; /* ISP running */
break;
- case CSS_EVENT_SEC_VF_OUTPUT_FRAME_DONE:
+ case IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE:
+ dev_dbg(isp->dev, "event: second VF output frame done");
atomisp_buf_done(asd, 0,
- CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME,
+ IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME,
current_event.pipe, true, stream_id);
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
reset_wdt_timer[asd->index] = true; /* ISP running */
break;
- case CSS_EVENT_DIS_STATISTICS_DONE:
+ case IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE:
+ dev_dbg(isp->dev, "event: dis stats frame done");
atomisp_buf_done(asd, 0,
- CSS_BUFFER_TYPE_DIS_STATISTICS,
+ IA_CSS_BUFFER_TYPE_DIS_STATISTICS,
current_event.pipe,
false, stream_id);
break;
- case CSS_EVENT_PIPELINE_DONE:
+ case IA_CSS_EVENT_TYPE_PIPELINE_DONE:
+ dev_dbg(isp->dev, "event: pipeline done");
css_pipe_done[asd->index] = true;
break;
- case CSS_EVENT_ACC_STAGE_COMPLETE:
+ case IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE:
+ dev_dbg(isp->dev, "event: acc stage done");
atomisp_acc_done(asd, current_event.event.fw_handle);
break;
default:
@@ -4588,7 +4266,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
}
}
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
return 0;
/* ISP2400: If there are no buffers queued then delete wdt timer. */
@@ -4618,8 +4296,13 @@ bool atomisp_css_valid_sof(struct atomisp_device *isp)
struct atomisp_sub_device *asd = &isp->asd[i];
/* Loop for each css vc stream */
for (j = 0; j < ATOMISP_INPUT_STREAM_NUM; j++) {
- if (asd->stream_env[j].stream &&
- asd->stream_env[j].stream_config.mode ==
+ if (!asd->stream_env[j].stream)
+ continue;
+
+ dev_dbg(isp->dev,
+ "stream #%d: mode: %d\n", j,
+ asd->stream_env[j].stream_config.mode);
+ if (asd->stream_env[j].stream_config.mode ==
IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
return false;
}
@@ -4640,6 +4323,20 @@ int atomisp_css_dump_sp_raw_copy_linecount(bool reduced)
return 0;
}
+static const char * const fw_type_name[] = {
+ [ia_css_sp_firmware] = "SP",
+ [ia_css_isp_firmware] = "ISP",
+ [ia_css_bootloader_firmware] = "BootLoader",
+ [ia_css_acc_firmware] = "accel",
+};
+
+static const char * const fw_acc_type_name[] = {
+ [IA_CSS_ACC_NONE] = "Normal",
+ [IA_CSS_ACC_OUTPUT] = "Accel stage on output",
+ [IA_CSS_ACC_VIEWFINDER] = "Accel stage on viewfinder",
+ [IA_CSS_ACC_STANDALONE] = "Stand-alone acceleration",
+};
+
int atomisp_css_dump_blob_infor(void)
{
struct ia_css_blob_descr *bd = sh_css_blob_info;
@@ -4650,9 +4347,28 @@ int atomisp_css_dump_blob_infor(void)
if (!bd)
return -EPERM;
- for (i = 1; i < sh_css_num_binaries; i++)
- dev_dbg(atomisp_dev, "Num%d binary id is %d, name is %s\n", i,
- bd[i - 1].header.info.isp.sp.id, bd[i - 1].name);
+ /*
+ * The sh_css_load_firmware function discard the initial
+ * "SPS" binaries
+ */
+ for (i = 0; i < sh_css_num_binaries - NUM_OF_SPS; i++) {
+ switch (bd[i].header.type) {
+ case ia_css_isp_firmware:
+ dev_dbg(atomisp_dev,
+ "Num%2d type %s (%s), binary id is %2d, name is %s\n",
+ i + NUM_OF_SPS,
+ fw_type_name[bd[i].header.type],
+ fw_acc_type_name[bd[i].header.info.isp.type],
+ bd[i].header.info.isp.sp.id,
+ bd[i].name);
+ break;
+ default:
+ dev_dbg(atomisp_dev,
+ "Num%2d type %s, name is %s\n",
+ i + NUM_OF_SPS, fw_type_name[bd[i].header.type],
+ bd[i].name);
+ }
+ }
return 0;
}
@@ -4664,7 +4380,7 @@ void atomisp_css_set_isp_config_id(struct atomisp_sub_device *asd,
}
void atomisp_css_set_isp_config_applied_frame(struct atomisp_sub_device *asd,
- struct atomisp_css_frame *output_frame)
+ struct ia_css_frame *output_frame)
{
asd->params.config.output_frame = output_frame;
}
@@ -4692,8 +4408,8 @@ void atomisp_en_dz_capt_pipe(struct atomisp_sub_device *asd, bool enable)
enable);
}
-struct atomisp_css_dvs_grid_info *atomisp_css_get_dvs_grid_info(
- struct atomisp_css_grid_info *grid_info)
+struct ia_css_dvs_grid_info *atomisp_css_get_dvs_grid_info(
+ struct ia_css_grid_info *grid_info)
{
if (!grid_info)
return NULL;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.h b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.h
index 7abd1ff35652..8376aec18e3e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Clovertrail PNW Camera Imaging ISP subsystem.
*
@@ -30,97 +31,6 @@
#define ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES_LOCK_EN 4
#define ATOMISP_CSS2_NUM_DVS_FRAME_DELAY 2
-#define atomisp_css_pipe_id ia_css_pipe_id
-#define atomisp_css_pipeline ia_css_pipe
-#define atomisp_css_buffer_type ia_css_buffer_type
-#define atomisp_css_dis_data ia_css_isp_dvs_statistics
-#define atomisp_css_irq_info ia_css_irq_info
-#define atomisp_css_isp_config ia_css_isp_config
-#define atomisp_css_bayer_order ia_css_bayer_order
-#define atomisp_css_capture_mode ia_css_capture_mode
-#define atomisp_css_input_mode ia_css_input_mode
-#define atomisp_css_frame ia_css_frame
-#define atomisp_css_frame_format ia_css_frame_format
-#define atomisp_css_frame_info ia_css_frame_info
-#define atomisp_css_dp_config ia_css_dp_config
-#define atomisp_css_wb_config ia_css_wb_config
-#define atomisp_css_cc_config ia_css_cc_config
-#define atomisp_css_nr_config ia_css_nr_config
-#define atomisp_css_ee_config ia_css_ee_config
-#define atomisp_css_ob_config ia_css_ob_config
-#define atomisp_css_de_config ia_css_de_config
-#define atomisp_css_dz_config ia_css_dz_config
-#define atomisp_css_ce_config ia_css_ce_config
-#define atomisp_css_gc_config ia_css_gc_config
-#define atomisp_css_tnr_config ia_css_tnr_config
-#define atomisp_css_cnr_config ia_css_cnr_config
-#define atomisp_css_ctc_config ia_css_ctc_config
-#define atomisp_css_3a_config ia_css_3a_config
-#define atomisp_css_ecd_config ia_css_ecd_config
-#define atomisp_css_ynr_config ia_css_ynr_config
-#define atomisp_css_fc_config ia_css_fc_config
-#define atomisp_css_aa_config ia_css_aa_config
-#define atomisp_css_baa_config ia_css_aa_config
-#define atomisp_css_anr_config ia_css_anr_config
-#define atomisp_css_xnr_config ia_css_xnr_config
-#define atomisp_css_macc_config ia_css_macc_config
-#define atomisp_css_gamma_table ia_css_gamma_table
-#define atomisp_css_ctc_table ia_css_ctc_table
-#define atomisp_css_macc_table ia_css_macc_table
-#define atomisp_css_xnr_table ia_css_xnr_table
-#define atomisp_css_rgb_gamma_table ia_css_rgb_gamma_table
-#define atomisp_css_anr_thres ia_css_anr_thres
-#define atomisp_css_dvs_6axis ia_css_dvs_6axis_config
-#define atomisp_css_grid_info ia_css_grid_info
-#define atomisp_css_3a_grid_info ia_css_3a_grid_info
-#define atomisp_css_dvs_grid_info ia_css_dvs_grid_info
-#define atomisp_css_shading_table ia_css_shading_table
-#define atomisp_css_morph_table ia_css_morph_table
-#define atomisp_css_dvs_6axis_config ia_css_dvs_6axis_config
-#define atomisp_css_fw_info ia_css_fw_info
-#define atomisp_css_formats_config ia_css_formats_config
-
-#define CSS_PIPE_ID_PREVIEW IA_CSS_PIPE_ID_PREVIEW
-#define CSS_PIPE_ID_COPY IA_CSS_PIPE_ID_COPY
-#define CSS_PIPE_ID_VIDEO IA_CSS_PIPE_ID_VIDEO
-#define CSS_PIPE_ID_CAPTURE IA_CSS_PIPE_ID_CAPTURE
-#define CSS_PIPE_ID_ACC IA_CSS_PIPE_ID_ACC
-#define CSS_PIPE_ID_YUVPP IA_CSS_PIPE_ID_YUVPP
-#define CSS_PIPE_ID_NUM IA_CSS_PIPE_ID_NUM
-
-#define CSS_INPUT_MODE_SENSOR IA_CSS_INPUT_MODE_BUFFERED_SENSOR
-#define CSS_INPUT_MODE_FIFO IA_CSS_INPUT_MODE_FIFO
-#define CSS_INPUT_MODE_TPG IA_CSS_INPUT_MODE_TPG
-#define CSS_INPUT_MODE_PRBS IA_CSS_INPUT_MODE_PRBS
-#define CSS_INPUT_MODE_MEMORY IA_CSS_INPUT_MODE_MEMORY
-
-#define CSS_IRQ_INFO_CSS_RECEIVER_ERROR IA_CSS_IRQ_INFO_CSS_RECEIVER_ERROR
-#define CSS_IRQ_INFO_EVENTS_READY IA_CSS_IRQ_INFO_EVENTS_READY
-#define CSS_IRQ_INFO_INPUT_SYSTEM_ERROR \
- IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR
-#define CSS_IRQ_INFO_IF_ERROR IA_CSS_IRQ_INFO_IF_ERROR
-
-#define CSS_BUFFER_TYPE_NUM IA_CSS_BUFFER_TYPE_NUM
-
-#define CSS_FRAME_FLASH_STATE_NONE IA_CSS_FRAME_FLASH_STATE_NONE
-#define CSS_FRAME_FLASH_STATE_PARTIAL IA_CSS_FRAME_FLASH_STATE_PARTIAL
-#define CSS_FRAME_FLASH_STATE_FULL IA_CSS_FRAME_FLASH_STATE_FULL
-
-#define CSS_BAYER_ORDER_GRBG IA_CSS_BAYER_ORDER_GRBG
-#define CSS_BAYER_ORDER_RGGB IA_CSS_BAYER_ORDER_RGGB
-#define CSS_BAYER_ORDER_BGGR IA_CSS_BAYER_ORDER_BGGR
-#define CSS_BAYER_ORDER_GBRG IA_CSS_BAYER_ORDER_GBRG
-
-/*
- * Hide IA_ naming difference in otherwise common CSS macros.
- */
-#define CSS_ID(val) (IA_ ## val)
-#define CSS_EVENT(val) (IA_CSS_EVENT_TYPE_ ## val)
-#define CSS_FORMAT(val) (ATOMISP_INPUT_FORMAT_ ## val)
-
-#define CSS_EVENT_PORT_EOF CSS_EVENT(PORT_EOF)
-#define CSS_EVENT_FRAME_TAGGED CSS_EVENT(FRAME_TAGGED)
-
#define CSS_MIPI_FRAME_BUFFER_SIZE_1 0x60000
#define CSS_MIPI_FRAME_BUFFER_SIZE_2 0x80000
@@ -181,7 +91,7 @@ struct atomisp_s3a_buf {
};
struct atomisp_dis_buf {
- struct atomisp_css_dis_data *dis_data;
+ struct ia_css_isp_dvs_statistics *dis_data;
struct ia_css_isp_dvs_statistics_map *dvs_map;
struct list_head list;
};
@@ -191,71 +101,53 @@ struct atomisp_css_buffer {
};
struct atomisp_css_event {
- enum atomisp_css_pipe_id pipe;
+ enum ia_css_pipe_id pipe;
struct ia_css_event event;
};
void atomisp_css_set_macc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_macc_config *macc_config);
+ struct ia_css_macc_config *macc_config);
void atomisp_css_set_ecd_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ecd_config *ecd_config);
+ struct ia_css_ecd_config *ecd_config);
void atomisp_css_set_ynr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ynr_config *ynr_config);
+ struct ia_css_ynr_config *ynr_config);
void atomisp_css_set_fc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_fc_config *fc_config);
+ struct ia_css_fc_config *fc_config);
void atomisp_css_set_aa_config(struct atomisp_sub_device *asd,
- struct atomisp_css_aa_config *aa_config);
+ struct ia_css_aa_config *aa_config);
void atomisp_css_set_baa_config(struct atomisp_sub_device *asd,
- struct atomisp_css_baa_config *baa_config);
+ struct ia_css_aa_config *baa_config);
void atomisp_css_set_anr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_anr_config *anr_config);
+ struct ia_css_anr_config *anr_config);
void atomisp_css_set_xnr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_xnr_config *xnr_config);
+ struct ia_css_xnr_config *xnr_config);
void atomisp_css_set_cnr_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cnr_config *cnr_config);
+ struct ia_css_cnr_config *cnr_config);
void atomisp_css_set_ctc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_ctc_config *ctc_config);
+ struct ia_css_ctc_config *ctc_config);
void atomisp_css_set_yuv2rgb_cc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cc_config *yuv2rgb_cc_config);
+ struct ia_css_cc_config *yuv2rgb_cc_config);
void atomisp_css_set_rgb2yuv_cc_config(struct atomisp_sub_device *asd,
- struct atomisp_css_cc_config *rgb2yuv_cc_config);
-
-void atomisp_css_set_xnr_table(struct atomisp_sub_device *asd,
- struct atomisp_css_xnr_table *xnr_table);
-
-void atomisp_css_set_r_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_rgb_gamma_table *r_gamma_table);
-
-void atomisp_css_set_g_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_rgb_gamma_table *g_gamma_table);
-
-void atomisp_css_set_b_gamma_table(struct atomisp_sub_device *asd,
- struct atomisp_css_rgb_gamma_table *b_gamma_table);
+ struct ia_css_cc_config *rgb2yuv_cc_config);
void atomisp_css_set_anr_thres(struct atomisp_sub_device *asd,
- struct atomisp_css_anr_thres *anr_thres);
-
-int atomisp_css_check_firmware_version(struct atomisp_device *isp);
+ struct ia_css_anr_thres *anr_thres);
int atomisp_css_load_firmware(struct atomisp_device *isp);
-void atomisp_css_unload_firmware(struct atomisp_device *isp);
-
void atomisp_css_set_dvs_6axis(struct atomisp_sub_device *asd,
- struct atomisp_css_dvs_6axis *dvs_6axis);
-
-unsigned int atomisp_css_debug_get_dtrace_level(void);
+ struct ia_css_dvs_6axis_config *dvs_6axis);
int atomisp_css_debug_dump_isp_binary(void);
@@ -267,11 +159,11 @@ void atomisp_css_set_isp_config_id(struct atomisp_sub_device *asd,
uint32_t isp_config_id);
void atomisp_css_set_isp_config_applied_frame(struct atomisp_sub_device *asd,
- struct atomisp_css_frame *output_frame);
+ struct ia_css_frame *output_frame);
int atomisp_get_css_dbgfunc(void);
int atomisp_set_css_dbgfunc(struct atomisp_device *isp, int opt);
-struct atomisp_css_dvs_grid_info *atomisp_css_get_dvs_grid_info(
- struct atomisp_css_grid_info *grid_info);
+struct ia_css_dvs_grid_info *atomisp_css_get_dvs_grid_info(
+ struct ia_css_grid_info *grid_info);
#endif
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
index 3079043f1fac..fa5918270614 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
*
@@ -24,66 +25,61 @@
#include "atomisp_ioctl.h"
#include "atomisp_compat_ioctl32.h"
-static int get_atomisp_histogram32(struct atomisp_histogram *kp,
+/* Macro borrowed from v4l2-compat-ioctl32.c */
+/* Use the same argument order as copy_in_user */
+#define assign_in_user(to, from) \
+({ \
+ typeof(*from) __assign_tmp; \
+ \
+ get_user(__assign_tmp, from) || put_user(__assign_tmp, to); \
+})
+
+
+static int get_atomisp_histogram32(struct atomisp_histogram __user *kp,
struct atomisp_histogram32 __user *up)
{
compat_uptr_t tmp;
if (!access_ok(up, sizeof(struct atomisp_histogram32)) ||
- get_user(kp->num_elements, &up->num_elements) ||
- get_user(tmp, &up->data))
+ assign_in_user(&kp->num_elements, &up->num_elements) ||
+ get_user(tmp, &up->data) ||
+ put_user(compat_ptr(tmp), &kp->data))
return -EFAULT;
- kp->data = compat_ptr(tmp);
return 0;
}
-static int put_atomisp_histogram32(struct atomisp_histogram *kp,
+static int put_atomisp_histogram32(struct atomisp_histogram __user *kp,
struct atomisp_histogram32 __user *up)
{
- compat_uptr_t tmp = (compat_uptr_t)((uintptr_t)kp->data);
+ void __user *tmp;
if (!access_ok(up, sizeof(struct atomisp_histogram32)) ||
- put_user(kp->num_elements, &up->num_elements) ||
- put_user(tmp, &up->data))
+ assign_in_user(&up->num_elements, &kp->num_elements) ||
+ get_user(tmp, &kp->data) ||
+ put_user(ptr_to_compat(tmp), &up->data))
return -EFAULT;
return 0;
}
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp,
- struct v4l2_pix_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp,
- struct v4l2_pix_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
- return -EFAULT;
- return 0;
-}
-
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp,
- struct v4l2_framebuffer32 __user *up)
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+ struct v4l2_framebuffer32 __user *up)
{
compat_uptr_t tmp;
if (!access_ok(up, sizeof(struct v4l2_framebuffer32)) ||
get_user(tmp, &up->base) ||
- get_user(kp->capability, &up->capability) ||
- get_user(kp->flags, &up->flags))
+ put_user(compat_ptr(tmp), &kp->base) ||
+ assign_in_user(&kp->capability, &up->capability) ||
+ assign_in_user(&kp->flags, &up->flags) ||
+ copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
return -EFAULT;
- kp->base = (void __force *)compat_ptr(tmp);
- get_v4l2_pix_format((struct v4l2_pix_format *)&kp->fmt, &up->fmt);
return 0;
}
-static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
+static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics __user *kp,
struct atomisp_dis_statistics32 __user *up)
{
compat_uptr_t hor_prod_odd_real;
@@ -96,67 +92,99 @@ static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
compat_uptr_t ver_prod_even_imag;
if (!access_ok(up, sizeof(struct atomisp_dis_statistics32)) ||
- copy_from_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
- get_user(hor_prod_odd_real, &up->dvs2_stat.hor_prod.odd_real) ||
- get_user(hor_prod_odd_imag, &up->dvs2_stat.hor_prod.odd_imag) ||
- get_user(hor_prod_even_real, &up->dvs2_stat.hor_prod.even_real) ||
- get_user(hor_prod_even_imag, &up->dvs2_stat.hor_prod.even_imag) ||
- get_user(ver_prod_odd_real, &up->dvs2_stat.ver_prod.odd_real) ||
- get_user(ver_prod_odd_imag, &up->dvs2_stat.ver_prod.odd_imag) ||
- get_user(ver_prod_even_real, &up->dvs2_stat.ver_prod.even_real) ||
- get_user(ver_prod_even_imag, &up->dvs2_stat.ver_prod.even_imag) ||
- get_user(kp->exp_id, &up->exp_id))
+ copy_in_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
+ get_user(hor_prod_odd_real,
+ &up->dvs2_stat.hor_prod.odd_real) ||
+ get_user(hor_prod_odd_imag,
+ &up->dvs2_stat.hor_prod.odd_imag) ||
+ get_user(hor_prod_even_real,
+ &up->dvs2_stat.hor_prod.even_real) ||
+ get_user(hor_prod_even_imag,
+ &up->dvs2_stat.hor_prod.even_imag) ||
+ get_user(ver_prod_odd_real,
+ &up->dvs2_stat.ver_prod.odd_real) ||
+ get_user(ver_prod_odd_imag,
+ &up->dvs2_stat.ver_prod.odd_imag) ||
+ get_user(ver_prod_even_real,
+ &up->dvs2_stat.ver_prod.even_real) ||
+ get_user(ver_prod_even_imag,
+ &up->dvs2_stat.ver_prod.even_imag) ||
+ assign_in_user(&kp->exp_id, &up->exp_id) ||
+ put_user(compat_ptr(hor_prod_odd_real),
+ &kp->dvs2_stat.hor_prod.odd_real) ||
+ put_user(compat_ptr(hor_prod_odd_imag),
+ &kp->dvs2_stat.hor_prod.odd_imag) ||
+ put_user(compat_ptr(hor_prod_even_real),
+ &kp->dvs2_stat.hor_prod.even_real) ||
+ put_user(compat_ptr(hor_prod_even_imag),
+ &kp->dvs2_stat.hor_prod.even_imag) ||
+ put_user(compat_ptr(ver_prod_odd_real),
+ &kp->dvs2_stat.ver_prod.odd_real) ||
+ put_user(compat_ptr(ver_prod_odd_imag),
+ &kp->dvs2_stat.ver_prod.odd_imag) ||
+ put_user(compat_ptr(ver_prod_even_real),
+ &kp->dvs2_stat.ver_prod.even_real) ||
+ put_user(compat_ptr(ver_prod_even_imag),
+ &kp->dvs2_stat.ver_prod.even_imag))
return -EFAULT;
- kp->dvs2_stat.hor_prod.odd_real = compat_ptr(hor_prod_odd_real);
- kp->dvs2_stat.hor_prod.odd_imag = compat_ptr(hor_prod_odd_imag);
- kp->dvs2_stat.hor_prod.even_real = compat_ptr(hor_prod_even_real);
- kp->dvs2_stat.hor_prod.even_imag = compat_ptr(hor_prod_even_imag);
- kp->dvs2_stat.ver_prod.odd_real = compat_ptr(ver_prod_odd_real);
- kp->dvs2_stat.ver_prod.odd_imag = compat_ptr(ver_prod_odd_imag);
- kp->dvs2_stat.ver_prod.even_real = compat_ptr(ver_prod_even_real);
- kp->dvs2_stat.ver_prod.even_imag = compat_ptr(ver_prod_even_imag);
return 0;
}
-static int put_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
+static int put_atomisp_dis_statistics32(struct atomisp_dis_statistics __user *kp,
struct atomisp_dis_statistics32 __user *up)
{
- compat_uptr_t hor_prod_odd_real =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.odd_real);
- compat_uptr_t hor_prod_odd_imag =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.odd_imag);
- compat_uptr_t hor_prod_even_real =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.even_real);
- compat_uptr_t hor_prod_even_imag =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.even_imag);
- compat_uptr_t ver_prod_odd_real =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.odd_real);
- compat_uptr_t ver_prod_odd_imag =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.odd_imag);
- compat_uptr_t ver_prod_even_real =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.even_real);
- compat_uptr_t ver_prod_even_imag =
- (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.even_imag);
-
- if (!access_ok(up, sizeof(struct atomisp_dis_statistics32)) ||
- copy_to_user(up, kp, sizeof(struct atomisp_dvs_grid_info)) ||
- put_user(hor_prod_odd_real, &up->dvs2_stat.hor_prod.odd_real) ||
- put_user(hor_prod_odd_imag, &up->dvs2_stat.hor_prod.odd_imag) ||
- put_user(hor_prod_even_real, &up->dvs2_stat.hor_prod.even_real) ||
- put_user(hor_prod_even_imag, &up->dvs2_stat.hor_prod.even_imag) ||
- put_user(ver_prod_odd_real, &up->dvs2_stat.ver_prod.odd_real) ||
- put_user(ver_prod_odd_imag, &up->dvs2_stat.ver_prod.odd_imag) ||
- put_user(ver_prod_even_real, &up->dvs2_stat.ver_prod.even_real) ||
- put_user(ver_prod_even_imag, &up->dvs2_stat.ver_prod.even_imag) ||
- put_user(kp->exp_id, &up->exp_id))
+ void __user *hor_prod_odd_real;
+ void __user *hor_prod_odd_imag;
+ void __user *hor_prod_even_real;
+ void __user *hor_prod_even_imag;
+ void __user *ver_prod_odd_real;
+ void __user *ver_prod_odd_imag;
+ void __user *ver_prod_even_real;
+ void __user *ver_prod_even_imag;
+
+ if (!!access_ok(up, sizeof(struct atomisp_dis_statistics32)) ||
+ copy_in_user(up, kp, sizeof(struct atomisp_dvs_grid_info)) ||
+ get_user(hor_prod_odd_real,
+ &kp->dvs2_stat.hor_prod.odd_real) ||
+ get_user(hor_prod_odd_imag,
+ &kp->dvs2_stat.hor_prod.odd_imag) ||
+ get_user(hor_prod_even_real,
+ &kp->dvs2_stat.hor_prod.even_real) ||
+ get_user(hor_prod_even_imag,
+ &kp->dvs2_stat.hor_prod.even_imag) ||
+ get_user(ver_prod_odd_real,
+ &kp->dvs2_stat.ver_prod.odd_real) ||
+ get_user(ver_prod_odd_imag,
+ &kp->dvs2_stat.ver_prod.odd_imag) ||
+ get_user(ver_prod_even_real,
+ &kp->dvs2_stat.ver_prod.even_real) ||
+ get_user(ver_prod_even_imag,
+ &kp->dvs2_stat.ver_prod.even_imag) ||
+ put_user(ptr_to_compat(hor_prod_odd_real),
+ &up->dvs2_stat.hor_prod.odd_real) ||
+ put_user(ptr_to_compat(hor_prod_odd_imag),
+ &up->dvs2_stat.hor_prod.odd_imag) ||
+ put_user(ptr_to_compat(hor_prod_even_real),
+ &up->dvs2_stat.hor_prod.even_real) ||
+ put_user(ptr_to_compat(hor_prod_even_imag),
+ &up->dvs2_stat.hor_prod.even_imag) ||
+ put_user(ptr_to_compat(ver_prod_odd_real),
+ &up->dvs2_stat.ver_prod.odd_real) ||
+ put_user(ptr_to_compat(ver_prod_odd_imag),
+ &up->dvs2_stat.ver_prod.odd_imag) ||
+ put_user(ptr_to_compat(ver_prod_even_real),
+ &up->dvs2_stat.ver_prod.even_real) ||
+ put_user(ptr_to_compat(ver_prod_even_imag),
+ &up->dvs2_stat.ver_prod.even_imag) ||
+ assign_in_user(&up->exp_id, &kp->exp_id))
return -EFAULT;
return 0;
}
-static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
- struct atomisp_dis_coefficients32 __user *up)
+static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients __user *kp,
+ struct atomisp_dis_coefficients32 __user *up)
{
compat_uptr_t hor_coefs_odd_real;
compat_uptr_t hor_coefs_odd_imag;
@@ -168,7 +196,7 @@ static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
compat_uptr_t ver_coefs_even_imag;
if (!access_ok(up, sizeof(struct atomisp_dis_coefficients32)) ||
- copy_from_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
+ copy_in_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
get_user(hor_coefs_odd_real, &up->hor_coefs.odd_real) ||
get_user(hor_coefs_odd_imag, &up->hor_coefs.odd_imag) ||
get_user(hor_coefs_even_real, &up->hor_coefs.even_real) ||
@@ -176,22 +204,30 @@ static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
get_user(ver_coefs_odd_real, &up->ver_coefs.odd_real) ||
get_user(ver_coefs_odd_imag, &up->ver_coefs.odd_imag) ||
get_user(ver_coefs_even_real, &up->ver_coefs.even_real) ||
- get_user(ver_coefs_even_imag, &up->ver_coefs.even_imag))
+ get_user(ver_coefs_even_imag, &up->ver_coefs.even_imag) ||
+ put_user(compat_ptr(hor_coefs_odd_real),
+ &kp->hor_coefs.odd_real) ||
+ put_user(compat_ptr(hor_coefs_odd_imag),
+ &kp->hor_coefs.odd_imag) ||
+ put_user(compat_ptr(hor_coefs_even_real),
+ &kp->hor_coefs.even_real) ||
+ put_user(compat_ptr(hor_coefs_even_imag),
+ &kp->hor_coefs.even_imag) ||
+ put_user(compat_ptr(ver_coefs_odd_real),
+ &kp->ver_coefs.odd_real) ||
+ put_user(compat_ptr(ver_coefs_odd_imag),
+ &kp->ver_coefs.odd_imag) ||
+ put_user(compat_ptr(ver_coefs_even_real),
+ &kp->ver_coefs.even_real) ||
+ put_user(compat_ptr(ver_coefs_even_imag),
+ &kp->ver_coefs.even_imag))
return -EFAULT;
- kp->hor_coefs.odd_real = compat_ptr(hor_coefs_odd_real);
- kp->hor_coefs.odd_imag = compat_ptr(hor_coefs_odd_imag);
- kp->hor_coefs.even_real = compat_ptr(hor_coefs_even_real);
- kp->hor_coefs.even_imag = compat_ptr(hor_coefs_even_imag);
- kp->ver_coefs.odd_real = compat_ptr(ver_coefs_odd_real);
- kp->ver_coefs.odd_imag = compat_ptr(ver_coefs_odd_imag);
- kp->ver_coefs.even_real = compat_ptr(ver_coefs_even_real);
- kp->ver_coefs.even_imag = compat_ptr(ver_coefs_even_imag);
return 0;
}
-static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config *kp,
- struct atomisp_dvs_6axis_config32 __user *up)
+static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config __user *kp,
+ struct atomisp_dvs_6axis_config32 __user *up)
{
compat_uptr_t xcoords_y;
compat_uptr_t ycoords_y;
@@ -199,62 +235,63 @@ static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config *kp,
compat_uptr_t ycoords_uv;
if (!access_ok(up, sizeof(struct atomisp_dvs_6axis_config32)) ||
- get_user(kp->exp_id, &up->exp_id) ||
- get_user(kp->width_y, &up->width_y) ||
- get_user(kp->height_y, &up->height_y) ||
- get_user(kp->width_uv, &up->width_uv) ||
- get_user(kp->height_uv, &up->height_uv) ||
+ assign_in_user(&kp->exp_id, &up->exp_id) ||
+ assign_in_user(&kp->width_y, &up->width_y) ||
+ assign_in_user(&kp->height_y, &up->height_y) ||
+ assign_in_user(&kp->width_uv, &up->width_uv) ||
+ assign_in_user(&kp->height_uv, &up->height_uv) ||
get_user(xcoords_y, &up->xcoords_y) ||
get_user(ycoords_y, &up->ycoords_y) ||
get_user(xcoords_uv, &up->xcoords_uv) ||
- get_user(ycoords_uv, &up->ycoords_uv))
+ get_user(ycoords_uv, &up->ycoords_uv) ||
+ put_user(compat_ptr(xcoords_y), &kp->xcoords_y) ||
+ put_user(compat_ptr(ycoords_y), &kp->ycoords_y) ||
+ put_user(compat_ptr(xcoords_uv), &kp->xcoords_uv) ||
+ put_user(compat_ptr(ycoords_uv), &kp->ycoords_uv))
return -EFAULT;
- kp->xcoords_y = (void __force *)compat_ptr(xcoords_y);
- kp->ycoords_y = (void __force *)compat_ptr(ycoords_y);
- kp->xcoords_uv = (void __force *)compat_ptr(xcoords_uv);
- kp->ycoords_uv = (void __force *)compat_ptr(ycoords_uv);
return 0;
}
-static int get_atomisp_3a_statistics32(struct atomisp_3a_statistics *kp,
+static int get_atomisp_3a_statistics32(struct atomisp_3a_statistics __user *kp,
struct atomisp_3a_statistics32 __user *up)
{
compat_uptr_t data;
compat_uptr_t rgby_data;
if (!access_ok(up, sizeof(struct atomisp_3a_statistics32)) ||
- copy_from_user(kp, up, sizeof(struct atomisp_grid_info)) ||
+ copy_in_user(kp, up, sizeof(struct atomisp_grid_info)) ||
get_user(rgby_data, &up->rgby_data) ||
+ put_user(compat_ptr(rgby_data), &kp->rgby_data) ||
get_user(data, &up->data) ||
- get_user(kp->exp_id, &up->exp_id) ||
- get_user(kp->isp_config_id, &up->isp_config_id))
+ put_user(compat_ptr(data), &kp->data) ||
+ assign_in_user(&kp->exp_id, &up->exp_id) ||
+ assign_in_user(&kp->isp_config_id, &up->isp_config_id))
return -EFAULT;
- kp->data = compat_ptr(data);
- kp->rgby_data = compat_ptr(rgby_data);
-
return 0;
}
-static int put_atomisp_3a_statistics32(struct atomisp_3a_statistics *kp,
+static int put_atomisp_3a_statistics32(struct atomisp_3a_statistics __user *kp,
struct atomisp_3a_statistics32 __user *up)
{
- compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
- compat_uptr_t rgby_data = (compat_uptr_t)((uintptr_t)kp->rgby_data);
+ void __user *data;
+ void __user *rgby_data;
if (!access_ok(up, sizeof(struct atomisp_3a_statistics32)) ||
copy_to_user(up, kp, sizeof(struct atomisp_grid_info)) ||
- put_user(rgby_data, &up->rgby_data) ||
- put_user(data, &up->data) ||
- put_user(kp->exp_id, &up->exp_id) ||
- put_user(kp->isp_config_id, &up->isp_config_id))
+ get_user(rgby_data, &kp->rgby_data) ||
+ put_user(ptr_to_compat(rgby_data), &up->rgby_data) ||
+ get_user(data, &kp->data) ||
+ put_user(ptr_to_compat(data), &up->data) ||
+ assign_in_user(&up->exp_id, &kp->exp_id) ||
+ assign_in_user(&up->isp_config_id, &kp->isp_config_id))
return -EFAULT;
return 0;
}
-static int get_atomisp_metadata_stat32(struct atomisp_metadata *kp,
+static int get_atomisp_metadata_stat32(struct atomisp_metadata __user *kp,
struct atomisp_metadata32 __user *up)
{
compat_uptr_t data;
@@ -262,553 +299,524 @@ static int get_atomisp_metadata_stat32(struct atomisp_metadata *kp,
if (!access_ok(up, sizeof(struct atomisp_metadata32)) ||
get_user(data, &up->data) ||
- get_user(kp->width, &up->width) ||
- get_user(kp->height, &up->height) ||
- get_user(kp->stride, &up->stride) ||
- get_user(kp->exp_id, &up->exp_id) ||
- get_user(effective_width, &up->effective_width))
+ put_user(compat_ptr(data), &kp->data) ||
+ assign_in_user(&kp->width, &up->width) ||
+ assign_in_user(&kp->height, &up->height) ||
+ assign_in_user(&kp->stride, &up->stride) ||
+ assign_in_user(&kp->exp_id, &up->exp_id) ||
+ get_user(effective_width, &up->effective_width) ||
+ put_user(compat_ptr(effective_width), &kp->effective_width))
return -EFAULT;
- kp->data = compat_ptr(data);
- kp->effective_width = (void __force *)compat_ptr(effective_width);
return 0;
}
-static int put_atomisp_metadata_stat32(struct atomisp_metadata *kp,
- struct atomisp_metadata32 __user *up)
+static int put_atomisp_metadata_stat32(struct atomisp_metadata __user *kp,
+ struct atomisp_metadata32 __user *up)
{
- compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
- compat_uptr_t effective_width =
- (compat_uptr_t)((uintptr_t)kp->effective_width);
+ void __user *data;
+ void __user *effective_width;
+
if (!access_ok(up, sizeof(struct atomisp_metadata32)) ||
- put_user(data, &up->data) ||
- put_user(kp->width, &up->width) ||
- put_user(kp->height, &up->height) ||
- put_user(kp->stride, &up->stride) ||
- put_user(kp->exp_id, &up->exp_id) ||
- put_user(effective_width, &up->effective_width))
+ get_user(data, &kp->data) ||
+ put_user(ptr_to_compat(data), &up->data) ||
+ assign_in_user(&up->width, &kp->width) ||
+ assign_in_user(&up->height, &kp->height) ||
+ assign_in_user(&up->stride, &kp->stride) ||
+ assign_in_user(&up->exp_id, &kp->exp_id) ||
+ get_user(effective_width, &kp->effective_width) ||
+ put_user(ptr_to_compat(effective_width), &up->effective_width))
return -EFAULT;
return 0;
}
-static int put_atomisp_metadata_by_type_stat32(
- struct atomisp_metadata_with_type *kp,
- struct atomisp_metadata_with_type32 __user *up)
+static int
+put_atomisp_metadata_by_type_stat32(struct atomisp_metadata_with_type __user *kp,
+ struct atomisp_metadata_with_type32 __user *up)
{
- compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
- compat_uptr_t effective_width =
- (compat_uptr_t)((uintptr_t)kp->effective_width);
+ void __user *data;
+ void __user *effective_width;
+
if (!access_ok(up, sizeof(struct atomisp_metadata_with_type32)) ||
- put_user(data, &up->data) ||
- put_user(kp->width, &up->width) ||
- put_user(kp->height, &up->height) ||
- put_user(kp->stride, &up->stride) ||
- put_user(kp->exp_id, &up->exp_id) ||
- put_user(effective_width, &up->effective_width) ||
- put_user(kp->type, &up->type))
+ get_user(data, &kp->data) ||
+ put_user(ptr_to_compat(data), &up->data) ||
+ assign_in_user(&up->width, &kp->width) ||
+ assign_in_user(&up->height, &kp->height) ||
+ assign_in_user(&up->stride, &kp->stride) ||
+ assign_in_user(&up->exp_id, &kp->exp_id) ||
+ get_user(effective_width, &kp->effective_width) ||
+ put_user(ptr_to_compat(effective_width),
+ &up->effective_width) ||
+ assign_in_user(&up->type, &kp->type))
return -EFAULT;
return 0;
}
-static int get_atomisp_metadata_by_type_stat32(
- struct atomisp_metadata_with_type *kp,
- struct atomisp_metadata_with_type32 __user *up)
+static int
+get_atomisp_metadata_by_type_stat32(struct atomisp_metadata_with_type __user *kp,
+ struct atomisp_metadata_with_type32 __user *up)
{
compat_uptr_t data;
compat_uptr_t effective_width;
if (!access_ok(up, sizeof(struct atomisp_metadata_with_type32)) ||
get_user(data, &up->data) ||
- get_user(kp->width, &up->width) ||
- get_user(kp->height, &up->height) ||
- get_user(kp->stride, &up->stride) ||
- get_user(kp->exp_id, &up->exp_id) ||
+ put_user(compat_ptr(data), &kp->data) ||
+ assign_in_user(&kp->width, &up->width) ||
+ assign_in_user(&kp->height, &up->height) ||
+ assign_in_user(&kp->stride, &up->stride) ||
+ assign_in_user(&kp->exp_id, &up->exp_id) ||
get_user(effective_width, &up->effective_width) ||
- get_user(kp->type, &up->type))
+ put_user(compat_ptr(effective_width), &kp->effective_width) ||
+ assign_in_user(&kp->type, &up->type))
return -EFAULT;
- kp->data = compat_ptr(data);
- kp->effective_width = (void __force *)compat_ptr(effective_width);
return 0;
}
-static int get_atomisp_morph_table32(struct atomisp_morph_table *kp,
- struct atomisp_morph_table32 __user *up)
+static int
+get_atomisp_morph_table32(struct atomisp_morph_table __user *kp,
+ struct atomisp_morph_table32 __user *up)
{
unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES;
if (!access_ok(up, sizeof(struct atomisp_morph_table32)) ||
- get_user(kp->enabled, &up->enabled) ||
- get_user(kp->width, &up->width) ||
- get_user(kp->height, &up->height))
- return -EFAULT;
+ assign_in_user(&kp->enabled, &up->enabled) ||
+ assign_in_user(&kp->width, &up->width) ||
+ assign_in_user(&kp->height, &up->height))
+ return -EFAULT;
while (n-- > 0) {
- uintptr_t *coord_kp = (uintptr_t *)&kp->coordinates_x[n];
-
- if (get_user((*coord_kp), &up->coordinates_x[n]))
- return -EFAULT;
+ compat_uptr_t coord_kp;
- coord_kp = (uintptr_t *)&kp->coordinates_y[n];
- if (get_user((*coord_kp), &up->coordinates_y[n]))
+ if (get_user(coord_kp, &up->coordinates_x[n]) ||
+ put_user(compat_ptr(coord_kp), &kp->coordinates_x[n]) ||
+ get_user(coord_kp, &up->coordinates_y[n]) ||
+ put_user(compat_ptr(coord_kp), &kp->coordinates_y[n]))
return -EFAULT;
}
return 0;
}
-static int put_atomisp_morph_table32(struct atomisp_morph_table *kp,
+static int put_atomisp_morph_table32(struct atomisp_morph_table __user *kp,
struct atomisp_morph_table32 __user *up)
{
unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES;
if (!access_ok(up, sizeof(struct atomisp_morph_table32)) ||
- put_user(kp->enabled, &up->enabled) ||
- put_user(kp->width, &up->width) ||
- put_user(kp->height, &up->height))
- return -EFAULT;
+ assign_in_user(&up->enabled, &kp->enabled) ||
+ assign_in_user(&up->width, &kp->width) ||
+ assign_in_user(&up->height, &kp->height))
+ return -EFAULT;
while (n-- > 0) {
- uintptr_t *coord_kp = (uintptr_t *)&kp->coordinates_x[n];
+ void __user *coord_kp;
- if (put_user((*coord_kp), &up->coordinates_x[n]))
- return -EFAULT;
-
- coord_kp = (uintptr_t *)&kp->coordinates_y[n];
- if (put_user((*coord_kp), &up->coordinates_y[n]))
+ if (get_user(coord_kp, &kp->coordinates_x[n]) ||
+ put_user(ptr_to_compat(coord_kp), &up->coordinates_x[n]) ||
+ get_user(coord_kp, &kp->coordinates_y[n]) ||
+ put_user(ptr_to_compat(coord_kp), &up->coordinates_y[n]))
return -EFAULT;
}
return 0;
}
-static int get_atomisp_overlay32(struct atomisp_overlay *kp,
+static int get_atomisp_overlay32(struct atomisp_overlay __user *kp,
struct atomisp_overlay32 __user *up)
{
compat_uptr_t frame;
if (!access_ok(up, sizeof(struct atomisp_overlay32)) ||
get_user(frame, &up->frame) ||
- get_user(kp->bg_y, &up->bg_y) ||
- get_user(kp->bg_u, &up->bg_u) ||
- get_user(kp->bg_v, &up->bg_v) ||
- get_user(kp->blend_input_perc_y, &up->blend_input_perc_y) ||
- get_user(kp->blend_input_perc_u, &up->blend_input_perc_u) ||
- get_user(kp->blend_input_perc_v, &up->blend_input_perc_v) ||
- get_user(kp->blend_overlay_perc_y, &up->blend_overlay_perc_y) ||
- get_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
- get_user(kp->blend_overlay_perc_v, &up->blend_overlay_perc_v) ||
- get_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
- get_user(kp->overlay_start_x, &up->overlay_start_y))
+ put_user(compat_ptr(frame), &kp->frame) ||
+ assign_in_user(&kp->bg_y, &up->bg_y) ||
+ assign_in_user(&kp->bg_u, &up->bg_u) ||
+ assign_in_user(&kp->bg_v, &up->bg_v) ||
+ assign_in_user(&kp->blend_input_perc_y,
+ &up->blend_input_perc_y) ||
+ assign_in_user(&kp->blend_input_perc_u,
+ &up->blend_input_perc_u) ||
+ assign_in_user(&kp->blend_input_perc_v,
+ &up->blend_input_perc_v) ||
+ assign_in_user(&kp->blend_overlay_perc_y,
+ &up->blend_overlay_perc_y) ||
+ assign_in_user(&kp->blend_overlay_perc_u,
+ &up->blend_overlay_perc_u) ||
+ assign_in_user(&kp->blend_overlay_perc_v,
+ &up->blend_overlay_perc_v) ||
+ assign_in_user(&kp->overlay_start_x, &up->overlay_start_x) ||
+ assign_in_user(&kp->overlay_start_y, &up->overlay_start_y))
return -EFAULT;
- kp->frame = (void __force *)compat_ptr(frame);
return 0;
}
-static int put_atomisp_overlay32(struct atomisp_overlay *kp,
+static int put_atomisp_overlay32(struct atomisp_overlay __user *kp,
struct atomisp_overlay32 __user *up)
{
- compat_uptr_t frame = (compat_uptr_t)((uintptr_t)kp->frame);
+ void __user *frame;
if (!access_ok(up, sizeof(struct atomisp_overlay32)) ||
- put_user(frame, &up->frame) ||
- put_user(kp->bg_y, &up->bg_y) ||
- put_user(kp->bg_u, &up->bg_u) ||
- put_user(kp->bg_v, &up->bg_v) ||
- put_user(kp->blend_input_perc_y, &up->blend_input_perc_y) ||
- put_user(kp->blend_input_perc_u, &up->blend_input_perc_u) ||
- put_user(kp->blend_input_perc_v, &up->blend_input_perc_v) ||
- put_user(kp->blend_overlay_perc_y, &up->blend_overlay_perc_y) ||
- put_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
- put_user(kp->blend_overlay_perc_v, &up->blend_overlay_perc_v) ||
- put_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
- put_user(kp->overlay_start_x, &up->overlay_start_y))
+ get_user(frame, &kp->frame) ||
+ put_user(ptr_to_compat(frame), &up->frame) ||
+ assign_in_user(&up->bg_y, &kp->bg_y) ||
+ assign_in_user(&up->bg_u, &kp->bg_u) ||
+ assign_in_user(&up->bg_v, &kp->bg_v) ||
+ assign_in_user(&up->blend_input_perc_y,
+ &kp->blend_input_perc_y) ||
+ assign_in_user(&up->blend_input_perc_u,
+ &kp->blend_input_perc_u) ||
+ assign_in_user(&up->blend_input_perc_v,
+ &kp->blend_input_perc_v) ||
+ assign_in_user(&up->blend_overlay_perc_y,
+ &kp->blend_overlay_perc_y) ||
+ assign_in_user(&up->blend_overlay_perc_u,
+ &kp->blend_overlay_perc_u) ||
+ assign_in_user(&up->blend_overlay_perc_v,
+ &kp->blend_overlay_perc_v) ||
+ assign_in_user(&up->overlay_start_x, &kp->overlay_start_x) ||
+ assign_in_user(&up->overlay_start_y, &kp->overlay_start_y))
return -EFAULT;
return 0;
}
-static int get_atomisp_calibration_group32(
- struct atomisp_calibration_group *kp,
- struct atomisp_calibration_group32 __user *up)
+static int
+get_atomisp_calibration_group32(struct atomisp_calibration_group __user *kp,
+ struct atomisp_calibration_group32 __user *up)
{
compat_uptr_t calb_grp_values;
if (!access_ok(up, sizeof(struct atomisp_calibration_group32)) ||
- get_user(kp->size, &up->size) ||
- get_user(kp->type, &up->type) ||
- get_user(calb_grp_values, &up->calb_grp_values))
+ assign_in_user(&kp->size, &up->size) ||
+ assign_in_user(&kp->type, &up->type) ||
+ get_user(calb_grp_values, &up->calb_grp_values) ||
+ put_user(compat_ptr(calb_grp_values), &kp->calb_grp_values))
return -EFAULT;
- kp->calb_grp_values = (void __force *)compat_ptr(calb_grp_values);
return 0;
}
-static int put_atomisp_calibration_group32(
- struct atomisp_calibration_group *kp,
- struct atomisp_calibration_group32 __user *up)
+static int
+put_atomisp_calibration_group32(struct atomisp_calibration_group __user *kp,
+ struct atomisp_calibration_group32 __user *up)
{
- compat_uptr_t calb_grp_values =
- (compat_uptr_t)((uintptr_t)kp->calb_grp_values);
+ void __user *calb_grp_values;
if (!access_ok(up, sizeof(struct atomisp_calibration_group32)) ||
- put_user(kp->size, &up->size) ||
- put_user(kp->type, &up->type) ||
- put_user(calb_grp_values, &up->calb_grp_values))
+ assign_in_user(&up->size, &kp->size) ||
+ assign_in_user(&up->type, &kp->type) ||
+ get_user(calb_grp_values, &kp->calb_grp_values) ||
+ put_user(ptr_to_compat(calb_grp_values), &up->calb_grp_values))
return -EFAULT;
return 0;
}
-static int get_atomisp_acc_fw_load32(struct atomisp_acc_fw_load *kp,
+static int get_atomisp_acc_fw_load32(struct atomisp_acc_fw_load __user *kp,
struct atomisp_acc_fw_load32 __user *up)
{
compat_uptr_t data;
if (!access_ok(up, sizeof(struct atomisp_acc_fw_load32)) ||
- get_user(kp->size, &up->size) ||
- get_user(kp->fw_handle, &up->fw_handle) ||
- get_user(data, &up->data))
+ assign_in_user(&kp->size, &up->size) ||
+ assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+ get_user(data, &up->data) ||
+ put_user(compat_ptr(data), &kp->data))
return -EFAULT;
- kp->data = compat_ptr(data);
return 0;
}
-static int put_atomisp_acc_fw_load32(struct atomisp_acc_fw_load *kp,
+static int put_atomisp_acc_fw_load32(struct atomisp_acc_fw_load __user *kp,
struct atomisp_acc_fw_load32 __user *up)
{
- compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
+ void __user *data;
if (!access_ok(up, sizeof(struct atomisp_acc_fw_load32)) ||
- put_user(kp->size, &up->size) ||
- put_user(kp->fw_handle, &up->fw_handle) ||
- put_user(data, &up->data))
+ assign_in_user(&up->size, &kp->size) ||
+ assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+ get_user(data, &kp->data) ||
+ put_user(ptr_to_compat(data), &up->data))
return -EFAULT;
return 0;
}
-static int get_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg *kp,
+static int get_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg __user *kp,
struct atomisp_acc_fw_arg32 __user *up)
{
compat_uptr_t value;
if (!access_ok(up, sizeof(struct atomisp_acc_fw_arg32)) ||
- get_user(kp->fw_handle, &up->fw_handle) ||
- get_user(kp->index, &up->index) ||
+ assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+ assign_in_user(&kp->index, &up->index) ||
get_user(value, &up->value) ||
- get_user(kp->size, &up->size))
+ put_user(compat_ptr(value), &kp->value) ||
+ assign_in_user(&kp->size, &up->size))
return -EFAULT;
- kp->value = compat_ptr(value);
return 0;
}
-static int put_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg *kp,
+static int put_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg __user *kp,
struct atomisp_acc_fw_arg32 __user *up)
{
- compat_uptr_t value = (compat_uptr_t)((uintptr_t)kp->value);
+ void __user *value;
if (!access_ok(up, sizeof(struct atomisp_acc_fw_arg32)) ||
- put_user(kp->fw_handle, &up->fw_handle) ||
- put_user(kp->index, &up->index) ||
- put_user(value, &up->value) ||
- put_user(kp->size, &up->size))
+ assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+ assign_in_user(&up->index, &kp->index) ||
+ get_user(value, &kp->value) ||
+ put_user(ptr_to_compat(value), &up->value) ||
+ assign_in_user(&up->size, &kp->size))
return -EFAULT;
return 0;
}
-static int get_v4l2_private_int_data32(struct v4l2_private_int_data *kp,
+static int get_v4l2_private_int_data32(struct v4l2_private_int_data __user *kp,
struct v4l2_private_int_data32 __user *up)
{
compat_uptr_t data;
if (!access_ok(up, sizeof(struct v4l2_private_int_data32)) ||
- get_user(kp->size, &up->size) ||
+ assign_in_user(&kp->size, &up->size) ||
get_user(data, &up->data) ||
- get_user(kp->reserved[0], &up->reserved[0]) ||
- get_user(kp->reserved[1], &up->reserved[1]))
+ put_user(compat_ptr(data), &kp->data) ||
+ assign_in_user(&kp->reserved[0], &up->reserved[0]) ||
+ assign_in_user(&kp->reserved[1], &up->reserved[1]))
return -EFAULT;
- kp->data = compat_ptr(data);
return 0;
}
-static int put_v4l2_private_int_data32(struct v4l2_private_int_data *kp,
+static int put_v4l2_private_int_data32(struct v4l2_private_int_data __user *kp,
struct v4l2_private_int_data32 __user *up)
{
- compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
+ void __user *data;
if (!access_ok(up, sizeof(struct v4l2_private_int_data32)) ||
- put_user(kp->size, &up->size) ||
- put_user(data, &up->data) ||
- put_user(kp->reserved[0], &up->reserved[0]) ||
- put_user(kp->reserved[1], &up->reserved[1]))
+ assign_in_user(&up->size, &kp->size) ||
+ get_user(data, &kp->data) ||
+ put_user(ptr_to_compat(data), &up->data) ||
+ assign_in_user(&up->reserved[0], &kp->reserved[0]) ||
+ assign_in_user(&up->reserved[1], &kp->reserved[1]))
return -EFAULT;
return 0;
}
-static int get_atomisp_shading_table32(struct atomisp_shading_table *kp,
+static int get_atomisp_shading_table32(struct atomisp_shading_table __user *kp,
struct atomisp_shading_table32 __user *up)
{
unsigned int n = ATOMISP_NUM_SC_COLORS;
if (!access_ok(up, sizeof(struct atomisp_shading_table32)) ||
- get_user(kp->enable, &up->enable) ||
- get_user(kp->sensor_width, &up->sensor_width) ||
- get_user(kp->sensor_height, &up->sensor_height) ||
- get_user(kp->width, &up->width) ||
- get_user(kp->height, &up->height) ||
- get_user(kp->fraction_bits, &up->fraction_bits))
+ assign_in_user(&kp->enable, &up->enable) ||
+ assign_in_user(&kp->sensor_width, &up->sensor_width) ||
+ assign_in_user(&kp->sensor_height, &up->sensor_height) ||
+ assign_in_user(&kp->width, &up->width) ||
+ assign_in_user(&kp->height, &up->height) ||
+ assign_in_user(&kp->fraction_bits, &up->fraction_bits))
return -EFAULT;
while (n-- > 0) {
- uintptr_t *data_p = (uintptr_t *)&kp->data[n];
+ compat_uptr_t tmp;
- if (get_user((*data_p), &up->data[n]))
+ if (get_user(tmp, &up->data[n]) ||
+ put_user(compat_ptr(tmp), &kp->data[n]))
return -EFAULT;
}
return 0;
}
-static int get_atomisp_acc_map32(struct atomisp_acc_map *kp,
+static int get_atomisp_acc_map32(struct atomisp_acc_map __user *kp,
struct atomisp_acc_map32 __user *up)
{
compat_uptr_t user_ptr;
if (!access_ok(up, sizeof(struct atomisp_acc_map32)) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->length, &up->length) ||
+ assign_in_user(&kp->flags, &up->flags) ||
+ assign_in_user(&kp->length, &up->length) ||
get_user(user_ptr, &up->user_ptr) ||
- get_user(kp->css_ptr, &up->css_ptr) ||
- get_user(kp->reserved[0], &up->reserved[0]) ||
- get_user(kp->reserved[1], &up->reserved[1]) ||
- get_user(kp->reserved[2], &up->reserved[2]) ||
- get_user(kp->reserved[3], &up->reserved[3]))
+ put_user(compat_ptr(user_ptr), &kp->user_ptr) ||
+ assign_in_user(&kp->css_ptr, &up->css_ptr) ||
+ assign_in_user(&kp->reserved[0], &up->reserved[0]) ||
+ assign_in_user(&kp->reserved[1], &up->reserved[1]) ||
+ assign_in_user(&kp->reserved[2], &up->reserved[2]) ||
+ assign_in_user(&kp->reserved[3], &up->reserved[3]))
return -EFAULT;
- kp->user_ptr = compat_ptr(user_ptr);
return 0;
}
-static int put_atomisp_acc_map32(struct atomisp_acc_map *kp,
+static int put_atomisp_acc_map32(struct atomisp_acc_map __user *kp,
struct atomisp_acc_map32 __user *up)
{
- compat_uptr_t user_ptr = (compat_uptr_t)((uintptr_t)kp->user_ptr);
+ void __user *user_ptr;
if (!access_ok(up, sizeof(struct atomisp_acc_map32)) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->length, &up->length) ||
- put_user(user_ptr, &up->user_ptr) ||
- put_user(kp->css_ptr, &up->css_ptr) ||
- put_user(kp->reserved[0], &up->reserved[0]) ||
- put_user(kp->reserved[1], &up->reserved[1]) ||
- put_user(kp->reserved[2], &up->reserved[2]) ||
- put_user(kp->reserved[3], &up->reserved[3]))
+ assign_in_user(&up->flags, &kp->flags) ||
+ assign_in_user(&up->length, &kp->length) ||
+ get_user(user_ptr, &kp->user_ptr) ||
+ put_user(ptr_to_compat(user_ptr), &up->user_ptr) ||
+ assign_in_user(&up->css_ptr, &kp->css_ptr) ||
+ assign_in_user(&up->reserved[0], &kp->reserved[0]) ||
+ assign_in_user(&up->reserved[1], &kp->reserved[1]) ||
+ assign_in_user(&up->reserved[2], &kp->reserved[2]) ||
+ assign_in_user(&up->reserved[3], &kp->reserved[3]))
return -EFAULT;
return 0;
}
-static int get_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg *kp,
- struct atomisp_acc_s_mapped_arg32 __user *up)
+static int
+get_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg __user *kp,
+ struct atomisp_acc_s_mapped_arg32 __user *up)
{
if (!access_ok(up, sizeof(struct atomisp_acc_s_mapped_arg32)) ||
- get_user(kp->fw_handle, &up->fw_handle) ||
- get_user(kp->memory, &up->memory) ||
- get_user(kp->length, &up->length) ||
- get_user(kp->css_ptr, &up->css_ptr))
+ assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+ assign_in_user(&kp->memory, &up->memory) ||
+ assign_in_user(&kp->length, &up->length) ||
+ assign_in_user(&kp->css_ptr, &up->css_ptr))
return -EFAULT;
return 0;
}
-static int put_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg *kp,
- struct atomisp_acc_s_mapped_arg32 __user *up)
+static int
+put_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg __user *kp,
+ struct atomisp_acc_s_mapped_arg32 __user *up)
{
if (!access_ok(up, sizeof(struct atomisp_acc_s_mapped_arg32)) ||
- put_user(kp->fw_handle, &up->fw_handle) ||
- put_user(kp->memory, &up->memory) ||
- put_user(kp->length, &up->length) ||
- put_user(kp->css_ptr, &up->css_ptr))
+ assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+ assign_in_user(&up->memory, &kp->memory) ||
+ assign_in_user(&up->length, &kp->length) ||
+ assign_in_user(&up->css_ptr, &kp->css_ptr))
return -EFAULT;
return 0;
}
-static int get_atomisp_parameters32(struct atomisp_parameters *kp,
+static int get_atomisp_parameters32(struct atomisp_parameters __user *kp,
struct atomisp_parameters32 __user *up)
{
int n = offsetof(struct atomisp_parameters32, output_frame) /
sizeof(compat_uptr_t);
- unsigned int size, offset = 0;
- void __user *user_ptr;
- unsigned int stp, mtp, dcp, dscp = 0;
+ compat_uptr_t stp, mtp, dcp, dscp;
+ struct {
+ struct atomisp_shading_table shading_table;
+ struct atomisp_morph_table morph_table;
+ struct atomisp_dis_coefficients dvs2_coefs;
+ struct atomisp_dvs_6axis_config dvs_6axis_config;
+ } __user *karg = (void *)(kp + 1);
if (!access_ok(up, sizeof(struct atomisp_parameters32)))
return -EFAULT;
while (n >= 0) {
- compat_uptr_t __user *src = ((compat_uptr_t __user *)up) + n;
- uintptr_t *dst = ((uintptr_t *)kp) + n;
+ compat_uptr_t *src = (compat_uptr_t *)up + n;
+ void * __user *dst = (void * __user *)kp + n;
+ compat_uptr_t tmp;
- if (get_user((*dst), src))
+ if (get_user(tmp, src) || put_user(compat_ptr(tmp), dst))
return -EFAULT;
n--;
}
- if (get_user(kp->isp_config_id, &up->isp_config_id) ||
- get_user(kp->per_frame_setting, &up->per_frame_setting) ||
+
+ if (assign_in_user(&kp->isp_config_id, &up->isp_config_id) ||
+ assign_in_user(&kp->per_frame_setting, &up->per_frame_setting) ||
get_user(stp, &up->shading_table) ||
get_user(mtp, &up->morph_table) ||
get_user(dcp, &up->dvs2_coefs) ||
get_user(dscp, &up->dvs_6axis_config))
return -EFAULT;
- {
- union {
- struct atomisp_shading_table shading_table;
- struct atomisp_morph_table morph_table;
- struct atomisp_dis_coefficients dvs2_coefs;
- struct atomisp_dvs_6axis_config dvs_6axis_config;
- } karg;
-
- size = sizeof(struct atomisp_shading_table) +
- sizeof(struct atomisp_morph_table) +
- sizeof(struct atomisp_dis_coefficients) +
- sizeof(struct atomisp_dvs_6axis_config);
- user_ptr = compat_alloc_user_space(size);
-
- /* handle shading table */
- if (stp != 0) {
- if (get_atomisp_shading_table32(&karg.shading_table,
- (struct atomisp_shading_table32 __user *)
- (uintptr_t)stp))
- return -EFAULT;
-
- kp->shading_table = (void __force *)user_ptr + offset;
- offset = sizeof(struct atomisp_shading_table);
- if (!kp->shading_table)
- return -EFAULT;
-
- if (copy_to_user((void __user *)kp->shading_table,
- &karg.shading_table,
- sizeof(struct atomisp_shading_table)))
- return -EFAULT;
- }
-
- /* handle morph table */
- if (mtp != 0) {
- if (get_atomisp_morph_table32(&karg.morph_table,
- (struct atomisp_morph_table32 __user *)
- (uintptr_t)mtp))
- return -EFAULT;
-
- kp->morph_table = (void __force *)user_ptr + offset;
- offset += sizeof(struct atomisp_morph_table);
- if (!kp->morph_table)
- return -EFAULT;
-
- if (copy_to_user((void __user *)kp->morph_table,
- &karg.morph_table,
- sizeof(struct atomisp_morph_table)))
- return -EFAULT;
- }
-
- /* handle dvs2 coefficients */
- if (dcp != 0) {
- if (get_atomisp_dis_coefficients32(&karg.dvs2_coefs,
- (struct atomisp_dis_coefficients32 __user *)
- (uintptr_t)dcp))
- return -EFAULT;
-
- kp->dvs2_coefs = (void __force *)user_ptr + offset;
- offset += sizeof(struct atomisp_dis_coefficients);
- if (!kp->dvs2_coefs)
- return -EFAULT;
-
- if (copy_to_user((void __user *)kp->dvs2_coefs,
- &karg.dvs2_coefs,
- sizeof(struct atomisp_dis_coefficients)))
- return -EFAULT;
- }
- /* handle dvs 6axis configuration */
- if (dscp != 0) {
- if (get_atomisp_dvs_6axis_config32(&karg.dvs_6axis_config,
- (struct atomisp_dvs_6axis_config32 __user *)
- (uintptr_t)dscp))
- return -EFAULT;
-
- kp->dvs_6axis_config = (void __force *)user_ptr + offset;
- offset += sizeof(struct atomisp_dvs_6axis_config);
- if (!kp->dvs_6axis_config)
- return -EFAULT;
-
- if (copy_to_user((void __user *)kp->dvs_6axis_config,
- &karg.dvs_6axis_config,
- sizeof(struct atomisp_dvs_6axis_config)))
- return -EFAULT;
- }
- }
+ /* handle shading table */
+ if (stp && (get_atomisp_shading_table32(&karg->shading_table,
+ compat_ptr(stp)) ||
+ put_user(&karg->shading_table, &kp->shading_table)))
+ return -EFAULT;
+
+ /* handle morph table */
+ if (mtp && (get_atomisp_morph_table32(&karg->morph_table,
+ compat_ptr(mtp)) ||
+ put_user(&karg->morph_table, &kp->morph_table)))
+ return -EFAULT;
+
+ /* handle dvs2 coefficients */
+ if (dcp && (get_atomisp_dis_coefficients32(&karg->dvs2_coefs,
+ compat_ptr(dcp)) ||
+ put_user(&karg->dvs2_coefs, &kp->dvs2_coefs)))
+ return -EFAULT;
+
+ /* handle dvs 6axis configuration */
+ if (dscp &&
+ (get_atomisp_dvs_6axis_config32(&karg->dvs_6axis_config,
+ compat_ptr(dscp)) ||
+ put_user(&karg->dvs_6axis_config, &kp->dvs_6axis_config)))
+ return -EFAULT;
+
return 0;
}
-static int get_atomisp_acc_fw_load_to_pipe32(
- struct atomisp_acc_fw_load_to_pipe *kp,
- struct atomisp_acc_fw_load_to_pipe32 __user *up)
+static int
+get_atomisp_acc_fw_load_to_pipe32(struct atomisp_acc_fw_load_to_pipe __user *kp,
+ struct atomisp_acc_fw_load_to_pipe32 __user *up)
{
compat_uptr_t data;
if (!access_ok(up, sizeof(struct atomisp_acc_fw_load_to_pipe32)) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->fw_handle, &up->fw_handle) ||
- get_user(kp->size, &up->size) ||
- get_user(kp->type, &up->type) ||
- get_user(kp->reserved[0], &up->reserved[0]) ||
- get_user(kp->reserved[1], &up->reserved[1]) ||
- get_user(kp->reserved[2], &up->reserved[2]) ||
- get_user(data, &up->data))
+ assign_in_user(&kp->flags, &up->flags) ||
+ assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+ assign_in_user(&kp->size, &up->size) ||
+ assign_in_user(&kp->type, &up->type) ||
+ assign_in_user(&kp->reserved[0], &up->reserved[0]) ||
+ assign_in_user(&kp->reserved[1], &up->reserved[1]) ||
+ assign_in_user(&kp->reserved[2], &up->reserved[2]) ||
+ get_user(data, &up->data) ||
+ put_user(compat_ptr(data), &kp->data))
return -EFAULT;
- kp->data = compat_ptr(data);
return 0;
}
-static int put_atomisp_acc_fw_load_to_pipe32(
- struct atomisp_acc_fw_load_to_pipe *kp,
- struct atomisp_acc_fw_load_to_pipe32 __user *up)
+static int
+put_atomisp_acc_fw_load_to_pipe32(struct atomisp_acc_fw_load_to_pipe __user *kp,
+ struct atomisp_acc_fw_load_to_pipe32 __user *up)
{
- compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
+ void __user *data;
if (!access_ok(up, sizeof(struct atomisp_acc_fw_load_to_pipe32)) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->fw_handle, &up->fw_handle) ||
- put_user(kp->size, &up->size) ||
- put_user(kp->type, &up->type) ||
- put_user(kp->reserved[0], &up->reserved[0]) ||
- put_user(kp->reserved[1], &up->reserved[1]) ||
- put_user(kp->reserved[2], &up->reserved[2]) ||
- put_user(data, &up->data))
+ assign_in_user(&up->flags, &kp->flags) ||
+ assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+ assign_in_user(&up->size, &kp->size) ||
+ assign_in_user(&up->type, &kp->type) ||
+ assign_in_user(&up->reserved[0], &kp->reserved[0]) ||
+ assign_in_user(&up->reserved[1], &kp->reserved[1]) ||
+ assign_in_user(&up->reserved[2], &kp->reserved[2]) ||
+ get_user(data, &kp->data) ||
+ put_user(ptr_to_compat(data), &up->data))
return -EFAULT;
return 0;
}
-static int get_atomisp_sensor_ae_bracketing_lut(
- struct atomisp_sensor_ae_bracketing_lut *kp,
- struct atomisp_sensor_ae_bracketing_lut32 __user *up)
+static int
+get_atomisp_sensor_ae_bracketing_lut(struct atomisp_sensor_ae_bracketing_lut __user *kp,
+ struct atomisp_sensor_ae_bracketing_lut32 __user *up)
{
compat_uptr_t lut;
if (!access_ok(up, sizeof(struct atomisp_sensor_ae_bracketing_lut32)) ||
- get_user(kp->lut_size, &up->lut_size) ||
- get_user(lut, &up->lut))
+ assign_in_user(&kp->lut_size, &up->lut_size) ||
+ get_user(lut, &up->lut) ||
+ put_user(compat_ptr(lut), &kp->lut))
return -EFAULT;
- kp->lut = (void __force *)compat_ptr(lut);
return 0;
}
@@ -846,11 +854,19 @@ static long atomisp_do_compat_ioctl(struct file *file,
struct atomisp_metadata md;
struct atomisp_metadata_with_type md_with_type;
struct atomisp_sensor_ae_bracketing_lut lut;
- } karg;
- mm_segment_t old_fs;
+ } __user *karg;
void __user *up = compat_ptr(arg);
long err = -ENOIOCTLCMD;
+ karg = compat_alloc_user_space(
+ sizeof(*karg) + (cmd == ATOMISP_IOC_S_PARAMETERS32 ?
+ sizeof(struct atomisp_shading_table) +
+ sizeof(struct atomisp_morph_table) +
+ sizeof(struct atomisp_dis_coefficients) +
+ sizeof(struct atomisp_dvs_6axis_config) : 0));
+ if (!karg)
+ return -ENOMEM;
+
/* First, convert the command. */
switch (cmd) {
case ATOMISP_IOC_G_HISTOGRAM32:
@@ -936,130 +952,127 @@ static long atomisp_do_compat_ioctl(struct file *file,
switch (cmd) {
case ATOMISP_IOC_G_HISTOGRAM:
case ATOMISP_IOC_S_HISTOGRAM:
- err = get_atomisp_histogram32(&karg.his, up);
+ err = get_atomisp_histogram32(&karg->his, up);
break;
case ATOMISP_IOC_G_DIS_STAT:
- err = get_atomisp_dis_statistics32(&karg.dis_s, up);
+ err = get_atomisp_dis_statistics32(&karg->dis_s, up);
break;
case ATOMISP_IOC_S_DIS_COEFS:
- err = get_atomisp_dis_coefficients32(&karg.dis_c, up);
+ err = get_atomisp_dis_coefficients32(&karg->dis_c, up);
break;
case ATOMISP_IOC_S_DIS_VECTOR:
- err = get_atomisp_dvs_6axis_config32(&karg.dvs_c, up);
+ err = get_atomisp_dvs_6axis_config32(&karg->dvs_c, up);
break;
case ATOMISP_IOC_G_3A_STAT:
- err = get_atomisp_3a_statistics32(&karg.s3a_s, up);
+ err = get_atomisp_3a_statistics32(&karg->s3a_s, up);
break;
case ATOMISP_IOC_G_ISP_GDC_TAB:
case ATOMISP_IOC_S_ISP_GDC_TAB:
- err = get_atomisp_morph_table32(&karg.mor_t, up);
+ err = get_atomisp_morph_table32(&karg->mor_t, up);
break;
case ATOMISP_IOC_S_ISP_FPN_TABLE:
- err = get_v4l2_framebuffer32(&karg.v4l2_buf, up);
+ err = get_v4l2_framebuffer32(&karg->v4l2_buf, up);
break;
case ATOMISP_IOC_G_ISP_OVERLAY:
case ATOMISP_IOC_S_ISP_OVERLAY:
- err = get_atomisp_overlay32(&karg.overlay, up);
+ err = get_atomisp_overlay32(&karg->overlay, up);
break;
case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
- err = get_atomisp_calibration_group32(&karg.cal_grp, up);
+ err = get_atomisp_calibration_group32(&karg->cal_grp, up);
break;
case ATOMISP_IOC_ACC_LOAD:
- err = get_atomisp_acc_fw_load32(&karg.acc_fw_load, up);
+ err = get_atomisp_acc_fw_load32(&karg->acc_fw_load, up);
break;
case ATOMISP_IOC_ACC_S_ARG:
case ATOMISP_IOC_ACC_DESTAB:
- err = get_atomisp_acc_fw_arg32(&karg.acc_fw_arg, up);
+ err = get_atomisp_acc_fw_arg32(&karg->acc_fw_arg, up);
break;
case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
- err = get_v4l2_private_int_data32(&karg.v4l2_pri_data, up);
+ err = get_v4l2_private_int_data32(&karg->v4l2_pri_data, up);
break;
case ATOMISP_IOC_S_ISP_SHD_TAB:
- err = get_atomisp_shading_table32(&karg.shd_tbl, up);
+ err = get_atomisp_shading_table32(&karg->shd_tbl, up);
break;
case ATOMISP_IOC_ACC_MAP:
case ATOMISP_IOC_ACC_UNMAP:
- err = get_atomisp_acc_map32(&karg.acc_map, up);
+ err = get_atomisp_acc_map32(&karg->acc_map, up);
break;
case ATOMISP_IOC_ACC_S_MAPPED_ARG:
- err = get_atomisp_acc_s_mapped_arg32(&karg.acc_map_arg, up);
+ err = get_atomisp_acc_s_mapped_arg32(&karg->acc_map_arg, up);
break;
case ATOMISP_IOC_S_PARAMETERS:
- err = get_atomisp_parameters32(&karg.param, up);
+ err = get_atomisp_parameters32(&karg->param, up);
break;
case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
- err = get_atomisp_acc_fw_load_to_pipe32(&karg.acc_fw_to_pipe,
+ err = get_atomisp_acc_fw_load_to_pipe32(&karg->acc_fw_to_pipe,
up);
break;
case ATOMISP_IOC_G_METADATA:
- err = get_atomisp_metadata_stat32(&karg.md, up);
+ err = get_atomisp_metadata_stat32(&karg->md, up);
break;
case ATOMISP_IOC_G_METADATA_BY_TYPE:
- err = get_atomisp_metadata_by_type_stat32(&karg.md_with_type,
- up);
+ err = get_atomisp_metadata_by_type_stat32(&karg->md_with_type,
+ up);
break;
case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
- err = get_atomisp_sensor_ae_bracketing_lut(&karg.lut, up);
+ err = get_atomisp_sensor_ae_bracketing_lut(&karg->lut, up);
break;
}
if (err)
return err;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- err = native_ioctl(file, cmd, (unsigned long)&karg);
- set_fs(old_fs);
+ err = native_ioctl(file, cmd, (unsigned long)karg);
if (err)
return err;
switch (cmd) {
case ATOMISP_IOC_G_HISTOGRAM:
- err = put_atomisp_histogram32(&karg.his, up);
+ err = put_atomisp_histogram32(&karg->his, up);
break;
case ATOMISP_IOC_G_DIS_STAT:
- err = put_atomisp_dis_statistics32(&karg.dis_s, up);
+ err = put_atomisp_dis_statistics32(&karg->dis_s, up);
break;
case ATOMISP_IOC_G_3A_STAT:
- err = put_atomisp_3a_statistics32(&karg.s3a_s, up);
+ err = put_atomisp_3a_statistics32(&karg->s3a_s, up);
break;
case ATOMISP_IOC_G_ISP_GDC_TAB:
- err = put_atomisp_morph_table32(&karg.mor_t, up);
+ err = put_atomisp_morph_table32(&karg->mor_t, up);
break;
case ATOMISP_IOC_G_ISP_OVERLAY:
- err = put_atomisp_overlay32(&karg.overlay, up);
+ err = put_atomisp_overlay32(&karg->overlay, up);
break;
case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
- err = put_atomisp_calibration_group32(&karg.cal_grp, up);
+ err = put_atomisp_calibration_group32(&karg->cal_grp, up);
break;
case ATOMISP_IOC_ACC_LOAD:
- err = put_atomisp_acc_fw_load32(&karg.acc_fw_load, up);
+ err = put_atomisp_acc_fw_load32(&karg->acc_fw_load, up);
break;
case ATOMISP_IOC_ACC_S_ARG:
case ATOMISP_IOC_ACC_DESTAB:
- err = put_atomisp_acc_fw_arg32(&karg.acc_fw_arg, up);
+ err = put_atomisp_acc_fw_arg32(&karg->acc_fw_arg, up);
break;
case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
- err = put_v4l2_private_int_data32(&karg.v4l2_pri_data, up);
+ err = put_v4l2_private_int_data32(&karg->v4l2_pri_data, up);
break;
case ATOMISP_IOC_ACC_MAP:
case ATOMISP_IOC_ACC_UNMAP:
- err = put_atomisp_acc_map32(&karg.acc_map, up);
+ err = put_atomisp_acc_map32(&karg->acc_map, up);
break;
case ATOMISP_IOC_ACC_S_MAPPED_ARG:
- err = put_atomisp_acc_s_mapped_arg32(&karg.acc_map_arg, up);
+ err = put_atomisp_acc_s_mapped_arg32(&karg->acc_map_arg, up);
break;
case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
- err = put_atomisp_acc_fw_load_to_pipe32(&karg.acc_fw_to_pipe,
+ err = put_atomisp_acc_fw_load_to_pipe32(&karg->acc_fw_to_pipe,
up);
break;
case ATOMISP_IOC_G_METADATA:
- err = put_atomisp_metadata_stat32(&karg.md, up);
+ err = put_atomisp_metadata_stat32(&karg->md, up);
break;
case ATOMISP_IOC_G_METADATA_BY_TYPE:
- err = put_atomisp_metadata_by_type_stat32(&karg.md_with_type,
- up);
+ err = put_atomisp_metadata_by_type_stat32(&karg->md_with_type,
+ up);
break;
}
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h
index 7e59ccb88a2e..86d3fbe01378 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.c b/drivers/staging/media/atomisp/pci/atomisp_csi2.c
index a2638863206e..060b8765ae96 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_csi2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -384,9 +385,9 @@ static void atomisp_csi2_configure_isp2401(struct atomisp_sub_device *asd)
for (n = 0; n < csi2_port_lanes[port] + 1; n++) {
hrt_address base = csi2_port_base[port] + csi2_lane_base[n];
- atomisp_store_uint32(base + CSI2_REG_RX_CSI_DLY_CNT_TERMEN,
+ atomisp_css2_hw_store_32(base + CSI2_REG_RX_CSI_DLY_CNT_TERMEN,
n == 0 ? clk_termen : dat_termen);
- atomisp_store_uint32(base + CSI2_REG_RX_CSI_DLY_CNT_SETTLE,
+ atomisp_css2_hw_store_32(base + CSI2_REG_RX_CSI_DLY_CNT_SETTLE,
n == 0 ? clk_settle : dat_settle);
}
}
diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.h b/drivers/staging/media/atomisp/pci/atomisp_csi2.h
index 739c26f0807a..59261e8f1a1a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_csi2.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_dfs_tables.h b/drivers/staging/media/atomisp/pci/atomisp_dfs_tables.h
index 9680f211d424..8f1cc3fca13a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_dfs_tables.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_dfs_tables.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c
index 4a6ea021ddcc..fe0e2bfde27f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for atomisp driver sysfs interface
*
@@ -24,6 +25,7 @@
#include "atomisp_ioctl.h"
#include "atomisp_drvfs.h"
#include "hmm/hmm.h"
+#include "ia_css_debug.h"
/*
* _iunit_debug:
@@ -94,7 +96,7 @@ opt_err:
static ssize_t iunit_dbglvl_show(struct device_driver *drv, char *buf)
{
- iunit_debug.dbglvl = atomisp_css_debug_get_dtrace_level();
+ iunit_debug.dbglvl = dbg_level;
return sprintf(buf, "dtrace level:%u\n", iunit_debug.dbglvl);
}
@@ -106,7 +108,7 @@ static ssize_t iunit_dbglvl_store(struct device_driver *drv, const char *buf,
|| iunit_debug.dbglvl > 9) {
return -ERANGE;
}
- atomisp_css_debug_set_dtrace_level(iunit_debug.dbglvl);
+ ia_css_debug_set_dtrace_level(iunit_debug.dbglvl);
return size;
}
diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h
index 7c99240d107a..4911037231fb 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for atomisp driver sysfs interface.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_file.c b/drivers/staging/media/atomisp/pci/atomisp_file.c
index 4ab0390316cf..e568ca99c45a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_file.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_file.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -50,11 +51,12 @@ static void file_work(struct work_struct *work)
V4L2_SUBDEV_FORMAT_ACTIVE,
ATOMISP_SUBDEV_PAD_SINK);
- while (!atomisp_css_isp_has_started())
+ while (!ia_css_isp_has_started())
usleep_range(1000, 1500);
- atomisp_css_send_input_frame(asd, buf, isp_sink_fmt.width,
- isp_sink_fmt.height);
+ ia_css_stream_send_input_frame(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
+ buf, isp_sink_fmt.width,
+ isp_sink_fmt.height);
dev_dbg(isp->dev, "<%s: streaming done\n", __func__);
}
@@ -217,7 +219,7 @@ int atomisp_file_input_init(struct atomisp_device *isp)
v4l2_subdev_init(sd, &file_input_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- strcpy(sd->name, "file_input_subdev");
+ strscpy(sd->name, "file_input_subdev", sizeof(sd->name));
v4l2_set_subdevdata(sd, file_dev);
pads[0].flags = MEDIA_PAD_FL_SINK;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_file.h b/drivers/staging/media/atomisp/pci/atomisp_file.h
index e38f8bc389f1..f166a2aefff1 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_file.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_file.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 667d6f7d1d5e..453bb6913550 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -34,11 +35,8 @@
#include "atomisp-regs.h"
#include "hmm/hmm.h"
-#include "hrt/hive_isp_css_mm_hrt.h"
-
#include "type_support.h"
#include "device_access/device_access.h"
-#include "memory_access/memory_access.h"
#include "atomisp_acc.h"
@@ -88,7 +86,7 @@ static int atomisp_buf_prepare(struct videobuf_queue *vq,
static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_metadata_buf *metadata_buf;
enum atomisp_metadata_type md_type =
@@ -128,7 +126,7 @@ static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd,
static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_s3a_buf *s3a_buf;
struct list_head *s3a_list;
@@ -170,7 +168,7 @@ static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd,
static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_pipe_id css_pipe_id)
{
struct atomisp_dis_buf *dis_buf;
unsigned long irqflags;
@@ -213,12 +211,12 @@ static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd,
int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
struct atomisp_video_pipe *pipe,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_buffer_type css_buf_type,
- enum atomisp_css_pipe_id css_pipe_id)
+ enum ia_css_buffer_type css_buf_type,
+ enum ia_css_pipe_id css_pipe_id)
{
struct videobuf_vmalloc_memory *vm_mem;
struct atomisp_css_params_with_list *param;
- struct atomisp_css_dvs_grid_info *dvs_grid =
+ struct ia_css_dvs_grid_info *dvs_grid =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
unsigned long irqflags;
int err = 0;
@@ -255,14 +253,13 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
err = atomisp_calculate_real_zoom_region(asd,
&param->params.dz_config, css_pipe_id);
if (!err)
- atomisp_css_set_dz_config(asd,
- &param->params.dz_config);
+ asd->params.config.dz_config = &param->params.dz_config;
}
atomisp_css_set_isp_config_applied_frame(asd,
vm_mem->vaddr);
atomisp_css_update_isp_params_on_pipe(asd,
asd->stream_env[stream_id].pipes[css_pipe_id]);
- asd->params.dvs_6axis = (struct atomisp_css_dvs_6axis *)
+ asd->params.dvs_6axis = (struct ia_css_dvs_6axis_config *)
param->params.dvs_6axis;
/*
@@ -302,19 +299,19 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
/* enqueue 3A/DIS/metadata buffers */
if (asd->params.curr_grid_info.s3a_grid.enable &&
css_pipe_id == asd->params.s3a_enabled_pipe &&
- css_buf_type == CSS_BUFFER_TYPE_OUTPUT_FRAME)
+ css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
atomisp_q_one_s3a_buffer(asd, stream_id,
css_pipe_id);
if (asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_info.
metadata_info.size &&
- css_buf_type == CSS_BUFFER_TYPE_OUTPUT_FRAME)
+ css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
atomisp_q_one_metadata_buffer(asd, stream_id,
css_pipe_id);
if (dvs_grid && dvs_grid->enable &&
- css_pipe_id == CSS_PIPE_ID_VIDEO &&
- css_buf_type == CSS_BUFFER_TYPE_OUTPUT_FRAME)
+ css_pipe_id == IA_CSS_PIPE_ID_VIDEO &&
+ css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
atomisp_q_one_dis_buffer(asd, stream_id,
css_pipe_id);
}
@@ -323,7 +320,7 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
}
static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
- enum atomisp_css_pipe_id pipe_id,
+ enum ia_css_pipe_id pipe_id,
uint16_t source_pad)
{
if (ATOMISP_USE_YUVPP(asd)) {
@@ -331,24 +328,24 @@ static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
if (asd->continuous_mode->val &&
asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
- return CSS_BUFFER_TYPE_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
- return CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
else
- return CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
}
/*when run SDV case*/
if (asd->continuous_mode->val &&
asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
- return CSS_BUFFER_TYPE_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
- return CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO)
- return CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
else
- return CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
}
/*other case: default setting*/
@@ -356,27 +353,27 @@ static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
(source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
- return CSS_BUFFER_TYPE_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
else
- return CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
}
- if (pipe_id == CSS_PIPE_ID_COPY ||
+ if (pipe_id == IA_CSS_PIPE_ID_COPY ||
source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
(source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
- return CSS_BUFFER_TYPE_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
else
- return CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
+ return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
}
static int atomisp_qbuffers_to_css_for_all_pipes(struct atomisp_sub_device *asd)
{
- enum atomisp_css_buffer_type buf_type;
- enum atomisp_css_pipe_id css_capture_pipe_id = CSS_PIPE_ID_COPY;
- enum atomisp_css_pipe_id css_preview_pipe_id = CSS_PIPE_ID_COPY;
- enum atomisp_css_pipe_id css_video_pipe_id = CSS_PIPE_ID_COPY;
+ enum ia_css_buffer_type buf_type;
+ enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
+ enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
+ enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
enum atomisp_input_stream_id input_stream_id;
struct atomisp_video_pipe *capture_pipe;
struct atomisp_video_pipe *preview_pipe;
@@ -413,10 +410,10 @@ static int atomisp_qbuffers_to_css_for_all_pipes(struct atomisp_sub_device *asd)
/* queue all available buffers to css */
int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
{
- enum atomisp_css_buffer_type buf_type;
- enum atomisp_css_pipe_id css_capture_pipe_id = CSS_PIPE_ID_NUM;
- enum atomisp_css_pipe_id css_preview_pipe_id = CSS_PIPE_ID_NUM;
- enum atomisp_css_pipe_id css_video_pipe_id = CSS_PIPE_ID_NUM;
+ enum ia_css_buffer_type buf_type;
+ enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_NUM;
+ enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_NUM;
+ enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_NUM;
enum atomisp_input_stream_id input_stream_id;
struct atomisp_video_pipe *capture_pipe = NULL;
struct atomisp_video_pipe *vf_pipe = NULL;
@@ -432,43 +429,43 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
video_pipe = &asd->video_out_video_capture;
- css_video_pipe_id = CSS_PIPE_ID_VIDEO;
+ css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
} else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
preview_pipe = &asd->video_out_capture;
- css_preview_pipe_id = CSS_PIPE_ID_CAPTURE;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
if (asd->continuous_mode->val) {
capture_pipe = &asd->video_out_capture;
vf_pipe = &asd->video_out_vf;
- css_capture_pipe_id = CSS_PIPE_ID_CAPTURE;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
}
video_pipe = &asd->video_out_video_capture;
preview_pipe = &asd->video_out_preview;
- css_video_pipe_id = CSS_PIPE_ID_VIDEO;
- css_preview_pipe_id = CSS_PIPE_ID_VIDEO;
+ css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO;
} else if (asd->continuous_mode->val) {
capture_pipe = &asd->video_out_capture;
vf_pipe = &asd->video_out_vf;
preview_pipe = &asd->video_out_preview;
- css_preview_pipe_id = CSS_PIPE_ID_PREVIEW;
- css_capture_pipe_id = CSS_PIPE_ID_CAPTURE;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
preview_pipe = &asd->video_out_preview;
- css_preview_pipe_id = CSS_PIPE_ID_PREVIEW;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
} else {
/* ATOMISP_RUN_MODE_STILL_CAPTURE */
capture_pipe = &asd->video_out_capture;
if (!raw_mode)
vf_pipe = &asd->video_out_vf;
- css_capture_pipe_id = CSS_PIPE_ID_CAPTURE;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
}
#ifdef ISP2401_NEW_INPUT_SYSTEM
if (asd->copy_mode) {
- css_capture_pipe_id = CSS_PIPE_ID_COPY;
- css_preview_pipe_id = CSS_PIPE_ID_COPY;
- css_video_pipe_id = CSS_PIPE_ID_COPY;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
+ css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
}
#endif
@@ -476,9 +473,9 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
capture_pipe = &asd->video_out_capture;
video_pipe = &asd->video_out_video_capture;
preview_pipe = &asd->video_out_preview;
- css_capture_pipe_id = CSS_PIPE_ID_COPY;
- css_video_pipe_id = CSS_PIPE_ID_YUVPP;
- css_preview_pipe_id = CSS_PIPE_ID_YUVPP;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
+ css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
}
if (capture_pipe) {
@@ -491,7 +488,7 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
* use yuvpp pipe for SOC camera.
*/
if (ATOMISP_USE_YUVPP(asd))
- css_capture_pipe_id = CSS_PIPE_ID_YUVPP;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
atomisp_q_video_buffers_to_css(asd, capture_pipe,
input_stream_id,
@@ -511,7 +508,7 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
* use yuvpp pipe for SOC camera.
*/
if (ATOMISP_USE_YUVPP(asd))
- css_capture_pipe_id = CSS_PIPE_ID_YUVPP;
+ css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
atomisp_q_video_buffers_to_css(asd, vf_pipe,
input_stream_id,
buf_type, css_capture_pipe_id);
@@ -521,10 +518,10 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
buf_type = atomisp_get_css_buf_type(
asd, css_preview_pipe_id,
atomisp_subdev_source_pad(&preview_pipe->vdev));
- if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == CSS_PIPE_ID_YUVPP)
+ if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
/* else for ext isp use case */
- else if (css_preview_pipe_id == CSS_PIPE_ID_YUVPP)
+ else if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream)
input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW;
@@ -535,7 +532,7 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
* use yuvpp pipe for SOC camera.
*/
if (ATOMISP_USE_YUVPP(asd))
- css_preview_pipe_id = CSS_PIPE_ID_YUVPP;
+ css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
atomisp_q_video_buffers_to_css(asd, preview_pipe,
input_stream_id,
@@ -555,7 +552,7 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
* use yuvpp pipe for SOC camera.
*/
if (ATOMISP_USE_YUVPP(asd))
- css_video_pipe_id = CSS_PIPE_ID_YUVPP;
+ css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP;
atomisp_q_video_buffers_to_css(asd, video_pipe,
input_stream_id,
@@ -717,7 +714,7 @@ static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
asd->params.online_process = 1;
asd->params.yuv_ds_en = 0;
/* s3a grid not enabled for any pipe */
- asd->params.s3a_enabled_pipe = CSS_PIPE_ID_NUM;
+ asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM;
asd->params.offline_parm.num_captures = 1;
asd->params.offline_parm.skip_frames = 0;
@@ -1000,7 +997,7 @@ subdev_uninit:
atomisp_css_uninit(isp);
if (defer_fw_load) {
- atomisp_css_unload_firmware(isp);
+ ia_css_unload_firmware();
isp->css_env.isp_css_fw.data = NULL;
isp->css_env.isp_css_fw.bytes = 0;
}
@@ -1054,7 +1051,7 @@ static int do_isp_mm_remap(struct atomisp_device *isp,
}
static int frame_mmap(struct atomisp_device *isp,
- const struct atomisp_css_frame *frame, struct vm_area_struct *vma)
+ const struct ia_css_frame *frame, struct vm_area_struct *vma)
{
ia_css_ptr isp_virt;
u32 host_virt;
@@ -1127,7 +1124,7 @@ int atomisp_videobuf_mmap_mapper(struct videobuf_queue *q,
* There is also padding on the right (padded_width - width).
*/
static int remove_pad_from_frame(struct atomisp_device *isp,
- struct atomisp_css_frame *in_frame, __u32 width, __u32 height)
+ struct ia_css_frame *in_frame, __u32 width, __u32 height)
{
unsigned int i;
unsigned short *buffer;
@@ -1164,7 +1161,7 @@ static int atomisp_mmap(struct file *file, struct vm_area_struct *vma)
struct atomisp_device *isp = video_get_drvdata(vdev);
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
struct atomisp_sub_device *asd = pipe->asd;
- struct atomisp_css_frame *raw_virt_addr;
+ struct ia_css_frame *raw_virt_addr;
u32 start = vma->vm_start;
u32 end = vma->vm_end;
u32 size = end - start;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.h b/drivers/staging/media/atomisp/pci/atomisp_fops.h
index e05e8f3a4442..3f1e442ba782 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -24,8 +25,8 @@
int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
struct atomisp_video_pipe *pipe,
enum atomisp_input_stream_id stream_id,
- enum atomisp_css_buffer_type css_buf_type,
- enum atomisp_css_pipe_id css_pipe_id);
+ enum ia_css_buffer_type css_buf_type,
+ enum ia_css_pipe_id css_pipe_id);
unsigned int atomisp_dev_users(struct atomisp_device *isp);
unsigned int atomisp_sub_dev_users(struct atomisp_sub_device *asd);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index b096b7d30463..1af9da8acf4c 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/dmi.h>
@@ -327,15 +328,6 @@ static struct gmin_cfg_var i8880_vars[] = {
{},
};
-static struct gmin_cfg_var asus_vars[] = {
- {"OVTI2680:00_CsiPort", "1"},
- {"OVTI2680:00_CsiLanes", "1"},
- {"OVTI2680:00_CsiFmt", "15"},
- {"OVTI2680:00_CsiBayer", "0"},
- {"OVTI2680:00_CamClk", "1"},
- {},
-};
-
static const struct dmi_system_id gmin_vars[] = {
{
.ident = "BYT-T FFD8",
@@ -373,13 +365,6 @@ static const struct dmi_system_id gmin_vars[] = {
},
.driver_data = i8880_vars,
},
- {
- .ident = "T101HA",
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "T101HA"),
- },
- .driver_data = asus_vars,
- },
{}
};
@@ -387,6 +372,10 @@ static const struct dmi_system_id gmin_vars[] = {
0xa9, 0x71, 0xe8, 0x77, \
0x75, 0x60, 0x68, 0xf7)
+static const guid_t atomisp_dsm_guid = GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d,
+ 0x97, 0xb9, 0x88, 0x2a,
+ 0x68, 0x60, 0xa4, 0xbe);
+
#define CFG_VAR_NAME_MAX 64
#define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */
@@ -454,15 +443,28 @@ static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg,
static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
{
- int i, ret;
- struct device *dev;
struct i2c_client *power = NULL, *client = v4l2_get_subdevdata(subdev);
+ struct acpi_device *adev;
+ acpi_handle handle;
+ struct device *dev;
+ int i, ret;
if (!client)
return NULL;
dev = &client->dev;
+ handle = ACPI_HANDLE(dev);
+
+ // FIXME: may need to release resources allocated by acpi_bus_get_device()
+ if (!handle || acpi_bus_get_device(handle, &adev)) {
+ dev_err(dev, "Error could not get ACPI device\n");
+ return NULL;
+ }
+
+ dev_info(&client->dev, "%s: ACPI detected it on bus ID=%s, HID=%s\n",
+ __func__, acpi_device_bid(adev), acpi_device_hid(adev));
+
if (!pmic_id) {
if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power))
pmic_id = PMIC_TI;
@@ -479,7 +481,6 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
if (i >= MAX_SUBDEVS)
return NULL;
-
if (power) {
gmin_subdevs[i].pwm_i2c_addr = power->addr;
dev_info(dev,
@@ -616,6 +617,7 @@ static int axp_regulator_set(struct device *dev, struct gmin_subdev *gs,
static int axp_v1p8_on(struct device *dev, struct gmin_subdev *gs)
{
int ret;
+
ret = axp_regulator_set(dev, gs, gs->eldo2_sel_reg, gs->eldo2_1p8v,
ELDO_CTRL_REG, gs->eldo2_ctrl_shift, true);
if (ret)
@@ -640,6 +642,7 @@ static int axp_v1p8_on(struct device *dev, struct gmin_subdev *gs)
static int axp_v1p8_off(struct device *dev, struct gmin_subdev *gs)
{
int ret;
+
ret = axp_regulator_set(dev, gs, gs->eldo1_sel_reg, gs->eldo1_1p8v,
ELDO_CTRL_REG, gs->eldo1_ctrl_shift, false);
if (ret)
@@ -650,7 +653,6 @@ static int axp_v1p8_off(struct device *dev, struct gmin_subdev *gs)
return ret;
}
-
static int gmin_gpio0_ctrl(struct v4l2_subdev *subdev, int on)
{
struct gmin_subdev *gs = find_gmin_subdev(subdev);
@@ -753,7 +755,6 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on)
dev_err(subdev->dev, "Couldn't set power mode for v1p2\n");
}
-
return -EINVAL;
}
@@ -921,7 +922,8 @@ int atomisp_gmin_register_vcm_control(struct camera_vcm_control *vcmCtrl)
}
EXPORT_SYMBOL_GPL(atomisp_gmin_register_vcm_control);
-static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
+static int gmin_get_hardcoded_var(struct device *dev,
+ struct gmin_cfg_var *varlist,
const char *var8, char *out, size_t *out_len)
{
struct gmin_cfg_var *gv;
@@ -932,11 +934,13 @@ static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
if (strcmp(var8, gv->name))
continue;
+ dev_info(dev, "Found DMI entry for '%s'\n", var8);
+
vl = strlen(gv->val);
if (vl > *out_len - 1)
return -ENOSPC;
- strcpy(out, gv->val);
+ strscpy(out, gv->val, *out_len);
*out_len = vl;
return 0;
}
@@ -944,6 +948,75 @@ static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
return -EINVAL;
}
+
+static int gmin_get_config_dsm_var(struct device *dev,
+ const char *var,
+ char *out, size_t *out_len)
+{
+ acpi_handle handle = ACPI_HANDLE(dev);
+ union acpi_object *obj, *cur = NULL;
+ int i;
+
+ obj = acpi_evaluate_dsm(handle, &atomisp_dsm_guid, 0, 0, NULL);
+ if (!obj) {
+ dev_info_once(dev, "Didn't find ACPI _DSM table.\n");
+ return -EINVAL;
+ }
+
+#if 0 /* Just for debugging purposes */
+ for (i = 0; i < obj->package.count; i++) {
+ union acpi_object *cur = &obj->package.elements[i];
+
+ if (cur->type == ACPI_TYPE_INTEGER)
+ dev_info(dev, "object #%d, type %d, value: %lld\n",
+ i, cur->type, cur->integer.value);
+ else if (cur->type == ACPI_TYPE_STRING)
+ dev_info(dev, "object #%d, type %d, string: %s\n",
+ i, cur->type, cur->string.pointer);
+ else
+ dev_info(dev, "object #%d, type %d\n",
+ i, cur->type);
+ }
+#endif
+
+ /* Seek for the desired var */
+ for (i = 0; i < obj->package.count - 1; i += 2) {
+ if (obj->package.elements[i].type == ACPI_TYPE_STRING &&
+ !strcmp(obj->package.elements[i].string.pointer, var)) {
+ /* Next element should be the required value */
+ cur = &obj->package.elements[i + 1];
+ break;
+ }
+ }
+
+ if (!cur) {
+ dev_info(dev, "didn't found _DSM entry for '%s'\n", var);
+ ACPI_FREE(obj);
+ return -EINVAL;
+ }
+
+ /*
+ * While it could be possible to have an ACPI_TYPE_INTEGER,
+ * and read the value from cur->integer.value, the table
+ * seen so far uses the string type. So, produce a warning
+ * if it founds something different than string, letting it
+ * to fall back to the old code.
+ */
+ if (cur && cur->type != ACPI_TYPE_STRING) {
+ dev_info(dev, "found non-string _DSM entry for '%s'\n", var);
+ ACPI_FREE(obj);
+ return -EINVAL;
+ }
+
+ dev_info(dev, "found _DSM entry for '%s': %s\n", var,
+ cur->string.pointer);
+ strscpy(out, cur->string.pointer, *out_len);
+ *out_len = strlen(cur->string.pointer);
+
+ ACPI_FREE(obj);
+ return 0;
+}
+
/* Retrieves a device-specific configuration variable. The dev
* argument should be a device with an ACPI companion, as all
* configuration is based on firmware ID.
@@ -953,12 +1026,21 @@ static int gmin_get_config_var(struct device *maindev,
const char *var,
char *out, size_t *out_len)
{
- char var8[CFG_VAR_NAME_MAX];
efi_char16_t var16[CFG_VAR_NAME_MAX];
- struct efivar_entry *ev;
const struct dmi_system_id *id;
- int i, ret;
struct device *dev = maindev;
+ char var8[CFG_VAR_NAME_MAX];
+ struct efivar_entry *ev;
+ int i, ret;
+
+ /* For sensors, try first to use the _DSM table */
+ if (!is_gmin) {
+ ret = gmin_get_config_dsm_var(maindev, var, out, out_len);
+ if (!ret)
+ return 0;
+ }
+
+ /* Fall-back to other approaches */
if (!is_gmin && ACPI_COMPANION(dev))
dev = &ACPI_COMPANION(dev)->dev;
@@ -977,9 +1059,10 @@ static int gmin_get_config_var(struct device *maindev,
*/
id = dmi_first_match(gmin_vars);
if (id) {
- dev_info(maindev, "Found DMI entry for '%s'\n", var8);
- return gmin_get_hardcoded_var(id->driver_data, var8, out,
- out_len);
+ ret = gmin_get_hardcoded_var(maindev, id->driver_data, var8,
+ out, out_len);
+ if (!ret)
+ return 0;
}
/* Our variable names are ASCII by construction, but EFI names
@@ -1009,9 +1092,9 @@ static int gmin_get_config_var(struct device *maindev,
*out_len = ev->var.DataSize;
dev_info(maindev, "found EFI entry for '%s'\n", var8);
} else if (is_gmin) {
- dev_warn(maindev, "Failed to find gmin variable %s\n", var8);
+ dev_info(maindev, "Failed to find EFI gmin variable %s\n", var8);
} else {
- dev_warn(maindev, "Failed to find variable %s\n", var8);
+ dev_info(maindev, "Failed to find EFI variable %s\n", var8);
}
kfree(ev);
@@ -1030,6 +1113,8 @@ int gmin_get_var_int(struct device *dev, bool is_gmin, const char *var, int def)
if (!ret) {
val[len] = 0;
ret = kstrtol(val, 0, &result);
+ } else {
+ dev_info(dev, "%s: using default (%d)\n", var, def);
}
return ret ? def : result;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_helper.h b/drivers/staging/media/atomisp/pci/atomisp_helper.h
deleted file mode 100644
index 56035063f81d..000000000000
--- a/drivers/staging/media/atomisp/pci/atomisp_helper.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Support for Medifield PNW Camera Imaging ISP subsystem.
- *
- * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
- *
- * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- *
- */
-#ifndef _atomisp_helper_h_
-#define _atomisp_helper_h_
-extern void __iomem *atomisp_io_base;
-
-static inline void __iomem *atomisp_get_io_virt_addr(unsigned int address)
-{
- void __iomem *ret = atomisp_io_base + (address & 0x003FFFFF);
- return ret;
-}
-#endif
diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h
index 26539f3ffb9b..ff3becd41110 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index a5e71e5b714e..9404a678fa6f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -39,8 +40,6 @@
#include "device_access.h"
#include "irq.h"
-#include "hrt/hive_isp_css_mm_hrt.h"
-
static const char *DRIVER = "atomisp"; /* max size 15 */
static const char *CARD = "ATOM ISP"; /* max size 31 */
@@ -341,163 +340,163 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
.pixelformat = V4L2_PIX_FMT_YUV420,
.depth = 12,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV420,
- .sh_fmt = CSS_FRAME_FORMAT_YUV420,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_YUV420,
.description = "YUV420, planar",
.planar = true
}, {
.pixelformat = V4L2_PIX_FMT_YVU420,
.depth = 12,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_YVU420,
- .sh_fmt = CSS_FRAME_FORMAT_YV12,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_YV12,
.description = "YVU420, planar",
.planar = true
}, {
.pixelformat = V4L2_PIX_FMT_YUV422P,
.depth = 16,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV422P,
- .sh_fmt = CSS_FRAME_FORMAT_YUV422,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_YUV422,
.description = "YUV422, planar",
.planar = true
}, {
.pixelformat = V4L2_PIX_FMT_YUV444,
.depth = 24,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV444,
- .sh_fmt = CSS_FRAME_FORMAT_YUV444,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_YUV444,
.description = "YUV444"
}, {
.pixelformat = V4L2_PIX_FMT_NV12,
.depth = 12,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_NV12,
- .sh_fmt = CSS_FRAME_FORMAT_NV12,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_NV12,
.description = "NV12, Y-plane, CbCr interleaved",
.planar = true
}, {
.pixelformat = V4L2_PIX_FMT_NV21,
.depth = 12,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_NV21,
- .sh_fmt = CSS_FRAME_FORMAT_NV21,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_NV21,
.description = "NV21, Y-plane, CbCr interleaved",
.planar = true
}, {
.pixelformat = V4L2_PIX_FMT_NV16,
.depth = 16,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_NV16,
- .sh_fmt = CSS_FRAME_FORMAT_NV16,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_NV16,
.description = "NV16, Y-plane, CbCr interleaved",
.planar = true
}, {
.pixelformat = V4L2_PIX_FMT_YUYV,
.depth = 16,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_YUYV,
- .sh_fmt = CSS_FRAME_FORMAT_YUYV,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_YUYV,
.description = "YUYV, interleaved"
}, {
.pixelformat = V4L2_PIX_FMT_UYVY,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
- .sh_fmt = CSS_FRAME_FORMAT_UYVY,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
.description = "UYVY, interleaved"
}, { /* This one is for parallel sensors! DO NOT USE! */
.pixelformat = V4L2_PIX_FMT_UYVY,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
- .sh_fmt = CSS_FRAME_FORMAT_UYVY,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
.description = "UYVY, interleaved"
}, {
.pixelformat = V4L2_PIX_FMT_SBGGR16,
.depth = 16,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_SBGGR16,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 16"
}, {
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.depth = 8,
.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 8"
}, {
.pixelformat = V4L2_PIX_FMT_SGBRG8,
.depth = 8,
.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 8"
}, {
.pixelformat = V4L2_PIX_FMT_SGRBG8,
.depth = 8,
.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 8"
}, {
.pixelformat = V4L2_PIX_FMT_SRGGB8,
.depth = 8,
.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 8"
}, {
.pixelformat = V4L2_PIX_FMT_SBGGR10,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 10"
}, {
.pixelformat = V4L2_PIX_FMT_SGBRG10,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 10"
}, {
.pixelformat = V4L2_PIX_FMT_SGRBG10,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 10"
}, {
.pixelformat = V4L2_PIX_FMT_SRGGB10,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 10"
}, {
.pixelformat = V4L2_PIX_FMT_SBGGR12,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 12"
}, {
.pixelformat = V4L2_PIX_FMT_SGBRG12,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 12"
}, {
.pixelformat = V4L2_PIX_FMT_SGRBG12,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 12"
}, {
.pixelformat = V4L2_PIX_FMT_SRGGB12,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
- .sh_fmt = CSS_FRAME_FORMAT_RAW,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
.description = "Bayer 12"
}, {
.pixelformat = V4L2_PIX_FMT_RGB32,
.depth = 32,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32,
- .sh_fmt = CSS_FRAME_FORMAT_RGBA888,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888,
.description = "32 RGB 8-8-8-8"
}, {
.pixelformat = V4L2_PIX_FMT_RGB565,
.depth = 16,
.mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE,
- .sh_fmt = CSS_FRAME_FORMAT_RGB565,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_RGB565,
.description = "16 RGB 5-6-5"
}, {
.pixelformat = V4L2_PIX_FMT_JPEG,
.depth = 8,
.mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
- .sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
.description = "JPEG"
},
#if 0
@@ -506,7 +505,7 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
.pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
.depth = 8,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW,
- .sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
+ .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
.description = "Custom RAW for M10MO"
},
#endif
@@ -548,8 +547,8 @@ static int atomisp_querycap(struct file *file, void *fh,
struct video_device *vdev = video_devdata(file);
struct atomisp_device *isp = video_get_drvdata(vdev);
- strscpy(cap->driver, DRIVER, sizeof(cap->driver) - 1);
- strscpy(cap->card, CARD, sizeof(cap->card) - 1);
+ strscpy(cap->driver, DRIVER, sizeof(cap->driver));
+ strscpy(cap->card, CARD, sizeof(cap->card));
snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
pci_name(isp->pdev));
@@ -574,8 +573,8 @@ static int atomisp_enum_input(struct file *file, void *fh,
return -EINVAL;
memset(input, 0, sizeof(struct v4l2_input));
- strncpy(input->name, isp->inputs[index].camera->name,
- sizeof(input->name) - 1);
+ strscpy(input->name, isp->inputs[index].camera->name,
+ sizeof(input->name));
/*
* HACK: append actuator's name to sensor's
@@ -583,7 +582,7 @@ static int atomisp_enum_input(struct file *file, void *fh,
* ioctl is the only way to enum inputs + possible external actuators
* for 3A tuning purpose.
*/
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
motor = isp->inputs[index].motor;
else
motor = isp->motor;
@@ -594,8 +593,8 @@ static int atomisp_enum_input(struct file *file, void *fh,
if (max_size > 1) {
input->name[cur_len] = '+';
- strncpy(&input->name[cur_len + 1],
- motor->name, max_size - 1);
+ strscpy(&input->name[cur_len + 1],
+ motor->name, max_size);
}
}
@@ -733,7 +732,7 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
goto error;
}
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
motor = isp->inputs[input].motor;
} else {
motor = isp->motor;
@@ -789,7 +788,7 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
* Is the atomisp-supported format is valid for the
* sensor (configuration)? If not, skip it.
*/
- if (format->sh_fmt == CSS_FRAME_FORMAT_RAW
+ if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW
&& format->mbus_code != code.code)
continue;
@@ -893,7 +892,7 @@ void atomisp_videobuf_free_buf(struct videobuf_buffer *vb)
vm_mem = vb->priv;
if (vm_mem && vm_mem->vaddr) {
- atomisp_css_frame_free(vm_mem->vaddr);
+ ia_css_frame_free(vm_mem->vaddr);
vm_mem->vaddr = NULL;
}
}
@@ -920,7 +919,7 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf;
struct atomisp_metadata_buf *md_buf = NULL, *_md_buf;
int count;
- struct atomisp_css_dvs_grid_info *dvs_grid_info =
+ struct ia_css_dvs_grid_info *dvs_grid_info =
atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
unsigned int i;
@@ -1024,8 +1023,8 @@ int __atomisp_reqbufs(struct file *file, void *fh,
struct video_device *vdev = video_devdata(file);
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
struct atomisp_sub_device *asd = pipe->asd;
- struct atomisp_css_frame_info frame_info;
- struct atomisp_css_frame *frame;
+ struct ia_css_frame_info frame_info;
+ struct ia_css_frame *frame;
struct videobuf_vmalloc_memory *vm_mem;
u16 source_pad = atomisp_subdev_source_pad(vdev);
u16 stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
@@ -1054,7 +1053,7 @@ int __atomisp_reqbufs(struct file *file, void *fh,
atomisp_alloc_css_stat_bufs(asd, stream_id);
/*
- * for user pointer type, buffers are not really allcated here,
+ * for user pointer type, buffers are not really allocated here,
* buffers are setup in QBUF operation through v4l2_buffer structure
*/
if (req->memory == V4L2_MEMORY_USERPTR)
@@ -1069,7 +1068,7 @@ int __atomisp_reqbufs(struct file *file, void *fh,
* memory management function
*/
for (i = 0; i < req->count; i++) {
- if (atomisp_css_frame_allocate_from_info(&frame, &frame_info))
+ if (ia_css_frame_allocate_from_info(&frame, &frame_info))
goto error;
vm_mem = pipe->capq.bufs[i]->priv;
vm_mem->vaddr = frame;
@@ -1080,11 +1079,11 @@ int __atomisp_reqbufs(struct file *file, void *fh,
error:
while (i--) {
vm_mem = pipe->capq.bufs[i]->priv;
- atomisp_css_frame_free(vm_mem->vaddr);
+ ia_css_frame_free(vm_mem->vaddr);
}
if (asd->vf_frame)
- atomisp_css_frame_free(asd->vf_frame);
+ ia_css_frame_free(asd->vf_frame);
return -ENOMEM;
}
@@ -1152,8 +1151,8 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
struct atomisp_sub_device *asd = pipe->asd;
struct videobuf_buffer *vb;
struct videobuf_vmalloc_memory *vm_mem;
- struct atomisp_css_frame_info frame_info;
- struct atomisp_css_frame *handle = NULL;
+ struct ia_css_frame_info frame_info;
+ struct ia_css_frame *handle = NULL;
u32 length;
u32 pgnr;
int ret = 0;
@@ -1183,8 +1182,6 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
* address and reprograme out page table properly
*/
if (buf->memory == V4L2_MEMORY_USERPTR) {
- struct hrt_userbuffer_attr attributes;
-
vb = pipe->capq.bufs[buf->index];
vm_mem = vb->priv;
if (!vm_mem) {
@@ -1204,45 +1201,9 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
goto error;
}
- attributes.pgnr = pgnr;
- attributes.type = HRT_USR_PTR;
-#ifdef CONFIG_ION
- if (!atomisp_hw_is_isp2401) {
- if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_ION)
- attributes.type = HRT_USR_ION;
- } else {
- if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_ION) {
- attributes.type = HRT_USR_ION;
- if (asd->ion_dev_fd->val != ION_FD_UNSET) {
- dev_dbg(isp->dev, "ION buffer queued, share_fd=%lddev_fd=%d.\n",
- buf->m.userptr, asd->ion_dev_fd->val);
- /*
- * Make sure the shared fd we just got
- * from user space isn't larger than
- * the space we have for it.
- */
- if ((buf->m.userptr &
- (ATOMISP_ION_DEVICE_FD_MASK)) != 0) {
- dev_err(isp->dev,
- "Error: v4l2 buffer fd:0X%0lX > 0XFFFF.\n",
- buf->m.userptr);
- ret = -EINVAL;
- goto error;
- }
- buf->m.userptr |= asd->ion_dev_fd->val <<
- ATOMISP_ION_DEVICE_FD_OFFSET;
- } else {
- dev_err(isp->dev, "v4l2 buffer type is ION, \
- but no dev fd set from userspace.\n");
- ret = -EINVAL;
- goto error;
- }
- }
- }
-#endif
- ret = atomisp_css_frame_map(&handle, &frame_info,
+ ret = ia_css_frame_map(&handle, &frame_info,
(void __user *)buf->m.userptr,
- 0, &attributes);
+ 0, pgnr);
if (ret) {
dev_err(isp->dev, "Failed to map user buffer\n");
goto error;
@@ -1250,7 +1211,7 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
if (vm_mem->vaddr) {
mutex_lock(&pipe->capq.vb_lock);
- atomisp_css_frame_free(vm_mem->vaddr);
+ ia_css_frame_free(vm_mem->vaddr);
vm_mem->vaddr = NULL;
vb->state = VIDEOBUF_NEEDS_INIT;
mutex_unlock(&pipe->capq.vb_lock);
@@ -1265,6 +1226,10 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
buf->flags |= V4L2_BUF_FLAG_MAPPED;
buf->flags |= V4L2_BUF_FLAG_QUEUED;
buf->flags &= ~V4L2_BUF_FLAG_DONE;
+
+ /*
+ * For mmap, frames were allocated at request buffers
+ */
}
done:
@@ -1299,7 +1264,7 @@ done:
} else {
atomisp_qbuffers_to_css(asd);
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (!atomisp_is_wdt_running(asd) && atomisp_buffers_queued(asd))
atomisp_wdt_start(asd);
} else {
@@ -1323,7 +1288,7 @@ done:
pipe->capq.streaming &&
!asd->enable_raw_buffer_lock->val &&
asd->params.offline_parm.num_captures == 1) {
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
asd->pending_capture_request++;
dev_dbg(isp->dev, "Add one pending capture request.\n");
} else {
@@ -1401,7 +1366,7 @@ static int __get_frame_exp_id(struct atomisp_video_pipe *pipe,
struct v4l2_buffer *buf)
{
struct videobuf_vmalloc_memory *vm_mem;
- struct atomisp_css_frame *handle;
+ struct ia_css_frame *handle;
int i;
for (i = 0; pipe->capq.bufs[i]; i++) {
@@ -1443,7 +1408,8 @@ static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
ret = videobuf_dqbuf(&pipe->capq, buf, file->f_flags & O_NONBLOCK);
if (ret) {
- dev_dbg(isp->dev, "<%s: %d\n", __func__, ret);
+ if (ret != -EAGAIN)
+ dev_dbg(isp->dev, "<%s: %d\n", __func__, ret);
return ret;
}
rt_mutex_lock(&isp->mutex);
@@ -1469,16 +1435,16 @@ static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
return 0;
}
-enum atomisp_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
+enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
{
if (ATOMISP_USE_YUVPP(asd))
- return CSS_PIPE_ID_YUVPP;
+ return IA_CSS_PIPE_ID_YUVPP;
if (asd->continuous_mode->val) {
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
- return CSS_PIPE_ID_VIDEO;
+ return IA_CSS_PIPE_ID_VIDEO;
else
- return CSS_PIPE_ID_PREVIEW;
+ return IA_CSS_PIPE_ID_PREVIEW;
}
/*
@@ -1486,7 +1452,7 @@ enum atomisp_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
* scaling but it has one frame delay due to CSS internal buffering.
*/
if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
- return CSS_PIPE_ID_VIDEO;
+ return IA_CSS_PIPE_ID_VIDEO;
/*
* Disable vf_pp and run CSS in still capture mode. In this mode
@@ -1494,17 +1460,17 @@ enum atomisp_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
* is not available.
*/
if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT)
- return CSS_PIPE_ID_CAPTURE;
+ return IA_CSS_PIPE_ID_CAPTURE;
switch (asd->run_mode->val) {
case ATOMISP_RUN_MODE_PREVIEW:
- return CSS_PIPE_ID_PREVIEW;
+ return IA_CSS_PIPE_ID_PREVIEW;
case ATOMISP_RUN_MODE_VIDEO:
- return CSS_PIPE_ID_VIDEO;
+ return IA_CSS_PIPE_ID_VIDEO;
case ATOMISP_RUN_MODE_STILL_CAPTURE:
/* fall through */
default:
- return CSS_PIPE_ID_CAPTURE;
+ return IA_CSS_PIPE_ID_CAPTURE;
}
}
@@ -1598,7 +1564,7 @@ int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp,
/* FIXME! ISP2400 */
static void __wdt_on_master_slave_sensor(struct atomisp_device *isp,
- unsigned int wdt_duration)
+ unsigned int wdt_duration)
{
if (atomisp_buffers_queued(&isp->asd[0]))
atomisp_wdt_refresh(&isp->asd[0], wdt_duration);
@@ -1654,9 +1620,9 @@ static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd)
ATOMISP_SUBDEV_PAD_SINK);
if (sink->width * sink->height >= 4096 * 3072)
- atomisp_store_uint32(DMA_BURST_SIZE_REG, 0x7F);
+ atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x7F);
else
- atomisp_store_uint32(DMA_BURST_SIZE_REG, 0x00);
+ atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);
}
/*
@@ -1669,7 +1635,7 @@ static int atomisp_streamon(struct file *file, void *fh,
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
struct atomisp_sub_device *asd = pipe->asd;
struct atomisp_device *isp = video_get_drvdata(vdev);
- enum atomisp_css_pipe_id css_pipe_id;
+ enum ia_css_pipe_id css_pipe_id;
unsigned int sensor_start_stream;
unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION;
int ret = 0;
@@ -1721,7 +1687,7 @@ static int atomisp_streamon(struct file *file, void *fh,
/* Reset pending capture request count. */
asd->pending_capture_request = 0;
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
asd->re_trigger_capture = false;
if ((atomisp_subdev_streaming_count(asd) > sensor_start_stream) &&
@@ -1793,8 +1759,7 @@ static int atomisp_streamon(struct file *file, void *fh,
if (asd->params.css_update_params_needed) {
atomisp_apply_css_parameters(asd, &asd->params.css_param);
if (asd->params.css_param.update_flag.dz_config)
- atomisp_css_set_dz_config(asd,
- &asd->params.css_param.dz_config);
+ asd->params.config.dz_config = &asd->params.css_param.dz_config;
atomisp_css_update_isp_params(asd);
asd->params.css_update_params_needed = false;
memset(&asd->params.css_param.update_flag, 0,
@@ -1835,7 +1800,7 @@ start_sensor:
}
if (!isp->sw_contex.file_input) {
- atomisp_css_irq_enable(isp, CSS_IRQ_INFO_CSS_RECEIVER_SOF,
+ atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
atomisp_css_valid_sof(isp));
atomisp_csi2_configure(asd);
/*
@@ -1845,15 +1810,15 @@ start_sensor:
if (atomisp_streaming_count(isp) > 1) {
if (atomisp_freq_scaling(isp,
ATOMISP_DFS_MODE_MAX, false) < 0)
- dev_dbg(isp->dev, "dfs failed!\n");
+ dev_dbg(isp->dev, "DFS max mode failed!\n");
} else {
if (atomisp_freq_scaling(isp,
ATOMISP_DFS_MODE_AUTO, false) < 0)
- dev_dbg(isp->dev, "dfs failed!\n");
+ dev_dbg(isp->dev, "DFS auto mode failed!\n");
}
} else {
if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false) < 0)
- dev_dbg(isp->dev, "dfs failed!\n");
+ dev_dbg(isp->dev, "DFS max mode failed!\n");
}
if (asd->depth_mode->val && atomisp_streaming_count(isp) ==
@@ -1863,7 +1828,7 @@ start_sensor:
dev_err(isp->dev, "master slave sensor stream on failed!\n");
goto out;
}
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
__wdt_on_master_slave_sensor(isp, wdt_duration);
} else {
__wdt_on_master_slave_sensor_pipe(pipe, wdt_duration, true);
@@ -1871,7 +1836,7 @@ start_sensor:
goto start_delay_wq;
} else if (asd->depth_mode->val && (atomisp_streaming_count(isp) <
ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) {
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
__wdt_on_master_slave_sensor_pipe(pipe, wdt_duration, false);
goto start_delay_wq;
}
@@ -1893,7 +1858,7 @@ start_sensor:
goto out;
}
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (atomisp_buffers_queued(asd))
atomisp_wdt_refresh(asd, wdt_duration);
} else {
@@ -1933,7 +1898,7 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
struct atomisp_video_pipe *preview_pipe = NULL;
struct atomisp_video_pipe *video_pipe = NULL;
struct videobuf_buffer *vb, *_vb;
- enum atomisp_css_pipe_id css_pipe_id;
+ enum ia_css_pipe_id css_pipe_id;
int ret;
unsigned long flags;
bool first_streamoff = false;
@@ -2039,7 +2004,7 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
atomisp_clear_css_buffer_counters(asd);
if (!isp->sw_contex.file_input)
- atomisp_css_irq_enable(isp, CSS_IRQ_INFO_CSS_RECEIVER_SOF,
+ atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
false);
if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
@@ -2352,7 +2317,7 @@ static int atomisp_queryctl(struct file *file, void *fh,
case V4L2_CID_FOCUS_ABSOLUTE:
case V4L2_CID_FOCUS_RELATIVE:
case V4L2_CID_FOCUS_STATUS:
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
return v4l2_queryctrl(isp->inputs[asd->input_curr].camera->
ctrl_handler, qc);
}
@@ -2393,7 +2358,7 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
int i;
int ret = 0;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
motor = isp->inputs[asd->input_curr].motor;
else
motor = isp->motor;
@@ -2502,8 +2467,7 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
int i;
int ret = 0;
-
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
motor = isp->inputs[asd->input_curr].motor;
else
motor = isp->motor;
@@ -2519,7 +2483,7 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
case V4L2_CID_EXPOSURE_METERING:
case V4L2_CID_IRIS_ABSOLUTE:
case V4L2_CID_FNUMBER_ABSOLUTE:
- case V4L2_CID_VCM_TIMEING:
+ case V4L2_CID_VCM_TIMING:
case V4L2_CID_VCM_SLEW:
case V4L2_CID_3A_LOCK:
case V4L2_CID_TEST_PATTERN:
@@ -2732,7 +2696,7 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
else
asd = atomisp_to_video_pipe(vdev)->asd;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
motor = isp->inputs[asd->input_curr].motor;
else
motor = isp->motor;
@@ -2757,7 +2721,7 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
}
switch (cmd) {
case ATOMISP_IOC_S_SENSOR_RUNMODE:
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
err = atomisp_set_sensor_runmode(asd, arg);
else
err = -EINVAL;
@@ -2932,7 +2896,7 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
core, ioctl, cmd, arg);
break;
case ATOMISP_IOC_G_UPDATE_EXPOSURE:
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
core, ioctl, cmd, arg);
else
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.h b/drivers/staging/media/atomisp/pci/atomisp_ioctl.h
index 5f3f2ec2539b..412bfcf33c0f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -43,7 +44,7 @@ int __atomisp_reqbufs(struct file *file, void *fh,
int atomisp_reqbufs(struct file *file, void *fh,
struct v4l2_requestbuffers *req);
-enum atomisp_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device
+enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device
*asd);
void atomisp_videobuf_free_buf(struct videobuf_buffer *vb);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
index 46590129cbe3..6ba817f15655 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -30,29 +31,31 @@
#include "atomisp_internal.h"
const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = {
- { MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_BGGR, CSS_FORMAT_RAW_8 },
- { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_GBRG, CSS_FORMAT_RAW_8 },
- { MEDIA_BUS_FMT_SGRBG8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_GRBG, CSS_FORMAT_RAW_8 },
- { MEDIA_BUS_FMT_SRGGB8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_RGGB, CSS_FORMAT_RAW_8 },
- { MEDIA_BUS_FMT_SBGGR10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_BGGR, CSS_FORMAT_RAW_10 },
- { MEDIA_BUS_FMT_SGBRG10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_GBRG, CSS_FORMAT_RAW_10 },
- { MEDIA_BUS_FMT_SGRBG10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_GRBG, CSS_FORMAT_RAW_10 },
- { MEDIA_BUS_FMT_SRGGB10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_RGGB, CSS_FORMAT_RAW_10 },
- { MEDIA_BUS_FMT_SBGGR12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_BGGR, CSS_FORMAT_RAW_12 },
- { MEDIA_BUS_FMT_SGBRG12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_GBRG, CSS_FORMAT_RAW_12 },
- { MEDIA_BUS_FMT_SGRBG12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_GRBG, CSS_FORMAT_RAW_12 },
- { MEDIA_BUS_FMT_SRGGB12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_RGGB, CSS_FORMAT_RAW_12 },
- { MEDIA_BUS_FMT_UYVY8_1X16, 8, 8, ATOMISP_INPUT_FORMAT_YUV422_8, 0, ATOMISP_INPUT_FORMAT_YUV422_8 },
- { MEDIA_BUS_FMT_YUYV8_1X16, 8, 8, ATOMISP_INPUT_FORMAT_YUV422_8, 0, ATOMISP_INPUT_FORMAT_YUV422_8 },
- { MEDIA_BUS_FMT_JPEG_1X8, 8, 8, CSS_FRAME_FORMAT_BINARY_8, 0, ATOMISP_INPUT_FORMAT_BINARY_8 },
- { V4L2_MBUS_FMT_CUSTOM_NV12, 12, 12, CSS_FRAME_FORMAT_NV12, 0, CSS_FRAME_FORMAT_NV12 },
- { V4L2_MBUS_FMT_CUSTOM_NV21, 12, 12, CSS_FRAME_FORMAT_NV21, 0, CSS_FRAME_FORMAT_NV21 },
- { V4L2_MBUS_FMT_CUSTOM_YUV420, 12, 12, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY, 0, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY },
+ { MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, IA_CSS_BAYER_ORDER_BGGR },
+ { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, IA_CSS_BAYER_ORDER_GBRG },
+ { MEDIA_BUS_FMT_SGRBG8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, IA_CSS_BAYER_ORDER_GRBG },
+ { MEDIA_BUS_FMT_SRGGB8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, IA_CSS_BAYER_ORDER_RGGB },
+ { MEDIA_BUS_FMT_SBGGR10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, IA_CSS_BAYER_ORDER_BGGR },
+ { MEDIA_BUS_FMT_SGBRG10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, IA_CSS_BAYER_ORDER_GBRG },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, IA_CSS_BAYER_ORDER_GRBG },
+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, IA_CSS_BAYER_ORDER_RGGB },
+ { MEDIA_BUS_FMT_SBGGR12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, IA_CSS_BAYER_ORDER_BGGR },
+ { MEDIA_BUS_FMT_SGBRG12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, IA_CSS_BAYER_ORDER_GBRG },
+ { MEDIA_BUS_FMT_SGRBG12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, IA_CSS_BAYER_ORDER_GRBG },
+ { MEDIA_BUS_FMT_SRGGB12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, IA_CSS_BAYER_ORDER_RGGB },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 8, 8, ATOMISP_INPUT_FORMAT_YUV422_8, 0 },
+ { MEDIA_BUS_FMT_YUYV8_1X16, 8, 8, ATOMISP_INPUT_FORMAT_YUV422_8, 0 },
+#if 0 // disabled due to clang warnings
+ { MEDIA_BUS_FMT_JPEG_1X8, 8, 8, IA_CSS_FRAME_FORMAT_BINARY_8, 0 },
+ { V4L2_MBUS_FMT_CUSTOM_NV12, 12, 12, IA_CSS_FRAME_FORMAT_NV12, 0 },
+ { V4L2_MBUS_FMT_CUSTOM_NV21, 12, 12, IA_CSS_FRAME_FORMAT_NV21, 0 },
+#endif
+ { V4L2_MBUS_FMT_CUSTOM_YUV420, 12, 12, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY, 0 },
#if 0
- { V4L2_MBUS_FMT_CUSTOM_M10MO_RAW, 8, 8, CSS_FRAME_FORMAT_BINARY_8, 0, ATOMISP_INPUT_FORMAT_BINARY_8 },
+ { V4L2_MBUS_FMT_CUSTOM_M10MO_RAW, 8, 8, IA_CSS_FRAME_FORMAT_BINARY_8, 0 },
#endif
/* no valid V4L2 MBUS code for metadata format, so leave it 0. */
- { 0, 0, 0, ATOMISP_INPUT_FORMAT_EMBEDDED, 0, ATOMISP_INPUT_FORMAT_EMBEDDED },
+ { 0, 0, 0, ATOMISP_INPUT_FORMAT_EMBEDDED, 0 },
{}
};
@@ -639,7 +642,7 @@ void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
atomisp_css_input_set_bayer_order(isp_sd, stream_id,
fc->bayer_order);
atomisp_css_input_set_format(isp_sd, stream_id,
- fc->css_stream_fmt);
+ fc->atomisp_in_fmt);
atomisp_css_set_default_isys_config(isp_sd, stream_id,
ffmt);
}
@@ -1219,15 +1222,10 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
v4l2_ctrl_new_custom(&asd->ctrl_handler,
&ctrl_disable_dz,
NULL);
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
asd->select_isp_version = v4l2_ctrl_new_custom(&asd->ctrl_handler,
&ctrl_select_isp_version,
NULL);
-#if 0 /* #ifdef CONFIG_ION */
- asd->ion_dev_fd = v4l2_ctrl_new_custom(&asd->ctrl_handler,
- &ctrl_ion_dev_fd,
- NULL);
-#endif
}
/* Make controls visible on subdev as well. */
@@ -1348,8 +1346,7 @@ int atomisp_subdev_register_entities(struct atomisp_sub_device *asd,
* Should any of those use V4L2_CAP_META_OUTPUT? Probably yes.
*/
- device_caps = V4L2_CAP_IO_MC |
- V4L2_CAP_VIDEO_CAPTURE |
+ device_caps = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING;
/* Register the subdev and video node. */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
index b0d561224beb..330a77eed8aa 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -59,8 +60,7 @@ struct atomisp_in_fmt_conv {
u8 bpp; /* bits per pixel */
u8 depth; /* uncompressed */
enum atomisp_input_format atomisp_in_fmt;
- enum atomisp_css_bayer_order bayer_order;
- enum atomisp_input_format css_stream_fmt;
+ enum ia_css_bayer_order bayer_order;
};
struct atomisp_sub_device;
@@ -215,8 +215,8 @@ struct atomisp_subdev_params {
unsigned int histogram_elenum;
/* Current grid info */
- struct atomisp_css_grid_info curr_grid_info;
- enum atomisp_css_pipe_id s3a_enabled_pipe;
+ struct ia_css_grid_info curr_grid_info;
+ enum ia_css_pipe_id s3a_enabled_pipe;
int s3a_output_bytes;
@@ -225,7 +225,7 @@ struct atomisp_subdev_params {
struct ia_css_dz_config dz_config; /** Digital Zoom */
struct ia_css_capture_config capture_config;
- struct atomisp_css_isp_config config;
+ struct ia_css_isp_config config;
/* current configurations */
struct atomisp_css_params css_param;
@@ -240,7 +240,7 @@ struct atomisp_subdev_params {
u32 metadata_width_size;
struct ia_css_dvs2_statistics *dvs_stat;
- struct atomisp_css_dvs_6axis *dvs_6axis;
+ struct ia_css_dvs_6axis_config *dvs_6axis;
u32 exp_id;
int dvs_hor_coef_bytes;
int dvs_ver_coef_bytes;
@@ -265,7 +265,7 @@ struct atomisp_css_params_with_list {
};
struct atomisp_acc_fw {
- struct atomisp_css_fw_info *fw;
+ struct ia_css_fw_info *fw;
unsigned int handle;
unsigned int flags;
unsigned int type;
@@ -323,7 +323,7 @@ struct atomisp_sub_device {
struct {
struct list_head fw;
struct list_head memory_maps;
- struct atomisp_css_pipeline *pipeline;
+ struct ia_css_pipe *pipeline;
bool extension_mode;
struct ida ida;
struct completion acc_done;
@@ -335,11 +335,11 @@ struct atomisp_sub_device {
struct atomisp_stream_env stream_env[ATOMISP_INPUT_STREAM_NUM];
struct v4l2_pix_format dvs_envelop;
- unsigned int s3a_bufs_in_css[CSS_PIPE_ID_NUM];
+ unsigned int s3a_bufs_in_css[IA_CSS_PIPE_ID_NUM];
unsigned int dis_bufs_in_css;
unsigned int metadata_bufs_in_css
- [ATOMISP_INPUT_STREAM_NUM][CSS_PIPE_ID_NUM];
+ [ATOMISP_INPUT_STREAM_NUM][IA_CSS_PIPE_ID_NUM];
/* The list of free and available metadata buffers for CSS */
struct list_head metadata[ATOMISP_METADATA_TYPE_NUM];
/* The list of metadata buffers which have been en-queued to CSS */
@@ -358,8 +358,8 @@ struct atomisp_sub_device {
struct list_head dis_stats_in_css;
spinlock_t dis_stats_lock;
- struct atomisp_css_frame *vf_frame; /* TODO: needed? */
- struct atomisp_css_frame *raw_output_frame;
+ struct ia_css_frame *vf_frame; /* TODO: needed? */
+ struct ia_css_frame *raw_output_frame;
enum atomisp_frame_status frame_status[VIDEO_MAX_FRAME];
/* This field specifies which camera (v4l2 input) is selected. */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_tables.h b/drivers/staging/media/atomisp/pci/atomisp_tables.h
index 22eac8a25dba..e718a3f661f9 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_tables.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_tables.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -22,25 +23,25 @@
#include "sh_css_params.h"
/*Sepia image effect table*/
-static struct atomisp_css_cc_config sepia_cc_config = {
+static struct ia_css_cc_config sepia_cc_config = {
.fraction_bits = 8,
.matrix = {141, 18, 68, -40, -5, -19, 35, 4, 16},
};
/*Negative image effect table*/
-static struct atomisp_css_cc_config nega_cc_config = {
+static struct ia_css_cc_config nega_cc_config = {
.fraction_bits = 8,
.matrix = {255, 29, 120, 0, 374, 342, 0, 672, -301},
};
/*Mono image effect table*/
-static struct atomisp_css_cc_config mono_cc_config = {
+static struct ia_css_cc_config mono_cc_config = {
.fraction_bits = 8,
.matrix = {255, 29, 120, 0, 0, 0, 0, 0, 0},
};
/*Skin whiten image effect table*/
-static struct atomisp_css_macc_table skin_low_macc_table = {
+static struct ia_css_macc_table skin_low_macc_table = {
.data = {
8192, 0, 0, 8192,
8192, 0, 0, 8192,
@@ -61,7 +62,7 @@ static struct atomisp_css_macc_table skin_low_macc_table = {
}
};
-static struct atomisp_css_macc_table skin_medium_macc_table = {
+static struct ia_css_macc_table skin_medium_macc_table = {
.data = {
8192, 0, 0, 8192,
8192, 0, 0, 8192,
@@ -82,7 +83,7 @@ static struct atomisp_css_macc_table skin_medium_macc_table = {
}
};
-static struct atomisp_css_macc_table skin_high_macc_table = {
+static struct ia_css_macc_table skin_high_macc_table = {
.data = {
8192, 0, 0, 8192,
8192, 0, 0, 8192,
@@ -104,7 +105,7 @@ static struct atomisp_css_macc_table skin_high_macc_table = {
};
/*Blue enhencement image effect table*/
-static struct atomisp_css_macc_table blue_macc_table = {
+static struct ia_css_macc_table blue_macc_table = {
.data = {
9728, -3072, 0, 8192,
8192, 0, 0, 8192,
@@ -126,7 +127,7 @@ static struct atomisp_css_macc_table blue_macc_table = {
};
/*Green enhencement image effect table*/
-static struct atomisp_css_macc_table green_macc_table = {
+static struct ia_css_macc_table green_macc_table = {
.data = {
8192, 0, 0, 8192,
8192, 0, 0, 8192,
@@ -147,7 +148,7 @@ static struct atomisp_css_macc_table green_macc_table = {
}
};
-static struct atomisp_css_ctc_table vivid_ctc_table = {
+static struct ia_css_ctc_table vivid_ctc_table = {
.data.vamem_2 = {
0, 384, 837, 957, 1011, 1062, 1083, 1080,
1078, 1077, 1053, 1039, 1012, 992, 969, 951,
diff --git a/drivers/staging/media/atomisp/pci/atomisp_tpg.c b/drivers/staging/media/atomisp/pci/atomisp_tpg.c
index 97176b54d1ec..1def80bab180 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_tpg.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_tpg.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -147,7 +148,7 @@ int atomisp_tpg_init(struct atomisp_device *isp)
tpg->isp = isp;
v4l2_subdev_init(sd, &tpg_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- strcpy(sd->name, "tpg_subdev");
+ strscpy(sd->name, "tpg_subdev", sizeof(sd->name));
v4l2_set_subdevdata(sd, tpg);
pads[0].flags = MEDIA_PAD_FL_SINK;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_tpg.h b/drivers/staging/media/atomisp/pci/atomisp_tpg.h
index cf492d757773..4176e076f63d 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_tpg.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_tpg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_trace_event.h b/drivers/staging/media/atomisp/pci/atomisp_trace_event.h
index 4d7a6794ee66..538d45e008b5 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_trace_event.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_trace_event.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support Camera Imaging tracer core.
*
@@ -43,7 +44,7 @@ TRACE_EVENT(camera_meminfo,
),
TP_fast_assign(
- strlcpy(__entry->name, name, 24);
+ strscpy(__entry->name, name, 24);
__entry->uptr_size = uptr_size;
__entry->counter = counter;
__entry->sys_size = sys_size;
@@ -73,8 +74,8 @@ TRACE_EVENT(camera_debug,
),
TP_fast_assign(
- strlcpy(__entry->name, name, 24);
- strlcpy(__entry->info, info, 24);
+ strscpy(__entry->name, name, 24);
+ strscpy(__entry->info, info, 24);
__entry->line = line;
),
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index 98cff13d9f93..d36809a0182c 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -42,7 +43,7 @@
#include "hmm/hmm.h"
#include "atomisp_trace_event.h"
-#include "hrt/hive_isp_css_mm_hrt.h"
+#include "sh_css_firmware.h"
#include "device_access.h"
@@ -58,21 +59,21 @@ module_param(skip_fwload, uint, 0644);
MODULE_PARM_DESC(skip_fwload, "Skip atomisp firmware load");
/* set reserved memory pool size in page */
-static unsigned int repool_pgnr;
+static unsigned int repool_pgnr = 32768;
module_param(repool_pgnr, uint, 0644);
MODULE_PARM_DESC(repool_pgnr,
- "Set the reserved memory pool size in page (default:0)");
+ "Set the reserved memory pool size in page (default:32768)");
/* set dynamic memory pool size in page */
unsigned int dypool_pgnr = UINT_MAX;
module_param(dypool_pgnr, uint, 0644);
MODULE_PARM_DESC(dypool_pgnr,
- "Set the dynamic memory pool size in page (default:0)");
+ "Set the dynamic memory pool size in page (default: unlimited)");
-bool dypool_enable;
+bool dypool_enable = true;
module_param(dypool_enable, bool, 0644);
MODULE_PARM_DESC(dypool_enable,
- "dynamic memory pool enable/disable (default:disable)");
+ "dynamic memory pool enable/disable (default:enabled)");
/* memory optimization: deferred firmware loading */
bool defer_fw_load;
@@ -83,7 +84,7 @@ MODULE_PARM_DESC(defer_fw_load,
/* cross componnet debug message flag */
int dbg_level;
module_param(dbg_level, int, 0644);
-MODULE_PARM_DESC(dbg_level, "debug message on/off (default:off)");
+MODULE_PARM_DESC(dbg_level, "debug message level (default:0)");
/* log function switch */
int dbg_func = 2;
@@ -95,6 +96,10 @@ int mipicsi_flag;
module_param(mipicsi_flag, int, 0644);
MODULE_PARM_DESC(mipicsi_flag, "mipi csi compression predictor algorithm");
+static char firmware_name[256];
+module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
+MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the default firmware name.");
+
/*set to 16x16 since this is the amount of lines and pixels the sensor
exports extra. If these are kept at the 10x8 that they were on, in yuv
downscaling modes incorrect resolutions where requested to the sensor
@@ -119,11 +124,6 @@ MODULE_PARM_DESC(pad_h, "extra data for ISP processing");
* be to replace this to something stored inside atomisp allocated
* structures.
*/
-bool atomisp_hw_is_isp2401;
-
-/* Types of atomisp hardware */
-#define HW_IS_ISP2400 0
-#define HW_IS_ISP2401 1
struct device *atomisp_dev;
@@ -349,52 +349,6 @@ static const struct atomisp_dfs_config dfs_config_byt = {
.dfs_table_size = ARRAY_SIZE(dfs_rules_byt),
};
-static const struct atomisp_freq_scaling_rule dfs_rules_byt_cr[] = {
- {
- .width = ISP_FREQ_RULE_ANY,
- .height = ISP_FREQ_RULE_ANY,
- .fps = ISP_FREQ_RULE_ANY,
- .isp_freq = ISP_FREQ_320MHZ,
- .run_mode = ATOMISP_RUN_MODE_VIDEO,
- },
- {
- .width = ISP_FREQ_RULE_ANY,
- .height = ISP_FREQ_RULE_ANY,
- .fps = ISP_FREQ_RULE_ANY,
- .isp_freq = ISP_FREQ_320MHZ,
- .run_mode = ATOMISP_RUN_MODE_STILL_CAPTURE,
- },
- {
- .width = ISP_FREQ_RULE_ANY,
- .height = ISP_FREQ_RULE_ANY,
- .fps = ISP_FREQ_RULE_ANY,
- .isp_freq = ISP_FREQ_320MHZ,
- .run_mode = ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE,
- },
- {
- .width = ISP_FREQ_RULE_ANY,
- .height = ISP_FREQ_RULE_ANY,
- .fps = ISP_FREQ_RULE_ANY,
- .isp_freq = ISP_FREQ_320MHZ,
- .run_mode = ATOMISP_RUN_MODE_PREVIEW,
- },
- {
- .width = ISP_FREQ_RULE_ANY,
- .height = ISP_FREQ_RULE_ANY,
- .fps = ISP_FREQ_RULE_ANY,
- .isp_freq = ISP_FREQ_320MHZ,
- .run_mode = ATOMISP_RUN_MODE_SDV,
- },
-};
-
-static const struct atomisp_dfs_config dfs_config_byt_cr = {
- .lowest_freq = ISP_FREQ_200MHZ,
- .max_freq_at_vmin = ISP_FREQ_320MHZ,
- .highest_freq = ISP_FREQ_320MHZ,
- .dfs_table = dfs_rules_byt_cr,
- .dfs_table_size = ARRAY_SIZE(dfs_rules_byt_cr),
-};
-
static const struct atomisp_freq_scaling_rule dfs_rules_cht[] = {
{
.width = ISP_FREQ_RULE_ANY,
@@ -659,7 +613,7 @@ static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp)
* which has bugs(like sighting:4567697 and 4567699) and
* will be removed in B0
*/
- atomisp_store_uint32(MRFLD_CSI_RECEIVER_SELECTION_REG, 1);
+ atomisp_css2_hw_store_32(MRFLD_CSI_RECEIVER_SELECTION_REG, 1);
return 0;
}
@@ -689,7 +643,7 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
if (!(irq & (1 << INTR_IIR)))
goto done;
- atomisp_store_uint32(MRFLD_INTR_CLEAR_REG, 0xFFFFFFFF);
+ atomisp_css2_hw_store_32(MRFLD_INTR_CLEAR_REG, 0xFFFFFFFF);
atomisp_load_uint32(MRFLD_INTR_STATUS_REG, &irq);
if (irq != 0) {
dev_err(isp->dev,
@@ -704,7 +658,7 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq);
if (!(irq & (1 << INTR_IIR))) {
- atomisp_store_uint32(MRFLD_INTR_ENABLE_REG, 0x0);
+ atomisp_css2_hw_store_32(MRFLD_INTR_ENABLE_REG, 0x0);
goto done;
}
dev_err(isp->dev,
@@ -1084,15 +1038,15 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
/* FIXME: should return -EPROBE_DEFER if not all subdevs were probed */
for (count = 0; count < SUBDEV_WAIT_TIMEOUT_MAX_COUNT; count++) {
int camera_count = 0;
+
for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) {
if (subdevs->type == RAW_CAMERA ||
subdevs->type == SOC_CAMERA)
- camera_count ++;
+ camera_count++;
}
if (camera_count)
break;
msleep(SUBDEV_WAIT_TIMEOUT);
- count++;
}
/* Wait more time to give more time for subdev init code to finish */
msleep(5 * SUBDEV_WAIT_TIMEOUT);
@@ -1143,9 +1097,9 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
switch (subdevs->type) {
case RAW_CAMERA:
- raw_index = isp->input_cnt;
dev_dbg(isp->dev, "raw_index: %d\n", raw_index);
- /* pass-though */
+ raw_index = isp->input_cnt;
+ /* fall through */
case SOC_CAMERA:
dev_dbg(isp->dev, "SOC_INDEX: %d\n", isp->input_cnt);
if (isp->input_cnt >= ATOM_ISP_MAX_INPUTS) {
@@ -1250,7 +1204,7 @@ static int atomisp_register_entities(struct atomisp_device *isp)
isp->media_dev.dev = isp->dev;
- strlcpy(isp->media_dev.model, "Intel Atom ISP",
+ strscpy(isp->media_dev.model, "Intel Atom ISP",
sizeof(isp->media_dev.model));
media_device_init(&isp->media_dev);
@@ -1447,19 +1401,23 @@ atomisp_load_firmware(struct atomisp_device *isp)
if (skip_fwload)
return NULL;
- if ((isp->media_dev.hw_revision >> ATOMISP_HW_REVISION_SHIFT)
- == ATOMISP_HW_REVISION_ISP2401)
- fw_path = "shisp_2401a0_v21.bin";
-
- if (isp->media_dev.hw_revision ==
- ((ATOMISP_HW_REVISION_ISP2401_LEGACY << ATOMISP_HW_REVISION_SHIFT)
- | ATOMISP_HW_STEPPING_A0))
- fw_path = "shisp_2401a0_legacy_v21.bin";
-
- if (isp->media_dev.hw_revision ==
- ((ATOMISP_HW_REVISION_ISP2400 << ATOMISP_HW_REVISION_SHIFT)
- | ATOMISP_HW_STEPPING_B0))
- fw_path = "shisp_2400b0_v21.bin";
+ if (firmware_name[0] != '\0') {
+ fw_path = firmware_name;
+ } else {
+ if ((isp->media_dev.hw_revision >> ATOMISP_HW_REVISION_SHIFT)
+ == ATOMISP_HW_REVISION_ISP2401)
+ fw_path = "shisp_2401a0_v21.bin";
+
+ if (isp->media_dev.hw_revision ==
+ ((ATOMISP_HW_REVISION_ISP2401_LEGACY << ATOMISP_HW_REVISION_SHIFT)
+ | ATOMISP_HW_STEPPING_A0))
+ fw_path = "shisp_2401a0_legacy_v21.bin";
+
+ if (isp->media_dev.hw_revision ==
+ ((ATOMISP_HW_REVISION_ISP2400 << ATOMISP_HW_REVISION_SHIFT)
+ | ATOMISP_HW_STEPPING_B0))
+ fw_path = "shisp_2400b0_v21.bin";
+ }
if (!fw_path) {
dev_err(isp->dev, "Unsupported hw_revision 0x%x\n",
@@ -1494,21 +1452,17 @@ static bool is_valid_device(struct pci_dev *dev,
switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) {
case ATOMISP_PCI_DEVICE_SOC_MRFLD:
a0_max_id = ATOMISP_PCI_REV_MRFLD_A0_MAX;
- atomisp_hw_is_isp2401 = false;
name = "Merrifield";
break;
case ATOMISP_PCI_DEVICE_SOC_BYT:
a0_max_id = ATOMISP_PCI_REV_BYT_A0_MAX;
- atomisp_hw_is_isp2401 = false;
name = "Baytrail";
break;
case ATOMISP_PCI_DEVICE_SOC_ANN:
name = "Anniedale";
- atomisp_hw_is_isp2401 = true;
break;
case ATOMISP_PCI_DEVICE_SOC_CHT:
name = "Cherrytrail";
- atomisp_hw_is_isp2401 = true;
break;
default:
dev_err(&dev->dev, "%s: unknown device ID %x04:%x04\n",
@@ -1528,13 +1482,13 @@ static bool is_valid_device(struct pci_dev *dev,
*/
#if defined(ISP2400)
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
dev_err(&dev->dev, "Support for %s (ISP2401) was disabled at compile time\n",
name);
return false;
}
#else
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
dev_err(&dev->dev, "Support for %s (ISP2400) was disabled at compile time\n",
name);
return false;
@@ -1543,7 +1497,7 @@ static bool is_valid_device(struct pci_dev *dev,
dev_info(&dev->dev, "Detected %s version %d (ISP240%c) on %s\n",
name, dev->revision,
- atomisp_hw_is_isp2401 ? '1' : '0',
+ IS_ISP2401 ? '1' : '0',
product);
return true;
@@ -1564,7 +1518,8 @@ static int init_atomisp_wdts(struct atomisp_device *isp)
for (i = 0; i < isp->num_of_streams; i++) {
struct atomisp_sub_device *asd = &isp->asd[i];
- if (!atomisp_hw_is_isp2401)
+
+ if (!IS_ISP2401)
timer_setup(&asd->wdt, atomisp_wdt, 0);
else {
timer_setup(&asd->video_out_capture.wdt,
@@ -1670,20 +1625,29 @@ static int atomisp_pci_probe(struct pci_dev *dev,
(ATOMISP_HW_REVISION_ISP2400
<< ATOMISP_HW_REVISION_SHIFT) |
ATOMISP_HW_STEPPING_B0;
-#ifdef FIXME
- if (INTEL_MID_BOARD(3, TABLET, BYT, BLK, PRO, CRV2) ||
- INTEL_MID_BOARD(3, TABLET, BYT, BLK, ENG, CRV2)) {
- isp->dfs = &dfs_config_byt_cr;
- isp->hpll_freq = HPLL_FREQ_2000MHZ;
- } else
-#endif
- {
- isp->dfs = &dfs_config_byt;
- isp->hpll_freq = HPLL_FREQ_1600MHZ;
- }
- /* HPLL frequency is known to be device-specific, but we don't
+
+ /*
+ * Note: some Intel-based tablets with Android use a different
+ * DFS table. Based on the comments at the Yocto Aero meta
+ * version of this driver (at the ssid.h header), they're
+ * identified via a "spid" var:
+ *
+ * androidboot.spid=vend:cust:manu:plat:prod:hard
+ *
+ * As we don't have this upstream, nor we know enough details
+ * to use a DMI or PCI match table, the old code was just
+ * removed, but let's keep a note here as a reminder that,
+ * for certain devices, we may need to limit the max DFS
+ * frequency to be below certain values, adjusting the
+ * resolution accordingly.
+ */
+ isp->dfs = &dfs_config_byt;
+
+ /*
+ * HPLL frequency is known to be device-specific, but we don't
* have specs yet for exactly how it varies. Default to
- * BYT-CR but let provisioning set it via EFI variable */
+ * BYT-CR but let provisioning set it via EFI variable
+ */
isp->hpll_freq = gmin_get_var_int(&dev->dev, false, "HpllFreq",
HPLL_FREQ_2000MHZ);
@@ -1735,7 +1699,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
default:
isp->hpll_freq = HPLL_FREQ_1600MHZ;
dev_warn(isp->dev,
- "read HPLL from cck failed.default 1600MHz.\n");
+ "read HPLL from cck failed. Default to 1600 MHz.\n");
}
break;
default:
@@ -1758,7 +1722,8 @@ static int atomisp_pci_probe(struct pci_dev *dev,
goto load_fw_fail;
}
- err = atomisp_css_check_firmware_version(isp);
+ err = sh_css_check_firmware_version(isp->dev,
+ isp->firmware->data);
if (err) {
dev_dbg(&dev->dev, "Firmware version check failed\n");
goto fw_validation_fail;
@@ -1787,7 +1752,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
* bugs(like sighting:4567697 and 4567699) and will be removed
* in B0
*/
- atomisp_store_uint32(MRFLD_CSI_RECEIVER_SELECTION_REG, 1);
+ atomisp_css2_hw_store_32(MRFLD_CSI_RECEIVER_SELECTION_REG, 1);
if ((id->device & ATOMISP_PCI_DEVICE_SOC_MASK) ==
ATOMISP_PCI_DEVICE_SOC_MRFLD) {
@@ -1938,7 +1903,7 @@ static void atomisp_pci_remove(struct pci_dev *dev)
atomisp_acc_cleanup(isp);
- atomisp_css_unload_firmware(isp);
+ ia_css_unload_firmware();
hmm_cleanup();
pm_runtime_forbid(&dev->dev);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.h b/drivers/staging/media/atomisp/pci/atomisp_v4l2.h
index 87881fa6a698..81bb356b8172 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
index 789a2e68cab8..0579deac5535 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h
index 09b049b3bd15..6fa6da859158 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h
index 47c488cec8ad..1071813a284c 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c
index 78e98268e188..d9f7c143794d 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/base/refcount/interface/ia_css_refcount.h b/drivers/staging/media/atomisp/pci/base/refcount/interface/ia_css_refcount.h
index 8cf3b0e0cc39..78cf0cbfb3be 100644
--- a/drivers/staging/media/atomisp/pci/base/refcount/interface/ia_css_refcount.h
+++ b/drivers/staging/media/atomisp/pci/base/refcount/interface/ia_css_refcount.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,17 +17,18 @@
#define _IA_CSS_REFCOUNT_H_
#include <type_support.h>
-#include <system_types.h>
+#include <system_local.h>
#include <ia_css_err.h>
+#include <ia_css_types.h>
-typedef void (*clear_func)(hrt_vaddress ptr);
+typedef void (*clear_func)(ia_css_ptr ptr);
/*! \brief Function for initializing refcount list
*
* \param[in] size Size of the refcount list.
* \return ia_css_err
*/
-enum ia_css_err ia_css_refcount_init(uint32_t size);
+int ia_css_refcount_init(uint32_t size);
/*! \brief Function for de-initializing refcount list
*
@@ -38,9 +40,9 @@ void ia_css_refcount_uninit(void);
*
* \param[in] id ID of the object.
* \param[in] ptr Data of the object (ptr).
- * \return hrt_vaddress (saved address)
+ * \return ia_css_ptr (saved address)
*/
-hrt_vaddress ia_css_refcount_increment(s32 id, hrt_vaddress ptr);
+ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr);
/*! \brief Function for decrease reference by 1.
*
@@ -50,7 +52,7 @@ hrt_vaddress ia_css_refcount_increment(s32 id, hrt_vaddress ptr);
* - true, if it is successful.
* - false, otherwise.
*/
-bool ia_css_refcount_decrement(s32 id, hrt_vaddress ptr);
+bool ia_css_refcount_decrement(s32 id, ia_css_ptr ptr);
/*! \brief Function to check if reference count is 1.
*
@@ -59,7 +61,7 @@ bool ia_css_refcount_decrement(s32 id, hrt_vaddress ptr);
* - true, if it is successful.
* - false, otherwise.
*/
-bool ia_css_refcount_is_single(hrt_vaddress ptr);
+bool ia_css_refcount_is_single(ia_css_ptr ptr);
/*! \brief Function to clear reference list objects.
*
@@ -78,6 +80,6 @@ void ia_css_refcount_clear(s32 id,
* - true, if valid
* - false, if invalid
*/
-bool ia_css_refcount_is_valid(hrt_vaddress ptr);
+bool ia_css_refcount_is_valid(ia_css_ptr ptr);
#endif /* _IA_CSS_REFCOUNT_H_ */
diff --git a/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c b/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c
index e39cc2132953..cf02737cf8d4 100644
--- a/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c
+++ b/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,8 +13,9 @@
* more details.
*/
+#include "hmm.h"
+
#include "ia_css_refcount.h"
-#include "memory_access/memory_access.h"
#include "sh_css_defs.h"
#include "platform_support.h"
@@ -23,10 +25,10 @@
#include "ia_css_debug.h"
/* TODO: enable for other memory aswell
- now only for hrt_vaddress */
+ now only for ia_css_ptr */
struct ia_css_refcount_entry {
u32 count;
- hrt_vaddress data;
+ ia_css_ptr data;
s32 id;
};
@@ -37,7 +39,7 @@ struct ia_css_refcount_list {
static struct ia_css_refcount_list myrefcount;
-static struct ia_css_refcount_entry *refcount_find_entry(hrt_vaddress ptr,
+static struct ia_css_refcount_entry *refcount_find_entry(ia_css_ptr ptr,
bool firstfree)
{
u32 i;
@@ -46,7 +48,7 @@ static struct ia_css_refcount_entry *refcount_find_entry(hrt_vaddress ptr,
return NULL;
if (!myrefcount.items) {
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
- "refcount_find_entry(): Ref count not initiliazed!\n");
+ "refcount_find_entry(): Ref count not initialized!\n");
return NULL;
}
@@ -65,25 +67,25 @@ static struct ia_css_refcount_entry *refcount_find_entry(hrt_vaddress ptr,
return NULL;
}
-enum ia_css_err ia_css_refcount_init(uint32_t size)
+int ia_css_refcount_init(uint32_t size)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if (size == 0) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_refcount_init(): Size of 0 for Ref count init!\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
if (myrefcount.items) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_refcount_init(): Ref count is already initialized\n");
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
myrefcount.items =
- sh_css_malloc(sizeof(struct ia_css_refcount_entry) * size);
+ kvmalloc(sizeof(struct ia_css_refcount_entry) * size, GFP_KERNEL);
if (!myrefcount.items)
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
- if (err == IA_CSS_SUCCESS) {
+ err = -ENOMEM;
+ if (!err) {
memset(myrefcount.items, 0,
sizeof(struct ia_css_refcount_entry) * size);
myrefcount.size = size;
@@ -114,14 +116,14 @@ void ia_css_refcount_uninit(void)
entry->id = 0;
}
}
- sh_css_free(myrefcount.items);
+ kvfree(myrefcount.items);
myrefcount.items = NULL;
myrefcount.size = 0;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_refcount_uninit() leave\n");
}
-hrt_vaddress ia_css_refcount_increment(s32 id, hrt_vaddress ptr)
+ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr)
{
struct ia_css_refcount_entry *entry;
@@ -158,7 +160,7 @@ hrt_vaddress ia_css_refcount_increment(s32 id, hrt_vaddress ptr)
return ptr;
}
-bool ia_css_refcount_decrement(s32 id, hrt_vaddress ptr)
+bool ia_css_refcount_decrement(s32 id, ia_css_ptr ptr)
{
struct ia_css_refcount_entry *entry;
@@ -201,7 +203,7 @@ bool ia_css_refcount_decrement(s32 id, hrt_vaddress ptr)
return false;
}
-bool ia_css_refcount_is_single(hrt_vaddress ptr)
+bool ia_css_refcount_is_single(ia_css_ptr ptr)
{
struct ia_css_refcount_entry *entry;
@@ -262,7 +264,7 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr)
count);
}
-bool ia_css_refcount_is_valid(hrt_vaddress ptr)
+bool ia_css_refcount_is_valid(ia_css_ptr ptr)
{
struct ia_css_refcount_entry *entry;
diff --git a/drivers/staging/media/atomisp/pci/bits.h b/drivers/staging/media/atomisp/pci/bits.h
index c6d2a5cba213..9fab02ebddc5 100644
--- a/drivers/staging/media/atomisp/pci/bits.h
+++ b/drivers/staging/media/atomisp/pci/bits.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h
index 551e8d7c5003..965cfda50707 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -59,10 +60,10 @@ void ia_css_pipe_get_vfpp_binarydesc(
* (= The numerator member in the sh_css_bds_factor structure.)
* @param[out] bds_factor_denominator: The denominator of the bayer downscaling factor.
* (= The denominator member in the sh_css_bds_factor structure.)
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err sh_css_bds_factor_get_numerator_denominator(
+int sh_css_bds_factor_get_numerator_denominator(
unsigned int bds_factor,
unsigned int *bds_factor_numerator,
unsigned int *bds_factor_denominator);
@@ -75,10 +76,10 @@ enum ia_css_err sh_css_bds_factor_get_numerator_denominator(
* @param[in/out] bds_out_info
* @param[in/out] out_info
* @param[in/out] vf_info
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipe_get_preview_binarydesc(
+int ia_css_pipe_get_preview_binarydesc(
struct ia_css_pipe *const pipe,
struct ia_css_binary_descr *preview_descr,
struct ia_css_frame_info *in_info,
@@ -93,10 +94,10 @@ enum ia_css_err ia_css_pipe_get_preview_binarydesc(
* @param[in/out] in_info
* @param[in/out] bds_out_info
* @param[in/out] vf_info
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipe_get_video_binarydesc(
+int ia_css_pipe_get_video_binarydesc(
struct ia_css_pipe *const pipe,
struct ia_css_binary_descr *video_descr,
struct ia_css_frame_info *in_info,
@@ -287,9 +288,9 @@ void ia_css_pipe_get_ldc_binarydesc(
* @param[in] input_res
* @param[in] output_res
* @param[in/out] bds_factor
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*/
-enum ia_css_err binarydesc_calculate_bds_factor(
+int binarydesc_calculate_bds_factor(
struct ia_css_resolution input_res,
struct ia_css_resolution output_res,
unsigned int *bds_factor);
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h
index e58c9190310d..40c8145a0797 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h
index ad60210abe95..c23d1bd915a3 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c
index c6b07d65ce3e..f20c9b02fbe0 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -141,7 +142,7 @@ static struct sh_css_bds_factor bds_factors_list[] = {
{8, 1, SH_CSS_BDS_FACTOR_8_00}
};
-enum ia_css_err sh_css_bds_factor_get_numerator_denominator(
+int sh_css_bds_factor_get_numerator_denominator(
unsigned int bds_factor,
unsigned int *bds_factor_numerator,
unsigned int *bds_factor_denominator)
@@ -153,16 +154,16 @@ enum ia_css_err sh_css_bds_factor_get_numerator_denominator(
if (bds_factors_list[i].bds_factor == bds_factor) {
*bds_factor_numerator = bds_factors_list[i].numerator;
*bds_factor_denominator = bds_factors_list[i].denominator;
- return IA_CSS_SUCCESS;
+ return 0;
}
}
/* Throw an error since bds_factor cannot be found
in bds_factors_list */
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
-enum ia_css_err binarydesc_calculate_bds_factor(
+int binarydesc_calculate_bds_factor(
struct ia_css_resolution input_res,
struct ia_css_resolution output_res,
unsigned int *bds_factor)
@@ -195,15 +196,15 @@ enum ia_css_err binarydesc_calculate_bds_factor(
if (cond) {
*bds_factor = bds_factors_list[i].bds_factor;
- return IA_CSS_SUCCESS;
+ return 0;
}
}
/* Throw an error since a suitable bds_factor cannot be found */
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
-enum ia_css_err ia_css_pipe_get_preview_binarydesc(
+int ia_css_pipe_get_preview_binarydesc(
struct ia_css_pipe *const pipe,
struct ia_css_binary_descr *preview_descr,
struct ia_css_frame_info *in_info,
@@ -211,7 +212,7 @@ enum ia_css_err ia_css_pipe_get_preview_binarydesc(
struct ia_css_frame_info *out_info,
struct ia_css_frame_info *vf_info)
{
- enum ia_css_err err;
+ int err;
struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
int mode = IA_CSS_BINARY_MODE_PREVIEW;
unsigned int i;
@@ -264,7 +265,7 @@ enum ia_css_err ia_css_pipe_get_preview_binarydesc(
binarydesc_calculate_bds_factor(in_info->res,
bds_out_info->res,
&preview_descr->required_bds_factor);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
} else {
bds_out_info->res.width = in_info->res.width / 2;
@@ -318,11 +319,11 @@ enum ia_css_err ia_css_pipe_get_preview_binarydesc(
preview_descr->enable_dpc = pipe->config.enable_dpc;
preview_descr->isp_pipe_version = pipe->config.isp_pipe_version;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-enum ia_css_err ia_css_pipe_get_video_binarydesc(
+int ia_css_pipe_get_video_binarydesc(
struct ia_css_pipe *const pipe,
struct ia_css_binary_descr *video_descr,
struct ia_css_frame_info *in_info,
@@ -334,7 +335,7 @@ enum ia_css_err ia_css_pipe_get_video_binarydesc(
int mode = IA_CSS_BINARY_MODE_VIDEO;
unsigned int i;
struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool stream_dz_config = false;
/* vf_info can be NULL */
@@ -407,7 +408,7 @@ enum ia_css_err ia_css_pipe_get_video_binarydesc(
binarydesc_calculate_bds_factor(
in_info->res, bds_out_info->res,
&video_descr->required_bds_factor);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
} else {
bds_out_info->res.width =
@@ -607,7 +608,7 @@ void ia_css_pipe_get_primary_binarydesc(
* since it has better performance. */
if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
prim_descr->striped = false;
- else if (!atomisp_hw_is_isp2401) {
+ else if (!IS_ISP2401) {
prim_descr->striped = prim_descr->continuous &&
(!pipe->stream->stop_copy_preview || !pipe->stream->disable_cont_vf);
} else {
@@ -848,7 +849,7 @@ void ia_css_pipe_get_ldc_binarydesc(
assert(out_info);
IA_CSS_ENTER_PRIVATE("");
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
*in_info = *out_info;
} else {
if (pipe->out_yuv_ds_input_info.res.width)
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c
index 43f63cc20f49..82a24aabe8ce 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c
index cc0631550724..03d9d168fcc9 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h b/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h
index 75333166ed9b..59df44d696a0 100644
--- a/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h
+++ b/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,8 +16,9 @@
#ifndef __IA_CSS_UTIL_H__
#define __IA_CSS_UTIL_H__
+#include <linux/errno.h>
+
#include <ia_css_err.h>
-#include <error_support.h>
#include <type_support.h>
#include <ia_css_frame_public.h>
#include <ia_css_stream_public.h>
@@ -28,26 +30,26 @@
* @return "ia_css_err" error code
*
*/
-enum ia_css_err ia_css_convert_errno(
+int ia_css_convert_errno(
int in_err);
/* @brief check vf frame info.
*
* @param[in] info
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_util_check_vf_info(
+int ia_css_util_check_vf_info(
const struct ia_css_frame_info *const info);
/* @brief check input configuration.
*
* @param[in] stream_config
* @param[in] must_be_raw
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_util_check_input(
+int ia_css_util_check_input(
const struct ia_css_stream_config *const stream_config,
bool must_be_raw,
bool must_be_yuv);
@@ -56,10 +58,10 @@ enum ia_css_err ia_css_util_check_input(
*
* @param[in] out_info
* @param[in] vf_info
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_util_check_vf_out_info(
+int ia_css_util_check_vf_out_info(
const struct ia_css_frame_info *const out_info,
const struct ia_css_frame_info *const vf_info);
@@ -67,10 +69,10 @@ enum ia_css_err ia_css_util_check_vf_out_info(
*
* @param[in] width
* @param[in] height
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_util_check_res(
+int ia_css_util_check_res(
unsigned int width,
unsigned int height);
diff --git a/drivers/staging/media/atomisp/pci/camera/util/src/util.c b/drivers/staging/media/atomisp/pci/camera/util/src/util.c
index 217fe9cb54ff..40a71e37cc4e 100644
--- a/drivers/staging/media/atomisp/pci/camera/util/src/util.c
+++ b/drivers/staging/media/atomisp/pci/camera/util/src/util.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -20,35 +21,6 @@
/* for ia_css_binary_max_vf_width() */
#include "ia_css_binary.h"
-enum ia_css_err ia_css_convert_errno(
- int in_err)
-{
- enum ia_css_err out_err;
-
- switch (in_err) {
- case 0:
- out_err = IA_CSS_SUCCESS;
- break;
- case EINVAL:
- out_err = IA_CSS_ERR_INVALID_ARGUMENTS;
- break;
- case ENODATA:
- out_err = IA_CSS_ERR_QUEUE_IS_EMPTY;
- break;
- case ENOSYS:
- case ENOTSUP:
- out_err = IA_CSS_ERR_INTERNAL_ERROR;
- break;
- case ENOBUFS:
- out_err = IA_CSS_ERR_QUEUE_IS_FULL;
- break;
- default:
- out_err = IA_CSS_ERR_INTERNAL_ERROR;
- break;
- }
- return out_err;
-}
-
/* MW: Table look-up ??? */
unsigned int ia_css_util_input_format_bpp(
enum atomisp_input_format format,
@@ -113,49 +85,49 @@ unsigned int ia_css_util_input_format_bpp(
return rval;
}
-enum ia_css_err ia_css_util_check_vf_info(
+int ia_css_util_check_vf_info(
const struct ia_css_frame_info *const info)
{
- enum ia_css_err err;
+ int err;
unsigned int max_vf_width;
assert(info);
err = ia_css_frame_check_info(info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
max_vf_width = ia_css_binary_max_vf_width();
if (max_vf_width != 0 && info->res.width > max_vf_width * 2)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
- return IA_CSS_SUCCESS;
+ return -EINVAL;
+ return 0;
}
-enum ia_css_err ia_css_util_check_vf_out_info(
+int ia_css_util_check_vf_out_info(
const struct ia_css_frame_info *const out_info,
const struct ia_css_frame_info *const vf_info)
{
- enum ia_css_err err;
+ int err;
assert(out_info);
assert(vf_info);
err = ia_css_frame_check_info(out_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = ia_css_util_check_vf_info(vf_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err ia_css_util_check_res(unsigned int width, unsigned int height)
+int ia_css_util_check_res(unsigned int width, unsigned int height)
{
/* height can be odd number for jpeg/embedded data from ISYS2401 */
if (((width == 0) ||
(height == 0) ||
IS_ODD(width))) {
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
/* ISP2401 */
@@ -200,7 +172,7 @@ bool ia_css_util_is_input_format_yuv(enum atomisp_input_format format)
format == ATOMISP_INPUT_FORMAT_YUV422_16;
}
-enum ia_css_err ia_css_util_check_input(
+int ia_css_util_check_input(
const struct ia_css_stream_config *const stream_config,
bool must_be_raw,
bool must_be_yuv)
@@ -208,18 +180,18 @@ enum ia_css_err ia_css_util_check_input(
assert(stream_config);
if (!stream_config)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (stream_config->input_config.effective_res.width == 0 ||
stream_config->input_config.effective_res.height == 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (must_be_raw &&
!ia_css_util_is_input_format_raw(stream_config->input_config.format))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (must_be_yuv &&
!ia_css_util_is_input_format_yuv(stream_config->input_config.format))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/cell_params.h b/drivers/staging/media/atomisp/pci/cell_params.h
index 0eabc59ff5af..3c21a18990ba 100644
--- a/drivers/staging/media/atomisp/pci/cell_params.h
+++ b/drivers/staging/media/atomisp/pci/cell_params.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c
index 3ef556a64825..1a021ae841fe 100644
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c
+++ b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c
index 2b90a7075b9b..b786247b322b 100644
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c
+++ b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c
index 42e0344c677d..a6bc2e9eddea 100644
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c
+++ b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -210,7 +211,7 @@ ia_css_initialize_ynr_state(
/* Code generated by genparam/genstate.c:gen_state_init_table() */
-void (* ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
+void (*ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
const struct ia_css_binary *binary) = {
ia_css_initialize_aa_state,
ia_css_initialize_cnr_state,
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hrt/isp2400_mamoiada_params.h b/drivers/staging/media/atomisp/pci/css_2400_system/hrt/isp2400_mamoiada_params.h
deleted file mode 100644
index edc4d4ff1846..000000000000
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hrt/isp2400_mamoiada_params.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* Version */
-#define RTL_VERSION
-
-/* Cell name */
-#define ISP_CELL_TYPE isp2400_mamoiada
-#define ISP_VMEM simd_vmem
-#define _HRT_ISP_VMEM isp2400_mamoiada_simd_vmem
-
-/* instruction pipeline depth */
-#define ISP_BRANCHDELAY 5
-
-/* bus */
-#define ISP_BUS_WIDTH 32
-#define ISP_BUS_ADDR_WIDTH 32
-#define ISP_BUS_BURST_SIZE 1
-
-/* data-path */
-#define ISP_SCALAR_WIDTH 32
-#define ISP_SLICE_NELEMS 4
-#define ISP_VEC_NELEMS 64
-#define ISP_VEC_ELEMBITS 14
-#define ISP_VEC_ELEM8BITS 16
-#define ISP_CLONE_DATAPATH_IS_16 1
-
-/* memories */
-#define ISP_DMEM_DEPTH 4096
-#define ISP_DMEM_BSEL_DOWNSAMPLE 8
-#define ISP_VMEM_DEPTH 3072
-#define ISP_VMEM_BSEL_DOWNSAMPLE 8
-#define ISP_VMEM_ELEMBITS 14
-#define ISP_VMEM_ELEM_PRECISION 14
-#define ISP_PMEM_DEPTH 2048
-#define ISP_PMEM_WIDTH 640
-#define ISP_VAMEM_ADDRESS_BITS 12
-#define ISP_VAMEM_ELEMBITS 12
-#define ISP_VAMEM_DEPTH 2048
-#define ISP_VAMEM_ALIGNMENT 2
-#define ISP_VA_ADDRESS_WIDTH 896
-#define ISP_VEC_VALSU_LATENCY ISP_VEC_NELEMS
-#define ISP_HIST_ADDRESS_BITS 12
-#define ISP_HIST_ALIGNMENT 4
-#define ISP_HIST_COMP_IN_PREC 12
-#define ISP_HIST_DEPTH 1024
-#define ISP_HIST_WIDTH 24
-#define ISP_HIST_COMPONENTS 4
-
-/* program counter */
-#define ISP_PC_WIDTH 13
-
-/* Template switches */
-#define ISP_SHIELD_INPUT_DMEM 0
-#define ISP_SHIELD_OUTPUT_DMEM 1
-#define ISP_SHIELD_INPUT_VMEM 0
-#define ISP_SHIELD_OUTPUT_VMEM 0
-#define ISP_SHIELD_INPUT_PMEM 1
-#define ISP_SHIELD_OUTPUT_PMEM 1
-#define ISP_SHIELD_INPUT_HIST 1
-#define ISP_SHIELD_OUTPUT_HIST 1
-/* When LUT is select the shielding is always on */
-#define ISP_SHIELD_INPUT_VAMEM 1
-#define ISP_SHIELD_OUTPUT_VAMEM 1
-
-#define ISP_HAS_IRQ 1
-#define ISP_HAS_SOFT_RESET 1
-#define ISP_HAS_VEC_DIV 0
-#define ISP_HAS_VFU_W_2O 1
-#define ISP_HAS_DEINT3 1
-#define ISP_HAS_LUT 1
-#define ISP_HAS_HIST 1
-#define ISP_HAS_VALSU 1
-#define ISP_HAS_3rdVALSU 1
-#define ISP_VRF1_HAS_2P 1
-
-#define ISP_SRU_GUARDING 1
-#define ISP_VLSU_GUARDING 1
-
-#define ISP_VRF_RAM 1
-#define ISP_SRF_RAM 1
-
-#define ISP_SPLIT_VMUL_VADD_IS 0
-#define ISP_RFSPLIT_FPGA 0
-
-/* RSN or Bus pipelining */
-#define ISP_RSN_PIPE 1
-#define ISP_VSF_BUS_PIPE 0
-
-/* extra slave port to vmem */
-#define ISP_IF_VMEM 0
-#define ISP_GDC_VMEM 0
-
-/* Streaming ports */
-#define ISP_IF 1
-#define ISP_IF_B 1
-#define ISP_GDC 1
-#define ISP_SCL 1
-#define ISP_GPFIFO 1
-#define ISP_SP 1
-
-/* Removing Issue Slot(s) */
-#define ISP_HAS_NOT_SIMD_IS2 0
-#define ISP_HAS_NOT_SIMD_IS3 0
-#define ISP_HAS_NOT_SIMD_IS4 0
-#define ISP_HAS_NOT_SIMD_IS4_VADD 0
-#define ISP_HAS_NOT_SIMD_IS5 0
-#define ISP_HAS_NOT_SIMD_IS6 0
-#define ISP_HAS_NOT_SIMD_IS7 0
-#define ISP_HAS_NOT_SIMD_IS8 0
-
-/* ICache */
-#define ISP_ICACHE 1
-#define ISP_ICACHE_ONLY 0
-#define ISP_ICACHE_PREFETCH 1
-#define ISP_ICACHE_INDEX_BITS 8
-#define ISP_ICACHE_SET_BITS 5
-#define ISP_ICACHE_BLOCKS_PER_SET_BITS 1
-
-/* Experimental Flags */
-#define ISP_EXP_1 0
-#define ISP_EXP_2 0
-#define ISP_EXP_3 0
-#define ISP_EXP_4 0
-#define ISP_EXP_5 0
-#define ISP_EXP_6 0
-
-/* Derived values */
-#define ISP_LOG2_PMEM_WIDTH 10
-#define ISP_VEC_WIDTH 896
-#define ISP_SLICE_WIDTH 56
-#define ISP_VMEM_WIDTH 896
-#define ISP_VMEM_ALIGN 128
-#define ISP_SIMDLSU 1
-#define ISP_LSU_IMM_BITS 12
-
-/* convenient shortcuts for software*/
-#define ISP_NWAY ISP_VEC_NELEMS
-#define NBITS ISP_VEC_ELEMBITS
-
-#define _isp_ceil_div(a, b) (((a) + (b) - 1) / (b))
-
-#define ISP_VEC_ALIGN ISP_VMEM_ALIGN
-
-/* HRT specific vector support */
-#define isp2400_mamoiada_vector_alignment ISP_VEC_ALIGN
-#define isp2400_mamoiada_vector_elem_bits ISP_VMEM_ELEMBITS
-#define isp2400_mamoiada_vector_elem_precision ISP_VMEM_ELEM_PRECISION
-#define isp2400_mamoiada_vector_num_elems ISP_VEC_NELEMS
-
-/* register file sizes */
-#define ISP_RF0_SIZE 64
-#define ISP_RF1_SIZE 16
-#define ISP_RF2_SIZE 64
-#define ISP_RF3_SIZE 4
-#define ISP_RF4_SIZE 64
-#define ISP_RF5_SIZE 16
-#define ISP_RF6_SIZE 16
-#define ISP_RF7_SIZE 16
-#define ISP_RF8_SIZE 16
-#define ISP_RF9_SIZE 16
-#define ISP_RF10_SIZE 16
-#define ISP_RF11_SIZE 16
-#define ISP_VRF1_SIZE 24
-#define ISP_VRF2_SIZE 24
-#define ISP_VRF3_SIZE 24
-#define ISP_VRF4_SIZE 24
-#define ISP_VRF5_SIZE 24
-#define ISP_VRF6_SIZE 24
-#define ISP_VRF7_SIZE 24
-#define ISP_VRF8_SIZE 24
-#define ISP_SRF1_SIZE 4
-#define ISP_SRF2_SIZE 64
-#define ISP_SRF3_SIZE 64
-#define ISP_SRF4_SIZE 32
-#define ISP_SRF5_SIZE 64
-#define ISP_FRF0_SIZE 16
-#define ISP_FRF1_SIZE 4
-#define ISP_FRF2_SIZE 16
-#define ISP_FRF3_SIZE 4
-#define ISP_FRF4_SIZE 4
-#define ISP_FRF5_SIZE 8
-#define ISP_FRF6_SIZE 4
-/* register file read latency */
-#define ISP_VRF1_READ_LAT 1
-#define ISP_VRF2_READ_LAT 1
-#define ISP_VRF3_READ_LAT 1
-#define ISP_VRF4_READ_LAT 1
-#define ISP_VRF5_READ_LAT 1
-#define ISP_VRF6_READ_LAT 1
-#define ISP_VRF7_READ_LAT 1
-#define ISP_VRF8_READ_LAT 1
-#define ISP_SRF1_READ_LAT 1
-#define ISP_SRF2_READ_LAT 1
-#define ISP_SRF3_READ_LAT 1
-#define ISP_SRF4_READ_LAT 1
-#define ISP_SRF5_READ_LAT 1
-#define ISP_SRF5_READ_LAT 1
-/* immediate sizes */
-#define ISP_IS1_IMM_BITS 14
-#define ISP_IS2_IMM_BITS 13
-#define ISP_IS3_IMM_BITS 14
-#define ISP_IS4_IMM_BITS 14
-#define ISP_IS5_IMM_BITS 9
-#define ISP_IS6_IMM_BITS 16
-#define ISP_IS7_IMM_BITS 9
-#define ISP_IS8_IMM_BITS 16
-#define ISP_IS9_IMM_BITS 11
-/* fifo depths */
-#define ISP_IF_FIFO_DEPTH 0
-#define ISP_IF_B_FIFO_DEPTH 0
-#define ISP_DMA_FIFO_DEPTH 0
-#define ISP_OF_FIFO_DEPTH 0
-#define ISP_GDC_FIFO_DEPTH 0
-#define ISP_SCL_FIFO_DEPTH 0
-#define ISP_GPFIFO_FIFO_DEPTH 0
-#define ISP_SP_FIFO_DEPTH 0
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/csi_rx_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/csi_rx_global.h
index 4de5bb81bd23..3aabd0248e4f 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/csi_rx_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/csi_rx_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c
index 29d85407cac4..1a021ae841fe 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -272,7 +273,6 @@ ia_css_configure_output(
"ia_css_configure_output() leave:\n");
}
-
/* Code generated by genparam/genconfig.c:gen_configure_function() */
void
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c
index 68297296885e..d9c672d8904e 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c
index c54787f3fc24..514ffe0303cb 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -210,7 +211,7 @@ ia_css_initialize_ynr_state(
/* Code generated by genparam/genstate.c:gen_state_init_table() */
-void (* ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
+void (*ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
const struct ia_css_binary *binary) = {
ia_css_initialize_aa_state,
ia_css_initialize_cnr_state,
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx.c b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx.c
index 50080565d0d6..8e661091f7d9 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_local.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_local.h
index a86de89b2cfc..6489ee644a4a 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_local.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h
index 3fa3c3a487ab..ece45d80eb2a 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -289,12 +290,12 @@ static inline void csi_rx_be_ctrl_dump_state(
* lut.
*/
for (i = 0; i < N_SHORT_PACKET_LUT_ENTRIES[ID]; i++) {
- ia_css_print("CSI RX BE STATE Controller ID %d Short packat entry %d shart packet lut id 0x%x\n",
+ ia_css_print("CSI RX BE STATE Controller ID %d Short packet entry %d short packet lut id 0x%x\n",
ID, i,
state->short_packet_lut_entry[i]);
}
for (i = 0; i < N_LONG_PACKET_LUT_ENTRIES[ID]; i++) {
- ia_css_print("CSI RX BE STATE Controller ID %d Long packat entry %d Long packet lut id 0x%x\n",
+ ia_css_print("CSI RX BE STATE Controller ID %d Long packet entry %d long packet lut id 0x%x\n",
ID, i,
state->long_packet_lut_entry[i]);
}
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl.c b/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl.c
index 8b06b2410d1d..58fec54a914d 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_local.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_local.h
index ea40284623d1..4952b42d8191 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_local.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_private.h
index a0800a5df68a..a58e8477da6e 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/ibuf_ctrl_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma.c b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma.c
index 36c026cbd7cc..5809dbb6e5aa 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_local.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_local.h
index 5c694a26386e..878933261a43 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_local.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
index a1a222372ed3..eb35b7bcead4 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq.c b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq.c
index 567c926bd47f..99576af4713c 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_local.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_local.h
index 4fd05b29dfdb..e3d6d5e1634e 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_local.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h
index c519e6f06462..91ef000d76dc 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio.c b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio.c
index 67570138ba24..b7d893aea88d 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio.c
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_local.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_local.h
index 1449c19abc86..4fbbcc2338d3 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_local.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h
index e5aae5c022eb..4a5646a229b8 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_local.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_local.h
index 24f4da9aef40..efaa4da8d36d 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_local.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h
index 65ea23604479..4faa519219ee 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -97,9 +98,9 @@ STORAGE_CLASS_PIXELGEN_C void pixelgen_ctrl_dump_state(
pixelgen_ctrl_state_t *state)
{
ia_css_print("Pixel Generator ID %d Enable 0x%x\n", ID, state->com_enable);
- ia_css_print("Pixel Generator ID %d PRBS reset vlue 0 0x%x\n", ID,
+ ia_css_print("Pixel Generator ID %d PRBS reset value 0 0x%x\n", ID,
state->prbs_rstval0);
- ia_css_print("Pixel Generator ID %d PRBS reset vlue 1 0x%x\n", ID,
+ ia_css_print("Pixel Generator ID %d PRBS reset value 1 0x%x\n", ID,
state->prbs_rstval1);
ia_css_print("Pixel Generator ID %d SYNC SID 0x%x\n", ID, state->syng_sid);
ia_css_print("Pixel Generator ID %d syng free run 0x%x\n", ID,
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/PixelGen_SysBlock_defs.h b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/PixelGen_SysBlock_defs.h
index ce53ba4837ea..ae471dd51737 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/PixelGen_SysBlock_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/PixelGen_SysBlock_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/ibuf_cntrl_defs.h b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/ibuf_cntrl_defs.h
index 5975b094a9d0..374466e6b7bf 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/ibuf_cntrl_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/ibuf_cntrl_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_common_defs.h b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_common_defs.h
index 84fe95c16404..ac8be2d49227 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_common_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_common_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_defs.h b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_defs.h
index 45f20b524368..6fae1c262446 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/mipi_backend_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/rx_csi_defs.h b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/rx_csi_defs.h
index a8d0dbd7f6d7..d0e5b54d1afc 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/rx_csi_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/rx_csi_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/stream2mmio_defs.h b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/stream2mmio_defs.h
index a3940d246890..e17783f96b23 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hrt/stream2mmio_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/hrt/stream2mmio_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/ibuf_ctrl_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/ibuf_ctrl_global.h
index dc8d091c6769..1b9f03d57659 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/ibuf_ctrl_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/ibuf_ctrl_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/isys_dma_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/isys_dma_global.h
index 2ca4d5210a38..f423f34134d3 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/isys_dma_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/isys_dma_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -46,6 +47,7 @@ struct isys2401_dma_port_cfg_s {
u32 cropping;
u32 width;
};
+
/* end of DMA Port */
/************************************************
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/isys_irq_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/isys_irq_global.h
index 41d051db3987..156b4c95277e 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/isys_irq_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/isys_irq_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/isys_stream2mmio_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/isys_stream2mmio_global.h
index bcb46b293b6a..0611047eabbc 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/isys_stream2mmio_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/isys_stream2mmio_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h
index cde599c5d0d2..75722ef572d0 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_receiver_2400_common_defs.h b/drivers/staging/media/atomisp/pci/css_receiver_2400_common_defs.h
index 99d292164efc..d2c39f9600bd 100644
--- a/drivers/staging/media/atomisp/pci/css_receiver_2400_common_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_receiver_2400_common_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_receiver_2400_defs.h b/drivers/staging/media/atomisp/pci/css_receiver_2400_defs.h
index f4b2b41b6d94..180ff7cd9ff5 100644
--- a/drivers/staging/media/atomisp/pci/css_receiver_2400_defs.h
+++ b/drivers/staging/media/atomisp/pci/css_receiver_2400_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_trace.h b/drivers/staging/media/atomisp/pci/css_trace.h
index 32520c21c324..d2ce50fcfb7a 100644
--- a/drivers/staging/media/atomisp/pci/css_trace.h
+++ b/drivers/staging/media/atomisp/pci/css_trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -171,7 +172,6 @@ enum TRACE_DUMP_FORMAT {
#define TRACE_ISP_DATA_SIZE (TRACE_ISP_SIZE - TRACE_ISP_HEADER_SIZE)
#define TRACE_ISP_MAX_POINTS (TRACE_ISP_DATA_SIZE / TRACE_ISP_ITEM_SIZE)
-
/* common majors */
/* SP0 */
#define MAJOR_MAIN 1
diff --git a/drivers/staging/media/atomisp/pci/defs.h b/drivers/staging/media/atomisp/pci/defs.h
index 47505f41790c..785e7a670a00 100644
--- a/drivers/staging/media/atomisp/pci/defs.h
+++ b/drivers/staging/media/atomisp/pci/defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/dma_v2_defs.h b/drivers/staging/media/atomisp/pci/dma_v2_defs.h
index 8741b8347dd4..27299e3a185d 100644
--- a/drivers/staging/media/atomisp/pci/dma_v2_defs.h
+++ b/drivers/staging/media/atomisp/pci/dma_v2_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/gdc_v2_defs.h b/drivers/staging/media/atomisp/pci/gdc_v2_defs.h
index 3cc627aa6b09..804df8179e36 100644
--- a/drivers/staging/media/atomisp/pci/gdc_v2_defs.h
+++ b/drivers/staging/media/atomisp/pci/gdc_v2_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/gp_timer_defs.h b/drivers/staging/media/atomisp/pci/gp_timer_defs.h
index ffd7b38fce9d..9bc04e5b4292 100644
--- a/drivers/staging/media/atomisp/pci/gp_timer_defs.h
+++ b/drivers/staging/media/atomisp/pci/gp_timer_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/gpio_block_defs.h b/drivers/staging/media/atomisp/pci/gpio_block_defs.h
index 96286a141b00..e1bd638d344a 100644
--- a/drivers/staging/media/atomisp/pci/gpio_block_defs.h
+++ b/drivers/staging/media/atomisp/pci/gpio_block_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_2401_irq_types_hrt.h b/drivers/staging/media/atomisp/pci/hive_isp_css_2401_irq_types_hrt.h
deleted file mode 100644
index 0760b95818f6..000000000000
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_2401_irq_types_hrt.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-#ifndef _HIVE_ISP_CSS_2401_IRQ_TYPES_HRT_H_
-#define _HIVE_ISP_CSS_2401_IRQ_TYPES_HRT_H_
-
-/*
- * These are the indices of each interrupt in the interrupt
- * controller's registers. these can be used as the irq_id
- * argument to the hrt functions irq_controller.h.
- *
- * The definitions are taken from <system>_defs.h
- */
-typedef enum hrt_isp_css_irq {
- hrt_isp_css_irq_gpio_pin_0 = HIVE_GP_DEV_IRQ_GPIO_PIN_0_BIT_ID,
- hrt_isp_css_irq_gpio_pin_1 = HIVE_GP_DEV_IRQ_GPIO_PIN_1_BIT_ID,
- hrt_isp_css_irq_gpio_pin_2 = HIVE_GP_DEV_IRQ_GPIO_PIN_2_BIT_ID,
- hrt_isp_css_irq_gpio_pin_3 = HIVE_GP_DEV_IRQ_GPIO_PIN_3_BIT_ID,
- hrt_isp_css_irq_gpio_pin_4 = HIVE_GP_DEV_IRQ_GPIO_PIN_4_BIT_ID,
- hrt_isp_css_irq_gpio_pin_5 = HIVE_GP_DEV_IRQ_GPIO_PIN_5_BIT_ID,
- hrt_isp_css_irq_gpio_pin_6 = HIVE_GP_DEV_IRQ_GPIO_PIN_6_BIT_ID,
- hrt_isp_css_irq_gpio_pin_7 = HIVE_GP_DEV_IRQ_GPIO_PIN_7_BIT_ID,
- hrt_isp_css_irq_gpio_pin_8 = HIVE_GP_DEV_IRQ_GPIO_PIN_8_BIT_ID,
- hrt_isp_css_irq_gpio_pin_9 = HIVE_GP_DEV_IRQ_GPIO_PIN_9_BIT_ID,
- hrt_isp_css_irq_gpio_pin_10 = HIVE_GP_DEV_IRQ_GPIO_PIN_10_BIT_ID,
- hrt_isp_css_irq_gpio_pin_11 = HIVE_GP_DEV_IRQ_GPIO_PIN_11_BIT_ID,
- hrt_isp_css_irq_sp = HIVE_GP_DEV_IRQ_SP_BIT_ID,
- hrt_isp_css_irq_isp = HIVE_GP_DEV_IRQ_ISP_BIT_ID,
- hrt_isp_css_irq_isys = HIVE_GP_DEV_IRQ_ISYS_BIT_ID,
- hrt_isp_css_irq_isel = HIVE_GP_DEV_IRQ_ISEL_BIT_ID,
- hrt_isp_css_irq_ifmt = HIVE_GP_DEV_IRQ_IFMT_BIT_ID,
- hrt_isp_css_irq_sp_stream_mon = HIVE_GP_DEV_IRQ_SP_STREAM_MON_BIT_ID,
- hrt_isp_css_irq_isp_stream_mon = HIVE_GP_DEV_IRQ_ISP_STREAM_MON_BIT_ID,
- hrt_isp_css_irq_mod_stream_mon = HIVE_GP_DEV_IRQ_MOD_STREAM_MON_BIT_ID,
- hrt_isp_css_irq_is2401 = HIVE_GP_DEV_IRQ_ISP_PMEM_ERROR_BIT_ID,
- hrt_isp_css_irq_isp_bamem_error = HIVE_GP_DEV_IRQ_ISP_BAMEM_ERROR_BIT_ID,
- hrt_isp_css_irq_isp_dmem_error = HIVE_GP_DEV_IRQ_ISP_DMEM_ERROR_BIT_ID,
- hrt_isp_css_irq_sp_icache_mem_error = HIVE_GP_DEV_IRQ_SP_ICACHE_MEM_ERROR_BIT_ID,
- hrt_isp_css_irq_sp_dmem_error = HIVE_GP_DEV_IRQ_SP_DMEM_ERROR_BIT_ID,
- hrt_isp_css_irq_mmu_cache_mem_error = HIVE_GP_DEV_IRQ_MMU_CACHE_MEM_ERROR_BIT_ID,
- hrt_isp_css_irq_gp_timer_0 = HIVE_GP_DEV_IRQ_GP_TIMER_0_BIT_ID,
- hrt_isp_css_irq_gp_timer_1 = HIVE_GP_DEV_IRQ_GP_TIMER_1_BIT_ID,
- hrt_isp_css_irq_sw_pin_0 = HIVE_GP_DEV_IRQ_SW_PIN_0_BIT_ID,
- hrt_isp_css_irq_sw_pin_1 = HIVE_GP_DEV_IRQ_SW_PIN_1_BIT_ID,
- hrt_isp_css_irq_dma = HIVE_GP_DEV_IRQ_DMA_BIT_ID,
- hrt_isp_css_irq_sp_stream_mon_b = HIVE_GP_DEV_IRQ_SP_STREAM_MON_B_BIT_ID,
- /* this must (obviously) be the last on in the enum */
- hrt_isp_css_irq_num_irqs
-} hrt_isp_css_irq_t;
-
-typedef enum hrt_isp_css_irq_status {
- hrt_isp_css_irq_status_error,
- hrt_isp_css_irq_status_more_irqs,
- hrt_isp_css_irq_status_success
-} hrt_isp_css_irq_status_t;
-
-#endif /* _HIVE_ISP_CSS_2401_IRQ_TYPES_HRT_H_ */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/debug_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/debug_global.h
index 7580cf5c9624..b6538beca18a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/debug_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/debug_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/dma_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/dma_global.h
index 85d509f5b923..135034c7245a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/dma_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/dma_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/event_fifo_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/event_fifo_global.h
index 4df7a405cdcf..a50635b717e3 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/event_fifo_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/event_fifo_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/fifo_monitor_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/fifo_monitor_global.h
index f43bf0ad2468..d941c82d530b 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/fifo_monitor_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/fifo_monitor_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gdc_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gdc_global.h
index f3ce9e9f1ad4..599d993b832e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gdc_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gdc_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_device_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_device_global.h
index 1c1b0667a53b..c8f416515e2c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_device_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_device_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_timer_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_timer_global.h
index ee636ad6c5b3..163003f2c759 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_timer_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gp_timer_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gpio_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gpio_global.h
index a82ca2a8cada..b5f017482f89 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/gpio_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/gpio_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/hmem_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/hmem_global.h
index e4b9daa2d062..746b07097681 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/hmem_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/hmem_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c
index d911aec24185..a502ba9f8c7f 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2016, Intel Corporation.
@@ -14,12 +15,12 @@
#include "debug.h"
+#include "hmm.h"
+
#ifndef __INLINE_DEBUG__
#include "debug_private.h"
#endif /* __INLINE_DEBUG__ */
-#include "memory_access.h"
-
#define __INLINE_SP__
#include "sp.h"
@@ -27,7 +28,7 @@
/* The address of the remote copy */
hrt_address debug_buffer_address = (hrt_address) - 1;
-hrt_vaddress debug_buffer_ddr_address = (hrt_vaddress)-1;
+ia_css_ptr debug_buffer_ddr_address = (ia_css_ptr)-1;
/* The local copy */
static debug_data_t debug_data;
debug_data_t *debug_data_ptr = &debug_data;
@@ -40,7 +41,7 @@ void debug_buffer_init(const hrt_address addr)
debug_data.tail = 0;
}
-void debug_buffer_ddr_init(const hrt_vaddress addr)
+void debug_buffer_ddr_init(const ia_css_ptr addr)
{
debug_buf_mode_t mode = DEBUG_BUFFER_MODE_LINEAR;
u32 enable = 1;
@@ -48,13 +49,13 @@ void debug_buffer_ddr_init(const hrt_vaddress addr)
u32 tail = 0;
/* set the ddr queue */
debug_buffer_ddr_address = addr;
- mmgr_store(addr + DEBUG_DATA_BUF_MODE_DDR_ADDR,
+ hmm_store(addr + DEBUG_DATA_BUF_MODE_DDR_ADDR,
&mode, sizeof(debug_buf_mode_t));
- mmgr_store(addr + DEBUG_DATA_HEAD_DDR_ADDR,
+ hmm_store(addr + DEBUG_DATA_HEAD_DDR_ADDR,
&head, sizeof(uint32_t));
- mmgr_store(addr + DEBUG_DATA_TAIL_DDR_ADDR,
+ hmm_store(addr + DEBUG_DATA_TAIL_DDR_ADDR,
&tail, sizeof(uint32_t));
- mmgr_store(addr + DEBUG_DATA_ENABLE_DDR_ADDR,
+ hmm_store(addr + DEBUG_DATA_ENABLE_DDR_ADDR,
&enable, sizeof(uint32_t));
/* set the local copy */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_local.h
index 4c95eda694f7..536a4dcf0f62 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_private.h
index 8447e33d1c04..3fea43a2125e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/debug_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -22,8 +23,6 @@
#define __INLINE_ISP__
#include "isp.h"
-#include "memory_access.h"
-
#include "assert_support.h"
STORAGE_CLASS_DEBUG_C bool is_debug_buffer_empty(void)
@@ -101,22 +100,22 @@ STORAGE_CLASS_DEBUG_C void debug_synch_queue_ddr(void)
{
u32 remote_tail;
- mmgr_load(debug_buffer_ddr_address + DEBUG_DATA_TAIL_DDR_ADDR, &remote_tail,
+ hmm_load(debug_buffer_ddr_address + DEBUG_DATA_TAIL_DDR_ADDR, &remote_tail,
sizeof(uint32_t));
/* We could move the remote head after the upload, but we would have to limit the upload w.r.t. the local head. This is easier */
if (remote_tail > debug_data_ptr->tail) {
size_t delta = remote_tail - debug_data_ptr->tail;
- mmgr_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR +
+ hmm_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR +
debug_data_ptr->tail * sizeof(uint32_t),
(void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
} else if (remote_tail < debug_data_ptr->tail) {
size_t delta = DEBUG_BUF_SIZE - debug_data_ptr->tail;
- mmgr_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR +
+ hmm_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR +
debug_data_ptr->tail * sizeof(uint32_t),
(void *)&debug_data_ptr->buf[debug_data_ptr->tail], delta * sizeof(uint32_t));
- mmgr_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR,
+ hmm_load(debug_buffer_ddr_address + DEBUG_DATA_BUF_DDR_ADDR,
(void *)&debug_data_ptr->buf[0],
remote_tail * sizeof(uint32_t));
} /* else we are up to date */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma.c
index 87df1da1164e..f85950c471c7 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2016, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h
index d7db964d5cec..7e4cc75733cd 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_private.h
index ebb75da72e18..1f62bc2f176f 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo.c
index 777670948d6f..62d4809e33dd 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_local.h
index 39a9dd697096..25d3823026e8 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_private.h
index 3b6cc27ecb28..f59d45cc78b7 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/event_fifo_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor.c
index 82f7c43bcb0a..01698064bbe1 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_local.h
index a557ff8a416f..dfdca944a40b 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_private.h
index abaef8672ae2..10d9c076c140 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/fifo_monitor_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c
index 65c5296163dd..8ed1cffc5384 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_local.h
index 0c6de867e012..4b2b3282c1b2 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_private.h
index f7dec75adf78..73051112f354 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device.c
index 5f20ac0b492e..a80e547d47b3 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_local.h
index 113d5ed32d42..320ed35269ea 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_private.h
index cdc1b12a9e8a..f11a19f21d10 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_device_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer.c
index 4a856f1f14bf..2a58dba3c87b 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_local.h
index 4d5961c78c16..efede25587fd 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_private.h
index 705be5e5cc70..3e1b36105bb6 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gp_timer_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_local.h
index f4652b79734d..14013733f826 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_private.h
index 56b442040ad9..cc60bed71ddb 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gpio_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem.c
index e48f180c9507..be102d5cec87 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_local.h
index 499f55f07253..a3ee274bdf19 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_private.h
index 270d04cc9d09..80d81983bd06 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/hmem_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter.c
index 0c90c5ed659b..bec9c7238a78 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_local.h
index ee2c8372421c..94fff77584f7 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_private.h
index bdca709219a4..e2bc952e6694 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_formatter_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c
index 2114cf4f3fda..fc000af042dc 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-015, Intel Corporation.
@@ -855,9 +856,9 @@ input_system_error_t input_system_configuration_reset(void)
input_system_network_rst(INPUT_SYSTEM0_ID);
- gp_device_rst(INPUT_SYSTEM0_ID);
+ gp_device_rst(GP_DEVICE0_ID);
- input_switch_rst(INPUT_SYSTEM0_ID);
+ input_switch_rst(GP_DEVICE0_ID);
//target_rst();
@@ -873,7 +874,7 @@ input_system_error_t input_system_configuration_reset(void)
for (i = 0; i < N_CSI_PORTS; i++) {
config.csi_buffer_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
- config.multicast[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
+ config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
}
config.source_type_flags = INPUT_SYSTEM_CFG_FLAG_RESET;
@@ -1323,10 +1324,10 @@ static input_system_error_t configuration_to_registers(void)
} // end of switch (source_type)
// Set input selector.
- input_selector_cfg_for_sensor(INPUT_SYSTEM0_ID);
+ input_selector_cfg_for_sensor(GP_DEVICE0_ID);
// Set input switch.
- input_switch_cfg(INPUT_SYSTEM0_ID, &config.input_switch_cfg);
+ input_switch_cfg(GP_DEVICE0_ID, &config.input_switch_cfg);
// Set input formatters.
// AM: IF are set dynamically.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq.c
index fdc99cc6eae4..80b5fd0dc9f6 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -20,17 +21,14 @@
#endif
#include "gp_device.h" /* _REG_GP_IRQ_REQUEST_ADDR */
-#include "platform_support.h" /* hrt_sleep() */
-
static inline void irq_wait_for_write_complete(
const irq_ID_t ID);
static inline bool any_irq_channel_enabled(
const irq_ID_t ID);
-static inline irq_ID_t virq_get_irq_id(
- const virq_id_t irq_ID,
- unsigned int *channel_ID);
+static inline irq_ID_t virq_get_irq_id(const enum virq_id irq_ID,
+ unsigned int *channel_ID);
#ifndef __INLINE_IRQ__
#include "irq_private.h"
@@ -51,7 +49,7 @@ static unsigned short IRQ_N_ID_OFFSET[N_IRQ_ID + 1] = {
IRQ_END_OFFSET
};
-static virq_id_t IRQ_NESTING_ID[N_IRQ_ID] = {
+static enum virq_id IRQ_NESTING_ID[N_IRQ_ID] = {
N_virq_id,
virq_ifmt,
virq_isys,
@@ -227,9 +225,8 @@ void irq_raise(
return;
}
-void irq_controller_get_state(
- const irq_ID_t ID,
- irq_controller_state_t *state)
+void irq_controller_get_state(const irq_ID_t ID,
+ struct irq_controller_state *state)
{
assert(ID < N_IRQ_ID);
assert(state);
@@ -256,7 +253,7 @@ bool any_virq_signal(void)
}
void cnd_virq_enable_channel(
- const virq_id_t irq_ID,
+ const enum virq_id irq_ID,
const bool en)
{
irq_ID_t i;
@@ -296,8 +293,8 @@ void virq_clear_all(void)
return;
}
-enum hrt_isp_css_irq_status virq_get_channel_signals(
- virq_info_t *irq_info)
+enum hrt_isp_css_irq_status
+virq_get_channel_signals(struct virq_info *irq_info)
{
enum hrt_isp_css_irq_status irq_status = hrt_isp_css_irq_status_error;
irq_ID_t ID;
@@ -326,8 +323,7 @@ enum hrt_isp_css_irq_status virq_get_channel_signals(
return irq_status;
}
-void virq_clear_info(
- virq_info_t *irq_info)
+void virq_clear_info(struct virq_info *irq_info)
{
irq_ID_t ID;
@@ -340,7 +336,7 @@ void virq_clear_info(
}
enum hrt_isp_css_irq_status virq_get_channel_id(
- virq_id_t *irq_id)
+ enum virq_id *irq_id)
{
unsigned int irq_status = irq_reg_load(IRQ0_ID,
_HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
@@ -367,7 +363,7 @@ enum hrt_isp_css_irq_status virq_get_channel_id(
/* Check whether we have an IRQ on one of the nested devices */
for (ID = N_IRQ_ID - 1 ; ID > (irq_ID_t)0; ID--) {
- if (IRQ_NESTING_ID[ID] == (virq_id_t)idx) {
+ if (IRQ_NESTING_ID[ID] == (enum virq_id)idx) {
break;
}
}
@@ -404,7 +400,7 @@ enum hrt_isp_css_irq_status virq_get_channel_id(
idx += IRQ_N_ID_OFFSET[ID];
if (irq_id)
- *irq_id = (virq_id_t)idx;
+ *irq_id = (enum virq_id)idx;
return status;
}
@@ -432,7 +428,7 @@ static inline bool any_irq_channel_enabled(
}
static inline irq_ID_t virq_get_irq_id(
- const virq_id_t irq_ID,
+ const enum virq_id irq_ID,
unsigned int *channel_ID)
{
irq_ID_t ID;
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_local.h
index 86028fde2a94..6a25345ae88e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -42,10 +43,7 @@
#define IRQ2_ID_N_CHANNEL HIVE_ISYS_IRQ_NUM_BITS
#define IRQ3_ID_N_CHANNEL HIVE_ISEL_IRQ_NUM_IRQS
-typedef struct virq_info_s virq_info_t;
-typedef struct irq_controller_state_s irq_controller_state_t;
-
-typedef enum {
+enum virq_id {
virq_gpio_pin_0 = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_GPIO_PIN_0_BIT_ID,
virq_gpio_pin_1 = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_GPIO_PIN_1_BIT_ID,
virq_gpio_pin_2 = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_GPIO_PIN_2_BIT_ID,
@@ -66,13 +64,7 @@ typedef enum {
virq_sp_stream_mon = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_SP_STREAM_MON_BIT_ID,
virq_isp_stream_mon = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_ISP_STREAM_MON_BIT_ID,
virq_mod_stream_mon = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_MOD_STREAM_MON_BIT_ID,
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM)
virq_isp_pmem_error = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_ISP_PMEM_ERROR_BIT_ID,
-#elif defined(IS_ISP_2401_MAMOIADA_SYSTEM)
- virq_isys_2401 = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_ISP_PMEM_ERROR_BIT_ID,
-#else
-#error "irq_local.h: 2400_SYSTEM must be one of {2400, 2401 }"
-#endif
virq_isp_bamem_error = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_ISP_BAMEM_ERROR_BIT_ID,
virq_isp_dmem_error = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_ISP_DMEM_ERROR_BIT_ID,
virq_sp_icache_mem_error = IRQ0_ID_OFFSET + HIVE_GP_DEV_IRQ_SP_ICACHE_MEM_ERROR_BIT_ID,
@@ -117,13 +109,13 @@ typedef enum {
virq_isel_eol = IRQ3_ID_OFFSET + HIVE_ISEL_IRQ_SYNC_GEN_EOL_BIT_ID,
N_virq_id = IRQ_END_OFFSET
-} virq_id_t;
+};
-struct virq_info_s {
+struct virq_info {
hrt_data irq_status_reg[N_IRQ_ID];
};
-struct irq_controller_state_s {
+struct irq_controller_state {
unsigned int irq_edge;
unsigned int irq_mask;
unsigned int irq_status;
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_private.h
index 8a947aefd851..e98663ef0fcd 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/irq_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp.c
index 7de7d08f4757..4ad5e2db8a89 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -12,6 +13,8 @@
* more details.
*/
+#include <linux/delay.h>
+
#include <system_global.h>
#include "isp.h"
@@ -20,7 +23,6 @@
#endif /* __INLINE_ISP__ */
#include "assert_support.h"
-#include "platform_support.h" /* hrt_sleep() */
void cnd_isp_irq_enable(
const isp_ID_t ID,
@@ -124,5 +126,5 @@ void isp_wake(isp_ID_t ID)
{
assert(ID < N_ISP_ID);
isp_ctrl_setbit(ID, ISP_SC_REG, ISP_START_BIT);
- hrt_sleep();
+ udelay(1);
}
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_local.h
index b04da7f1f98c..eceeb5d160ad 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_private.h
index a6ab10711255..2f9aeb3bd9d4 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/isp_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu.c
index a17b32b6d414..eb02835aa98a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu_local.h
index 7c3ad157189f..913150504f0f 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/mmu_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp.c
index f084b316e373..aae18465b6ae 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_local.h
index 0e477b497c98..2956c7023b33 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_private.h
index e3e24fac126e..05e6b438d2c8 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/sp_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl.c
index aaea74389443..bc9e7f10f1ab 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_local.h
index e570813af28d..f58ee6afcff9 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_private.h
index 3c137badbd43..c19eeafed3a3 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/timed_ctrl_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vamem_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vamem_local.h
index c4e99afe0d29..c68ed984ca48 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vamem_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vamem_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
index 0c6830ae7344..6620f091442f 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2016, Intel Corporation.
@@ -20,7 +21,6 @@
#include "ia_css_device_access.h"
#endif
#include "assert_support.h"
-#include "platform_support.h" /* hrt_sleep() */
typedef unsigned long long hive_uedge;
typedef hive_uedge *hive_wide;
@@ -154,7 +154,7 @@ static void load_vector(
hive_sim_wide_unpack(data, &elem, ISP_VEC_ELEMBITS, i);
to[i] = elem;
}
- hrt_sleep(); /* Spend at least 1 cycles per vector */
+ udelay(1); /* Spend at least 1 cycles per vector */
}
static void store_vector(
@@ -179,7 +179,7 @@ static void store_vector(
//hrt_mem_store (ISP, VMEM, (unsigned)to, &v, siz); /* This will overwrite the next vector as well */
hrt_master_port_store(ISP_BAMEM_BASE[ID] + (unsigned long)to, &v, size);
#endif
- hrt_sleep(); /* Spend at least 1 cycles per vector */
+ udelay(1); /* Spend at least 1 cycles per vector */
}
void isp_vmem_load(
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_local.h
index a42cce42f29d..d0ba59cedc92 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_private.h
index f48d1281b5a7..39cf1316b404 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/input_formatter_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/input_formatter_global.h
index 163521c53d4b..605cf02e520c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/input_formatter_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/input_formatter_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -19,7 +20,7 @@
#define IS_INPUT_SWITCH_VERSION2
#include <type_support.h>
-#include <system_types.h>
+#include <system_local.h>
#include "if_defs.h"
#include "str2mem_defs.h"
#include "input_switch_2400_defs.h"
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h
index 64554d80dc0b..4a1dea6dfd40 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/irq_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,22 +16,14 @@
#ifndef __IRQ_GLOBAL_H_INCLUDED__
#define __IRQ_GLOBAL_H_INCLUDED__
-#include <system_types.h>
+#include <system_local.h>
#define IS_IRQ_VERSION_2
#define IS_IRQ_MAP_VERSION_2
/* We cannot include the (hrt host ID) file defining the "CSS_RECEIVER" property without side effects */
#ifndef HAS_NO_RX
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM)
-/*#define CSS_RECEIVER testbench_isp_inp_sys_csi_receiver*/
-#include "hive_isp_css_irq_types_hrt.h" /* enum hrt_isp_css_irq */
-#elif defined(IS_ISP_2401_MAMOIADA_SYSTEM)
-/*#define CSS_RECEIVER testbench_isp_is_2400_inp_sys_csi_receiver*/
-#include "hive_isp_css_2401_irq_types_hrt.h" /* enum hrt_isp_css_irq */
-#else
-#error "irq_global.h: 2400_SYSTEM must be one of {2400, 2401 }"
-#endif
+#include "irq_types_hrt.h"
#endif
/* The IRQ is not mapped uniformly on its related interfaces */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/isp_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/isp_global.h
index 1a8547d58435..5c6891c9b451 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/isp_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/isp_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,19 +16,9 @@
#ifndef __ISP_GLOBAL_H_INCLUDED__
#define __ISP_GLOBAL_H_INCLUDED__
-#include <system_types.h>
+#include <system_local.h>
-#if defined(HAS_ISP_2401_MAMOIADA)
-#define IS_ISP_2401_MAMOIADA
-
-#include "isp2401_mamoiada_params.h"
-#elif defined(HAS_ISP_2400_MAMOIADA)
-#define IS_ISP_2400_MAMOIADA
-
-#include "isp2400_mamoiada_params.h"
-#else
-#error "isp_global_h: ISP_2400_MAMOIDA must be one of {2400, 2401 }"
-#endif
+#include "mamoiada_params.h"
#define ISP_PMEM_WIDTH_LOG2 ISP_LOG2_PMEM_WIDTH
#define ISP_PMEM_SIZE ISP_PMEM_DEPTH
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/mmu_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/mmu_global.h
index 83ca418c8ff2..8738fed6afdf 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/mmu_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/mmu_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/sp_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/sp_global.h
index 6ec4e590e3b4..b8338f9b5c0c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/sp_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/sp_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,19 +16,9 @@
#ifndef __SP_GLOBAL_H_INCLUDED__
#define __SP_GLOBAL_H_INCLUDED__
-#include <system_types.h>
+#include <system_local.h>
-#if defined(HAS_SP_2401)
-#define IS_SP_2401
-/* 2401 uses 2400 */
#include <scalar_processor_2400_params.h>
-#elif defined(HAS_SP_2400)
-#define IS_SP_2400
-
-#include <scalar_processor_2400_params.h>
-#else
-#error "sp_global.h: SP_2400 must be one of {2400, 2401 }"
-#endif
#define SP_PMEM_WIDTH_LOG2 SP_PMEM_LOG_WIDTH_BITS
#define SP_PMEM_SIZE SP_PMEM_DEPTH
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h
index f185859e3084..3f2915a78031 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/vamem_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/vamem_global.h
index 92b783fed82c..0d290e815767 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/vamem_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/vamem_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/vmem_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/vmem_global.h
index 7867cd137f3f..537b074211da 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/vmem_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/vmem_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_defs.h b/drivers/staging/media/atomisp/pci/hive_isp_css_defs.h
index 52676f3610ba..e9cf2743868c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_defs.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/assert_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/assert_support.h
index 4cb7e4c952c5..7382c0bbf7cb 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/assert_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/assert_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/bitop_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/bitop_support.h
index 76856db58626..29f14e900580 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/bitop_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/bitop_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/csi_rx.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/csi_rx.h
index badb15705710..4602885d50e8 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/csi_rx.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/csi_rx.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/debug.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/debug.h
index ba11b956eb1a..0f8195ba8d1a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/debug.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/debug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h
index be031d41de7c..492f9e26cfff 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
@@ -39,7 +40,7 @@ more details.
* User provided file that defines the system address types:
* - hrt_address a type that can hold the (sub)system address range
*/
-#include "system_types.h"
+#include "system_local.h"
/*
* We cannot assume that the global system address size is the size of
* a pointer because a (say) 64-bit host can be simulated in a 32-bit
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/dma.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/dma.h
index b6c464a530ea..2f5ebfcd7e8b 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/dma.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/dma.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/error_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/error_support.h
deleted file mode 100644
index 4f0d259bf7ed..000000000000
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/error_support.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-#ifndef __ERROR_SUPPORT_H_INCLUDED__
-#define __ERROR_SUPPORT_H_INCLUDED__
-
-#include <linux/errno.h>
-/*
- * Put here everything __KERNEL__ specific not covered in
- * "errno.h"
- */
-#define ENOTSUP 252
-
-#define verifexit(cond, error_tag) \
-do { \
- if (!(cond)) { \
- goto EXIT; \
- } \
-} while (0)
-
-#define verifjmpexit(cond) \
-do { \
- if (!(cond)) { \
- goto EXIT; \
- } \
-} while (0)
-
-#endif /* __ERROR_SUPPORT_H_INCLUDED__ */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/event_fifo.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/event_fifo.h
index 8bfe348772f4..0a085abd3ade 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/event_fifo.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/event_fifo.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/fifo_monitor.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/fifo_monitor.h
index 1743caa006d0..19a1bdd9171a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/fifo_monitor.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/fifo_monitor.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gdc_device.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gdc_device.h
index 4f8d7fbc8e7f..4ed57fb4530e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gdc_device.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gdc_device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_device.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_device.h
index 665557bae7a1..d122bdeae7e7 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_device.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_timer.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_timer.h
index cd26c9d16a35..0b7e92b963d0 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_timer.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gp_timer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gpio.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gpio.h
index ad79c03e59f4..6f16ca77cf75 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/gpio.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/gpio.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/hmem.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/hmem.h
index f87fd6b2ba23..898facd7b17a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/hmem.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/hmem.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
index f7cd4d7b96e5..e6f695691407 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/debug_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/debug_public.h
index 79a8446658ee..ee861ddb8e92 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/debug_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/debug_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,7 +17,8 @@
#define __DEBUG_PUBLIC_H_INCLUDED__
#include <type_support.h>
-#include "system_types.h"
+#include <ia_css_types.h>
+#include "system_local.h"
/*! brief
*
@@ -42,7 +44,7 @@ typedef struct debug_data_ddr_s debug_data_ddr_t;
extern debug_data_t *debug_data_ptr;
extern hrt_address debug_buffer_address;
-extern hrt_vaddress debug_buffer_ddr_address;
+extern ia_css_ptr debug_buffer_ddr_address;
/*! Check the empty state of the local debug data buffer
@@ -86,7 +88,7 @@ void debug_buffer_init(
\return none
*/
void debug_buffer_ddr_init(
- const hrt_vaddress addr);
+ const ia_css_ptr addr);
/*! Set the (remote) operating mode of the debug buffer
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/dma_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/dma_public.h
index 385b978b703b..a23cbc9a2129 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/dma_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/dma_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __DMA_PUBLIC_H_INCLUDED__
#define __DMA_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
typedef struct dma_state_s dma_state_t;
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/event_fifo_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/event_fifo_public.h
index a84b74b3bc1e..22f1875f038e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/event_fifo_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/event_fifo_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,7 +17,7 @@
#define __EVENT_FIFO_PUBLIC_H
#include <type_support.h>
-#include "system_types.h"
+#include "system_local.h"
/*! Blocking read from an event source EVENT[ID]
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/fifo_monitor_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/fifo_monitor_public.h
index e451d6f2a70d..7c1c3d2f24c6 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/fifo_monitor_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/fifo_monitor_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __FIFO_MONITOR_PUBLIC_H_INCLUDED__
#define __FIFO_MONITOR_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
typedef struct fifo_channel_state_s fifo_channel_state_t;
typedef struct fifo_switch_state_s fifo_switch_state_t;
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gdc_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gdc_public.h
index fc6f42e76fbe..385b79254455 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gdc_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gdc_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_device_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_device_public.h
index 7cc0799d49ed..f017742d9ac4 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_device_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_device_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __GP_DEVICE_PUBLIC_H_INCLUDED__
#define __GP_DEVICE_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
typedef struct gp_device_state_s gp_device_state_t;
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_timer_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_timer_public.h
index 2ddb8c40a5b2..13baf7236375 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_timer_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gp_timer_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __GP_TIMER_PUBLIC_H_INCLUDED__
#define __GP_TIMER_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
/*! initialize mentioned timer
param ID timer_id
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gpio_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gpio_public.h
index d21aab3a179d..13df9b57a5fb 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gpio_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/gpio_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __GPIO_PUBLIC_H_INCLUDED__
#define __GPIO_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
/*! Write to a control register of GPIO[ID]
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/hmem_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/hmem_public.h
index 567fbc1d35e7..8d271fb84209 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/hmem_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/hmem_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/ibuf_ctrl_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/ibuf_ctrl_public.h
index 6b17a6b651b7..053803d2cae3 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/ibuf_ctrl_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/ibuf_ctrl_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/input_formatter_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/input_formatter_public.h
index e5758cb8bedd..81dc58640d83 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/input_formatter_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/input_formatter_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,7 +17,7 @@
#define __INPUT_FORMATTER_PUBLIC_H_INCLUDED__
#include <type_support.h>
-#include "system_types.h"
+#include "system_local.h"
/*! Reset INPUT_FORMATTER[ID]
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/irq_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/irq_public.h
index dfe2aa9ff257..d335e7b0a76e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/irq_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/irq_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,7 +17,7 @@
#define __IRQ_PUBLIC_H_INCLUDED__
#include <type_support.h>
-#include "system_types.h"
+#include "system_local.h"
/*! Read the control registers of IRQ[ID]
@@ -25,9 +26,8 @@
\return none, state = IRQ[ID].state
*/
-void irq_controller_get_state(
- const irq_ID_t ID,
- irq_controller_state_t *state);
+void irq_controller_get_state(const irq_ID_t ID,
+ struct irq_controller_state *state);
/*! Write to a control register of IRQ[ID]
@@ -136,7 +136,7 @@ bool any_virq_signal(void);
\return none, VIRQ.channel[irq_ID].enable = en
*/
void cnd_virq_enable_channel(
- const virq_id_t irq_ID,
+ const enum virq_id irq_ID,
const bool en);
/*! Clear the state of all IRQ channels of the virtual super IRQ
@@ -151,8 +151,7 @@ void virq_clear_all(void);
\return none
*/
-void virq_clear_info(
- virq_info_t *irq_info);
+void virq_clear_info(struct virq_info *irq_info);
/*! Return the ID of a signalling IRQ channel of the virtual super IRQ
@@ -165,7 +164,7 @@ void virq_clear_info(
\return state(IRQ[...])
*/
enum hrt_isp_css_irq_status virq_get_channel_id(
- virq_id_t *irq_id);
+ enum virq_id *irq_id);
/*! Return the IDs of all signaling IRQ channels of the virtual super IRQ
@@ -178,7 +177,7 @@ enum hrt_isp_css_irq_status virq_get_channel_id(
\return (error(state(IRQ[...]))
*/
-enum hrt_isp_css_irq_status virq_get_channel_signals(
- virq_info_t *irq_info);
+enum hrt_isp_css_irq_status
+virq_get_channel_signals(struct virq_info *irq_info);
#endif /* __IRQ_PUBLIC_H_INCLUDED__ */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isp_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isp_public.h
index 0da2937b900e..a8ff75c639e5 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isp_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isp_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,7 +17,7 @@
#define __ISP_PUBLIC_H_INCLUDED__
#include <type_support.h>
-#include "system_types.h"
+#include "system_local.h"
/*! Enable or disable the program complete irq signal of ISP[ID]
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_dma_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_dma_public.h
index 734634aedadf..23a158b81b13 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_dma_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_dma_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -17,7 +18,7 @@
#ifdef USE_INPUT_SYSTEM_VERSION_2401
-#include "system_types.h"
+#include "system_local.h"
#include "type_support.h"
STORAGE_CLASS_ISYS2401_DMA_H void isys2401_dma_reg_store(
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_irq_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_irq_public.h
index d561783e47a3..b9befdd2508e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_irq_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_irq_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_public.h
index 2d1859f2c656..509f75fe025c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h
index 87a8d512713e..73bcc424e472 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/mmu_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/mmu_public.h
index 278f9cd85a00..b8c7bbb71b01 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/mmu_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/mmu_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __MMU_PUBLIC_H_INCLUDED__
#define __MMU_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
#include "device_access.h"
#include "assert_support.h"
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h
index ba67a276ce55..ded4dce06d09 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/sp_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/sp_public.h
index b8db5469b592..b0b7f2e27854 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/sp_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/sp_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -16,7 +17,7 @@
#define __SP_PUBLIC_H_INCLUDED__
#include <type_support.h>
-#include "system_types.h"
+#include "system_local.h"
typedef struct sp_state_s sp_state_t;
typedef struct sp_stall_s sp_stall_t;
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h
index afd5a59489cc..b18b4a4e13ac 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/timed_ctrl_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/timed_ctrl_public.h
index 5f9277adb2ab..563a2833d1d9 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/timed_ctrl_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/timed_ctrl_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef __TIMED_CTRL_PUBLIC_H_INCLUDED__
#define __TIMED_CTRL_PUBLIC_H_INCLUDED__
-#include "system_types.h"
+#include "system_local.h"
/*! Write to a control register of TIMED_CTRL[ID]
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vamem_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vamem_public.h
index 577b9b8449e8..823e3857e83c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vamem_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vamem_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vmem_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vmem_public.h
index e9801c0fe147..c510d6a08017 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vmem_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/vmem_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/ibuf_ctrl.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/ibuf_ctrl.h
index f9cf7b586045..218341041811 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/ibuf_ctrl.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/ibuf_ctrl.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_formatter.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_formatter.h
index 377996e0536d..daeb919b5384 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_formatter.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_formatter.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_system.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_system.h
index 33ab8a85909e..0d951fbf42e9 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_system.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/input_system.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/irq.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/irq.h
index 133dd9014fef..3a83a85111a2 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/irq.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/irq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isp.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isp.h
index 749610b8a831..cb64e62c5569 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isp.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_dma.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_dma.h
index dbdd17115018..6a759142eda8 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_dma.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_dma.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_irq.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_irq.h
index d3f64cfd0b7d..d854124f4f97 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_irq.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_irq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_stream2mmio.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_stream2mmio.h
index e2ebeb14e7c2..b0f09ffb4f18 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_stream2mmio.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/isys_stream2mmio.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h
index 0b9519c8961c..a444ec14ff9d 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_access/memory_access.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_access/memory_access.h
deleted file mode 100644
index dc63ff0c9c6a..000000000000
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_access/memory_access.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015-2017, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-#ifndef __MEMORY_ACCESS_H_INCLUDED__
-#define __MEMORY_ACCESS_H_INCLUDED__
-
-/*!
- * \brief
- * Define the public interface for virtual memory
- * access functions. Access types are limited to
- * those defined in <stdint.h>
- *
- * The address representation is private to the system
- * and represented as "hrt_vaddress" rather than a
- * pointer, as the memory allocation cannot be accessed
- * by dereferencing but reaquires load and store access
- * functions
- *
- * The page table selection or virtual memory context;
- * The page table base index; Is implicit. This page
- * table base index must be set by the implementation
- * of the access function
- *
- * "store" is a transfer to the system
- * "load" is a transfer from the system
- *
- * Allocation properties can be specified by setting
- * attributes (see below) in case of multiple physical
- * memories the memory ID is encoded on the attribute
- *
- * Allocations in the same physical memory, but in a
- * different (set of) page tables can be shared through
- * a page table information mapping function
- */
-
-#include <type_support.h>
-#include "platform_support.h" /* for __func__ */
-
-/*
- * User provided file that defines the (sub)system address types:
- * - hrt_vaddress a type that can hold the (sub)system virtual address range
- */
-#include "system_types.h"
-
-/*
- * The MMU base address is a physical address, thus the same type is used
- * as for the device base address
- */
-#include "device_access.h"
-
-#include "hmm/hmm.h"
-
-/*!
- * \brief
- * Bit masks for specialised allocation functions
- * the default is "uncached", "not contiguous",
- * "not page aligned" and "not cleared"
- *
- * Forcing alignment (usually) returns a pointer
- * at an alignment boundary that is offset from
- * the allocated pointer. Without storing this
- * pointer/offset, we cannot free it. The memory
- * manager is responsible for the bookkeeping, e.g.
- * the allocation function creates a sentinel
- * within the allocation referencable from the
- * returned pointer/address.
- */
-#define MMGR_ATTRIBUTE_MASK 0x000f
-#define MMGR_ATTRIBUTE_CACHED 0x0001
-#define MMGR_ATTRIBUTE_CONTIGUOUS 0x0002
-#define MMGR_ATTRIBUTE_PAGEALIGN 0x0004
-#define MMGR_ATTRIBUTE_CLEARED 0x0008
-#define MMGR_ATTRIBUTE_UNUSED 0xfff0
-
-/* #define MMGR_ATTRIBUTE_DEFAULT (MMGR_ATTRIBUTE_CACHED) */
-#define MMGR_ATTRIBUTE_DEFAULT 0
-
-extern const hrt_vaddress mmgr_NULL;
-extern const hrt_vaddress mmgr_EXCEPTION;
-
-/*! Return the address of an allocation in memory
-
- \param size[in] Size in bytes of the allocation
- \param caller_func[in] Caller function name
- \param caller_line[in] Caller function line number
-
- \return vaddress
- */
-hrt_vaddress mmgr_malloc(const size_t size);
-
-/*! Return the address of a zero initialised allocation in memory
-
- \param N[in] Horizontal dimension of array
- \param size[in] Vertical dimension of array Total size is N*size
-
- \return vaddress
- */
-hrt_vaddress mmgr_calloc(const size_t N, const size_t size);
-
-/*! Return the address of an allocation in memory
-
- \param size[in] Size in bytes of the allocation
- \param attribute[in] Bit vector specifying the properties
- of the allocation including zero initialisation
-
- \return vaddress
- */
-
-hrt_vaddress mmgr_alloc_attr(const size_t size, const uint16_t attribute);
-
-/*! Return the address of a mapped existing allocation in memory
-
- \param ptr[in] Pointer to an allocation in a different
- virtual memory page table, but the same
- physical memory
- \param size[in] Size of the memory of the pointer
- \param attribute[in] Bit vector specifying the properties
- of the allocation
- \param context Pointer of a context provided by
- client/driver for additional parameters
- needed by the implementation
- \Note
- This interface is tentative, limited to the desired function
- the actual interface may require furhter parameters
-
- \return vaddress
- */
-hrt_vaddress mmgr_mmap(
- const void __user *ptr,
- const size_t size,
- u16 attribute,
- void *context);
-
-/*! Zero initialise an allocation in memory
-
- \param vaddr[in] Address of an allocation
- \param size[in] Size in bytes of the area to be cleared
-
- \return none
- */
-void mmgr_clear(hrt_vaddress vaddr, const size_t size);
-
-/*! Read an array of bytes from a virtual memory address
-
- \param vaddr[in] Address of an allocation
- \param data[out] pointer to the destination array
- \param size[in] number of bytes to read
-
- \return none
- */
-void mmgr_load(const hrt_vaddress vaddr, void *data, const size_t size);
-
-/*! Write an array of bytes to device registers or memory in the device
-
- \param vaddr[in] Address of an allocation
- \param data[in] pointer to the source array
- \param size[in] number of bytes to write
-
- \return none
- */
-void mmgr_store(const hrt_vaddress vaddr, const void *data, const size_t size);
-
-#endif /* __MEMORY_ACCESS_H_INCLUDED__ */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_realloc.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_realloc.h
deleted file mode 100644
index 546b93ca1186..000000000000
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/memory_realloc.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
-Support for Intel Camera Imaging ISP subsystem.
-Copyright (c) 2010 - 2015, Intel Corporation.
-
-This program is free software; you can redistribute it and/or modify it
-under the terms and conditions of the GNU General Public License,
-version 2, as published by the Free Software Foundation.
-
-This program is distributed in the hope it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-more details.
-*/
-#ifndef __MEMORY_REALLOC_H_INCLUDED__
-#define __MEMORY_REALLOC_H_INCLUDED__
-
-/*!
- * \brief
- * Define the internal reallocation of private css memory
- *
- */
-
-#include <type_support.h>
-/*
- * User provided file that defines the (sub)system address types:
- * - hrt_vaddress a type that can hold the (sub)system virtual address range
- */
-#include "system_types.h"
-#include "ia_css_err.h"
-
-bool reallocate_buffer(
- hrt_vaddress *curr_buf,
- size_t *curr_size,
- size_t needed_size,
- bool force,
- enum ia_css_err *err);
-
-#endif /*__MEMORY_REALLOC_H_INCLUDED__*/
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/misc_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/misc_support.h
index 38db1ecef3c8..393452d7a3d6 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/misc_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/misc_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/mmu_device.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/mmu_device.h
index 1a36cb493fd8..b6f6eda4c55e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/mmu_device.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/mmu_device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/pixelgen.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/pixelgen.h
index 74335fdeff7d..e34cd3c58dd7 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/pixelgen.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/pixelgen.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h
index 525c34882fd7..0cdef4a5e8b1 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -24,9 +25,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
-/* For definition of hrt_sleep() */
-#include "hive_isp_css_custom_host_hrt.h"
-
#define UINT16_MAX USHRT_MAX
#define UINT32_MAX UINT_MAX
#define UCHAR_MAX (255)
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/print_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/print_support.h
index f5fcf6b1d667..a1f7a5839560 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/print_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/print_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/queue.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/queue.h
index 1bcadd838161..e6978750a362 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/queue.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/queue.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/resource.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/resource.h
index 129446600067..9be45b679386 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/resource.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/resource.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/sp.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/sp.h
index 194cd64a7da8..a7d00c7bb8bc 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/sp.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/sp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/string_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/string_support.h
deleted file mode 100644
index 84efbbe78650..000000000000
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/string_support.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-#ifndef __STRING_SUPPORT_H_INCLUDED__
-#define __STRING_SUPPORT_H_INCLUDED__
-#include <platform_support.h>
-#include <type_support.h>
-
-/*
- * For all non microsoft cases, we need the following functions
- */
-
-/* @brief Copy from src_buf to dest_buf.
- *
- * @param[out] dest_buf. Destination buffer to copy to
- * @param[in] dest_size. The size of the destination buffer in bytes
- * @param[in] src_buf. The source buffer
- * @param[in] src_size. The size of the source buffer in bytes
- * @return 0 on success, error code on failure
- * @return EINVAL on Invalid arguments
- * @return ERANGE on Destination size too small
- */
-static inline int memcpy_s(
- void *dest_buf,
- size_t dest_size,
- const void *src_buf,
- size_t src_size)
-{
- if ((!src_buf) || (!dest_buf)) {
- /* Invalid arguments*/
- return EINVAL;
- }
-
- if ((dest_size < src_size) || (src_size == 0)) {
- /* Destination too small*/
- return ERANGE;
- }
-
- memcpy(dest_buf, src_buf, src_size);
- return 0;
-}
-
-/* @brief Get the length of the string, excluding the null terminator
- *
- * @param[in] src_str. The source string
- * @param[in] max_len. Look only for max_len bytes in the string
- * @return Return the string length excluding null character
- * @return Return max_len if no null character in the first max_len bytes
- * @return Returns 0 if src_str is NULL
- */
-static size_t strnlen_s(
- const char *src_str,
- size_t max_len)
-{
- size_t ix;
-
- if (!src_str) {
- /* Invalid arguments*/
- return 0;
- }
-
- for (ix = 0; ix < max_len && src_str[ix] != '\0'; ix++)
- ;
-
- /* On Error, it will return src_size == max_len*/
- return ix;
-}
-
-/* @brief Copy string from src_str to dest_str
- *
- * @param[out] dest_str. Destination buffer to copy to
- * @param[in] dest_size. The size of the destination buffer in bytes
- * @param[in] src_str. The source buffer
- * @param[in] src_size. The size of the source buffer in bytes
- * @return Returns 0 on success
- * @return Returns EINVAL on invalid arguments
- * @return Returns ERANGE on destination size too small
- */
-static inline int strncpy_s(
- char *dest_str,
- size_t dest_size,
- const char *src_str,
- size_t src_size)
-{
- size_t len;
-
- if (!dest_str) {
- /* Invalid arguments*/
- return EINVAL;
- }
-
- if ((!src_str) || (dest_size == 0)) {
- /* Invalid arguments*/
- dest_str[0] = '\0';
- return EINVAL;
- }
-
- len = strnlen_s(src_str, src_size);
-
- if (len >= dest_size) {
- /* Destination too small*/
- dest_str[0] = '\0';
- return ERANGE;
- }
-
- /* dest_str is big enough for the len */
- strncpy(dest_str, src_str, len);
- dest_str[len] = '\0';
- return 0;
-}
-
-/* @brief Copy string from src_str to dest_str
- *
- * @param[out] dest_str. Destination buffer to copy to
- * @param[in] dest_size. The size of the destination buffer in bytes
- * @param[in] src_str. The source buffer
- * @return Returns 0 on success
- * @return Returns EINVAL on invalid arguments
- * @return Returns ERANGE on destination size too small
- */
-static inline int strcpy_s(
- char *dest_str,
- size_t dest_size,
- const char *src_str)
-{
- size_t len;
-
- if (!dest_str) {
- /* Invalid arguments*/
- return EINVAL;
- }
-
- if ((!src_str) || (dest_size == 0)) {
- /* Invalid arguments*/
- dest_str[0] = '\0';
- return EINVAL;
- }
-
- len = strnlen_s(src_str, dest_size);
-
- if (len >= dest_size) {
- /* Destination too small*/
- dest_str[0] = '\0';
- return ERANGE;
- }
-
- /* dest_str is big enough for the len */
- strncpy(dest_str, src_str, len);
- dest_str[len] = '\0';
- return 0;
-}
-
-
-#endif /* __STRING_SUPPORT_H_INCLUDED__ */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/system_types.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/system_types.h
deleted file mode 100644
index 764fda8dd214..000000000000
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/system_types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-#ifndef __SYSTEM_TYPES_H_INCLUDED__
-#define __SYSTEM_TYPES_H_INCLUDED__
-
-/**
-* @file
-* Platform specific types.
-*/
-
-#include "system_local.h"
-
-#endif /* __SYSTEM_TYPES_H_INCLUDED__ */
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/tag.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/tag.h
index 1f0a5d948316..98d7e922aed9 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/tag.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/tag.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/timed_ctrl.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/timed_ctrl.h
index 403abcb828bf..65b2871fb4ea 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/timed_ctrl.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/timed_ctrl.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h
index bc77537fa73a..b996ee54d4a5 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/vamem.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/vamem.h
index 9918ca398138..3ea6758aa798 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/vamem.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/vamem.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/vmem.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/vmem.h
index 873e01e6d054..da479b370192 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/vmem.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/vmem.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_local.h
index 9f4060319b4b..31121a22d13d 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_private.h
index 2b396955cdad..be6162dfbc66 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/queue_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag.c b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag.c
index a7089ee7462a..8931539a4c01 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_local.h
index 01a8977c189e..921e50a4554a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_local.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_private.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_private.h
index 0570a95ec5bf..b14f09adef07 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_private.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/host/tag_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/queue_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/queue_global.h
index ce0d99418538..6ae453782515 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/queue_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/queue_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/sw_event_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/sw_event_global.h
index 549c0d2b7970..b256ea19c0eb 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/sw_event_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/sw_event_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/tag_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/tag_global.h
index 9db8766b3a7b..af5a47ace32a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_shared/tag_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_shared/tag_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_streaming_to_mipi_types_hrt.h b/drivers/staging/media/atomisp/pci/hive_isp_css_streaming_to_mipi_types_hrt.h
index a22b771f61f2..301dd923950c 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_streaming_to_mipi_types_hrt.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_streaming_to_mipi_types_hrt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_types.h b/drivers/staging/media/atomisp/pci/hive_types.h
index 9715893c8a36..addda9b81d7b 100644
--- a/drivers/staging/media/atomisp/pci/hive_types.h
+++ b/drivers/staging/media/atomisp/pci/hive_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -78,9 +79,6 @@ typedef hive_uint32 hrt_address;
#error adddres width not supported
#endif
-/* The SP side representation of an HMM virtual address */
-typedef hive_uint32 hrt_vaddress;
-
/* use 64 bit addresses in simulation, where possible */
typedef hive_uint64 hive_sim_address;
diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
index cd70307ffd57..42fef1779862 100644
--- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
+++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -193,7 +194,7 @@ int hmm_init(void)
* at the beginning, to avoid hmm_alloc return 0 in the
* further allocation.
*/
- dummy_ptr = hmm_alloc(1, HMM_BO_PRIVATE, 0, NULL, HMM_UNCACHED);
+ dummy_ptr = hmm_alloc(1, HMM_BO_PRIVATE, 0, NULL, 0);
if (!ret) {
ret = sysfs_create_group(&atomisp_dev->kobj,
@@ -208,6 +209,8 @@ int hmm_init(void)
void hmm_cleanup(void)
{
+ if (!dummy_ptr)
+ return;
sysfs_remove_group(&atomisp_dev->kobj, atomisp_attribute_group);
/* free dummy memory first */
@@ -219,12 +222,16 @@ void hmm_cleanup(void)
}
ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type,
- int from_highmem, const void __user *userptr, bool cached)
+ int from_highmem, const void __user *userptr,
+ const uint16_t attrs)
{
unsigned int pgnr;
struct hmm_buffer_object *bo;
+ bool cached = attrs & ATOMISP_MAP_FLAG_CACHED;
int ret;
+ WARN_ON(attrs & ATOMISP_MAP_FLAG_CONTIGUOUS);
+
/*
* Check if we are initialized. In the ideal world we wouldn't need
* this but we can tackle it once the driver is a lot cleaner
@@ -249,7 +256,7 @@ ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type,
goto alloc_page_err;
}
- /* Combind the virtual address and pages togather */
+ /* Combine the virtual address and pages together */
ret = hmm_bo_bind(bo);
if (ret) {
dev_err(atomisp_dev, "hmm_bo_bind failed.\n");
@@ -258,6 +265,13 @@ ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type,
hmm_mem_stat.tol_cnt += pgnr;
+ if (attrs & ATOMISP_MAP_FLAG_CLEARED)
+ hmm_set(bo->start, 0, bytes);
+
+ dev_dbg(atomisp_dev,
+ "%s: pages: 0x%08x (%ld bytes), type: %d from highmem %d, user ptr %p, cached %d\n",
+ __func__, bo->start, bytes, type, from_highmem, userptr, cached);
+
return bo->start;
bind_err:
@@ -272,6 +286,8 @@ void hmm_free(ia_css_ptr virt)
{
struct hmm_buffer_object *bo;
+ dev_dbg(atomisp_dev, "%s: free 0x%08x\n", __func__, virt);
+
WARN_ON(!virt);
bo = hmm_bo_device_search_start(&bo_device, (unsigned int)virt);
@@ -396,9 +412,14 @@ static int load_and_flush(ia_css_ptr virt, void *data, unsigned int bytes)
/* Read function in ISP memory management */
int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes)
{
+ if (!virt) {
+ dev_warn(atomisp_dev,
+ "hmm_store: address is NULL\n");
+ return -EINVAL;
+ }
if (!data) {
dev_err(atomisp_dev,
- "hmm_load NULL argument\n");
+ "hmm_store: data is a NULL argument\n");
return -EINVAL;
}
return load_and_flush(virt, data, bytes);
@@ -418,6 +439,17 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
char *src, *des;
int ret;
+ if (!virt) {
+ dev_warn(atomisp_dev,
+ "hmm_store: address is NULL\n");
+ return -EINVAL;
+ }
+ if (!data) {
+ dev_err(atomisp_dev,
+ "hmm_store: data is a NULL argument\n");
+ return -EINVAL;
+ }
+
bo = hmm_bo_device_search_in_range(&bo_device, virt);
ret = hmm_check_bo(bo, virt);
if (ret)
diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c
index 492b76c29490..4fb9bfdd2f4c 100644
--- a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c
+++ b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
@@ -659,6 +660,8 @@ static void free_private_bo_pages(struct hmm_buffer_object *bo,
break;
}
+ /* fall through */
+
/*
* if dynamic memory pool doesn't exist, need to free
* pages to system directly.
@@ -854,109 +857,20 @@ static void free_private_pages(struct hmm_buffer_object *bo,
kfree(bo->page_obj);
}
-/*
- * Hacked from kernel function __get_user_pages in mm/memory.c
- *
- * Handle buffers allocated by other kernel space driver and mmaped into user
- * space, function Ignore the VM_PFNMAP and VM_IO flag in VMA structure
- *
- * Get physical pages from user space virtual address and update into page list
- */
-static int __get_pfnmap_pages(struct task_struct *tsk, struct mm_struct *mm,
- unsigned long start, int nr_pages,
- unsigned int gup_flags, struct page **pages,
- struct vm_area_struct **vmas)
-{
- int i, ret;
- unsigned long vm_flags;
-
- if (nr_pages <= 0)
- return 0;
-
- VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET));
-
- /*
- * Require read or write permissions.
- * If FOLL_FORCE is set, we only require the "MAY" flags.
- */
- vm_flags = (gup_flags & FOLL_WRITE) ?
- (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
- vm_flags &= (gup_flags & FOLL_FORCE) ?
- (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
- i = 0;
-
- do {
- struct vm_area_struct *vma;
-
- vma = find_vma(mm, start);
- if (!vma) {
- dev_err(atomisp_dev, "find_vma failed\n");
- return i ? : -EFAULT;
- }
-
- if (is_vm_hugetlb_page(vma)) {
- /*
- i = follow_hugetlb_page(mm, vma, pages, vmas,
- &start, &nr_pages, i, gup_flags);
- */
- continue;
- }
-
- do {
- struct page *page;
- unsigned long pfn;
-
- /*
- * If we have a pending SIGKILL, don't keep faulting
- * pages and potentially allocating memory.
- */
- if (unlikely(fatal_signal_pending(current))) {
- dev_err(atomisp_dev,
- "fatal_signal_pending in %s\n",
- __func__);
- return i ? i : -ERESTARTSYS;
- }
-
- ret = follow_pfn(vma, start, &pfn);
- if (ret) {
- dev_err(atomisp_dev, "follow_pfn() failed\n");
- return i ? : -EFAULT;
- }
-
- page = pfn_to_page(pfn);
- if (IS_ERR(page))
- return i ? i : PTR_ERR(page);
- if (pages) {
- pages[i] = page;
- get_page(page);
- flush_anon_page(vma, page, start);
- flush_dcache_page(page);
- }
- if (vmas)
- vmas[i] = vma;
- i++;
- start += PAGE_SIZE;
- nr_pages--;
- } while (nr_pages && start < vma->vm_end);
- } while (nr_pages);
-
- return i;
-}
-
-static int get_pfnmap_pages(struct task_struct *tsk, struct mm_struct *mm,
- unsigned long start, int nr_pages, int write, int force,
- struct page **pages, struct vm_area_struct **vmas)
+static void free_user_pages(struct hmm_buffer_object *bo)
{
- int flags = FOLL_TOUCH;
+ int i;
- if (pages)
- flags |= FOLL_GET;
- if (write)
- flags |= FOLL_WRITE;
- if (force)
- flags |= FOLL_FORCE;
+ hmm_mem_stat.usr_size -= bo->pgnr;
- return __get_pfnmap_pages(tsk, mm, start, nr_pages, flags, pages, vmas);
+ if (bo->mem_type == HMM_BO_MEM_TYPE_PFN) {
+ unpin_user_pages(bo->pages, bo->pgnr);
+ } else {
+ for (i = 0; i < bo->pgnr; i++)
+ put_page(bo->pages[i]);
+ }
+ kfree(bo->pages);
+ kfree(bo->page_obj);
}
/*
@@ -982,9 +896,9 @@ static int alloc_user_pages(struct hmm_buffer_object *bo,
}
mutex_unlock(&bo->mutex);
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
vma = find_vma(current->mm, (unsigned long)userptr);
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
if (!vma) {
dev_err(atomisp_dev, "find_vma failed\n");
kfree(bo->page_obj);
@@ -997,11 +911,15 @@ static int alloc_user_pages(struct hmm_buffer_object *bo,
* Handle frame buffer allocated in other kerenl space driver
* and map to user space
*/
+
+ userptr = untagged_addr(userptr);
+
+ bo->pages = pages;
+
if (vma->vm_flags & (VM_IO | VM_PFNMAP)) {
- page_nr = get_pfnmap_pages(current, current->mm,
- (unsigned long)userptr,
- (int)(bo->pgnr), 1, 0,
- pages, NULL);
+ page_nr = pin_user_pages((unsigned long)userptr, bo->pgnr,
+ FOLL_LONGTERM | FOLL_WRITE,
+ pages, NULL);
bo->mem_type = HMM_BO_MEM_TYPE_PFN;
} else {
/*Handle frame buffer allocated in user space*/
@@ -1012,6 +930,13 @@ static int alloc_user_pages(struct hmm_buffer_object *bo,
bo->mem_type = HMM_BO_MEM_TYPE_USER;
}
+ dev_dbg(atomisp_dev, "%s: %d %s pages were allocated as 0x%08x\n",
+ __func__,
+ bo->pgnr,
+ bo->mem_type == HMM_BO_MEM_TYPE_USER ? "user" : "pfn", page_nr);
+
+ hmm_mem_stat.usr_size += bo->pgnr;
+
/* can be written by caller, not forced */
if (page_nr != bo->pgnr) {
dev_err(atomisp_dev,
@@ -1024,29 +949,14 @@ static int alloc_user_pages(struct hmm_buffer_object *bo,
bo->page_obj[i].page = pages[i];
bo->page_obj[i].type = HMM_PAGE_TYPE_GENERAL;
}
- hmm_mem_stat.usr_size += bo->pgnr;
- kfree(pages);
return 0;
out_of_mem:
- for (i = 0; i < page_nr; i++)
- put_page(pages[i]);
- kfree(pages);
- kfree(bo->page_obj);
- return -ENOMEM;
-}
+ free_user_pages(bo);
-static void free_user_pages(struct hmm_buffer_object *bo)
-{
- int i;
-
- for (i = 0; i < bo->pgnr; i++)
- put_page(bo->page_obj[i].page);
- hmm_mem_stat.usr_size -= bo->pgnr;
-
- kfree(bo->page_obj);
+ return -ENOMEM;
}
/*
diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_dynamic_pool.c b/drivers/staging/media/atomisp/pci/hmm/hmm_dynamic_pool.c
index 1a87af68a924..eaf97e5f3b68 100644
--- a/drivers/staging/media/atomisp/pci/hmm/hmm_dynamic_pool.c
+++ b/drivers/staging/media/atomisp/pci/hmm/hmm_dynamic_pool.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_reserved_pool.c b/drivers/staging/media/atomisp/pci/hmm/hmm_reserved_pool.c
index d739ed914d65..57525fece921 100644
--- a/drivers/staging/media/atomisp/pci/hmm/hmm_reserved_pool.c
+++ b/drivers/staging/media/atomisp/pci/hmm/hmm_reserved_pool.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_vm.c b/drivers/staging/media/atomisp/pci/hmm/hmm_vm.c
deleted file mode 100644
index 976a2cb51354..000000000000
--- a/drivers/staging/media/atomisp/pci/hmm/hmm_vm.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Support for Medifield PNW Camera Imaging ISP subsystem.
- *
- * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
- *
- * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- *
- */
-/*
- * This file contains function for ISP virtual address management in ISP driver
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/page.h>
-
-#include "atomisp_internal.h"
-#include "mmu/isp_mmu.h"
-#include "hmm/hmm_vm.h"
-#include "hmm/hmm_common.h"
-
-static unsigned int vm_node_end(unsigned int start, unsigned int pgnr)
-{
- return start + pgnr_to_size(pgnr);
-}
-
-static int addr_in_vm_node(unsigned int addr,
- struct hmm_vm_node *node)
-{
- return (addr >= node->start) && (addr < (node->start + node->size));
-}
-
-int hmm_vm_init(struct hmm_vm *vm, unsigned int start,
- unsigned int size)
-{
- if (!vm)
- return -1;
-
- vm->start = start;
- vm->pgnr = size_to_pgnr_ceil(size);
- vm->size = pgnr_to_size(vm->pgnr);
-
- INIT_LIST_HEAD(&vm->vm_node_list);
- spin_lock_init(&vm->lock);
- vm->cache = kmem_cache_create("atomisp_vm", sizeof(struct hmm_vm_node),
- 0, 0, NULL);
-
- return vm->cache ? 0 : -ENOMEM;
-}
-
-void hmm_vm_clean(struct hmm_vm *vm)
-{
- struct hmm_vm_node *node, *tmp;
- struct list_head new_head;
-
- if (!vm)
- return;
-
- spin_lock(&vm->lock);
- list_replace_init(&vm->vm_node_list, &new_head);
- spin_unlock(&vm->lock);
-
- list_for_each_entry_safe(node, tmp, &new_head, list) {
- list_del(&node->list);
- kmem_cache_free(vm->cache, node);
- }
-
- kmem_cache_destroy(vm->cache);
-}
-
-static struct hmm_vm_node *alloc_hmm_vm_node(unsigned int pgnr,
- struct hmm_vm *vm)
-{
- struct hmm_vm_node *node;
-
- node = kmem_cache_alloc(vm->cache, GFP_KERNEL);
- if (!node)
- return NULL;
-
- INIT_LIST_HEAD(&node->list);
- node->pgnr = pgnr;
- node->size = pgnr_to_size(pgnr);
- node->vm = vm;
-
- return node;
-}
-
-struct hmm_vm_node *hmm_vm_alloc_node(struct hmm_vm *vm, unsigned int pgnr)
-{
- struct list_head *head;
- struct hmm_vm_node *node, *cur, *next;
- unsigned int vm_start, vm_end;
- unsigned int addr;
- unsigned int size;
-
- if (!vm)
- return NULL;
-
- vm_start = vm->start;
- vm_end = vm_node_end(vm->start, vm->pgnr);
- size = pgnr_to_size(pgnr);
-
- addr = vm_start;
- head = &vm->vm_node_list;
-
- node = alloc_hmm_vm_node(pgnr, vm);
- if (!node) {
- dev_err(atomisp_dev, "no memory to allocate hmm vm node.\n");
- return NULL;
- }
-
- spin_lock(&vm->lock);
- /*
- * if list is empty, the loop code will not be executed.
- */
- list_for_each_entry(cur, head, list) {
- /* Add gap between vm areas as helper to not hide overflow */
- addr = PAGE_ALIGN(vm_node_end(cur->start, cur->pgnr) + 1);
-
- if (list_is_last(&cur->list, head)) {
- if (addr + size > vm_end) {
- /* vm area does not have space anymore */
- spin_unlock(&vm->lock);
- kmem_cache_free(vm->cache, node);
- dev_err(atomisp_dev,
- "no enough virtual address space.\n");
- return NULL;
- }
-
- /* We still have vm space to add new node to tail */
- break;
- }
-
- next = list_entry(cur->list.next, struct hmm_vm_node, list);
- if ((next->start - addr) > size)
- break;
- }
- node->start = addr;
- node->vm = vm;
- list_add(&node->list, &cur->list);
- spin_unlock(&vm->lock);
-
- return node;
-}
-
-void hmm_vm_free_node(struct hmm_vm_node *node)
-{
- struct hmm_vm *vm;
-
- if (!node)
- return;
-
- vm = node->vm;
-
- spin_lock(&vm->lock);
- list_del(&node->list);
- spin_unlock(&vm->lock);
-
- kmem_cache_free(vm->cache, node);
-}
-
-struct hmm_vm_node *hmm_vm_find_node_start(struct hmm_vm *vm, unsigned int addr)
-{
- struct hmm_vm_node *node;
-
- if (!vm)
- return NULL;
-
- spin_lock(&vm->lock);
-
- list_for_each_entry(node, &vm->vm_node_list, list) {
- if (node->start == addr) {
- spin_unlock(&vm->lock);
- return node;
- }
- }
-
- spin_unlock(&vm->lock);
- return NULL;
-}
-
-struct hmm_vm_node *hmm_vm_find_node_in_range(struct hmm_vm *vm,
- unsigned int addr)
-{
- struct hmm_vm_node *node;
-
- if (!vm)
- return NULL;
-
- spin_lock(&vm->lock);
-
- list_for_each_entry(node, &vm->vm_node_list, list) {
- if (addr_in_vm_node(addr, node)) {
- spin_unlock(&vm->lock);
- return node;
- }
- }
-
- spin_unlock(&vm->lock);
- return NULL;
-}
diff --git a/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_custom_host_hrt.h b/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_custom_host_hrt.h
deleted file mode 100644
index c6893d712d61..000000000000
--- a/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_custom_host_hrt.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Support for Medifield PNW Camera Imaging ISP subsystem.
- *
- * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
- *
- * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- *
- */
-#ifndef _hive_isp_css_custom_host_hrt_h_
-#define _hive_isp_css_custom_host_hrt_h_
-
-#include <linux/delay.h>
-#include "atomisp_helper.h"
-
-/*
- * _hrt_master_port_store/load/uload -macros using __force attributed
- * cast to intentional dereferencing __iomem attributed (noderef)
- * pointer from atomisp_get_io_virt_addr
- */
-#define _hrt_master_port_store_8(a, d) \
- (*((s8 __force *)atomisp_get_io_virt_addr(a)) = (d))
-
-#define _hrt_master_port_store_16(a, d) \
- (*((s16 __force *)atomisp_get_io_virt_addr(a)) = (d))
-
-#define _hrt_master_port_store_32(a, d) \
- (*((s32 __force *)atomisp_get_io_virt_addr(a)) = (d))
-
-#define _hrt_master_port_load_8(a) \
- (*(s8 __force *)atomisp_get_io_virt_addr(a))
-
-#define _hrt_master_port_load_16(a) \
- (*(s16 __force *)atomisp_get_io_virt_addr(a))
-
-#define _hrt_master_port_load_32(a) \
- (*(s32 __force *)atomisp_get_io_virt_addr(a))
-
-#define _hrt_master_port_uload_8(a) \
- (*(u8 __force *)atomisp_get_io_virt_addr(a))
-
-#define _hrt_master_port_uload_16(a) \
- (*(u16 __force *)atomisp_get_io_virt_addr(a))
-
-#define _hrt_master_port_uload_32(a) \
- (*(u32 __force *)atomisp_get_io_virt_addr(a))
-
-#define _hrt_master_port_store_8_volatile(a, d) _hrt_master_port_store_8(a, d)
-#define _hrt_master_port_store_16_volatile(a, d) _hrt_master_port_store_16(a, d)
-#define _hrt_master_port_store_32_volatile(a, d) _hrt_master_port_store_32(a, d)
-
-#define _hrt_master_port_load_8_volatile(a) _hrt_master_port_load_8(a)
-#define _hrt_master_port_load_16_volatile(a) _hrt_master_port_load_16(a)
-#define _hrt_master_port_load_32_volatile(a) _hrt_master_port_load_32(a)
-
-#define _hrt_master_port_uload_8_volatile(a) _hrt_master_port_uload_8(a)
-#define _hrt_master_port_uload_16_volatile(a) _hrt_master_port_uload_16(a)
-#define _hrt_master_port_uload_32_volatile(a) _hrt_master_port_uload_32(a)
-
-static inline void hrt_sleep(void)
-{
- udelay(1);
-}
-
-static inline u32 _hrt_mem_store(u32 to, const void *from, size_t n)
-{
- unsigned int i;
- u32 _to = to;
- const char *_from = (const char *)from;
-
- for (i = 0; i < n; i++, _to++, _from++)
- _hrt_master_port_store_8(_to, *_from);
- return _to;
-}
-
-static inline void *_hrt_mem_load(u32 from, void *to, size_t n)
-{
- unsigned int i;
- char *_to = (char *)to;
- u32 _from = from;
-
- for (i = 0; i < n; i++, _to++, _from++)
- *_to = _hrt_master_port_load_8(_from);
- return _to;
-}
-
-static inline u32 _hrt_mem_set(u32 to, int c, size_t n)
-{
- unsigned int i;
- u32 _to = to;
-
- for (i = 0; i < n; i++, _to++)
- _hrt_master_port_store_8(_to, c);
- return _to;
-}
-
-#endif /* _hive_isp_css_custom_host_hrt_h_ */
diff --git a/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.c b/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.c
deleted file mode 100644
index 236f27b50386..000000000000
--- a/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Support for Medifield PNW Camera Imaging ISP subsystem.
- *
- * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
- *
- * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- *
- */
-
-#include "atomisp_internal.h"
-
-#include "hive_isp_css_mm_hrt.h"
-#include "hmm/hmm.h"
-
-#define __page_align(size) (((size) + (PAGE_SIZE - 1)) & (~(PAGE_SIZE - 1)))
-
-static void __user *my_userptr;
-static unsigned int my_num_pages;
-static enum hrt_userptr_type my_usr_type;
-
-void hrt_isp_css_mm_set_user_ptr(void __user *userptr,
- unsigned int num_pages,
- enum hrt_userptr_type type)
-{
- my_userptr = userptr;
- my_num_pages = num_pages;
- my_usr_type = type;
-}
-
-static ia_css_ptr __hrt_isp_css_mm_alloc(size_t bytes,
- const void __user *userptr,
- unsigned int num_pages,
- enum hrt_userptr_type type,
- bool cached)
-{
-#ifdef CONFIG_ION
- if (type == HRT_USR_ION)
- return hmm_alloc(bytes, HMM_BO_ION, 0,
- userptr, cached);
-
-#endif
- if (type == HRT_USR_PTR) {
- if (!userptr)
- return hmm_alloc(bytes, HMM_BO_PRIVATE, 0,
- NULL, cached);
- else {
- if (num_pages < ((__page_align(bytes)) >> PAGE_SHIFT))
- dev_err(atomisp_dev,
- "user space memory size is less than the expected size..\n");
- else if (num_pages > ((__page_align(bytes))
- >> PAGE_SHIFT))
- dev_err(atomisp_dev,
- "user space memory size is large than the expected size..\n");
-
- return hmm_alloc(bytes, HMM_BO_USER, 0,
- userptr, cached);
- }
- } else {
- dev_err(atomisp_dev, "user ptr type is incorrect.\n");
- return 0;
- }
-}
-
-ia_css_ptr hrt_isp_css_mm_alloc(size_t bytes)
-{
- return __hrt_isp_css_mm_alloc(bytes, my_userptr,
- my_num_pages, my_usr_type, false);
-}
-
-ia_css_ptr hrt_isp_css_mm_alloc_user_ptr(size_t bytes,
- const void __user *userptr,
- unsigned int num_pages,
- enum hrt_userptr_type type,
- bool cached)
-{
- return __hrt_isp_css_mm_alloc(bytes, userptr, num_pages,
- type, cached);
-}
-
-ia_css_ptr hrt_isp_css_mm_alloc_cached(size_t bytes)
-{
- if (!my_userptr)
- return hmm_alloc(bytes, HMM_BO_PRIVATE, 0, NULL,
- HMM_CACHED);
- else {
- if (my_num_pages < ((__page_align(bytes)) >> PAGE_SHIFT))
- dev_err(atomisp_dev,
- "user space memory size is less than the expected size..\n");
- else if (my_num_pages > ((__page_align(bytes)) >> PAGE_SHIFT))
- dev_err(atomisp_dev,
- "user space memory size is large than the expected size..\n");
-
- return hmm_alloc(bytes, HMM_BO_USER, 0,
- my_userptr, HMM_CACHED);
- }
-}
-
-ia_css_ptr hrt_isp_css_mm_calloc(size_t bytes)
-{
- ia_css_ptr ptr = hrt_isp_css_mm_alloc(bytes);
-
- if (ptr)
- hmm_set(ptr, 0, bytes);
- return ptr;
-}
-
-ia_css_ptr hrt_isp_css_mm_calloc_cached(size_t bytes)
-{
- ia_css_ptr ptr = hrt_isp_css_mm_alloc_cached(bytes);
-
- if (ptr)
- hmm_set(ptr, 0, bytes);
- return ptr;
-}
diff --git a/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.h b/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.h
deleted file mode 100644
index 818ecf90b1f5..000000000000
--- a/drivers/staging/media/atomisp/pci/hrt/hive_isp_css_mm_hrt.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Support for Medfield PNW Camera Imaging ISP subsystem.
- *
- * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
- *
- * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- *
- */
-
-#ifndef _hive_isp_css_mm_hrt_h_
-#define _hive_isp_css_mm_hrt_h_
-
-#include <hmm/hmm.h>
-#include <hrt/hive_isp_css_custom_host_hrt.h>
-
-#define HRT_BUF_FLAG_CACHED BIT(0)
-
-enum hrt_userptr_type {
- HRT_USR_PTR = 0,
-#ifdef CONFIG_ION
- HRT_USR_ION,
-#endif
-};
-
-struct hrt_userbuffer_attr {
- enum hrt_userptr_type type;
- unsigned int pgnr;
-};
-
-void hrt_isp_css_mm_set_user_ptr(void __user *userptr,
- unsigned int num_pages, enum hrt_userptr_type);
-
-/* Allocate memory, returns a virtual address */
-ia_css_ptr hrt_isp_css_mm_alloc(size_t bytes);
-ia_css_ptr hrt_isp_css_mm_alloc_user_ptr(size_t bytes,
- const void __user *userptr,
- unsigned int num_pages,
- enum hrt_userptr_type,
- bool cached);
-ia_css_ptr hrt_isp_css_mm_alloc_cached(size_t bytes);
-
-/* allocate memory and initialize with zeros,
- returns a virtual address */
-ia_css_ptr hrt_isp_css_mm_calloc(size_t bytes);
-ia_css_ptr hrt_isp_css_mm_calloc_cached(size_t bytes);
-
-#endif /* _hive_isp_css_mm_hrt_h_ */
diff --git a/drivers/staging/media/atomisp/pci/ia_css.h b/drivers/staging/media/atomisp/pci/ia_css.h
index e44df6916d90..d83e1ae5b0b3 100644
--- a/drivers/staging/media/atomisp/pci/ia_css.h
+++ b/drivers/staging/media/atomisp/pci/ia_css.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/*
* Support for Intel Camera Imaging ISP subsystem.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_3a.h b/drivers/staging/media/atomisp/pci/ia_css_3a.h
index a79941a2e0f2..70cfc915cc56 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_3a.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_3a.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -106,7 +107,7 @@ struct ia_css_isp_3a_statistics_map {
* used.
* Always use this function, never copy the buffer directly.
*/
-enum ia_css_err
+int
ia_css_get_3a_statistics(struct ia_css_3a_statistics *host_stats,
const struct ia_css_isp_3a_statistics *isp_stats);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
index d281846eeba5..36583ab12e3f 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -19,7 +20,7 @@
* This file contains types used for acceleration
*/
-#include <system_types.h> /* HAS_IRQ_MAP_VERSION_# */
+#include <system_local.h> /* HAS_IRQ_MAP_VERSION_# */
#include <type_support.h>
#include <platform_support.h>
#include <debug_global.h>
@@ -62,8 +63,8 @@ enum ia_css_cell_type {
*/
enum ia_css_fw_type {
ia_css_sp_firmware, /** Firmware for the SP */
- ia_css_isp_firmware, /** Firmware for the ISP */
- ia_css_bootloader_firmware, /** Firmware for the BootLoader */
+ ia_css_isp_firmware, /** Firmware for the ISP */
+ ia_css_bootloader_firmware, /** Firmware for the BootLoader */
ia_css_acc_firmware /** Firmware for accelrations */
};
diff --git a/drivers/staging/media/atomisp/pci/ia_css_buffer.h b/drivers/staging/media/atomisp/pci/ia_css_buffer.h
index 38e1f4791029..b1e8357b94b5 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_buffer.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_buffer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_control.h b/drivers/staging/media/atomisp/pci/ia_css_control.h
index 248040b3ec07..88f031a63ba2 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_control.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_control.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -37,15 +38,15 @@
* of the L1 page table. This is a physical
* address or index.
* @param[in] irq_type The type of interrupt to be used (edge or level)
- * @return Returns IA_CSS_ERR_INTERNAL_ERROR in case of any
- * errors and IA_CSS_SUCCESS otherwise.
+ * @return Returns -EINVAL in case of any
+ * errors and 0 otherwise.
*
* This function initializes the API which includes allocating and initializing
* internal data structures. This also interprets the firmware package. All
* contents of this firmware package are copied into local data structures, so
* the fw pointer could be freed after this function completes.
*/
-enum ia_css_err ia_css_init(struct device *dev,
+int ia_css_init(struct device *dev,
const struct ia_css_env *env,
const struct ia_css_fw *fw,
u32 l1_base,
@@ -77,7 +78,7 @@ ia_css_uninit(void);
* This function should only be called when the SP is not running, calling it
* when the SP is running will result in an error value being returned. }
*/
-enum ia_css_err
+int
ia_css_enable_isys_event_queue(bool enable);
/* @brief Test whether the ISP has started.
@@ -109,23 +110,23 @@ ia_css_sp_has_terminated(void);
/* @brief start SP hardware
*
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* It will boot the SP hardware and start multi-threading infrastructure.
* All threads will be started and blocked by semaphore. This function should
* be called before any ia_css_stream_start().
*/
-enum ia_css_err
+int
ia_css_start_sp(void);
/* @brief stop SP hardware
*
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* This function will terminate all threads and shut down SP. It should be
* called after all ia_css_stream_stop().
*/
-enum ia_css_err
+int
ia_css_stop_sp(void);
#endif /* __IA_CSS_CONTROL_H */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_device_access.c b/drivers/staging/media/atomisp/pci/ia_css_device_access.c
index 6ad8687cf08b..9cd2d3caa5c9 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_device_access.c
+++ b/drivers/staging/media/atomisp/pci/ia_css_device_access.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -14,7 +15,7 @@
#include "ia_css_device_access.h"
#include <type_support.h> /* for uint*, size_t */
-#include <system_types.h> /* for hrt_address */
+#include <system_local.h> /* for hrt_address */
#include <ia_css_env.h> /* for ia_css_hw_access_env */
#include <assert_support.h> /* for assert */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_device_access.h b/drivers/staging/media/atomisp/pci/ia_css_device_access.h
index b2bf7d540b62..07d611fdd19f 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_device_access.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_device_access.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -20,7 +21,7 @@
*/
#include <type_support.h> /* for uint*, size_t */
-#include <system_types.h> /* for hrt_address */
+#include <system_local.h> /* for hrt_address */
#include <ia_css_env.h> /* for ia_css_hw_access_env */
void
diff --git a/drivers/staging/media/atomisp/pci/ia_css_dvs.h b/drivers/staging/media/atomisp/pci/ia_css_dvs.h
index e647f73c3bd6..3367dfd64050 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_dvs.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_dvs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -94,7 +95,7 @@ union ia_css_dvs_statistics_host {
* advised to map the ISP memory into a host-side pointer and use
* the ia_css_translate_dvs_statistics() function instead.
*/
-enum ia_css_err
+int
ia_css_get_dvs_statistics(struct ia_css_dvs_statistics *host_stats,
const struct ia_css_isp_dvs_statistics *isp_stats);
@@ -128,7 +129,7 @@ ia_css_translate_dvs_statistics(
* advised to map the ISP memory into a host-side pointer and use
* the ia_css_translate_dvs2_statistics() function instead.
*/
-enum ia_css_err
+int
ia_css_get_dvs2_statistics(struct ia_css_dvs2_statistics *host_stats,
const struct ia_css_isp_dvs_statistics *isp_stats);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_env.h b/drivers/staging/media/atomisp/pci/ia_css_env.h
index 8b0218ee658d..8debf334c15c 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_env.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_env.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_err.h b/drivers/staging/media/atomisp/pci/ia_css_err.h
index 375952a7782e..98401a4a171d 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_err.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_err.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -20,27 +21,6 @@
* functions in the CSS-API.
*/
-/* Errors, these values are used as the return value for most
- * functions in this API.
- */
-enum ia_css_err {
- IA_CSS_SUCCESS,
- IA_CSS_ERR_INTERNAL_ERROR,
- IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY,
- IA_CSS_ERR_INVALID_ARGUMENTS,
- IA_CSS_ERR_SYSTEM_NOT_IDLE,
- IA_CSS_ERR_MODE_HAS_NO_VIEWFINDER,
- IA_CSS_ERR_QUEUE_IS_FULL,
- IA_CSS_ERR_QUEUE_IS_EMPTY,
- IA_CSS_ERR_RESOURCE_NOT_AVAILABLE,
- IA_CSS_ERR_RESOURCE_LIST_TO_SMALL,
- IA_CSS_ERR_RESOURCE_ITEMS_STILL_ALLOCATED,
- IA_CSS_ERR_RESOURCE_EXHAUSTED,
- IA_CSS_ERR_RESOURCE_ALREADY_ALLOCATED,
- IA_CSS_ERR_VERSION_MISMATCH,
- IA_CSS_ERR_NOT_SUPPORTED
-};
-
/* FW warnings. This enum contains a value for each warning that
* the SP FW could indicate potential performance issue
*/
diff --git a/drivers/staging/media/atomisp/pci/ia_css_event_public.h b/drivers/staging/media/atomisp/pci/ia_css_event_public.h
index 5c0470fa4a74..08ea801dd5ac 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_event_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_event_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -143,9 +144,9 @@ struct ia_css_event {
*
* @param[out] event Pointer to the event struct which will be filled by
* this function if an event is available.
- * @return IA_CSS_ERR_QUEUE_IS_EMPTY if no events are
+ * @return -ENODATA if no events are
* available or
- * IA_CSS_SUCCESS otherwise.
+ * 0 otherwise.
*
* This function dequeues an event from the PSYS event queue. The queue is
* between the Host CPU and the CSS system. This function can be
@@ -153,31 +154,31 @@ struct ia_css_event {
* was available and can be used in a polling-like situation where the NO_EVENT
* return value is used to determine whether an event was available or not.
*/
-enum ia_css_err
+int
ia_css_dequeue_psys_event(struct ia_css_event *event);
/* @brief Dequeue an event from the CSS system.
*
* @param[out] event Pointer to the event struct which will be filled by
* this function if an event is available.
- * @return IA_CSS_ERR_QUEUE_IS_EMPTY if no events are
+ * @return -ENODATA if no events are
* available or
- * IA_CSS_SUCCESS otherwise.
+ * 0 otherwise.
*
* deprecated{Use ia_css_dequeue_psys_event instead}.
* Unless the isys event queue is explicitly enabled, this function will
* dequeue both isys (EOF) and psys events (all others).
*/
-enum ia_css_err
+int
ia_css_dequeue_event(struct ia_css_event *event);
/* @brief Dequeue an ISYS event from the CSS system.
*
* @param[out] event Pointer to the event struct which will be filled by
* this function if an event is available.
- * @return IA_CSS_ERR_QUEUE_IS_EMPTY if no events are
+ * @return -ENODATA if no events are
* available or
- * IA_CSS_SUCCESS otherwise.
+ * 0 otherwise.
*
* This function dequeues an event from the ISYS event queue. The queue is
* between host and the CSS system.
@@ -190,7 +191,7 @@ ia_css_dequeue_event(struct ia_css_event *event);
* incurring additional latency due to locks being held by other CSS API
* functions.
*/
-enum ia_css_err
+int
ia_css_dequeue_isys_event(struct ia_css_event *event);
#endif /* __IA_CSS_EVENT_PUBLIC_H */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_firmware.h b/drivers/staging/media/atomisp/pci/ia_css_firmware.h
index 50817162703b..edab72256494 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_firmware.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_firmware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -36,8 +37,8 @@ struct ia_css_fw {
* printing.
* @param[in] fw Firmware package containing the firmware for all
* predefined ISP binaries.
- * @return Returns IA_CSS_ERR_INTERNAL_ERROR in case of any
- * errors and IA_CSS_SUCCESS otherwise.
+ * @return Returns -EINVAL in case of any
+ * errors and 0 otherwise.
*
* This function interprets the firmware package. All
* contents of this firmware package are copied into local data structures, so
@@ -47,7 +48,7 @@ struct ia_css_fw {
* speeds up ia_css_init (ia_css_init is called each time a stream is created but the
* firmware only needs to be loaded once).
*/
-enum ia_css_err
+int
ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
const struct ia_css_fw *fw);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_frac.h b/drivers/staging/media/atomisp/pci/ia_css_frac.h
index 59720370cb8e..661af9225b19 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_frac.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_frac.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_frame_format.h b/drivers/staging/media/atomisp/pci/ia_css_frame_format.h
index 2f177edc36ac..093e23a9b079 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_frame_format.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_frame_format.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_frame_public.h b/drivers/staging/media/atomisp/pci/ia_css_frame_public.h
index 69e9143e5418..96c86f0dc81c 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_frame_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_frame_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -121,8 +122,7 @@ struct ia_css_frame_info {
struct ia_css_crop_info crop_info;
};
-#define IA_CSS_BINARY_DEFAULT_FRAME_INFO \
-(struct ia_css_frame_info) { \
+#define IA_CSS_BINARY_DEFAULT_FRAME_INFO { \
.format = IA_CSS_FRAME_FORMAT_NUM, \
.raw_bayer_order = IA_CSS_BAYER_ORDER_NUM, \
}
@@ -184,8 +184,7 @@ struct ia_css_frame {
info.format */
};
-#define DEFAULT_FRAME \
-(struct ia_css_frame) { \
+#define DEFAULT_FRAME { \
.info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \
.dynamic_queue_id = SH_CSS_INVALID_QUEUE_ID, \
.buf_type = IA_CSS_BUFFER_TYPE_INVALID, \
@@ -214,7 +213,7 @@ void ia_css_frame_zero(struct ia_css_frame *frame);
* Allocate a CSS frame structure. The memory for the frame data will be
* allocated in the CSS address space.
*/
-enum ia_css_err
+int
ia_css_frame_allocate(struct ia_css_frame **frame,
unsigned int width,
unsigned int height,
@@ -232,7 +231,7 @@ ia_css_frame_allocate(struct ia_css_frame **frame,
* This is a convenience function, implemented on top of
* ia_css_frame_allocate().
*/
-enum ia_css_err
+int
ia_css_frame_allocate_from_info(struct ia_css_frame **frame,
const struct ia_css_frame_info *info);
/* @brief Free a CSS frame structure.
@@ -260,7 +259,7 @@ ia_css_frame_free(struct ia_css_frame *frame);
* physically contiguous memory.
* Deprecated.
*/
-enum ia_css_err
+int
ia_css_frame_allocate_contiguous(struct ia_css_frame **frame,
unsigned int width,
unsigned int height,
@@ -280,7 +279,7 @@ ia_css_frame_allocate_contiguous(struct ia_css_frame **frame,
* Only for FPGA display driver which needs physically contiguous memory.
* Deprecated.
*/
-enum ia_css_err
+int
ia_css_frame_allocate_contiguous_from_info(struct ia_css_frame **frame,
const struct ia_css_frame_info *info);
@@ -293,7 +292,7 @@ ia_css_frame_allocate_contiguous_from_info(struct ia_css_frame **frame,
* Allocate an empty CSS frame with no data buffer using the parameters
* in the frame info.
*/
-enum ia_css_err
+int
ia_css_frame_create_from_info(struct ia_css_frame **frame,
const struct ia_css_frame_info *info);
@@ -310,7 +309,7 @@ ia_css_frame_create_from_info(struct ia_css_frame **frame,
* free the mapped_data buffer. However if ia_css_frame_free() is called and
* the frame had a valid data buffer, it would be freed along with the frame.
*/
-enum ia_css_err
+int
ia_css_frame_set_data(struct ia_css_frame *frame,
const ia_css_ptr mapped_data,
size_t data_size_bytes);
@@ -331,12 +330,12 @@ ia_css_frame_set_data(struct ia_css_frame *frame,
* ia_css_frame_allocate() does, but instead of allocating the memory, it will
* map the pre-allocated memory into the CSS address space.
*/
-enum ia_css_err
+int
ia_css_frame_map(struct ia_css_frame **frame,
const struct ia_css_frame_info *info,
const void __user *data,
u16 attribute,
- void *context);
+ unsigned int pgnr);
/* @brief Unmap a CSS frame structure.
*
diff --git a/drivers/staging/media/atomisp/pci/ia_css_host_data.h b/drivers/staging/media/atomisp/pci/ia_css_host_data.h
index bc82e97d24cb..f54cc504f5d4 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_host_data.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_host_data.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/*
* Support for Intel Camera Imaging ISP subsystem.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_input_port.h b/drivers/staging/media/atomisp/pci/ia_css_input_port.h
index ad9ca5449369..9772b6928239 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_input_port.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_input_port.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_irq.h b/drivers/staging/media/atomisp/pci/ia_css_irq.h
index 7716373553e0..3b81a39cfe97 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_irq.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_irq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -55,11 +56,8 @@ enum ia_css_irq_info {
/** the css receiver received the end of frame */
IA_CSS_IRQ_INFO_CSS_RECEIVER_SOL = 1 << 4,
/** the css receiver received the start of line */
- IA_CSS_IRQ_INFO_PSYS_EVENTS_READY = 1 << 5,
+ IA_CSS_IRQ_INFO_EVENTS_READY = 1 << 5,
/** One or more events are available in the PSYS event queue */
- IA_CSS_IRQ_INFO_EVENTS_READY = IA_CSS_IRQ_INFO_PSYS_EVENTS_READY,
- /** deprecated{obsolete version of IA_CSS_IRQ_INFO_PSYS_EVENTS_READY,
- * same functionality.} */
IA_CSS_IRQ_INFO_CSS_RECEIVER_EOL = 1 << 6,
/** the css receiver received the end of line */
IA_CSS_IRQ_INFO_CSS_RECEIVER_SIDEBAND_CHANGED = 1 << 7,
@@ -144,14 +142,14 @@ struct ia_css_irq {
* @return If an error is encountered during the interrupt info
* and no interrupt could be translated successfully, this
* will return IA_CSS_INTERNAL_ERROR. Otherwise
- * IA_CSS_SUCCESS.
+ * 0.
*
* This function is expected to be executed after an interrupt has been sent
* to the IA from the CSS. This function returns information about the interrupt
* which is needed by the IA code to properly handle the interrupt. This
* information includes the image pipe, buffer type etc.
*/
-enum ia_css_err
+int
ia_css_irq_translate(unsigned int *info);
/* @brief Get CSI receiver error info.
@@ -227,9 +225,9 @@ ia_css_rx_port_clear_irq_info(enum mipi_port_id port, unsigned int irq_bits);
* @return Returns IA_CSS_INTERNAL_ERROR if this interrupt
* type cannot be enabled/disabled which is true for
* CSS internal interrupts. Otherwise returns
- * IA_CSS_SUCCESS.
+ * 0.
*/
-enum ia_css_err
+int
ia_css_irq_enable(enum ia_css_irq_info type, bool enable);
#endif /* __IA_CSS_IRQ_H */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h b/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h
index 6545efd24cbe..1abb2fd6a913 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_isp_params.h b/drivers/staging/media/atomisp/pci/ia_css_isp_params.h
index b8b3c48492ae..6e3082b39ed6 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_isp_params.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_params.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_isp_states.h b/drivers/staging/media/atomisp/pci/ia_css_isp_states.h
index cc9cdcd0e2be..9f6c342a1705 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_isp_states.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_states.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -65,7 +66,7 @@ struct ia_css_state_memory_offsets {
#include "ia_css_binary.h" /* struct ia_css_binary */
/* Code generated by genparam/genstate.c:gen_state_init_table() */
-extern void (* ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
+extern void (*ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
const struct ia_css_binary *binary);
#endif /* IA_CSS_INCLUDE_STATE */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_memory_access.c b/drivers/staging/media/atomisp/pci/ia_css_memory_access.c
deleted file mode 100644
index 8d1356047448..000000000000
--- a/drivers/staging/media/atomisp/pci/ia_css_memory_access.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015-2017, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-#include <type_support.h>
-#include <system_types.h>
-#include <assert_support.h>
-#include <memory_access.h>
-#include <ia_css_env.h>
-#include <hrt/hive_isp_css_mm_hrt.h>
-
-const hrt_vaddress mmgr_NULL = (hrt_vaddress)0;
-const hrt_vaddress mmgr_EXCEPTION = (hrt_vaddress)-1;
-
-hrt_vaddress
-mmgr_malloc(const size_t size)
-{
- return mmgr_alloc_attr(size, 0);
-}
-
-hrt_vaddress mmgr_alloc_attr(const size_t size, const uint16_t attrs)
-{
- u16 masked_attrs = attrs & MMGR_ATTRIBUTE_MASK;
-
- WARN_ON(attrs & MMGR_ATTRIBUTE_CONTIGUOUS);
-
- if (masked_attrs & MMGR_ATTRIBUTE_CLEARED) {
- if (masked_attrs & MMGR_ATTRIBUTE_CACHED)
- return (ia_css_ptr) hrt_isp_css_mm_calloc_cached(size);
- else
- return (ia_css_ptr) hrt_isp_css_mm_calloc(size);
- } else {
- if (masked_attrs & MMGR_ATTRIBUTE_CACHED)
- return (ia_css_ptr) hrt_isp_css_mm_alloc_cached(size);
- else
- return (ia_css_ptr) hrt_isp_css_mm_alloc(size);
- }
-}
-
-hrt_vaddress
-mmgr_calloc(const size_t N, const size_t size)
-{
- return mmgr_alloc_attr(size * N, MMGR_ATTRIBUTE_CLEARED);
-}
-
-void mmgr_clear(hrt_vaddress vaddr, const size_t size)
-{
- if (vaddr)
- hmm_set(vaddr, 0, size);
-}
-
-void mmgr_load(const hrt_vaddress vaddr, void *data, const size_t size)
-{
- if (vaddr && data)
- hmm_load(vaddr, data, size);
-}
-
-void
-mmgr_store(const hrt_vaddress vaddr, const void *data, const size_t size)
-{
- if (vaddr && data)
- hmm_store(vaddr, data, size);
-}
-
-hrt_vaddress
-mmgr_mmap(const void __user *ptr, const size_t size,
- u16 attribute, void *context)
-{
- struct hrt_userbuffer_attr *userbuffer_attr = context;
-
- return hrt_isp_css_mm_alloc_user_ptr(
- size, ptr, userbuffer_attr->pgnr,
- userbuffer_attr->type,
- attribute & HRT_BUF_FLAG_CACHED);
-}
diff --git a/drivers/staging/media/atomisp/pci/ia_css_metadata.h b/drivers/staging/media/atomisp/pci/ia_css_metadata.h
index 0212d71b3355..9eb1b76a3b2a 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_metadata.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_metadata.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_mipi.h b/drivers/staging/media/atomisp/pci/ia_css_mipi.h
index c02138ee2511..56a2fca8117f 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_mipi.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_mipi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -37,7 +38,7 @@
*
* Specifies a CSS MIPI frame buffer: size in memory words (32B).
*/
-enum ia_css_err
+int
ia_css_mipi_frame_specify(const unsigned int size_mem_words,
const bool contiguous);
@@ -54,7 +55,7 @@ ia_css_mipi_frame_specify(const unsigned int size_mem_words,
*
*
*/
-enum ia_css_err
+int
ia_css_mipi_frame_enable_check_on_size(const enum mipi_port_id port,
const unsigned int size_mem_words);
#endif
@@ -71,7 +72,7 @@ ia_css_mipi_frame_enable_check_on_size(const enum mipi_port_id port,
*
* Calculate the size of a mipi frame, based on the resolution and format.
*/
-enum ia_css_err
+int
ia_css_mipi_frame_calculate_size(const unsigned int width,
const unsigned int height,
const enum atomisp_input_format format,
diff --git a/drivers/staging/media/atomisp/pci/ia_css_mmu.h b/drivers/staging/media/atomisp/pci/ia_css_mmu.h
index 13c21056bfbf..8f04d196c646 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_mmu.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_mmu.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_mmu_private.h b/drivers/staging/media/atomisp/pci/ia_css_mmu_private.h
index 1021e4f380a5..dc6542aa64f2 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_mmu_private.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_mmu_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_morph.h b/drivers/staging/media/atomisp/pci/ia_css_morph.h
index de409638d009..9c4b41b94256 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_morph.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_morph.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_pipe.h b/drivers/staging/media/atomisp/pci/ia_css_pipe.h
index 91653952f1a7..bb0abf9bffb1 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_pipe.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_pipe.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -31,7 +32,7 @@ struct ia_css_preview_settings {
struct ia_css_binary vf_pp_binary;
/* 2401 only for these two - do we in fact use them for anything real */
- struct ia_css_frame *delay_frames[MAX_NUM_DELAY_FRAMES];
+ struct ia_css_frame *delay_frames[MAX_NUM_VIDEO_DELAY_FRAMES];
struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES];
struct ia_css_pipe *copy_pipe;
@@ -39,8 +40,7 @@ struct ia_css_preview_settings {
struct ia_css_pipe *acc_pipe;
};
-#define IA_CSS_DEFAULT_PREVIEW_SETTINGS \
-(struct ia_css_preview_settings) { \
+#define IA_CSS_DEFAULT_PREVIEW_SETTINGS { \
.copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
.preview_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
.vf_pp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
@@ -64,8 +64,7 @@ struct ia_css_capture_settings {
unsigned int num_yuv_scaler;
};
-#define IA_CSS_DEFAULT_CAPTURE_SETTINGS \
-(struct ia_css_capture_settings) { \
+#define IA_CSS_DEFAULT_CAPTURE_SETTINGS { \
.copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
.primary_binary = {IA_CSS_BINARY_DEFAULT_SETTINGS}, \
.pre_isp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
@@ -90,8 +89,7 @@ struct ia_css_video_settings {
unsigned int num_yuv_scaler;
};
-#define IA_CSS_DEFAULT_VIDEO_SETTINGS \
-(struct ia_css_video_settings) { \
+#define IA_CSS_DEFAULT_VIDEO_SETTINGS { \
.copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
.video_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
.vf_pp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
@@ -107,8 +105,7 @@ struct ia_css_yuvpp_settings {
unsigned int num_output;
};
-#define IA_CSS_DEFAULT_YUVPP_SETTINGS \
-(struct ia_css_yuvpp_settings) { \
+#define IA_CSS_DEFAULT_YUVPP_SETTINGS { \
.copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \
}
@@ -146,7 +143,7 @@ struct ia_css_pipe {
struct ia_css_capture_settings capture;
struct ia_css_yuvpp_settings yuvpp;
} pipe_settings;
- hrt_vaddress scaler_pp_lut;
+ ia_css_ptr scaler_pp_lut;
struct osys_object *osys_obj;
/* This number is unique per pipe each instance of css. This number is
@@ -156,8 +153,7 @@ struct ia_css_pipe {
unsigned int pipe_num;
};
-#define IA_CSS_DEFAULT_PIPE \
-(struct ia_css_pipe) { \
+#define IA_CSS_DEFAULT_PIPE { \
.config = DEFAULT_PIPE_CONFIG, \
.info = DEFAULT_PIPE_INFO, \
.mode = IA_CSS_PIPE_ID_ACC, /* (pipe_id) */ \
@@ -181,7 +177,7 @@ struct ia_css_pipe {
void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map);
-enum ia_css_err
+int
sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
struct ia_css_isp_parameters *params,
bool commit, struct ia_css_pipe *pipe);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h b/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
index e782978a5ce7..4affd21f9e3f 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -148,8 +149,7 @@ struct ia_css_pipe_config {
/**
* Default settings for newly created pipe configurations.
*/
-#define DEFAULT_PIPE_CONFIG \
-(struct ia_css_pipe_config) { \
+#define DEFAULT_PIPE_CONFIG { \
.mode = IA_CSS_PIPE_MODE_PREVIEW, \
.isp_pipe_version = 1, \
.output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \
@@ -202,8 +202,7 @@ struct ia_css_pipe_info {
/**
* Defaults for ia_css_pipe_info structs.
*/
-#define DEFAULT_PIPE_INFO \
-(struct ia_css_pipe_info) { \
+#define DEFAULT_PIPE_INFO {\
.output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \
.vf_output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \
.raw_output_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \
@@ -249,44 +248,44 @@ void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config);
/* @brief Create a pipe
* @param[in] config The pipe configuration.
* @param[out] pipe The pipe.
- * @return IA_CSS_SUCCESS or the error code.
+ * @return 0 or the error code.
*
* This function will create a pipe with the given
* configuration.
*/
-enum ia_css_err
+int
ia_css_pipe_create(const struct ia_css_pipe_config *config,
struct ia_css_pipe **pipe);
/* @brief Destroy a pipe
* @param[in] pipe The pipe.
- * @return IA_CSS_SUCCESS or the error code.
+ * @return 0 or the error code.
*
* This function will destroy a given pipe.
*/
-enum ia_css_err
+int
ia_css_pipe_destroy(struct ia_css_pipe *pipe);
/* @brief Provides information about a pipe
* @param[in] pipe The pipe.
* @param[out] pipe_info The pipe information.
- * @return IA_CSS_SUCCESS or IA_CSS_ERR_INVALID_ARGUMENTS.
+ * @return 0 or -EINVAL.
*
* This function will provide information about a given pipe.
*/
-enum ia_css_err
+int
ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
struct ia_css_pipe_info *pipe_info);
/* @brief Configure a pipe with filter coefficients.
* @param[in] pipe The pipe.
* @param[in] config The pointer to ISP configuration.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* This function configures the filter coefficients for an image
* pipe.
*/
-enum ia_css_err
+int
ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe,
struct ia_css_isp_config *config);
@@ -304,7 +303,7 @@ ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe,
at the same moment in time. There is no control over
the order of these events. Once an IRQ has been raised
all remembered events are reset.
- * @return IA_CSS_SUCCESS.
+ * @return 0.
*
Controls when the Event generator in the CSS raises an IRQ to the Host.
The main purpose of this function is to reduce the amount of interrupts
@@ -362,7 +361,7 @@ ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe,
All other events (3A, VF output, pipeline done) will not raise an interrupt
to the Host. These events are not lost but always stored in the event queue.
*/
-enum ia_css_err
+int
ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
unsigned int or_mask,
unsigned int and_mask);
@@ -374,7 +373,7 @@ ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
of enum ia_css_event_irq_mask_type. Pointer may be NULL.
* @param[out] and_mask Current and_mask.The bits in this mask are a binary or
of enum ia_css_event_irq_mask_type. Pointer may be NULL.
- * @return IA_CSS_SUCCESS.
+ * @return 0.
*
Reads the current event IRQ mask from the CSS. Reading returns the actual
values as used by the SP and not any mirrored values stored at the Host.\n
@@ -383,7 +382,7 @@ Precondition:\n
SP must be running.\n
*/
-enum ia_css_err
+int
ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
unsigned int *or_mask,
unsigned int *and_mask);
@@ -396,7 +395,7 @@ ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
* structure. Only the data pointer within it will
* be passed into the internal queues.
* @return IA_CSS_INTERNAL_ERROR in case of unexpected errors,
- * IA_CSS_SUCCESS otherwise.
+ * 0 otherwise.
*
* This function adds a buffer (which has a certain buffer type) to the queue
* for this type. This queue is owned by the image pipe. After this function
@@ -406,7 +405,7 @@ ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
* host code via an interrupt. Buffers will be consumed in the same order they
* get queued, but may be returned to the host out of order.
*/
-enum ia_css_err
+int
ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
const struct ia_css_buffer *buffer);
@@ -418,7 +417,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
* The resulting buffer pointer is written into the dta
* field.
* @return IA_CSS_ERR_NO_BUFFER if the queue is empty or
- * IA_CSS_SUCCESS otherwise.
+ * 0 otherwise.
*
* This function dequeues a buffer from a buffer queue. The queue is indicated
* by the buffer type argument. This function can be called after an interrupt
@@ -426,7 +425,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
* be used in a polling-like situation where the NO_BUFFER return value is used
* to determine whether a buffer was available or not.
*/
-enum ia_css_err
+int
ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
struct ia_css_buffer *buffer);
@@ -437,9 +436,9 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
* @param[in] enable Enable Flag (1 to enable ; 0 to disable)
*
* @return
- * IA_CSS_SUCCESS : Success
- * IA_CSS_ERR_INVALID_ARGUMENTS : Invalid Parameters
- * IA_CSS_ERR_RESOURCE_NOT_AVAILABLE : Inactive QOS Pipe
+ * 0 : Success
+ * -EINVAL : Invalid Parameters
+ * -EBUSY : Inactive QOS Pipe
* (No active stream with this pipe)
*
* This function will request state change (enable or disable) for the Extension
@@ -452,7 +451,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
* 4. State change cannot be guaranteed immediately OR on frame boundary
*
*/
-enum ia_css_err
+int
ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe,
u32 fw_handle,
bool enable);
@@ -464,9 +463,9 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe,
* @param[out] *enable Enable Flag
*
* @return
- * IA_CSS_SUCCESS : Success
- * IA_CSS_ERR_INVALID_ARGUMENTS : Invalid Parameters
- * IA_CSS_ERR_RESOURCE_NOT_AVAILABLE : Inactive QOS Pipe
+ * 0 : Success
+ * -EINVAL : Invalid Parameters
+ * -EBUSY : Inactive QOS Pipe
* (No active stream with this pipe)
*
* This function will query the state of the Extension stage (firmware handle)
@@ -478,7 +477,7 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe,
* 3. Initial(Default) state of QOS Extensions is Disabled.
*
*/
-enum ia_css_err
+int
ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe,
u32 fw_handle,
bool *enable);
@@ -491,18 +490,18 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe,
* @param[in] isp_seg Parameter memory descriptors for ISP segments.
*
* @return
- * IA_CSS_SUCCESS : Success
- * IA_CSS_ERR_INVALID_ARGUMENTS : Invalid Parameters
- * IA_CSS_ERR_RESOURCE_NOT_AVAILABLE : Inactive QOS Pipe
+ * 0 : Success
+ * -EINVAL : Invalid Parameters
+ * -EBUSY : Inactive QOS Pipe
* (No active stream with this pipe)
*
* \deprecated{This interface is used to temporarily support a late-developed,
* specific use-case on a specific IPU2 platform. It will not be supported or
* maintained on IPU3 or further.}
*/
-enum ia_css_err
+int
ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
- uint32_t fw_handle,
+ u32 fw_handle,
struct ia_css_isp_param_css_segments *css_seg,
struct ia_css_isp_param_isp_segments *isp_seg);
@@ -521,8 +520,8 @@ ia_css_pipe_get_isp_config(struct ia_css_pipe *pipe,
* @param[in] lut Look up tabel
*
* @return
- * IA_CSS_SUCCESS : Success
- * IA_CSS_ERR_INVALID_ARGUMENTS : Invalid Parameters
+ * 0 : Success
+ * -EINVAL : Invalid Parameters
*
* Note:
* 1) Note that both GDC's are programmed with the same table.
@@ -531,7 +530,7 @@ ia_css_pipe_get_isp_config(struct ia_css_pipe *pipe,
* 3) This function must be called before stream start
*
*/
-enum ia_css_err
+int
ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
const void *lut);
/* @brief Checking of DVS statistics ability
@@ -550,9 +549,9 @@ bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info);
* @param[in] format Format to set
*
* @return
- * IA_CSS_SUCCESS : Success
- * IA_CSS_ERR_INVALID_ARGUMENTS : Invalid Parameters
- * IA_CSS_ERR_INTERNAL_ERROR : Pipe misses binary info
+ * 0 : Success
+ * -EINVAL : Invalid Parameters
+ * -EINVAL : Pipe misses binary info
*
* Note:
* 1) This is an optional function to override the formats set in the pipe.
@@ -561,7 +560,7 @@ bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info);
* 4) If this function is used, it MUST be called after ia_css_pipe_create.
* 5) If this function is used, this function MUST be called before ia_css_stream_start.
*/
-enum ia_css_err
+int
ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
int output_pin,
enum ia_css_frame_format format);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_prbs.h b/drivers/staging/media/atomisp/pci/ia_css_prbs.h
index 037fc4f77c77..53bbf1dce3bf 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_prbs.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_prbs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_properties.h b/drivers/staging/media/atomisp/pci/ia_css_properties.h
index 9a167306611c..2cd014f7ae29 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_properties.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_properties.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_shading.h b/drivers/staging/media/atomisp/pci/ia_css_shading.h
index 588f53d32b72..de7ae5cabf7d 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_shading.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_shading.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream.h b/drivers/staging/media/atomisp/pci/ia_css_stream.h
index 5690fe832f41..e3e7a8a03b04 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_stream.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_stream.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -102,7 +103,7 @@ ia_css_get_isp_dvs2_coefficients(struct ia_css_stream *stream,
short *ver_coefs_even_real,
short *ver_coefs_even_imag);
-enum ia_css_err
+int
ia_css_stream_isp_parameters_init(struct ia_css_stream *stream);
void
diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream_format.h b/drivers/staging/media/atomisp/pci/ia_css_stream_format.h
index 4cd29833584f..aac22d8581a0 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_stream_format.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_stream_format.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream_public.h b/drivers/staging/media/atomisp/pci/ia_css_stream_public.h
index fe11c8bf3cdc..83846e417ae5 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_stream_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_stream_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -171,11 +172,11 @@ void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config);
* @param[in] num_pipes The number of pipes to incorporate in the stream.
* @param[in] pipes The pipes.
* @param[out] stream The stream.
-* @return IA_CSS_SUCCESS or the error code.
+* @return 0 or the error code.
*
* This function will create a stream with a given configuration and given pipes.
*/
-enum ia_css_err
+int
ia_css_stream_create(const struct ia_css_stream_config *stream_config,
int num_pipes,
struct ia_css_pipe *pipes[],
@@ -183,37 +184,37 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
/* @brief Destroys a stream
* @param[in] stream The stream.
- * @return IA_CSS_SUCCESS or the error code.
+ * @return 0 or the error code.
*
* This function will destroy a given stream.
*/
-enum ia_css_err
+int
ia_css_stream_destroy(struct ia_css_stream *stream);
/* @brief Provides information about a stream
* @param[in] stream The stream.
* @param[out] stream_info The information about the stream.
- * @return IA_CSS_SUCCESS or the error code.
+ * @return 0 or the error code.
*
* This function will destroy a given stream.
*/
-enum ia_css_err
+int
ia_css_stream_get_info(const struct ia_css_stream *stream,
struct ia_css_stream_info *stream_info);
/* @brief load (rebuild) a stream that was unloaded.
* @param[in] stream The stream
- * @return IA_CSS_SUCCESS or the error code
+ * @return 0 or the error code
*
* Rebuild a stream, including allocating structs, setting configuration and
* building the required pipes.
*/
-enum ia_css_err
+int
ia_css_stream_load(struct ia_css_stream *stream);
/* @brief Starts the stream.
* @param[in] stream The stream.
- * @return IA_CSS_SUCCESS or the error code.
+ * @return 0 or the error code.
*
* The dynamic data in
* the buffers are not used and need to be queued with a separate call
@@ -221,17 +222,17 @@ ia_css_stream_load(struct ia_css_stream *stream);
* NOTE: this function will only send start event to corresponding
* thread and will not start SP any more.
*/
-enum ia_css_err
+int
ia_css_stream_start(struct ia_css_stream *stream);
/* @brief Stop the stream.
* @param[in] stream The stream.
- * @return IA_CSS_SUCCESS or the error code.
+ * @return 0 or the error code.
*
* NOTE: this function will send stop event to pipes belong to this
* stream but will not terminate threads.
*/
-enum ia_css_err
+int
ia_css_stream_stop(struct ia_css_stream *stream);
/* @brief Check if a stream has stopped
@@ -245,11 +246,11 @@ ia_css_stream_has_stopped(struct ia_css_stream *stream);
/* @brief destroy a stream according to the stream seed previosly saved in the seed array.
* @param[in] stream The stream.
- * @return IA_CSS_SUCCESS (no other errors are generated now)
+ * @return 0 (no other errors are generated now)
*
* Destroy the stream and all the pipes related to it.
*/
-enum ia_css_err
+int
ia_css_stream_unload(struct ia_css_stream *stream);
/* @brief Returns stream format
@@ -278,19 +279,19 @@ ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream);
*
* This function will Set the output frame stride (at the last pipe)
*/
-enum ia_css_err
+int
ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
unsigned int output_padded_width);
/* @brief Return max number of continuous RAW frames.
* @param[in] stream The stream.
* @param[out] buffer_depth The maximum number of continuous RAW frames.
- * @return IA_CSS_SUCCESS or IA_CSS_ERR_INVALID_ARGUMENTS
+ * @return 0 or -EINVAL
*
* This function will return the maximum number of continuous RAW frames
* the system can support.
*/
-enum ia_css_err
+int
ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream,
int *buffer_depth);
@@ -298,22 +299,22 @@ ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream,
*
* @param[in] stream The stream.
* @param[in] buffer_depth Number of frames to set.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* Set the number of continuous frames to use during continuous modes.
*/
-enum ia_css_err
+int
ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth);
/* @brief Get number of continuous RAW frames to use.
* @param[in] stream The stream.
* @param[out] buffer_depth The number of frames to use
- * @return IA_CSS_SUCCESS or IA_CSS_ERR_INVALID_ARGUMENTS
+ * @return 0 or -EINVAL
*
* Get the currently set number of continuous frames
* to use during continuous modes.
*/
-enum ia_css_err
+int
ia_css_stream_get_buffer_depth(struct ia_css_stream *stream, int *buffer_depth);
/* ===== CAPTURE ===== */
@@ -338,13 +339,13 @@ ia_css_stream_get_buffer_depth(struct ia_css_stream *stream, int *buffer_depth);
* with this offset. This allows the user to
* process RAW frames that were captured in the
* past or future.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* For example, to capture the current frame plus the 2 previous
* frames and 2 subsequent frames, you would call
* ia_css_stream_capture(5, 0, -2).
*/
-enum ia_css_err
+int
ia_css_stream_capture(struct ia_css_stream *stream,
int num_captures,
unsigned int skip,
@@ -355,12 +356,12 @@ ia_css_stream_capture(struct ia_css_stream *stream,
* @param[in] stream The stream.
* @param[in] exp_id The exposure id of the raw frame to tag.
*
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* This function allows the user to tag a raw frame based on the exposure id
* found in the viewfinder frames' frame info.
*/
-enum ia_css_err
+int
ia_css_stream_capture_frame(struct ia_css_stream *stream,
unsigned int exp_id);
@@ -492,7 +493,7 @@ ia_css_stream_request_flash(struct ia_css_stream *stream);
* @param[in] config The set of filter coefficients.
* @param[in] pipe Pipe to be updated when set isp config, NULL means to
* update all pipes in the stream.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* This function configures the filter coefficients for an image
* stream. For image pipes that do not execute any ISP filters, this
@@ -501,7 +502,7 @@ ia_css_stream_request_flash(struct ia_css_stream *stream);
* in fact this is the expected behavior most of the time. Proper
* resource locking and double buffering is in place to allow for this.
*/
-enum ia_css_err
+int
ia_css_stream_set_isp_config_on_pipe(struct ia_css_stream *stream,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe);
@@ -511,7 +512,7 @@ ia_css_stream_set_isp_config_on_pipe(struct ia_css_stream *stream,
* ia_css_pipe_set_isp_config()}
* @param[in] stream The stream.
* @param[in] config The set of filter coefficients.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* This function configures the filter coefficients for an image
* stream. For image pipes that do not execute any ISP filters, this
@@ -521,7 +522,7 @@ ia_css_stream_set_isp_config_on_pipe(struct ia_css_stream *stream,
* in fact this is the expected behaviour most of the time. Proper
* resource locking and double buffering is in place to allow for this.
*/
-enum ia_css_err
+int
ia_css_stream_set_isp_config(
struct ia_css_stream *stream,
const struct ia_css_isp_config *config);
@@ -537,37 +538,37 @@ ia_css_stream_get_isp_config(const struct ia_css_stream *stream,
/* @brief allocate continuous raw frames for continuous capture
* @param[in] stream The stream.
- * @return IA_CSS_SUCCESS or error code.
+ * @return 0 or error code.
*
* because this allocation takes a long time (around 120ms per frame),
* we separate the allocation part and update part to let driver call
* this function without locking. This function is the allocation part
* and next one is update part
*/
-enum ia_css_err
+int
ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream);
/* @brief allocate continuous raw frames for continuous capture
* @param[in] stream The stream.
- * @return IA_CSS_SUCCESS or error code.
+ * @return 0 or error code.
*
* because this allocation takes a long time (around 120ms per frame),
* we separate the allocation part and update part to let driver call
* this function without locking. This function is the update part
*/
-enum ia_css_err
+int
ia_css_update_continuous_frames(struct ia_css_stream *stream);
/* @brief ia_css_unlock_raw_frame . unlock a raw frame (HALv3 Support)
* @param[in] stream The stream.
* @param[in] exp_id exposure id that uniquely identifies the locked Raw Frame Buffer
- * @return ia_css_err IA_CSS_SUCCESS or error code
+ * @return ia_css_err 0 or error code
*
* As part of HALv3 Feature requirement, SP locks raw buffer until the Application
* releases its reference to a raw buffer (which are managed by SP), this function allows
* application to explicitly unlock that buffer in SP.
*/
-enum ia_css_err
+int
ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id);
/* @brief ia_css_en_dz_capt_pipe . Enable/Disable digital zoom for capture pipe
diff --git a/drivers/staging/media/atomisp/pci/ia_css_timer.h b/drivers/staging/media/atomisp/pci/ia_css_timer.h
index a37cfa60ad35..c78fbda907a1 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_timer.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_timer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
@@ -58,10 +59,10 @@ struct ia_css_time_meas {
/* @brief API to fetch timer count directly
*
* @param curr_ts [out] measured count value
-* @return IA_CSS_SUCCESS if success
+* @return 0 if success
*
*/
-enum ia_css_err
+int
ia_css_timer_get_current_tick(
struct ia_css_clock_tick *curr_ts);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_tpg.h b/drivers/staging/media/atomisp/pci/ia_css_tpg.h
index 79c4e1b3b48f..8c744bedb0a6 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_tpg.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_tpg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_types.h b/drivers/staging/media/atomisp/pci/ia_css_types.h
index d3584756e34e..6e34d401f9df 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_types.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/*
* Support for Intel Camera Imaging ISP subsystem.
@@ -306,7 +307,6 @@ struct ia_css_shading_info {
u32 bayer_scale_ver_ratio_in;
u32 bayer_scale_ver_ratio_out;
-
/** Vertical ratio of bayer scaling
between input height and output height, for the scaling
which should be done before shading correction.
@@ -392,8 +392,7 @@ struct ia_css_grid_info {
};
/* defaults for ia_css_grid_info structs */
-#define DEFAULT_GRID_INFO \
-(struct ia_css_grid_info) { \
+#define DEFAULT_GRID_INFO { \
.dvs_grid = DEFAULT_DVS_GRID_INFO, \
.vamem_type = IA_CSS_VAMEM_TYPE_1 \
}
@@ -485,8 +484,7 @@ struct ia_css_capture_config {
};
/* default settings for ia_css_capture_config structs */
-#define DEFAULT_CAPTURE_CONFIG \
-(struct ia_css_capture_config) { \
+#define DEFAULT_CAPTURE_CONFIG { \
.mode = IA_CSS_CAPTURE_MODE_PRIMARY, \
}
diff --git a/drivers/staging/media/atomisp/pci/ia_css_version.h b/drivers/staging/media/atomisp/pci/ia_css_version.h
index 1e88901e0b82..cf1d010baceb 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_version.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_version.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -34,7 +35,7 @@
* This function generates and returns the version string. If FW is loaded, it
* attaches the FW version.
*/
-enum ia_css_err
+int
ia_css_get_version(char *version, int max_size);
#endif /* __IA_CSS_VERSION_H */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_version_data.h b/drivers/staging/media/atomisp/pci/ia_css_version_data.h
index f630fa5d55cc..428d78e1616f 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_version_data.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_version_data.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/if_defs.h b/drivers/staging/media/atomisp/pci/if_defs.h
index 7d39e45796ae..e21efa749368 100644
--- a/drivers/staging/media/atomisp/pci/if_defs.h
+++ b/drivers/staging/media/atomisp/pci/if_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/input_formatter_subsystem_defs.h b/drivers/staging/media/atomisp/pci/input_formatter_subsystem_defs.h
index 176456da961f..594fc36a01c7 100644
--- a/drivers/staging/media/atomisp/pci/input_formatter_subsystem_defs.h
+++ b/drivers/staging/media/atomisp/pci/input_formatter_subsystem_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/input_selector_defs.h b/drivers/staging/media/atomisp/pci/input_selector_defs.h
index 1dd8ea3cd6d4..61882e4cb813 100644
--- a/drivers/staging/media/atomisp/pci/input_selector_defs.h
+++ b/drivers/staging/media/atomisp/pci/input_selector_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/input_switch_2400_defs.h b/drivers/staging/media/atomisp/pci/input_switch_2400_defs.h
index 2d5baae30522..8ea1d7991d38 100644
--- a/drivers/staging/media/atomisp/pci/input_switch_2400_defs.h
+++ b/drivers/staging/media/atomisp/pci/input_switch_2400_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/input_system_ctrl_defs.h b/drivers/staging/media/atomisp/pci/input_system_ctrl_defs.h
index fcfa8c4971be..c801ddd71192 100644
--- a/drivers/staging/media/atomisp/pci/input_system_ctrl_defs.h
+++ b/drivers/staging/media/atomisp/pci/input_system_ctrl_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/input_system_defs.h b/drivers/staging/media/atomisp/pci/input_system_defs.h
index ae62163034a6..0c6a74b1891f 100644
--- a/drivers/staging/media/atomisp/pci/input_system_defs.h
+++ b/drivers/staging/media/atomisp/pci/input_system_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/input_system_global.h b/drivers/staging/media/atomisp/pci/input_system_global.h
index e75c2f29042d..5ac580ce64ed 100644
--- a/drivers/staging/media/atomisp/pci/input_system_global.h
+++ b/drivers/staging/media/atomisp/pci/input_system_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
diff --git a/drivers/staging/media/atomisp/pci/input_system_local.h b/drivers/staging/media/atomisp/pci/input_system_local.h
index 8533a1e017e4..b33aa2838290 100644
--- a/drivers/staging/media/atomisp/pci/input_system_local.h
+++ b/drivers/staging/media/atomisp/pci/input_system_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
diff --git a/drivers/staging/media/atomisp/pci/input_system_private.h b/drivers/staging/media/atomisp/pci/input_system_private.h
index 69c63a79a30c..889f204e77d5 100644
--- a/drivers/staging/media/atomisp/pci/input_system_private.h
+++ b/drivers/staging/media/atomisp/pci/input_system_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
diff --git a/drivers/staging/media/atomisp/pci/input_system_public.h b/drivers/staging/media/atomisp/pci/input_system_public.h
index 17682c86bceb..3f5167fd6643 100644
--- a/drivers/staging/media/atomisp/pci/input_system_public.h
+++ b/drivers/staging/media/atomisp/pci/input_system_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
diff --git a/drivers/staging/media/atomisp/pci/irq_controller_defs.h b/drivers/staging/media/atomisp/pci/irq_controller_defs.h
index efb3d7e135bd..e49e61e17ee7 100644
--- a/drivers/staging/media/atomisp/pci/irq_controller_defs.h
+++ b/drivers/staging/media/atomisp/pci/irq_controller_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hrt/hive_isp_css_irq_types_hrt.h b/drivers/staging/media/atomisp/pci/irq_types_hrt.h
index 5c636effba48..4212bb01c8d8 100644
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hrt/hive_isp_css_irq_types_hrt.h
+++ b/drivers/staging/media/atomisp/pci/irq_types_hrt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.c
index 9cdfe50b2835..daf2f25c1ed6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.h
index 71587d85ff2d..3abc125debd0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_param.h
index 3c699bae2f55..4f8bb4de4edc 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_types.h
index cc6a444ac716..900ba8f5e30c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/aa/aa_2/ia_css_aa2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.c
index c190483dc2b3..3f079c954c1f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.h
index 3855f54765e3..a4720c4a948a 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_param.h
index 6bf834cb47d9..37dcb013b76d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h
index d3fa0193ae07..be3534e46c15 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.c
index feee073b5099..9cdefedc6312 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.h
index e99108682f5d..2b3ab01c279d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_param.h
index 47a0fb08cfcc..4b83b8100160 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -21,7 +22,7 @@
/* Advanced Noise Reduction (ANR) thresholds */
struct ia_css_isp_anr2_params {
- VMEM_ARRAY(data, ANR_PARAM_SIZE *ISP_VEC_NELEMS);
+ VMEM_ARRAY(data, ANR_PARAM_SIZE * ISP_VEC_NELEMS);
};
#endif /* __IA_CSS_ANR2_PARAM_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.c
index 070e90e3e2b5..649283bd44f2 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.h
index 534119e064c1..9e383e030ac4 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_types.h
index 200df3829fc7..e12aae819dce 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_2/ia_css_anr2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
index 6c7aa51ec079..82aa69b74677 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -14,7 +15,6 @@
#if !defined(HAS_NO_HMEM)
-#include "memory_access.h"
#include "ia_css_types.h"
#include "sh_css_internal.h"
#include "assert_support.h"
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.h
index ccd83169fe22..736b6e3f9512 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_param.h
index 692a855ba012..05d5c43e6b16 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_types.h
index 8b2a53a26b75..4c0e92f13d6c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.c
index 6888a7363710..45e37dc4f1e3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -42,7 +43,7 @@ static const s32 div_lut_intercepts[BNLM_DIV_LUT_SIZE] = {
*/
static inline void
bnlm_lut_encode(struct bnlm_lut *lut, const int32_t *lut_thr,
- const int32_t *lut_val, const uint32_t lut_size)
+ const s32 *lut_val, const uint32_t lut_size)
{
u32 blk, i;
const u32 block_size = 16;
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.h
index a57933bfb974..3632bf27cc21 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_param.h
index c7d5cadf5fd4..30672db269df 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_types.h
index 8dd1b1766c64..407b5a3b0fcd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnlm/ia_css_bnlm_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.c
index a5e20596539d..c42fcb1d9100 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.h
index a021733dcdf7..f6ab5d2bb218 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_param.h
index 698fdc0b13fa..087723795476 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_types.h
index ee9569891747..5f3dfa59f950 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr2_2/ia_css_bnr2_2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.c
index 5efb0ce7f323..457a004e194d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.h
index 4c29b47b8177..7fc2a728a6c2 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr_param.h
index 52f21ce8f4d2..4f6469315386 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.c
index c50afa6bf8a6..0eb40517e08c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.h
index 87250ca5842c..4d046b730f06 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr_param.h
index c1af207cbf9a..971ab87af2c5 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_1.0/ia_css_cnr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.c
index 610871d213bb..495dc1f33ca6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.h
index d322359feedf..38f848137eda 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_param.h
index 0d2fb2897720..3709aa4d3652 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_types.h
index 35fc2e77eb3d..d0a25616727c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/cnr/cnr_2/ia_css_cnr2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.c
index e64e26089a4d..ff452e2cc23a 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.h
index c136d5e03511..520623e27349 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_param.h
index 3a6ede394bdc..fcbec189eff8 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h
index 79a626fe3a29..34152d6d09be 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c
index 6e29b7eeb3ed..5d34f3256a43 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h
index 6f42abdec9bb..615cb6771884 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output_param.h
index 587d0c62c936..56daa1d96747 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c
index c6a3bd4fbf80..38912062edd4 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h
index 2e451a872d2a..21a259d33256 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_param.h
index 35835929d252..7416e74dd782 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_types.h
index 5c166be6c5e8..aaaae5e2abb9 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.c
index ea81e1d3e445..284c17970e55 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.h
index 347ccd864577..6b0256a73e52 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_param.h
index 53e270df2db7..3809ef73e490 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_types.h
index d49203d322bd..160f19bdfca0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/csc/csc_1.0/ia_css_csc_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.c
index e80f42ab0e6a..149adbc57730 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.h
index f3c40a49f7c0..8c17e7b921b5 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5_param.h
index 95cf34ef4ed2..c18cfc930db6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc1_5/ia_css_ctc1_5_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.c
index b247dc6bec6a..e3d3f1253422 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.h
index 3733aee24dcd..eb10c3884020 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_param.h
index 224bdb199942..94844da665e5 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_types.h
index 9d5dadf70f1a..f9f329a58737 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.c
index 26311b0a23f9..82f2adbbfac3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.h
index e4ad676361dd..57d1d08e1bc8 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_param.h
index 6e541a0ebaa9..7e2fa192a0fe 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.c
index adb146c03a73..f13b79586963 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,8 +13,9 @@
* more details.
*/
+#include <linux/string.h> /* for memcpy() */
+
#include <type_support.h>
-#include <string_support.h> /* memcpy */
#include "system_global.h"
#include "vamem.h"
#include "ia_css_types.h"
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.h
index a350dec8b4ad..33e8a05455a3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_types.h
index f6f5ec28827f..b2d42f3c1f4d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc_1.0/ia_css_ctc_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.c
index 8e4218cb70cd..25e3f0822fb8 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.h
index baae1d9809da..cb91062029cf 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_param.h
index c85a57e194cc..2070ce040470 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_types.h
index a4b446904570..daac1275c129 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.c
index ade23d53f6bb..f90da39296ec 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.h
index f3749e514505..294f619a3b15 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_param.h
index 868dfaaf78c7..4c9d5c630cb0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_types.h
index 24700d256bfd..372cd9d2b803 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/de/de_2/ia_css_de2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.c
index 9fb37447831c..eff428c67c86 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.h
index 009541fafda0..e5f5a2716010 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_param.h
index 8567a620696a..e0e7f2d48237 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_types.h
index e96f83e5d47c..c1666ebf1d3b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dp/dp_1.0/ia_css_dp_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.c
index 4dfad4ace20b..f6fe064bdda4 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.h
index a31ef0e5047b..f6e019a65208 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h
index 6df06fb249aa..1ccceadbb7bf 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_types.h
index f78451be8d6a..f742a8dc1d67 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c
index d2c3e8edf626..b8b71791466f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,6 +13,8 @@
* more details.
*/
+#include "hmm.h"
+
#include "ia_css_frame_public.h"
#define IA_CSS_INCLUDE_CONFIGURATIONS
#include "ia_css_isp_configs.h"
@@ -22,7 +25,6 @@
#include "sh_css_params.h"
#include "ia_css_binary.h"
#include "ia_css_debug.h"
-#include "memory_access.h"
#include "assert_support.h"
#include "ia_css_dvs.host.h"
@@ -270,12 +272,12 @@ convert_allocate_dvs_6axis_config(
return me;
}
-enum ia_css_err
+int
store_dvs_6axis_config(
const struct ia_css_dvs_6axis_config *dvs_6axis_config,
const struct ia_css_binary *binary,
const struct ia_css_frame_info *dvs_in_frame_info,
- hrt_vaddress ddr_addr_y) {
+ ia_css_ptr ddr_addr_y) {
struct ia_css_host_data *me;
assert(dvs_6axis_config);
@@ -288,8 +290,8 @@ store_dvs_6axis_config(
if (!me)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
ia_css_params_store_ia_css_host_data(
@@ -297,5 +299,5 @@ store_dvs_6axis_config(
me);
ia_css_host_data_free(me);
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h
index d711170cf7cc..f9bc17ee0f86 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -50,11 +51,11 @@ convert_allocate_dvs_6axis_config(
const struct ia_css_binary *binary,
const struct ia_css_frame_info *dvs_in_frame_info);
-enum ia_css_err
+int
store_dvs_6axis_config(
const struct ia_css_dvs_6axis_config *dvs_6axis_config,
const struct ia_css_binary *binary,
const struct ia_css_frame_info *dvs_in_frame_info,
- hrt_vaddress ddr_addr_y);
+ ia_css_ptr ddr_addr_y);
#endif /* __IA_CSS_DVS_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_param.h
index f8842dae943b..2963bb10b129 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_types.h
index a1a14d93ef29..e99ff0ce8bab 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.c
index 03e1998b0464..bfea78171f7c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.h
index 05f817125d3c..f1ad07e78b3a 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h
index 880454d4dcf5..6fb3b38f49e7 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h
index b8fdb7a51a12..836e348c184f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.c
index 0b96b9618ab6..bae1ca2cd505 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.h
index 0aac424d9d54..540423d85e9d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_param.h
index 8f36af1a5ae6..5275a1dadefa 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_types.h
index 7cfebaf05dc2..16b6a3ddcd08 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fc/fc_1.0/ia_css_formats_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h
index adfd4b37171c..6cd635f3ee27 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_types.h
index 6485834704da..3a55d4c698e6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
index 7b55dfea359a..47b5c7956fbd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h
index 02e85570bd1c..12187d213d90 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_param.h
index f103ddd882fd..b21415743705 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_types.h
index 95552a0e3c45..14dc5e183184 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.c
index 1a489c93eb97..7f3f87920dc7 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.h
index 2fb2927b07f1..c2dc1574a3da 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_param.h
index beeba6c9be6a..a81233add437 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.c
index 15cf0575aac5..f48f876777dc 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,8 +13,9 @@
* more details.
*/
+#include <linux/string.h> /* for memcpy() */
+
#include <type_support.h>
-#include <string_support.h> /* memcpy */
#include "system_global.h"
#include "vamem.h"
#include "ia_css_types.h"
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.h
index 9686623d9cdd..ee6fa07b3511 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_types.h
index c896c138b569..ccd3d91a24d3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_1.0/ia_css_gc_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.c
index 29a1e013a9aa..76209b7c14cb 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.h
index ca7d54576471..eabf78737bfc 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_param.h
index 458c72a45eef..af456e75e476 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.c
index d2fe0052fb00..7eadb31268eb 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,8 +13,9 @@
* more details.
*/
+#include <linux/string.h> /* for memcpy() */
+
#include <type_support.h>
-#include <string_support.h> /* memcpy */
#include "system_global.h"
#include "vamem.h"
#include "ia_css_types.h"
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.h
index 8686e6e3586c..13049fbfab84 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_types.h
index 30780394ed7f..ae16409d84a5 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/gc/gc_2/ia_css_gc2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c
index 643b7d9095e6..698550cc2fcc 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/* Release Version: irci_ecr-master_20150911_0724 */
/*
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h
index ecc8bea3542b..04599ab590cd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/* Release Version: irci_ecr-master_20150911_0724 */
/*
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h
index 47651cdf94b7..97a89fd3cfda 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/* Release Version: irci_ecr-master_20150911_0724 */
/*
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
index 7c2f8f213bef..1b4090880201 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
/* Release Version: irci_ecr-master_20150911_0724 */
/*
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
index bf71a7f661e6..ea8055148fb3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h
index f9db75a089af..635ccb1b27d0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_param.h
index 77cfed002e14..283ace8385b0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_types.h
index 59b58f30af11..d06d25c9b81c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h
index 22aedcc4470f..5e0e4cd5bfba 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h
index e49bd95f77da..0801481c4b49 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
index ba490c5fc18e..f8bd207b28e1 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
index 556e53e05607..e7cfd380e108 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h
index 1cc2aff57ef3..9b7537d508ad 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h
index 990299a0d2c7..137a2a05c65b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c
index 49c1b3e3370d..6d8a35a73750 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -37,7 +38,7 @@ ia_css_iterator_config(
ia_css_resolution_to_sp_resolution(&to->dvs_envelope, from->dvs_envelope);
}
-enum ia_css_err
+int
ia_css_iterator_configure(
const struct ia_css_binary *binary,
const struct ia_css_frame_info *in_info) {
@@ -76,5 +77,5 @@ ia_css_iterator_configure(
ia_css_configure_iterator(binary, &config);
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.h
index c5e8d58e0fe1..1419fa9a07f0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -26,7 +27,7 @@ ia_css_iterator_config(
const struct ia_css_iterator_configuration *from,
unsigned int size);
-enum ia_css_err
+int
ia_css_iterator_configure(
const struct ia_css_binary *binary,
const struct ia_css_frame_info *in_info);
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator_param.h
index d308126e41d3..e062f8d06128 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.c
index 7a6abe0c5b7d..562662ab8a44 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.h
index ae9ede2b685a..6c1189e1d263 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_param.h
index 497ad89ab728..66b8fb259218 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -25,7 +26,7 @@ struct sh_css_isp_macc1_5_params {
};
struct sh_css_isp_macc1_5_vmem_params {
- VMEM_ARRAY(data, IA_CSS_MACC_NUM_COEFS *ISP_NWAY);
+ VMEM_ARRAY(data, IA_CSS_MACC_NUM_COEFS * ISP_NWAY);
};
#endif /* __IA_CSS_MACC1_5_PARAM_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.c
index c094f3df10aa..d205d64e0b94 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.h
index 10a50aa82be8..d451efbaa184 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_types.h
index 9aa352cbcffc..5492af0dfa9f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.c
index 0b1d1bf5e8a0..f2d3832a0039 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.h
index 0e13e9cb0547..912db92540e6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_param.h
index 3b4e440c3c30..71665204e4dd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c
index f9a430da54b8..946b074e8288 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.h
index 96d62c9912b8..35099cb79d6a 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_types.h
index 093302f08bca..172a518cb935 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.c
index 102dc6feb6d1..69283b631da7 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.h
index 42b5143ef78f..3987abcae85c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm_param.h
index d432e2e39df6..06c39fdfc9e3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/norm/norm_1.0/ia_css_norm_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.c
index f7403ce16c99..c4ffff630b64 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.h
index 936f6a08a174..26c2e43202dc 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_param.h
index c728f8791ef4..c3c9fc3f9064 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_types.h
index 0ccc09f6eb0f..51e4c35cf659 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob2/ia_css_ob2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.c
index 6367d94275fb..12191cd36d5c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.h
index d767c5856880..dfcac0c64040 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_param.h
index f5c3e14a1a8a..991aa3c4051b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_types.h
index 317b24e240d8..b74296517b03 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ob/ob_1.0/ia_css_ob_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c
index df4cb9c362a4..c8e074f42353 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h
index 3d8f61c225cf..1f5a2242640e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_param.h
index 3a63eee58cb6..df125674bb35 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_types.h
index 3248bc3fd6c3..e5f9c05d2120 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c
index 3de108b56005..1603fd44ece3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h
index ad6d7ca783e4..8d940959f40a 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_param.h
index 87898d2df2de..9ae290450865 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_types.h
index b7ecd8f40c1c..549f1a36bb7e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c
index 1a85f20770c1..1c6f6792d57b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h
index 36a4079aa24a..346928435a8b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_param.h
index a1a314272a77..c4b5f719a336 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_types.h
index 7838f59a2986..1ccaa3c48407 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
index 2045b974ec8a..29c707ecf9f3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -14,7 +15,6 @@
#if !defined(HAS_NO_HMEM)
-#include "memory_access.h"
#include "ia_css_types.h"
#include "sh_css_internal.h"
#include "sh_css_frac.h"
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.h
index d4df1dc540a0..4c2b3de7281e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c
index c3f43fd327d4..061558fbe329 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -29,10 +30,15 @@ ia_css_ref_config(
{
unsigned int elems_a = ISP_VEC_NELEMS, i;
- (void)size;
- ia_css_dma_configure_from_info(&to->port_b, &from->ref_frames[0]->info);
- to->width_a_over_b = elems_a / to->port_b.elems;
- to->dvs_frame_delay = from->dvs_frame_delay;
+ if (from->ref_frames[0]) {
+ ia_css_dma_configure_from_info(&to->port_b, &from->ref_frames[0]->info);
+ to->width_a_over_b = elems_a / to->port_b.elems;
+ to->dvs_frame_delay = from->dvs_frame_delay;
+ } else {
+ to->width_a_over_b = 1;
+ to->dvs_frame_delay = 0;
+ to->port_b.elems = elems_a;
+ }
for (i = 0; i < MAX_NUM_VIDEO_DELAY_FRAMES; i++) {
if (from->ref_frames[i]) {
to->ref_frame_addr_y[i] = from->ref_frames[i]->data +
@@ -52,7 +58,7 @@ ia_css_ref_config(
void
ia_css_ref_configure(
const struct ia_css_binary *binary,
- const struct ia_css_frame **ref_frames,
+ const struct ia_css_frame * const *ref_frames,
const uint32_t dvs_frame_delay)
{
struct ia_css_ref_configuration config;
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h
index 4f48a8cfc604..3ce590b436a1 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -31,7 +32,7 @@ ia_css_ref_config(
void
ia_css_ref_configure(
const struct ia_css_binary *binary,
- const struct ia_css_frame **ref_frames,
+ const struct ia_css_frame * const *ref_frames,
const uint32_t dvs_frame_delay);
void
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_param.h
index 0a0498c17fba..c727e27a8e14 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -28,8 +29,8 @@ struct ia_css_ref_configuration {
struct sh_css_isp_ref_isp_config {
u32 width_a_over_b;
struct dma_port_config port_b;
- hrt_vaddress ref_frame_addr_y[MAX_NUM_VIDEO_DELAY_FRAMES];
- hrt_vaddress ref_frame_addr_c[MAX_NUM_VIDEO_DELAY_FRAMES];
+ ia_css_ptr ref_frame_addr_y[MAX_NUM_VIDEO_DELAY_FRAMES];
+ ia_css_ptr ref_frame_addr_c[MAX_NUM_VIDEO_DELAY_FRAMES];
u32 dvs_frame_delay;
};
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_state.h b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_state.h
index 1d30ccc2c638..d4f7a66763eb 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_state.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_state.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_types.h
index 156d6cd8cf3a..07d040bcf281 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
index d093565d9eb8..ba52c80df4a5 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h
index 13d19dab1f1d..f9926e297568 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_param.h
index 041101767ff2..9cb75b220678 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h
index 5a5b277ca0eb..f369e9b95ca8 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c
index 43954ed6d106..f3fb4b9b3c82 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h
index efbe40b399dd..f1eb568f23d4 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h
index 38a625821987..fab11d3350fd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h
index 41f3ee7158ff..aae534521b7b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common.host.h
index c03936fb0550..7b661e49b4d0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -76,12 +77,12 @@ struct sh_css_isp_sdis_vert_proj_tbl {
struct sh_css_isp_sdis_hori_coef_tbl {
VMEM_ARRAY(tbl[ISP_DVS_NUM_COEF_TYPES],
- ISP_MAX_SDIS_HOR_COEF_NUM_VECS *ISP_NWAY);
+ ISP_MAX_SDIS_HOR_COEF_NUM_VECS * ISP_NWAY);
};
struct sh_css_isp_sdis_vert_coef_tbl {
VMEM_ARRAY(tbl[ISP_DVS_NUM_COEF_TYPES],
- ISP_MAX_SDIS_VER_COEF_NUM_VECS *ISP_NWAY);
+ ISP_MAX_SDIS_VER_COEF_NUM_VECS * ISP_NWAY);
};
#endif /* defined(__ISP) || defined (MK_FIRMWARE) */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common_types.h
index e257841bba67..c2ec30b4abd4 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/common/ia_css_sdis_common_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -196,12 +197,11 @@ struct ia_css_dvs_stat_grid_info {
/* DVS statistics generated by accelerator default grid info
*/
-#define DEFAULT_DVS_GRID_INFO \
-(union ia_css_dvs_grid_u) { \
- .dvs_stat_grid_info = (struct ia_css_dvs_stat_grid_info) { \
+#define DEFAULT_DVS_GRID_INFO { \
+ .dvs_stat_grid_info = { \
.fe_roi_cfg = { \
- [1] = (struct dvs_stat_public_dvs_level_fe_roi_cfg) { \
- .x_start = 4 \
+ [1] = { \
+ .x_start = 4 \
} \
} \
} \
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c
index 418481e016f7..3e72dabe7ef6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,7 +13,8 @@
* more details.
*/
-#include "memory_access.h"
+#include "hmm.h"
+
#include "assert_support.h"
#include "ia_css_debug.h"
#include "ia_css_sdis_types.h"
@@ -234,12 +236,12 @@ void ia_css_sdis_clear_coefficients(
dvs_coefs->ver_coefs = NULL;
}
-enum ia_css_err
+int
ia_css_get_dvs_statistics(
struct ia_css_dvs_statistics *host_stats,
const struct ia_css_isp_dvs_statistics *isp_stats) {
struct ia_css_isp_dvs_statistics_map *map;
- enum ia_css_err ret = IA_CSS_SUCCESS;
+ int ret = 0;
IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats);
@@ -249,13 +251,13 @@ ia_css_get_dvs_statistics(
map = ia_css_isp_dvs_statistics_map_allocate(isp_stats, NULL);
if (map)
{
- mmgr_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
+ hmm_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
ia_css_translate_dvs_statistics(host_stats, map);
ia_css_isp_dvs_statistics_map_free(map);
} else
{
IA_CSS_ERROR("out of memory");
- ret = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ ret = -ENOMEM;
}
IA_CSS_LEAVE_ERR(ret);
@@ -317,7 +319,7 @@ ia_css_isp_dvs_statistics_allocate(
if (!grid->enable)
return NULL;
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
@@ -329,7 +331,7 @@ ia_css_isp_dvs_statistics_allocate(
HIVE_ISP_DDR_WORD_BYTES);
me->size = hor_size + ver_size;
- me->data_ptr = mmgr_malloc(me->size);
+ me->data_ptr = hmm_alloc(me->size, HMM_BO_PRIVATE, 0, NULL, 0);
if (me->data_ptr == mmgr_NULL)
goto err;
me->hor_size = hor_size;
@@ -358,7 +360,7 @@ ia_css_isp_dvs_statistics_map_allocate(
* so we use a local char * instead. */
char *base_ptr;
- me = sh_css_malloc(sizeof(*me));
+ me = kvmalloc(sizeof(*me), GFP_KERNEL);
if (!me) {
IA_CSS_LOG("cannot allocate memory");
goto err;
@@ -368,7 +370,7 @@ ia_css_isp_dvs_statistics_map_allocate(
me->data_allocated = !data_ptr;
if (!me->data_ptr) {
- me->data_ptr = sh_css_malloc(isp_stats->size);
+ me->data_ptr = kvmalloc(isp_stats->size, GFP_KERNEL);
if (!me->data_ptr) {
IA_CSS_LOG("cannot allocate memory");
goto err;
@@ -385,7 +387,7 @@ ia_css_isp_dvs_statistics_map_allocate(
return me;
err:
if (me)
- sh_css_free(me);
+ kvfree(me);
return NULL;
}
@@ -394,8 +396,8 @@ ia_css_isp_dvs_statistics_map_free(struct ia_css_isp_dvs_statistics_map *me)
{
if (me) {
if (me->data_allocated)
- sh_css_free(me->data_ptr);
- sh_css_free(me);
+ kvfree(me->data_ptr);
+ kvfree(me);
}
}
@@ -404,7 +406,7 @@ ia_css_isp_dvs_statistics_free(struct ia_css_isp_dvs_statistics *me)
{
if (me) {
hmm_free(me->data_ptr);
- sh_css_free(me);
+ kvfree(me);
}
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.h
index b1b0cb8ea175..0d0ed96e08fe 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -53,7 +54,7 @@ void ia_css_get_isp_dis_coefficients(
short *horizontal_coefficients,
short *vertical_coefficients);
-enum ia_css_err
+int
ia_css_get_dvs_statistics(
struct ia_css_dvs_statistics *host_stats,
const struct ia_css_isp_dvs_statistics *isp_stats);
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis_types.h
index 5542fa5555b4..a8f2b8afcfd6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c
index 20fa7d924d58..7922198f6784 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,8 +13,9 @@
* more details.
*/
+#include "hmm.h"
+
#include <assert_support.h>
-#include "memory_access.h"
#include "ia_css_debug.h"
#include "ia_css_sdis2.host.h"
@@ -174,12 +176,12 @@ void ia_css_sdis2_clear_coefficients(
dvs2_coefs->ver_coefs.even_imag = NULL;
}
-enum ia_css_err
+int
ia_css_get_dvs2_statistics(
struct ia_css_dvs2_statistics *host_stats,
const struct ia_css_isp_dvs_statistics *isp_stats) {
struct ia_css_isp_dvs_statistics_map *map;
- enum ia_css_err ret = IA_CSS_SUCCESS;
+ int ret = 0;
IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats);
@@ -189,13 +191,13 @@ ia_css_get_dvs2_statistics(
map = ia_css_isp_dvs_statistics_map_allocate(isp_stats, NULL);
if (map)
{
- mmgr_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
+ hmm_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
ia_css_translate_dvs2_statistics(host_stats, map);
ia_css_isp_dvs_statistics_map_free(map);
} else
{
IA_CSS_ERROR("out of memory");
- ret = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ ret = -ENOMEM;
}
IA_CSS_LEAVE_ERR(ret);
@@ -284,7 +286,7 @@ ia_css_isp_dvs2_statistics_allocate(
if (!grid->enable)
return NULL;
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
@@ -295,7 +297,7 @@ ia_css_isp_dvs2_statistics_allocate(
* grid->aligned_height * IA_CSS_DVS2_NUM_COEF_TYPES;
me->size = 2 * size;
- me->data_ptr = mmgr_malloc(me->size);
+ me->data_ptr = hmm_alloc(me->size, HMM_BO_PRIVATE, 0, NULL, 0);
if (me->data_ptr == mmgr_NULL)
goto err;
me->hor_proj = me->data_ptr;
@@ -317,7 +319,7 @@ ia_css_isp_dvs2_statistics_free(struct ia_css_isp_dvs_statistics *me)
{
if (me) {
hmm_free(me->data_ptr);
- sh_css_free(me);
+ kvfree(me);
}
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.h
index a966a6bcb692..e0e6b9c338ad 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -62,7 +63,7 @@ void ia_css_get_isp_dvs2_coefficients(
void ia_css_sdis2_clear_coefficients(
struct ia_css_dvs2_coefficients *dvs2_coefs);
-enum ia_css_err
+int
ia_css_get_dvs2_statistics(
struct ia_css_dvs2_statistics *host_stats,
const struct ia_css_isp_dvs_statistics *isp_stats);
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h
index e8ae135bfd6a..d75b72e9551b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.c
index 69921c27bfae..fef8c5457cda 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.h
index bc6e1653e354..7e44d78c5d5d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_param.h
index a93891448cde..e904f7122142 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_types.h
index e4263afee7da..0f69f9128f0e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tdf/tdf_1.0/ia_css_tdf_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h
index 349f0800bbe6..4b53fddfcd2d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c
index ecbd3042951a..ac80e6c6e67e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -95,7 +96,7 @@ ia_css_tnr_config(
void
ia_css_tnr_configure(
const struct ia_css_binary *binary,
- const struct ia_css_frame **frames)
+ const struct ia_css_frame * const *frames)
{
struct ia_css_tnr_configuration config;
unsigned int i;
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h
index 3dbf962089d0..90d6e6b44a8d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -47,7 +48,7 @@ ia_css_tnr_config(
void
ia_css_tnr_configure(
const struct ia_css_binary *binary,
- const struct ia_css_frame **frames);
+ const struct ia_css_frame * const *frames);
void
ia_css_init_tnr_state(
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h
index 1973766d8e41..60a2542cf685 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -34,7 +35,7 @@ struct sh_css_isp_tnr_isp_config {
u32 width_a_over_b;
u32 frame_height;
struct dma_port_config port_b;
- hrt_vaddress tnr_frame_addr[NUM_TNR_FRAMES];
+ ia_css_ptr tnr_frame_addr[NUM_TNR_FRAMES];
};
#endif /* __IA_CSS_TNR_PARAM_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_state.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_state.h
index 901aa1e298e0..d57238423947 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_state.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_state.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_types.h
index 98b0daeeab39..92dbe13895c6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/uds/uds_1.0/ia_css_uds_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/uds/uds_1.0/ia_css_uds_param.h
index 26b7b5bc9391..784b5c4facd2 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/uds/uds_1.0/ia_css_uds_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/uds/uds_1.0/ia_css_uds_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c
index be274d680caf..358cb7d2cd4c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -49,7 +50,7 @@ ia_css_vf_config(
* to the requested viewfinder resolution on the upper side. The output cannot
* be smaller than the requested viewfinder resolution.
*/
-enum ia_css_err
+int
sh_css_vf_downscale_log2(
const struct ia_css_frame_info *out_info,
const struct ia_css_frame_info *vf_info,
@@ -58,12 +59,12 @@ sh_css_vf_downscale_log2(
unsigned int out_width;
if ((!out_info) | (!vf_info))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
out_width = out_info->res.width;
if (out_width == 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* downscale until width smaller than the viewfinder width. We don't
* test for the height since the vmem buffers only put restrictions on
@@ -79,26 +80,26 @@ sh_css_vf_downscale_log2(
ds_log2--;
/* TODO: use actual max input resolution of vf_pp binary */
if ((out_info->res.width >> ds_log2) >= 2 * ia_css_binary_max_vf_width())
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
*downscale_log2 = ds_log2;
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
configure_kernel(
const struct ia_css_binary_info *info,
const struct ia_css_frame_info *out_info,
const struct ia_css_frame_info *vf_info,
unsigned int *downscale_log2,
struct ia_css_vf_configuration *config) {
- enum ia_css_err err;
+ int err;
unsigned int vf_log_ds = 0;
/* First compute value */
if (vf_info)
{
err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
vf_log_ds = min(vf_log_ds, info->vf_dec.max_log_downscale);
@@ -106,7 +107,7 @@ configure_kernel(
/* Then store it in isp config section */
config->vf_downscale_bits = vf_log_ds;
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -117,13 +118,13 @@ configure_dma(
config->info = vf_info;
}
-enum ia_css_err
+int
ia_css_vf_configure(
const struct ia_css_binary *binary,
const struct ia_css_frame_info *out_info,
struct ia_css_frame_info *vf_info,
unsigned int *downscale_log2) {
- enum ia_css_err err;
+ int err;
struct ia_css_vf_configuration config;
const struct ia_css_binary_info *info = &binary->info->sp;
@@ -134,5 +135,5 @@ ia_css_vf_configure(
vf_info->raw_bit_depth = info->dma.vfdec_bits_per_pixel;
ia_css_configure_vf(binary, &config);
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h
index 9cc594f9a840..0e8de034a00e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -25,7 +26,7 @@
* to the requested viewfinder resolution on the upper side. The output cannot
* be smaller than the requested viewfinder resolution.
*/
-enum ia_css_err
+int
sh_css_vf_downscale_log2(
const struct ia_css_frame_info *out_info,
const struct ia_css_frame_info *vf_info,
@@ -37,7 +38,7 @@ ia_css_vf_config(
const struct ia_css_vf_configuration *from,
unsigned int size);
-enum ia_css_err
+int
ia_css_vf_configure(
const struct ia_css_binary *binary,
const struct ia_css_frame_info *out_info,
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_param.h
index 171a98508a88..487ddf163324 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_types.h
index a4d39e2e9d8e..24fbb61d349c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.c
index d07c500eb542..01d1a2d361c3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.h
index 545dea39c2e0..ffd75c8a64fb 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_param.h
index dcf548da55cc..51b2ba8efc18 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_types.h
index 59cbd71ef332..20ae73c0ef8c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/wb/wb_1.0/ia_css_wb_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.c
index e04c604ba612..1cd59660857f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.h
index 31833b78739f..686101c0b6a9 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_param.h
index 72a5c5fd10e7..7ebf139f3618 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.c
index 78653b2666a4..5566f3c16aac 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,8 +13,9 @@
* more details.
*/
+#include <linux/string.h> /* for memcpy() */
+
#include <type_support.h>
-#include <string_support.h> /* memcpy */
#include "system_global.h"
#include "vamem.h"
#include "ia_css_types.h"
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.h
index 130086713a7f..2f4ab8ad402b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_table.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_types.h
index 22189c936f64..9a4d2e470524 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_1.0/ia_css_xnr_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.c
index a9db6366d20b..9c9d9b9a453e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -126,7 +127,7 @@ compute_blending(int strength)
* exactly as s0.11 fixed point, but -1.0 can.
*/
isp_strength = -(((strength * isp_scale) + offset) / host_scale);
- return MAX(MIN(isp_strength, 0), -XNR_BLENDING_SCALE_FACTOR);
+ return MAX(MIN(isp_strength, 0), -isp_scale);
}
void
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.h
index 959533ec29c6..6b57990b72da 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_param.h
index 7d108669e19a..c728db7ce917 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h
index 6963bef3c07d..4447ba31ad69 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.c
index a1d0e915636d..048ffbc90b8e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.h
index 20165093a298..049706e1ffa9 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_param.h
index 8f104bcb4d0f..8d9069ec28a1 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_types.h
index 1a62e1dbfc6f..da1ba21a0726 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.c
index 9a3cd59c4507..08e9d72c143f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.h
index 38204f8c5735..eaf253d59c4d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2.host.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_param.h
index 7479bce598d5..96c80b3af426 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_types.h
index 36e4bb61b38c..ab77f4e85319 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_2/ia_css_ynr2_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h
index 5774c905d8e1..f86cf9bf13a5 100644
--- a/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h
+++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h
index fc392c7fb18b..11e439d838ae 100644
--- a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h
+++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h
index 6bdf8451e7d4..ae273c826808 100644
--- a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h
index 759141c9310a..b4142bdde51b 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h
index 3c0e2efb08ae..33ebf89ca053 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -20,15 +21,15 @@
#include "input_system_global.h"
#include "input_system_defs.h" /* HIVE_ISYS_GPREG_MULTICAST_A_IDX,... */
-#include "css_receiver_2400_defs.h" /* _HRT_CSS_RECEIVER_2400_TWO_PIXEL_EN_REG_IDX, _HRT_CSS_RECEIVER_2400_CSI2_FUNC_PROG_REG_IDX,... */
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM)
-#include "isp_capture_defs.h"
-#elif defined(IS_ISP_2401_MAMOIADA_SYSTEM)
-/* Same name, but keep the distinction,it is a different device */
+
+/*
+ * _HRT_CSS_RECEIVER_2400_TWO_PIXEL_EN_REG_IDX,
+ * _HRT_CSS_RECEIVER_2400_CSI2_FUNC_PROG_REG_IDX,...
+ */
+#include "css_receiver_2400_defs.h"
+
#include "isp_capture_defs.h"
-#else
-#error "input_system_local.h: 2400_SYSTEM must be one of {2400, 2401 }"
-#endif
+
#include "isp_acquisition_defs.h"
#include "input_system_ctrl_defs.h"
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_private.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_private.h
index 0ce9cbc0063e..9c39ca2da923 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_private.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h
index d0de27abb95a..689e451f1ce2 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2400_support.h b/drivers/staging/media/atomisp/pci/isp2400_support.h
index e9106d1e6a63..06d04853d4ee 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_support.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_support.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2400_system_global.h b/drivers/staging/media/atomisp/pci/isp2400_system_global.h
index 06fce25f2034..d87ddf1d2fe9 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_system_global.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_system_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -46,27 +47,6 @@
* N.B. the 3 input formatters are of 2 different classess
*/
-/*
- * Since this file is visible everywhere and the system definition
- * macros are not, detect the separate definitions for {host, SP, ISP}
- *
- * The 2401 system has the nice property that it uses a vanilla 2400 SP
- * so the SP will believe it is a 2400 system rather than 2401...
- */
-//#if defined(SYSTEM_hive_isp_css_2401_system) || defined(__isp2401_mamoiada) || defined(__scalar_processor_2401)
-#if defined(SYSTEM_hive_isp_css_2401_system) || defined(__isp2401_mamoiada)
-#define IS_ISP_2401_MAMOIADA_SYSTEM
-#define HAS_ISP_2401_MAMOIADA
-#define HAS_SP_2400
-//#elif defined(SYSTEM_hive_isp_css_2400_system) || defined(__isp2400_mamoiada) || defined(__scalar_processor_2400)
-#elif defined(SYSTEM_hive_isp_css_2400_system) || defined(__isp2400_mamoiada)
-#define IS_ISP_2400_MAMOIADA_SYSTEM
-#define HAS_ISP_2400_MAMOIADA
-#define HAS_SP_2400
-#else
-#error "system_global.h: 2400_SYSTEM must be one of {2400, 2401 }"
-#endif
-
#define USE_INPUT_SYSTEM_VERSION_2
#define HAS_MMU_VERSION_2
@@ -129,21 +109,11 @@ typedef enum {
N_SP_ID
} sp_ID_t;
-#if defined(IS_ISP_2401_MAMOIADA_SYSTEM)
typedef enum {
MMU0_ID = 0,
MMU1_ID,
N_MMU_ID
} mmu_ID_t;
-#elif defined(IS_ISP_2400_MAMOIADA_SYSTEM)
-typedef enum {
- MMU0_ID = 0,
- MMU1_ID,
- N_MMU_ID
-} mmu_ID_t;
-#else
-#error "system_global.h: SYSTEM must be one of {2400, 2401}"
-#endif
typedef enum {
DMA0_ID = 0,
diff --git a/drivers/staging/media/atomisp/pci/isp2400_system_local.h b/drivers/staging/media/atomisp/pci/isp2400_system_local.h
index ee38059d6ceb..675b8e5bdcc1 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_system_local.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_system_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -19,8 +20,6 @@
#ifndef HRT_USE_VIR_ADDRS
#define HRT_USE_VIR_ADDRS
#endif
-/* This interface is deprecated */
-/*#include "hive_isp_css_custom_host_hrt.h"*/
#endif
#include "system_global.h"
@@ -81,7 +80,6 @@ static const hrt_address SP_PMEM_BASE[N_SP_ID] = {
};
/* MMU */
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM) || defined(IS_ISP_2401_MAMOIADA_SYSTEM)
/*
* MMU0_ID: The data MMU
* MMU1_ID: The icache MMU
@@ -90,9 +88,6 @@ static const hrt_address MMU_BASE[N_MMU_ID] = {
(hrt_address)0x0000000000070000ULL,
(hrt_address)0x00000000000A0000ULL
};
-#else
-#error "system_local.h: SYSTEM must be one of {2400, 2401 }"
-#endif
/* DMA */
static const hrt_address DMA_BASE[N_DMA_ID] = {
@@ -106,6 +101,7 @@ static const hrt_address IRQ_BASE[N_IRQ_ID] = {
(hrt_address)0x000000000008C000ULL,
(hrt_address)0x0000000000090200ULL
};
+
/*
(hrt_address)0x0000000000000500ULL};
*/
@@ -161,6 +157,7 @@ static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
(hrt_address)0x0000000000080000ULL
};
+
/* (hrt_address)0x0000000000081000ULL, */ /* capture A */
/* (hrt_address)0x0000000000082000ULL, */ /* capture B */
/* (hrt_address)0x0000000000083000ULL, */ /* capture C */
@@ -222,7 +219,6 @@ static const hrt_address SP_PMEM_BASE[N_SP_ID] = {
};
/* MMU */
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM) || defined(IS_ISP_2401_MAMOIADA_SYSTEM)
/*
* MMU0_ID: The data MMU
* MMU1_ID: The icache MMU
@@ -231,9 +227,6 @@ static const hrt_address MMU_BASE[N_MMU_ID] = {
(hrt_address)0x00070000UL,
(hrt_address)0x000A0000UL
};
-#else
-#error "system_local.h: SYSTEM must be one of {2400, 2401 }"
-#endif
/* DMA */
static const hrt_address DMA_BASE[N_DMA_ID] = {
@@ -247,6 +240,7 @@ static const hrt_address IRQ_BASE[N_IRQ_ID] = {
(hrt_address)0x0008C000UL,
(hrt_address)0x00090200UL
};
+
/*
(hrt_address)0x00000500UL};
*/
@@ -297,12 +291,14 @@ static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
(hrt_address)0x00030200UL,
(hrt_address)0x00030400UL
};
+
/* (hrt_address)0x00030600UL, */ /* memcpy() */
/* INPUT_SYSTEM */
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
(hrt_address)0x00080000UL
};
+
/* (hrt_address)0x00081000UL, */ /* capture A */
/* (hrt_address)0x00082000UL, */ /* capture B */
/* (hrt_address)0x00083000UL, */ /* capture C */
diff --git a/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h
index 9c882fe134f4..5070e651f7c4 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h b/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h
index f199423e28da..f52a8ca5f86b 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2401_input_system_private.h b/drivers/staging/media/atomisp/pci/isp2401_input_system_private.h
index 3f60f59ae51f..f3ca5d1bcb01 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_input_system_private.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_input_system_private.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2401_system_global.h b/drivers/staging/media/atomisp/pci/isp2401_system_global.h
index 213b6ee52208..8bb2a956f983 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_system_global.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_system_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -52,27 +53,6 @@
#define USE_INPUT_SYSTEM_VERSION_2401
-/*
- * Since this file is visible everywhere and the system definition
- * macros are not, detect the separate definitions for {host, SP, ISP}
- *
- * The 2401 system has the nice property that it uses a vanilla 2400 SP
- * so the SP will believe it is a 2400 system rather than 2401...
- */
-/* #if defined(SYSTEM_hive_isp_css_2401_system) || defined(__isp2401_mamoiada) || defined(__scalar_processor_2401) */
-#if defined(SYSTEM_hive_isp_css_2401_system) || defined(__isp2401_mamoiada)
-#define IS_ISP_2401_MAMOIADA_SYSTEM
-#define HAS_ISP_2401_MAMOIADA
-#define HAS_SP_2400
-/* #elif defined(SYSTEM_hive_isp_css_2400_system) || defined(__isp2400_mamoiada) || defined(__scalar_processor_2400)*/
-#elif defined(SYSTEM_hive_isp_css_2400_system) || defined(__isp2400_mamoiada)
-#define IS_ISP_2400_MAMOIADA_SYSTEM
-#define HAS_ISP_2400_MAMOIADA
-#define HAS_SP_2400
-#else
-#error "system_global.h: 2400_SYSTEM must be one of {2400, 2401 }"
-#endif
-
#define HAS_MMU_VERSION_2
#define HAS_DMA_VERSION_2
#define HAS_GDC_VERSION_2
@@ -143,21 +123,11 @@ typedef enum {
N_SP_ID
} sp_ID_t;
-#if defined(IS_ISP_2401_MAMOIADA_SYSTEM)
-typedef enum {
- MMU0_ID = 0,
- MMU1_ID,
- N_MMU_ID
-} mmu_ID_t;
-#elif defined(IS_ISP_2400_MAMOIADA_SYSTEM)
typedef enum {
MMU0_ID = 0,
MMU1_ID,
N_MMU_ID
} mmu_ID_t;
-#else
-#error "system_global.h: SYSTEM must be one of {2400, 2401}"
-#endif
typedef enum {
DMA0_ID = 0,
diff --git a/drivers/staging/media/atomisp/pci/isp2401_system_local.h b/drivers/staging/media/atomisp/pci/isp2401_system_local.h
index 4bd95b818494..b09f8faadb13 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_system_local.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_system_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -19,8 +20,6 @@
#ifndef HRT_USE_VIR_ADDRS
#define HRT_USE_VIR_ADDRS
#endif
-/* This interface is deprecated */
-/*#include "hive_isp_css_custom_host_hrt.h"*/
#endif
#include "system_global.h"
@@ -75,7 +74,6 @@ static const hrt_address SP_DMEM_BASE[N_SP_ID] = {
};
/* MMU */
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM) || defined(IS_ISP_2401_MAMOIADA_SYSTEM)
/*
* MMU0_ID: The data MMU
* MMU1_ID: The icache MMU
@@ -84,9 +82,6 @@ static const hrt_address MMU_BASE[N_MMU_ID] = {
0x0000000000070000ULL,
0x00000000000A0000ULL
};
-#else
-#error "system_local.h: SYSTEM must be one of {2400, 2401 }"
-#endif
/* DMA */
static const hrt_address DMA_BASE[N_DMA_ID] = {
@@ -104,6 +99,7 @@ static const hrt_address IRQ_BASE[N_IRQ_ID] = {
0x000000000008C000ULL,
0x0000000000090200ULL
};
+
/*
0x0000000000000500ULL};
*/
@@ -160,6 +156,7 @@ static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
0x0000000000080000ULL
};
+
/* 0x0000000000081000ULL, */ /* capture A */
/* 0x0000000000082000ULL, */ /* capture B */
/* 0x0000000000083000ULL, */ /* capture C */
@@ -258,7 +255,6 @@ static const hrt_address SP_DMEM_BASE[N_SP_ID] = {
};
/* MMU */
-#if defined(IS_ISP_2400_MAMOIADA_SYSTEM) || defined(IS_ISP_2401_MAMOIADA_SYSTEM)
/*
* MMU0_ID: The data MMU
* MMU1_ID: The icache MMU
@@ -267,9 +263,6 @@ static const hrt_address MMU_BASE[N_MMU_ID] = {
0x00070000UL,
0x000A0000UL
};
-#else
-#error "system_local.h: SYSTEM must be one of {2400, 2401 }"
-#endif
/* DMA */
static const hrt_address DMA_BASE[N_DMA_ID] = {
@@ -287,6 +280,7 @@ static const hrt_address IRQ_BASE[N_IRQ_ID] = {
0x0008C000UL,
0x00090200UL
};
+
/*
0x00000500UL};
*/
@@ -336,12 +330,14 @@ static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = {
0x00030200UL,
0x00030400UL
};
+
/* 0x00030600UL, */ /* memcpy() */
/* INPUT_SYSTEM */
static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = {
0x00080000UL
};
+
/* 0x00081000UL, */ /* capture A */
/* 0x00082000UL, */ /* capture B */
/* 0x00083000UL, */ /* capture C */
diff --git a/drivers/staging/media/atomisp/pci/isp_acquisition_defs.h b/drivers/staging/media/atomisp/pci/isp_acquisition_defs.h
index 5bdc16c71e82..8e4bddc3790d 100644
--- a/drivers/staging/media/atomisp/pci/isp_acquisition_defs.h
+++ b/drivers/staging/media/atomisp/pci/isp_acquisition_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp_capture_defs.h b/drivers/staging/media/atomisp/pci/isp_capture_defs.h
index 5ab796e5a53f..14cbb6390d3e 100644
--- a/drivers/staging/media/atomisp/pci/isp_capture_defs.h
+++ b/drivers/staging/media/atomisp/pci/isp_capture_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp2401_mamoiada_params.h b/drivers/staging/media/atomisp/pci/mamoiada_params.h
index 42f821473826..e18e5f3576df 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_mamoiada_params.h
+++ b/drivers/staging/media/atomisp/pci/mamoiada_params.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,11 +16,6 @@
/* Version */
#define RTL_VERSION
-/* Cell name */
-#define ISP_CELL_TYPE isp2401_mamoiada
-#define ISP_VMEM simd_vmem
-#define _HRT_ISP_VMEM isp2401_mamoiada_simd_vmem
-
/* instruction pipeline depth */
#define ISP_BRANCHDELAY 5
@@ -153,12 +149,6 @@
#define ISP_VEC_ALIGN ISP_VMEM_ALIGN
-/* HRT specific vector support */
-#define isp2401_mamoiada_vector_alignment ISP_VEC_ALIGN
-#define isp2401_mamoiada_vector_elem_bits ISP_VMEM_ELEMBITS
-#define isp2401_mamoiada_vector_elem_precision ISP_VMEM_ELEM_PRECISION
-#define isp2401_mamoiada_vector_num_elems ISP_VEC_NELEMS
-
/* register file sizes */
#define ISP_RF0_SIZE 64
#define ISP_RF1_SIZE 16
@@ -172,14 +162,7 @@
#define ISP_RF9_SIZE 16
#define ISP_RF10_SIZE 16
#define ISP_RF11_SIZE 16
-#define ISP_VRF1_SIZE 32
-#define ISP_VRF2_SIZE 32
-#define ISP_VRF3_SIZE 32
-#define ISP_VRF4_SIZE 32
-#define ISP_VRF5_SIZE 32
-#define ISP_VRF6_SIZE 32
-#define ISP_VRF7_SIZE 32
-#define ISP_VRF8_SIZE 32
+
#define ISP_SRF1_SIZE 4
#define ISP_SRF2_SIZE 64
#define ISP_SRF3_SIZE 64
diff --git a/drivers/staging/media/atomisp/pci/memory_realloc.c b/drivers/staging/media/atomisp/pci/memory_realloc.c
deleted file mode 100644
index e640d5daf502..000000000000
--- a/drivers/staging/media/atomisp/pci/memory_realloc.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-Support for Intel Camera Imaging ISP subsystem.
-Copyright (c) 2010 - 2015, Intel Corporation.
-
-This program is free software; you can redistribute it and/or modify it
-under the terms and conditions of the GNU General Public License,
-version 2, as published by the Free Software Foundation.
-
-This program is distributed in the hope it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-more details.
-*/
-#include "memory_realloc.h"
-#include "ia_css_debug.h"
-#include "ia_css_refcount.h"
-#include "memory_access.h"
-
-static bool realloc_isp_css_mm_buf(
- hrt_vaddress *curr_buf,
- size_t *curr_size,
- size_t needed_size,
- bool force,
- enum ia_css_err *err,
- uint16_t mmgr_attribute);
-
-bool reallocate_buffer(
- hrt_vaddress *curr_buf,
- size_t *curr_size,
- size_t needed_size,
- bool force,
- enum ia_css_err *err)
-{
- bool ret;
- u16 mmgr_attribute = MMGR_ATTRIBUTE_DEFAULT;
-
- IA_CSS_ENTER_PRIVATE("void");
-
- ret = realloc_isp_css_mm_buf(curr_buf,
- curr_size, needed_size, force, err, mmgr_attribute);
-
- IA_CSS_LEAVE_PRIVATE("ret=%d", ret);
- return ret;
-}
-
-static bool realloc_isp_css_mm_buf(
- hrt_vaddress *curr_buf,
- size_t *curr_size,
- size_t needed_size,
- bool force,
- enum ia_css_err *err,
- uint16_t mmgr_attribute)
-{
- s32 id;
-
- *err = IA_CSS_SUCCESS;
- /* Possible optimization: add a function sh_css_isp_css_mm_realloc()
- * and implement on top of hmm. */
-
- IA_CSS_ENTER_PRIVATE("void");
-
- if (ia_css_refcount_is_single(*curr_buf) && !force &&
- *curr_size >= needed_size) {
- IA_CSS_LEAVE_PRIVATE("false");
- return false;
- }
-
- id = IA_CSS_REFCOUNT_PARAM_BUFFER;
- ia_css_refcount_decrement(id, *curr_buf);
- *curr_buf = ia_css_refcount_increment(id, mmgr_alloc_attr(needed_size,
- mmgr_attribute));
-
- if (!*curr_buf) {
- *err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
- *curr_size = 0;
- } else {
- *curr_size = needed_size;
- }
- IA_CSS_LEAVE_PRIVATE("true");
- return true;
-}
diff --git a/drivers/staging/media/atomisp/pci/mmu/isp_mmu.c b/drivers/staging/media/atomisp/pci/mmu/isp_mmu.c
index 8930fd629dc3..72287de75a63 100644
--- a/drivers/staging/media/atomisp/pci/mmu/isp_mmu.c
+++ b/drivers/staging/media/atomisp/pci/mmu/isp_mmu.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Medifield PNW Camera Imaging ISP subsystem.
*
diff --git a/drivers/staging/media/atomisp/pci/mmu/sh_mmu_mrfld.c b/drivers/staging/media/atomisp/pci/mmu/sh_mmu_mrfld.c
index 031d7fa00510..0fbb361f5661 100644
--- a/drivers/staging/media/atomisp/pci/mmu/sh_mmu_mrfld.c
+++ b/drivers/staging/media/atomisp/pci/mmu/sh_mmu_mrfld.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Merrifield PNW Camera Imaging ISP subsystem.
*
@@ -19,7 +20,6 @@
#include "type_support.h"
#include "mmu/isp_mmu.h"
#include "mmu/sh_mmu_mrfld.h"
-#include "memory_access/memory_access.h"
#include "atomisp_compat.h"
#define MERR_VALID_PTE_MASK 0x80000000
@@ -63,7 +63,7 @@ static unsigned int sh_get_pd_base(struct isp_mmu *mmu,
*/
static void sh_tlb_flush(struct isp_mmu *mmu)
{
- atomisp_css_mmu_invalidate_cache();
+ ia_css_mmu_invalidate_cache();
}
struct isp_mmu_client sh_mmu_mrfld = {
diff --git a/drivers/staging/media/atomisp/pci/mmu_defs.h b/drivers/staging/media/atomisp/pci/mmu_defs.h
index c038f39ffd25..03cfb5833027 100644
--- a/drivers/staging/media/atomisp/pci/mmu_defs.h
+++ b/drivers/staging/media/atomisp/pci/mmu_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h b/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
index 26a3fc4d48e8..b44099dbdacd 100644
--- a/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
+++ b/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
@@ -143,8 +144,7 @@ struct ia_css_binary {
struct ia_css_isp_param_css_segments css_params;
};
-#define IA_CSS_BINARY_DEFAULT_SETTINGS \
-(struct ia_css_binary) { \
+#define IA_CSS_BINARY_DEFAULT_SETTINGS { \
.input_format = ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY, \
.in_frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \
.internal_frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \
@@ -152,13 +152,13 @@ struct ia_css_binary {
.vf_frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \
}
-enum ia_css_err
+int
ia_css_binary_init_infos(void);
-enum ia_css_err
+int
ia_css_binary_uninit(void);
-enum ia_css_err
+int
ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
bool online,
bool two_ppc,
@@ -172,7 +172,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
int stream_config_left_padding,
bool accelerator);
-enum ia_css_err
+int
ia_css_binary_find(struct ia_css_binary_descr *descr,
struct ia_css_binary *binary);
@@ -188,10 +188,10 @@ ia_css_binary_find(struct ia_css_binary_descr *descr,
* the shading table directly required from ISP.
* @param[out] pipe_config: The pipe configuration.
* The shading information related to ISP (but, not necessary as API) is stored in the pipe_config.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err
+int
ia_css_binary_get_shading_info(const struct ia_css_binary *binary,
enum ia_css_shading_correction_type type,
unsigned int required_bds_factor,
@@ -199,7 +199,7 @@ ia_css_binary_get_shading_info(const struct ia_css_binary *binary,
struct ia_css_shading_info *shading_info,
struct ia_css_pipe_config *pipe_config);
-enum ia_css_err
+int
ia_css_binary_3a_grid_info(const struct ia_css_binary *binary,
struct ia_css_grid_info *info,
struct ia_css_pipe *pipe);
diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
index 2a23b7c6aeeb..9813014c3fd3 100644
--- a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
+++ b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -14,6 +15,9 @@
#include <math_support.h>
#include <gdc_device.h> /* HR_GDC_N */
+
+#include "hmm.h"
+
#include "isp.h" /* ISP_VEC_NELEMS */
#include "ia_css_binary.h"
@@ -26,6 +30,8 @@
#include "sh_css_defs.h"
#include "sh_css_legacy.h"
+#include "atomisp_internal.h"
+
#include "vf/vf_1.0/ia_css_vf.host.h"
#include "sc/sc_1.0/ia_css_sc.host.h"
#include "sdis/sdis_1.0/ia_css_sdis.host.h"
@@ -33,8 +39,6 @@
#include "camera/pipe/interface/ia_css_pipe_binarydesc.h"
-#include "memory_access.h"
-
#include "assert_support.h"
#define IMPLIES(a, b) (!(a) || (b)) /* A => B */
@@ -132,7 +136,7 @@ struct sh_css_binary_sc_requirements {
};
/* Get the requirements for the shading correction. */
-static enum ia_css_err
+static int
#ifndef ISP2401
ia_css_binary_compute_shading_table_bayer_origin(
const struct ia_css_binary *binary, /* [in] */
@@ -147,7 +151,7 @@ sh_css_binary_get_sc_requirements(
struct sh_css_binary_sc_requirements *scr) /* [out] */
#endif
{
- enum ia_css_err err;
+ int err;
#ifndef ISP2401
/* Numerator and denominator of the fixed bayer downscaling factor.
@@ -196,7 +200,7 @@ sh_css_binary_get_sc_requirements(
/* Get the numerator and denominator of bayer downscaling factor. */
err = sh_css_bds_factor_get_numerator_denominator
(required_bds_factor, &bds_num, &bds_den);
- if (err != IA_CSS_SUCCESS)
+ if (err)
#else
/* Flags corresponding to NEED_BDS_FACTOR_2_00/NEED_BDS_FACTOR_1_50/NEED_BDS_FACTOR_1_25 macros
* defined in isp kernels. */
@@ -226,7 +230,7 @@ sh_css_binary_get_sc_requirements(
/* Get the numerator and denominator of the required bayer downscaling factor. */
err = sh_css_bds_factor_get_numerator_denominator(required_bds_factor, &bds_num, &bds_den);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
#endif
@@ -479,7 +483,7 @@ return err;
}
/* Get the shading information of Shading Correction Type 1. */
-static enum ia_css_err
+static int
ia_css_binary_get_shading_info_type_1(const struct ia_css_binary
*binary, /* [in] */
unsigned int required_bds_factor, /* [in] */
@@ -491,7 +495,7 @@ ia_css_binary_get_shading_info_type_1(const struct ia_css_binary
struct ia_css_pipe_config *pipe_config) /* [out] */
#endif
{
- enum ia_css_err err;
+ int err;
#ifndef ISP2401
struct sh_css_shading_table_bayer_origin_compute_results res;
#else
@@ -545,12 +549,12 @@ ia_css_binary_get_shading_info_type_1(const struct ia_css_binary
required_bds_factor,
stream_config,
&res);
- if (err != IA_CSS_SUCCESS)
+ if (err)
#else
*shading_info = DEFAULT_SHADING_INFO_TYPE_1;
err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
#endif
@@ -639,8 +643,8 @@ IA_CSS_LOG("adjust_width_bqs=%d, adjust_height_bqs=%d", adjust_width_bqs, adjust
if (adjust_width_bqs > tbl_width_bqs || adjust_height_bqs > tbl_height_bqs)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
/* Origin of the internal frame on the shading table. */
@@ -698,7 +702,7 @@ IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
-enum ia_css_err
+int
ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */
enum ia_css_shading_correction_type type, /* [in] */
unsigned int required_bds_factor, /* [in] */
@@ -706,7 +710,7 @@ ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */
struct ia_css_shading_info *shading_info, /* [out] */
struct ia_css_pipe_config *pipe_config) /* [out] */
{
- enum ia_css_err err;
+ int err;
assert(binary);
assert(shading_info);
@@ -726,7 +730,7 @@ ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */
/* Other function calls can be added here when other shading correction types will be added in the future. */
else
- err = IA_CSS_ERR_NOT_SUPPORTED;
+ err = -ENOTSUPP;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -784,12 +788,12 @@ ia_css_binary_dvs_stat_grid_info(
return;
}
-enum ia_css_err
+int
ia_css_binary_3a_grid_info(const struct ia_css_binary *binary,
struct ia_css_grid_info *info,
struct ia_css_pipe *pipe) {
struct ia_css_3a_grid_info *s3a_info;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("binary=%p, info=%p, pipe=%p",
binary, info, pipe);
@@ -857,18 +861,6 @@ binary_supports_output_format(const struct ia_css_binary_xinfo *info,
return false;
}
-#ifdef ISP2401
-static bool
-binary_supports_input_format(const struct ia_css_binary_xinfo *info,
- enum atomisp_input_format format)
-{
- assert(info);
- (void)format;
-
- return true;
-}
-#endif
-
static bool
binary_supports_vf_format(const struct ia_css_binary_xinfo *info,
enum ia_css_frame_format format)
@@ -892,52 +884,52 @@ supports_bds_factor(u32 supported_factors,
return ((supported_factors & PACK_BDS_FACTOR(bds_factor)) != 0);
}
-static enum ia_css_err
+static int
binary_init_info(struct ia_css_binary_xinfo *info, unsigned int i,
bool *binary_found) {
const unsigned char *blob = sh_css_blob_info[i].blob;
unsigned int size = sh_css_blob_info[i].header.blob.size;
if ((!info) || (!binary_found))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
*info = sh_css_blob_info[i].header.info.isp;
*binary_found = blob;
info->blob_index = i;
/* we don't have this binary, skip it */
if (!size)
- return IA_CSS_SUCCESS;
+ return 0;
info->xmem_addr = sh_css_load_blob(blob, size);
if (!info->xmem_addr)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
- return IA_CSS_SUCCESS;
+ return -ENOMEM;
+ return 0;
}
/* When binaries are put at the beginning, they will only
* be selected if no other primary matches.
*/
-enum ia_css_err
+int
ia_css_binary_init_infos(void) {
unsigned int i;
unsigned int num_of_isp_binaries = sh_css_num_binaries - NUM_OF_SPS - NUM_OF_BLS;
if (num_of_isp_binaries == 0)
- return IA_CSS_SUCCESS;
+ return 0;
- all_binaries = sh_css_malloc(num_of_isp_binaries *
- sizeof(*all_binaries));
+ all_binaries = kvmalloc(num_of_isp_binaries * sizeof(*all_binaries),
+ GFP_KERNEL);
if (!all_binaries)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
for (i = 0; i < num_of_isp_binaries; i++)
{
- enum ia_css_err ret;
+ int ret;
struct ia_css_binary_xinfo *binary = &all_binaries[i];
bool binary_found;
ret = binary_init_info(binary, i, &binary_found);
- if (ret != IA_CSS_SUCCESS)
+ if (ret)
return ret;
if (!binary_found)
continue;
@@ -947,10 +939,10 @@ ia_css_binary_init_infos(void) {
binary->blob = &sh_css_blob_info[i];
binary->mem_offsets = sh_css_blob_info[i].mem_offsets;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
ia_css_binary_uninit(void) {
unsigned int i;
struct ia_css_binary_xinfo *b;
@@ -964,8 +956,8 @@ ia_css_binary_uninit(void) {
}
binary_infos[i] = NULL;
}
- sh_css_free(all_binaries);
- return IA_CSS_SUCCESS;
+ kvfree(all_binaries);
+ return 0;
}
/* @brief Compute decimation factor for 3A statistics and shading correction.
@@ -1083,7 +1075,7 @@ binary_in_frame_padded_width(int in_frame_width,
return rval;
}
-enum ia_css_err
+int
ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
bool online,
bool two_ppc,
@@ -1114,7 +1106,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
bool need_scaling = false;
struct ia_css_resolution binary_dvs_env, internal_res;
- enum ia_css_err err;
+ int err;
unsigned int i;
const struct ia_css_frame_info *bin_out_info = NULL;
@@ -1128,7 +1120,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
err = ia_css_isp_param_allocate_isp_parameters(
&binary->mem_params, &binary->css_params,
&info->mem_initializers);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
return err;
}
}
@@ -1231,7 +1223,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
{
err = ia_css_vf_configure(binary, bin_out_info,
(struct ia_css_frame_info *)vf_info, &vf_log_ds);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
if (!accelerator) {
ia_css_isp_param_destroy_isp_parameters(
&binary->mem_params,
@@ -1252,7 +1244,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
binary->vf_frame_info.format = vf_info->format;
if (!bin_out_info)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width,
vf_log_ds);
vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
@@ -1350,7 +1342,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
if (info->enable.sc)
{
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
binary->sctbl_width_per_color = _ISP2400_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
binary->sctbl_aligned_width_per_color = ISP2400_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
binary->sctbl_height = _ISP2400_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci);
@@ -1366,7 +1358,7 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
binary->sctbl_width_per_color = 0;
binary->sctbl_aligned_width_per_color = 0;
binary->sctbl_height = 0;
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
binary->sctbl_legacy_width_per_color = 0;
binary->sctbl_legacy_height = 0;
}
@@ -1382,12 +1374,11 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
else
binary->left_padding = 0;
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
-ia_css_binary_find(struct ia_css_binary_descr *descr,
- struct ia_css_binary *binary) {
+static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
+ struct ia_css_binary *binary) {
int mode;
bool online;
bool two_ppc;
@@ -1413,7 +1404,7 @@ ia_css_binary_find(struct ia_css_binary_descr *descr,
#ifdef ISP2401
bool enable_luma_only;
#endif
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
bool continuous;
unsigned int isp_pipe_version;
struct ia_css_resolution dvs_env, internal_res;
@@ -1441,7 +1432,7 @@ ia_css_binary_find(struct ia_css_binary_descr *descr,
req_bin_out_info = req_out_info[i];
}
if (!req_bin_out_info)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
#ifndef ISP2401
req_vf_info = descr->vf_info;
#else
@@ -1699,15 +1690,6 @@ ia_css_binary_find(struct ia_css_binary_descr *descr,
binary_supports_output_format(xcandidate, req_bin_out_info->format));
continue;
}
-#ifdef ISP2401
- if (!binary_supports_input_format(xcandidate, descr->stream_format)) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_binary_find() [%d] continue: !%d\n",
- __LINE__,
- binary_supports_input_format(xcandidate, req_in_info->format));
- continue;
- }
-#endif
if (xcandidate->num_output_pins > 1 &&
/* in case we have a second output pin, */
req_vf_info && /* and we need vf output. */
@@ -1799,7 +1781,7 @@ ia_css_binary_find(struct ia_css_binary_descr *descr,
descr->stream_config_left_padding,
false);
- if (err != IA_CSS_SUCCESS)
+ if (err)
break;
binary_init_metrics(&binary->metrics, &binary->info->sp);
break;
@@ -1812,9 +1794,32 @@ ia_css_binary_find(struct ia_css_binary_descr *descr,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_binary_find() leave: return_err=%d\n", err);
+ if (!err && xcandidate)
+ dev_dbg(atomisp_dev,
+ "Using binary %s (id %d), type %d, mode %d, continuous %s\n",
+ xcandidate->blob->name,
+ xcandidate->sp.id,
+ xcandidate->type,
+ xcandidate->sp.pipeline.mode,
+ xcandidate->sp.enable.continuous ? "true" : "false");
+
+
return err;
}
+int ia_css_binary_find(struct ia_css_binary_descr *descr,
+ struct ia_css_binary *binary)
+{
+ int ret = __ia_css_binary_find(descr, binary);
+
+ if (unlikely(ret)) {
+ dev_dbg(atomisp_dev, "Seeking for binary failed at:");
+ dump_stack();
+ }
+
+ return ret;
+}
+
unsigned
ia_css_binary_max_vf_width(void)
{
diff --git a/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h b/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h
index 78e433fa3466..a461b0ed03f1 100644
--- a/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h
+++ b/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -77,10 +78,10 @@ void ia_css_bufq_init(void);
*
* @param queue_id[in] Index of the queue in the specified thread
* @param item[in] Object to enqueue.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_enqueue_buffer(
+int ia_css_bufq_enqueue_buffer(
int thread_index,
int queue_id,
uint32_t item);
@@ -91,10 +92,10 @@ enum ia_css_err ia_css_bufq_enqueue_buffer(
* @param queue_id[in] Specifies the index of the queue in the list where
* the item has to be read.
* @paramitem [out] Object to be dequeued into this item.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_dequeue_buffer(
+int ia_css_bufq_dequeue_buffer(
int queue_id,
uint32_t *item);
@@ -105,10 +106,10 @@ enum ia_css_err ia_css_bufq_dequeue_buffer(
* @param[in] evt_payload_0 The event payload.
* @param[in] evt_payload_1 The event payload.
* @param[in] evt_payload_2 The event payload.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_enqueue_psys_event(
+int ia_css_bufq_enqueue_psys_event(
u8 evt_id,
u8 evt_payload_0,
u8 evt_payload_1,
@@ -119,10 +120,10 @@ enum ia_css_err ia_css_bufq_enqueue_psys_event(
* @brief Dequeue an item from SP to host communication event queue.
*
* @param item Object to be dequeued into this item.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_dequeue_psys_event(
+int ia_css_bufq_dequeue_psys_event(
u8 item[BUFQ_EVENT_SIZE]
);
@@ -131,10 +132,10 @@ enum ia_css_err ia_css_bufq_dequeue_psys_event(
* @brief Enqueue an event item into host to SP EOF event queue.
*
* @param[in] evt_id The event ID.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_enqueue_isys_event(
+int ia_css_bufq_enqueue_isys_event(
uint8_t evt_id);
/**
@@ -142,29 +143,29 @@ enum ia_css_err ia_css_bufq_enqueue_isys_event(
*
* @param item Object to be dequeued into this item.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_dequeue_isys_event(
+int ia_css_bufq_dequeue_isys_event(
u8 item[BUFQ_EVENT_SIZE]);
/**
* @brief Enqueue a tagger command item into tagger command queue..
*
* @param item Object to be enqueue.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_enqueue_tag_cmd(
+int ia_css_bufq_enqueue_tag_cmd(
uint32_t item);
/**
* @brief Uninitializes bufq module.
*
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_bufq_deinit(void);
+int ia_css_bufq_deinit(void);
/**
* @brief Dump queue states
diff --git a/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq_comm.h b/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq_comm.h
index 508209711edc..cddf5882b76a 100644
--- a/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq_comm.h
+++ b/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq_comm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/bufq/src/bufq.c b/drivers/staging/media/atomisp/pci/runtime/bufq/src/bufq.c
index 7e01df257150..38e85735293b 100644
--- a/drivers/staging/media/atomisp/pci/runtime/bufq/src/bufq.c
+++ b/drivers/staging/media/atomisp/pci/runtime/bufq/src/bufq.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -22,7 +23,6 @@
#include "ia_css_debug.h" /* ia_css_debug_dtrace*/
#include "sh_css_internal.h" /* sh_css_queue_type */
#include "sp_local.h" /* sp_address_of */
-#include "ia_css_util.h" /* ia_css_convert_errno()*/
#include "sh_css_firmware.h" /* sh_css_sp_fw*/
#define BUFQ_DUMP_FILE_NAME_PREFIX_SIZE 256
@@ -329,19 +329,18 @@ void ia_css_bufq_init(void)
IA_CSS_LEAVE_PRIVATE("");
}
-enum ia_css_err ia_css_bufq_enqueue_buffer(
+int ia_css_bufq_enqueue_buffer(
int thread_index,
int queue_id,
uint32_t item)
{
- enum ia_css_err return_err = IA_CSS_SUCCESS;
ia_css_queue_t *q;
int error;
IA_CSS_ENTER_PRIVATE("queue_id=%d", queue_id);
if ((thread_index >= SH_CSS_MAX_SP_THREADS) || (thread_index < 0) ||
(queue_id == SH_CSS_INVALID_QUEUE_ID))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* Get the queue for communication */
q = bufq_get_qhandle(sh_css_host2sp_buffer_queue,
@@ -349,22 +348,20 @@ enum ia_css_err ia_css_bufq_enqueue_buffer(
thread_index);
if (q) {
error = ia_css_queue_enqueue(q, item);
- return_err = ia_css_convert_errno(error);
} else {
IA_CSS_ERROR("queue is not initialized");
- return_err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ error = -EBUSY;
}
- IA_CSS_LEAVE_ERR_PRIVATE(return_err);
- return return_err;
+ IA_CSS_LEAVE_ERR_PRIVATE(error);
+ return error;
}
-enum ia_css_err ia_css_bufq_dequeue_buffer(
+int ia_css_bufq_dequeue_buffer(
int queue_id,
uint32_t *item)
{
- enum ia_css_err return_err;
- int error = 0;
+ int error;
ia_css_queue_t *q;
IA_CSS_ENTER_PRIVATE("queue_id=%d", queue_id);
@@ -372,52 +369,49 @@ enum ia_css_err ia_css_bufq_dequeue_buffer(
(queue_id <= SH_CSS_INVALID_QUEUE_ID) ||
(queue_id >= SH_CSS_MAX_NUM_QUEUES)
)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
q = bufq_get_qhandle(sh_css_sp2host_buffer_queue,
queue_id,
-1);
if (q) {
error = ia_css_queue_dequeue(q, item);
- return_err = ia_css_convert_errno(error);
} else {
IA_CSS_ERROR("queue is not initialized");
- return_err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ error = -EBUSY;
}
- IA_CSS_LEAVE_ERR_PRIVATE(return_err);
- return return_err;
+ IA_CSS_LEAVE_ERR_PRIVATE(error);
+ return error;
}
-enum ia_css_err ia_css_bufq_enqueue_psys_event(
+int ia_css_bufq_enqueue_psys_event(
u8 evt_id,
u8 evt_payload_0,
u8 evt_payload_1,
uint8_t evt_payload_2)
{
- enum ia_css_err return_err;
- int error = 0;
+
+ int error = 0;
ia_css_queue_t *q;
IA_CSS_ENTER_PRIVATE("evt_id=%d", evt_id);
q = bufq_get_qhandle(sh_css_host2sp_psys_event_queue, -1, -1);
if (!q) {
IA_CSS_ERROR("queue is not initialized");
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
error = ia_css_eventq_send(q,
evt_id, evt_payload_0, evt_payload_1, evt_payload_2);
- return_err = ia_css_convert_errno(error);
- IA_CSS_LEAVE_ERR_PRIVATE(return_err);
- return return_err;
+ IA_CSS_LEAVE_ERR_PRIVATE(error);
+ return error;
}
-enum ia_css_err ia_css_bufq_dequeue_psys_event(
+int ia_css_bufq_dequeue_psys_event(
u8 item[BUFQ_EVENT_SIZE])
{
- enum ia_css_err;
int error = 0;
ia_css_queue_t *q;
@@ -425,23 +419,22 @@ enum ia_css_err ia_css_bufq_dequeue_psys_event(
* by some test apps. Enablign logging here floods the log
* files which may cause timeouts. */
if (!item)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
q = bufq_get_qhandle(sh_css_sp2host_psys_event_queue, -1, -1);
if (!q) {
IA_CSS_ERROR("queue is not initialized");
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
error = ia_css_eventq_recv(q, item);
- return ia_css_convert_errno(error);
+ return error;
}
-enum ia_css_err ia_css_bufq_dequeue_isys_event(
+int ia_css_bufq_dequeue_isys_event(
u8 item[BUFQ_EVENT_SIZE])
{
#if !defined(HAS_NO_INPUT_SYSTEM)
- enum ia_css_err;
int error = 0;
ia_css_queue_t *q;
@@ -449,25 +442,24 @@ enum ia_css_err ia_css_bufq_dequeue_isys_event(
* by some test apps. Enablign logging here floods the log
* files which may cause timeouts. */
if (!item)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
q = bufq_get_qhandle(sh_css_sp2host_isys_event_queue, -1, -1);
if (!q) {
IA_CSS_ERROR("queue is not initialized");
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
error = ia_css_eventq_recv(q, item);
- return ia_css_convert_errno(error);
+ return error;
#else
(void)item;
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
#endif
}
-enum ia_css_err ia_css_bufq_enqueue_isys_event(uint8_t evt_id)
+int ia_css_bufq_enqueue_isys_event(uint8_t evt_id)
{
#if !defined(HAS_NO_INPUT_SYSTEM)
- enum ia_css_err return_err;
int error = 0;
ia_css_queue_t *q;
@@ -475,47 +467,45 @@ enum ia_css_err ia_css_bufq_enqueue_isys_event(uint8_t evt_id)
q = bufq_get_qhandle(sh_css_host2sp_isys_event_queue, -1, -1);
if (!q) {
IA_CSS_ERROR("queue is not initialized");
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
error = ia_css_eventq_send(q, evt_id, 0, 0, 0);
- return_err = ia_css_convert_errno(error);
- IA_CSS_LEAVE_ERR_PRIVATE(return_err);
- return return_err;
+
+ IA_CSS_LEAVE_ERR_PRIVATE(error);
+ return error;
#else
(void)evt_id;
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
#endif
}
-enum ia_css_err ia_css_bufq_enqueue_tag_cmd(
+int ia_css_bufq_enqueue_tag_cmd(
uint32_t item)
{
#if !defined(HAS_NO_INPUT_SYSTEM)
- enum ia_css_err return_err;
- int error = 0;
+ int error;
ia_css_queue_t *q;
IA_CSS_ENTER_PRIVATE("item=%d", item);
q = bufq_get_qhandle(sh_css_host2sp_tag_cmd_queue, -1, -1);
if (!q) {
IA_CSS_ERROR("queue is not initialized");
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
error = ia_css_queue_enqueue(q, item);
- return_err = ia_css_convert_errno(error);
- IA_CSS_LEAVE_ERR_PRIVATE(return_err);
- return return_err;
+ IA_CSS_LEAVE_ERR_PRIVATE(error);
+ return error;
#else
(void)item;
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
#endif
}
-enum ia_css_err ia_css_bufq_deinit(void)
+int ia_css_bufq_deinit(void)
{
- return IA_CSS_SUCCESS;
+ return 0;
}
static void bufq_dump_queue_info(const char *prefix, ia_css_queue_t *qhandle)
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h
index 61d612ec3a05..e04d2485ea75 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -44,8 +45,9 @@
#define IA_CSS_DEBUG_PARAM 8
/*! Level for tracing info messages */
#define IA_CSS_DEBUG_INFO 9
+
/* Global variable which controls the verbosity levels of the debug tracing */
-extern unsigned int ia_css_debug_trace_level;
+extern int dbg_level;
/*! @brief Enum defining the different isp parameters to dump.
* Values can be combined to dump a combination of sets.
@@ -90,7 +92,7 @@ enum ia_css_debug_enable_param_dump {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, \
"%s(): leave: " fmt "\n", __func__, ##__VA_ARGS__)
-/* Shorthand for returning an enum ia_css_err return value */
+/* Shorthand for returning an int return value */
#define IA_CSS_LEAVE_ERR(__err) \
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, \
"%s() %d: leave: return_err=%d\n", __func__, __LINE__, __err)
@@ -111,7 +113,7 @@ enum ia_css_debug_enable_param_dump {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, \
"%s(): leave: " fmt "\n", __func__, ##__VA_ARGS__)
-/* Shorthand for returning an enum ia_css_err return value */
+/* Shorthand for returning an int return value */
#define IA_CSS_LEAVE_ERR_PRIVATE(__err) \
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, \
"%s() %d: leave: return_err=%d\n", __func__, __LINE__, __err)
@@ -130,7 +132,7 @@ enum ia_css_debug_enable_param_dump {
static inline void
ia_css_debug_vdtrace(unsigned int level, const char *fmt, va_list args)
{
- if (ia_css_debug_trace_level >= level)
+ if (dbg_level >= level)
sh_css_vprint(fmt, args);
}
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_internal.h b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_internal.h
index 27136381857f..8ec487ad4298 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_internal.h
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h
index e9964bb421d6..538918cfb2fc 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c
index 6fadc20104bf..2bca27a04b02 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -13,7 +14,6 @@
*/
#include "debug.h"
-#include "memory_access.h"
#ifndef __INLINE_INPUT_SYSTEM__
#define __INLINE_INPUT_SYSTEM__
@@ -31,6 +31,8 @@
#define __INLINE_STREAM2MMIO__
#endif
+#include <linux/string.h> /* for strscpy() */
+
#include "ia_css_debug.h"
#include "ia_css_debug_pipe.h"
#include "ia_css_irq.h"
@@ -47,7 +49,6 @@
#include "system_local.h"
#include "assert_support.h"
#include "print_support.h"
-#include "string_support.h"
#include "fifo_monitor.h"
@@ -103,9 +104,6 @@
#include "gc/gc_2/ia_css_gc2.host.h"
#include "ynr/ynr_2/ia_css_ynr2.host.h"
-/* Global variable to store the dtrace verbosity level */
-unsigned int ia_css_debug_trace_level = IA_CSS_DEBUG_WARNING;
-
#define DPG_START "ia_css_debug_pipe_graph_dump_start "
#define DPG_END " ia_css_debug_pipe_graph_dump_end\n"
@@ -244,13 +242,13 @@ void ia_css_debug_dump_sp_stack_info(void)
void ia_css_debug_set_dtrace_level(const unsigned int trace_level)
{
- ia_css_debug_trace_level = trace_level;
+ dbg_level = trace_level;
return;
}
unsigned int ia_css_debug_get_dtrace_level(void)
{
- return ia_css_debug_trace_level;
+ return dbg_level;
}
static const char *debug_stream_format2str(const enum atomisp_input_format
@@ -463,7 +461,6 @@ void ia_css_debug_dump_isp_state(void)
#endif
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "[2] dma_FIFO stalled",
stall.fifo2);
-#if defined(HAS_ISP_2400_MAMOIADA) || defined(HAS_ISP_2401_MAMOIADA) || defined(IS_ISP_2500_SYSTEM)
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "[3] gdc0_FIFO stalled",
stall.fifo3);
@@ -475,9 +472,6 @@ void ia_css_debug_dump_isp_state(void)
#endif
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "[6] sp_FIFO stalled",
stall.fifo6);
-#else
-#error "ia_css_debug: ISP cell must be one of {2400_MAMOIADA,, 2401_MAMOIADA, 2500_SKYCAM}"
-#endif
ia_css_debug_dtrace(2, "\t%-32s: %d\n",
"status & control stalled",
stall.stat_ctrl);
@@ -489,14 +483,12 @@ void ia_css_debug_dump_isp_state(void)
stall.vamem1);
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "vamem2 stalled",
stall.vamem2);
-#if defined(HAS_ISP_2400_MAMOIADA) || defined(HAS_ISP_2401_MAMOIADA)
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "vamem3 stalled",
stall.vamem3);
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "hmem stalled",
stall.hmem);
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "pmem stalled",
stall.pmem);
-#endif
}
return;
}
@@ -509,7 +501,6 @@ void ia_css_debug_dump_sp_state(void)
sp_get_state(SP0_ID, &state, &stall);
debug_print_sp_state(&state, "SP");
if (state.is_stalling) {
-#if defined(HAS_SP_2400) || defined(IS_ISP_2500_SYSTEM)
#if !defined(HAS_NO_INPUT_SYSTEM)
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "isys_FIFO stalled",
stall.fifo0);
@@ -540,9 +531,6 @@ void ia_css_debug_dump_sp_state(void)
#endif
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "irq FIFO stalled",
stall.fifoa);
-#else
-#error "ia_css_debug: SP cell must be one of {SP2400, SP2500}"
-#endif
ia_css_debug_dtrace(2, "\t%-32s: %d\n", "dmem stalled",
stall.dmem);
ia_css_debug_dtrace(2, "\t%-32s: %d\n",
@@ -2231,7 +2219,7 @@ void ia_css_debug_dump_debug_info(const char *context)
ia_css_debug_dump_isys_state();
{
- irq_controller_state_t state;
+ struct irq_controller_state state;
irq_controller_get_state(IRQ2_ID, &state);
@@ -2492,8 +2480,8 @@ void ia_css_debug_dump_perf_counters(void)
void sh_css_init_ddr_debug_queue(void)
{
- hrt_vaddress ddr_debug_queue_addr =
- mmgr_malloc(sizeof(debug_data_ddr_t));
+ ia_css_ptr ddr_debug_queue_addr =
+ hmm_alloc(sizeof(debug_data_ddr_t), HMM_BO_PRIVATE, 0, NULL, 0);
const struct ia_css_fw_info *fw;
unsigned int HIVE_ADDR_debug_buffer_ddr_address;
@@ -2665,7 +2653,7 @@ void sh_css_dump_pipe_stripe_info(void)
static void
ia_css_debug_pipe_graph_dump_frame(
- struct ia_css_frame *frame,
+ const struct ia_css_frame *frame,
enum ia_css_pipe_id id,
char const *blob_name,
char const *frame_name,
@@ -2782,8 +2770,9 @@ ia_css_debug_pipe_graph_dump_stage(
stage->binary->info->blob->name, stage->stage_num);
} else if (stage->firmware) {
bin_type = "firmware";
- strncpy_s(blob_name, sizeof(blob_name),
- IA_CSS_EXT_ISP_PROG_NAME(stage->firmware), sizeof(blob_name));
+
+ strscpy(blob_name, IA_CSS_EXT_ISP_PROG_NAME(stage->firmware),
+ sizeof(blob_name));
}
/* Guard in case of binaries that don't have any binary_info */
@@ -2849,10 +2838,8 @@ ia_css_debug_pipe_graph_dump_stage(
while (ei[p] != ',')
p--;
/* Last comma found, copy till that comma */
- strncpy_s(enable_info1,
- sizeof(enable_info1),
- ei, p);
- enable_info1[p] = '\0';
+ strscpy(enable_info1, ei,
+ p > sizeof(enable_info1) ? sizeof(enable_info1) : p);
ei += p + 1;
l = strlen(ei);
@@ -2862,10 +2849,10 @@ ia_css_debug_pipe_graph_dump_stage(
/* we cannot use ei as argument because
* it is not guaranteed dword aligned
*/
- strncpy_s(enable_info2,
- sizeof(enable_info2),
- ei, l);
- enable_info2[l] = '\0';
+
+ strscpy(enable_info2, ei,
+ l > sizeof(enable_info2) ? sizeof(enable_info2) : l);
+
snprintf(enable_info, sizeof(enable_info), "%s\\n%s",
enable_info1, enable_info2);
@@ -2874,10 +2861,10 @@ ia_css_debug_pipe_graph_dump_stage(
p = ENABLE_LINE_MAX_LENGTH;
while (ei[p] != ',')
p--;
- strncpy_s(enable_info2,
- sizeof(enable_info2),
- ei, p);
- enable_info2[p] = '\0';
+
+ strscpy(enable_info2, ei,
+ p > sizeof(enable_info2) ? sizeof(enable_info2) : p);
+
ei += p + 1;
l = strlen(ei);
@@ -2886,9 +2873,8 @@ ia_css_debug_pipe_graph_dump_stage(
/* we cannot use ei as argument because
* it is not guaranteed dword aligned
*/
- strcpy_s(enable_info3,
- sizeof(enable_info3), ei);
- enable_info3[l] = '\0';
+ strscpy(enable_info3, ei,
+ sizeof(enable_info3));
snprintf(enable_info, sizeof(enable_info),
"%s\\n%s\\n%s",
enable_info1, enable_info2,
@@ -2898,13 +2884,11 @@ ia_css_debug_pipe_graph_dump_stage(
p = ENABLE_LINE_MAX_LENGTH;
while (ei[p] != ',')
p--;
- strncpy_s(enable_info3,
- sizeof(enable_info3),
- ei, p);
- enable_info3[p] = '\0';
+ strscpy(enable_info3, ei,
+ p > sizeof(enable_info3) ? sizeof(enable_info3) : p);
ei += p + 1;
- strcpy_s(enable_info3,
- sizeof(enable_info3), ei);
+ strscpy(enable_info3, ei,
+ sizeof(enable_info3));
snprintf(enable_info, sizeof(enable_info),
"%s\\n%s\\n%s",
enable_info1, enable_info2,
@@ -3100,7 +3084,7 @@ ia_css_debug_dump_pipe_config(
"capt_pp_in_res");
ia_css_debug_dump_resolution(&config->vf_pp_in_res, "vf_pp_in_res");
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
ia_css_debug_dump_resolution(&config->output_system_in_res,
"output_system_in_res");
}
@@ -3328,7 +3312,7 @@ static void debug_dump_one_trace(enum TRACE_CORE_ID proc_id)
return;
}
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
tmp = ia_css_device_load_uint32(start_addr);
point_num = (tmp >> 16) & 0xFFFF;
@@ -3362,7 +3346,7 @@ static void debug_dump_one_trace(enum TRACE_CORE_ID proc_id)
if ((limit == (-1)) && (trace_read_buf[i] == 0))
limit = i;
}
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "Status:\n");
for (i = 0; i < SH_CSS_MAX_SP_THREADS; i++)
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
@@ -3395,7 +3379,7 @@ static void debug_dump_one_trace(enum TRACE_CORE_ID proc_id)
for (i = 0; i < point_num; i++) {
j = (limit + i) % point_num;
if (trace_read_buf[j]) {
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
TRACE_DUMP_FORMAT dump_format = FIELD_FORMAT_UNPACK(trace_read_buf[j]);
} else {
tid_val = FIELD_TID_UNPACK(trace_read_buf[j]);
diff --git a/drivers/staging/media/atomisp/pci/runtime/event/interface/ia_css_event.h b/drivers/staging/media/atomisp/pci/runtime/event/interface/ia_css_event.h
index 1fcd0fadcac8..ebbd90b14bff 100644
--- a/drivers/staging/media/atomisp/pci/runtime/event/interface/ia_css_event.h
+++ b/drivers/staging/media/atomisp/pci/runtime/event/interface/ia_css_event.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/event/src/event.c b/drivers/staging/media/atomisp/pci/runtime/event/src/event.c
index c4578470ad8c..e702297b0a76 100644
--- a/drivers/staging/media/atomisp/pci/runtime/event/src/event.c
+++ b/drivers/staging/media/atomisp/pci/runtime/event/src/event.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -29,10 +30,7 @@
/*#include "sp.h"*/ /* host2sp_enqueue_frame_data() */
-#include "memory_access.h"
-
#include "assert_support.h"
-#include "platform_support.h" /* hrt_sleep() */
#include "ia_css_queue.h" /* host_sp_enqueue_XXX */
#include "ia_css_event.h" /* ia_css_event_encode */
diff --git a/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h b/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h
index 8602398ede52..fd001ae3522d 100644
--- a/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h
+++ b/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -23,8 +24,8 @@
* @param[in] eventq_handle eventq_handle.
* @param[in] payload The event payload.
* @return 0 - Successfully dequeue.
- * @return EINVAL - Invalid argument.
- * @return ENODATA - Queue is empty.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENODATA - Queue is empty.
*/
int ia_css_eventq_recv(
ia_css_queue_t *eventq_handle,
@@ -41,8 +42,8 @@ int ia_css_eventq_recv(
* @param[in] evt_payload_1 The event payload.
* @param[in] evt_payload_2 The event payload.
* @return 0 - Successfully enqueue.
- * @return EINVAL - Invalid argument.
- * @return ENOBUFS - Queue is full.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENOBUFS - Queue is full.
*/
int ia_css_eventq_send(
ia_css_queue_t *eventq_handle,
diff --git a/drivers/staging/media/atomisp/pci/runtime/eventq/src/eventq.c b/drivers/staging/media/atomisp/pci/runtime/eventq/src/eventq.c
index 0460f102d36f..df75cef46a51 100644
--- a/drivers/staging/media/atomisp/pci/runtime/eventq/src/eventq.c
+++ b/drivers/staging/media/atomisp/pci/runtime/eventq/src/eventq.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -19,8 +20,6 @@
#include "ia_css_event.h" /* ia_css_event_encode()
ia_css_event_decode()
*/
-#include "platform_support.h" /* hrt_sleep() */
-
int ia_css_eventq_recv(
ia_css_queue_t *eventq_handle,
uint8_t *payload)
@@ -50,7 +49,7 @@ int ia_css_eventq_send(
{
u8 tmp[4];
u32 sw_event;
- int error = ENOSYS;
+ int error = -ENOSYS;
/*
* Encode the queue type, the thread ID and
@@ -65,13 +64,13 @@ int ia_css_eventq_send(
/* queue the software event (busy-waiting) */
for ( ; ; ) {
error = ia_css_queue_enqueue(eventq_handle, sw_event);
- if (error != ENOBUFS) {
+ if (error != -ENOBUFS) {
/* We were able to successfully send the event
or had a real failure. return the status*/
break;
}
/* Wait for the queue to be not full and try again*/
- hrt_sleep();
+ udelay(1);
}
return error;
}
diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h b/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h
index 613fa33ab930..31f01e0f58aa 100644
--- a/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h
+++ b/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -80,7 +81,7 @@ bool ia_css_frame_info_is_same_resolution(
* @param[in] info The frame attributes to be initialized
* @return The error code.
*/
-enum ia_css_err ia_css_frame_check_info(const struct ia_css_frame_info *info);
+int ia_css_frame_check_info(const struct ia_css_frame_info *info);
/*********************************************************************
**** Frame APIs
@@ -92,7 +93,7 @@ enum ia_css_err ia_css_frame_check_info(const struct ia_css_frame_info *info);
* @param[in] frame The frame attributes to be initialized
* @return The error code.
*/
-enum ia_css_err ia_css_frame_init_planes(struct ia_css_frame *frame);
+int ia_css_frame_init_planes(struct ia_css_frame *frame);
/* @brief Free an array of frames
*
@@ -114,7 +115,7 @@ void ia_css_frame_free_multiple(unsigned int num_frames,
* Allocate a frame using the given size in bytes.
* The frame structure is partially null initialized.
*/
-enum ia_css_err ia_css_frame_allocate_with_buffer_size(
+int ia_css_frame_allocate_with_buffer_size(
struct ia_css_frame **frame,
const unsigned int size_bytes,
const bool contiguous);
@@ -153,9 +154,9 @@ void ia_css_dma_configure_from_info(
* @param[in] in_res Resolution of input image
* @param[in] out_res Resolution of output image
* @param[out] crop_res Crop resolution of input image
- * @return Returns IA_CSS_SUCCESS or IA_CSS_ERR_INVALID_ARGUMENTS on error
+ * @return Returns 0 or -EINVAL on error
*/
-enum ia_css_err
+int
ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
const struct ia_css_resolution *out_res,
struct ia_css_resolution *crop_res);
diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame_comm.h b/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame_comm.h
index 8861d07193bd..ce6110efbfc9 100644
--- a/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame_comm.h
+++ b/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame_comm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -18,7 +19,7 @@
#include "type_support.h"
#include "platform_support.h"
#include "runtime/bufq/interface/ia_css_bufq_comm.h"
-#include <system_types.h> /* hrt_vaddress */
+#include <system_local.h> /* ia_css_ptr */
/*
* These structs are derived from structs defined in ia_css_types.h
@@ -83,7 +84,7 @@ struct ia_css_frame_sp_info {
struct ia_css_buffer_sp {
union {
- hrt_vaddress xmem_addr;
+ ia_css_ptr xmem_addr;
enum sh_css_queue_id queue_id;
} buf_src;
enum ia_css_buffer_type buf_type;
diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c
index fcd8b06034f2..10c4907187d9 100644
--- a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c
+++ b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,13 +13,15 @@
* more details.
*/
+#include "hmm.h"
+
#include "ia_css_frame.h"
#include <math_support.h>
#include "assert_support.h"
#include "ia_css_debug.h"
#include "isp.h"
#include "sh_css_internal.h"
-#include "memory_access.h"
+#include "atomisp_internal.h"
#define NV12_TILEY_TILE_WIDTH 128
#define NV12_TILEY_TILE_HEIGHT 32
@@ -67,9 +70,9 @@ static void frame_init_rgb_planes(struct ia_css_frame *frame,
static void frame_init_qplane6_planes(struct ia_css_frame *frame);
-static enum ia_css_err frame_allocate_buffer_data(struct ia_css_frame *frame);
+static int frame_allocate_buffer_data(struct ia_css_frame *frame);
-static enum ia_css_err frame_allocate_with_data(struct ia_css_frame **frame,
+static int frame_allocate_with_data(struct ia_css_frame **frame,
unsigned int width,
unsigned int height,
enum ia_css_frame_format format,
@@ -96,16 +99,16 @@ ia_css_elems_bytes_from_info(
void ia_css_frame_zero(struct ia_css_frame *frame)
{
assert(frame);
- mmgr_clear(frame->data, frame->data_bytes);
+ hmm_set(frame->data, 0, frame->data_bytes);
}
-enum ia_css_err ia_css_frame_allocate_from_info(struct ia_css_frame **frame,
+int ia_css_frame_allocate_from_info(struct ia_css_frame **frame,
const struct ia_css_frame_info *info)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if (!frame || !info)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_allocate_from_info() enter:\n");
err =
@@ -117,17 +120,17 @@ enum ia_css_err ia_css_frame_allocate_from_info(struct ia_css_frame **frame,
return err;
}
-enum ia_css_err ia_css_frame_allocate(struct ia_css_frame **frame,
+int ia_css_frame_allocate(struct ia_css_frame **frame,
unsigned int width,
unsigned int height,
enum ia_css_frame_format format,
unsigned int padded_width,
unsigned int raw_bit_depth)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if (!frame || width == 0 || height == 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_allocate() enter: width=%d, height=%d, format=%d, padded_width=%d, raw_bit_depth=%d\n",
@@ -136,7 +139,7 @@ enum ia_css_err ia_css_frame_allocate(struct ia_css_frame **frame,
err = frame_allocate_with_data(frame, width, height, format,
padded_width, raw_bit_depth, false);
- if ((*frame) && err == IA_CSS_SUCCESS)
+ if ((*frame) && err == 0)
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_allocate() leave: frame=%p, data(DDR address)=0x%x\n", *frame,
(*frame)->data);
@@ -148,13 +151,13 @@ enum ia_css_err ia_css_frame_allocate(struct ia_css_frame **frame,
return err;
}
-enum ia_css_err ia_css_frame_map(struct ia_css_frame **frame,
+int ia_css_frame_map(struct ia_css_frame **frame,
const struct ia_css_frame_info *info,
const void __user *data,
u16 attribute,
- void *context)
+ unsigned int pgnr)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame *me;
assert(frame);
@@ -162,20 +165,32 @@ enum ia_css_err ia_css_frame_map(struct ia_css_frame **frame,
/* Create the frame structure */
err = ia_css_frame_create_from_info(&me, info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
- if (err == IA_CSS_SUCCESS) {
- /* use mmgr_mmap to map */
- me->data = (ia_css_ptr) mmgr_mmap(data,
- me->data_bytes,
- attribute, context);
+ if (!err) {
+ if (pgnr < ((PAGE_ALIGN(me->data_bytes)) >> PAGE_SHIFT)) {
+ dev_err(atomisp_dev,
+ "user space memory size is less than the expected size..\n");
+ err = -ENOMEM;
+ goto error;
+ } else if (pgnr > ((PAGE_ALIGN(me->data_bytes)) >> PAGE_SHIFT)) {
+ dev_err(atomisp_dev,
+ "user space memory size is large than the expected size..\n");
+ err = -ENOMEM;
+ goto error;
+ }
+
+ me->data = hmm_alloc(me->data_bytes, HMM_BO_USER, 0, data,
+ attribute & ATOMISP_MAP_FLAG_CACHED);
+
if (me->data == mmgr_NULL)
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
- if (err != IA_CSS_SUCCESS) {
- sh_css_free(me);
+error:
+ if (err) {
+ kvfree(me);
me = NULL;
}
@@ -184,10 +199,10 @@ enum ia_css_err ia_css_frame_map(struct ia_css_frame **frame,
return err;
}
-enum ia_css_err ia_css_frame_create_from_info(struct ia_css_frame **frame,
+int ia_css_frame_create_from_info(struct ia_css_frame **frame,
const struct ia_css_frame_info *info)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame *me;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
@@ -195,7 +210,7 @@ enum ia_css_err ia_css_frame_create_from_info(struct ia_css_frame **frame,
if (!frame || !info) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_create_from_info() leave: invalid arguments\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
me = frame_create(info->res.width,
@@ -208,13 +223,13 @@ enum ia_css_err ia_css_frame_create_from_info(struct ia_css_frame **frame,
if (!me) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_create_from_info() leave: frame create failed\n");
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
}
err = ia_css_frame_init_planes(me);
- if (err != IA_CSS_SUCCESS) {
- sh_css_free(me);
+ if (err) {
+ kvfree(me);
me = NULL;
}
@@ -226,18 +241,18 @@ enum ia_css_err ia_css_frame_create_from_info(struct ia_css_frame **frame,
return err;
}
-enum ia_css_err ia_css_frame_set_data(struct ia_css_frame *frame,
+int ia_css_frame_set_data(struct ia_css_frame *frame,
const ia_css_ptr mapped_data,
size_t data_bytes)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_set_data() enter:\n");
if (!frame) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_set_data() leave: NULL frame\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* If we are setting a valid data.
@@ -247,7 +262,7 @@ enum ia_css_err ia_css_frame_set_data(struct ia_css_frame *frame,
if ((mapped_data != mmgr_NULL) && (frame->data_bytes > data_bytes)) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_frame_set_data() leave: invalid arguments\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
frame->data = mapped_data;
@@ -257,18 +272,17 @@ enum ia_css_err ia_css_frame_set_data(struct ia_css_frame *frame,
return err;
}
-enum ia_css_err ia_css_frame_allocate_contiguous(struct ia_css_frame **frame,
+int ia_css_frame_allocate_contiguous(struct ia_css_frame **frame,
unsigned int width,
unsigned int height,
enum ia_css_frame_format format,
unsigned int padded_width,
unsigned int raw_bit_depth)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_frame_allocate_contiguous() "
- "enter: width=%d, height=%d, format=%d, padded_width=%d, raw_bit_depth=%d\n",
+ "ia_css_frame_allocate_contiguous() enter: width=%d, height=%d, format=%d, padded_width=%d, raw_bit_depth=%d\n",
width, height, format, padded_width, raw_bit_depth);
err = frame_allocate_with_data(frame, width, height, format,
@@ -281,11 +295,11 @@ enum ia_css_err ia_css_frame_allocate_contiguous(struct ia_css_frame **frame,
return err;
}
-enum ia_css_err ia_css_frame_allocate_contiguous_from_info(
+int ia_css_frame_allocate_contiguous_from_info(
struct ia_css_frame **frame,
const struct ia_css_frame_info *info)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(frame);
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
@@ -307,7 +321,7 @@ void ia_css_frame_free(struct ia_css_frame *frame)
if (frame) {
hmm_free(frame->data);
- sh_css_free(frame);
+ kvfree(frame);
}
IA_CSS_LEAVE_PRIVATE("void");
@@ -317,15 +331,15 @@ void ia_css_frame_free(struct ia_css_frame *frame)
** Module public functions
**************************************************************************/
-enum ia_css_err ia_css_frame_check_info(const struct ia_css_frame_info *info)
+int ia_css_frame_check_info(const struct ia_css_frame_info *info)
{
assert(info);
if (info->res.width == 0 || info->res.height == 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
- return IA_CSS_SUCCESS;
+ return -EINVAL;
+ return 0;
}
-enum ia_css_err ia_css_frame_init_planes(struct ia_css_frame *frame)
+int ia_css_frame_init_planes(struct ia_css_frame *frame)
{
assert(frame);
@@ -430,9 +444,9 @@ enum ia_css_err ia_css_frame_init_planes(struct ia_css_frame *frame)
frame->planes.binary.size = 0;
break;
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
void ia_css_frame_info_set_width(struct ia_css_frame_info *info,
@@ -517,27 +531,27 @@ void ia_css_frame_free_multiple(unsigned int num_frames,
}
}
-enum ia_css_err ia_css_frame_allocate_with_buffer_size(
+int ia_css_frame_allocate_with_buffer_size(
struct ia_css_frame **frame,
const unsigned int buffer_size_bytes,
const bool contiguous)
{
/* AM: Body coppied from frame_allocate_with_data(). */
- enum ia_css_err err;
+ int err;
struct ia_css_frame *me = frame_create(0, 0,
IA_CSS_FRAME_FORMAT_NUM,/* Not valid format yet */
0, 0, contiguous, false);
if (!me)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
/* Get the data size */
me->data_bytes = buffer_size_bytes;
err = frame_allocate_buffer_data(me);
- if (err != IA_CSS_SUCCESS) {
- sh_css_free(me);
+ if (err) {
+ kvfree(me);
me = NULL;
}
@@ -782,22 +796,22 @@ static void frame_init_qplane6_planes(struct ia_css_frame *frame)
return;
}
-static enum ia_css_err frame_allocate_buffer_data(struct ia_css_frame *frame)
+static int frame_allocate_buffer_data(struct ia_css_frame *frame)
{
#ifdef ISP2401
IA_CSS_ENTER_LEAVE_PRIVATE("frame->data_bytes=%d\n", frame->data_bytes);
#endif
- frame->data = mmgr_alloc_attr(frame->data_bytes,
- frame->contiguous ?
- MMGR_ATTRIBUTE_CONTIGUOUS :
- MMGR_ATTRIBUTE_DEFAULT);
+ frame->data = hmm_alloc(frame->data_bytes,
+ HMM_BO_PRIVATE, 0, NULL,
+ frame->contiguous ?
+ ATOMISP_MAP_FLAG_CONTIGUOUS : 0);
if (frame->data == mmgr_NULL)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
- return IA_CSS_SUCCESS;
+ return -ENOMEM;
+ return 0;
}
-static enum ia_css_err frame_allocate_with_data(struct ia_css_frame **frame,
+static int frame_allocate_with_data(struct ia_css_frame **frame,
unsigned int width,
unsigned int height,
enum ia_css_frame_format format,
@@ -805,7 +819,7 @@ static enum ia_css_err frame_allocate_with_data(struct ia_css_frame **frame,
unsigned int raw_bit_depth,
bool contiguous)
{
- enum ia_css_err err;
+ int err;
struct ia_css_frame *me = frame_create(width,
height,
format,
@@ -815,15 +829,15 @@ static enum ia_css_err frame_allocate_with_data(struct ia_css_frame **frame,
true);
if (!me)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
err = ia_css_frame_init_planes(me);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
err = frame_allocate_buffer_data(me);
- if (err != IA_CSS_SUCCESS) {
- sh_css_free(me);
+ if (err) {
+ kvfree(me);
#ifndef ISP2401
return err;
#else
@@ -844,7 +858,7 @@ static struct ia_css_frame *frame_create(unsigned int width,
bool contiguous,
bool valid)
{
- struct ia_css_frame *me = sh_css_malloc(sizeof(*me));
+ struct ia_css_frame *me = kvmalloc(sizeof(*me), GFP_KERNEL);
if (!me)
return NULL;
@@ -919,7 +933,7 @@ void ia_css_resolution_to_sp_resolution(
}
/* ISP2401 */
-enum ia_css_err
+int
ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
const struct ia_css_resolution *out_res,
struct ia_css_resolution *crop_res) {
@@ -927,7 +941,7 @@ ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
u32 in_ratio, out_ratio;
if ((!in_res) || (!out_res) || (!crop_res))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
IA_CSS_ENTER_PRIVATE("in(%ux%u) -> out(%ux%u)", in_res->width,
in_res->height, out_res->width, out_res->height);
@@ -936,11 +950,11 @@ ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
|| (in_res->height == 0)
|| (out_res->width == 0)
|| (out_res->height == 0))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if ((out_res->width > in_res->width) ||
(out_res->height > in_res->height))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* If aspect ratio (width/height) of out_res is higher than the aspect
* ratio of the in_res, then we crop vertically, otherwise we crop
@@ -985,5 +999,5 @@ ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
IA_CSS_LEAVE_PRIVATE("in(%ux%u) -> out(%ux%u)", crop_res->width,
crop_res->height, out_res->width, out_res->height);
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/runtime/ifmtr/interface/ia_css_ifmtr.h b/drivers/staging/media/atomisp/pci/runtime/ifmtr/interface/ia_css_ifmtr.h
index d4b0b2361176..2c440feec3ce 100644
--- a/drivers/staging/media/atomisp/pci/runtime/ifmtr/interface/ia_css_ifmtr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/ifmtr/interface/ia_css_ifmtr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -27,7 +28,7 @@ unsigned int ia_css_ifmtr_lines_needed_for_bayer_order(
unsigned int ia_css_ifmtr_columns_needed_for_bayer_order(
const struct ia_css_stream_config *config);
-enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config,
+int ia_css_ifmtr_configure(struct ia_css_stream_config *config,
struct ia_css_binary *binary);
#endif /* __IA_CSS_IFMTR_H__ */
diff --git a/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c b/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c
index 7a18eae8c638..89cded6b6e2b 100644
--- a/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c
+++ b/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -28,12 +29,12 @@
/************************************************************
* Static functions declarations
************************************************************/
-static enum ia_css_err ifmtr_start_column(
+static int ifmtr_start_column(
const struct ia_css_stream_config *config,
unsigned int bin_in,
unsigned int *start_column);
-static enum ia_css_err ifmtr_input_start_line(
+static int ifmtr_input_start_line(
const struct ia_css_stream_config *config,
unsigned int bin_in,
unsigned int *start_line);
@@ -71,7 +72,7 @@ unsigned int ia_css_ifmtr_columns_needed_for_bayer_order(
return 0;
}
-enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config,
+int ia_css_ifmtr_configure(struct ia_css_stream_config *config,
struct ia_css_binary *binary)
{
unsigned int start_line, start_column = 0,
@@ -97,7 +98,7 @@ enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config,
left_padding = 0;
input_formatter_cfg_t if_a_config, if_b_config;
enum atomisp_input_format input_format;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
u8 if_config_index;
/* Determine which input formatter config set is targeted. */
@@ -142,10 +143,10 @@ enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config,
* columns.
*/
err = ifmtr_input_start_line(config, cropped_height, &start_line);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = ifmtr_start_column(config, cropped_width, &start_column);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
if (config->left_padding == -1)
@@ -358,7 +359,7 @@ enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config,
break;
}
if (width_a == 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (two_ppc)
left_padding /= 2;
@@ -459,7 +460,7 @@ enum ia_css_err ia_css_ifmtr_configure(struct ia_css_stream_config *config,
}
}
- return IA_CSS_SUCCESS;
+ return 0;
}
bool ifmtr_set_if_blocking_mode_reset = true;
@@ -496,7 +497,7 @@ static void ifmtr_set_if_blocking_mode(
return;
}
-static enum ia_css_err ifmtr_start_column(
+static int ifmtr_start_column(
const struct ia_css_stream_config *config,
unsigned int bin_in,
unsigned int *start_column)
@@ -505,7 +506,7 @@ static enum ia_css_err ifmtr_start_column(
for_bayer = ia_css_ifmtr_columns_needed_for_bayer_order(config);
if (bin_in + 2 * for_bayer > in)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* On the hardware, we want to use the middle of the input, so we
* divide the start column by 2. */
@@ -519,10 +520,10 @@ static enum ia_css_err ifmtr_start_column(
*/
start += for_bayer;
*start_column = start;
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err ifmtr_input_start_line(
+static int ifmtr_input_start_line(
const struct ia_css_stream_config *config,
unsigned int bin_in,
unsigned int *start_line)
@@ -531,7 +532,7 @@ static enum ia_css_err ifmtr_input_start_line(
for_bayer = ia_css_ifmtr_lines_needed_for_bayer_order(config);
if (bin_in + 2 * for_bayer > in)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* On the hardware, we want to use the middle of the input, so we
* divide the start line by 2. On the simulator, we cannot handle extra
@@ -546,7 +547,7 @@ static enum ia_css_err ifmtr_input_start_line(
/* now we add the one line (if needed) to correct for the bayer order */
start += for_bayer;
*start_line = start;
- return IA_CSS_SUCCESS;
+ return 0;
}
#endif
diff --git a/drivers/staging/media/atomisp/pci/runtime/inputfifo/interface/ia_css_inputfifo.h b/drivers/staging/media/atomisp/pci/runtime/inputfifo/interface/ia_css_inputfifo.h
index d2dd231b6296..7950c5c36693 100644
--- a/drivers/staging/media/atomisp/pci/runtime/inputfifo/interface/ia_css_inputfifo.h
+++ b/drivers/staging/media/atomisp/pci/runtime/inputfifo/interface/ia_css_inputfifo.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/inputfifo/src/inputfifo.c b/drivers/staging/media/atomisp/pci/runtime/inputfifo/src/inputfifo.c
index e5a339fb52f2..38712530f566 100644
--- a/drivers/staging/media/atomisp/pci/runtime/inputfifo/src/inputfifo.c
+++ b/drivers/staging/media/atomisp/pci/runtime/inputfifo/src/inputfifo.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -103,7 +104,7 @@ static inline void
_sh_css_fifo_snd(unsigned int token)
{
while (!can_event_send_token(STR2MIPI_EVENT_ID))
- hrt_sleep();
+ udelay(1);
event_send_token(STR2MIPI_EVENT_ID, token);
return;
}
diff --git a/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param.h b/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param.h
index 2769183a8956..0ea5d6fdc88b 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -31,7 +32,7 @@ ia_css_isp_param_set_css_mem_init(
struct ia_css_isp_param_css_segments *mem_init,
enum ia_css_param_class pclass,
enum ia_css_isp_memories mem,
- hrt_vaddress address, size_t size);
+ ia_css_ptr address, size_t size);
void
ia_css_isp_param_set_isp_mem_init(
@@ -67,7 +68,7 @@ ia_css_init_memory_interface(
const struct ia_css_isp_param_css_segments *css_params);
/* Allocate memory parameters */
-enum ia_css_err
+int
ia_css_isp_param_allocate_isp_parameters(
struct ia_css_isp_param_host_segments *mem_params,
struct ia_css_isp_param_css_segments *css_params,
@@ -88,7 +89,7 @@ ia_css_isp_param_load_fw_params(
bool init);
/* Copy host parameter images to ddr */
-enum ia_css_err
+int
ia_css_isp_param_copy_isp_mem_if_to_ddr(
struct ia_css_isp_param_css_segments *ddr,
const struct ia_css_isp_param_host_segments *host,
diff --git a/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h b/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h
index 5d23b2f57719..8cdeae98bda8 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c b/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c
index 443e412d05ad..e861777385a0 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -12,7 +13,8 @@
* more details.
*/
-#include "memory_access.h"
+#include "hmm.h"
+
#include "ia_css_pipeline.h"
#include "ia_css_isp_param.h"
@@ -34,7 +36,7 @@ ia_css_isp_param_set_css_mem_init(
struct ia_css_isp_param_css_segments *mem_init,
enum ia_css_param_class pclass,
enum ia_css_isp_memories mem,
- hrt_vaddress address, size_t size)
+ ia_css_ptr address, size_t size)
{
mem_init->params[pclass][mem].address = address;
mem_init->params[pclass][mem].size = (uint32_t)size;
@@ -100,12 +102,12 @@ ia_css_init_memory_interface(
}
}
-enum ia_css_err
+int
ia_css_isp_param_allocate_isp_parameters(
struct ia_css_isp_param_host_segments *mem_params,
struct ia_css_isp_param_css_segments *css_params,
const struct ia_css_isp_param_isp_segments *mem_initializers) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int mem, pclass;
pclass = IA_CSS_PARAM_CLASS_PARAM;
@@ -121,15 +123,17 @@ ia_css_isp_param_allocate_isp_parameters(
css_params->params[pclass][mem].size = size;
css_params->params[pclass][mem].address = 0x0;
if (size) {
- mem_params->params[pclass][mem].address = sh_css_calloc(1, size);
+ mem_params->params[pclass][mem].address = kvcalloc(1,
+ size,
+ GFP_KERNEL);
if (!mem_params->params[pclass][mem].address) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto cleanup;
}
if (pclass != IA_CSS_PARAM_CLASS_PARAM) {
- css_params->params[pclass][mem].address = mmgr_malloc(size);
+ css_params->params[pclass][mem].address = hmm_alloc(size, HMM_BO_PRIVATE, 0, NULL, 0);
if (!css_params->params[pclass][mem].address) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto cleanup;
}
}
@@ -152,7 +156,7 @@ ia_css_isp_param_destroy_isp_parameters(
for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) {
for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
if (mem_params->params[pclass][mem].address)
- sh_css_free(mem_params->params[pclass][mem].address);
+ kvfree(mem_params->params[pclass][mem].address);
if (css_params->params[pclass][mem].address)
hmm_free(css_params->params[pclass][mem].address);
mem_params->params[pclass][mem].address = NULL;
@@ -177,7 +181,7 @@ ia_css_isp_param_load_fw_params(
}
}
-enum ia_css_err
+int
ia_css_isp_param_copy_isp_mem_if_to_ddr(
struct ia_css_isp_param_css_segments *ddr,
const struct ia_css_isp_param_host_segments *host,
@@ -187,16 +191,16 @@ ia_css_isp_param_copy_isp_mem_if_to_ddr(
for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++)
{
size_t size = host->params[pclass][mem].size;
- hrt_vaddress ddr_mem_ptr = ddr->params[pclass][mem].address;
+ ia_css_ptr ddr_mem_ptr = ddr->params[pclass][mem].address;
char *host_mem_ptr = host->params[pclass][mem].address;
if (size != ddr->params[pclass][mem].size)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
if (!size)
continue;
- mmgr_store(ddr_mem_ptr, host_mem_ptr, size);
+ hmm_store(ddr_mem_ptr, host_mem_ptr, size);
}
- return IA_CSS_SUCCESS;
+ return 0;
}
void
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h b/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h
index e2aca35452c0..f975429b8705 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -48,10 +49,10 @@ enum mipi_port_id ia_css_isys_port_to_mipi_port(
* @param[in] port CSI port
* @param[in] isys_stream_id Stream handle generated with ia_css_isys_generate_stream_id()
* Must be lower than SH_CSS_MAX_ISYS_CHANNEL_NODES
- * @return IA_CSS_SUCCESS if successful, IA_CSS_ERR_INTERNAL_ERROR if
+ * @return 0 if successful, -EINVAL if
* there is already a stream registered with the same handle
*/
-enum ia_css_err ia_css_isys_csi_rx_register_stream(
+int ia_css_isys_csi_rx_register_stream(
enum mipi_port_id port,
uint32_t isys_stream_id);
@@ -63,14 +64,14 @@ enum ia_css_err ia_css_isys_csi_rx_register_stream(
* @param[in] port CSI port
* @param[in] isys_stream_id Stream handle generated with ia_css_isys_generate_stream_id()
* Must be lower than SH_CSS_MAX_ISYS_CHANNEL_NODES
- * @return IA_CSS_SUCCESS if successful, IA_CSS_ERR_INTERNAL_ERROR if
+ * @return 0 if successful, -EINVAL if
* there is no stream registered with that handle
*/
-enum ia_css_err ia_css_isys_csi_rx_unregister_stream(
+int ia_css_isys_csi_rx_unregister_stream(
enum mipi_port_id port,
uint32_t isys_stream_id);
-enum ia_css_err ia_css_isys_convert_compressed_format(
+int ia_css_isys_convert_compressed_format(
struct ia_css_csi2_compression *comp,
struct input_system_cfg_s *cfg);
unsigned int ia_css_csi2_calculate_input_system_alignment(
@@ -107,7 +108,7 @@ unsigned int ia_css_isys_rx_translate_irq_infos(unsigned int bits);
* This is normally done by the sensor, but when using the input fifo, this
* format type must be sumitted correctly by the application.
*/
-enum ia_css_err ia_css_isys_convert_stream_format_to_mipi_format(
+int ia_css_isys_convert_stream_format_to_mipi_format(
enum atomisp_input_format input_format,
mipi_predictor_t compression,
unsigned int *fmt_type);
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys_comm.h b/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys_comm.h
index 6ad7a0cd5146..6f1a86c81d7c 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys_comm.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys_comm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.c
index 8f2ce2c057eb..5a44d8f6c196 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -126,11 +127,11 @@ void ia_css_isys_csi_rx_lut_rmgr_release(
}
}
-enum ia_css_err ia_css_isys_csi_rx_register_stream(
+int ia_css_isys_csi_rx_register_stream(
enum mipi_port_id port,
uint32_t isys_stream_id)
{
- enum ia_css_err retval = IA_CSS_ERR_INTERNAL_ERROR;
+ int retval = -EINVAL;
if ((port < N_INPUT_SYSTEM_CSI_PORT) &&
(isys_stream_id < SH_CSS_MAX_ISYS_CHANNEL_NODES)) {
@@ -140,17 +141,17 @@ enum ia_css_err ia_css_isys_csi_rx_register_stream(
if (bitop_getbit(pipe_io_status->active[port], isys_stream_id) == 0) {
bitop_setbit(pipe_io_status->active[port], isys_stream_id);
pipe_io_status->running[port] = 0;
- retval = IA_CSS_SUCCESS;
+ retval = 0;
}
}
return retval;
}
-enum ia_css_err ia_css_isys_csi_rx_unregister_stream(
+int ia_css_isys_csi_rx_unregister_stream(
enum mipi_port_id port,
uint32_t isys_stream_id)
{
- enum ia_css_err retval = IA_CSS_ERR_INTERNAL_ERROR;
+ int retval = -EINVAL;
if ((port < N_INPUT_SYSTEM_CSI_PORT) &&
(isys_stream_id < SH_CSS_MAX_ISYS_CHANNEL_NODES)) {
@@ -159,7 +160,7 @@ enum ia_css_err ia_css_isys_csi_rx_unregister_stream(
pipe_io_status = ia_css_pipeline_get_pipe_io_status();
if (bitop_getbit(pipe_io_status->active[port], isys_stream_id) == 1) {
bitop_clearbit(pipe_io_status->active[port], isys_stream_id);
- retval = IA_CSS_SUCCESS;
+ retval = 0;
}
}
return retval;
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.h b/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.h
index 79d7c4b29bf4..11f730dc1c08 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/csi_rx_rmgr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.c
index 9055ed387673..9710493c47ac 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.h b/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.h
index 7155e2c6e05c..7c754ec7224a 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/ibuf_ctrl_rmgr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.c
index 930fa7a0ff53..68baec78b1c4 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.h b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.h
index e3d07ac390fc..88c3d5581999 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_dma_rmgr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_init.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_init.c
index b923233ec5b0..de442f1fa6ba 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_init.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_init.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.c
index 53355a55d05d..bc4a2ff3c0fc 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.h b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.h
index b55cf02c8bce..78a4c867fb1b 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/isys_stream2mmio_rmgr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/rx.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/rx.c
index 43665ddff8ea..4f0dcdfa13be 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/rx.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/rx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -216,7 +217,7 @@ void ia_css_isys_rx_clear_irq_info(enum mipi_port_id port,
}
#endif /* #if !defined(USE_INPUT_SYSTEM_VERSION_2401) */
-enum ia_css_err ia_css_isys_convert_stream_format_to_mipi_format(
+int ia_css_isys_convert_stream_format_to_mipi_format(
enum atomisp_input_format input_format,
mipi_predictor_t compression,
unsigned int *fmt_type)
@@ -254,9 +255,9 @@ enum ia_css_err ia_css_isys_convert_stream_format_to_mipi_format(
*fmt_type = 16;
break;
default:
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
/*
* This mapping comes from the Arasan CSS function spec
@@ -356,9 +357,9 @@ enum ia_css_err ia_css_isys_convert_stream_format_to_mipi_format(
case ATOMISP_INPUT_FORMAT_YUV420_16:
case ATOMISP_INPUT_FORMAT_YUV422_16:
default:
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
#if defined(USE_INPUT_SYSTEM_VERSION_2401)
@@ -379,11 +380,11 @@ static mipi_predictor_t sh_css_csi2_compression_type_2_mipi_predictor(
return predictor;
}
-enum ia_css_err ia_css_isys_convert_compressed_format(
+int ia_css_isys_convert_compressed_format(
struct ia_css_csi2_compression *comp,
struct input_system_cfg_s *cfg)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(comp);
assert(cfg);
@@ -414,7 +415,7 @@ enum ia_css_err ia_css_isys_convert_compressed_format(
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_8_10;
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
} else if (comp->uncompressed_bits_per_pixel ==
UNCOMPRESSED_BITS_PER_PIXEL_12) {
@@ -429,10 +430,10 @@ enum ia_css_err ia_css_isys_convert_compressed_format(
cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_8_12;
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
} else
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
cfg->csi_port_attr.comp_predictor =
sh_css_csi2_compression_type_2_mipi_predictor(comp->type);
cfg->csi_port_attr.comp_enable = true;
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
index 9a795a21d3e6..b3c6831cb9e3 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,6 +13,8 @@
* more details.
*/
+#include <linux/string.h> /* for memcpy() */
+
#include "system_global.h"
#ifdef USE_INPUT_SYSTEM_VERSION_2401
@@ -19,7 +22,6 @@
#include "ia_css_isys.h"
#include "ia_css_debug.h"
#include "math_support.h"
-#include "string_support.h"
#include "virtual_isys.h"
#include "isp.h"
#include "sh_css_defs.h"
@@ -649,14 +651,8 @@ static bool calculate_tpg_cfg(
input_system_cfg_t *isys_cfg,
pixelgen_tpg_cfg_t *cfg)
{
- (void)channel;
- (void)input_port;
+ memcpy(cfg, &isys_cfg->tpg_port_attr, sizeof(pixelgen_tpg_cfg_t));
- memcpy_s(
- (void *)cfg,
- sizeof(pixelgen_tpg_cfg_t),
- (void *)(&isys_cfg->tpg_port_attr),
- sizeof(pixelgen_tpg_cfg_t));
return true;
}
@@ -666,14 +662,8 @@ static bool calculate_prbs_cfg(
input_system_cfg_t *isys_cfg,
pixelgen_prbs_cfg_t *cfg)
{
- (void)channel;
- (void)input_port;
+ memcpy(cfg, &isys_cfg->prbs_port_attr, sizeof(pixelgen_prbs_cfg_t));
- memcpy_s(
- (void *)cfg,
- sizeof(pixelgen_prbs_cfg_t),
- (void *)(&isys_cfg->prbs_port_attr),
- sizeof(pixelgen_prbs_cfg_t));
return true;
}
@@ -691,12 +681,10 @@ static bool calculate_be_cfg(
bool metadata,
csi_rx_backend_cfg_t *cfg)
{
- memcpy_s(
- (void *)(&cfg->lut_entry),
- sizeof(csi_rx_backend_lut_entry_t),
- metadata ? (void *)(&input_port->metadata.backend_lut_entry) :
- (void *)(&input_port->csi_rx.backend_lut_entry),
- sizeof(csi_rx_backend_lut_entry_t));
+ memcpy(&cfg->lut_entry,
+ metadata ? &input_port->metadata.backend_lut_entry :
+ &input_port->csi_rx.backend_lut_entry,
+ sizeof(csi_rx_backend_lut_entry_t));
cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id;
if (metadata) {
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.h b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.h
index b675907791ad..fbdbca0cfcc8 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h
index 6a41efee5635..18a7d18e197e 100644
--- a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h
+++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -56,8 +57,7 @@ struct ia_css_pipeline {
u32 pipe_qos_config;
};
-#define DEFAULT_PIPELINE \
-(struct ia_css_pipeline) { \
+#define DEFAULT_PIPELINE { \
.pipe_id = IA_CSS_PIPE_ID_PREVIEW, \
.in_frame = DEFAULT_FRAME, \
.out_frame = {DEFAULT_FRAME}, \
@@ -94,13 +94,13 @@ void ia_css_pipeline_init(void);
* @param[out] pipeline structure to be initialized with defaults
* @param[in] pipe_id
* @param[in] pipe_num Number that uniquely identifies a pipeline.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* Initializes the pipeline structure with a set of default values.
* This API is expected to be used when a pipeline structure is allocated
* externally and needs sane defaults
*/
-enum ia_css_err ia_css_pipeline_create(
+int ia_css_pipeline_create(
struct ia_css_pipeline *pipeline,
enum ia_css_pipe_id pipe_id,
unsigned int pipe_num,
@@ -127,10 +127,10 @@ void ia_css_pipeline_start(enum ia_css_pipe_id pipe_id,
/* @brief Request to stop a pipeline
*
* @param[in] pipeline
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline);
+int ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline);
/* @brief Check whether pipeline has stopped
*
@@ -153,13 +153,13 @@ void ia_css_pipeline_clean(struct ia_css_pipeline *pipeline);
* @param pipeline Pointer to the pipeline to be added to.
* @param[in] stage_desc The description of the stage
* @param[out] stage The successor of the stage.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* Add a new stage to a non-NULL pipeline.
* The stage consists of an ISP binary or firmware and input and output
* arguments.
*/
-enum ia_css_err ia_css_pipeline_create_and_add_stage(
+int ia_css_pipeline_create_and_add_stage(
struct ia_css_pipeline *pipeline,
struct ia_css_pipeline_stage_desc *stage_desc,
struct ia_css_pipeline_stage **stage);
@@ -177,10 +177,10 @@ void ia_css_pipeline_finalize_stages(struct ia_css_pipeline *pipeline,
/* @brief gets a stage from the pipeline
*
* @param[in] pipeline
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline,
+int ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline,
int mode,
struct ia_css_pipeline_stage **stage);
@@ -190,10 +190,10 @@ enum ia_css_err ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline,
* @param[in] fw_handle
* @param[out] stage Pointer to Stage
*
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline
+int ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline
*pipeline,
u32 fw_handle,
struct ia_css_pipeline_stage **stage);
@@ -204,10 +204,10 @@ enum ia_css_err ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline
* @param[in] stage_num
* @param[out] fw_handle
*
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline
+int ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline
*pipeline,
u32 stage_num,
uint32_t *fw_handle);
@@ -215,10 +215,10 @@ enum ia_css_err ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline
/* @brief gets the output stage from the pipeline
*
* @param[in] pipeline
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
*/
-enum ia_css_err ia_css_pipeline_get_output_stage(
+int ia_css_pipeline_get_output_stage(
struct ia_css_pipeline *pipeline,
int mode,
struct ia_css_pipeline_stage **stage);
diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline_common.h b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline_common.h
index b96a5b146096..cc44f03c3b34 100644
--- a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline_common.h
+++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline_common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
index 8b9982de8deb..4b8e85bc2122 100644
--- a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
+++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -12,11 +13,12 @@
* more details.
*/
+#include "hmm.h"
+
#include "ia_css_debug.h"
#include "sw_event_global.h" /* encode_sw_event */
#include "sp.h" /* cnd_sp_irq_enable() */
#include "assert_support.h"
-#include "memory_access.h"
#include "sh_css_sp.h"
#include "ia_css_pipeline.h"
#include "ia_css_isp_param.h"
@@ -45,7 +47,7 @@ static void pipeline_init_defaults(
unsigned int dvs_frame_delay);
static void pipeline_stage_destroy(struct ia_css_pipeline_stage *stage);
-static enum ia_css_err pipeline_stage_create(
+static int pipeline_stage_create(
struct ia_css_pipeline_stage_desc *stage_desc,
struct ia_css_pipeline_stage **new_stage);
static void ia_css_pipeline_set_zoom_stage(struct ia_css_pipeline *pipeline);
@@ -60,7 +62,7 @@ void ia_css_pipeline_init(void)
pipeline_init_sp_thread_map();
}
-enum ia_css_err ia_css_pipeline_create(
+int ia_css_pipeline_create(
struct ia_css_pipeline *pipeline,
enum ia_css_pipe_id pipe_id,
unsigned int pipe_num,
@@ -70,14 +72,14 @@ enum ia_css_err ia_css_pipeline_create(
IA_CSS_ENTER_PRIVATE("pipeline = %p, pipe_id = %d, pipe_num = %d, dvs_frame_delay = %d",
pipeline, pipe_id, pipe_num, dvs_frame_delay);
if (!pipeline) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
pipeline_init_defaults(pipeline, pipe_id, pipe_num, dvs_frame_delay);
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
void ia_css_pipeline_map(unsigned int pipe_num, bool map)
@@ -195,15 +197,15 @@ void ia_css_pipeline_dump_thread_map_info(void)
}
}
-enum ia_css_err ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline)
+int ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int thread_id;
assert(pipeline);
if (!pipeline)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_pipeline_request_stop() enter: pipeline=%p\n",
@@ -218,7 +220,7 @@ enum ia_css_err ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline)
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_pipeline_request_stop() leaving\n");
/* queues are invalid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
ia_css_bufq_enqueue_psys_event(IA_CSS_PSYS_SW_EVENT_STOP_STREAM,
(uint8_t)thread_id,
@@ -263,19 +265,19 @@ void ia_css_pipeline_clean(struct ia_css_pipeline *pipeline)
* @param pipeline Pointer to the pipeline to be added to.
* @param[in] stage_desc The description of the stage
* @param[out] stage The successor of the stage.
- * @return IA_CSS_SUCCESS or error code upon error.
+ * @return 0 or error code upon error.
*
* Add a new stage to a non-NULL pipeline.
* The stage consists of an ISP binary or firmware and input and
* output arguments.
*/
-enum ia_css_err ia_css_pipeline_create_and_add_stage(
+int ia_css_pipeline_create_and_add_stage(
struct ia_css_pipeline *pipeline,
struct ia_css_pipeline_stage_desc *stage_desc,
struct ia_css_pipeline_stage **stage)
{
struct ia_css_pipeline_stage *last, *new_stage = NULL;
- enum ia_css_err err;
+ int err;
/* other arguments can be NULL */
assert(pipeline);
@@ -289,7 +291,7 @@ enum ia_css_err ia_css_pipeline_create_and_add_stage(
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_pipeline_create_and_add_stage() done: Invalid args\n");
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
/* Find the last stage */
@@ -308,12 +310,12 @@ enum ia_css_err ia_css_pipeline_create_and_add_stage(
stage_desc->in_frame = last->args.out_frame[0];
if (!stage_desc->in_frame)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
/* Create the new stage */
err = pipeline_stage_create(stage_desc, &new_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_pipeline_create_and_add_stage() done: stage_create_failed\n");
return err;
@@ -330,7 +332,7 @@ enum ia_css_err ia_css_pipeline_create_and_add_stage(
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_pipeline_create_and_add_stage() done:\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
void ia_css_pipeline_finalize_stages(struct ia_css_pipeline *pipeline,
@@ -350,7 +352,7 @@ void ia_css_pipeline_finalize_stages(struct ia_css_pipeline *pipeline,
ia_css_pipeline_configure_inout_port(pipeline, continuous);
}
-enum ia_css_err ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline,
+int ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline,
int mode,
struct ia_css_pipeline_stage **stage)
{
@@ -363,13 +365,13 @@ enum ia_css_err ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline,
for (s = pipeline->stages; s; s = s->next) {
if (s->mode == mode) {
*stage = s;
- return IA_CSS_SUCCESS;
+ return 0;
}
}
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
-enum ia_css_err ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline
+int ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline
*pipeline,
u32 fw_handle,
struct ia_css_pipeline_stage **stage)
@@ -382,13 +384,13 @@ enum ia_css_err ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline
for (s = pipeline->stages; s; s = s->next) {
if ((s->firmware) && (s->firmware->handle == fw_handle)) {
*stage = s;
- return IA_CSS_SUCCESS;
+ return 0;
}
}
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
-enum ia_css_err ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline
+int ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline
*pipeline,
u32 stage_num,
uint32_t *fw_handle)
@@ -397,18 +399,18 @@ enum ia_css_err ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s()\n", __func__);
if ((!pipeline) || (!fw_handle))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
for (s = pipeline->stages; s; s = s->next) {
if ((s->stage_num == stage_num) && (s->firmware)) {
*fw_handle = s->firmware->handle;
- return IA_CSS_SUCCESS;
+ return 0;
}
}
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
-enum ia_css_err ia_css_pipeline_get_output_stage(
+int ia_css_pipeline_get_output_stage(
struct ia_css_pipeline *pipeline,
int mode,
struct ia_css_pipeline_stage **stage)
@@ -428,7 +430,7 @@ enum ia_css_err ia_css_pipeline_get_output_stage(
*stage = s;
}
if (*stage)
- return IA_CSS_SUCCESS;
+ return 0;
/* If no firmware, find binary in pipe */
return ia_css_pipeline_get_stage(pipeline, mode, stage);
}
@@ -511,7 +513,7 @@ static void pipeline_stage_destroy(struct ia_css_pipeline_stage *stage)
ia_css_frame_free(stage->args.out_vf_frame);
stage->args.out_vf_frame = NULL;
}
- sh_css_free(stage);
+ kvfree(stage);
}
static void pipeline_init_sp_thread_map(void)
@@ -566,11 +568,11 @@ static void pipeline_unmap_num_to_sp_thread(unsigned int pipe_num)
pipeline_sp_thread_list[thread_id] = PIPELINE_SP_THREAD_EMPTY_TOKEN;
}
-static enum ia_css_err pipeline_stage_create(
+static int pipeline_stage_create(
struct ia_css_pipeline_stage_desc *stage_desc,
struct ia_css_pipeline_stage **new_stage)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipeline_stage *stage = NULL;
struct ia_css_binary *binary;
struct ia_css_frame *vf_frame;
@@ -581,7 +583,7 @@ static enum ia_css_err pipeline_stage_create(
/* Verify input parameters*/
if (!(stage_desc->in_frame) && !(stage_desc->firmware)
&& (stage_desc->binary) && !(stage_desc->binary->online)) {
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto ERR;
}
@@ -592,12 +594,11 @@ static enum ia_css_err pipeline_stage_create(
out_frame[i] = stage_desc->out_frame[i];
}
- stage = sh_css_malloc(sizeof(*stage));
+ stage = kvzalloc(sizeof(*stage), GFP_KERNEL);
if (!stage) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
- memset(stage, 0, sizeof(*stage));
if (firmware) {
stage->binary = NULL;
@@ -627,7 +628,7 @@ static enum ia_css_err pipeline_stage_create(
&& (binary->out_frame_info[i].res.width)) {
err = ia_css_frame_allocate_from_info(&out_frame[i],
&binary->out_frame_info[i]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
stage->out_frame_allocated[i] = true;
}
@@ -641,7 +642,7 @@ static enum ia_css_err pipeline_stage_create(
) {
err = ia_css_frame_allocate_from_info(&vf_frame,
&binary->vf_frame_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
stage->vf_frame_allocated = true;
}
@@ -664,6 +665,8 @@ ERR:
return err;
}
+static const struct ia_css_frame ia_css_default_frame = DEFAULT_FRAME;
+
static void pipeline_init_defaults(
struct ia_css_pipeline *pipeline,
enum ia_css_pipe_id pipe_id,
@@ -676,10 +679,15 @@ static void pipeline_init_defaults(
pipeline->stages = NULL;
pipeline->stop_requested = false;
pipeline->current_stage = NULL;
- pipeline->in_frame = DEFAULT_FRAME;
+
+ memcpy(&pipeline->in_frame, &ia_css_default_frame,
+ sizeof(ia_css_default_frame));
+
for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
- pipeline->out_frame[i] = DEFAULT_FRAME;
- pipeline->vf_frame[i] = DEFAULT_FRAME;
+ memcpy(&pipeline->out_frame[i], &ia_css_default_frame,
+ sizeof(ia_css_default_frame));
+ memcpy(&pipeline->vf_frame[i], &ia_css_default_frame,
+ sizeof(ia_css_default_frame));
}
pipeline->num_execs = -1;
pipeline->acquire_isp_each_stage = true;
@@ -690,30 +698,30 @@ static void pipeline_init_defaults(
static void ia_css_pipeline_set_zoom_stage(struct ia_css_pipeline *pipeline)
{
struct ia_css_pipeline_stage *stage = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(pipeline);
if (pipeline->pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
/* in preview pipeline, vf_pp stage should do zoom */
err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_VF_PP, &stage);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
stage->enable_zoom = true;
} else if (pipeline->pipe_id == IA_CSS_PIPE_ID_CAPTURE) {
/* in capture pipeline, capture_pp stage should do zoom */
err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_CAPTURE_PP,
&stage);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
stage->enable_zoom = true;
} else if (pipeline->pipe_id == IA_CSS_PIPE_ID_VIDEO) {
/* in video pipeline, video stage should do zoom */
err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_VIDEO, &stage);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
stage->enable_zoom = true;
} else if (pipeline->pipe_id == IA_CSS_PIPE_ID_YUVPP) {
/* in yuvpp pipeline, first yuv_scaler stage should do zoom */
err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_CAPTURE_PP,
&stage);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
stage->enable_zoom = true;
}
}
diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue.h b/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue.h
index 6daeb060daf9..08112be4633f 100644
--- a/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue.h
+++ b/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -40,7 +41,7 @@ typedef struct ia_css_queue ia_css_queue_t;
* @param[out] qhandle. Handle to queue instance for use with API
* @param[in] desc. Descriptor with queue properties filled-in
* @return 0 - Successful init of local queue instance.
- * @return EINVAL - Invalid argument.
+ * @return -EINVAL - Invalid argument.
*
*/
int ia_css_queue_local_init(
@@ -52,7 +53,7 @@ int ia_css_queue_local_init(
* @param[out] qhandle. Handle to queue instance for use with API
* @param[in] desc. Descriptor with queue properties filled-in
* @return 0 - Successful init of remote queue instance.
- * @return EINVAL - Invalid argument.
+ * @return -EINVAL - Invalid argument.
*/
int ia_css_queue_remote_init(
ia_css_queue_t *qhandle,
@@ -72,8 +73,8 @@ int ia_css_queue_uninit(
* @param[in] qhandle. Handle to queue instance
* @param[in] item. Object to be enqueued.
* @return 0 - Successful enqueue.
- * @return EINVAL - Invalid argument.
- * @return ENOBUFS - Queue is full.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENOBUFS - Queue is full.
*
*/
int ia_css_queue_enqueue(
@@ -86,8 +87,8 @@ int ia_css_queue_enqueue(
* @param[out] item. Object to be dequeued into this item.
* @return 0 - Successful dequeue.
- * @return EINVAL - Invalid argument.
- * @return ENODATA - Queue is empty.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENODATA - Queue is empty.
*
*/
int ia_css_queue_dequeue(
@@ -99,8 +100,8 @@ int ia_css_queue_dequeue(
* @param[in] qhandle. Handle to queue instance
* @param[in] is_empty True if empty, False if not.
* @return 0 - Successful access state.
- * @return EINVAL - Invalid argument.
- * @return ENOSYS - Function not implemented.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENOSYS - Function not implemented.
*
*/
int ia_css_queue_is_empty(
@@ -112,8 +113,8 @@ int ia_css_queue_is_empty(
* @param[in] qhandle. Handle to queue instance
* @param[in] is_full True if Full, False if not.
* @return 0 - Successfully access state.
- * @return EINVAL - Invalid argument.
- * @return ENOSYS - Function not implemented.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENOSYS - Function not implemented.
*
*/
int ia_css_queue_is_full(
@@ -125,7 +126,7 @@ int ia_css_queue_is_full(
* @param[in] qhandle. Handle to queue instance
* @param[in] size Number of available elements in the queue
* @return 0 - Successfully access state.
- * @return EINVAL - Invalid argument.
+ * @return -EINVAL - Invalid argument.
*
*/
int ia_css_queue_get_used_space(
@@ -137,7 +138,7 @@ int ia_css_queue_get_used_space(
* @param[in] qhandle. Handle to queue instance
* @param[in] size Number of free elements in the queue
* @return 0 - Successfully access state.
- * @return EINVAL - Invalid argument.
+ * @return -EINVAL - Invalid argument.
*
*/
int ia_css_queue_get_free_space(
@@ -151,7 +152,7 @@ int ia_css_queue_get_free_space(
* starting from head of queue
* @param[in] element Value of element returned
* @return 0 - Successfully access state.
- * @return EINVAL - Invalid argument.
+ * @return -EINVAL - Invalid argument.
*
*/
int ia_css_queue_peek(
@@ -164,8 +165,8 @@ int ia_css_queue_peek(
* @param[in] qhandle. Handle to queue instance
* @param[out] size Size value to be returned here.
* @return 0 - Successful get size.
- * @return EINVAL - Invalid argument.
- * @return ENOSYS - Function not implemented.
+ * @return -EINVAL - Invalid argument.
+ * @return -ENOSYS - Function not implemented.
*
*/
int ia_css_queue_get_size(
diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue_comm.h b/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue_comm.h
index 87fa4288d9a6..1379ae8f8c01 100644
--- a/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue_comm.h
+++ b/drivers/staging/media/atomisp/pci/runtime/queue/interface/ia_css_queue_comm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c
index dd79c6f180af..aea6c66a3cee 100644
--- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c
+++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -28,7 +29,7 @@ int ia_css_queue_local_init(
if (NULL == qhandle || NULL == desc
|| NULL == desc->cb_elems || NULL == desc->cb_desc) {
/* Invalid parameters, return error*/
- return EINVAL;
+ return -EINVAL;
}
/* Mark the queue as Local */
@@ -48,7 +49,7 @@ int ia_css_queue_remote_init(
{
if (NULL == qhandle || NULL == desc) {
/* Invalid parameters, return error*/
- return EINVAL;
+ return -EINVAL;
}
/* Mark the queue as remote*/
@@ -72,7 +73,7 @@ int ia_css_queue_uninit(
ia_css_queue_t *qhandle)
{
if (!qhandle)
- return EINVAL;
+ return -EINVAL;
/* Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -90,7 +91,7 @@ int ia_css_queue_enqueue(
int error = 0;
if (!qhandle)
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -99,7 +100,7 @@ int ia_css_queue_enqueue(
*/
if (ia_css_circbuf_is_full(&qhandle->desc.cb_local)) {
/* Cannot push the element. Return*/
- return ENOBUFS;
+ return -ENOBUFS;
}
/* Push the element*/
@@ -117,7 +118,7 @@ int ia_css_queue_enqueue(
/* b. Operate on the queue */
if (ia_css_circbuf_desc_is_full(&cb_desc))
- return ENOBUFS;
+ return -ENOBUFS;
cb_elem.val = item;
@@ -149,7 +150,7 @@ int ia_css_queue_dequeue(
int error = 0;
if (!qhandle || NULL == item)
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -158,7 +159,7 @@ int ia_css_queue_dequeue(
*/
if (ia_css_circbuf_is_empty(&qhandle->desc.cb_local)) {
/* Nothing to pop. Return empty queue*/
- return ENODATA;
+ return -ENODATA;
}
*item = ia_css_circbuf_pop(&qhandle->desc.cb_local);
@@ -176,7 +177,7 @@ int ia_css_queue_dequeue(
/* b. Operate on the queue */
if (ia_css_circbuf_desc_is_empty(&cb_desc))
- return ENODATA;
+ return -ENODATA;
error = ia_css_queue_item_load(qhandle, cb_desc.start, &cb_elem);
if (error != 0)
@@ -206,7 +207,7 @@ int ia_css_queue_is_full(
int error = 0;
if ((!qhandle) || (!is_full))
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -230,7 +231,7 @@ int ia_css_queue_is_full(
return 0;
}
- return EINVAL;
+ return -EINVAL;
}
int ia_css_queue_get_free_space(
@@ -240,7 +241,7 @@ int ia_css_queue_get_free_space(
int error = 0;
if ((!qhandle) || (!size))
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -264,7 +265,7 @@ int ia_css_queue_get_free_space(
return 0;
}
- return EINVAL;
+ return -EINVAL;
}
int ia_css_queue_get_used_space(
@@ -274,7 +275,7 @@ int ia_css_queue_get_used_space(
int error = 0;
if ((!qhandle) || (!size))
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -298,7 +299,7 @@ int ia_css_queue_get_used_space(
return 0;
}
- return EINVAL;
+ return -EINVAL;
}
int ia_css_queue_peek(
@@ -310,7 +311,7 @@ int ia_css_queue_peek(
int error = 0;
if ((!qhandle) || (!element))
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -320,7 +321,7 @@ int ia_css_queue_peek(
/* Check if offset is valid */
num_elems = ia_css_circbuf_get_num_elems(&qhandle->desc.cb_local);
if (offset > num_elems)
- return EINVAL;
+ return -EINVAL;
*element = ia_css_circbuf_peek_from_start(&qhandle->desc.cb_local, (int)offset);
return 0;
@@ -339,7 +340,7 @@ int ia_css_queue_peek(
/* Check if offset is valid */
num_elems = ia_css_circbuf_desc_get_num_elems(&cb_desc);
if (offset > num_elems)
- return EINVAL;
+ return -EINVAL;
offset = OP_std_modadd(cb_desc.start, offset, cb_desc.size);
error = ia_css_queue_item_load(qhandle, (uint8_t)offset, &cb_elem);
@@ -350,7 +351,7 @@ int ia_css_queue_peek(
return 0;
}
- return EINVAL;
+ return -EINVAL;
}
int ia_css_queue_is_empty(
@@ -360,7 +361,7 @@ int ia_css_queue_is_empty(
int error = 0;
if ((!qhandle) || (!is_empty))
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
@@ -384,7 +385,7 @@ int ia_css_queue_is_empty(
return 0;
}
- return EINVAL;
+ return -EINVAL;
}
int ia_css_queue_get_size(
@@ -394,7 +395,7 @@ int ia_css_queue_get_size(
int error = 0;
if ((!qhandle) || (!size))
- return EINVAL;
+ return -EINVAL;
/* 1. Load the required queue object */
if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.c b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.c
index 1e8d3eb82eab..fdca743c4ab7 100644
--- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.c
+++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -12,11 +13,12 @@
* more details.
*/
+#include "hmm.h"
+
#include "type_support.h"
#include "queue_access.h"
#include "ia_css_circbuf.h"
#include "sp.h"
-#include "memory_access.h"
#include "assert_support.h"
int ia_css_queue_load(
@@ -25,7 +27,7 @@ int ia_css_queue_load(
uint32_t ignore_desc_flags)
{
if (!rdesc || !cb_desc)
- return EINVAL;
+ return -EINVAL;
if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
assert(ignore_desc_flags <= QUEUE_IGNORE_DESC_FLAGS_MAX);
@@ -63,12 +65,12 @@ int ia_css_queue_load(
} else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
/* doing DMA transfer of entire structure */
- mmgr_load(rdesc->desc.remote.cb_desc_addr,
+ hmm_load(rdesc->desc.remote.cb_desc_addr,
(void *)cb_desc,
sizeof(ia_css_circbuf_desc_t));
} else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
/* Not supported yet */
- return ENOTSUP;
+ return -ENOTSUPP;
}
return 0;
@@ -80,7 +82,7 @@ int ia_css_queue_store(
uint32_t ignore_desc_flags)
{
if (!rdesc || !cb_desc)
- return EINVAL;
+ return -EINVAL;
if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
assert(ignore_desc_flags <= QUEUE_IGNORE_DESC_FLAGS_MAX);
@@ -110,12 +112,12 @@ int ia_css_queue_store(
cb_desc->step);
} else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
/* doing DMA transfer of entire structure */
- mmgr_store(rdesc->desc.remote.cb_desc_addr,
+ hmm_store(rdesc->desc.remote.cb_desc_addr,
(void *)cb_desc,
sizeof(ia_css_circbuf_desc_t));
} else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
/* Not supported yet */
- return ENOTSUP;
+ return -ENOTSUPP;
}
return 0;
@@ -127,7 +129,7 @@ int ia_css_queue_item_load(
ia_css_circbuf_elem_t *item)
{
if (!rdesc || !item)
- return EINVAL;
+ return -EINVAL;
if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
sp_dmem_load(rdesc->proc_id,
@@ -136,13 +138,13 @@ int ia_css_queue_item_load(
item,
sizeof(ia_css_circbuf_elem_t));
} else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
- mmgr_load(rdesc->desc.remote.cb_elems_addr
+ hmm_load(rdesc->desc.remote.cb_elems_addr
+ position * sizeof(ia_css_circbuf_elem_t),
(void *)item,
sizeof(ia_css_circbuf_elem_t));
} else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
/* Not supported yet */
- return ENOTSUP;
+ return -ENOTSUPP;
}
return 0;
@@ -154,7 +156,7 @@ int ia_css_queue_item_store(
ia_css_circbuf_elem_t *item)
{
if (!rdesc || !item)
- return EINVAL;
+ return -EINVAL;
if (rdesc->location == IA_CSS_QUEUE_LOC_SP) {
sp_dmem_store(rdesc->proc_id,
@@ -163,13 +165,13 @@ int ia_css_queue_item_store(
item,
sizeof(ia_css_circbuf_elem_t));
} else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) {
- mmgr_store(rdesc->desc.remote.cb_elems_addr
+ hmm_store(rdesc->desc.remote.cb_elems_addr
+ position * sizeof(ia_css_circbuf_elem_t),
(void *)item,
sizeof(ia_css_circbuf_elem_t));
} else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) {
/* Not supported yet */
- return ENOTSUP;
+ return -ENOTSUPP;
}
return 0;
diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.h b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.h
index 884c55a754d1..d5107adccef9 100644
--- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.h
+++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue_access.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -15,10 +16,11 @@
#ifndef __QUEUE_ACCESS_H
#define __QUEUE_ACCESS_H
+#include <linux/errno.h>
+
#include <type_support.h>
#include <ia_css_queue_comm.h>
#include <ia_css_circbuf.h>
-#include <error_support.h>
#define QUEUE_IGNORE_START_FLAG 0x0001
#define QUEUE_IGNORE_END_FLAG 0x0002
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h
index 47a80ae8dbf3..9cd3d92b34c9 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -28,7 +29,7 @@
/**
* @brief Initialize resource manager (host/common)
*/
-enum ia_css_err ia_css_rmgr_init(void);
+int ia_css_rmgr_init(void);
/**
* @brief Uninitialize resource manager (host/common)
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h
index 0660b65f2e34..ac969afc8bb4 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -17,13 +18,14 @@
#include "ia_css_rmgr.h"
#include <type_support.h>
-#include <system_types.h>
+#include <ia_css_types.h>
+#include <system_local.h>
/**
* @brief Data structure for the resource handle (host, vbuf)
*/
struct ia_css_rmgr_vbuf_handle {
- hrt_vaddress vptr;
+ ia_css_ptr vptr;
u8 count;
u32 size;
};
@@ -51,7 +53,7 @@ extern struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool;
*
* @param pool The pointer to the pool
*/
-STORAGE_CLASS_RMGR_H enum ia_css_err ia_css_rmgr_init_vbuf(
+STORAGE_CLASS_RMGR_H int ia_css_rmgr_init_vbuf(
struct ia_css_rmgr_vbuf_pool *pool);
/**
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr.c b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr.c
index 23ae19ee65ca..c94a428aadde 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr.c
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -14,16 +15,16 @@
#include "ia_css_rmgr.h"
-enum ia_css_err ia_css_rmgr_init(void)
+int ia_css_rmgr_init(void)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
err = ia_css_rmgr_init_vbuf(vbuf_ref);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
err = ia_css_rmgr_init_vbuf(vbuf_write);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
err = ia_css_rmgr_init_vbuf(hmm_buffer_pool);
- if (err != IA_CSS_SUCCESS)
+ if (err)
ia_css_rmgr_uninit();
return err;
}
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c
index 2c204dceb491..1ea74296fc8d 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010-2015, Intel Corporation.
@@ -12,12 +13,12 @@
* more details.
*/
+#include "hmm.h"
#include "ia_css_rmgr.h"
#include <type_support.h>
#include <assert_support.h>
#include <platform_support.h> /* memset */
-#include <memory_access.h> /* mmmgr_malloc, mhmm_free */
#include <ia_css_debug.h>
/*
@@ -137,26 +138,26 @@ void ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
*
* @param pool The pointer to the pool
*/
-enum ia_css_err ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
+int ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
size_t bytes_needed;
rmgr_refcount_init_vbuf();
assert(pool);
if (!pool)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* initialize the recycle pool if used */
if (pool->recycle && pool->size) {
/* allocate memory for storing the handles */
bytes_needed =
sizeof(void *) *
pool->size;
- pool->handles = sh_css_malloc(bytes_needed);
+ pool->handles = kvmalloc(bytes_needed, GFP_KERNEL);
if (pool->handles)
memset(pool->handles, 0, bytes_needed);
else
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
} else {
/* just in case, set the size to 0 */
pool->size = 0;
@@ -196,7 +197,7 @@ void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
}
}
/* now free the pool handles list */
- sh_css_free(pool->handles);
+ kvfree(pool->handles);
pool->handles = NULL;
}
}
@@ -297,7 +298,7 @@ void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
}
if ((*handle)->vptr == 0x0) {
/* we need to allocate */
- (*handle)->vptr = mmgr_malloc((*handle)->size);
+ (*handle)->vptr = hmm_alloc((*handle)->size, HMM_BO_PRIVATE, 0, NULL, 0);
} else {
/* we popped a buffer */
return;
diff --git a/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl.h b/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl.h
index 543ca8968418..efe6c4a82caf 100644
--- a/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl.h
+++ b/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -34,11 +35,11 @@ typedef struct {
} ia_css_spctrl_cfg;
/* Get the code addr in DDR of SP */
-hrt_vaddress get_sp_code_addr(sp_ID_t sp_id);
+ia_css_ptr get_sp_code_addr(sp_ID_t sp_id);
/* ! Load firmware on to specfied SP
*/
-enum ia_css_err ia_css_spctrl_load_fw(sp_ID_t sp_id,
+int ia_css_spctrl_load_fw(sp_ID_t sp_id,
ia_css_spctrl_cfg *spctrl_cfg);
/* ISP2401 */
@@ -47,15 +48,15 @@ void sh_css_spctrl_reload_fw(sp_ID_t sp_id);
/*! Unload/release any memory allocated to hold the firmware
*/
-enum ia_css_err ia_css_spctrl_unload_fw(sp_ID_t sp_id);
+int ia_css_spctrl_unload_fw(sp_ID_t sp_id);
/*! Intilaize dmem_cfg in SP dmem and start SP program
*/
-enum ia_css_err ia_css_spctrl_start(sp_ID_t sp_id);
+int ia_css_spctrl_start(sp_ID_t sp_id);
/*! stop spctrl
*/
-enum ia_css_err ia_css_spctrl_stop(sp_ID_t sp_id);
+int ia_css_spctrl_stop(sp_ID_t sp_id);
/*! Query the state of SP
*/
diff --git a/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl_comm.h b/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl_comm.h
index ca37c4ab7544..78e0f3096f60 100644
--- a/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl_comm.h
+++ b/drivers/staging/media/atomisp/pci/runtime/spctrl/interface/ia_css_spctrl_comm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c b/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c
index db39fa273251..753a99703f1e 100644
--- a/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c
+++ b/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -12,11 +13,12 @@
* more details.
*/
+#include "hmm.h"
+
#include "ia_css_types.h"
#define __INLINE_SP__
#include "sp.h"
-#include "memory_access.h"
#include "assert_support.h"
#include "ia_css_spctrl.h"
#include "ia_css_debug.h"
@@ -26,7 +28,7 @@ struct spctrl_context_info {
u32 spctrl_config_dmem_addr; /* location of dmem_cfg in SP dmem */
u32 spctrl_state_dmem_addr;
unsigned int sp_entry; /* entry function ptr on SP */
- hrt_vaddress code_addr; /* sp firmware location in host mem-DDR*/
+ ia_css_ptr code_addr; /* sp firmware location in host mem-DDR*/
u32 code_size;
char *program_name; /* used in case of PLATFORM_SIM */
};
@@ -35,14 +37,14 @@ static struct spctrl_context_info spctrl_cofig_info[N_SP_ID];
static bool spctrl_loaded[N_SP_ID] = {0};
/* Load firmware */
-enum ia_css_err ia_css_spctrl_load_fw(sp_ID_t sp_id,
+int ia_css_spctrl_load_fw(sp_ID_t sp_id,
ia_css_spctrl_cfg *spctrl_cfg)
{
- hrt_vaddress code_addr = mmgr_NULL;
+ ia_css_ptr code_addr = mmgr_NULL;
struct ia_css_sp_init_dmem_cfg *init_dmem_cfg;
if ((sp_id >= N_SP_ID) || (!spctrl_cfg))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
spctrl_cofig_info[sp_id].code_addr = mmgr_NULL;
@@ -63,17 +65,17 @@ enum ia_css_err ia_css_spctrl_load_fw(sp_ID_t sp_id,
* Data used to be stored separately, because of access alignment constraints,
* fix the FW generation instead
*/
- code_addr = mmgr_malloc(spctrl_cfg->code_size);
+ code_addr = hmm_alloc(spctrl_cfg->code_size, HMM_BO_PRIVATE, 0, NULL, 0);
if (code_addr == mmgr_NULL)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
- mmgr_store(code_addr, spctrl_cfg->code, spctrl_cfg->code_size);
+ return -ENOMEM;
+ hmm_store(code_addr, spctrl_cfg->code, spctrl_cfg->code_size);
- if (sizeof(hrt_vaddress) > sizeof(hrt_data)) {
+ if (sizeof(ia_css_ptr) > sizeof(hrt_data)) {
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
- "size of hrt_vaddress can not be greater than hrt_data\n");
+ "size of ia_css_ptr can not be greater than hrt_data\n");
hmm_free(code_addr);
code_addr = mmgr_NULL;
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
init_dmem_cfg->ddr_data_addr = code_addr + spctrl_cfg->ddr_data_offset;
@@ -82,7 +84,7 @@ enum ia_css_err ia_css_spctrl_load_fw(sp_ID_t sp_id,
"DDR address pointer is not properly aligned for DMA transfer\n");
hmm_free(code_addr);
code_addr = mmgr_NULL;
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
spctrl_cofig_info[sp_id].sp_entry = spctrl_cfg->sp_entry;
@@ -96,7 +98,7 @@ enum ia_css_err ia_css_spctrl_load_fw(sp_ID_t sp_id,
(hrt_data)spctrl_cofig_info[sp_id].code_addr);
sp_ctrl_setbit(sp_id, SP_ICACHE_INV_REG, SP_ICACHE_INV_BIT);
spctrl_loaded[sp_id] = true;
- return IA_CSS_SUCCESS;
+ return 0;
}
/* ISP2401 */
@@ -112,15 +114,15 @@ void sh_css_spctrl_reload_fw(sp_ID_t sp_id)
spctrl_loaded[sp_id] = true;
}
-hrt_vaddress get_sp_code_addr(sp_ID_t sp_id)
+ia_css_ptr get_sp_code_addr(sp_ID_t sp_id)
{
return spctrl_cofig_info[sp_id].code_addr;
}
-enum ia_css_err ia_css_spctrl_unload_fw(sp_ID_t sp_id)
+int ia_css_spctrl_unload_fw(sp_ID_t sp_id)
{
if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id])))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* freeup the resource */
if (spctrl_cofig_info[sp_id].code_addr) {
@@ -128,14 +130,14 @@ enum ia_css_err ia_css_spctrl_unload_fw(sp_ID_t sp_id)
spctrl_cofig_info[sp_id].code_addr = mmgr_NULL;
}
spctrl_loaded[sp_id] = false;
- return IA_CSS_SUCCESS;
+ return 0;
}
/* Initialize dmem_cfg in SP dmem and start SP program*/
-enum ia_css_err ia_css_spctrl_start(sp_ID_t sp_id)
+int ia_css_spctrl_start(sp_ID_t sp_id)
{
if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id])))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* Set descr in the SP to initialize the SP DMEM */
/*
@@ -154,7 +156,7 @@ enum ia_css_err ia_css_spctrl_start(sp_ID_t sp_id)
(hrt_data)spctrl_cofig_info[sp_id].sp_entry);
sp_ctrl_setbit(sp_id, SP_SC_REG, SP_RUN_BIT);
sp_ctrl_setbit(sp_id, SP_SC_REG, SP_START_BIT);
- return IA_CSS_SUCCESS;
+ return 0;
}
/* Query the state of SP1 */
diff --git a/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h b/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h
index 899294646494..49801fbc1924 100644
--- a/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h
+++ b/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2010 - 2015, Intel Corporation.
@@ -23,11 +24,7 @@
*
* Should be one less than NUM_CONTINUOUS_FRAMES in sh_css_internal.h
*/
-#if defined(HAS_SP_2400)
#define MAX_CB_ELEMS_FOR_TAGGER 14
-#else
-#define MAX_CB_ELEMS_FOR_TAGGER 9
-#endif
/**
* @brief Data structure for the tagger buffer element.
diff --git a/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c b/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c
index 57dddd74d668..679ef8242574 100644
--- a/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c
+++ b/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -18,14 +19,14 @@
#include "gp_timer.h" /*gp_timer_read()*/
#include "assert_support.h"
-enum ia_css_err
+int
ia_css_timer_get_current_tick(
struct ia_css_clock_tick *curr_ts) {
assert(curr_ts);
if (!curr_ts)
{
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
curr_ts->ticks = (clock_value_t)gp_timer_read(GP_TIMER_SEL);
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/scalar_processor_2400_params.h b/drivers/staging/media/atomisp/pci/scalar_processor_2400_params.h
index 9b6c2893d950..7e7188797b0a 100644
--- a/drivers/staging/media/atomisp/pci/scalar_processor_2400_params.h
+++ b/drivers/staging/media/atomisp/pci/scalar_processor_2400_params.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c
index d77432254a2c..6676537f0e97 100644
--- a/drivers/staging/media/atomisp/pci/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/sh_css.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -17,6 +18,8 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include "hmm.h"
+
#include "ia_css.h"
#include "sh_css_hrt.h" /* only for file 2 MIPI */
#include "ia_css_buffer.h"
@@ -52,7 +55,6 @@
#include "ia_css_isys.h"
#endif
-#include "memory_access.h"
#include "tag.h"
#include "assert_support.h"
#include "math_support.h"
@@ -74,7 +76,6 @@
#define __INLINE_GPIO__
#include "gpio.h"
#include "timed_ctrl.h"
-#include "platform_support.h" /* hrt_sleep(), inline */
#include "ia_css_inputfifo.h"
#define WITH_PC_MONITORING 0
@@ -181,10 +182,10 @@ static bool fw_explicitly_loaded;
* Local prototypes
*/
-static enum ia_css_err
+static int
allocate_delay_frames(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
sh_css_pipe_start(struct ia_css_stream *stream);
/* ISP 2401 */
@@ -195,7 +196,7 @@ sh_css_pipe_start(struct ia_css_stream *stream);
* @param[in] stream Point to the target "ia_css_stream" instance.
*
* @return
- * - IA_CSS_SUCCESS, if the "stop" requests have been successfully sent out.
+ * - 0, if the "stop" requests have been successfully sent out.
* - CSS error code, otherwise.
*
*
@@ -205,7 +206,7 @@ sh_css_pipe_start(struct ia_css_stream *stream);
* return without waiting for all "ia_css_pipe" instatnces
* being stopped.
*/
-static enum ia_css_err
+static int
sh_css_pipes_stop(struct ia_css_stream *stream);
/*
@@ -224,15 +225,15 @@ static bool
sh_css_pipes_have_stopped(struct ia_css_stream *stream);
/* ISP 2401 */
-static enum ia_css_err
+static int
ia_css_pipe_check_format(struct ia_css_pipe *pipe,
enum ia_css_frame_format format);
/* ISP 2401 */
-static enum ia_css_err
+static int
check_pipe_resolutions(const struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
struct ia_css_fw_info *firmware);
@@ -245,7 +246,7 @@ ia_css_reset_defaults(struct sh_css *css);
static void
sh_css_init_host_sp_control_vars(void);
-static enum ia_css_err set_num_primary_stages(unsigned int *num,
+static int set_num_primary_stages(unsigned int *num,
enum ia_css_pipe_version version);
static bool
@@ -254,7 +255,7 @@ need_capture_pp(const struct ia_css_pipe *pipe);
static bool
need_yuv_scaler_stage(const struct ia_css_pipe *pipe);
-static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output(
+static int ia_css_pipe_create_cas_scaler_desc_single_output(
struct ia_css_frame_info *cas_scaler_in_info,
struct ia_css_frame_info *cas_scaler_out_info,
struct ia_css_frame_info *cas_scaler_vf_info,
@@ -269,91 +270,91 @@ need_downscaling(const struct ia_css_resolution in_res,
static bool need_capt_ldc(const struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
sh_css_pipe_load_binaries(struct ia_css_pipe *pipe);
static
-enum ia_css_err sh_css_pipe_get_viewfinder_frame_info(
+int sh_css_pipe_get_viewfinder_frame_info(
struct ia_css_pipe *pipe,
struct ia_css_frame_info *info,
unsigned int idx);
-static enum ia_css_err
+static int
sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
struct ia_css_frame_info *info,
unsigned int idx);
-static enum ia_css_err
+static int
capture_start(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
video_start(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
preview_start(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
yuvpp_start(struct ia_css_pipe *pipe);
static bool copy_on_sp(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
struct ia_css_frame *vf_frame, unsigned int idx);
-static enum ia_css_err
+static int
init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
struct ia_css_frame *frame, enum ia_css_frame_format format);
-static enum ia_css_err
+static int
init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
struct ia_css_frame *out_frame, unsigned int idx);
-static enum ia_css_err
+static int
sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
const void *acc_fw);
-static enum ia_css_err
+static int
alloc_continuous_frames(
struct ia_css_pipe *pipe, bool init_time);
static void
pipe_global_init(void);
-static enum ia_css_err
+static int
pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
unsigned int *pipe_number);
static void
pipe_release_pipe_num(unsigned int pipe_num);
-static enum ia_css_err
+static int
create_host_pipeline_structure(struct ia_css_stream *stream);
-static enum ia_css_err
+static int
create_host_pipeline(struct ia_css_stream *stream);
-static enum ia_css_err
+static int
create_host_preview_pipeline(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
create_host_video_pipeline(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
create_host_copy_pipeline(struct ia_css_pipe *pipe,
unsigned int max_input_width,
struct ia_css_frame *out_frame);
-static enum ia_css_err
+static int
create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
create_host_capture_pipeline(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
create_host_yuvpp_pipeline(struct ia_css_pipe *pipe);
-static enum ia_css_err
+static int
create_host_acc_pipeline(struct ia_css_pipe *pipe);
static unsigned int
@@ -383,7 +384,7 @@ static struct sh_css_hmm_buffer_record
hrt_address kernel_ptr);
static struct sh_css_hmm_buffer_record
-*sh_css_hmm_buffer_record_validate(hrt_vaddress ddr_buffer_addr,
+*sh_css_hmm_buffer_record_validate(ia_css_ptr ddr_buffer_addr,
enum ia_css_buffer_type type);
void
@@ -392,7 +393,7 @@ ia_css_get_acc_configs(
struct ia_css_isp_config *config);
#if CONFIG_ON_FRAME_ENQUEUE()
-static enum ia_css_err set_config_on_frame_enqueue(struct ia_css_frame_info
+static int set_config_on_frame_enqueue(struct ia_css_frame_info
*info, struct frame_data_wrapper *frame);
#endif
@@ -403,7 +404,7 @@ static unsigned int get_crop_columns_for_bayer_order(const struct
ia_css_stream_config *config);
static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
unsigned int *extra_row, unsigned int *extra_column);
-static enum ia_css_err
+static int
aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
struct ia_css_pipe *pipes[],
bool *do_crop_status);
@@ -411,7 +412,7 @@ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
static bool
aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe);
-static enum ia_css_err
+static int
aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
struct ia_css_resolution *effective_res);
#endif
@@ -458,7 +459,7 @@ static enum ia_css_frame_format yuv422_copy_formats[] = {
/* Verify whether the selected output format is can be produced
* by the copy binary given the stream format.
* */
-static enum ia_css_err
+static int
verify_copy_out_frame_format(struct ia_css_pipe *pipe) {
enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
unsigned int i, found = 0;
@@ -514,8 +515,8 @@ verify_copy_out_frame_format(struct ia_css_pipe *pipe) {
break;
}
if (!found)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
- return IA_CSS_SUCCESS;
+ return -EINVAL;
+ return 0;
}
unsigned int
@@ -533,12 +534,12 @@ ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream)
#define GP_ISEL_TPG_MODE 0x90058
#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
-static enum ia_css_err
+static int
sh_css_config_input_network(struct ia_css_stream *stream) {
unsigned int fmt_type;
struct ia_css_pipe *pipe = stream->last_pipe;
struct ia_css_binary *binary = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(stream);
assert(pipe);
@@ -553,7 +554,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
stream->config.input_config.format,
stream->csi_rx_config.comp,
&fmt_type);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
sh_css_sp_program_input_circuit(fmt_type,
stream->config.channel_id,
@@ -564,7 +565,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
{
err = ia_css_ifmtr_configure(&stream->config,
binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -582,7 +583,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
vblank_cycles = vblank_lines * (width + hblank_cycles);
sh_css_sp_configure_sync_gen(width, height, hblank_cycles,
vblank_cycles);
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) {
/* TODO: move define to proper file in tools */
ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0);
@@ -591,7 +592,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
}
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"sh_css_config_input_network() leave:\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
#elif !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2401)
static unsigned int csi2_protocol_calculate_max_subpixels_per_line(
@@ -879,14 +880,14 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr(
break;
case IA_CSS_INPUT_MODE_BUFFERED_SENSOR: {
- enum ia_css_err err;
+ int err;
unsigned int fmt_type;
err = ia_css_isys_convert_stream_format_to_mipi_format(
stream_cfg->isys_config[isys_stream_idx].format,
MIPI_PREDICTOR_NONE,
&fmt_type);
- if (err != IA_CSS_SUCCESS)
+ if (err)
rc = false;
isys_stream_descr->csi_port_attr.active_lanes =
@@ -899,7 +900,7 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr(
err |= ia_css_isys_convert_compressed_format(
&stream_cfg->source.port.compression,
isys_stream_descr);
- if (err != IA_CSS_SUCCESS)
+ if (err)
rc = false;
/* metadata */
@@ -909,7 +910,7 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr(
stream_cfg->metadata_config.data_type,
MIPI_PREDICTOR_NONE,
&fmt_type);
- if (err != IA_CSS_SUCCESS)
+ if (err)
rc = false;
isys_stream_descr->metadata.fmt_type = fmt_type;
isys_stream_descr->metadata.bits_per_pixel =
@@ -1050,7 +1051,7 @@ static bool sh_css_translate_binary_info_to_input_system_output_port_attr(
return true;
}
-static enum ia_css_err
+static int
sh_css_config_input_network(struct ia_css_stream *stream) {
bool rc;
ia_css_isys_descr_t isys_stream_descr;
@@ -1095,7 +1096,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
assert(pipe);
if (!pipe)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
if (pipe->pipeline.stages)
if (pipe->pipeline.stages->binary)
@@ -1113,7 +1114,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
/* get the SP thread id */
rc = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &sp_thread_id);
if (!rc)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
/* get the target input terminal */
sp_pipeline_input_terminal = &sh_css_sp_group.pipe_io[sp_thread_id].input;
@@ -1140,7 +1141,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
}
if (!rc)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
isys_stream_id = ia_css_isys_generate_stream_id(sp_thread_id, i);
@@ -1150,7 +1151,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
&sp_pipeline_input_terminal->context.virtual_input_system_stream[i],
isys_stream_id);
if (!rc)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
/* calculate the configuration of the virtual Input System (2401) */
rc = ia_css_isys_stream_calculate_cfg(
@@ -1160,14 +1161,14 @@ sh_css_config_input_network(struct ia_css_stream *stream) {
if (!rc) {
ia_css_isys_stream_destroy(
&sp_pipeline_input_terminal->context.virtual_input_system_stream[i]);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
}
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"sh_css_config_input_network() leave:\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
static inline struct ia_css_pipe *stream_get_last_pipe(
@@ -1225,11 +1226,11 @@ static inline struct ia_css_pipe *stream_get_target_pipe(
return target_pipe;
}
-static enum ia_css_err stream_csi_rx_helper(
+static int stream_csi_rx_helper(
struct ia_css_stream *stream,
- enum ia_css_err (*func)(enum mipi_port_id, uint32_t))
+ int (*func)(enum mipi_port_id, uint32_t))
{
- enum ia_css_err retval = IA_CSS_ERR_INTERNAL_ERROR;
+ int retval = -EINVAL;
u32 sp_thread_id, stream_id;
bool rc;
struct ia_css_pipe *target_pipe = NULL;
@@ -1258,20 +1259,20 @@ static enum ia_css_err stream_csi_rx_helper(
retval = func(stream->config.source.port.port, isys_stream_id);
}
stream_id++;
- } while ((retval == IA_CSS_SUCCESS) &&
+ } while ((retval == 0) &&
(stream_id < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH));
exit:
return retval;
}
-static inline enum ia_css_err stream_register_with_csi_rx(
+static inline int stream_register_with_csi_rx(
struct ia_css_stream *stream)
{
return stream_csi_rx_helper(stream, ia_css_isys_csi_rx_register_stream);
}
-static inline enum ia_css_err stream_unregister_with_csi_rx(
+static inline int stream_unregister_with_csi_rx(
struct ia_css_stream *stream)
{
return stream_csi_rx_helper(stream, ia_css_isys_csi_rx_unregister_stream);
@@ -1324,7 +1325,7 @@ static void print_pc_histogram(void)
sh_css_print(" pc_histogram for binary %d\n", metrics->id);
print_pc_histo(" ISP", &metrics->isp_histogram);
print_pc_histo(" SP", &metrics->sp_histogram);
- sh_css_print("print_pc_histogram() done for binay->id = %d, done.\n",
+ sh_css_print("print_pc_histogram() done for binary->id = %d, done.\n",
metrics->id);
}
@@ -1404,7 +1405,7 @@ start_binary(struct ia_css_pipe *pipe,
}
/* start the copy function on the SP */
-static enum ia_css_err
+static int
start_copy_on_sp(struct ia_css_pipe *pipe,
struct ia_css_frame *out_frame) {
(void)out_frame;
@@ -1412,7 +1413,7 @@ start_copy_on_sp(struct ia_css_pipe *pipe,
assert(pipe->stream);
if ((!pipe) || (!pipe->stream))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
#if !defined(HAS_NO_INPUT_SYSTEM) && !defined(USE_INPUT_SYSTEM_VERSION_2401)
if (pipe->stream->reconfigure_css_rx)
@@ -1420,7 +1421,7 @@ start_copy_on_sp(struct ia_css_pipe *pipe,
#endif
if (pipe->stream->config.input_config.format != ATOMISP_INPUT_FORMAT_BINARY_8)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
sh_css_sp_start_binary_copy(ia_css_pipe_get_pipe_num(pipe), out_frame, pipe->stream->config.pixels_per_clock == 2);
#if !defined(HAS_NO_INPUT_SYSTEM) && !defined(USE_INPUT_SYSTEM_VERSION_2401)
@@ -1432,7 +1433,7 @@ start_copy_on_sp(struct ia_css_pipe *pipe,
}
#endif
- return IA_CSS_SUCCESS;
+ return 0;
}
void sh_css_binary_args_reset(struct sh_css_binary_args *args)
@@ -1469,7 +1470,7 @@ static void start_pipe(
assert(me); /* all callers are in this file and call with non null argument */
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
coord = &me->config.internal_frame_origin_bqs_on_sctbl;
params = me->stream->isp_params_configs;
}
@@ -1544,16 +1545,16 @@ enable_interrupts(enum ia_css_irq_type irq_type)
/* Enable SW interrupt 0, this is used to signal ISYS events */
cnd_virq_enable_channel(
- (virq_id_t)(IRQ_SW_CHANNEL0_ID + IRQ_SW_CHANNEL_OFFSET),
+ (enum virq_id)(IRQ_SW_CHANNEL0_ID + IRQ_SW_CHANNEL_OFFSET),
true);
/* Enable SW interrupt 1, this is used to signal PSYS events */
cnd_virq_enable_channel(
- (virq_id_t)(IRQ_SW_CHANNEL1_ID + IRQ_SW_CHANNEL_OFFSET),
+ (enum virq_id)(IRQ_SW_CHANNEL1_ID + IRQ_SW_CHANNEL_OFFSET),
true);
#if !defined(HAS_IRQ_MAP_VERSION_2)
/* IRQ_SW_CHANNEL2_ID does not exist on 240x systems */
cnd_virq_enable_channel(
- (virq_id_t)(IRQ_SW_CHANNEL2_ID + IRQ_SW_CHANNEL_OFFSET),
+ (enum virq_id)(IRQ_SW_CHANNEL2_ID + IRQ_SW_CHANNEL_OFFSET),
true);
virq_clear_all();
#endif
@@ -1624,15 +1625,15 @@ ia_css_reset_defaults(struct sh_css *css)
*css = default_css;
}
-enum ia_css_err
+int
ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
const struct ia_css_fw *fw) {
- enum ia_css_err err;
+ int err;
if (!env)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!fw)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() enter\n");
@@ -1645,10 +1646,10 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
ia_css_unload_firmware(); /* in case we are called twice */
err = sh_css_load_firmware(dev, fw->data, fw->bytes);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
{
err = ia_css_binary_init_infos();
- if (err == IA_CSS_SUCCESS)
+ if (!err)
fw_explicitly_loaded = true;
}
@@ -1656,12 +1657,12 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
return err;
}
-enum ia_css_err
+int
ia_css_init(struct device *dev, const struct ia_css_env *env,
const struct ia_css_fw *fw,
u32 mmu_l1_base,
enum ia_css_irq_type irq_type) {
- enum ia_css_err err;
+ int err;
ia_css_spctrl_cfg spctrl_cfg;
void (*flush_func)(struct ia_css_acc_fw *fw);
@@ -1704,9 +1705,9 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
COMPILATION_ERROR_IF(sizeof(struct ia_css_sp_init_dmem_cfg) != SIZE_OF_IA_CSS_SP_INIT_DMEM_CFG_STRUCT);
if (!fw && !fw_explicitly_loaded)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!env)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
sh_css_printf = env->print_env.debug_print;
@@ -1734,7 +1735,7 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
my_css.flush = flush_func;
err = ia_css_rmgr_init();
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
@@ -1771,13 +1772,13 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_0, 0);
err = ia_css_refcount_init(REFCOUNT_SIZE);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
}
err = sh_css_params_init();
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
@@ -1786,12 +1787,12 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
{
ia_css_unload_firmware(); /* in case we already had firmware loaded */
err = sh_css_load_firmware(dev, fw->data, fw->bytes);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR(err);
return err;
}
err = ia_css_binary_init_infos();
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -1801,10 +1802,10 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
#endif
}
if (!sh_css_setup_spctrl_config(&sh_css_sp_fw, SP_PROG_NAME, &spctrl_cfg))
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
err = ia_css_spctrl_load_fw(SP0_ID, &spctrl_cfg);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
@@ -1821,8 +1822,8 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
#endif
if (!sh_css_hrt_system_is_idle())
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_SYSTEM_NOT_IDLE);
- return IA_CSS_ERR_SYSTEM_NOT_IDLE;
+ IA_CSS_LEAVE_ERR(-EBUSY);
+ return -EBUSY;
}
/* can be called here, queuing works, but:
- when sp is started later, it will wipe queued items
@@ -1844,7 +1845,7 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
ISP_DMA_MAX_BURST_LENGTH);
if (ia_css_isys_init() != INPUT_SYSTEM_ERR_NO_ERROR)
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
#endif
sh_css_params_map_and_store_default_gdc_lut();
@@ -1853,49 +1854,12 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
return err;
}
-enum ia_css_err
+int
ia_css_enable_isys_event_queue(bool enable) {
if (sh_css_sp_is_running())
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
sh_css_sp_enable_isys_event_queue(enable);
- return IA_CSS_SUCCESS;
-}
-
-void *sh_css_malloc(size_t size)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_malloc() enter: size=%zu\n",
- size);
- /* FIXME: This first test can probably go away */
- if (size == 0)
- return NULL;
- if (size > PAGE_SIZE)
- return vmalloc(size);
- return kmalloc(size, GFP_KERNEL);
-}
-
-void *sh_css_calloc(size_t N, size_t size)
-{
- void *p;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "sh_css_calloc() enter: N=%zu, size=%zu\n", N, size);
-
- /* FIXME: this test can probably go away */
- if (size > 0) {
- p = sh_css_malloc(N * size);
- if (p)
- memset(p, 0, size);
- return p;
- }
- return NULL;
-}
-
-void sh_css_free(void *ptr)
-{
- if (is_vmalloc_addr(ptr))
- vfree(ptr);
- else
- kfree(ptr);
+ return 0;
}
/* For Acceleration API: Flush FW (shared buffer pointer) arguments */
@@ -1911,13 +1875,13 @@ sh_css_flush(struct ia_css_acc_fw *fw)
* pipelines are ready to be converted to sp pipelines. Be careful if you are
* doing it from stream_create since we could run out of sp threads due to
* allocation on inactive pipelines. */
-static enum ia_css_err
+static int
map_sp_threads(struct ia_css_stream *stream, bool map) {
struct ia_css_pipe *main_pipe = NULL;
struct ia_css_pipe *copy_pipe = NULL;
struct ia_css_pipe *capture_pipe = NULL;
struct ia_css_pipe *acc_pipe = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
enum ia_css_pipe_id pipe_id;
assert(stream);
@@ -1926,8 +1890,8 @@ map_sp_threads(struct ia_css_stream *stream, bool map) {
if (!stream)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
main_pipe = stream->last_pipe;
@@ -1984,13 +1948,13 @@ map_sp_threads(struct ia_css_stream *stream, bool map) {
/* creates a host pipeline skeleton for all pipes in a stream. Called during
* stream_create. */
-static enum ia_css_err
+static int
create_host_pipeline_structure(struct ia_css_stream *stream) {
struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
struct ia_css_pipe *acc_pipe = NULL;
enum ia_css_pipe_id pipe_id;
struct ia_css_pipe *main_pipe = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int copy_pipe_delay = 0,
capture_pipe_delay = 0;
@@ -1999,16 +1963,16 @@ create_host_pipeline_structure(struct ia_css_stream *stream) {
if (!stream)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
main_pipe = stream->last_pipe;
assert(main_pipe);
if (!main_pipe)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
pipe_id = main_pipe->mode;
@@ -2050,10 +2014,10 @@ create_host_pipeline_structure(struct ia_css_stream *stream) {
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
- if ((err == IA_CSS_SUCCESS) && copy_pipe)
+ if (!(err) && copy_pipe)
{
err = ia_css_pipeline_create(&copy_pipe->pipeline,
copy_pipe->mode,
@@ -2061,7 +2025,7 @@ create_host_pipeline_structure(struct ia_css_stream *stream) {
copy_pipe_delay);
}
- if ((err == IA_CSS_SUCCESS) && capture_pipe)
+ if (!(err) && capture_pipe)
{
err = ia_css_pipeline_create(&capture_pipe->pipeline,
capture_pipe->mode,
@@ -2069,7 +2033,7 @@ create_host_pipeline_structure(struct ia_css_stream *stream) {
capture_pipe_delay);
}
- if ((err == IA_CSS_SUCCESS) && acc_pipe)
+ if (!(err) && acc_pipe)
{
err = ia_css_pipeline_create(&acc_pipe->pipeline, acc_pipe->mode,
acc_pipe->pipe_num, main_pipe->dvs_frame_delay);
@@ -2080,7 +2044,7 @@ create_host_pipeline_structure(struct ia_css_stream *stream) {
{
int i;
- for (i = 1; i < stream->num_pipes && IA_CSS_SUCCESS == err; i++) {
+ for (i = 1; i < stream->num_pipes && 0 == err; i++) {
main_pipe = stream->pipes[i];
err = ia_css_pipeline_create(&main_pipe->pipeline,
main_pipe->mode,
@@ -2095,20 +2059,20 @@ create_host_pipeline_structure(struct ia_css_stream *stream) {
/* creates a host pipeline for all pipes in a stream. Called during
* stream_start. */
-static enum ia_css_err
+static int
create_host_pipeline(struct ia_css_stream *stream) {
struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
struct ia_css_pipe *acc_pipe = NULL;
enum ia_css_pipe_id pipe_id;
struct ia_css_pipe *main_pipe = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int max_input_width = 0;
IA_CSS_ENTER_PRIVATE("stream = %p", stream);
if (!stream)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
main_pipe = stream->last_pipe;
@@ -2129,7 +2093,7 @@ create_host_pipeline(struct ia_css_stream *stream) {
(pipe_id == IA_CSS_PIPE_ID_PREVIEW &&
stream->config.mode != IA_CSS_INPUT_MODE_MEMORY)) {
err = alloc_continuous_frames(main_pipe, true);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
}
@@ -2139,7 +2103,7 @@ create_host_pipeline(struct ia_css_stream *stream) {
if (pipe_id != IA_CSS_PIPE_ID_ACC)
{
err = allocate_mipi_frames(main_pipe, &stream->info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
#elif defined(USE_INPUT_SYSTEM_VERSION_2401)
@@ -2147,7 +2111,7 @@ create_host_pipeline(struct ia_css_stream *stream) {
(main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY))
{
err = allocate_mipi_frames(main_pipe, &stream->info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
#endif
@@ -2162,7 +2126,7 @@ create_host_pipeline(struct ia_css_stream *stream) {
main_pipe->pipe_settings.preview.preview_binary.info->sp.input.max_width;
err = create_host_preview_pipeline(main_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
break;
@@ -2174,7 +2138,7 @@ create_host_pipeline(struct ia_css_stream *stream) {
main_pipe->pipe_settings.video.video_binary.info->sp.input.max_width;
err = create_host_video_pipeline(main_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
break;
@@ -2186,42 +2150,42 @@ create_host_pipeline(struct ia_css_stream *stream) {
case IA_CSS_PIPE_ID_YUVPP:
err = create_host_yuvpp_pipeline(main_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
break;
case IA_CSS_PIPE_ID_ACC:
err = create_host_acc_pipeline(main_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
if (copy_pipe)
{
err = create_host_copy_pipeline(copy_pipe, max_input_width,
main_pipe->continuous_frames[0]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
if (capture_pipe)
{
err = create_host_capture_pipeline(capture_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
if (acc_pipe)
{
err = create_host_acc_pipeline(acc_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
@@ -2230,7 +2194,7 @@ create_host_pipeline(struct ia_css_stream *stream) {
{
int i;
- for (i = 1; i < stream->num_pipes && IA_CSS_SUCCESS == err; i++) {
+ for (i = 1; i < stream->num_pipes && 0 == err; i++) {
switch (stream->pipes[i]->mode) {
case IA_CSS_PIPE_ID_PREVIEW:
err = create_host_preview_pipeline(stream->pipes[i]);
@@ -2248,9 +2212,9 @@ create_host_pipeline(struct ia_css_stream *stream) {
err = create_host_acc_pipeline(stream->pipes[i]);
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
}
@@ -2260,25 +2224,32 @@ ERR:
return err;
}
-static enum ia_css_err
+static const struct ia_css_pipe default_pipe = IA_CSS_DEFAULT_PIPE;
+static const struct ia_css_preview_settings preview = IA_CSS_DEFAULT_PREVIEW_SETTINGS;
+static const struct ia_css_capture_settings capture = IA_CSS_DEFAULT_CAPTURE_SETTINGS;
+static const struct ia_css_video_settings video = IA_CSS_DEFAULT_VIDEO_SETTINGS;
+static const struct ia_css_yuvpp_settings yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS;
+
+static int
init_pipe_defaults(enum ia_css_pipe_mode mode,
struct ia_css_pipe *pipe,
bool copy_pipe) {
+
if (!pipe)
{
IA_CSS_ERROR("NULL pipe parameter");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* Initialize pipe to pre-defined defaults */
- *pipe = IA_CSS_DEFAULT_PIPE;
+ memcpy(pipe, &default_pipe, sizeof(default_pipe));
/* TODO: JB should not be needed, but temporary backward reference */
switch (mode)
{
case IA_CSS_PIPE_MODE_PREVIEW:
pipe->mode = IA_CSS_PIPE_ID_PREVIEW;
- pipe->pipe_settings.preview = IA_CSS_DEFAULT_PREVIEW_SETTINGS;
+ memcpy(&pipe->pipe_settings.preview, &preview, sizeof(preview));
break;
case IA_CSS_PIPE_MODE_CAPTURE:
if (copy_pipe) {
@@ -2286,11 +2257,11 @@ init_pipe_defaults(enum ia_css_pipe_mode mode,
} else {
pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
}
- pipe->pipe_settings.capture = IA_CSS_DEFAULT_CAPTURE_SETTINGS;
+ memcpy(&pipe->pipe_settings.capture, &capture, sizeof(capture));
break;
case IA_CSS_PIPE_MODE_VIDEO:
pipe->mode = IA_CSS_PIPE_ID_VIDEO;
- pipe->pipe_settings.video = IA_CSS_DEFAULT_VIDEO_SETTINGS;
+ memcpy(&pipe->pipe_settings.video, &video, sizeof(video));
break;
case IA_CSS_PIPE_MODE_ACC:
pipe->mode = IA_CSS_PIPE_ID_ACC;
@@ -2300,13 +2271,13 @@ init_pipe_defaults(enum ia_css_pipe_mode mode,
break;
case IA_CSS_PIPE_MODE_YUVPP:
pipe->mode = IA_CSS_PIPE_ID_YUVPP;
- pipe->pipe_settings.yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS;
+ memcpy(&pipe->pipe_settings.yuvpp, &yuvpp, sizeof(yuvpp));
break;
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -2320,7 +2291,7 @@ pipe_global_init(void)
}
}
-static enum ia_css_err
+static int
pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
unsigned int *pipe_number) {
const u8 INVALID_PIPE_NUM = (uint8_t)~(0);
@@ -2330,7 +2301,7 @@ pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
if (!pipe)
{
IA_CSS_ERROR("NULL pipe parameter");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* Assign a new pipe_num .... search for empty place */
@@ -2347,7 +2318,7 @@ pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
{
/* Max number of pipes already allocated */
IA_CSS_ERROR("Max number of pipes already created");
- return IA_CSS_ERR_RESOURCE_EXHAUSTED;
+ return -ENOSPC;
}
my_css.pipe_counter++;
@@ -2355,7 +2326,7 @@ pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
IA_CSS_LOG("pipe_num (%d)", pipe_num);
*pipe_number = pipe_num;
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -2367,39 +2338,39 @@ pipe_release_pipe_num(unsigned int pipe_num)
"pipe_release_pipe_num (%d)\n", pipe_num);
}
-static enum ia_css_err
+static int
create_pipe(enum ia_css_pipe_mode mode,
struct ia_css_pipe **pipe,
bool copy_pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipe *me;
if (!pipe)
{
IA_CSS_ERROR("NULL pipe parameter");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
me = kmalloc(sizeof(*me), GFP_KERNEL);
if (!me)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
err = init_pipe_defaults(mode, me, copy_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
kfree(me);
return err;
}
err = pipe_generate_pipe_num(me, &me->pipe_num);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
kfree(me);
return err;
}
*pipe = me;
- return IA_CSS_SUCCESS;
+ return 0;
}
struct ia_css_pipe *
@@ -2438,23 +2409,23 @@ static void sh_css_pipe_free_acc_binaries(
}
}
-enum ia_css_err
+int
ia_css_pipe_destroy(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("pipe = %p", pipe);
if (!pipe)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if (pipe->stream)
{
IA_CSS_LOG("ia_css_stream_destroy not called!");
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
switch (pipe->config.mode)
@@ -2574,10 +2545,10 @@ ia_css_uninit(void)
}
#if defined(HAS_IRQ_MAP_VERSION_2)
-enum ia_css_err ia_css_irq_translate(
+int ia_css_irq_translate(
unsigned int *irq_infos)
{
- virq_id_t irq;
+ enum virq_id irq;
enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_more_irqs;
unsigned int infos = 0;
@@ -2589,7 +2560,7 @@ enum ia_css_err ia_css_irq_translate(
while (status == hrt_isp_css_irq_status_more_irqs) {
status = virq_get_channel_id(&irq);
if (status == hrt_isp_css_irq_status_error)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
#if WITH_PC_MONITORING
sh_css_print("PC_MONITORING: %s() irq = %d, sh_binary_running set to 0\n",
@@ -2643,14 +2614,14 @@ enum ia_css_err ia_css_irq_translate(
"ia_css_irq_translate() leave: irq_infos=%u\n",
infos);
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err ia_css_irq_enable(
+int ia_css_irq_enable(
enum ia_css_irq_info info,
bool enable)
{
- virq_id_t irq = N_virq_id;
+ enum virq_id irq = N_virq_id;
IA_CSS_ENTER("info=%d, enable=%d", info, enable);
@@ -2674,7 +2645,7 @@ enum ia_css_err ia_css_irq_enable(
case IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR:
case IA_CSS_IRQ_INFO_IF_ERROR:
/* Just ignore those unused IRQs without printing errors */
- return IA_CSS_SUCCESS;
+ return 0;
#endif
case IA_CSS_IRQ_INFO_DMA_ERROR:
irq = virq_dma;
@@ -2686,14 +2657,14 @@ enum ia_css_err ia_css_irq_enable(
irq = virq_sw_pin_1;
break;
default:
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
cnd_virq_enable_channel(irq, enable);
- IA_CSS_LEAVE_ERR(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR(0);
+ return 0;
}
#else
@@ -2715,14 +2686,14 @@ sh_css_get_sw_interrupt_value(unsigned int irq)
/* configure and load the copy binary, the next binary is used to
determine whether the copy binary needs to do left padding. */
-static enum ia_css_err load_copy_binary(
+static int load_copy_binary(
struct ia_css_pipe *pipe,
struct ia_css_binary *copy_binary,
struct ia_css_binary *next_binary)
{
struct ia_css_frame_info copy_out_info, copy_in_info, copy_vf_info;
unsigned int left_padding;
- enum ia_css_err err;
+ int err;
struct ia_css_binary_descr copy_descr;
/* next_binary can be NULL */
@@ -2745,16 +2716,16 @@ static enum ia_css_err load_copy_binary(
&copy_in_info, &copy_out_info,
(next_binary) ? NULL : NULL/*TODO: &copy_vf_info*/);
err = ia_css_binary_find(&copy_descr, copy_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
copy_binary->left_padding = left_padding;
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
alloc_continuous_frames(
struct ia_css_pipe *pipe, bool init_time) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame_info ref_info;
enum ia_css_pipe_id pipe_id;
bool continuous;
@@ -2766,8 +2737,8 @@ alloc_continuous_frames(
if ((!pipe) || (!pipe->stream))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
pipe_id = pipe->mode;
@@ -2794,8 +2765,8 @@ alloc_continuous_frames(
} else
{
/* should not happen */
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
#if defined(USE_INPUT_SYSTEM_VERSION_2401)
@@ -2834,8 +2805,8 @@ alloc_continuous_frames(
} else
{
/* should not happen */
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
if (init_time)
@@ -2860,7 +2831,7 @@ alloc_continuous_frames(
err = ia_css_frame_allocate_from_info(
&pipe->continuous_frames[i],
&ref_info);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -2869,18 +2840,18 @@ alloc_continuous_frames(
&pipe->stream->info.metadata_info);
}
}
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-enum ia_css_err
+int
ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream) {
if (!stream)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
return alloc_continuous_frames(stream->continuous_pipe, false);
}
-static enum ia_css_err
+static int
load_preview_binaries(struct ia_css_pipe *pipe) {
struct ia_css_frame_info prev_in_info,
prev_bds_out_info,
@@ -2888,7 +2859,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
prev_vf_info;
struct ia_css_binary_descr preview_descr;
bool online;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool continuous, need_vf_pp = false;
bool need_isp_copy_binary = false;
#ifdef USE_INPUT_SYSTEM_VERSION_2401
@@ -2910,13 +2881,13 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
#endif
if (mycs->preview_binary.info)
- return IA_CSS_SUCCESS;
+ return 0;
err = ia_css_util_check_input(&pipe->stream->config, false, false);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = ia_css_frame_check_info(pipe_out_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
/* Note: the current selection of vf_pp binary and
@@ -2960,13 +2931,13 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
&prev_bds_out_info,
&prev_out_info,
&prev_vf_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = ia_css_binary_find(&preview_descr, &mycs->preview_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
/* The delay latency determines the number of invalid frames after
* a stream is started. */
pipe->num_invalid_frames = pipe->dvs_frame_delay;
@@ -3004,11 +2975,11 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
&prev_bds_out_info,
&prev_out_info,
&prev_vf_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = ia_css_binary_find(&preview_descr,
&mycs->preview_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -3022,7 +2993,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
pipe_out_info);
err = ia_css_binary_find(&vf_pp_descr,
&mycs->vf_pp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -3037,7 +3008,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
* where the driver chooses for memory based input frames. In these cases, a copy binary (which typical
* copies sensor data to DDR) does not have much use.
*/
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
need_isp_copy_binary = !online && !continuous;
else
need_isp_copy_binary = !online && !continuous && !(pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY);
@@ -3049,7 +3020,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
err = load_copy_binary(pipe,
&mycs->copy_binary,
&mycs->preview_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -3059,7 +3030,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) {
pipe->shading_table = NULL;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -3068,21 +3039,21 @@ ia_css_binary_unload(struct ia_css_binary *binary)
ia_css_binary_destroy_isp_parameters(binary);
}
-static enum ia_css_err
+static int
unload_preview_binaries(struct ia_css_pipe *pipe) {
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_binary_unload(&pipe->pipe_settings.preview.copy_binary);
ia_css_binary_unload(&pipe->pipe_settings.preview.preview_binary);
ia_css_binary_unload(&pipe->pipe_settings.preview.vf_pp_binary);
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
static const struct ia_css_fw_info *last_output_firmware(
@@ -3101,7 +3072,7 @@ static const struct ia_css_fw_info *last_output_firmware(
return last_fw;
}
-static enum ia_css_err add_firmwares(
+static int add_firmwares(
struct ia_css_pipeline *me,
struct ia_css_binary *binary,
const struct ia_css_fw_info *fw,
@@ -3113,7 +3084,7 @@ static enum ia_css_err add_firmwares(
struct ia_css_pipeline_stage **my_stage,
struct ia_css_pipeline_stage **vf_stage)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipeline_stage *extra_stage = NULL;
struct ia_css_pipeline_stage_desc stage_desc;
@@ -3140,7 +3111,7 @@ static enum ia_css_err add_firmwares(
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&extra_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
if (fw->info.isp.sp.enable.output != 0)
in_frame = extra_stage->args.out_frame[0];
@@ -3153,7 +3124,7 @@ static enum ia_css_err add_firmwares(
return err;
}
-static enum ia_css_err add_vf_pp_stage(
+static int add_vf_pp_stage(
struct ia_css_pipe *pipe,
struct ia_css_frame *in_frame,
struct ia_css_frame *out_frame,
@@ -3162,20 +3133,20 @@ static enum ia_css_err add_vf_pp_stage(
{
struct ia_css_pipeline *me = NULL;
const struct ia_css_fw_info *last_fw = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
struct ia_css_pipeline_stage_desc stage_desc;
/* out_frame can be NULL ??? */
if (!pipe)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!in_frame)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!vf_pp_binary)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!vf_pp_stage)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_pipe_util_create_output_frames(out_frames);
me = &pipe->pipeline;
@@ -3197,7 +3168,7 @@ static enum ia_css_err add_vf_pp_stage(
out_frames, in_frame, NULL);
}
err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, vf_pp_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
in_frame = (*vf_pp_stage)->args.out_frame[0];
}
@@ -3208,7 +3179,7 @@ static enum ia_css_err add_vf_pp_stage(
return err;
}
-static enum ia_css_err add_yuv_scaler_stage(
+static int add_yuv_scaler_stage(
struct ia_css_pipe *pipe,
struct ia_css_pipeline *me,
struct ia_css_frame *in_frame,
@@ -3218,7 +3189,7 @@ static enum ia_css_err add_yuv_scaler_stage(
struct ia_css_pipeline_stage **pre_vf_pp_stage)
{
const struct ia_css_fw_info *last_fw;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame *vf_frame = NULL;
struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
struct ia_css_pipeline_stage_desc stage_desc;
@@ -3250,7 +3221,7 @@ static enum ia_css_err add_yuv_scaler_stage(
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
pre_vf_pp_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
in_frame = (*pre_vf_pp_stage)->args.out_frame[0];
@@ -3267,7 +3238,7 @@ static enum ia_css_err add_yuv_scaler_stage(
return err;
}
-static enum ia_css_err add_capture_pp_stage(
+static int add_capture_pp_stage(
struct ia_css_pipe *pipe,
struct ia_css_pipeline *me,
struct ia_css_frame *in_frame,
@@ -3276,7 +3247,7 @@ static enum ia_css_err add_capture_pp_stage(
struct ia_css_pipeline_stage **capture_pp_stage)
{
const struct ia_css_fw_info *last_fw = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame *vf_frame = NULL;
struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
struct ia_css_pipeline_stage_desc stage_desc;
@@ -3296,7 +3267,7 @@ static enum ia_css_err add_capture_pp_stage(
last_fw = last_output_firmware(pipe->output_stage);
err = ia_css_frame_allocate_from_info(&vf_frame,
&capture_pp_binary->vf_frame_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
if (last_fw) {
ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
@@ -3310,7 +3281,7 @@ static enum ia_css_err add_capture_pp_stage(
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
capture_pp_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = add_firmwares(me, capture_pp_binary, pipe->output_stage, last_fw,
IA_CSS_BINARY_MODE_CAPTURE_PP,
@@ -3346,10 +3317,10 @@ static void sh_css_setup_queues(void)
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_setup_queues() leave:\n");
}
-static enum ia_css_err
+static int
init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
struct ia_css_frame *vf_frame, unsigned int idx) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int thread_id;
enum sh_css_queue_id queue_id;
@@ -3511,11 +3482,11 @@ ia_css_get_crop_offsets(
}
#endif
-static enum ia_css_err
+static int
init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
struct ia_css_frame *frame, enum ia_css_frame_format format) {
struct ia_css_frame *in_frame;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int thread_id;
enum sh_css_queue_id queue_id;
@@ -3552,10 +3523,10 @@ init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
return err;
}
-static enum ia_css_err
+static int
init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
struct ia_css_frame *out_frame, unsigned int idx) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int thread_id;
enum sh_css_queue_id queue_id;
@@ -3574,7 +3545,7 @@ init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
}
/* Create stages for video pipe */
-static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
+static int create_host_video_pipeline(struct ia_css_pipe *pipe)
{
struct ia_css_pipeline_stage_desc stage_desc;
struct ia_css_binary *copy_binary, *video_binary,
@@ -3588,7 +3559,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
struct ia_css_frame *out_frame;
struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
struct ia_css_frame *vf_frame = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool need_copy = false;
bool need_vf_pp = false;
bool need_yuv_pp = false;
@@ -3600,8 +3571,8 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_pipe_util_create_output_frames(out_frames);
out_frame = &pipe->out_frame_struct;
@@ -3629,20 +3600,20 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
in_frame = &pipe->in_frame_struct;
err = init_in_frameinfo_memory_defaults(pipe, in_frame,
IA_CSS_FRAME_FORMAT_RAW);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
out_frame->data = 0;
err = init_out_frameinfo_defaults(pipe, out_frame, 0);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
vf_frame = &pipe->vf_frame_struct;
vf_frame->data = 0;
err = init_vf_frameinfo_defaults(pipe, vf_frame, 0);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
@@ -3666,7 +3637,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&copy_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
in_frame = me->stages->args.out_frame[0];
} else if (pipe->stream->config.continuous) {
@@ -3695,7 +3666,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&video_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
/* If we use copy iso video, the input must be yuv iso raw */
@@ -3711,16 +3682,13 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
in_frame = video_stage->args.out_vf_frame;
err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
&vf_pp_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
if (video_stage) {
int frm;
-#ifndef ISP2401
- for (frm = 0; frm < NUM_TNR_FRAMES; frm++) {
-#else
+
for (frm = 0; frm < NUM_TNR_FRAMES; frm++) {
-#endif
video_stage->args.tnr_frames[frm] =
pipe->pipe_settings.video.tnr_frames[frm];
}
@@ -3742,7 +3710,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
/* In/Out Frame mapping to support output frame extension.*/
out = video_stage->args.out_frame[0];
err = ia_css_frame_allocate_from_info(&in, &pipe->output_info[0]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
video_stage->args.out_frame[0] = in;
}
@@ -3751,7 +3719,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
last_output_firmware(pipe->output_stage),
IA_CSS_BINARY_MODE_VIDEO,
in, out, NULL, &video_stage, NULL);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
@@ -3770,7 +3738,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
&yuv_scaler_binary[i],
&yuv_scaler_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -3789,17 +3757,17 @@ ERR:
return err;
}
-static enum ia_css_err
+static int
create_host_acc_pipeline(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
const struct ia_css_fw_info *fw;
unsigned int i;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (!pipe->stream))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
pipe->pipeline.num_execs = pipe->config.acc_num_execs;
@@ -3811,7 +3779,7 @@ create_host_acc_pipeline(struct ia_css_pipe *pipe) {
for (i = 0; fw; fw = fw->next)
{
err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
@@ -3820,7 +3788,7 @@ create_host_acc_pipeline(struct ia_css_pipe *pipe) {
struct ia_css_fw_info *fw = pipe->config.acc_stages[i];
err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
@@ -3832,7 +3800,7 @@ ERR:
}
/* Create stages for preview */
-static enum ia_css_err
+static int
create_host_preview_pipeline(struct ia_css_pipe *pipe) {
struct ia_css_pipeline_stage *copy_stage = NULL;
struct ia_css_pipeline_stage *preview_stage = NULL;
@@ -3841,7 +3809,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
struct ia_css_pipeline *me = NULL;
struct ia_css_binary *copy_binary, *preview_binary, *vf_pp_binary = NULL;
struct ia_css_frame *in_frame = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame *out_frame;
struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
bool need_in_frameinfo_memory = false;
@@ -3855,8 +3823,8 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_pipe_util_create_output_frames(out_frames);
@@ -3886,7 +3854,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
{
err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
IA_CSS_FRAME_FORMAT_RAW);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
in_frame = &me->in_frame;
@@ -3896,7 +3864,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
}
err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
out_frame = &me->out_frame[0];
@@ -3913,7 +3881,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&copy_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
in_frame = me->stages->args.out_frame[0];
#ifndef ISP2401
@@ -3949,7 +3917,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&preview_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
/* If we use copy iso preview, the input must be yuv iso raw */
preview_stage->args.copy_vf =
@@ -3969,7 +3937,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) {
in_frame = preview_stage->args.out_frame[0];
err = add_vf_pp_stage(pipe, in_frame, out_frame, vf_pp_binary,
&vf_pp_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
@@ -4001,11 +3969,11 @@ static void send_raw_frames(struct ia_css_pipe *pipe)
return;
}
-static enum ia_css_err
+static int
preview_start(struct ia_css_pipe *pipe) {
struct ia_css_pipeline *me;
struct ia_css_binary *copy_binary, *preview_binary, *vf_pp_binary = NULL;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipe *copy_pipe, *capture_pipe;
struct ia_css_pipe *acc_pipe;
enum sh_css_pipe_config_override copy_ovrd;
@@ -4016,8 +3984,8 @@ preview_start(struct ia_css_pipe *pipe) {
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
me = &pipe->pipeline;
@@ -4038,8 +4006,8 @@ preview_start(struct ia_css_pipe *pipe) {
#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
/* multi stream video needs mipi buffers */
err = send_mipi_frames(pipe);
- if (err != IA_CSS_SUCCESS) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
#endif
@@ -4059,7 +4027,7 @@ preview_start(struct ia_css_pipe *pipe) {
}
}
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
coord = &pipe->config.internal_frame_origin_bqs_on_sctbl;
params = pipe->stream->isp_params_configs;
}
@@ -4137,10 +4105,10 @@ preview_start(struct ia_css_pipe *pipe) {
return err;
}
-enum ia_css_err
+int
ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
const struct ia_css_buffer *buffer) {
- enum ia_css_err return_err = IA_CSS_SUCCESS;
+ int return_err = 0;
unsigned int thread_id;
enum sh_css_queue_id queue_id;
struct ia_css_pipeline *pipeline;
@@ -4156,8 +4124,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
if ((!pipe) || (!buffer))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
buf_type = buffer->type;
@@ -4177,7 +4145,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
}
}
if (!found_pipe)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
{
@@ -4192,7 +4160,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
}
}
if (!found_pipe)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
#endif
pipe_id = pipe->mode;
@@ -4205,36 +4173,36 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
(buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE) ||
(pipe_id >= IA_CSS_PIPE_ID_NUM))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
if (!ret_err)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
if (!ret_err)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if (!sh_css_sp_is_running())
{
IA_CSS_LOG("SP is not running!");
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
+ IA_CSS_LEAVE_ERR(-EBUSY);
/* SP is not running. The queues are not valid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
pipeline = &pipe->pipeline;
@@ -4251,24 +4219,24 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
{
if (!buffer->data.stats_3a) {
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_3a);
ddr_buffer.payload.s3a = *buffer->data.stats_3a;
} else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
{
if (!buffer->data.stats_dvs) {
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_dvs);
ddr_buffer.payload.dis = *buffer->data.stats_dvs;
} else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA)
{
if (!buffer->data.metadata) {
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.metadata);
ddr_buffer.payload.metadata = *buffer->data.metadata;
@@ -4279,8 +4247,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
|| (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME))
{
if (!buffer->data.frame) {
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.frame);
ddr_buffer.payload.frame.frame_data = buffer->data.frame->data;
@@ -4294,7 +4262,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
return_err = set_config_on_frame_enqueue(
&buffer->data.frame->info,
&ddr_buffer.payload.frame);
- if (return_err != IA_CSS_SUCCESS) {
+ if (return_err) {
IA_CSS_LEAVE_ERR(return_err);
return return_err;
}
@@ -4314,11 +4282,11 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
if ((!h_vbuf) || (h_vbuf->vptr == 0x0))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
- mmgr_store(h_vbuf->vptr,
+ hmm_store(h_vbuf->vptr,
(void *)(&ddr_buffer),
sizeof(struct sh_css_hmm_buffer));
if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
@@ -4328,8 +4296,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
if (!pipeline) {
ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
IA_CSS_LOG("pipeline is empty!");
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
for (stage = pipeline->stages; stage; stage = stage->next) {
@@ -4353,7 +4321,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
queue_id,
(uint32_t)h_vbuf->vptr);
#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
- if ((return_err == IA_CSS_SUCCESS) &&
+ if (!(return_err) &&
(buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)) {
IA_CSS_LOG("pfp: enqueued OF %d to q %d thread %d",
ddr_buffer.payload.frame.frame_data,
@@ -4362,14 +4330,14 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
#endif
}
- if (return_err == IA_CSS_SUCCESS)
+ if (!return_err)
{
if (sh_css_hmm_buffer_record_acquire(
h_vbuf, buf_type,
HOST_ADDRESS(ddr_buffer.kernel_ptr))) {
IA_CSS_LOG("send vbuf=%p", h_vbuf);
} else {
- return_err = IA_CSS_ERR_INTERNAL_ERROR;
+ return_err = -EINVAL;
IA_CSS_ERROR("hmm_buffer_record[]: no available slots\n");
}
}
@@ -4378,13 +4346,13 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
* Tell the SP which queues are not empty,
* by sending the software event.
*/
- if (return_err == IA_CSS_SUCCESS)
+ if (!return_err)
{
if (!sh_css_sp_is_running()) {
/* SP is not running. The queues are not valid */
IA_CSS_LOG("SP is not running!");
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ IA_CSS_LEAVE_ERR(-EBUSY);
+ return -EBUSY;
}
return_err = ia_css_bufq_enqueue_psys_event(
IA_CSS_PSYS_SW_EVENT_BUFFER_ENQUEUED,
@@ -4405,12 +4373,12 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
/*
* TODO: Free up the hmm memory space.
*/
-enum ia_css_err
+int
ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
struct ia_css_buffer *buffer) {
- enum ia_css_err return_err;
+ int return_err;
enum sh_css_queue_id queue_id;
- hrt_vaddress ddr_buffer_addr = (hrt_vaddress)0;
+ ia_css_ptr ddr_buffer_addr = (ia_css_ptr)0;
struct sh_css_hmm_buffer ddr_buffer;
enum ia_css_buffer_type buf_type;
enum ia_css_pipe_id pipe_id;
@@ -4422,8 +4390,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
if ((!pipe) || (!buffer))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
pipe_id = pipe->mode;
@@ -4437,35 +4405,35 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
if (!ret_err)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
if (!ret_err)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if (!sh_css_sp_is_running())
{
IA_CSS_LOG("SP is not running!");
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
+ IA_CSS_LEAVE_ERR(-EBUSY);
/* SP is not running. The queues are not valid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
return_err = ia_css_bufq_dequeue_buffer(queue_id,
(uint32_t *)&ddr_buffer_addr);
- if (return_err == IA_CSS_SUCCESS)
+ if (!return_err)
{
struct ia_css_frame *frame;
struct sh_css_hmm_buffer_record *hmm_buffer_record = NULL;
@@ -4477,7 +4445,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
ddr_buffer_addr, buf_type);
if (hmm_buffer_record) {
/* valid hmm_buffer_record found. Save the kernel_ptr
- * for validation after performing mmgr_load. The
+ * for validation after performing hmm_load. The
* vbuf handle and buffer_record can be released.
*/
kernel_ptr = hmm_buffer_record->kernel_ptr;
@@ -4486,11 +4454,11 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
} else {
IA_CSS_ERROR("hmm_buffer_record not found (0x%x) buf_type(%d)",
ddr_buffer_addr, buf_type);
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
- mmgr_load(ddr_buffer_addr,
+ hmm_load(ddr_buffer_addr,
&ddr_buffer,
sizeof(struct sh_css_hmm_buffer));
@@ -4503,8 +4471,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
IA_CSS_ERROR("expected: (0x%llx)", (u64)kernel_ptr);
IA_CSS_ERROR("actual: (0x%llx)", (u64)HOST_ADDRESS(ddr_buffer.kernel_ptr));
IA_CSS_ERROR("buf_type: %d\n", buf_type);
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if (ddr_buffer.kernel_ptr != 0) {
@@ -4529,7 +4497,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
* for 2401 it is done in ia_css_stream_destroy call
*/
return_err = free_mipi_frames(pipe);
- if (return_err != IA_CSS_SUCCESS) {
+ if (return_err) {
IA_CSS_LOG("free_mipi_frames() failed");
IA_CSS_LEAVE_ERR(return_err);
return return_err;
@@ -4537,6 +4505,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
#endif
pipe->stop_requested = false;
}
+ /* fall through */
case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:
case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
frame = (struct ia_css_frame *)HOST_ADDRESS(ddr_buffer.kernel_ptr);
@@ -4597,7 +4566,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
buffer->data.metadata->exp_id = ddr_buffer.payload.metadata.exp_id;
break;
default:
- return_err = IA_CSS_ERR_INTERNAL_ERROR;
+ return_err = -EINVAL;
break;
}
}
@@ -4607,13 +4576,13 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
* Tell the SP which queues are not full,
* by sending the software event.
*/
- if (return_err == IA_CSS_SUCCESS)
+ if (!return_err)
{
if (!sh_css_sp_is_running()) {
IA_CSS_LOG("SP is not running!");
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
+ IA_CSS_LEAVE_ERR(-EBUSY);
/* SP is not running. The queues are not valid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
ia_css_bufq_enqueue_psys_event(
IA_CSS_PSYS_SW_EVENT_BUFFER_DEQUEUED,
@@ -4656,16 +4625,16 @@ static enum ia_css_event_type convert_event_sp_to_host_domain[] = {
0, /* error if sp passes SH_CSS_SP_EVENT_NR_OF_TYPES as a valid event. */
};
-enum ia_css_err
+int
ia_css_dequeue_event(struct ia_css_event *event) {
return ia_css_dequeue_psys_event(event);
}
-enum ia_css_err
+int
ia_css_dequeue_psys_event(struct ia_css_event *event) {
enum ia_css_pipe_id pipe_id = 0;
u8 payload[4] = {0, 0, 0, 0};
- enum ia_css_err ret_err;
+ int ret_err;
/*TODO:
* a) use generic decoding function , same as the one used by sp.
@@ -4675,17 +4644,17 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) {
* to avoid flooding the logs when the host application
* uses polling. */
if (!event)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!sh_css_sp_is_running())
{
/* SP is not running. The queues are not valid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
/* dequeue the event (if any) from the psys event queue */
ret_err = ia_css_bufq_dequeue_psys_event(payload);
- if (ret_err != IA_CSS_SUCCESS)
+ if (ret_err)
return ret_err;
IA_CSS_LOG("event dequeued from psys event queue");
@@ -4717,7 +4686,7 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) {
event->timer_code = payload[2];
payload[0] = payload[1] = payload[2] = payload[3] = 0;
ret_err = ia_css_bufq_dequeue_psys_event(payload);
- if (ret_err != IA_CSS_SUCCESS) {
+ if (ret_err) {
/* no 2nd event ??? an error */
/* Putting IA_CSS_ERROR is resulting in failures in
* Merrifield smoke testing */
@@ -4771,7 +4740,7 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) {
pipe_id = (enum ia_css_pipe_id)payload[2];
/* Check to see if pipe still exists */
if (!event->pipe)
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
if (event->type == IA_CSS_EVENT_TYPE_FRAME_TAGGED) {
/* find the capture pipe that goes with this */
@@ -4796,7 +4765,7 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) {
&event->pipe->pipeline,
stage_num,
&event->fw_handle);
- if (ret_err != IA_CSS_SUCCESS) {
+ if (ret_err) {
IA_CSS_ERROR("Invalid stage num received for ACC event. stage_num:%u",
stage_num);
return ret_err;
@@ -4809,28 +4778,28 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) {
else
IA_CSS_LEAVE("event_id=%d", event->type);
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
ia_css_dequeue_isys_event(struct ia_css_event *event) {
u8 payload[4] = {0, 0, 0, 0};
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
/* We skip the IA_CSS_ENTER logging call
* to avoid flooding the logs when the host application
* uses polling. */
if (!event)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!sh_css_sp_is_running())
{
/* SP is not running. The queues are not valid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
err = ia_css_bufq_dequeue_isys_event(payload);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
IA_CSS_LOG("event dequeued from isys event queue");
@@ -4859,9 +4828,9 @@ acc_start(struct ia_css_pipe *pipe)
pipe->stream->config.mode);
}
-static enum ia_css_err
+static int
sh_css_pipe_start(struct ia_css_stream *stream) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipe *pipe;
enum ia_css_pipe_id pipe_id;
@@ -4871,14 +4840,14 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
if (!stream)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
pipe = stream->last_pipe;
if (!pipe)
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
pipe_id = pipe->mode;
@@ -4910,14 +4879,14 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
acc_start(pipe);
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
/* DH regular multi pipe - not continuous mode: start the next pipes too */
if (!stream->config.continuous)
{
int i;
- for (i = 1; i < stream->num_pipes && IA_CSS_SUCCESS == err ; i++) {
+ for (i = 1; i < stream->num_pipes && 0 == err ; i++) {
switch (stream->pipes[i]->mode) {
case IA_CSS_PIPE_ID_PREVIEW:
stream->pipes[i]->stop_requested = false;
@@ -4940,11 +4909,11 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
acc_start(stream->pipes[i]);
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
}
}
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -4960,7 +4929,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
sh_css_invalidate_params(stream);
err = sh_css_param_update_isp_params(pipe,
stream->isp_params_configs, true, NULL);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4972,9 +4941,9 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
if (!sh_css_sp_is_running())
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
+ IA_CSS_LEAVE_ERR_PRIVATE(-EBUSY);
/* SP is not running. The queues are not valid */
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
ia_css_bufq_enqueue_psys_event(IA_CSS_PSYS_SW_EVENT_START_STREAM,
(uint8_t)thread_id, 0, 0);
@@ -5005,8 +4974,8 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
copy_pipe = pipe->pipe_settings.video.copy_pipe;
if (!copy_pipe) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(copy_pipe),
&thread_id);
@@ -5025,8 +4994,8 @@ sh_css_pipe_start(struct ia_css_stream *stream) {
capture_pipe = pipe->pipe_settings.video.capture_pipe;
if (!capture_pipe) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
&thread_id);
@@ -5087,39 +5056,39 @@ sh_css_continuous_is_enabled(uint8_t pipe_num)
}
/* ISP2400 */
-enum ia_css_err
+int
ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream,
int *buffer_depth) {
if (!buffer_depth)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_max_buffer_depth() enter: void\n");
(void)stream;
*buffer_depth = NUM_CONTINUOUS_FRAMES;
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_set_buffer_depth() enter: num_frames=%d\n", buffer_depth);
(void)stream;
if (buffer_depth > NUM_CONTINUOUS_FRAMES || buffer_depth < 1)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* ok, value allowed */
stream->config.target_num_cont_raw_buf = buffer_depth;
/* TODO: check what to regarding initialization */
- return IA_CSS_SUCCESS;
+ return 0;
}
/* ISP2401 */
-enum ia_css_err
+int
ia_css_stream_get_buffer_depth(struct ia_css_stream *stream,
int *buffer_depth) {
if (!buffer_depth)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_buffer_depth() enter: void\n");
(void)stream;
*buffer_depth = stream->config.target_num_cont_raw_buf;
- return IA_CSS_SUCCESS;
+ return 0;
}
/*
@@ -5129,10 +5098,10 @@ ia_css_stream_get_buffer_depth(struct ia_css_stream *stream,
* Refer to "Local prototypes" for more info.
*/
/* ISP2401 */
-static enum ia_css_err
+static int
sh_css_pipes_stop(struct ia_css_stream *stream)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipe *main_pipe;
enum ia_css_pipe_id main_pipe_id;
int i;
@@ -5141,7 +5110,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream)
if (!stream)
{
IA_CSS_LOG("stream does NOT exist!");
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto ERR;
}
@@ -5150,7 +5119,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream)
if (!main_pipe)
{
IA_CSS_LOG("main_pipe does NOT exist!");
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto ERR;
}
@@ -5183,7 +5152,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream)
* the CSS driver should capture these error code and
* handle it in the driver exception handling mechanism.
*/
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
goto ERR;
}
}
@@ -5211,7 +5180,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream)
assert(copy_pipe);
if (!copy_pipe) {
IA_CSS_LOG("Copy Pipe does NOT exist!");
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto ERR;
}
@@ -5325,7 +5294,7 @@ sh_css_get_mipi_sizes_for_check(const unsigned int port, const unsigned int idx)
}
#endif
-static enum ia_css_err sh_css_pipe_configure_output(
+static int sh_css_pipe_configure_output(
struct ia_css_pipe *pipe,
unsigned int width,
unsigned int height,
@@ -5333,17 +5302,17 @@ static enum ia_css_err sh_css_pipe_configure_output(
enum ia_css_frame_format format,
unsigned int idx)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
- IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, paddaed width = %d, format = %d, idx = %d",
+ IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, padded width = %d, format = %d, idx = %d",
pipe, width, height, padded_width, format, idx);
if (!pipe) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
err = ia_css_util_check_res(width, height);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -5357,16 +5326,16 @@ static enum ia_css_err sh_css_pipe_configure_output(
format,
padded_width);
}
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-static enum ia_css_err
+static int
sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe,
struct ia_css_shading_info *shading_info,
struct ia_css_pipe_config *pipe_config)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_binary *binary = NULL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
@@ -5390,17 +5359,17 @@ sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe,
/* When the pipe does not have a binary which has the shading
* correction, this function does not need to fill the shading
* information. It is not a error case, and then
- * this function should return IA_CSS_SUCCESS.
+ * this function should return 0.
*/
memset(shading_info, 0, sizeof(*shading_info));
}
return err;
}
-static enum ia_css_err
+static int
sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe,
struct ia_css_grid_info *info) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_binary *binary = NULL;
assert(pipe);
@@ -5413,7 +5382,7 @@ sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe,
if (binary)
{
err = ia_css_binary_3a_grid_info(binary, info, pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
} else
memset(&info->s3a_grid, 0, sizeof(info->s3a_grid));
@@ -5457,7 +5426,7 @@ ERR :
* @brief Check if a format is supported by the pipe.
*
*/
-static enum ia_css_err
+static int
ia_css_pipe_check_format(struct ia_css_pipe *pipe,
enum ia_css_frame_format format) {
const enum ia_css_frame_format *supported_formats;
@@ -5470,8 +5439,8 @@ ia_css_pipe_check_format(struct ia_css_pipe *pipe,
if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info)
{
IA_CSS_ERROR("Pipe or binary info is not set");
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
supported_formats = pipe->pipe_settings.video.video_binary.info->output_formats;
@@ -5487,21 +5456,21 @@ ia_css_pipe_check_format(struct ia_css_pipe *pipe,
if (!found)
{
IA_CSS_ERROR("Requested format is not supported by binary");
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
} else
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
}
-static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
+static int load_video_binaries(struct ia_css_pipe *pipe)
{
struct ia_css_frame_info video_in_info, tnr_info,
*video_vf_info, video_bds_out_info, *pipe_out_info, *pipe_vf_out_info;
bool online;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool continuous = pipe->stream->config.continuous;
unsigned int i;
unsigned int num_output_pins;
@@ -5520,7 +5489,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
* All are always reset at the same time anyway.
*/
if (mycs->video_binary.info)
- return IA_CSS_SUCCESS;
+ return 0;
online = pipe->stream->config.online;
pipe_out_info = &pipe->output_info[0];
@@ -5534,19 +5503,19 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
* This is checked in the binary_find(), so no need to check it here
*/
err = ia_css_util_check_input(&pipe->stream->config, false, false);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
/* cannot have online video and input_mode memory */
if (online && pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
err = ia_css_util_check_vf_out_info(pipe_out_info,
pipe_vf_out_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
} else {
err = ia_css_frame_check_info(pipe_out_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -5581,19 +5550,19 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
pipe_out_info,
NULL,
&cas_scaler_descr);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
sizeof(struct ia_css_binary), GFP_KERNEL);
if (!mycs->yuv_scaler_binary) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
return err;
}
mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage
* sizeof(bool), GFP_KERNEL);
if (!mycs->is_output_stage) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
return err;
}
for (i = 0; i < cas_scaler_descr.num_stage; i++) {
@@ -5607,7 +5576,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
&cas_scaler_descr.vf_info[i]);
err = ia_css_binary_find(&yuv_scaler_descr,
&mycs->yuv_scaler_binary[i]);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
kfree(mycs->is_output_stage);
mycs->is_output_stage = NULL;
return err;
@@ -5624,7 +5593,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
&video_descr, &video_in_info, &video_bds_out_info, &video_bin_out_info,
video_vf_info,
pipe->stream->config.left_padding);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
/* In the case where video_vf_info is not NULL, this allows
@@ -5635,7 +5604,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
err = ia_css_binary_find(&video_descr,
&mycs->video_binary);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
if (video_vf_info) {
/* This will do another video binary lookup later for YUV_LINE format*/
need_vf_pp = true;
@@ -5677,7 +5646,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
/* restore original vf_info format */
ia_css_frame_info_set_format(video_vf_info,
vf_info_format);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
}
@@ -5712,7 +5681,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
err = load_copy_binary(pipe,
&mycs->copy_binary,
&mycs->video_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
#else
@@ -5739,14 +5708,14 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
err = ia_css_binary_find(&vf_pp_descr,
&mycs->vf_pp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
#endif
err = allocate_delay_frames(pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
if (mycs->video_binary.info->sp.enable.block_output) {
@@ -5755,7 +5724,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
tnr_info = mycs->video_binary.out_frame_info[0];
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
/* Select resolution for TNR. If
* output_system_in_resolution(GDC_out_resolution) is
* being used, then select that as it will also be in resolution for
@@ -5794,14 +5763,14 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
err = ia_css_frame_allocate_from_info(
&mycs->tnr_frames[i],
&tnr_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
IA_CSS_LEAVE_PRIVATE("");
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
unload_video_binaries(struct ia_css_pipe *pipe) {
unsigned int i;
@@ -5809,8 +5778,8 @@ unload_video_binaries(struct ia_css_pipe *pipe) {
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_binary_unload(&pipe->pipe_settings.video.copy_binary);
ia_css_binary_unload(&pipe->pipe_settings.video.video_binary);
@@ -5824,14 +5793,14 @@ unload_video_binaries(struct ia_css_pipe *pipe) {
kfree(pipe->pipe_settings.video.yuv_scaler_binary);
pipe->pipe_settings.video.yuv_scaler_binary = NULL;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-static enum ia_css_err video_start(struct ia_css_pipe *pipe)
+static int video_start(struct ia_css_pipe *pipe)
{
struct ia_css_binary *copy_binary;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipe *copy_pipe, *capture_pipe;
enum sh_css_pipe_config_override copy_ovrd;
enum ia_css_input_mode video_pipe_input_mode;
@@ -5841,8 +5810,8 @@ static enum ia_css_err video_start(struct ia_css_pipe *pipe)
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
video_pipe_input_mode = pipe->stream->config.mode;
@@ -5858,7 +5827,7 @@ static enum ia_css_err video_start(struct ia_css_pipe *pipe)
#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
err = send_mipi_frames(pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
#endif
@@ -5876,7 +5845,7 @@ static enum ia_css_err video_start(struct ia_css_pipe *pipe)
}
}
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
coord = &pipe->config.internal_frame_origin_bqs_on_sctbl;
params = pipe->stream->isp_params_configs;
}
@@ -5932,7 +5901,7 @@ static enum ia_css_err video_start(struct ia_css_pipe *pipe)
}
static
-enum ia_css_err sh_css_pipe_get_viewfinder_frame_info(
+int sh_css_pipe_get_viewfinder_frame_info(
struct ia_css_pipe *pipe,
struct ia_css_frame_info *info,
unsigned int idx)
@@ -5947,7 +5916,7 @@ enum ia_css_err sh_css_pipe_get_viewfinder_frame_info(
if (pipe->mode == IA_CSS_PIPE_ID_CAPTURE &&
(pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW ||
pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER))
- return IA_CSS_ERR_MODE_HAS_NO_VIEWFINDER;
+ return -EINVAL;
/* offline video does not generate viewfinder output */
*info = pipe->vf_output_info[idx];
@@ -5960,27 +5929,27 @@ enum ia_css_err sh_css_pipe_get_viewfinder_frame_info(
info->padded_width, info->format,
info->raw_bit_depth, info->raw_bayer_order);
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width,
unsigned int height, unsigned int min_width,
enum ia_css_frame_format format,
unsigned int idx) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, min_width = %d, format = %d, idx = %d\n",
pipe, width, height, min_width, format, idx);
if (!pipe)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
err = ia_css_util_check_res(width, height);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -5992,13 +5961,13 @@ sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width,
ia_css_frame_info_init(&pipe->vf_output_info[idx], width, height,
format, min_width);
}
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-static enum ia_css_err load_copy_binaries(struct ia_css_pipe *pipe)
+static int load_copy_binaries(struct ia_css_pipe *pipe)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(pipe);
IA_CSS_ENTER_PRIVATE("");
@@ -6006,14 +5975,14 @@ static enum ia_css_err load_copy_binaries(struct ia_css_pipe *pipe)
assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
pipe->mode == IA_CSS_PIPE_ID_COPY);
if (pipe->pipe_settings.capture.copy_binary.info)
- return IA_CSS_SUCCESS;
+ return 0;
err = ia_css_frame_check_info(&pipe->output_info[0]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
err = verify_copy_out_frame_format(pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
err = load_copy_binary(pipe,
@@ -6034,7 +6003,7 @@ static bool need_capture_pp(
assert(pipe);
assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE);
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
/* ldc and capture_pp are not supported in the same pipeline */
if (need_capt_ldc(pipe) == true)
return false;
@@ -6071,13 +6040,13 @@ static bool need_capt_ldc(
return (pipe->extra_config.enable_dvs_6axis) ? true : false;
}
-static enum ia_css_err set_num_primary_stages(unsigned int *num,
+static int set_num_primary_stages(unsigned int *num,
enum ia_css_pipe_version version)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if (!num)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
switch (version) {
case IA_CSS_PIPE_VERSION_2_6_1:
@@ -6088,14 +6057,14 @@ static enum ia_css_err set_num_primary_stages(unsigned int *num,
*num = NUM_PRIMARY_STAGES;
break;
default:
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
break;
}
return err;
}
-static enum ia_css_err load_primary_binaries(
+static int load_primary_binaries(
struct ia_css_pipe *pipe)
{
bool online = false;
@@ -6113,10 +6082,11 @@ static enum ia_css_err load_primary_binaries(
*vf_pp_in_info, *pipe_out_info,
*pipe_vf_out_info, *capt_pp_in_info,
capt_ldc_out_info;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_capture_settings *mycs;
unsigned int i;
bool need_extra_yuv_scaler = false;
+ struct ia_css_binary_descr prim_descr[MAX_NUM_PRIMARY_STAGES];
IA_CSS_ENTER_PRIVATE("");
assert(pipe);
@@ -6136,24 +6106,24 @@ static enum ia_css_err load_primary_binaries(
pipe_vf_out_info = &pipe->vf_output_info[0];
if (mycs->primary_binary[0].info)
- return IA_CSS_SUCCESS;
+ return 0;
err = set_num_primary_stages(&mycs->num_primary_stage,
pipe->config.isp_pipe_version);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
err = ia_css_util_check_vf_out_info(pipe_out_info, pipe_vf_out_info);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
} else {
err = ia_css_frame_check_info(pipe_out_info);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6187,18 +6157,8 @@ static enum ia_css_err load_primary_binaries(
capt_pp_out_info.res.height /= MAX_PREFERRED_YUV_DS_PER_STEP;
ia_css_frame_info_set_width(&capt_pp_out_info, capt_pp_out_info.res.width, 0);
- /*
- * WARNING: The #if def flag has been added below as a
- * temporary solution to solve the problem of enabling the
- * view finder in a single binary in a capture flow. The
- * vf-pp stage has been removed for Skycam in the solution
- * provided. The vf-pp stage should be re-introduced when
- * required. This should not be considered as a clean solution.
- * Proper investigation should be done to come up with the clean
- * solution.
- * */
need_extra_yuv_scaler = need_downscaling(capt_pp_out_info.res,
- pipe_out_info->res);
+ pipe_out_info->res);
if (need_extra_yuv_scaler) {
struct ia_css_cas_binary_descr cas_scaler_descr = { };
@@ -6208,7 +6168,7 @@ static enum ia_css_err load_primary_binaries(
pipe_out_info,
NULL,
&cas_scaler_descr);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6216,14 +6176,14 @@ static enum ia_css_err load_primary_binaries(
mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
sizeof(struct ia_css_binary), GFP_KERNEL);
if (!mycs->yuv_scaler_binary) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage *
sizeof(bool), GFP_KERNEL);
if (!mycs->is_output_stage) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6238,7 +6198,7 @@ static enum ia_css_err load_primary_binaries(
&cas_scaler_descr.vf_info[i]);
err = ia_css_binary_find(&yuv_scaler_descr,
&mycs->yuv_scaler_binary[i]);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6251,29 +6211,30 @@ static enum ia_css_err load_primary_binaries(
/* TODO Do we disable ldc for skycam */
need_ldc = need_capt_ldc(pipe);
-
- if (atomisp_hw_is_isp2401 && need_ldc) {
+ if (IS_ISP2401 && need_ldc) {
/* ldc and capt_pp are not supported in the same pipeline */
struct ia_css_binary_descr capt_ldc_descr;
ia_css_pipe_get_ldc_binarydesc(pipe,
- &capt_ldc_descr, &prim_out_info,
- &capt_pp_out_info);
+ &capt_ldc_descr, &prim_out_info,
+ &capt_pp_out_info);
err = ia_css_binary_find(&capt_ldc_descr,
- &mycs->capture_ldc_binary);
- if (err != IA_CSS_SUCCESS) {
+ &mycs->capture_ldc_binary);
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
need_pp = 0;
need_ldc = 0;
}
+
+ /* we build up the pipeline starting at the end */
+ /* Capture post-processing */
if (need_pp) {
struct ia_css_binary_descr capture_pp_descr;
- struct ia_css_binary_descr prim_descr[MAX_NUM_PRIMARY_STAGES];
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
capt_pp_in_info = need_ldc ? &capt_ldc_out_info : &prim_out_info;
else
capt_pp_in_info = &prim_out_info;
@@ -6283,7 +6244,7 @@ static enum ia_css_err load_primary_binaries(
&capt_pp_out_info, &vf_info);
err = ia_css_binary_find(&capture_pp_descr,
&mycs->capture_pp_binary);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6297,92 +6258,92 @@ static enum ia_css_err load_primary_binaries(
err = ia_css_binary_find(&capt_ldc_descr,
&mycs->capture_ldc_binary);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
- } else {
- prim_out_info = *pipe_out_info;
}
+ } else {
+ prim_out_info = *pipe_out_info;
+ }
- /* Primary */
- for (i = 0; i < mycs->num_primary_stage; i++) {
- struct ia_css_frame_info *local_vf_info = NULL;
+ /* Primary */
+ for (i = 0; i < mycs->num_primary_stage; i++) {
+ struct ia_css_frame_info *local_vf_info = NULL;
- if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
- (i == mycs->num_primary_stage - 1))
- local_vf_info = &vf_info;
- ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], &prim_in_info,
- &prim_out_info, local_vf_info, i);
- err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
- if (err != IA_CSS_SUCCESS) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
+ if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] &&
+ (i == mycs->num_primary_stage - 1))
+ local_vf_info = &vf_info;
+ ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], &prim_in_info,
+ &prim_out_info, local_vf_info, i);
+ err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
}
+ }
- /* Viewfinder post-processing */
- if (need_pp)
- vf_pp_in_info = &mycs->capture_pp_binary.vf_frame_info;
- else
- vf_pp_in_info = &mycs->primary_binary[mycs->num_primary_stage - 1].vf_frame_info;
+ /* Viewfinder post-processing */
+ if (need_pp)
+ vf_pp_in_info = &mycs->capture_pp_binary.vf_frame_info;
+ else
+ vf_pp_in_info = &mycs->primary_binary[mycs->num_primary_stage - 1].vf_frame_info;
- /*
- * WARNING: The #if def flag has been added below as a
- * temporary solution to solve the problem of enabling the
- * view finder in a single binary in a capture flow. The
- * vf-pp stage has been removed for Skycam in the solution
- * provided. The vf-pp stage should be re-introduced when
- * required. Thisshould not be considered as a clean solution.
- * Proper * investigation should be done to come up with the clean
- * solution.
- * */
- if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
- struct ia_css_binary_descr vf_pp_descr;
-
- ia_css_pipe_get_vfpp_binarydesc(pipe,
- &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
- err = ia_css_binary_find(&vf_pp_descr, &mycs->vf_pp_binary);
- if (err != IA_CSS_SUCCESS) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
- }
- err = allocate_delay_frames(pipe);
+ /*
+ * WARNING: The #if def flag has been added below as a
+ * temporary solution to solve the problem of enabling the
+ * view finder in a single binary in a capture flow. The
+ * vf-pp stage has been removed for Skycam in the solution
+ * provided. The vf-pp stage should be re-introduced when
+ * required. Thisshould not be considered as a clean solution.
+ * Proper * investigation should be done to come up with the clean
+ * solution.
+ * */
+ if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
+ struct ia_css_binary_descr vf_pp_descr;
- if (err != IA_CSS_SUCCESS)
+ ia_css_pipe_get_vfpp_binarydesc(pipe,
+ &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
+ err = ia_css_binary_find(&vf_pp_descr, &mycs->vf_pp_binary);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
+ }
+ }
+ err = allocate_delay_frames(pipe);
+
+ if (err)
+ return err;
#ifdef USE_INPUT_SYSTEM_VERSION_2401
- /* When the input system is 2401, only the Direct Sensor Mode
- * Offline Capture uses the ISP copy binary.
- */
- need_isp_copy_binary = !online && sensor;
+ /* When the input system is 2401, only the Direct Sensor Mode
+ * Offline Capture uses the ISP copy binary.
+ */
+ need_isp_copy_binary = !online && sensor;
#else
- need_isp_copy_binary = !online && !continuous && !memory;
+ need_isp_copy_binary = !online && !continuous && !memory;
#endif
- /* ISP Copy */
- if (need_isp_copy_binary) {
- err = load_copy_binary(pipe,
- &mycs->copy_binary,
- &mycs->primary_binary[0]);
- if (err != IA_CSS_SUCCESS) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
+ /* ISP Copy */
+ if (need_isp_copy_binary) {
+ err = load_copy_binary(pipe,
+ &mycs->copy_binary,
+ &mycs->primary_binary[0]);
+ if (err) {
+ IA_CSS_LEAVE_ERR_PRIVATE(err);
+ return err;
}
}
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
allocate_delay_frames(struct ia_css_pipe *pipe) {
unsigned int num_delay_frames = 0, i = 0;
unsigned int dvs_frame_delay = 0;
struct ia_css_frame_info ref_info;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
enum ia_css_pipe_id mode = IA_CSS_PIPE_ID_VIDEO;
struct ia_css_frame **delay_frames = NULL;
@@ -6391,7 +6352,7 @@ allocate_delay_frames(struct ia_css_pipe *pipe) {
if (!pipe)
{
IA_CSS_ERROR("Invalid args - pipe %p", pipe);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
mode = pipe->mode;
@@ -6447,7 +6408,7 @@ allocate_delay_frames(struct ia_css_pipe *pipe) {
}
break;
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
ref_info.raw_bit_depth = SH_CSS_REF_BIT_DEPTH;
@@ -6456,14 +6417,14 @@ allocate_delay_frames(struct ia_css_pipe *pipe) {
for (i = 0; i < num_delay_frames; i++)
{
err = ia_css_frame_allocate_from_info(&delay_frames[i], &ref_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
IA_CSS_LEAVE_PRIVATE("");
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err load_advanced_binaries(
+static int load_advanced_binaries(
struct ia_css_pipe *pipe) {
struct ia_css_frame_info pre_in_info, gdc_in_info,
post_in_info, post_out_info,
@@ -6471,7 +6432,7 @@ static enum ia_css_err load_advanced_binaries(
*pipe_vf_out_info;
bool need_pp;
bool need_isp_copy = true;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("");
@@ -6479,13 +6440,13 @@ static enum ia_css_err load_advanced_binaries(
assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE ||
pipe->mode == IA_CSS_PIPE_ID_COPY);
if (pipe->pipe_settings.capture.pre_isp_binary.info)
- return IA_CSS_SUCCESS;
+ return 0;
pipe_out_info = &pipe->output_info[0];
pipe_vf_out_info = &pipe->vf_output_info[0];
vf_info = *pipe_vf_out_info;
err = ia_css_util_check_vf_out_info(pipe_out_info, &vf_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
need_pp = need_capture_pp(pipe);
@@ -6501,7 +6462,7 @@ static enum ia_css_err load_advanced_binaries(
&capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
err = ia_css_binary_find(&capture_pp_descr,
&pipe->pipe_settings.capture.capture_pp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
} else {
post_out_info = *pipe_out_info;
@@ -6515,7 +6476,7 @@ static enum ia_css_err load_advanced_binaries(
&post_gdc_descr, &post_in_info, &post_out_info, &vf_info);
err = ia_css_binary_find(&post_gdc_descr,
&pipe->pipe_settings.capture.post_isp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -6527,7 +6488,7 @@ static enum ia_css_err load_advanced_binaries(
&pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
err = ia_css_binary_find(&gdc_descr,
&pipe->pipe_settings.capture.anr_gdc_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
pipe->pipe_settings.capture.anr_gdc_binary.left_padding =
@@ -6541,7 +6502,7 @@ static enum ia_css_err load_advanced_binaries(
&pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
err = ia_css_binary_find(&pre_gdc_descr,
&pipe->pipe_settings.capture.pre_isp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
pipe->pipe_settings.capture.pre_isp_binary.left_padding =
@@ -6563,7 +6524,7 @@ static enum ia_css_err load_advanced_binaries(
&vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
err = ia_css_binary_find(&vf_pp_descr,
&pipe->pipe_settings.capture.vf_pp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -6580,10 +6541,10 @@ static enum ia_css_err load_advanced_binaries(
return err;
}
-static enum ia_css_err load_bayer_isp_binaries(
+static int load_bayer_isp_binaries(
struct ia_css_pipe *pipe) {
struct ia_css_frame_info pre_isp_in_info, *pipe_out_info;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_binary_descr pre_de_descr;
IA_CSS_ENTER_PRIVATE("");
@@ -6593,10 +6554,10 @@ static enum ia_css_err load_bayer_isp_binaries(
pipe_out_info = &pipe->output_info[0];
if (pipe->pipe_settings.capture.pre_isp_binary.info)
- return IA_CSS_SUCCESS;
+ return 0;
err = ia_css_frame_check_info(pipe_out_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
ia_css_pipe_get_pre_de_binarydesc(pipe, &pre_de_descr,
@@ -6609,7 +6570,7 @@ static enum ia_css_err load_bayer_isp_binaries(
return err;
}
-static enum ia_css_err load_low_light_binaries(
+static int load_low_light_binaries(
struct ia_css_pipe *pipe) {
struct ia_css_frame_info pre_in_info, anr_in_info,
post_in_info, post_out_info,
@@ -6617,7 +6578,7 @@ static enum ia_css_err load_low_light_binaries(
*vf_pp_in_info;
bool need_pp;
bool need_isp_copy = true;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("");
assert(pipe);
@@ -6625,14 +6586,14 @@ static enum ia_css_err load_low_light_binaries(
pipe->mode == IA_CSS_PIPE_ID_COPY);
if (pipe->pipe_settings.capture.pre_isp_binary.info)
- return IA_CSS_SUCCESS;
+ return 0;
pipe_vf_out_info = &pipe->vf_output_info[0];
pipe_out_info = &pipe->output_info[0];
vf_info = *pipe_vf_out_info;
err = ia_css_util_check_vf_out_info(pipe_out_info,
&vf_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
need_pp = need_capture_pp(pipe);
@@ -6648,7 +6609,7 @@ static enum ia_css_err load_low_light_binaries(
&capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
err = ia_css_binary_find(&capture_pp_descr,
&pipe->pipe_settings.capture.capture_pp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
} else {
post_out_info = *pipe_out_info;
@@ -6662,7 +6623,7 @@ static enum ia_css_err load_low_light_binaries(
&post_anr_descr, &post_in_info, &post_out_info, &vf_info);
err = ia_css_binary_find(&post_anr_descr,
&pipe->pipe_settings.capture.post_isp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -6674,7 +6635,7 @@ static enum ia_css_err load_low_light_binaries(
&pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
err = ia_css_binary_find(&anr_descr,
&pipe->pipe_settings.capture.anr_gdc_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
pipe->pipe_settings.capture.anr_gdc_binary.left_padding =
@@ -6688,7 +6649,7 @@ static enum ia_css_err load_low_light_binaries(
&pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
err = ia_css_binary_find(&pre_anr_descr,
&pipe->pipe_settings.capture.pre_isp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
pipe->pipe_settings.capture.pre_isp_binary.left_padding =
@@ -6710,7 +6671,7 @@ static enum ia_css_err load_low_light_binaries(
&vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
err = ia_css_binary_find(&vf_pp_descr,
&pipe->pipe_settings.capture.vf_pp_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
@@ -6727,7 +6688,8 @@ static enum ia_css_err load_low_light_binaries(
return err;
}
-static bool copy_on_sp(struct ia_css_pipe *pipe) {
+static bool copy_on_sp(struct ia_css_pipe *pipe)
+{
bool rval;
assert(pipe);
@@ -6746,9 +6708,9 @@ static bool copy_on_sp(struct ia_css_pipe *pipe) {
return rval;
}
-static enum ia_css_err load_capture_binaries(
+static int load_capture_binaries(
struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool must_be_raw;
IA_CSS_ENTER_PRIVATE("");
@@ -6757,8 +6719,8 @@ static enum ia_css_err load_capture_binaries(
pipe->mode == IA_CSS_PIPE_ID_COPY);
if (pipe->pipe_settings.capture.primary_binary[0].info) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
/* in primary, advanced,low light or bayer,
@@ -6768,7 +6730,7 @@ static enum ia_css_err load_capture_binaries(
pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER ||
pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT;
err = ia_css_util_check_input(&pipe->stream->config, must_be_raw, false);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6780,15 +6742,15 @@ static enum ia_css_err load_capture_binaries(
1,
IA_CSS_FRAME_FORMAT_BINARY_8,
0);
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
switch (pipe->config.default_capture_config.mode) {
case IA_CSS_CAPTURE_MODE_RAW:
err = load_copy_binaries(pipe);
#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2401)
- if (err == IA_CSS_SUCCESS)
+ if (!err)
pipe->pipe_settings.capture.copy_binary.online = pipe->stream->config.online;
#endif
break;
@@ -6805,7 +6767,7 @@ static enum ia_css_err load_capture_binaries(
err = load_low_light_binaries(pipe);
break;
}
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -6814,7 +6776,7 @@ static enum ia_css_err load_capture_binaries(
return err;
}
-static enum ia_css_err
+static int
unload_capture_binaries(struct ia_css_pipe *pipe) {
unsigned int i;
@@ -6822,8 +6784,8 @@ unload_capture_binaries(struct ia_css_pipe *pipe) {
if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY)))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_binary_unload(&pipe->pipe_settings.capture.copy_binary);
for (i = 0; i < MAX_NUM_PRIMARY_STAGES; i++)
@@ -6843,8 +6805,8 @@ unload_capture_binaries(struct ia_css_pipe *pipe) {
kfree(pipe->pipe_settings.capture.yuv_scaler_binary);
pipe->pipe_settings.capture.yuv_scaler_binary = NULL;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
static bool
@@ -6895,14 +6857,14 @@ need_yuv_scaler_stage(const struct ia_css_pipe *pipe) {
/* TODO: it is temporarily created from ia_css_pipe_create_cas_scaler_desc */
/* which has some hard-coded knowledge which prevents reuse of the function. */
/* Later, merge this with ia_css_pipe_create_cas_scaler_desc */
-static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output(
+static int ia_css_pipe_create_cas_scaler_desc_single_output(
struct ia_css_frame_info *cas_scaler_in_info,
struct ia_css_frame_info *cas_scaler_out_info,
struct ia_css_frame_info *cas_scaler_vf_info,
struct ia_css_cas_binary_descr *descr) {
unsigned int i;
unsigned int hor_ds_factor = 0, ver_ds_factor = 0;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_frame_info tmp_in_info;
unsigned int max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP;
@@ -6932,30 +6894,30 @@ static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output(
descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
GFP_KERNEL);
if (!descr->in_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->internal_out_info = kmalloc(descr->num_stage * sizeof(
struct ia_css_frame_info), GFP_KERNEL);
if (!descr->internal_out_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
GFP_KERNEL);
if (!descr->out_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
GFP_KERNEL);
if (!descr->vf_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
if (!descr->is_output_stage) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
@@ -7015,7 +6977,7 @@ ERR:
}
/* FIXME: merge most of this and single output version */
-static enum ia_css_err ia_css_pipe_create_cas_scaler_desc(
+static int ia_css_pipe_create_cas_scaler_desc(
struct ia_css_pipe *pipe,
struct ia_css_cas_binary_descr *descr) {
struct ia_css_frame_info in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
@@ -7027,7 +6989,7 @@ static enum ia_css_err ia_css_pipe_create_cas_scaler_desc(
ver_scale_factor[IA_CSS_PIPE_MAX_OUTPUT_STAGE],
scale_factor = 0;
unsigned int num_stages = 0;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP;
@@ -7076,30 +7038,30 @@ static enum ia_css_err ia_css_pipe_create_cas_scaler_desc(
descr->in_info = kmalloc_array(descr->num_stage,
sizeof(struct ia_css_frame_info), GFP_KERNEL);
if (!descr->in_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->internal_out_info = kmalloc(descr->num_stage * sizeof(
struct ia_css_frame_info), GFP_KERNEL);
if (!descr->internal_out_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
GFP_KERNEL);
if (!descr->out_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info),
GFP_KERNEL);
if (!descr->vf_info) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
if (!descr->is_output_stage) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
@@ -7190,9 +7152,9 @@ static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr
"ia_css_pipe_destroy_cas_scaler_desc() leave\n");
}
-static enum ia_css_err
+static int
load_yuvpp_binaries(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool need_scaler = false;
struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
struct ia_css_yuvpp_settings *mycs;
@@ -7211,7 +7173,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
/* Set both must_be_raw and must_be_yuv to false then yuvpp can take rgb inputs */
err = ia_css_util_check_input(&pipe->stream->config, false, false);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
mycs = &pipe->pipe_settings.yuvpp;
@@ -7221,7 +7183,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
if (pipe->vf_output_info[i].res.width != 0) {
err = ia_css_util_check_vf_out_info(&pipe->output_info[i],
&pipe->vf_output_info[i]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
vf_pp_in_info[i] = NULL;
@@ -7237,20 +7199,20 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
err = ia_css_pipe_create_cas_scaler_desc(pipe,
&cas_scaler_descr);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
mycs->num_output = cas_scaler_descr.num_output_stage;
mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
sizeof(struct ia_css_binary), GFP_KERNEL);
if (!mycs->yuv_scaler_binary) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage *
sizeof(bool), GFP_KERNEL);
if (!mycs->is_output_stage) {
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
for (i = 0; i < cas_scaler_descr.num_stage; i++) {
@@ -7262,7 +7224,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
&cas_scaler_descr.vf_info[i]);
err = ia_css_binary_find(&yuv_scaler_descr,
&mycs->yuv_scaler_binary[i]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
@@ -7309,7 +7271,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
&mycs->copy_binary,
next_binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
/*
@@ -7358,7 +7320,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
GFP_KERNEL);
if (!mycs->vf_pp_binary)
{
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto ERR;
}
@@ -7371,13 +7333,13 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) {
ia_css_pipe_get_vfpp_binarydesc(pipe,
&vf_pp_descr, vf_pp_in_info[i], &pipe->vf_output_info[i]);
err = ia_css_binary_find(&vf_pp_descr, &mycs->vf_pp_binary[i]);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
}
}
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
ERR:
@@ -7390,7 +7352,7 @@ ERR:
return err;
}
-static enum ia_css_err
+static int
unload_yuvpp_binaries(struct ia_css_pipe *pipe) {
unsigned int i;
@@ -7398,8 +7360,8 @@ unload_yuvpp_binaries(struct ia_css_pipe *pipe) {
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_binary_unload(&pipe->pipe_settings.yuvpp.copy_binary);
for (i = 0; i < pipe->pipe_settings.yuvpp.num_yuv_scaler; i++)
@@ -7417,20 +7379,21 @@ unload_yuvpp_binaries(struct ia_css_pipe *pipe) {
kfree(pipe->pipe_settings.yuvpp.vf_pp_binary);
pipe->pipe_settings.yuvpp.vf_pp_binary = NULL;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-static enum ia_css_err yuvpp_start(struct ia_css_pipe *pipe) {
+static int yuvpp_start(struct ia_css_pipe *pipe)
+{
struct ia_css_binary *copy_binary;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
enum sh_css_pipe_config_override copy_ovrd;
enum ia_css_input_mode yuvpp_pipe_input_mode;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
yuvpp_pipe_input_mode = pipe->stream->config.mode;
@@ -7443,7 +7406,7 @@ static enum ia_css_err yuvpp_start(struct ia_css_pipe *pipe) {
#if !defined(HAS_NO_INPUT_SYSTEM) && (defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401))
err = send_mipi_frames(pipe);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7462,22 +7425,22 @@ static enum ia_css_err yuvpp_start(struct ia_css_pipe *pipe) {
return err;
}
-static enum ia_css_err
+static int
sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if (!pipe)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
/* PIPE_MODE_COPY has no binaries, but has output frames to outside*/
if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
switch (pipe->mode)
@@ -7501,9 +7464,9 @@ sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) {
return err;
}
-static enum ia_css_err
+static int
sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(pipe);
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_pipe_load_binaries() enter:\n");
@@ -7529,24 +7492,24 @@ sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) {
case IA_CSS_PIPE_ID_ACC:
break;
default:
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
break;
}
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
- if (sh_css_pipe_unload_binaries(pipe) != IA_CSS_SUCCESS) {
+ if (sh_css_pipe_unload_binaries(pipe)) {
/* currently css does not support multiple error returns in a single function,
- * using IA_CSS_ERR_INTERNAL_ERROR in this case */
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ * using -EINVAL in this case */
+ err = -EINVAL;
}
}
return err;
}
-static enum ia_css_err
+static int
create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
struct ia_css_pipeline *me;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipeline_stage *vf_pp_stage = NULL,
*copy_stage = NULL,
*yuv_scaler_stage = NULL;
@@ -7573,8 +7536,8 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
me = &pipe->pipeline;
ia_css_pipeline_clean(me);
@@ -7652,7 +7615,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
&me->in_frame,
in_frame_format);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7668,7 +7631,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
assert(i < IA_CSS_PIPE_MAX_OUTPUT_STAGE);
if (pipe->output_info[i].res.width != 0) {
err = init_out_frameinfo_defaults(pipe, &me->out_frame[i], i);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7678,7 +7641,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
/* Construct vf_frame info (only in case we have VF) */
if (pipe->vf_output_info[i].res.width != 0) {
err = init_vf_frameinfo_defaults(pipe, &me->vf_frame[i], i);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7715,7 +7678,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
&stage_desc,
&copy_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7751,7 +7714,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
&yuv_scaler_binary[i],
&yuv_scaler_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7763,7 +7726,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
err = add_vf_pp_stage(pipe, in_frame, tmp_vf_frame, &vf_pp_binary[j],
&vf_pp_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7778,7 +7741,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0],
&vf_pp_stage);
}
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7786,17 +7749,17 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) {
ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
create_host_copy_pipeline(struct ia_css_pipe *pipe,
unsigned int max_input_width,
struct ia_css_frame *out_frame) {
struct ia_css_pipeline *me;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipeline_stage_desc stage_desc;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
@@ -7843,10 +7806,10 @@ create_host_copy_pipeline(struct ia_css_pipe *pipe,
return err;
}
-static enum ia_css_err
+static int
create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) {
struct ia_css_pipeline *me = &pipe->pipeline;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_pipeline_stage_desc stage_desc;
struct ia_css_frame *out_frame = &me->out_frame[0];
struct ia_css_pipeline_stage *out_stage = NULL;
@@ -7860,7 +7823,7 @@ create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) {
/* Construct out_frame info */
err = sh_css_pipe_get_output_frame_info(pipe, &out_frame->info, 0);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
out_frame->contiguous = false;
out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
@@ -7876,7 +7839,7 @@ create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) {
IA_CSS_PIPELINE_ISYS_COPY, max_input_width);
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc, &out_stage);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
ia_css_pipeline_finalize_stages(me, pipe->stream->config.continuous);
@@ -7887,10 +7850,10 @@ create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) {
return err;
}
-static enum ia_css_err
+static int
create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
struct ia_css_pipeline *me;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
enum ia_css_capture_mode mode;
struct ia_css_pipeline_stage *current_stage = NULL;
struct ia_css_pipeline_stage *yuv_scaler_stage = NULL;
@@ -7956,7 +7919,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
{
err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
IA_CSS_FRAME_FORMAT_RAW);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -7968,7 +7931,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
}
err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -7994,8 +7957,8 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
num_primary_stage = pipe->pipe_settings.capture.num_primary_stage;
if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
for (i = 0; i < num_primary_stage; i++)
{
@@ -8043,7 +8006,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&current_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8086,7 +8049,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
&current_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8105,7 +8068,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
out_frames, in_frame, NULL);
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc, NULL);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8114,7 +8077,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
out_frames, NULL, NULL);
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc, NULL);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8131,7 +8094,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc, &current_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8143,7 +8106,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
err = ia_css_pipeline_create_and_add_stage(me,
&stage_desc,
NULL);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8185,7 +8148,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
#endif
capture_pp_binary,
&current_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8206,7 +8169,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
NULL,
&yuv_scaler_binary[i],
&yuv_scaler_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8229,7 +8192,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
in_frame = current_stage->args.out_vf_frame;
err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
&current_stage);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8239,12 +8202,12 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"create_host_regular_capture_pipeline() leave:\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
create_host_capture_pipeline(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
@@ -8252,7 +8215,7 @@ create_host_capture_pipeline(struct ia_css_pipe *pipe) {
err = create_host_isyscopy_capture_pipeline(pipe);
else
err = create_host_regular_capture_pipeline(pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -8263,17 +8226,17 @@ create_host_capture_pipeline(struct ia_css_pipe *pipe) {
return err;
}
-static enum ia_css_err capture_start(
+static int capture_start(
struct ia_css_pipe *pipe) {
struct ia_css_pipeline *me;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
enum sh_css_pipe_config_override copy_ovrd;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if (!pipe) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
me = &pipe->pipeline;
@@ -8291,14 +8254,14 @@ static enum ia_css_err capture_start(
#if defined(USE_INPUT_SYSTEM_VERSION_2)
/* old isys: need to send_mipi_frames() in all pipe modes */
err = send_mipi_frames(pipe);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
#elif defined(USE_INPUT_SYSTEM_VERSION_2401)
if (pipe->config.mode != IA_CSS_PIPE_MODE_COPY) {
err = send_mipi_frames(pipe);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -8332,7 +8295,7 @@ static enum ia_css_err capture_start(
return err;
}
-static enum ia_css_err
+static int
sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
struct ia_css_frame_info *info,
unsigned int idx) {
@@ -8361,7 +8324,7 @@ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"sh_css_pipe_get_output_frame_info() leave:\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
#if !defined(HAS_NO_INPUT_SYSTEM)
@@ -8448,12 +8411,13 @@ remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) {
return; /* removing single and multiple firmware is handled in acc_unload_extension() */
}
-static enum ia_css_err upload_isp_code(struct ia_css_fw_info *firmware) {
- hrt_vaddress binary;
+static int upload_isp_code(struct ia_css_fw_info *firmware)
+{
+ ia_css_ptr binary;
if (!firmware) {
IA_CSS_ERROR("NULL input parameter");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
binary = firmware->info.isp.xmem_addr;
@@ -8473,27 +8437,27 @@ static enum ia_css_err upload_isp_code(struct ia_css_fw_info *firmware) {
}
if (!binary)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
- return IA_CSS_SUCCESS;
+ return -ENOMEM;
+ return 0;
}
-static enum ia_css_err
+static int
acc_load_extension(struct ia_css_fw_info *firmware) {
- enum ia_css_err err;
+ int err;
struct ia_css_fw_info *hd = firmware;
while (hd)
{
err = upload_isp_code(hd);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
hd = hd->next;
}
if (!firmware)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
firmware->loaded = true;
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -8519,36 +8483,23 @@ acc_unload_extension(struct ia_css_fw_info *firmware) {
}
/* Load firmware for extension */
-static enum ia_css_err
+static int
ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
struct ia_css_fw_info *firmware) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
if ((!firmware) || (!pipe))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
if (firmware->info.isp.type == IA_CSS_ACC_OUTPUT)
- {
- if (&pipe->output_stage)
- append_firmware(&pipe->output_stage, firmware);
- else {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
- }
- } else if (firmware->info.isp.type == IA_CSS_ACC_VIEWFINDER)
- {
- if (&pipe->vf_stage)
- append_firmware(&pipe->vf_stage, firmware);
- else {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- return IA_CSS_ERR_INTERNAL_ERROR;
- }
- }
+ append_firmware(&pipe->output_stage, firmware);
+ else if (firmware->info.isp.type == IA_CSS_ACC_VIEWFINDER)
+ append_firmware(&pipe->vf_stage, firmware);
err = acc_load_extension(firmware);
IA_CSS_LEAVE_ERR_PRIVATE(err);
@@ -8596,12 +8547,12 @@ ia_css_pipeline_uses_params(struct ia_css_pipeline *me) {
return false;
}
-static enum ia_css_err
+static int
sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
const void *acc_fw) {
struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw;
/* In QoS case, load_extension already called, so skipping */
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if (fw->loaded == false)
err = acc_load_extension(fw);
@@ -8610,7 +8561,7 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
"sh_css_pipeline_add_acc_stage() enter: pipeline=%p, acc_fw=%p\n",
pipeline, acc_fw);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
{
struct ia_css_pipeline_stage_desc stage_desc;
@@ -8629,25 +8580,25 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
* @brief Tag a specific frame in continuous capture.
* Refer to "sh_css_internal.h" for details.
*/
-enum ia_css_err ia_css_stream_capture_frame(struct ia_css_stream *stream,
+int ia_css_stream_capture_frame(struct ia_css_stream *stream,
unsigned int exp_id) {
struct sh_css_tag_descr tag_descr;
u32 encoded_tag_descr;
- enum ia_css_err err;
+ int err;
assert(stream);
IA_CSS_ENTER("exp_id=%d", exp_id);
/* Only continuous streams have a tagger */
if (exp_id == 0 || !stream->config.continuous) {
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
if (!sh_css_sp_is_running()) {
/* SP is not running. The queues are not valid */
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ IA_CSS_LEAVE_ERR(-EBUSY);
+ return -EBUSY;
}
/* Create the tag descriptor from the parameters */
@@ -8668,17 +8619,17 @@ enum ia_css_err ia_css_stream_capture_frame(struct ia_css_stream *stream,
* @brief Configure the continuous capture.
* Refer to "sh_css_internal.h" for details.
*/
-enum ia_css_err ia_css_stream_capture(
+int ia_css_stream_capture(
struct ia_css_stream *stream,
int num_captures,
unsigned int skip,
int offset) {
struct sh_css_tag_descr tag_descr;
unsigned int encoded_tag_descr;
- enum ia_css_err return_err;
+ int return_err;
if (!stream)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_stream_capture() enter: num_captures=%d, skip=%d, offset=%d\n",
@@ -8688,8 +8639,8 @@ enum ia_css_err ia_css_stream_capture(
if (num_captures < SH_CSS_MINIMUM_TAG_ID) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_stream_capture() leave: return_err=%d\n",
- IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ -EINVAL);
+ return -EINVAL;
}
/* Create the tag descriptor from the parameters */
@@ -8702,7 +8653,7 @@ enum ia_css_err ia_css_stream_capture(
/* SP is not running. The queues are not valid */
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_stream_capture() leaving:queues unavailable\n");
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ return -EBUSY;
}
/* Enqueue the encoded tag to the host2sp queue.
@@ -8718,7 +8669,8 @@ enum ia_css_err ia_css_stream_capture(
return return_err;
}
-void ia_css_stream_request_flash(struct ia_css_stream *stream) {
+void ia_css_stream_request_flash(struct ia_css_stream *stream)
+{
(void)stream;
assert(stream);
@@ -8817,11 +8769,16 @@ sh_css_init_host_sp_control_vars(void) {
}
/*
- * create the internal structures and fill in the configuration data
- */
-void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config) {
+ * create the internal structures and fill in the configuration data
+ */
+
+static const struct
+ia_css_pipe_config ia_css_pipe_default_config = DEFAULT_PIPE_CONFIG;
+
+void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config)
+{
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_config_defaults()\n");
- *pipe_config = DEFAULT_PIPE_CONFIG;
+ memcpy(pipe_config, &ia_css_pipe_default_config, sizeof(*pipe_config));
}
void
@@ -8841,7 +8798,8 @@ ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config
extra_config->enable_fractional_ds = false;
}
-void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config) {
+void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config)
+{
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_config_defaults()\n");
assert(stream_config);
memset(stream_config, 0, sizeof(*stream_config));
@@ -8854,14 +8812,14 @@ void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config) {
stream_config->source.port.rxcount = 0x04040404;
}
-static enum ia_css_err
+static int
ia_css_acc_pipe_create(struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if (!pipe)
{
IA_CSS_ERROR("NULL input parameter");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* There is not meaning for num_execs = 0 semantically. Run atleast once. */
@@ -8876,30 +8834,31 @@ ia_css_acc_pipe_create(struct ia_css_pipe *pipe) {
return err;
}
-enum ia_css_err
+int
ia_css_pipe_create(const struct ia_css_pipe_config *config,
struct ia_css_pipe **pipe) {
#ifndef ISP2401
if (!config)
#else
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("config = %p, pipe = %p", config, pipe);
if (!config)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
#endif
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
#ifndef ISP2401
if (!pipe)
#else
}
+
if (!pipe)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
#endif
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
#ifndef ISP2401
return ia_css_pipe_create_extra(config, NULL, pipe);
#else
@@ -8907,7 +8866,7 @@ if (!pipe)
err = ia_css_pipe_create_extra(config, NULL, pipe);
-if (err == IA_CSS_SUCCESS)
+if (err == 0)
{
IA_CSS_LOG("pipe created successfully = %p", *pipe);
}
@@ -8918,11 +8877,11 @@ return err;
#endif
}
-enum ia_css_err
+int
ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
const struct ia_css_pipe_extra_config *extra_config,
struct ia_css_pipe **pipe) {
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
struct ia_css_pipe *internal_pipe = NULL;
unsigned int i;
@@ -8931,21 +8890,21 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
/* do not allow to create more than the maximum limit */
if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_RESOURCE_EXHAUSTED);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOSPC);
+ return -EINVAL;
}
if ((!pipe) || (!config))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
ia_css_debug_dump_pipe_config(config);
ia_css_debug_dump_pipe_extra_config(extra_config);
err = create_pipe(config->mode, &internal_pipe, false);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -8968,8 +8927,8 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
internal_pipe->config.num_acc_stages ==
0) { /* if no acc binary and no standalone stage */
*pipe = NULL;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
return ia_css_acc_pipe_create(internal_pipe);
}
@@ -9044,9 +9003,9 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
internal_pipe->config.output_info[i].padded_width,
internal_pipe->config.output_info[i].format,
i);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
- sh_css_free(internal_pipe);
+ kvfree(internal_pipe);
internal_pipe = NULL;
return err;
}
@@ -9063,9 +9022,9 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
internal_pipe->config.vf_output_info[i].padded_width,
internal_pipe->config.vf_output_info[i].format,
i);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
- sh_css_free(internal_pipe);
+ kvfree(internal_pipe);
internal_pipe = NULL;
return err;
}
@@ -9075,9 +9034,9 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
{
err = ia_css_pipe_load_extension(internal_pipe,
internal_pipe->config.acc_extension);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
- sh_css_free(internal_pipe);
+ kvfree(internal_pipe);
return err;
}
}
@@ -9086,11 +9045,11 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
/* all went well, return the pipe */
*pipe = internal_pipe;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
-enum ia_css_err
+int
ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
struct ia_css_pipe_info *pipe_info) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
@@ -9100,21 +9059,22 @@ ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
{
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
"ia_css_pipe_get_info: pipe_info cannot be NULL\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
if (!pipe || !pipe->stream)
{
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
"ia_css_pipe_get_info: ia_css_stream_create needs to be called before ia_css_[stream/pipe]_get_info\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* we succeeded return the info */
*pipe_info = pipe->info;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_get_info() leave\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
-bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info) {
+bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info)
+{
unsigned int i;
if (pipe_info) {
@@ -9127,38 +9087,38 @@ bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info) {
return false;
}
-enum ia_css_err
+int
ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
int pin_index,
enum ia_css_frame_format new_format) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("pipe = %p, pin_index = %d, new_formats = %d", pipe, pin_index, new_format);
if (!pipe)
{
IA_CSS_ERROR("pipe is not set");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
if (0 != pin_index && 1 != pin_index)
{
IA_CSS_ERROR("pin index is not valid");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY)
{
IA_CSS_ERROR("new format is not valid");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
} else
{
err = ia_css_pipe_check_format(pipe, new_format);
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
if (pin_index == 0) {
pipe->output_info[0].format = new_format;
} else {
@@ -9172,7 +9132,7 @@ ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
#if defined(USE_INPUT_SYSTEM_VERSION_2)
/* Configuration of INPUT_SYSTEM_VERSION_2401 is done on SP */
-static enum ia_css_err
+static int
ia_css_stream_configure_rx(struct ia_css_stream *stream) {
struct ia_css_input_port *config;
@@ -9189,10 +9149,10 @@ ia_css_stream_configure_rx(struct ia_css_stream *stream) {
else if (config->num_lanes == 4)
stream->csi_rx_config.mode = MONO_4L_1L_0L;
else if (config->num_lanes != 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (config->port > MIPI_PORT2_ID)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
stream->csi_rx_config.port =
ia_css_isys_port_to_mipi_port(config->port);
stream->csi_rx_config.timeout = config->timeout;
@@ -9205,11 +9165,11 @@ ia_css_stream_configure_rx(struct ia_css_stream *stream) {
{
/* not implemented yet, requires extension of the rx_cfg_t
* struct */
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
stream->csi_rx_config.is_two_ppc = (stream->config.pixels_per_clock == 2);
stream->reconfigure_css_rx = true;
- return IA_CSS_SUCCESS;
+ return 0;
}
#endif
@@ -9232,18 +9192,18 @@ find_pipe(struct ia_css_pipe *pipes[],
return NULL;
}
-static enum ia_css_err
+static int
ia_css_acc_stream_create(struct ia_css_stream *stream) {
int i;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(stream);
IA_CSS_ENTER_PRIVATE("stream = %p", stream);
if (!stream)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
for (i = 0; i < stream->num_pipes; i++)
@@ -9252,8 +9212,8 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) {
assert(pipe);
if (!pipe) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
pipe->stream = stream;
@@ -9261,7 +9221,7 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) {
/* Map SP threads before doing anything. */
err = map_sp_threads(stream, true);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -9276,7 +9236,7 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) {
}
err = create_host_pipeline_structure(stream);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -9284,42 +9244,43 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) {
stream->started = false;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
metadata_info_init(const struct ia_css_metadata_config *mdc,
struct ia_css_metadata_info *md) {
/* Either both width and height should be set or neither */
if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
md->resolution = mdc->resolution;
/* We round up the stride to a multiple of the width
* of the port going to DDR, this is a HW requirements (DMA). */
md->stride = CEIL_MUL(mdc->resolution.width, HIVE_ISP_DDR_WORD_BYTES);
md->size = mdc->resolution.height * md->stride;
- return IA_CSS_SUCCESS;
+ return 0;
}
/* ISP2401 */
-static enum ia_css_err check_pipe_resolutions(const struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+static int check_pipe_resolutions(const struct ia_css_pipe *pipe)
+{
+ int err = 0;
IA_CSS_ENTER_PRIVATE("");
if (!pipe || !pipe->stream) {
IA_CSS_ERROR("null arguments");
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto EXIT;
}
if (ia_css_util_check_res(pipe->config.input_effective_res.width,
- pipe->config.input_effective_res.height) != IA_CSS_SUCCESS) {
+ pipe->config.input_effective_res.height) != 0) {
IA_CSS_ERROR("effective resolution not supported");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
goto EXIT;
}
if (!ia_css_util_resolution_is_zero(
@@ -9327,18 +9288,18 @@ static enum ia_css_err check_pipe_resolutions(const struct ia_css_pipe *pipe) {
if (!ia_css_util_res_leq(pipe->config.input_effective_res,
pipe->stream->config.input_config.input_res)) {
IA_CSS_ERROR("effective resolution is larger than input resolution");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
goto EXIT;
}
}
if (!ia_css_util_resolution_is_even(pipe->config.output_info[0].res)) {
IA_CSS_ERROR("output resolution must be even");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
goto EXIT;
}
if (!ia_css_util_resolution_is_even(pipe->config.vf_output_info[0].res)) {
IA_CSS_ERROR("VF resolution must be even");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
goto EXIT;
}
EXIT:
@@ -9346,7 +9307,7 @@ EXIT:
return err;
}
-enum ia_css_err
+int
ia_css_stream_create(const struct ia_css_stream_config *stream_config,
int num_pipes,
struct ia_css_pipe *pipes[],
@@ -9356,7 +9317,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
bool spcopyonly;
bool sensor_binning_changed;
int i, j;
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
struct ia_css_metadata_info md_info;
struct ia_css_resolution effective_res;
#ifdef USE_INPUT_SYSTEM_VERSION_2401
@@ -9371,7 +9332,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
!stream ||
!pipes)
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9381,7 +9342,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
if (stream_config->input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8 &&
stream_config->metadata_config.resolution.height > 0)
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9391,7 +9352,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
if (stream_config->online && stream_config->pack_raw_pixels)
{
IA_CSS_LOG("online and pack raw is invalid on input system 2401");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9409,7 +9370,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
unsigned int port = (unsigned int)stream_config->source.port.port;
if (port >= N_MIPI_PORT_ID) {
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9422,7 +9383,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_stream_create() exit: error, need to set mipi frame size.\n");
assert(stream_config->mipi_buffer_config.size_mem_words != 0);
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9437,7 +9398,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_stream_create() exit: error, need to set number of mipi frames.\n");
assert(stream_config->mipi_buffer_config.nof_mipi_buffers != 0);
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9446,22 +9407,21 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
/* Currently we only supported metadata up to a certain size. */
err = metadata_info_init(&stream_config->metadata_config, &md_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
}
/* allocate the stream instance */
- curr_stream = kmalloc(sizeof(struct ia_css_stream), GFP_KERNEL);
+ curr_stream = kzalloc(sizeof(struct ia_css_stream), GFP_KERNEL);
if (!curr_stream)
{
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
IA_CSS_LEAVE_ERR(err);
return err;
}
/* default all to 0 */
- memset(curr_stream, 0, sizeof(struct ia_css_stream));
curr_stream->info.metadata_info = md_info;
/* allocate pipes */
@@ -9472,7 +9432,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
curr_stream->num_pipes = 0;
kfree(curr_stream);
curr_stream = NULL;
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -9553,7 +9513,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
err = aspect_ratio_crop_init(curr_stream,
pipes,
&aspect_ratio_crop_enabled);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
@@ -9579,7 +9539,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
struct ia_css_resolution crop_res;
err = aspect_ratio_crop(curr_pipe, &crop_res);
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
effective_res = crop_res;
} else {
/* in case of error fallback to default
@@ -9595,12 +9555,12 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
effective_res.height);
}
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
for (i = 0; i < num_pipes; i++) {
if (pipes[i]->config.mode != IA_CSS_PIPE_MODE_ACC &&
pipes[i]->config.mode != IA_CSS_PIPE_MODE_COPY) {
err = check_pipe_resolutions(pipes[i]);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
goto ERR;
}
}
@@ -9608,7 +9568,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
}
err = ia_css_stream_isp_parameters_init(curr_stream);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
IA_CSS_LOG("isp_params_configs: %p", curr_stream->isp_params_configs);
@@ -9649,7 +9609,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
curr_stream->cont_capt = true;
curr_stream->disable_cont_vf = curr_stream->config.disable_cont_viewfinder;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
curr_stream->stop_copy_preview = my_css.stop_copy_preview;
}
@@ -9667,19 +9627,19 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
capture_pipe = find_pipe(pipes, num_pipes,
IA_CSS_PIPE_MODE_CAPTURE, false);
if (!capture_pipe) {
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto ERR;
}
}
/* We do not support preview and video pipe at the same time */
if (preview_pipe && video_pipe) {
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
goto ERR;
}
if (preview_pipe && !preview_pipe->pipe_settings.preview.copy_pipe) {
err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, &copy_pipe, true);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
ia_css_pipe_config_defaults(&copy_pipe->config);
preview_pipe->pipe_settings.preview.copy_pipe = copy_pipe;
@@ -9690,7 +9650,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
}
if (video_pipe && !video_pipe->pipe_settings.video.copy_pipe) {
err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, &copy_pipe, true);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
ia_css_pipe_config_defaults(&copy_pipe->config);
video_pipe->pipe_settings.video.copy_pipe = copy_pipe;
@@ -9709,14 +9669,14 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
/* set current stream */
curr_pipe->stream = curr_stream;
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
/* take over effective info */
effective_res = curr_pipe->config.input_effective_res;
err = ia_css_util_check_res(
effective_res.width,
effective_res.height);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
/* sensor binning per pipe */
@@ -9732,7 +9692,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
curr_pipe = pipes[i];
err = sh_css_pipe_load_binaries(curr_pipe);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
/* handle each pipe */
@@ -9740,31 +9700,31 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) {
err = sh_css_pipe_get_output_frame_info(curr_pipe,
&pipe_info->output_info[j], j);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
- if (atomisp_hw_is_isp2401)
+ if (IS_ISP2401)
pipe_info->output_system_in_res_info = curr_pipe->config.output_system_in_res;
if (!spcopyonly) {
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
err = sh_css_pipe_get_shading_info(curr_pipe,
&pipe_info->shading_info, NULL);
else
err = sh_css_pipe_get_shading_info(curr_pipe,
&pipe_info->shading_info, &curr_pipe->config);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
err = sh_css_pipe_get_grid_info(curr_pipe,
&pipe_info->grid_info);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) {
sh_css_pipe_get_viewfinder_frame_info(curr_pipe,
&pipe_info->vf_output_info[j], j);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
}
}
@@ -9776,7 +9736,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
/* Map SP threads before doing anything. */
err = map_sp_threads(curr_stream, true);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LOG("map_sp_threads: return_err=%d", err);
goto ERR;
@@ -9790,7 +9750,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
/* Create host side pipeline objects without stages */
err = create_host_pipeline_structure(curr_stream);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LOG("create_host_pipeline_structure: return_err=%d", err);
goto ERR;
@@ -9800,7 +9760,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
*stream = curr_stream;
ERR:
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
/* working mode: enter into the seed list */
if (my_css_save.mode == sh_css_mode_working) {
for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
@@ -9828,15 +9788,15 @@ ERR:
return err;
}
-enum ia_css_err
+int
ia_css_stream_destroy(struct ia_css_stream *stream) {
int i;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("stream = %p", stream);
if (!stream)
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -9859,7 +9819,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) {
/* get the SP thread id */
if (ia_css_pipeline_get_sp_thread_id(
ia_css_pipe_get_pipe_num(entry), &sp_thread_id) != true)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
/* get the target input terminal */
sp_pipeline_input_terminal =
&sh_css_sp_group.pipe_io[sp_thread_id].input;
@@ -9873,7 +9833,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) {
}
}
free_mpi = stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
free_mpi |= stream->config.mode == IA_CSS_INPUT_MODE_TPG;
free_mpi |= stream->config.mode == IA_CSS_INPUT_MODE_PRBS;
}
@@ -9900,7 +9860,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) {
}
err = map_sp_threads(stream, false);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -9952,7 +9912,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) {
return err;
}
-enum ia_css_err
+int
ia_css_stream_get_info(const struct ia_css_stream *stream,
struct ia_css_stream_info *stream_info) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n");
@@ -9960,7 +9920,7 @@ ia_css_stream_get_info(const struct ia_css_stream *stream,
assert(stream_info);
*stream_info = stream->info;
- return IA_CSS_SUCCESS;
+ return 0;
}
/*
@@ -9969,12 +9929,11 @@ ia_css_stream_get_info(const struct ia_css_stream *stream,
* The data is taken from the css_save struct updated upon stream creation.
* The stream handle is used to identify the correct entry in the css_save struct
*/
-enum ia_css_err
+int
ia_css_stream_load(struct ia_css_stream *stream) {
-
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
int i;
- enum ia_css_err err;
+ int err;
assert(stream);
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n");
@@ -9985,7 +9944,7 @@ ia_css_stream_load(struct ia_css_stream *stream) {
for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) {
if ((err = ia_css_pipe_create(&my_css_save.stream_seeds[i].pipe_config[j],
- &my_css_save.stream_seeds[i].pipes[j])) != IA_CSS_SUCCESS) {
+ &my_css_save.stream_seeds[i].pipes[j])) != 0) {
if (j) {
int k;
@@ -9999,7 +9958,7 @@ ia_css_stream_load(struct ia_css_stream *stream) {
my_css_save.stream_seeds[i].num_pipes,
my_css_save.stream_seeds[i].pipes,
&my_css_save.stream_seeds[i].stream);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
ia_css_stream_destroy(stream);
for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++)
ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]);
@@ -10009,23 +9968,23 @@ ia_css_stream_load(struct ia_css_stream *stream) {
}
}
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() exit,\n");
- return IA_CSS_SUCCESS;
+ return 0;
} else {
/* TODO remove function - DEPRECATED */
(void)stream;
- return IA_CSS_ERR_NOT_SUPPORTED;
+ return -ENOTSUPP;
}
}
-enum ia_css_err
+int
ia_css_stream_start(struct ia_css_stream *stream) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("stream = %p", stream);
if ((!stream) || (!stream->last_pipe))
{
- IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR(-EINVAL);
+ return -EINVAL;
}
IA_CSS_LOG("starting %d", stream->last_pipe->mode);
@@ -10033,7 +9992,7 @@ ia_css_stream_start(struct ia_css_stream *stream) {
/* Create host side pipeline. */
err = create_host_pipeline(stream);
- if (err != IA_CSS_SUCCESS)
+ if (err)
{
IA_CSS_LEAVE_ERR(err);
return err;
@@ -10065,7 +10024,7 @@ ia_css_stream_start(struct ia_css_stream *stream) {
if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY)
{
err = sh_css_config_input_network(stream);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
#endif /* !HAS_NO_INPUT_SYSTEM */
@@ -10075,9 +10034,9 @@ ia_css_stream_start(struct ia_css_stream *stream) {
return err;
}
-enum ia_css_err
+int
ia_css_stream_stop(struct ia_css_stream *stream) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_stop() enter/exit\n");
assert(stream);
@@ -10098,13 +10057,13 @@ ia_css_stream_stop(struct ia_css_stream *stream) {
}
#endif
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline);
} else {
err = sh_css_pipes_stop(stream);
}
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
/* Ideally, unmapping should happen after pipeline_stop, but current
@@ -10120,7 +10079,7 @@ ia_css_stream_has_stopped(struct ia_css_stream *stream) {
assert(stream);
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline);
} else {
stopped = sh_css_pipes_have_stopped(stream);
@@ -10134,7 +10093,7 @@ ia_css_stream_has_stopped(struct ia_css_stream *stream) {
* Destroy the stream and all the pipes related to it.
* The stream handle is used to identify the correct entry in the css_save struct
*/
-enum ia_css_err
+int
ia_css_stream_unload(struct ia_css_stream *stream) {
int i;
@@ -10159,10 +10118,10 @@ ia_css_stream_unload(struct ia_css_stream *stream) {
break;
}
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_unload() exit,\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe,
enum ia_css_pipe_id *pipe_id) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_temp_pipe_to_pipe_id() enter/exit\n");
@@ -10171,7 +10130,7 @@ ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe,
else
*pipe_id = IA_CSS_PIPE_ID_COPY;
- return IA_CSS_SUCCESS;
+ return 0;
}
enum atomisp_input_format
@@ -10243,7 +10202,7 @@ ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) {
return s3a_binary;
}
-enum ia_css_err
+int
ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
unsigned int output_padded_width) {
struct ia_css_pipe *pipe;
@@ -10258,7 +10217,7 @@ ia_css_stream_set_output_padded_width(struct ia_css_stream *stream,
pipe->config.output_info[IA_CSS_PIPE_OUTPUT_STAGE_0].padded_width = output_padded_width;
pipe->output_info[IA_CSS_PIPE_OUTPUT_STAGE_0].padded_width = output_padded_width;
- return IA_CSS_SUCCESS;
+ return 0;
}
static struct ia_css_binary *
@@ -10406,10 +10365,10 @@ ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe) {
#define SP_START_TIMEOUT_US 30000000
-enum ia_css_err
+int
ia_css_start_sp(void) {
unsigned long timeout;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("");
sh_css_sp_start_isp();
@@ -10419,12 +10378,12 @@ ia_css_start_sp(void) {
while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout)
{
timeout--;
- hrt_sleep();
+ udelay(1);
}
if (timeout == 0)
{
IA_CSS_ERROR("timeout during SP initialization");
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
/* Workaround, in order to run two streams in parallel. See TASK 4271*/
@@ -10449,16 +10408,16 @@ ia_css_start_sp(void) {
*/
#define SP_SHUTDOWN_TIMEOUT_US 200000
-enum ia_css_err
+int
ia_css_stop_sp(void) {
unsigned long timeout;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("void");
if (!sh_css_sp_is_running())
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE("SP already stopped : return_err=%d", err);
/* Return an error - stop SP should not have been called by driver */
@@ -10466,7 +10425,7 @@ ia_css_stop_sp(void) {
}
/* For now, stop whole SP */
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
sh_css_write_host2sp_command(host2sp_cmd_terminate);
} else {
if (!sh_css_write_host2sp_command(host2sp_cmd_terminate))
@@ -10483,7 +10442,7 @@ ia_css_stop_sp(void) {
while (!ia_css_spctrl_is_idle(SP0_ID) && timeout)
{
timeout--;
- hrt_sleep();
+ udelay(1);
}
if ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_TERMINATED))
IA_CSS_WARNING("SP has not terminated (SW)");
@@ -10497,7 +10456,7 @@ ia_css_stop_sp(void) {
while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout)
{
timeout--;
- hrt_sleep();
+ udelay(1);
}
if (timeout == 0)
{
@@ -10514,7 +10473,7 @@ ia_css_stop_sp(void) {
return err;
}
-enum ia_css_err
+int
ia_css_update_continuous_frames(struct ia_css_stream *stream) {
struct ia_css_pipe *pipe;
unsigned int i;
@@ -10528,7 +10487,7 @@ ia_css_update_continuous_frames(struct ia_css_stream *stream) {
ia_css_debug_dtrace(
IA_CSS_DEBUG_TRACE,
"sh_css_update_continuous_frames() leave: invalid stream, return_void\n");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
pipe = stream->continuous_pipe;
@@ -10545,10 +10504,11 @@ ia_css_update_continuous_frames(struct ia_css_stream *stream) {
IA_CSS_DEBUG_TRACE,
"sh_css_update_continuous_frames() leave: return_void\n");
- return IA_CSS_SUCCESS;
+ return 0;
}
-void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map) {
+void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
+{
unsigned int thread_id;
enum ia_css_pipe_id pipe_id;
unsigned int pipe_num;
@@ -10664,7 +10624,7 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map) {
}
#if CONFIG_ON_FRAME_ENQUEUE()
-static enum ia_css_err set_config_on_frame_enqueue(struct ia_css_frame_info
+static int set_config_on_frame_enqueue(struct ia_css_frame_info
*info, struct frame_data_wrapper *frame) {
frame->config_on_frame_enqueue.padded_width = 0;
@@ -10676,7 +10636,7 @@ static enum ia_css_err set_config_on_frame_enqueue(struct ia_css_frame_info
if (info->padded_width > info->res.width) {
frame->config_on_frame_enqueue.padded_width = info->padded_width;
} else if ((info->padded_width < info->res.width) && (info->padded_width > 0)) {
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* nothing to do if width == padded width or padded width is zeroed (the same) */
break;
@@ -10684,13 +10644,13 @@ static enum ia_css_err set_config_on_frame_enqueue(struct ia_css_frame_info
break;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
#endif
-enum ia_css_err
+int
ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) {
- enum ia_css_err ret;
+ int ret;
IA_CSS_ENTER("");
@@ -10699,14 +10659,14 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) {
if (!stream || !stream->config.continuous)
{
IA_CSS_ERROR("invalid stream pointer");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
if (exp_id > IA_CSS_ISYS_MAX_EXPOSURE_ID ||
exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID)
{
- IA_CSS_ERROR("invalid expsure ID: %d\n", exp_id);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_ERROR("invalid exposure ID: %d\n", exp_id);
+ return -EINVAL;
}
/* Send the event. Since we verified that the exp_id is valid,
@@ -10721,12 +10681,12 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) {
/* @brief Set the state (Enable or Disable) of the Extension stage in the
* given pipe.
*/
-enum ia_css_err
+int
ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
bool enable) {
unsigned int thread_id;
struct ia_css_pipeline_stage *stage;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("");
@@ -10734,28 +10694,28 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
if (!pipe || !pipe->stream)
{
IA_CSS_ERROR("Invalid Pipe.");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
} else if (!(pipe->config.acc_extension))
{
IA_CSS_ERROR("Invalid Pipe(No Extension Firmware)");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
} else if (!sh_css_sp_is_running())
{
IA_CSS_ERROR("Leaving: queue unavailable.");
- err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ err = -EBUSY;
} else
{
/* Query the threadid and stage_num for the Extension firmware*/
ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
/* Set the Extension State;. TODO: Add check for stage firmware.type (QOS)*/
err = ia_css_bufq_enqueue_psys_event(
(uint8_t)IA_CSS_PSYS_SW_EVENT_STAGE_ENABLE_DISABLE,
(uint8_t)thread_id,
(uint8_t)stage->stage_num,
enable ? 1 : 0);
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
if (enable)
SH_CSS_QOS_STAGE_ENABLE(&sh_css_sp_group.pipe[thread_id], stage->stage_num);
else
@@ -10770,12 +10730,12 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
/* @brief Get the state (Enable or Disable) of the Extension stage in the
* given pipe.
*/
-enum ia_css_err
+int
ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
bool *enable) {
struct ia_css_pipeline_stage *stage;
unsigned int thread_id;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("");
@@ -10783,22 +10743,22 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
if (!pipe || !pipe->stream)
{
IA_CSS_ERROR("Invalid Pipe.");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
} else if (!(pipe->config.acc_extension))
{
IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
} else if (!sh_css_sp_is_running())
{
IA_CSS_ERROR("Leaving: queue unavailable.");
- err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ err = -EBUSY;
} else
{
/* Query the threadid and stage_num corresponding to the Extension firmware*/
ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
/* Get the Extension State */
*enable = (SH_CSS_QOS_STAGE_IS_ENABLED(&sh_css_sp_group.pipe[thread_id],
stage->stage_num)) ? true : false;
@@ -10809,9 +10769,9 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
}
/* ISP2401 */
-enum ia_css_err
+int
ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
- uint32_t fw_handle,
+ u32 fw_handle,
struct ia_css_isp_param_css_segments *css_seg,
struct ia_css_isp_param_isp_segments *isp_seg) {
unsigned int HIVE_ADDR_sp_group;
@@ -10821,7 +10781,7 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
const struct ia_css_fw_info *fw;
unsigned int thread_id;
struct ia_css_pipeline_stage *stage;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
int stage_num = 0;
enum ia_css_isp_memories mem;
bool enabled;
@@ -10834,28 +10794,28 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
if (!pipe || !pipe->stream)
{
IA_CSS_ERROR("Invalid Pipe.");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
} else if (!(pipe->config.acc_extension))
{
IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
} else if (!sh_css_sp_is_running())
{
IA_CSS_ERROR("Leaving: queue unavailable.");
- err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ err = -EBUSY;
} else
{
/* Query the thread_id and stage_num corresponding to the Extension firmware */
ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
- if (err == IA_CSS_SUCCESS) {
+ if (!err) {
/* Get the Extension State */
enabled = (SH_CSS_QOS_STAGE_IS_ENABLED(&sh_css_sp_group.pipe[thread_id],
stage->stage_num)) ? true : false;
/* Update mapped arg only when extension stage is not enabled */
if (enabled) {
IA_CSS_ERROR("Leaving: cannot update when stage is enabled.");
- err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ err = -EBUSY;
} else {
stage_num = stage->stage_num;
@@ -10863,10 +10823,10 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
sp_dmem_load(SP0_ID,
(unsigned int)sp_address_of(sp_group),
&sp_group, sizeof(struct sh_css_sp_group));
- mmgr_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num],
+ hmm_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num],
&sp_stage, sizeof(struct sh_css_sp_stage));
- mmgr_load(sp_stage.isp_stage_addr,
+ hmm_load(sp_stage.isp_stage_addr,
&isp_stage, sizeof(struct sh_css_isp_stage));
for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) {
@@ -10882,7 +10842,7 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
isp_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].size;
}
- mmgr_store(sp_stage.isp_stage_addr,
+ hmm_store(sp_stage.isp_stage_addr,
&isp_stage, sizeof(struct sh_css_isp_stage));
}
}
@@ -10892,11 +10852,11 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
}
#ifdef USE_INPUT_SYSTEM_VERSION_2401
-static enum ia_css_err
+static int
aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
struct ia_css_pipe *pipes[],
bool *do_crop_status) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
int i;
struct ia_css_pipe *curr_pipe;
u32 pipe_mask = 0;
@@ -10906,7 +10866,7 @@ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
(!pipes) ||
(!do_crop_status))
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -10922,7 +10882,7 @@ aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
(pipe_mask & (1 << IA_CSS_PIPE_MODE_VIDEO))) &&
(pipe_mask & (1 << IA_CSS_PIPE_MODE_CAPTURE)) &&
curr_stream->config.continuous);
- return IA_CSS_SUCCESS;
+ return 0;
}
static bool
@@ -10939,10 +10899,10 @@ aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) {
return status;
}
-static enum ia_css_err
+static int
aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
struct ia_css_resolution *effective_res) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_resolution crop_res;
struct ia_css_resolution *in_res = NULL;
struct ia_css_resolution *out_res = NULL;
@@ -10953,7 +10913,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
if ((!curr_pipe) ||
(!effective_res))
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -10962,7 +10922,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
(curr_pipe->config.mode != IA_CSS_PIPE_MODE_VIDEO) &&
(curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE))
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR(err);
return err;
}
@@ -11009,7 +10969,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
}
err = ia_css_frame_find_crop_resolution(in_res, out_res, &crop_res);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
{
*effective_res = crop_res;
} else
@@ -11085,7 +11045,7 @@ static struct sh_css_hmm_buffer_record
}
static struct sh_css_hmm_buffer_record
-*sh_css_hmm_buffer_record_validate(hrt_vaddress ddr_buffer_addr,
+*sh_css_hmm_buffer_record_validate(ia_css_ptr ddr_buffer_addr,
enum ia_css_buffer_type type) {
int i;
struct sh_css_hmm_buffer_record *buffer_record = NULL;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_defs.h b/drivers/staging/media/atomisp/pci/sh_css_defs.h
index fcd5081edf82..92d80213860f 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_defs.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -177,7 +178,6 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
#define SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD \
(HIVE_ISP_DDR_WORD_BYTES / SH_CSS_MORPH_TABLE_ELEM_BYTES)
-
#define ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR (SH_CSS_MAX_BQ_GRID_WIDTH + 1)
#define ISP2400_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR (SH_CSS_MAX_BQ_GRID_HEIGHT + 1)
@@ -225,8 +225,6 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
#define NUM_VIDEO_TNR_FRAMES 2
-#define MAX_NUM_DELAY_FRAMES MAX(MAX_NUM_VIDEO_DELAY_FRAMES, NUM_PREVIEW_DVS_FRAMES)
-
/* Note that this is the define used to configure all data structures common for all modes */
/* It should be equal or bigger to the max number of DVS frames for all possible modes */
/* Rules: these implement logic shared between the host code and ISP firmware.
@@ -277,7 +275,6 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
(ISP_BQ_GRID_HEIGHT(input_height, deci_factor_log2) + \
SH_CSS_SCTBL_CENTERING_MARGIN + SH_CSS_SCTBL_LAST_GRID_COUNT)
-
/* ISP2401: Legacy API: Number of horizontal grids per color in the shading table. */
#define _ISP_SCTBL_LEGACY_WIDTH_PER_COLOR(input_width, deci_factor_log2) \
(ISP_BQ_GRID_WIDTH(input_width, deci_factor_log2) + SH_CSS_SCTBL_LAST_GRID_COUNT)
@@ -286,7 +283,6 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
#define _ISP_SCTBL_LEGACY_HEIGHT(input_height, deci_factor_log2) \
(ISP_BQ_GRID_HEIGHT(input_height, deci_factor_log2) + SH_CSS_SCTBL_LAST_GRID_COUNT)
-
/* *****************************************************************
* Statistics for 3A (Auto Focus, Auto White Balance, Auto Exposure)
* *****************************************************************/
diff --git a/drivers/staging/media/atomisp/pci/sh_css_dvs_info.h b/drivers/staging/media/atomisp/pci/sh_css_dvs_info.h
index 23044aad654f..6f058f132300 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_dvs_info.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_dvs_info.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/sh_css_firmware.c
index eb3c01574853..d4ab15b6d1ac 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_firmware.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_firmware.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,9 +13,12 @@
* more details.
*/
+#include <linux/string.h> /* for memcpy() */
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include "hmm.h"
+
#include <math_support.h>
#include "platform_support.h"
#include "sh_css_firmware.h"
@@ -24,9 +28,7 @@
#include "sh_css_internal.h"
#include "ia_css_isp_param.h"
-#include "memory_access.h"
#include "assert_support.h"
-#include "string_support.h"
#include "isp.h" /* PMEM_WIDTH_LOG2 */
@@ -74,13 +76,13 @@ char *sh_css_get_fw_version(void)
*/
/* Setup sp/sp1 binary */
-static enum ia_css_err
+static int
setup_binary(struct ia_css_fw_info *fw, const char *fw_data,
struct ia_css_fw_info *sh_css_fw, unsigned int binary_id) {
const char *blob_data;
if ((!fw) || (!fw_data))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
blob_data = fw_data + fw->blob.offset;
@@ -88,16 +90,16 @@ setup_binary(struct ia_css_fw_info *fw, const char *fw_data,
sh_css_fw->blob.code = vmalloc(fw->blob.size);
if (!sh_css_fw->blob.code)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
memcpy((void *)sh_css_fw->blob.code, blob_data, fw->blob.size);
sh_css_fw->blob.data = (char *)sh_css_fw->blob.code + fw->blob.data_source;
fw_minibuffer[binary_id].buffer = sh_css_fw->blob.code;
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
struct ia_css_blob_descr *bd,
unsigned int index) {
@@ -105,7 +107,7 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
const unsigned char *blob;
if ((!fw) || (!bd))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
/* Special case: only one binary in fw */
if (!bi) bi = (const struct ia_css_fw_info *)fw;
@@ -117,11 +119,11 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
if (bi->blob.size != bi->blob.text_size + bi->blob.icache_size + bi->blob.data_size + bi->blob.padding_size)
{
/* sanity check, note the padding bytes added for section to DDR alignment */
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
if ((bi->blob.offset % (1UL << (ISP_PMEM_WIDTH_LOG2 - 3))) != 0)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
bd->blob = blob;
bd->header = *bi;
@@ -132,7 +134,7 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
namebuffer = kstrdup(name, GFP_KERNEL);
if (!namebuffer)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
bd->name = fw_minibuffer[index].name = namebuffer;
} else
{
@@ -149,7 +151,7 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
statestruct_size,
GFP_KERNEL);
if (!parambuf)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
bd->mem_offsets.array[IA_CSS_PARAM_CLASS_PARAM].ptr = NULL;
bd->mem_offsets.array[IA_CSS_PARAM_CLASS_CONFIG].ptr = NULL;
@@ -177,7 +179,7 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
bd->mem_offsets.array[IA_CSS_PARAM_CLASS_STATE].ptr = parambuf +
paramstruct_size + configstruct_size;
}
- return IA_CSS_SUCCESS;
+ return 0;
}
bool
@@ -187,7 +189,7 @@ sh_css_check_firmware_version(struct device *dev, const char *fw_data)
const char *release_version;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
release_version = isp2400_release_version;
else
release_version = isp2401_release_version;
@@ -202,19 +204,33 @@ sh_css_check_firmware_version(struct device *dev, const char *fw_data)
}
/* For now, let's just accept a wrong version, even if wrong */
- return true;
+ return 0;
}
-enum ia_css_err
+static const char * const fw_type_name[] = {
+ [ia_css_sp_firmware] = "SP",
+ [ia_css_isp_firmware] = "ISP",
+ [ia_css_bootloader_firmware] = "BootLoader",
+ [ia_css_acc_firmware] = "accel",
+};
+
+static const char * const fw_acc_type_name[] = {
+ [IA_CSS_ACC_NONE] = "Normal",
+ [IA_CSS_ACC_OUTPUT] = "Accel for output",
+ [IA_CSS_ACC_VIEWFINDER] = "Accel for viewfinder",
+ [IA_CSS_ACC_STANDALONE] = "Stand-alone accel",
+};
+
+int
sh_css_load_firmware(struct device *dev, const char *fw_data,
unsigned int fw_size) {
unsigned int i;
struct ia_css_fw_info *binaries;
struct sh_css_fw_bi_file_h *file_header;
- bool valid_firmware = false;
+ int ret;
const char *release_version;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
release_version = isp2400_release_version;
else
release_version = isp2401_release_version;
@@ -223,21 +239,21 @@ sh_css_load_firmware(struct device *dev, const char *fw_data,
file_header = &firmware_header->file_header;
binaries = &firmware_header->binary_header;
strscpy(FW_rel_ver_name, file_header->version, min(sizeof(FW_rel_ver_name), sizeof(file_header->version)));
- valid_firmware = sh_css_check_firmware_version(dev, fw_data);
- if (!valid_firmware) {
+ ret = sh_css_check_firmware_version(dev, fw_data);
+ if (ret) {
IA_CSS_ERROR("CSS code version (%s) and firmware version (%s) mismatch!",
file_header->version, release_version);
- return IA_CSS_ERR_VERSION_MISMATCH;
+ return -EINVAL;
} else {
IA_CSS_LOG("successfully load firmware version %s", release_version);
}
/* some sanity checks */
if (!fw_data || fw_size < sizeof(struct sh_css_fw_bi_file_h))
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
if (file_header->h_size != sizeof(struct sh_css_fw_bi_file_h))
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
sh_css_num_binaries = file_header->binary_nr;
/* Only allocate memory for ISP blob info */
@@ -247,7 +263,7 @@ sh_css_load_firmware(struct device *dev, const char *fw_data,
(sh_css_num_binaries - NUM_OF_SPS) *
sizeof(*sh_css_blob_info), GFP_KERNEL);
if (!sh_css_blob_info)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
} else {
sh_css_blob_info = NULL;
}
@@ -255,7 +271,7 @@ sh_css_load_firmware(struct device *dev, const char *fw_data,
fw_minibuffer = kcalloc(sh_css_num_binaries, sizeof(struct fw_param),
GFP_KERNEL);
if (!fw_minibuffer)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
for (i = 0; i < sh_css_num_binaries; i++)
{
@@ -265,36 +281,71 @@ sh_css_load_firmware(struct device *dev, const char *fw_data,
cause issues for drivers
*/
static struct ia_css_blob_descr bd;
- enum ia_css_err err;
+ int err;
err = sh_css_load_blob_info(fw_data, bi, &bd, i);
- if (err != IA_CSS_SUCCESS)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ if (err)
+ return -EINVAL;
if (bi->blob.offset + bi->blob.size > fw_size)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
+
+ switch (bd.header.type) {
+ case ia_css_isp_firmware:
+ if (bd.header.info.isp.type > IA_CSS_ACC_STANDALONE) {
+ dev_err(dev, "binary #%2d: invalid SP type\n",
+ i);
+ return -EINVAL;
+ }
+
+ dev_dbg(dev,
+ "binary #%-2d type %s (%s), binary id is %2d: %s\n",
+ i,
+ fw_type_name[bd.header.type],
+ fw_acc_type_name[bd.header.info.isp.type],
+ bd.header.info.isp.sp.id,
+ bd.name);
+ break;
+ case ia_css_sp_firmware:
+ case ia_css_bootloader_firmware:
+ case ia_css_acc_firmware:
+ dev_dbg(dev,
+ "binary #%-2d type %s: %s\n",
+ i, fw_type_name[bd.header.type],
+ bd.name);
+ break;
+ default:
+ if (bd.header.info.isp.type > IA_CSS_ACC_STANDALONE) {
+ dev_err(dev,
+ "binary #%2d: invalid firmware type\n",
+ i);
+ return -EINVAL;
+ }
+ break;
+ }
if (bi->type == ia_css_sp_firmware) {
if (i != SP_FIRMWARE)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
err = setup_binary(bi, fw_data, &sh_css_sp_fw, i);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
+
} else {
/* All subsequent binaries (including bootloaders) (i>NUM_OF_SPS) are ISP firmware */
if (i < NUM_OF_SPS)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
if (bi->type != ia_css_isp_firmware)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
if (!sh_css_blob_info) /* cannot happen but KW does not see this */
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
sh_css_blob_info[i - NUM_OF_SPS] = bd;
}
}
- return IA_CSS_SUCCESS;
+ return 0;
}
void sh_css_unload_firmware(void)
@@ -319,15 +370,15 @@ void sh_css_unload_firmware(void)
sh_css_num_binaries = 0;
}
-hrt_vaddress
+ia_css_ptr
sh_css_load_blob(const unsigned char *blob, unsigned int size)
{
- hrt_vaddress target_addr = mmgr_malloc(size);
+ ia_css_ptr target_addr = hmm_alloc(size, HMM_BO_PRIVATE, 0, NULL, 0);
/* this will allocate memory aligned to a DDR word boundary which
is required for the CSS DMA to read the instructions. */
assert(blob);
if (target_addr)
- mmgr_store(target_addr, blob, size);
+ hmm_store(target_addr, blob, size);
return target_addr;
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_firmware.h b/drivers/staging/media/atomisp/pci/sh_css_firmware.h
index f6253392a6c9..66cd38f08f71 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_firmware.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_firmware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -15,7 +16,7 @@
#ifndef _SH_CSS_FIRMWARE_H_
#define _SH_CSS_FIRMWARE_H_
-#include <system_types.h>
+#include <system_local.h>
#include <ia_css_err.h>
#include <ia_css_acc_types.h>
@@ -37,18 +38,19 @@ extern unsigned int sh_css_num_binaries;
char
*sh_css_get_fw_version(void);
+struct device;
bool
sh_css_check_firmware_version(struct device *dev, const char *fw_data);
-enum ia_css_err
+int
sh_css_load_firmware(struct device *dev, const char *fw_data,
unsigned int fw_size);
void sh_css_unload_firmware(void);
-hrt_vaddress sh_css_load_blob(const unsigned char *blob, unsigned int size);
+ia_css_ptr sh_css_load_blob(const unsigned char *blob, unsigned int size);
-enum ia_css_err
+int
sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
struct ia_css_blob_descr *bd, unsigned int i);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_frac.h b/drivers/staging/media/atomisp/pci/sh_css_frac.h
index cd2d755ec523..8f08df5c88cc 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_frac.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_frac.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_host_data.c b/drivers/staging/media/atomisp/pci/sh_css_host_data.c
index 348183a221a8..39a9b9812682 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_host_data.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_host_data.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -24,7 +25,7 @@ struct ia_css_host_data *ia_css_host_data_allocate(size_t size)
if (!me)
return NULL;
me->size = (uint32_t)size;
- me->address = sh_css_malloc(size);
+ me->address = kvmalloc(size, GFP_KERNEL);
if (!me->address) {
kfree(me);
return NULL;
@@ -35,7 +36,7 @@ struct ia_css_host_data *ia_css_host_data_allocate(size_t size)
void ia_css_host_data_free(struct ia_css_host_data *me)
{
if (me) {
- sh_css_free(me->address);
+ kvfree(me->address);
me->address = NULL;
kfree(me);
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_hrt.c b/drivers/staging/media/atomisp/pci/sh_css_hrt.c
index 94b2de5b5ef4..06b502151af9 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_hrt.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_hrt.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -61,7 +62,7 @@ bool sh_css_hrt_system_is_idle(void)
return !not_idle;
}
-enum ia_css_err sh_css_hrt_sp_wait(void)
+int sh_css_hrt_sp_wait(void)
{
#if defined(HAS_IRQ_MAP_VERSION_2)
irq_sw_channel_id_t irq_id = IRQ_SW_CHANNEL0_ID;
@@ -78,8 +79,8 @@ enum ia_css_err sh_css_hrt_sp_wait(void)
((irq_reg_load(IRQ0_ID,
_HRT_IRQ_CONTROLLER_STATUS_REG_IDX) &
(1U << (irq_id + IRQ_SW_CHANNEL_OFFSET))) == 0)) {
- hrt_sleep();
+ udelay(1);
}
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_hrt.h b/drivers/staging/media/atomisp/pci/sh_css_hrt.h
index fd23ed1848ec..168bbd579798 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_hrt.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_hrt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -27,7 +28,7 @@ void sh_css_hrt_sp_start_copy_frame(void);
void sh_css_hrt_sp_start_isp(void);
-enum ia_css_err sh_css_hrt_sp_wait(void);
+int sh_css_hrt_sp_wait(void);
bool sh_css_hrt_system_is_idle(void);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_internal.h b/drivers/staging/media/atomisp/pci/sh_css_internal.h
index 5f271d9ae485..5c25a25dce92 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_internal.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -75,11 +76,7 @@
#define SH_CSS_REF_BIT_DEPTH 8
/* keep next up to date with the definition for MAX_CB_ELEMS_FOR_TAGGER in tagger.sp.c */
-#if defined(HAS_SP_2400)
#define NUM_CONTINUOUS_FRAMES 15
-#else
-#define NUM_CONTINUOUS_FRAMES 10
-#endif
#define NUM_MIPI_FRAMES_PER_STREAM 2
#define NUM_ONLINE_INIT_CONTINUOUS_FRAMES 2
@@ -209,28 +206,28 @@ enum sh_css_sp_event_type {
};
/* xmem address map allocation per pipeline, css pointers */
-/* Note that the struct below should only consist of hrt_vaddress-es
+/* Note that the struct below should only consist of ia_css_ptr-es
Otherwise this will cause a fail in the function ref_sh_css_ddr_address_map
*/
struct sh_css_ddr_address_map {
- hrt_vaddress isp_param;
- hrt_vaddress isp_mem_param[SH_CSS_MAX_STAGES][IA_CSS_NUM_MEMORIES];
- hrt_vaddress macc_tbl;
- hrt_vaddress fpn_tbl;
- hrt_vaddress sc_tbl;
- hrt_vaddress tetra_r_x;
- hrt_vaddress tetra_r_y;
- hrt_vaddress tetra_gr_x;
- hrt_vaddress tetra_gr_y;
- hrt_vaddress tetra_gb_x;
- hrt_vaddress tetra_gb_y;
- hrt_vaddress tetra_b_x;
- hrt_vaddress tetra_b_y;
- hrt_vaddress tetra_ratb_x;
- hrt_vaddress tetra_ratb_y;
- hrt_vaddress tetra_batr_x;
- hrt_vaddress tetra_batr_y;
- hrt_vaddress dvs_6axis_params_y;
+ ia_css_ptr isp_param;
+ ia_css_ptr isp_mem_param[SH_CSS_MAX_STAGES][IA_CSS_NUM_MEMORIES];
+ ia_css_ptr macc_tbl;
+ ia_css_ptr fpn_tbl;
+ ia_css_ptr sc_tbl;
+ ia_css_ptr tetra_r_x;
+ ia_css_ptr tetra_r_y;
+ ia_css_ptr tetra_gr_x;
+ ia_css_ptr tetra_gr_y;
+ ia_css_ptr tetra_gb_x;
+ ia_css_ptr tetra_gb_y;
+ ia_css_ptr tetra_b_x;
+ ia_css_ptr tetra_b_y;
+ ia_css_ptr tetra_ratb_x;
+ ia_css_ptr tetra_ratb_y;
+ ia_css_ptr tetra_batr_x;
+ ia_css_ptr tetra_batr_y;
+ ia_css_ptr dvs_6axis_params_y;
};
#define SIZE_OF_SH_CSS_DDR_ADDRESS_MAP_STRUCT \
@@ -279,9 +276,9 @@ struct ia_css_isp_parameter_set_info {
a binary. It depends on the binary which ones are used. */
struct sh_css_binary_args {
struct ia_css_frame *in_frame; /* input frame */
- struct ia_css_frame
+ const struct ia_css_frame
*delay_frames[MAX_NUM_VIDEO_DELAY_FRAMES]; /* reference input frame */
- struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES]; /* tnr frames */
+ const struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES]; /* tnr frames */
struct ia_css_frame
*out_frame[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; /* output frame */
struct ia_css_frame *out_vf_frame; /* viewfinder output frame */
@@ -531,8 +528,8 @@ struct sh_css_sp_pipeline {
u32 port_id; /* port_id for input system */
u32 num_stages; /* the pipe config */
u32 running; /* needed for pipe termination */
- hrt_vaddress sp_stage_addr[SH_CSS_MAX_STAGES];
- hrt_vaddress scaler_pp_lut; /* Early bound LUT */
+ ia_css_ptr sp_stage_addr[SH_CSS_MAX_STAGES];
+ ia_css_ptr scaler_pp_lut; /* Early bound LUT */
u32 dummy; /* stage ptr is only used on sp but lives in
this struct; needs cleanup */
s32 num_execs; /* number of times to run if this is
@@ -544,7 +541,7 @@ struct sh_css_sp_pipeline {
u32 height; /* Number of lines */
u32 stride; /* Stride (in bytes) per line */
u32 size; /* Total size (in bytes) */
- hrt_vaddress cont_buf; /* Address of continuous buffer */
+ ia_css_ptr cont_buf; /* Address of continuous buffer */
} metadata;
#endif
#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
@@ -657,9 +654,9 @@ struct sh_css_sp_stage {
struct ia_css_frames_sp frames;
struct ia_css_resolution dvs_envelope;
struct sh_css_uds_info uds;
- hrt_vaddress isp_stage_addr;
- hrt_vaddress xmem_bin_addr;
- hrt_vaddress xmem_map_addr;
+ ia_css_ptr isp_stage_addr;
+ ia_css_ptr xmem_bin_addr;
+ ia_css_ptr xmem_map_addr;
u16 top_cropping;
u16 row_stripes_height;
@@ -692,7 +689,7 @@ struct sh_css_sp_group {
/* Data in SP dmem that is set from the host every stage. */
struct sh_css_sp_per_frame_data {
/* ddr address of sp_group and sp_stage */
- hrt_vaddress sp_group_addr;
+ ia_css_ptr sp_group_addr;
};
#define SH_CSS_NUM_SDW_IRQS 3
@@ -728,25 +725,19 @@ struct sh_css_sp_output {
* separate SP thread for this. */
#define IA_CSS_NUM_ELEMS_HOST2SP_ISYS_EVENT_QUEUE (2 * N_CSI_PORTS)
-#if defined(HAS_SP_2400)
#define IA_CSS_NUM_ELEMS_HOST2SP_PSYS_EVENT_QUEUE 13
#define IA_CSS_NUM_ELEMS_SP2HOST_BUFFER_QUEUE 19
#define IA_CSS_NUM_ELEMS_SP2HOST_PSYS_EVENT_QUEUE 26 /* holds events for all type of buffers, hence deeper */
-#else
-#define IA_CSS_NUM_ELEMS_HOST2SP_PSYS_EVENT_QUEUE 6
-#define IA_CSS_NUM_ELEMS_SP2HOST_BUFFER_QUEUE 6
-#define IA_CSS_NUM_ELEMS_SP2HOST_PSYS_EVENT_QUEUE 6
-#endif
struct sh_css_hmm_buffer {
union {
struct ia_css_isp_3a_statistics s3a;
struct ia_css_isp_dvs_statistics dis;
- hrt_vaddress skc_dvs_statistics;
- hrt_vaddress lace_stat;
+ ia_css_ptr skc_dvs_statistics;
+ ia_css_ptr lace_stat;
struct ia_css_metadata metadata;
struct frame_data_wrapper {
- hrt_vaddress frame_data;
+ ia_css_ptr frame_data;
u32 flashed;
u32 exp_id;
u32 isp_parameters_id; /** Unique ID to track which config was
@@ -755,7 +746,7 @@ struct sh_css_hmm_buffer {
struct sh_css_config_on_frame_enqueue config_on_frame_enqueue;
#endif
} frame;
- hrt_vaddress ddr_ptrs;
+ ia_css_ptr ddr_ptrs;
} payload;
/*
* kernel_ptr is present for host administration purposes only.
@@ -834,12 +825,12 @@ struct host_sp_communication {
* TODO:
* Remove it when the Host and the SP is decoupled.
*/
- hrt_vaddress host2sp_offline_frames[NUM_CONTINUOUS_FRAMES];
- hrt_vaddress host2sp_offline_metadata[NUM_CONTINUOUS_FRAMES];
+ ia_css_ptr host2sp_offline_frames[NUM_CONTINUOUS_FRAMES];
+ ia_css_ptr host2sp_offline_metadata[NUM_CONTINUOUS_FRAMES];
#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
- hrt_vaddress host2sp_mipi_frames[N_CSI_PORTS][NUM_MIPI_FRAMES_PER_STREAM];
- hrt_vaddress host2sp_mipi_metadata[N_CSI_PORTS][NUM_MIPI_FRAMES_PER_STREAM];
+ ia_css_ptr host2sp_mipi_frames[N_CSI_PORTS][NUM_MIPI_FRAMES_PER_STREAM];
+ ia_css_ptr host2sp_mipi_metadata[N_CSI_PORTS][NUM_MIPI_FRAMES_PER_STREAM];
u32 host2sp_num_mipi_frames[N_CSI_PORTS];
#endif
u32 host2sp_cont_avail_num_raw_frames;
@@ -960,20 +951,14 @@ sh_css_vprint(const char *fmt, va_list args)
issue with the firmware struct/union's.
More permanent solution will be to refactor this include.
*/
-hrt_vaddress sh_css_params_ddr_address_map(void);
+ia_css_ptr sh_css_params_ddr_address_map(void);
-enum ia_css_err
+int
sh_css_params_init(void);
void
sh_css_params_uninit(void);
-void *sh_css_malloc(size_t size);
-
-void *sh_css_calloc(size_t N, size_t size);
-
-void sh_css_free(void *ptr);
-
/* For Acceleration API: Flush FW (shared buffer pointer) arguments */
void sh_css_flush(struct ia_css_acc_fw *fw);
@@ -1010,13 +995,13 @@ sh_css_get_mipi_sizes_for_check(const unsigned int port,
#endif
-hrt_vaddress
+ia_css_ptr
sh_css_store_sp_group_to_ddr(void);
-hrt_vaddress
+ia_css_ptr
sh_css_store_sp_stage_to_ddr(unsigned int pipe, unsigned int stage);
-hrt_vaddress
+ia_css_ptr
sh_css_store_isp_stage_to_ddr(unsigned int pipe, unsigned int stage);
void
diff --git a/drivers/staging/media/atomisp/pci/sh_css_legacy.h b/drivers/staging/media/atomisp/pci/sh_css_legacy.h
index 99ac690ba7aa..567c8d6dcc2c 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_legacy.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_legacy.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -45,7 +46,7 @@ struct ia_css_pipe_extra_config {
bool disable_vf_pp;
};
-enum ia_css_err
+int
ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
const struct ia_css_pipe_extra_config *extra_config,
struct ia_css_pipe **pipe);
@@ -54,12 +55,12 @@ void
ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config
*extra_config);
-enum ia_css_err
+int
ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe,
enum ia_css_pipe_id *pipe_id);
/* DEPRECATED. FPN is not supported. */
-enum ia_css_err
+int
sh_css_set_black_frame(struct ia_css_stream *stream,
const struct ia_css_frame *raw_black_frame);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_metadata.c b/drivers/staging/media/atomisp/pci/sh_css_metadata.c
index ebdf84d4a138..04a4b7da85e2 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_metadata.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_metadata.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_metrics.c b/drivers/staging/media/atomisp/pci/sh_css_metrics.c
index 17f6dd9afab4..9744bbebe1bc 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_metrics.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_metrics.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -67,13 +68,16 @@ make_histogram(struct sh_css_pc_histogram *histogram, unsigned int length)
return;
if (histogram->run)
return;
- histogram->run = sh_css_malloc(length * sizeof(*histogram->run));
+ histogram->run = kvmalloc(length * sizeof(*histogram->run),
+ GFP_KERNEL);
if (!histogram->run)
return;
- histogram->stall = sh_css_malloc(length * sizeof(*histogram->stall));
+ histogram->stall = kvmalloc(length * sizeof(*histogram->stall),
+ GFP_KERNEL);
if (!histogram->stall)
return;
- histogram->msink = sh_css_malloc(length * sizeof(*histogram->msink));
+ histogram->msink = kvmalloc(length * sizeof(*histogram->msink),
+ GFP_KERNEL);
if (!histogram->msink)
return;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_metrics.h b/drivers/staging/media/atomisp/pci/sh_css_metrics.h
index f465d1545b8b..f4bcd08384e9 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_metrics.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_metrics.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
index 35cbef5f9f71..2ef5dbd62a6d 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -34,10 +35,10 @@ static u32
ref_count_mipi_allocation[N_CSI_PORTS]; /* Initialized in mipi_init */
#endif
-enum ia_css_err
+int
ia_css_mipi_frame_specify(const unsigned int size_mem_words,
const bool contiguous) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
my_css.size_mem_words = size_mem_words;
(void)contiguous;
@@ -97,14 +98,14 @@ static bool ia_css_mipi_is_source_port_valid(struct ia_css_pipe *pipe,
* etc.).
* Result is given in DDR mem words, 32B or 256 bits
*/
-enum ia_css_err
+int
ia_css_mipi_frame_calculate_size(const unsigned int width,
const unsigned int height,
const enum atomisp_input_format format,
const bool hasSOLandEOL,
const unsigned int embedded_data_size_words,
unsigned int *size_mem_words) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int bits_per_pixel = 0;
unsigned int even_line_bytes = 0;
@@ -182,7 +183,7 @@ ia_css_mipi_frame_calculate_size(const unsigned int width,
case ATOMISP_INPUT_FORMAT_YUV422_16: /* Not supported */
case ATOMISP_INPUT_FORMAT_RAW_16: /* TODO: not specified in MIPI SPEC, check */
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
odd_line_bytes = (width_padded * bits_per_pixel + 7) >> 3; /* ceil ( bits per line / 8) */
@@ -246,12 +247,12 @@ ia_css_mipi_frame_calculate_size(const unsigned int width,
}
#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
-enum ia_css_err
+int
ia_css_mipi_frame_enable_check_on_size(const enum mipi_port_id port,
const unsigned int size_mem_words) {
u32 idx;
- enum ia_css_err err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ int err = -EBUSY;
OP___assert(port < N_CSI_PORTS);
OP___assert(size_mem_words != 0);
@@ -264,7 +265,7 @@ ia_css_mipi_frame_enable_check_on_size(const enum mipi_port_id port,
if (idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT)
{
my_css.mipi_sizes_for_check[port][idx] = size_mem_words;
- err = IA_CSS_SUCCESS;
+ err = 0;
}
return err;
@@ -282,12 +283,12 @@ mipi_init(void)
#endif
}
-enum ia_css_err
+int
calculate_mipi_buff_size(
struct ia_css_stream_config *stream_cfg,
unsigned int *size_mem_words) {
#if !defined(USE_INPUT_SYSTEM_VERSION_2401)
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
(void)stream_cfg;
(void)size_mem_words;
#else
@@ -310,7 +311,7 @@ calculate_mipi_buff_size(
unsigned int mem_words_per_buff_line = 0;
unsigned int mem_words_per_buff = 0;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
/**
* zhengjie.lu@intel.com
@@ -354,7 +355,7 @@ calculate_mipi_buff_size(
bits_per_pixel =
(format == ATOMISP_INPUT_FORMAT_RAW_10 && pack_raw_pixels) ? bits_per_pixel : 16;
if (bits_per_pixel == 0)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
odd_line_bytes = (width_padded * bits_per_pixel + 7) >> 3; /* ceil ( bits per line / 8) */
@@ -390,7 +391,7 @@ calculate_mipi_buff_size(
static bool buffers_needed(struct ia_css_pipe *pipe)
{
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
return false;
else
@@ -405,11 +406,11 @@ static bool buffers_needed(struct ia_css_pipe *pipe)
return true;
}
-enum ia_css_err
+int
allocate_mipi_frames(struct ia_css_pipe *pipe,
struct ia_css_stream_info *info) {
#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
unsigned int port;
struct ia_css_frame_info mipi_intermediate_info;
@@ -423,7 +424,7 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: pipe or stream is null.\n",
pipe);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
#ifdef USE_INPUT_SYSTEM_VERSION_2401
@@ -432,7 +433,7 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: no buffers needed for 2401 pipe mode.\n",
pipe);
- return IA_CSS_SUCCESS;
+ return 0;
}
#endif
@@ -441,10 +442,10 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: no buffers needed for pipe mode.\n",
pipe);
- return IA_CSS_SUCCESS; /* AM TODO: Check */
+ return 0; /* AM TODO: Check */
}
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
port = (unsigned int)pipe->stream->config.source.port.port;
else
err = ia_css_mipi_is_source_port_valid(pipe, &port);
@@ -455,7 +456,7 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: error: port is not correct (port=%d).\n",
pipe, port);
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
#ifdef USE_INPUT_SYSTEM_VERSION_2401
@@ -470,7 +471,7 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: already allocated for this port (port=%d).\n",
pipe, port);
- return IA_CSS_SUCCESS;
+ return 0;
}
#else
/* 2401 system allows multiple streams to use same physical port. This is not
@@ -484,7 +485,7 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) leave: nothing to do, already allocated for this port (port=%d).\n",
pipe, port);
- return IA_CSS_SUCCESS;
+ return 0;
}
#endif
@@ -522,7 +523,7 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
&my_css.mipi_frames[port][i],
my_css.mipi_frame_size[port] * HIVE_ISP_DDR_WORD_BYTES,
false);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
for (j = 0; j < i; j++) {
if (my_css.mipi_frames[port][j]) {
ia_css_frame_free(my_css.mipi_frames[port][j]);
@@ -562,14 +563,14 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
#else
(void)pipe;
(void)info;
- return IA_CSS_SUCCESS;
+ return 0;
#endif
}
-enum ia_css_err
+int
free_mipi_frames(struct ia_css_pipe *pipe) {
#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
unsigned int port;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
@@ -583,7 +584,7 @@ free_mipi_frames(struct ia_css_pipe *pipe) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"free_mipi_frames(%p) exit: error: pipe or stream is null.\n",
pipe);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
if (!buffers_needed(pipe)) {
@@ -593,7 +594,7 @@ free_mipi_frames(struct ia_css_pipe *pipe) {
return err;
}
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
port = (unsigned int)pipe->stream->config.source.port.port;
else
err = ia_css_mipi_is_source_port_valid(pipe, &port);
@@ -677,13 +678,13 @@ free_mipi_frames(struct ia_css_pipe *pipe) {
#else
(void)pipe;
#endif
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
send_mipi_frames(struct ia_css_pipe *pipe) {
#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
- enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
+ int err = -EINVAL;
unsigned int i;
#ifndef ISP2401
unsigned int port;
@@ -698,18 +699,18 @@ send_mipi_frames(struct ia_css_pipe *pipe) {
if (!pipe || !pipe->stream)
{
IA_CSS_ERROR("pipe or stream is null");
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
/* multi stream video needs mipi buffers */
/* nothing to be done in other cases. */
if (!buffers_needed(pipe)) {
IA_CSS_LOG("nothing to be done for this mode");
- return IA_CSS_SUCCESS;
+ return 0;
/* TODO: AM: maybe this should be returning an error. */
}
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
port = (unsigned int)pipe->stream->config.source.port.port;
else
err = ia_css_mipi_is_source_port_valid(pipe, &port);
@@ -749,9 +750,9 @@ send_mipi_frames(struct ia_css_pipe *pipe) {
(uint8_t)port,
(uint8_t)my_css.num_mipi_frames[port],
0 /* not used */);
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
#else
(void)pipe;
#endif
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.h b/drivers/staging/media/atomisp/pci/sh_css_mipi.h
index ab38589d6457..52f08a103883 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -22,13 +23,13 @@
void
mipi_init(void);
-enum ia_css_err
+int
allocate_mipi_frames(struct ia_css_pipe *pipe, struct ia_css_stream_info *info);
-enum ia_css_err
+int
free_mipi_frames(struct ia_css_pipe *pipe);
-enum ia_css_err
+int
send_mipi_frames(struct ia_css_pipe *pipe);
/**
@@ -41,7 +42,7 @@ send_mipi_frames(struct ia_css_pipe *pipe);
*
* @return
*/
-enum ia_css_err
+int
calculate_mipi_buff_size(
struct ia_css_stream_config *stream_cfg,
unsigned int *size_mem_words);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mmu.c b/drivers/staging/media/atomisp/pci/sh_css_mmu.c
index 179b6f40be49..1da7459eaa25 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mmu.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_mmu.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -43,7 +44,6 @@ ia_css_mmu_invalidate_cache(void)
"ia_css_mmu_invalidate_cache() leave\n");
}
-/* Deprecated, this is an HRT backend function (memory_access.h) */
void
sh_css_mmu_set_page_table_base_index(hrt_data base_index)
{
diff --git a/drivers/staging/media/atomisp/pci/sh_css_morph.c b/drivers/staging/media/atomisp/pci/sh_css_morph.c
index 1f4fa25b1e79..edd1da941ccb 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_morph.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_morph.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
index 52e29161cb35..ff0082d02af3 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -18,7 +19,6 @@
#include <ia_css_err.h>
#include <ia_css_types.h>
#include "ia_css_debug.h"
-#include "memory_access.h"
static struct ia_css_dvs_6axis_config *
alloc_dvs_6axis_table(const struct ia_css_resolution *frame_res,
@@ -28,14 +28,14 @@ alloc_dvs_6axis_table(const struct ia_css_resolution *frame_res,
unsigned int height_y = 0;
unsigned int width_uv = 0;
unsigned int height_uv = 0;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_dvs_6axis_config *dvs_config = NULL;
- dvs_config = (struct ia_css_dvs_6axis_config *)sh_css_malloc(sizeof(
- struct ia_css_dvs_6axis_config));
+ dvs_config = kvmalloc(sizeof(struct ia_css_dvs_6axis_config),
+ GFP_KERNEL);
if (!dvs_config) {
IA_CSS_ERROR("out of memory");
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
} else {
/*Initialize new struct with latest config settings*/
if (dvs_config_src) {
@@ -58,41 +58,41 @@ alloc_dvs_6axis_table(const struct ia_css_resolution *frame_res,
}
/* Generate Y buffers */
- dvs_config->xcoords_y = (uint32_t *)sh_css_malloc(width_y * height_y * sizeof(
- uint32_t));
+ dvs_config->xcoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->xcoords_y) {
IA_CSS_ERROR("out of memory");
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto exit;
}
- dvs_config->ycoords_y = (uint32_t *)sh_css_malloc(width_y * height_y * sizeof(
- uint32_t));
+ dvs_config->ycoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->ycoords_y) {
IA_CSS_ERROR("out of memory");
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto exit;
}
/* Generate UV buffers */
IA_CSS_LOG("UV W %d H %d", width_uv, height_uv);
- dvs_config->xcoords_uv = (uint32_t *)sh_css_malloc(width_uv * height_uv *
- sizeof(uint32_t));
+ dvs_config->xcoords_uv = kvmalloc(width_uv * height_uv * sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->xcoords_uv) {
IA_CSS_ERROR("out of memory");
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
goto exit;
}
- dvs_config->ycoords_uv = (uint32_t *)sh_css_malloc(width_uv * height_uv *
- sizeof(uint32_t));
+ dvs_config->ycoords_uv = kvmalloc(width_uv * height_uv * sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->ycoords_uv) {
IA_CSS_ERROR("out of memory");
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
}
exit:
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
free_dvs_6axis_table(
&dvs_config); /* we might have allocated some memory, release this */
dvs_config = NULL;
@@ -208,28 +208,28 @@ free_dvs_6axis_table(struct ia_css_dvs_6axis_config **dvs_6axis_config)
if ((dvs_6axis_config) && (*dvs_6axis_config)) {
IA_CSS_ENTER_PRIVATE("dvs_6axis_config %p", (*dvs_6axis_config));
if ((*dvs_6axis_config)->xcoords_y) {
- sh_css_free((*dvs_6axis_config)->xcoords_y);
+ kvfree((*dvs_6axis_config)->xcoords_y);
(*dvs_6axis_config)->xcoords_y = NULL;
}
if ((*dvs_6axis_config)->ycoords_y) {
- sh_css_free((*dvs_6axis_config)->ycoords_y);
+ kvfree((*dvs_6axis_config)->ycoords_y);
(*dvs_6axis_config)->ycoords_y = NULL;
}
/* Free up UV buffers */
if ((*dvs_6axis_config)->xcoords_uv) {
- sh_css_free((*dvs_6axis_config)->xcoords_uv);
+ kvfree((*dvs_6axis_config)->xcoords_uv);
(*dvs_6axis_config)->xcoords_uv = NULL;
}
if ((*dvs_6axis_config)->ycoords_uv) {
- sh_css_free((*dvs_6axis_config)->ycoords_uv);
+ kvfree((*dvs_6axis_config)->ycoords_uv);
(*dvs_6axis_config)->ycoords_uv = NULL;
}
IA_CSS_LEAVE_PRIVATE("dvs_6axis_config %p", (*dvs_6axis_config));
- sh_css_free(*dvs_6axis_config);
+ kvfree(*dvs_6axis_config);
*dvs_6axis_config = NULL;
}
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h
index b4cffbbdafde..7782f76b9f97 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
index 4b648df2d073..046f34857891 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -360,12 +361,13 @@ ia_css_shading_table_alloc(
me->fraction_bits = 0;
for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) {
me->data[i] =
- sh_css_malloc(width * height * sizeof(*me->data[0]));
+ kvmalloc(width * height * sizeof(*me->data[0]),
+ GFP_KERNEL);
if (!me->data[i]) {
unsigned int j;
for (j = 0; j < i; j++) {
- sh_css_free(me->data[j]);
+ kvfree(me->data[j]);
me->data[j] = NULL;
}
kfree(me);
@@ -392,7 +394,7 @@ ia_css_shading_table_free(struct ia_css_shading_table *table)
for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) {
if (table->data[i]) {
- sh_css_free(table->data[i]);
+ kvfree(table->data[i]);
table->data[i] = NULL;
}
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_shading.h b/drivers/staging/media/atomisp/pci/sh_css_param_shading.h
index 6e480d31c201..7cdfaaec0b1c 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_shading.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_shading.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
index 2e719f7db89e..ba42be9b06eb 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -24,6 +25,7 @@
#define IA_CSS_INCLUDE_PARAMETERS
#define IA_CSS_INCLUDE_ACC_PARAMETERS
+#include "hmm.h"
#include "sh_css_params.h"
#include "ia_css_queue.h"
#include "sw_event_global.h" /* Event IDs */
@@ -45,10 +47,7 @@
#include "sh_css_sp.h"
#include "ia_css_pipeline.h"
#include "ia_css_debug.h"
-#include "memory_access.h"
-#if 0 /* FIXME */
-#include "memory_realloc.h"
-#endif
+
#include "ia_css_isp_param.h"
#include "ia_css_isp_params.h"
#include "ia_css_mipi.h"
@@ -126,17 +125,17 @@
/* We keep a second copy of the ptr struct for the SP to access.
Again, this would not be necessary on the chip. */
-static hrt_vaddress sp_ddr_ptrs;
+static ia_css_ptr sp_ddr_ptrs;
/* sp group address on DDR */
-static hrt_vaddress xmem_sp_group_ptrs;
+static ia_css_ptr xmem_sp_group_ptrs;
-static hrt_vaddress xmem_sp_stage_ptrs[IA_CSS_PIPE_ID_NUM]
+static ia_css_ptr xmem_sp_stage_ptrs[IA_CSS_PIPE_ID_NUM]
[SH_CSS_MAX_STAGES];
-static hrt_vaddress xmem_isp_stage_ptrs[IA_CSS_PIPE_ID_NUM]
+static ia_css_ptr xmem_isp_stage_ptrs[IA_CSS_PIPE_ID_NUM]
[SH_CSS_MAX_STAGES];
-static hrt_vaddress default_gdc_lut;
+static ia_css_ptr default_gdc_lut;
static int interleaved_lut_temp[4][HRT_GDC_N];
/* END DO NOT MOVE INTO VIMALS_WORLD */
@@ -1229,20 +1228,20 @@ struct ia_css_isp_skc_dvs_statistics {
ia_css_ptr p_data;
};
-static enum ia_css_err
+static int
ref_sh_css_ddr_address_map(
struct sh_css_ddr_address_map *map,
struct sh_css_ddr_address_map *out);
-static enum ia_css_err
+static int
write_ia_css_isp_parameter_set_info_to_ddr(
struct ia_css_isp_parameter_set_info *me,
- hrt_vaddress *out);
+ ia_css_ptr *out);
-static enum ia_css_err
-free_ia_css_isp_parameter_set_info(hrt_vaddress ptr);
+static int
+free_ia_css_isp_parameter_set_info(ia_css_ptr ptr);
-static enum ia_css_err
+static int
sh_css_params_write_to_ddr_internal(
struct ia_css_pipe *pipe,
unsigned int pipe_id,
@@ -1251,7 +1250,7 @@ sh_css_params_write_to_ddr_internal(
struct sh_css_ddr_address_map *ddr_map,
struct sh_css_ddr_address_map_size *ddr_map_size);
-static enum ia_css_err
+static int
sh_css_create_isp_params(struct ia_css_stream *stream,
struct ia_css_isp_parameters **isp_params_out);
@@ -1261,27 +1260,27 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
bool use_default_config,
struct ia_css_pipe *pipe_in);
-static enum ia_css_err
+static int
sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
struct ia_css_isp_parameters *params,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe_in);
-static enum ia_css_err
+static int
sh_css_set_global_isp_config_on_pipe(
struct ia_css_pipe *curr_pipe,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe);
#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
-static enum ia_css_err
+static int
sh_css_set_per_frame_isp_config_on_pipe(
struct ia_css_stream *stream,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe);
#endif
-static enum ia_css_err
+static int
sh_css_update_uds_and_crop_info_based_on_zoom_region(
const struct ia_css_binary_info *info,
const struct ia_css_frame_info *in_frame_info,
@@ -1294,7 +1293,7 @@ sh_css_update_uds_and_crop_info_based_on_zoom_region(
struct ia_css_resolution pipe_in_res,
bool enable_zoom);
-hrt_vaddress
+ia_css_ptr
sh_css_params_ddr_address_map(void)
{
return sp_ddr_ptrs;
@@ -1351,8 +1350,8 @@ convert_allocate_fpntbl(struct ia_css_isp_parameters *params)
return me;
}
-static enum ia_css_err
-store_fpntbl(struct ia_css_isp_parameters *params, hrt_vaddress ptr) {
+static int
+store_fpntbl(struct ia_css_isp_parameters *params, ia_css_ptr ptr) {
struct ia_css_host_data *isp_data;
assert(params);
@@ -1361,13 +1360,13 @@ store_fpntbl(struct ia_css_isp_parameters *params, hrt_vaddress ptr) {
isp_data = convert_allocate_fpntbl(params);
if (!isp_data)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
ia_css_params_store_ia_css_host_data(ptr, isp_data);
ia_css_host_data_free(isp_data);
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -1431,10 +1430,10 @@ ia_css_process_kernel(struct ia_css_stream *stream,
}
}
-static enum ia_css_err
+static int
sh_css_select_dp_10bpp_config(const struct ia_css_pipe *pipe,
bool *is_dp_10bpp) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
/* Currently we check if 10bpp DPC configuration is required based
* on the use case,i.e. if BDS and DPC is both enabled. The more cleaner
* design choice would be to expose the type of DPC (either 10bpp or 13bpp)
@@ -1444,8 +1443,8 @@ sh_css_select_dp_10bpp_config(const struct ia_css_pipe *pipe,
*/
if ((!pipe) || (!is_dp_10bpp))
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ err = -EINVAL;
} else
{
*is_dp_10bpp = false;
@@ -1457,7 +1456,7 @@ sh_css_select_dp_10bpp_config(const struct ia_css_pipe *pipe,
if ((pipe->config.bayer_ds_out_res.width != 0) &&
(pipe->config.bayer_ds_out_res.height != 0)) {
- if (IA_CSS_SUCCESS == binarydesc_calculate_bds_factor(
+ if (0 == binarydesc_calculate_bds_factor(
pipe->config.input_effective_res,
pipe->config.bayer_ds_out_res,
&required_bds_factor)) {
@@ -1473,7 +1472,7 @@ sh_css_select_dp_10bpp_config(const struct ia_css_pipe *pipe,
return err;
}
-enum ia_css_err
+int
sh_css_set_black_frame(struct ia_css_stream *stream,
const struct ia_css_frame *raw_black_frame) {
struct ia_css_isp_parameters *params;
@@ -1481,7 +1480,7 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
* that it can use the DMA.
*/
unsigned int height, width, y, x, k, data;
- hrt_vaddress ptr;
+ ia_css_ptr ptr;
assert(stream);
assert(raw_black_frame);
@@ -1498,16 +1497,17 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
if (params->fpn_config.data &&
(params->fpn_config.width != width || params->fpn_config.height != height))
{
- sh_css_free(params->fpn_config.data);
+ kvfree(params->fpn_config.data);
params->fpn_config.data = NULL;
}
if (!params->fpn_config.data)
{
- params->fpn_config.data = sh_css_malloc(height * width * sizeof(short));
+ params->fpn_config.data = kvmalloc(height * width *
+ sizeof(short), GFP_KERNEL);
if (!params->fpn_config.data) {
IA_CSS_ERROR("out of memory");
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
params->fpn_config.width = width;
params->fpn_config.height = height;
@@ -1521,7 +1521,7 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
int ofs = y * width + x;
for (k = 0; k < ISP_VEC_NELEMS; k += 2) {
- mmgr_load(ptr, (void *)(&data), sizeof(int));
+ hmm_load(ptr, (void *)(&data), sizeof(int));
params->fpn_config.data[ofs + 2 * k] =
(short)(data & 0xFFFF);
params->fpn_config.data[ofs + 2 * k + 2] =
@@ -1529,7 +1529,7 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
ptr += sizeof(int); /* byte system address */
}
for (k = 0; k < ISP_VEC_NELEMS; k += 2) {
- mmgr_load(ptr, (void *)(&data), sizeof(int));
+ hmm_load(ptr, (void *)(&data), sizeof(int));
params->fpn_config.data[ofs + 2 * k + 1] =
(short)(data & 0xFFFF);
params->fpn_config.data[ofs + 2 * k + 3] =
@@ -1545,9 +1545,9 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
/* overwrite isp parameter */
ia_css_process_kernel(stream, params, ia_css_kernel_process_param[IA_CSS_FPN_ID]);
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
- return IA_CSS_SUCCESS;
+ return 0;
}
bool
@@ -1611,7 +1611,7 @@ sh_css_set_shading_table(struct ia_css_stream *stream,
void
ia_css_params_store_ia_css_host_data(
- hrt_vaddress ddr_addr,
+ ia_css_ptr ddr_addr,
struct ia_css_host_data *data)
{
assert(data);
@@ -1620,7 +1620,7 @@ ia_css_params_store_ia_css_host_data(
IA_CSS_ENTER_PRIVATE("");
- mmgr_store(ddr_addr,
+ hmm_store(ddr_addr,
(void *)(data->address),
(size_t)data->size);
@@ -1676,9 +1676,9 @@ ia_css_params_alloc_convert_sctbl(
return sctbl;
}
-enum ia_css_err ia_css_params_store_sctbl(
+int ia_css_params_store_sctbl(
const struct ia_css_pipeline_stage *stage,
- hrt_vaddress sc_tbl,
+ ia_css_ptr sc_tbl,
const struct ia_css_shading_table *sc_config)
{
struct ia_css_host_data *isp_sc_tbl;
@@ -1687,13 +1687,13 @@ enum ia_css_err ia_css_params_store_sctbl(
if (!sc_config) {
IA_CSS_LEAVE_PRIVATE("void");
- return IA_CSS_SUCCESS;
+ return 0;
}
isp_sc_tbl = ia_css_params_alloc_convert_sctbl(stage, sc_config);
if (!isp_sc_tbl) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
/* store the shading table to ddr */
ia_css_params_store_ia_css_host_data(sc_tbl, isp_sc_tbl);
@@ -1701,7 +1701,7 @@ enum ia_css_err ia_css_params_store_sctbl(
IA_CSS_LEAVE_PRIVATE("void");
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -1717,13 +1717,13 @@ sh_css_enable_pipeline(const struct ia_css_binary *binary)
IA_CSS_LEAVE_PRIVATE("void");
}
-static enum ia_css_err
+static int
ia_css_process_zoom_and_motion(
struct ia_css_isp_parameters *params,
const struct ia_css_pipeline_stage *first_stage) {
/* first_stage can be NULL */
const struct ia_css_pipeline_stage *stage;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
struct ia_css_resolution pipe_in_res;
pipe_in_res.width = 0;
@@ -1799,7 +1799,7 @@ ia_css_process_zoom_and_motion(
&params->uds[stage->stage_num].crop_pos,
pipe_in_res,
stage->enable_zoom);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
}
@@ -1912,16 +1912,16 @@ void ia_css_morph_table_free(
for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
if (me->coordinates_x[i]) {
- sh_css_free(me->coordinates_x[i]);
+ kvfree(me->coordinates_x[i]);
me->coordinates_x[i] = NULL;
}
if (me->coordinates_y[i]) {
- sh_css_free(me->coordinates_y[i]);
+ kvfree(me->coordinates_y[i]);
me->coordinates_y[i] = NULL;
}
}
- sh_css_free(me);
+ kvfree(me);
IA_CSS_LEAVE("void");
}
@@ -1934,7 +1934,7 @@ struct ia_css_morph_table *ia_css_morph_table_allocate(
IA_CSS_ENTER("");
- me = sh_css_malloc(sizeof(*me));
+ me = kvmalloc(sizeof(*me), GFP_KERNEL);
if (!me) {
IA_CSS_ERROR("out of memory");
return me;
@@ -1946,12 +1946,12 @@ struct ia_css_morph_table *ia_css_morph_table_allocate(
}
for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
- me->coordinates_x[i] =
- sh_css_malloc(height * width *
- sizeof(*me->coordinates_x[i]));
- me->coordinates_y[i] =
- sh_css_malloc(height * width *
- sizeof(*me->coordinates_y[i]));
+ me->coordinates_x[i] = kvmalloc(height * width *
+ sizeof(*me->coordinates_x[i]),
+ GFP_KERNEL);
+ me->coordinates_y[i] = kvmalloc(height * width *
+ sizeof(*me->coordinates_y[i]),
+ GFP_KERNEL);
if ((!me->coordinates_x[i]) ||
(!me->coordinates_y[i])) {
@@ -1966,7 +1966,7 @@ struct ia_css_morph_table *ia_css_morph_table_allocate(
return me;
}
-static enum ia_css_err sh_css_params_default_morph_table(
+static int sh_css_params_default_morph_table(
struct ia_css_morph_table **table,
const struct ia_css_binary *binary)
{
@@ -1987,7 +1987,7 @@ static enum ia_css_err sh_css_params_default_morph_table(
tab = ia_css_morph_table_allocate(width, height);
if (!tab)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
short val_y = start_y[i];
@@ -2016,9 +2016,9 @@ static enum ia_css_err sh_css_params_default_morph_table(
}
*table = tab;
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -2065,11 +2065,11 @@ ia_css_isp_3a_statistics_map_free(struct ia_css_isp_3a_statistics_map *me)
{
if (me) {
if (me->data_allocated) {
- sh_css_free(me->data_ptr);
+ kvfree(me->data_ptr);
me->data_ptr = NULL;
me->data_allocated = false;
}
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -2083,7 +2083,7 @@ ia_css_isp_3a_statistics_map_allocate(
* so we use a local char * instead. */
char *base_ptr;
- me = sh_css_malloc(sizeof(*me));
+ me = kvmalloc(sizeof(*me), GFP_KERNEL);
if (!me) {
IA_CSS_LEAVE("cannot allocate memory");
goto err;
@@ -2092,7 +2092,7 @@ ia_css_isp_3a_statistics_map_allocate(
me->data_ptr = data_ptr;
me->data_allocated = !data_ptr;
if (!data_ptr) {
- me->data_ptr = sh_css_malloc(isp_stats->size);
+ me->data_ptr = kvmalloc(isp_stats->size, GFP_KERNEL);
if (!me->data_ptr) {
IA_CSS_LEAVE("cannot allocate memory");
goto err;
@@ -2115,15 +2115,15 @@ ia_css_isp_3a_statistics_map_allocate(
err:
if (me)
- sh_css_free(me);
+ kvfree(me);
return NULL;
}
-enum ia_css_err
+int
ia_css_get_3a_statistics(struct ia_css_3a_statistics *host_stats,
const struct ia_css_isp_3a_statistics *isp_stats) {
struct ia_css_isp_3a_statistics_map *map;
- enum ia_css_err ret = IA_CSS_SUCCESS;
+ int ret = 0;
IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats);
@@ -2133,13 +2133,13 @@ ia_css_get_3a_statistics(struct ia_css_3a_statistics *host_stats,
map = ia_css_isp_3a_statistics_map_allocate(isp_stats, NULL);
if (map)
{
- mmgr_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
+ hmm_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
ia_css_translate_3a_statistics(host_stats, map);
ia_css_isp_3a_statistics_map_free(map);
} else
{
IA_CSS_ERROR("out of memory");
- ret = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ ret = -ENOMEM;
}
IA_CSS_LEAVE_ERR(ret);
@@ -2161,7 +2161,7 @@ ia_css_set_param_exceptions(const struct ia_css_pipe *pipe,
params->dp_config.b = params->wb_config.b;
params->dp_config.gb = params->wb_config.gb;
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
assert(pipe);
assert(pipe->mode < IA_CSS_PIPE_ID_NUM);
@@ -2431,22 +2431,22 @@ sh_css_pipe_isp_config_get(struct ia_css_pipe *pipe)
return pipe->config.p_isp_config;
}
-enum ia_css_err
+int
ia_css_stream_set_isp_config(
struct ia_css_stream *stream,
const struct ia_css_isp_config *config) {
return ia_css_stream_set_isp_config_on_pipe(stream, config, NULL);
}
-enum ia_css_err
+int
ia_css_stream_set_isp_config_on_pipe(
struct ia_css_stream *stream,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
if ((!stream) || (!config))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
IA_CSS_ENTER("stream=%p, config=%p, pipe=%p", stream, config, pipe);
@@ -2461,16 +2461,16 @@ ia_css_stream_set_isp_config_on_pipe(
return err;
}
-enum ia_css_err
+int
ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe,
struct ia_css_isp_config *config) {
struct ia_css_pipe *pipe_in = pipe;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER("pipe=%p", pipe);
if ((!pipe) || (!pipe->stream))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "config=%p\n", config);
@@ -2484,14 +2484,14 @@ ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe,
return err;
}
-static enum ia_css_err
+static int
sh_css_set_global_isp_config_on_pipe(
struct ia_css_pipe *curr_pipe,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe) {
- enum ia_css_err err = IA_CSS_SUCCESS;
- enum ia_css_err err1 = IA_CSS_SUCCESS;
- enum ia_css_err err2 = IA_CSS_SUCCESS;
+ int err = 0;
+ int err1 = 0;
+ int err2 = 0;
IA_CSS_ENTER_PRIVATE("stream=%p, config=%p, pipe=%p", curr_pipe, config, pipe);
@@ -2506,24 +2506,24 @@ sh_css_set_global_isp_config_on_pipe(
* but instead continue with updating the ISP params to enable testing of features
* which are currently in TR phase. */
- err = (err1 != IA_CSS_SUCCESS) ? err1 : ((err2 != IA_CSS_SUCCESS) ? err2 : err);
+ err = (err1 != 0) ? err1 : ((err2 != 0) ? err2 : err);
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
-static enum ia_css_err
+static int
sh_css_set_per_frame_isp_config_on_pipe(
struct ia_css_stream *stream,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe) {
unsigned int i;
bool per_frame_config_created = false;
- enum ia_css_err err = IA_CSS_SUCCESS;
- enum ia_css_err err1 = IA_CSS_SUCCESS;
- enum ia_css_err err2 = IA_CSS_SUCCESS;
- enum ia_css_err err3 = IA_CSS_SUCCESS;
+ int err = 0;
+ int err1 = 0;
+ int err2 = 0;
+ int err3 = 0;
struct sh_css_ddr_address_map *ddr_ptrs;
struct sh_css_ddr_address_map_size *ddr_ptrs_size;
@@ -2533,7 +2533,7 @@ sh_css_set_per_frame_isp_config_on_pipe(
if (!pipe)
{
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
goto exit;
}
@@ -2544,7 +2544,7 @@ sh_css_set_per_frame_isp_config_on_pipe(
{
err = sh_css_create_isp_params(stream,
&stream->per_frame_isp_params_configs);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto exit;
per_frame_config_created = true;
}
@@ -2554,7 +2554,7 @@ sh_css_set_per_frame_isp_config_on_pipe(
/* update new ISP params object with the new config */
if (!sh_css_init_isp_params_from_global(stream, params, false, pipe))
{
- err1 = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err1 = -EINVAL;
}
err2 = sh_css_init_isp_params_from_config(stream->pipes[0], params, config, pipe);
@@ -2578,21 +2578,21 @@ sh_css_set_per_frame_isp_config_on_pipe(
* The CSS API must pass this error information to the caller, ie. the host.
* We do not return this error immediately, but instead continue with updating the ISP params
* to enable testing of features which are currently in TR phase. */
- err = (err1 != IA_CSS_SUCCESS) ? err1 :
- (err2 != IA_CSS_SUCCESS) ? err2 :
- (err3 != IA_CSS_SUCCESS) ? err3 : err;
+ err = (err1 != 0) ? err1 :
+ (err2 != 0) ? err2 :
+ (err3 != 0) ? err3 : err;
exit:
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
#endif
-static enum ia_css_err
+static int
sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
struct ia_css_isp_parameters *params,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe_in) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool is_dp_10bpp = true;
assert(pipe);
@@ -2630,12 +2630,12 @@ sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
* before (NORM+OBC) or after. The folllowing code to set the
* DPC configuration should be updated when this interface is made
* available */
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
sh_css_set_dp_config(pipe, params, config->dp_config);
ia_css_set_param_exceptions(pipe, params);
}
- if (IA_CSS_SUCCESS ==
+ if (0 ==
sh_css_select_dp_10bpp_config(pipe, &is_dp_10bpp))
{
/* return an error when both DPC and BDS is enabled by the
@@ -2643,15 +2643,15 @@ sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
/* we do not exit from this point immediately to allow internal
* firmware feature testing. */
if (is_dp_10bpp) {
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
} else
{
- err = IA_CSS_ERR_INTERNAL_ERROR;
+ err = -EINVAL;
goto exit;
}
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
ia_css_set_param_exceptions(pipe, params);
exit:
@@ -2709,16 +2709,16 @@ ia_css_pipe_get_isp_config(struct ia_css_pipe *pipe,
* Deprecated: Implement mmgr_realloc()
*/
static bool realloc_isp_css_mm_buf(
- hrt_vaddress *curr_buf,
+ ia_css_ptr *curr_buf,
size_t *curr_size,
size_t needed_size,
bool force,
- enum ia_css_err *err,
+ int *err,
uint16_t mmgr_attribute)
{
s32 id;
- *err = IA_CSS_SUCCESS;
+ *err = 0;
/* Possible optimization: add a function sh_css_isp_css_mm_realloc()
* and implement on top of hmm. */
@@ -2736,11 +2736,13 @@ static bool realloc_isp_css_mm_buf(
id = IA_CSS_REFCOUNT_PARAM_BUFFER;
ia_css_refcount_decrement(id, *curr_buf);
- *curr_buf = ia_css_refcount_increment(id, mmgr_alloc_attr(needed_size,
- mmgr_attribute));
+ *curr_buf = ia_css_refcount_increment(id, hmm_alloc(needed_size,
+ HMM_BO_PRIVATE, 0,
+ NULL,
+ mmgr_attribute));
if (!*curr_buf) {
- *err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ *err = -ENOMEM;
*curr_size = 0;
} else {
*curr_size = needed_size;
@@ -2750,19 +2752,18 @@ static bool realloc_isp_css_mm_buf(
}
static bool reallocate_buffer(
- hrt_vaddress *curr_buf,
+ ia_css_ptr *curr_buf,
size_t *curr_size,
size_t needed_size,
bool force,
- enum ia_css_err *err)
+ int *err)
{
bool ret;
- u16 mmgr_attribute = MMGR_ATTRIBUTE_DEFAULT;
IA_CSS_ENTER_PRIVATE("void");
ret = realloc_isp_css_mm_buf(curr_buf,
- curr_size, needed_size, force, err, mmgr_attribute);
+ curr_size, needed_size, force, err, 0);
IA_CSS_LEAVE_PRIVATE("ret=%d", ret);
return ret;
@@ -2781,7 +2782,7 @@ ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
if (!grid->enable)
return NULL;
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
@@ -2803,9 +2804,9 @@ ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
me->hmem_size = CEIL_MUL(me->hmem_size, HIVE_ISP_DDR_WORD_BYTES);
me->size = me->dmem_size + me->vmem_size * 2 + me->hmem_size;
- me->data_ptr = mmgr_malloc(me->size);
+ me->data_ptr = hmm_alloc(me->size, HMM_BO_PRIVATE, 0, NULL, 0);
if (me->data_ptr == mmgr_NULL) {
- sh_css_free(me);
+ kvfree(me);
me = NULL;
goto err;
}
@@ -2828,7 +2829,7 @@ ia_css_isp_3a_statistics_free(struct ia_css_isp_3a_statistics *me)
{
if (me) {
hmm_free(me->data_ptr);
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -2847,13 +2848,13 @@ ia_css_metadata_allocate(const struct ia_css_metadata_info *metadata_info)
if (metadata_info->size == 0)
return NULL;
- md = sh_css_malloc(sizeof(*md));
+ md = kvmalloc(sizeof(*md), GFP_KERNEL);
if (!md)
goto error;
md->info = *metadata_info;
md->exp_id = 0;
- md->address = mmgr_malloc(metadata_info->size);
+ md->address = hmm_alloc(metadata_info->size, HMM_BO_PRIVATE, 0, NULL, 0);
if (md->address == mmgr_NULL)
goto error;
@@ -2877,7 +2878,7 @@ ia_css_metadata_free(struct ia_css_metadata *me)
* and debugging. */
IA_CSS_ENTER("me=%p", me);
hmm_free(me->address);
- sh_css_free(me);
+ kvfree(me);
IA_CSS_LEAVE("void");
}
}
@@ -2897,9 +2898,9 @@ ia_css_metadata_free_multiple(unsigned int num_bufs,
static unsigned int g_param_buffer_dequeue_count;
static unsigned int g_param_buffer_enqueue_count;
-enum ia_css_err
+int
ia_css_stream_isp_parameters_init(struct ia_css_stream *stream) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int i;
struct sh_css_ddr_address_map *ddr_ptrs;
struct sh_css_ddr_address_map_size *ddr_ptrs_size;
@@ -2910,8 +2911,8 @@ ia_css_stream_isp_parameters_init(struct ia_css_stream *stream) {
if (!stream)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
+ return -EINVAL;
}
/* TMP: tracking of paramsets */
g_param_buffer_dequeue_count = 0;
@@ -2920,7 +2921,7 @@ ia_css_stream_isp_parameters_init(struct ia_css_stream *stream) {
stream->per_frame_isp_params_configs = NULL;
err = sh_css_create_isp_params(stream,
&stream->isp_params_configs);
- if (err != IA_CSS_SUCCESS)
+ if (err)
goto ERR;
params = stream->isp_params_configs;
@@ -2928,7 +2929,7 @@ ia_css_stream_isp_parameters_init(struct ia_css_stream *stream) {
{
/* we do not return the error immediately to enable internal
* firmware feature testing */
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
}
ddr_ptrs = &params->ddr_ptrs;
@@ -2968,22 +2969,22 @@ ia_css_set_sdis2_config(
ia_css_set_sdis2_vertproj_config(params, dvs2_coefs);
}
-static enum ia_css_err
+static int
sh_css_create_isp_params(struct ia_css_stream *stream,
struct ia_css_isp_parameters **isp_params_out) {
bool succ = true;
unsigned int i;
struct sh_css_ddr_address_map *ddr_ptrs;
struct sh_css_ddr_address_map_size *ddr_ptrs_size;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
size_t params_size;
struct ia_css_isp_parameters *params =
- sh_css_malloc(sizeof(struct ia_css_isp_parameters));
+ kvmalloc(sizeof(struct ia_css_isp_parameters), GFP_KERNEL);
if (!params)
{
*isp_params_out = NULL;
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
IA_CSS_ERROR("%s:%d error: cannot allocate memory", __FILE__, __LINE__);
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -3010,13 +3011,13 @@ sh_css_create_isp_params(struct ia_css_stream *stream,
ddr_ptrs_size->isp_param = params_size;
ddr_ptrs->isp_param =
ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_BUFFER,
- mmgr_malloc(params_size));
+ hmm_alloc(params_size, HMM_BO_PRIVATE, 0, NULL, 0));
succ &= (ddr_ptrs->isp_param != mmgr_NULL);
ddr_ptrs_size->macc_tbl = sizeof(struct ia_css_macc_table);
ddr_ptrs->macc_tbl =
ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_BUFFER,
- mmgr_malloc(sizeof(struct ia_css_macc_table)));
+ hmm_alloc(sizeof(struct ia_css_macc_table), HMM_BO_PRIVATE, 0, NULL, 0));
succ &= (ddr_ptrs->macc_tbl != mmgr_NULL);
*isp_params_out = params;
@@ -3068,12 +3069,12 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
ia_css_set_ob_config(params, &default_ob_config);
ia_css_set_dp_config(params, &default_dp_config);
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
ia_css_set_param_exceptions(pipe_in, params);
} else {
for (i = 0; i < stream->num_pipes; i++) {
if (sh_css_select_dp_10bpp_config(stream->pipes[i],
- &is_dp_10bpp) == IA_CSS_SUCCESS) {
+ &is_dp_10bpp) == 0) {
/* set the return value as false if both DPC and
* BDS is enabled by the user. But we do not return
* the value immediately to enable internal firmware
@@ -3180,7 +3181,7 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
ia_css_set_formats_config(params, &stream_params->formats_config);
for (i = 0; i < stream->num_pipes; i++) {
- if (IA_CSS_SUCCESS ==
+ if (0 ==
sh_css_select_dp_10bpp_config(stream->pipes[i], &is_dp_10bpp)) {
/* set the return value as false if both DPC and
* BDS is enabled by the user. But we do not return
@@ -3195,7 +3196,7 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
retval = false;
goto exit;
}
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
if (stream->pipes[i]->mode < IA_CSS_PIPE_ID_NUM) {
sh_css_set_dp_config(stream->pipes[i], params,
&stream_params->pipe_dp_config[stream->pipes[i]->mode]);
@@ -3207,7 +3208,7 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
}
}
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
ia_css_set_param_exceptions(pipe_in, params);
params->fpn_config.data = stream_params->fpn_config.data;
@@ -3252,7 +3253,7 @@ exit:
return retval;
}
-enum ia_css_err
+int
sh_css_params_init(void) {
int i, p;
@@ -3267,18 +3268,20 @@ sh_css_params_init(void) {
for (i = 0; i < SH_CSS_MAX_STAGES; i++) {
xmem_sp_stage_ptrs[p][i] =
ia_css_refcount_increment(-1,
- mmgr_calloc(1,
- sizeof(struct sh_css_sp_stage)));
+ hmm_alloc(sizeof(struct sh_css_sp_stage),
+ HMM_BO_PRIVATE, 0, NULL,
+ ATOMISP_MAP_FLAG_CLEARED));
xmem_isp_stage_ptrs[p][i] =
ia_css_refcount_increment(-1,
- mmgr_calloc(1,
- sizeof(struct sh_css_isp_stage)));
+ hmm_alloc(sizeof(struct sh_css_sp_stage),
+ HMM_BO_PRIVATE, 0, NULL,
+ ATOMISP_MAP_FLAG_CLEARED));
if ((xmem_sp_stage_ptrs[p][i] == mmgr_NULL) ||
(xmem_isp_stage_ptrs[p][i] == mmgr_NULL)) {
sh_css_params_uninit();
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
}
}
@@ -3288,21 +3291,25 @@ sh_css_params_init(void) {
ia_css_config_rgb_gamma_tables();
ia_css_config_xnr_table();
- sp_ddr_ptrs = ia_css_refcount_increment(-1, mmgr_calloc(1,
- CEIL_MUL(sizeof(struct sh_css_ddr_address_map),
- HIVE_ISP_DDR_WORD_BYTES)));
- xmem_sp_group_ptrs = ia_css_refcount_increment(-1, mmgr_calloc(1,
- sizeof(struct sh_css_sp_group)));
+ sp_ddr_ptrs = ia_css_refcount_increment(-1,
+ hmm_alloc(CEIL_MUL(sizeof(struct sh_css_ddr_address_map),
+ HIVE_ISP_DDR_WORD_BYTES),
+ HMM_BO_PRIVATE, 0, NULL,
+ ATOMISP_MAP_FLAG_CLEARED));
+ xmem_sp_group_ptrs = ia_css_refcount_increment(-1,
+ hmm_alloc(sizeof(struct sh_css_sp_group),
+ HMM_BO_PRIVATE, 0, NULL,
+ ATOMISP_MAP_FLAG_CLEARED));
if ((sp_ddr_ptrs == mmgr_NULL) ||
(xmem_sp_group_ptrs == mmgr_NULL))
{
ia_css_uninit();
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
static void host_lut_store(const void *lut)
@@ -3314,27 +3321,27 @@ static void host_lut_store(const void *lut)
}
/* Note that allocation is in ipu address space. */
-inline hrt_vaddress sh_css_params_alloc_gdc_lut(void)
+inline ia_css_ptr sh_css_params_alloc_gdc_lut(void)
{
- return mmgr_malloc(sizeof(zoom_table));
+ return hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
}
-inline void sh_css_params_free_gdc_lut(hrt_vaddress addr)
+inline void sh_css_params_free_gdc_lut(ia_css_ptr addr)
{
if (addr != mmgr_NULL)
hmm_free(addr);
}
-enum ia_css_err ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
+int ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
const void *lut)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool stream_started = false;
IA_CSS_ENTER("pipe=%p lut=%p", pipe, lut);
if (!lut || !pipe) {
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE("err=%d", err);
return err;
}
@@ -3347,7 +3354,7 @@ enum ia_css_err ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
"unable to set scaler lut since stream has started\n");
stream_started = true;
- err = IA_CSS_ERR_NOT_SUPPORTED;
+ err = -ENOTSUPP;
}
/* Free any existing tables. */
@@ -3355,19 +3362,19 @@ enum ia_css_err ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
pipe->scaler_pp_lut = mmgr_NULL;
if (!stream_started) {
- if (!atomisp_hw_is_isp2401)
- pipe->scaler_pp_lut = mmgr_malloc(sizeof(zoom_table));
+ if (!IS_ISP2401)
+ pipe->scaler_pp_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
else
pipe->scaler_pp_lut = sh_css_params_alloc_gdc_lut();
if (pipe->scaler_pp_lut == mmgr_NULL) {
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
"unable to allocate scaler_pp_lut\n");
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
} else {
gdc_lut_convert_to_isp_format((const int(*)[HRT_GDC_N])lut,
interleaved_lut_temp);
- mmgr_store(pipe->scaler_pp_lut,
+ hmm_store(pipe->scaler_pp_lut,
(int *)interleaved_lut_temp,
sizeof(zoom_table));
}
@@ -3378,7 +3385,7 @@ enum ia_css_err ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
}
/* if pipe is NULL, returns default lut addr. */
-hrt_vaddress sh_css_pipe_get_pp_gdc_lut(const struct ia_css_pipe *pipe)
+ia_css_ptr sh_css_pipe_get_pp_gdc_lut(const struct ia_css_pipe *pipe)
{
assert(pipe);
@@ -3388,9 +3395,9 @@ hrt_vaddress sh_css_pipe_get_pp_gdc_lut(const struct ia_css_pipe *pipe)
return sh_css_params_get_default_gdc_lut();
}
-enum ia_css_err sh_css_params_map_and_store_default_gdc_lut(void)
+int sh_css_params_map_and_store_default_gdc_lut(void)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
IA_CSS_ENTER_PRIVATE("void");
@@ -3400,17 +3407,17 @@ enum ia_css_err sh_css_params_map_and_store_default_gdc_lut(void)
host_lut_store((void *)zoom_table);
- if (!atomisp_hw_is_isp2401)
- default_gdc_lut = mmgr_malloc(sizeof(zoom_table));
+ if (!IS_ISP2401)
+ default_gdc_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
else
default_gdc_lut = sh_css_params_alloc_gdc_lut();
if (default_gdc_lut == mmgr_NULL)
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ return -ENOMEM;
gdc_lut_convert_to_isp_format((const int(*)[HRT_GDC_N])zoom_table,
interleaved_lut_temp);
- mmgr_store(default_gdc_lut, (int *)interleaved_lut_temp,
+ hmm_store(default_gdc_lut, (int *)interleaved_lut_temp,
sizeof(zoom_table));
IA_CSS_LEAVE_PRIVATE("lut(%u) err=%d", default_gdc_lut, err);
@@ -3427,13 +3434,13 @@ void sh_css_params_free_default_gdc_lut(void)
IA_CSS_LEAVE_PRIVATE("void");
}
-hrt_vaddress sh_css_params_get_default_gdc_lut(void)
+ia_css_ptr sh_css_params_get_default_gdc_lut(void)
{
return default_gdc_lut;
}
static void free_param_set_callback(
- hrt_vaddress ptr)
+ ia_css_ptr ptr)
{
IA_CSS_ENTER_PRIVATE("void");
@@ -3443,7 +3450,7 @@ static void free_param_set_callback(
}
static void free_buffer_callback(
- hrt_vaddress ptr)
+ ia_css_ptr ptr)
{
IA_CSS_ENTER_PRIVATE("void");
@@ -3476,7 +3483,7 @@ static void free_map(struct sh_css_ddr_address_map *map)
{
unsigned int i;
- hrt_vaddress *addrs = (hrt_vaddress *)map;
+ ia_css_ptr *addrs = (ia_css_ptr *)map;
IA_CSS_ENTER_PRIVATE("void");
@@ -3521,7 +3528,7 @@ ia_css_stream_isp_parameters_uninit(struct ia_css_stream *stream)
free_map(&per_frame_params->ddr_ptrs);
if (params->fpn_config.data) {
- sh_css_free(params->fpn_config.data);
+ kvfree(params->fpn_config.data);
params->fpn_config.data = NULL;
}
@@ -3537,9 +3544,9 @@ ia_css_stream_isp_parameters_uninit(struct ia_css_stream *stream)
}
}
- sh_css_free(params);
+ kvfree(params);
if (per_frame_params)
- sh_css_free(per_frame_params);
+ kvfree(per_frame_params);
stream->isp_params_configs = NULL;
stream->per_frame_isp_params_configs = NULL;
@@ -3603,7 +3610,7 @@ convert_allocate_morph_plane(
me = ia_css_host_data_allocate((size_t)isp_data_size);
if (!me) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
return NULL;
}
@@ -3622,12 +3629,12 @@ convert_allocate_morph_plane(
return me;
}
-static enum ia_css_err
+static int
store_morph_plane(
unsigned short *data,
unsigned int width,
unsigned int height,
- hrt_vaddress dest,
+ ia_css_ptr dest,
unsigned int aligned_width) {
struct ia_css_host_data *isp_data;
@@ -3636,18 +3643,18 @@ store_morph_plane(
isp_data = convert_allocate_morph_plane(data, width, height, aligned_width);
if (!isp_data)
{
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
ia_css_params_store_ia_css_host_data(dest, isp_data);
ia_css_host_data_free(isp_data);
- return IA_CSS_SUCCESS;
+ return 0;
}
static void sh_css_update_isp_params_to_ddr(
struct ia_css_isp_parameters *params,
- hrt_vaddress ddr_ptr)
+ ia_css_ptr ddr_ptr)
{
size_t size = sizeof(params->uds);
@@ -3655,13 +3662,13 @@ static void sh_css_update_isp_params_to_ddr(
assert(params);
- mmgr_store(ddr_ptr, &params->uds, size);
+ hmm_store(ddr_ptr, &params->uds, size);
IA_CSS_LEAVE_PRIVATE("void");
}
static void sh_css_update_isp_mem_params_to_ddr(
const struct ia_css_binary *binary,
- hrt_vaddress ddr_mem_ptr,
+ ia_css_ptr ddr_mem_ptr,
size_t size,
enum ia_css_isp_memories mem)
{
@@ -3671,7 +3678,7 @@ static void sh_css_update_isp_mem_params_to_ddr(
params = ia_css_isp_param_get_mem_init(&binary->mem_params,
IA_CSS_PARAM_CLASS_PARAM, mem);
- mmgr_store(ddr_mem_ptr, params->address, size);
+ hmm_store(ddr_mem_ptr, params->address, size);
IA_CSS_LEAVE_PRIVATE("void");
}
@@ -3679,7 +3686,7 @@ static void sh_css_update_isp_mem_params_to_ddr(
void ia_css_dequeue_param_buffers(/*unsigned int pipe_num*/ void)
{
unsigned int i;
- hrt_vaddress cpy;
+ ia_css_ptr cpy;
enum sh_css_queue_id param_queue_ids[3] = { IA_CSS_PARAMETER_SET_QUEUE_ID,
IA_CSS_PER_FRAME_PARAMETER_SET_QUEUE_ID,
SH_CSS_INVALID_QUEUE_ID
@@ -3694,10 +3701,10 @@ void ia_css_dequeue_param_buffers(/*unsigned int pipe_num*/ void)
}
for (i = 0; SH_CSS_INVALID_QUEUE_ID != param_queue_ids[i]; i++) {
- cpy = (hrt_vaddress)0;
+ cpy = (ia_css_ptr)0;
/* clean-up old copy */
while (ia_css_bufq_dequeue_buffer(param_queue_ids[i],
- (uint32_t *)&cpy) == IA_CSS_SUCCESS) {
+ (uint32_t *)&cpy) == 0) {
/* TMP: keep track of dequeued param set count
*/
g_param_buffer_dequeue_count++;
@@ -3709,7 +3716,7 @@ void ia_css_dequeue_param_buffers(/*unsigned int pipe_num*/ void)
IA_CSS_LOG("dequeued param set %x from %d, release ref", cpy, 0);
free_ia_css_isp_parameter_set_info(cpy);
- cpy = (hrt_vaddress)0;
+ cpy = (ia_css_ptr)0;
}
}
@@ -3751,13 +3758,13 @@ process_kernel_parameters(unsigned int pipe_id,
}
}
-enum ia_css_err
+int
sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
struct ia_css_isp_parameters *params,
bool commit,
struct ia_css_pipe *pipe_in) {
- enum ia_css_err err = IA_CSS_SUCCESS;
- hrt_vaddress cpy;
+ int err = 0;
+ ia_css_ptr cpy;
int i;
unsigned int raw_bit_depth = 10;
unsigned int isp_pipe_version = SH_CSS_ISP_PIPE_VERSION_1;
@@ -3807,7 +3814,7 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
#endif
if (!sh_css_sp_is_running()) {
/* SP is not running. The queues are not valid */
- err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ err = -EBUSY;
break;
}
cur_map = &params->pipe_ddr_ptrs[pipeline->pipe_id];
@@ -3823,7 +3830,7 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
/* the processing is a.o. resolution dependent */
err = ia_css_process_zoom_and_motion(params,
pipeline->stages);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
}
/* check if to actually update the parameters for this pipe */
@@ -3854,14 +3861,14 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
cur_map,
cur_map_size);
- if (err != IA_CSS_SUCCESS)
+ if (err)
break;
for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) {
params->isp_mem_params_changed
[pipeline->pipe_id][stage->stage_num][mem] = false;
}
} /* for */
- if (err != IA_CSS_SUCCESS)
+ if (err)
break;
/* update isp_params to pipe specific copies */
if (params->isp_params_changed) {
@@ -3870,7 +3877,7 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
cur_map_size->isp_param,
true,
&err);
- if (err != IA_CSS_SUCCESS)
+ if (err)
break;
sh_css_update_isp_params_to_ddr(params, cur_map->isp_param);
}
@@ -3879,7 +3886,7 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
err = ref_sh_css_ddr_address_map(
cur_map,
&isp_params_info.mem_map);
- if (err != IA_CSS_SUCCESS)
+ if (err)
break;
/* Update Parameters ID */
@@ -3891,14 +3898,14 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
/* now write the copy to ddr */
err = write_ia_css_isp_parameter_set_info_to_ddr(&isp_params_info, &cpy);
- if (err != IA_CSS_SUCCESS)
+ if (err)
break;
/* enqueue the set to sp */
IA_CSS_LOG("queue param set %x to %d", cpy, thread_id);
err = ia_css_bufq_enqueue_buffer(thread_id, queue_id, (uint32_t)cpy);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
free_ia_css_isp_parameter_set_info(cpy);
#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
IA_CSS_LOG("pfp: FAILED to add config id %d for OF %d to q %d on thread %d",
@@ -3919,8 +3926,8 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
*/
if (!sh_css_sp_is_running()) {
/* SP is not running. The queues are not valid */
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
- return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
+ IA_CSS_LEAVE_ERR_PRIVATE(-EBUSY);
+ return -EBUSY;
}
ia_css_bufq_enqueue_psys_event(
IA_CSS_PSYS_SW_EVENT_BUFFER_ENQUEUED,
@@ -3957,7 +3964,7 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
return err;
}
-static enum ia_css_err
+static int
sh_css_params_write_to_ddr_internal(
struct ia_css_pipe *pipe,
unsigned int pipe_id,
@@ -3965,7 +3972,7 @@ sh_css_params_write_to_ddr_internal(
const struct ia_css_pipeline_stage *stage,
struct sh_css_ddr_address_map *ddr_map,
struct sh_css_ddr_address_map_size *ddr_map_size) {
- enum ia_css_err err;
+ int err;
const struct ia_css_binary *binary;
unsigned int stage_num;
@@ -3993,14 +4000,14 @@ sh_css_params_write_to_ddr_internal(
(size_t)(FPNTBL_BYTES(binary)),
params->config_changed[IA_CSS_FPN_ID],
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
if (params->config_changed[IA_CSS_FPN_ID] || buff_realloced) {
if (params->fpn_config.enabled) {
err = store_fpntbl(params, ddr_map->fpn_tbl);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4013,7 +4020,7 @@ sh_css_params_write_to_ddr_internal(
u32 enable_conv;
size_t bytes;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
bytes = ISP2400_SCTBL_BYTES(binary);
else
bytes = ISP2401_SCTBL_BYTES(binary);
@@ -4025,7 +4032,7 @@ sh_css_params_write_to_ddr_internal(
bytes,
params->sc_table_changed,
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4036,7 +4043,7 @@ sh_css_params_write_to_ddr_internal(
if (params->sc_table) {
/* store the shading table to ddr */
err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_table);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4054,13 +4061,13 @@ sh_css_params_write_to_ddr_internal(
binary->sctbl_width_per_color,
binary->sctbl_height);
if (!params->sc_config) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
/* store the shading table to ddr */
err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_config);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4085,13 +4092,13 @@ sh_css_params_write_to_ddr_internal(
&params->sc_config,
binary, pipe->required_bds_factor);
if (!params->sc_config) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
/* store the shading table to ddr */
err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_config);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4110,7 +4117,7 @@ sh_css_params_write_to_ddr_internal(
/* DPC configuration is made pipe specific to allow flexibility in positioning of the
* DPC kernel. The code below sets the pipe specific configuration to
* individual binaries. */
- if (atomisp_hw_is_isp2401 &&
+ if (IS_ISP2401 &&
params->pipe_dpc_config_changed[pipe_id] && binary->info->sp.enable.dpc)
{
unsigned int size =
@@ -4171,11 +4178,11 @@ sh_css_params_write_to_ddr_internal(
ddr_map_size->macc_tbl,
true,
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
- mmgr_store(ddr_map->macc_tbl,
+ hmm_store(ddr_map->macc_tbl,
converted_macc_table.data,
sizeof(converted_macc_table.data));
}
@@ -4192,7 +4199,7 @@ sh_css_params_write_to_ddr_internal(
(size_t)((DVS_6AXIS_BYTES(binary) / 2) * 3),
params->pipe_dvs_6axis_config_changed[pipe_id],
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4213,7 +4220,7 @@ sh_css_params_write_to_ddr_internal(
if (!params->pipe_dvs_6axis_config[pipe_id]) {
struct ia_css_resolution dvs_offset = {0};
- if (!atomisp_hw_is_isp2401) {
+ if (!IS_ISP2401) {
dvs_offset.width = (PIX_SHIFT_FILTER_RUN_IN_X + binary->dvs_envelope.width) / 2;
} else {
if (binary->dvs_envelope.width || binary->dvs_envelope.height) {
@@ -4225,8 +4232,8 @@ sh_css_params_write_to_ddr_internal(
params->pipe_dvs_6axis_config[pipe_id] =
generate_dvs_6axis_table(&binary->out_frame_info[0].res, &dvs_offset);
if (!params->pipe_dvs_6axis_config[pipe_id]) {
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY);
- return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+ return -ENOMEM;
}
params->pipe_dvs_6axis_config_changed[pipe_id] = true;
@@ -4242,13 +4249,17 @@ sh_css_params_write_to_ddr_internal(
if (binary->info->sp.enable.ca_gdc)
{
unsigned int i;
- hrt_vaddress *virt_addr_tetra_x[
+ ia_css_ptr *virt_addr_tetra_x[
+
IA_CSS_MORPH_TABLE_NUM_PLANES];
size_t *virt_size_tetra_x[
+
IA_CSS_MORPH_TABLE_NUM_PLANES];
- hrt_vaddress *virt_addr_tetra_y[
+ ia_css_ptr *virt_addr_tetra_y[
+
IA_CSS_MORPH_TABLE_NUM_PLANES];
size_t *virt_size_tetra_y[
+
IA_CSS_MORPH_TABLE_NUM_PLANES];
virt_addr_tetra_x[0] = &ddr_map->tetra_r_x;
@@ -4288,7 +4299,7 @@ sh_css_params_write_to_ddr_internal(
(MORPH_PLANE_BYTES(binary)),
params->morph_table_changed,
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4299,7 +4310,7 @@ sh_css_params_write_to_ddr_internal(
(MORPH_PLANE_BYTES(binary)),
params->morph_table_changed,
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4316,7 +4327,7 @@ sh_css_params_write_to_ddr_internal(
if (!table) {
err = sh_css_params_default_morph_table(&id_table,
binary);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4354,7 +4365,7 @@ sh_css_params_write_to_ddr_internal(
size,
params->isp_mem_params_changed[pipe_id][stage_num][mem],
&err);
- if (err != IA_CSS_SUCCESS) {
+ if (err) {
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -4365,8 +4376,8 @@ sh_css_params_write_to_ddr_internal(
}
}
- IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
- return IA_CSS_SUCCESS;
+ IA_CSS_LEAVE_ERR_PRIVATE(0);
+ return 0;
}
const struct ia_css_fpn_table *ia_css_get_fpn_table(struct ia_css_stream
@@ -4457,42 +4468,42 @@ struct ia_css_shading_table *ia_css_get_shading_table(struct ia_css_stream
return table;
}
-hrt_vaddress sh_css_store_sp_group_to_ddr(void)
+ia_css_ptr sh_css_store_sp_group_to_ddr(void)
{
IA_CSS_ENTER_LEAVE_PRIVATE("void");
- mmgr_store(xmem_sp_group_ptrs,
+ hmm_store(xmem_sp_group_ptrs,
&sh_css_sp_group,
sizeof(struct sh_css_sp_group));
return xmem_sp_group_ptrs;
}
-hrt_vaddress sh_css_store_sp_stage_to_ddr(
+ia_css_ptr sh_css_store_sp_stage_to_ddr(
unsigned int pipe,
unsigned int stage)
{
IA_CSS_ENTER_LEAVE_PRIVATE("void");
- mmgr_store(xmem_sp_stage_ptrs[pipe][stage],
+ hmm_store(xmem_sp_stage_ptrs[pipe][stage],
&sh_css_sp_stage,
sizeof(struct sh_css_sp_stage));
return xmem_sp_stage_ptrs[pipe][stage];
}
-hrt_vaddress sh_css_store_isp_stage_to_ddr(
+ia_css_ptr sh_css_store_isp_stage_to_ddr(
unsigned int pipe,
unsigned int stage)
{
IA_CSS_ENTER_LEAVE_PRIVATE("void");
- mmgr_store(xmem_isp_stage_ptrs[pipe][stage],
+ hmm_store(xmem_isp_stage_ptrs[pipe][stage],
&sh_css_isp_stage,
sizeof(struct sh_css_isp_stage));
return xmem_isp_stage_ptrs[pipe][stage];
}
-static enum ia_css_err ref_sh_css_ddr_address_map(
+static int ref_sh_css_ddr_address_map(
struct sh_css_ddr_address_map *map,
struct sh_css_ddr_address_map *out)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
unsigned int i;
/* we will use a union to copy things; overlaying an array
@@ -4501,7 +4512,7 @@ static enum ia_css_err ref_sh_css_ddr_address_map(
*/
union {
struct sh_css_ddr_address_map *map;
- hrt_vaddress *addrs;
+ ia_css_ptr *addrs;
} in_addrs, to_addrs;
IA_CSS_ENTER_PRIVATE("void");
@@ -4512,7 +4523,7 @@ static enum ia_css_err ref_sh_css_ddr_address_map(
to_addrs.map = out;
assert(sizeof(struct sh_css_ddr_address_map_size) / sizeof(size_t) ==
- sizeof(struct sh_css_ddr_address_map) / sizeof(hrt_vaddress));
+ sizeof(struct sh_css_ddr_address_map) / sizeof(ia_css_ptr));
/* copy map using size info */
for (i = 0; i < (sizeof(struct sh_css_ddr_address_map_size) /
@@ -4528,11 +4539,11 @@ static enum ia_css_err ref_sh_css_ddr_address_map(
return err;
}
-static enum ia_css_err write_ia_css_isp_parameter_set_info_to_ddr(
+static int write_ia_css_isp_parameter_set_info_to_ddr(
struct ia_css_isp_parameter_set_info *me,
- hrt_vaddress *out)
+ ia_css_ptr *out)
{
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
bool succ;
IA_CSS_ENTER_PRIVATE("void");
@@ -4540,26 +4551,26 @@ static enum ia_css_err write_ia_css_isp_parameter_set_info_to_ddr(
assert(me);
assert(out);
- *out = ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_SET_POOL, mmgr_malloc(
- sizeof(struct ia_css_isp_parameter_set_info)));
+ *out = ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_SET_POOL,
+ hmm_alloc(sizeof(struct ia_css_isp_parameter_set_info), HMM_BO_PRIVATE, 0, NULL, 0));
succ = (*out != mmgr_NULL);
if (succ)
- mmgr_store(*out,
+ hmm_store(*out,
me, sizeof(struct ia_css_isp_parameter_set_info));
else
- err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
+ err = -ENOMEM;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
-static enum ia_css_err
+static int
free_ia_css_isp_parameter_set_info(
- hrt_vaddress ptr) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ ia_css_ptr ptr) {
+ int err = 0;
struct ia_css_isp_parameter_set_info isp_params_info;
unsigned int i;
- hrt_vaddress *addrs = (hrt_vaddress *) &isp_params_info.mem_map;
+ ia_css_ptr *addrs = (ia_css_ptr *)&isp_params_info.mem_map;
IA_CSS_ENTER_PRIVATE("ptr = %u", ptr);
@@ -4568,12 +4579,12 @@ free_ia_css_isp_parameter_set_info(
{
IA_CSS_ERROR("%s: IA_CSS_REFCOUNT_PARAM_SET_POOL(0x%x) invalid arg", __func__,
ptr);
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
- mmgr_load(ptr, &isp_params_info.mem_map, sizeof(struct sh_css_ddr_address_map));
+ hmm_load(ptr, &isp_params_info.mem_map, sizeof(struct sh_css_ddr_address_map));
/* copy map using size info */
for (i = 0; i < (sizeof(struct sh_css_ddr_address_map_size) /
sizeof(size_t)); i++)
@@ -4585,7 +4596,7 @@ free_ia_css_isp_parameter_set_info(
if (!ia_css_refcount_is_valid(addrs[i])) {
IA_CSS_ERROR("%s: IA_CSS_REFCOUNT_PARAM_BUFFER(0x%x) invalid arg", __func__,
ptr);
- err = IA_CSS_ERR_INVALID_ARGUMENTS;
+ err = -EINVAL;
continue;
}
@@ -4773,7 +4784,7 @@ sh_css_update_uds_and_crop_info(
IA_CSS_LEAVE_PRIVATE("void");
}
-static enum ia_css_err
+static int
sh_css_update_uds_and_crop_info_based_on_zoom_region(
const struct ia_css_binary_info *info,
const struct ia_css_frame_info *in_frame_info,
@@ -4786,7 +4797,7 @@ sh_css_update_uds_and_crop_info_based_on_zoom_region(
struct ia_css_resolution pipe_in_res,
bool enable_zoom) {
unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
/* Note:
* Filter_Envelope = 0 for NND/LUT
* Filter_Envelope = 1 for BCI
@@ -4813,7 +4824,7 @@ sh_css_update_uds_and_crop_info_based_on_zoom_region(
y1 = zoom->zoom_region.resolution.height + y0;
if ((x0 > x1) || (y0 > y1) || (x1 > pipe_in_res.width) || (y1 > pipe_in_res.height))
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
if (!enable_zoom)
{
@@ -4825,7 +4836,7 @@ sh_css_update_uds_and_crop_info_based_on_zoom_region(
{
/* Zoom region is only supported by the UDS module on ISP
* 2 and higher. It is not supported in video mode on ISP 1 */
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
} else
{
if (enable_zoom) {
@@ -4875,19 +4886,18 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
assert(grid);
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
me->grid = *grid;
grid_size = grid->width * grid->height;
- me->data = sh_css_malloc(grid_size * sizeof(*me->data));
+ me->data = kvmalloc(grid_size * sizeof(*me->data), GFP_KERNEL);
if (!me->data)
goto err;
#if !defined(HAS_NO_HMEM)
/* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */
- me->rgby_data = (struct ia_css_3a_rgby_output *)sh_css_malloc(sizeof_hmem(
- HMEM0_ID));
+ me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL);
#else
me->rgby_data = NULL;
#endif
@@ -4905,10 +4915,10 @@ void
ia_css_3a_statistics_free(struct ia_css_3a_statistics *me)
{
if (me) {
- sh_css_free(me->rgby_data);
- sh_css_free(me->data);
+ kvfree(me->rgby_data);
+ kvfree(me->data);
memset(me, 0, sizeof(struct ia_css_3a_statistics));
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -4919,18 +4929,18 @@ ia_css_dvs_statistics_allocate(const struct ia_css_dvs_grid_info *grid)
assert(grid);
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
me->grid = *grid;
- me->hor_proj = sh_css_malloc(grid->height * IA_CSS_DVS_NUM_COEF_TYPES *
- sizeof(*me->hor_proj));
+ me->hor_proj = kvmalloc(grid->height * IA_CSS_DVS_NUM_COEF_TYPES *
+ sizeof(*me->hor_proj), GFP_KERNEL);
if (!me->hor_proj)
goto err;
- me->ver_proj = sh_css_malloc(grid->width * IA_CSS_DVS_NUM_COEF_TYPES *
- sizeof(*me->ver_proj));
+ me->ver_proj = kvmalloc(grid->width * IA_CSS_DVS_NUM_COEF_TYPES *
+ sizeof(*me->ver_proj), GFP_KERNEL);
if (!me->ver_proj)
goto err;
@@ -4944,10 +4954,10 @@ void
ia_css_dvs_statistics_free(struct ia_css_dvs_statistics *me)
{
if (me) {
- sh_css_free(me->hor_proj);
- sh_css_free(me->ver_proj);
+ kvfree(me->hor_proj);
+ kvfree(me->ver_proj);
memset(me, 0, sizeof(struct ia_css_dvs_statistics));
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -4958,21 +4968,21 @@ ia_css_dvs_coefficients_allocate(const struct ia_css_dvs_grid_info *grid)
assert(grid);
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
me->grid = *grid;
- me->hor_coefs = sh_css_malloc(grid->num_hor_coefs *
- IA_CSS_DVS_NUM_COEF_TYPES *
- sizeof(*me->hor_coefs));
+ me->hor_coefs = kvmalloc(grid->num_hor_coefs *
+ IA_CSS_DVS_NUM_COEF_TYPES *
+ sizeof(*me->hor_coefs), GFP_KERNEL);
if (!me->hor_coefs)
goto err;
- me->ver_coefs = sh_css_malloc(grid->num_ver_coefs *
- IA_CSS_DVS_NUM_COEF_TYPES *
- sizeof(*me->ver_coefs));
+ me->ver_coefs = kvmalloc(grid->num_ver_coefs *
+ IA_CSS_DVS_NUM_COEF_TYPES *
+ sizeof(*me->ver_coefs), GFP_KERNEL);
if (!me->ver_coefs)
goto err;
@@ -4986,10 +4996,10 @@ void
ia_css_dvs_coefficients_free(struct ia_css_dvs_coefficients *me)
{
if (me) {
- sh_css_free(me->hor_coefs);
- sh_css_free(me->ver_coefs);
+ kvfree(me->hor_coefs);
+ kvfree(me->ver_coefs);
memset(me, 0, sizeof(struct ia_css_dvs_coefficients));
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -5000,49 +5010,65 @@ ia_css_dvs2_statistics_allocate(const struct ia_css_dvs_grid_info *grid)
assert(grid);
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
me->grid = *grid;
- me->hor_prod.odd_real = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->hor_prod.odd_real));
+ me->hor_prod.odd_real = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->hor_prod.odd_real),
+ GFP_KERNEL);
if (!me->hor_prod.odd_real)
goto err;
- me->hor_prod.odd_imag = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->hor_prod.odd_imag));
+ me->hor_prod.odd_imag = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->hor_prod.odd_imag),
+ GFP_KERNEL);
if (!me->hor_prod.odd_imag)
goto err;
- me->hor_prod.even_real = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->hor_prod.even_real));
+ me->hor_prod.even_real = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->hor_prod.even_real),
+ GFP_KERNEL);
if (!me->hor_prod.even_real)
goto err;
- me->hor_prod.even_imag = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->hor_prod.even_imag));
+ me->hor_prod.even_imag = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->hor_prod.even_imag),
+ GFP_KERNEL);
if (!me->hor_prod.even_imag)
goto err;
- me->ver_prod.odd_real = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->ver_prod.odd_real));
+ me->ver_prod.odd_real = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->ver_prod.odd_real),
+ GFP_KERNEL);
if (!me->ver_prod.odd_real)
goto err;
- me->ver_prod.odd_imag = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->ver_prod.odd_imag));
+ me->ver_prod.odd_imag = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->ver_prod.odd_imag),
+ GFP_KERNEL);
if (!me->ver_prod.odd_imag)
goto err;
- me->ver_prod.even_real = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->ver_prod.even_real));
+ me->ver_prod.even_real = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->ver_prod.even_real),
+ GFP_KERNEL);
if (!me->ver_prod.even_real)
goto err;
- me->ver_prod.even_imag = sh_css_malloc(grid->aligned_width *
- grid->aligned_height * sizeof(*me->ver_prod.even_imag));
+ me->ver_prod.even_imag = kvmalloc(grid->aligned_width *
+ grid->aligned_height *
+ sizeof(*me->ver_prod.even_imag),
+ GFP_KERNEL);
if (!me->ver_prod.even_imag)
goto err;
@@ -5056,16 +5082,16 @@ void
ia_css_dvs2_statistics_free(struct ia_css_dvs2_statistics *me)
{
if (me) {
- sh_css_free(me->hor_prod.odd_real);
- sh_css_free(me->hor_prod.odd_imag);
- sh_css_free(me->hor_prod.even_real);
- sh_css_free(me->hor_prod.even_imag);
- sh_css_free(me->ver_prod.odd_real);
- sh_css_free(me->ver_prod.odd_imag);
- sh_css_free(me->ver_prod.even_real);
- sh_css_free(me->ver_prod.even_imag);
+ kvfree(me->hor_prod.odd_real);
+ kvfree(me->hor_prod.odd_imag);
+ kvfree(me->hor_prod.even_real);
+ kvfree(me->hor_prod.even_imag);
+ kvfree(me->ver_prod.odd_real);
+ kvfree(me->ver_prod.odd_imag);
+ kvfree(me->ver_prod.even_real);
+ kvfree(me->ver_prod.even_imag);
memset(me, 0, sizeof(struct ia_css_dvs2_statistics));
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -5076,49 +5102,57 @@ ia_css_dvs2_coefficients_allocate(const struct ia_css_dvs_grid_info *grid)
assert(grid);
- me = sh_css_calloc(1, sizeof(*me));
+ me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
if (!me)
goto err;
me->grid = *grid;
- me->hor_coefs.odd_real = sh_css_malloc(grid->num_hor_coefs *
- sizeof(*me->hor_coefs.odd_real));
+ me->hor_coefs.odd_real = kvmalloc(grid->num_hor_coefs *
+ sizeof(*me->hor_coefs.odd_real),
+ GFP_KERNEL);
if (!me->hor_coefs.odd_real)
goto err;
- me->hor_coefs.odd_imag = sh_css_malloc(grid->num_hor_coefs *
- sizeof(*me->hor_coefs.odd_imag));
+ me->hor_coefs.odd_imag = kvmalloc(grid->num_hor_coefs *
+ sizeof(*me->hor_coefs.odd_imag),
+ GFP_KERNEL);
if (!me->hor_coefs.odd_imag)
goto err;
- me->hor_coefs.even_real = sh_css_malloc(grid->num_hor_coefs *
- sizeof(*me->hor_coefs.even_real));
+ me->hor_coefs.even_real = kvmalloc(grid->num_hor_coefs *
+ sizeof(*me->hor_coefs.even_real),
+ GFP_KERNEL);
if (!me->hor_coefs.even_real)
goto err;
- me->hor_coefs.even_imag = sh_css_malloc(grid->num_hor_coefs *
- sizeof(*me->hor_coefs.even_imag));
+ me->hor_coefs.even_imag = kvmalloc(grid->num_hor_coefs *
+ sizeof(*me->hor_coefs.even_imag),
+ GFP_KERNEL);
if (!me->hor_coefs.even_imag)
goto err;
- me->ver_coefs.odd_real = sh_css_malloc(grid->num_ver_coefs *
- sizeof(*me->ver_coefs.odd_real));
+ me->ver_coefs.odd_real = kvmalloc(grid->num_ver_coefs *
+ sizeof(*me->ver_coefs.odd_real),
+ GFP_KERNEL);
if (!me->ver_coefs.odd_real)
goto err;
- me->ver_coefs.odd_imag = sh_css_malloc(grid->num_ver_coefs *
- sizeof(*me->ver_coefs.odd_imag));
+ me->ver_coefs.odd_imag = kvmalloc(grid->num_ver_coefs *
+ sizeof(*me->ver_coefs.odd_imag),
+ GFP_KERNEL);
if (!me->ver_coefs.odd_imag)
goto err;
- me->ver_coefs.even_real = sh_css_malloc(grid->num_ver_coefs *
- sizeof(*me->ver_coefs.even_real));
+ me->ver_coefs.even_real = kvmalloc(grid->num_ver_coefs *
+ sizeof(*me->ver_coefs.even_real),
+ GFP_KERNEL);
if (!me->ver_coefs.even_real)
goto err;
- me->ver_coefs.even_imag = sh_css_malloc(grid->num_ver_coefs *
- sizeof(*me->ver_coefs.even_imag));
+ me->ver_coefs.even_imag = kvmalloc(grid->num_ver_coefs *
+ sizeof(*me->ver_coefs.even_imag),
+ GFP_KERNEL);
if (!me->ver_coefs.even_imag)
goto err;
@@ -5132,16 +5166,16 @@ void
ia_css_dvs2_coefficients_free(struct ia_css_dvs2_coefficients *me)
{
if (me) {
- sh_css_free(me->hor_coefs.odd_real);
- sh_css_free(me->hor_coefs.odd_imag);
- sh_css_free(me->hor_coefs.even_real);
- sh_css_free(me->hor_coefs.even_imag);
- sh_css_free(me->ver_coefs.odd_real);
- sh_css_free(me->ver_coefs.odd_imag);
- sh_css_free(me->ver_coefs.even_real);
- sh_css_free(me->ver_coefs.even_imag);
+ kvfree(me->hor_coefs.odd_real);
+ kvfree(me->hor_coefs.odd_imag);
+ kvfree(me->hor_coefs.even_real);
+ kvfree(me->hor_coefs.even_imag);
+ kvfree(me->ver_coefs.odd_real);
+ kvfree(me->ver_coefs.odd_imag);
+ kvfree(me->ver_coefs.even_real);
+ kvfree(me->ver_coefs.even_imag);
memset(me, 0, sizeof(struct ia_css_dvs2_coefficients));
- sh_css_free(me);
+ kvfree(me);
}
}
@@ -5164,8 +5198,8 @@ ia_css_dvs2_6axis_config_allocate(const struct ia_css_stream *stream)
goto err;
}
- dvs_config = (struct ia_css_dvs_6axis_config *)sh_css_calloc(1,
- sizeof(struct ia_css_dvs_6axis_config));
+ dvs_config = kvcalloc(1, sizeof(struct ia_css_dvs_6axis_config),
+ GFP_KERNEL);
if (!dvs_config)
goto err;
@@ -5179,23 +5213,25 @@ ia_css_dvs2_6axis_config_allocate(const struct ia_css_stream *stream)
params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]->height_uv;
IA_CSS_LOG("table Y: W %d H %d", width_y, height_y);
IA_CSS_LOG("table UV: W %d H %d", width_uv, height_uv);
- dvs_config->xcoords_y = (uint32_t *)sh_css_malloc(width_y * height_y * sizeof(
- uint32_t));
+ dvs_config->xcoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->xcoords_y)
goto err;
- dvs_config->ycoords_y = (uint32_t *)sh_css_malloc(width_y * height_y * sizeof(
- uint32_t));
+ dvs_config->ycoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->ycoords_y)
goto err;
- dvs_config->xcoords_uv = (uint32_t *)sh_css_malloc(width_uv * height_uv *
- sizeof(uint32_t));
+ dvs_config->xcoords_uv = kvmalloc(width_uv * height_uv *
+ sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->xcoords_uv)
goto err;
- dvs_config->ycoords_uv = (uint32_t *)sh_css_malloc(width_uv * height_uv *
- sizeof(uint32_t));
+ dvs_config->ycoords_uv = kvmalloc(width_uv * height_uv *
+ sizeof(uint32_t),
+ GFP_KERNEL);
if (!dvs_config->ycoords_uv)
goto err;
@@ -5209,12 +5245,12 @@ void
ia_css_dvs2_6axis_config_free(struct ia_css_dvs_6axis_config *dvs_6axis_config)
{
if (dvs_6axis_config) {
- sh_css_free(dvs_6axis_config->xcoords_y);
- sh_css_free(dvs_6axis_config->ycoords_y);
- sh_css_free(dvs_6axis_config->xcoords_uv);
- sh_css_free(dvs_6axis_config->ycoords_uv);
+ kvfree(dvs_6axis_config->xcoords_y);
+ kvfree(dvs_6axis_config->ycoords_y);
+ kvfree(dvs_6axis_config->xcoords_uv);
+ kvfree(dvs_6axis_config->ycoords_uv);
memset(dvs_6axis_config, 0, sizeof(struct ia_css_dvs_6axis_config));
- sh_css_free(dvs_6axis_config);
+ kvfree(dvs_6axis_config);
}
}
@@ -5225,7 +5261,7 @@ ia_css_en_dz_capt_pipe(struct ia_css_stream *stream, bool enable)
struct ia_css_pipeline *pipeline;
struct ia_css_pipeline_stage *stage;
enum ia_css_pipe_id pipe_id;
- enum ia_css_err err;
+ int err;
int i;
if (!stream)
@@ -5239,7 +5275,7 @@ ia_css_en_dz_capt_pipe(struct ia_css_stream *stream, bool enable)
if (pipe_id == IA_CSS_PIPE_ID_CAPTURE) {
err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_CAPTURE_PP,
&stage);
- if (err == IA_CSS_SUCCESS)
+ if (!err)
stage->enable_zoom = enable;
break;
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.h b/drivers/staging/media/atomisp/pci/sh_css_params.h
index 96d503967fd1..62a7b6ada237 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -150,13 +151,13 @@ struct ia_css_isp_parameters {
void
ia_css_params_store_ia_css_host_data(
- hrt_vaddress ddr_addr,
+ ia_css_ptr ddr_addr,
struct ia_css_host_data *data);
-enum ia_css_err
+int
ia_css_params_store_sctbl(
const struct ia_css_pipeline_stage *stage,
- hrt_vaddress ddr_addr,
+ ia_css_ptr ddr_addr,
const struct ia_css_shading_table *shading_table);
struct ia_css_host_data *
@@ -168,21 +169,21 @@ struct ia_css_isp_config *
sh_css_pipe_isp_config_get(struct ia_css_pipe *pipe);
/* ipu address allocation/free for gdc lut */
-hrt_vaddress
+ia_css_ptr
sh_css_params_alloc_gdc_lut(void);
void
-sh_css_params_free_gdc_lut(hrt_vaddress addr);
+sh_css_params_free_gdc_lut(ia_css_ptr addr);
-enum ia_css_err
+int
sh_css_params_map_and_store_default_gdc_lut(void);
void
sh_css_params_free_default_gdc_lut(void);
-hrt_vaddress
+ia_css_ptr
sh_css_params_get_default_gdc_lut(void);
-hrt_vaddress
+ia_css_ptr
sh_css_pipe_get_pp_gdc_lut(const struct ia_css_pipe *pipe);
#endif /* _SH_CSS_PARAMS_H_ */
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params_internal.h b/drivers/staging/media/atomisp/pci/sh_css_params_internal.h
index baca24532f9f..8e5e6f273a95 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params_internal.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_params_internal.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_pipe.c b/drivers/staging/media/atomisp/pci/sh_css_pipe.c
deleted file mode 100644
index 1f57ffad8921..000000000000
--- a/drivers/staging/media/atomisp/pci/sh_css_pipe.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* This file will contain the code to implement the functions declared in ia_css_pipe.h and ia_css_pipe_public.h
- and associated helper functions */
diff --git a/drivers/staging/media/atomisp/pci/sh_css_properties.c b/drivers/staging/media/atomisp/pci/sh_css_properties.c
index 50f99c53c3d4..de588f9bd540 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_properties.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_properties.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_shading.c b/drivers/staging/media/atomisp/pci/sh_css_shading.c
index 2a2d0f4db44b..462caf9cb571 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_shading.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_shading.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.c b/drivers/staging/media/atomisp/pci/sh_css_sp.c
index e574396ad0f4..a26680b1d0b0 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_sp.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_sp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -12,6 +13,8 @@
* more details.
*/
+#include "hmm.h"
+
#include "sh_css_sp.h"
#if !defined(HAS_NO_INPUT_FORMATTER)
@@ -43,10 +46,8 @@
/*#include "sp.h"*/ /* host2sp_enqueue_frame_data() */
-#include "memory_access.h"
#include "assert_support.h"
-#include "platform_support.h" /* hrt_sleep() */
#include "sw_event_global.h" /* Event IDs.*/
#include "ia_css_event.h"
@@ -75,14 +76,14 @@ static struct sh_css_sp_per_frame_data per_frame_data;
/* TODO: add code that sets this bool to false */
static bool sp_running;
-static enum ia_css_err
+static int
set_output_frame_buffer(const struct ia_css_frame *frame,
unsigned int idx);
static void
sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf,
const enum sh_css_queue_id queue_id,
- const hrt_vaddress xmem_addr,
+ const ia_css_ptr xmem_addr,
const enum ia_css_buffer_type buf_type);
static void
@@ -412,7 +413,7 @@ sh_css_sp_get_sw_interrupt_value(unsigned int irq)
static void
sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf,
const enum sh_css_queue_id queue_id,
- const hrt_vaddress xmem_addr,
+ const ia_css_ptr xmem_addr,
const enum ia_css_buffer_type buf_type)
{
assert(buf_type < IA_CSS_NUM_BUFFER_TYPE);
@@ -535,10 +536,10 @@ sh_css_copy_frame_to_spframe(struct ia_css_frame_sp *sp_frame_out,
}
}
-static enum ia_css_err
+static int
set_input_frame_buffer(const struct ia_css_frame *frame) {
if (!frame)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
switch (frame->info.format)
{
@@ -558,18 +559,18 @@ set_input_frame_buffer(const struct ia_css_frame *frame) {
case IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_10:
break;
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.in, frame);
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
set_output_frame_buffer(const struct ia_css_frame *frame,
unsigned int idx) {
if (!frame)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
switch (frame->info.format)
{
@@ -601,16 +602,16 @@ set_output_frame_buffer(const struct ia_css_frame *frame,
case IA_CSS_FRAME_FORMAT_BINARY_8:
break;
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.out[idx], frame);
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
set_view_finder_buffer(const struct ia_css_frame *frame) {
if (!frame)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
switch (frame->info.format)
{
@@ -630,11 +631,11 @@ set_view_finder_buffer(const struct ia_css_frame *frame) {
case IA_CSS_FRAME_FORMAT_YUV_LINE:
break;
default:
- return IA_CSS_ERR_INVALID_ARGUMENTS;
+ return -EINVAL;
}
sh_css_copy_frame_to_spframe(&sh_css_sp_stage.frames.out_vf, frame);
- return IA_CSS_SUCCESS;
+ return 0;
}
#if !defined(HAS_NO_INPUT_FORMATTER)
@@ -736,26 +737,26 @@ sh_css_sp_set_disable_continuous_viewfinder(bool flag)
sh_css_sp_group.config.disable_cont_vf = flag;
}
-static enum ia_css_err
+static int
sh_css_sp_write_frame_pointers(const struct sh_css_binary_args *args) {
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
int i;
assert(args);
if (args->in_frame)
err = set_input_frame_buffer(args->in_frame);
- if (err == IA_CSS_SUCCESS && args->out_vf_frame)
+ if (!err && args->out_vf_frame)
err = set_view_finder_buffer(args->out_vf_frame);
for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
{
- if (err == IA_CSS_SUCCESS && args->out_frame[i])
+ if (!err && args->out_frame[i])
err = set_output_frame_buffer(args->out_frame[i], i);
}
/* we don't pass this error back to the upper layer, so we add a assert here
because we actually hit the error here but it still works by accident... */
- if (err != IA_CSS_SUCCESS) assert(false);
+ if (err) assert(false);
return err;
}
@@ -790,23 +791,23 @@ sh_css_stage_write_binary_info(struct ia_css_binary_info *info)
sh_css_isp_stage.binary_info = *info;
}
-static enum ia_css_err
+static int
copy_isp_mem_if_to_ddr(struct ia_css_binary *binary) {
- enum ia_css_err err;
+ int err;
err = ia_css_isp_param_copy_isp_mem_if_to_ddr(
&binary->css_params,
&binary->mem_params,
IA_CSS_PARAM_CLASS_CONFIG);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
err = ia_css_isp_param_copy_isp_mem_if_to_ddr(
&binary->css_params,
&binary->mem_params,
IA_CSS_PARAM_CLASS_STATE);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
- return IA_CSS_SUCCESS;
+ return 0;
}
static bool
@@ -816,7 +817,7 @@ is_sp_stage(struct ia_css_pipeline_stage *stage)
return stage->sp_func != IA_CSS_PIPELINE_NO_FUNC;
}
-static enum ia_css_err
+static int
configure_isp_from_args(
const struct sh_css_sp_pipeline *pipeline,
const struct ia_css_binary *binary,
@@ -838,10 +839,21 @@ configure_isp_from_args(
ia_css_dvs_configure(binary, &args->out_frame[0]->info);
ia_css_output_configure(binary, &args->out_frame[0]->info);
ia_css_raw_configure(pipeline, binary, &args->in_frame->info, &binary->in_frame_info, two_ppc, deinterleaved);
- ia_css_ref_configure(binary, (const struct ia_css_frame **)args->delay_frames, pipeline->dvs_frame_delay);
- ia_css_tnr_configure(binary, (const struct ia_css_frame **)args->tnr_frames);
+
+ /*
+ * FIXME: args->delay_frames can be NULL here
+ *
+ * Somehow, the driver at the Intel Atom Yocto tree doesn't seem to
+ * suffer from the same issue.
+ *
+ * Anyway, the function below should now handle a NULL delay_frames
+ * without crashing, but the pipeline should likely be built without
+ * adding it at the first place (or there are a hidden bug somewhere)
+ */
+ ia_css_ref_configure(binary, args->delay_frames, pipeline->dvs_frame_delay);
+ ia_css_tnr_configure(binary, args->tnr_frames);
ia_css_bayer_io_config(binary, args);
- return IA_CSS_SUCCESS;
+ return 0;
}
static void
@@ -880,7 +892,7 @@ initialize_stage_frames(struct ia_css_frames_sp *frames)
#endif
}
-static enum ia_css_err
+static int
sh_css_sp_init_stage(struct ia_css_binary *binary,
const char *binary_name,
const struct ia_css_blob_info *blob_info,
@@ -893,7 +905,7 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
bool two_ppc) {
const struct ia_css_binary_xinfo *xinfo;
const struct ia_css_binary_info *info;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
int i;
struct ia_css_pipe *pipe = NULL;
unsigned int thread_id;
@@ -925,7 +937,7 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
if (!info)
{
sh_css_sp_group.pipe[thread_id].sp_stage_addr[stage] = mmgr_NULL;
- return IA_CSS_SUCCESS;
+ return 0;
}
#if defined(USE_INPUT_SYSTEM_VERSION_2401)
@@ -978,8 +990,7 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
/* Make sure binary name is smaller than allowed string size */
assert(strlen(binary_name) < SH_CSS_MAX_BINARY_NAME - 1);
- strncpy(sh_css_isp_stage.binary_name, binary_name, SH_CSS_MAX_BINARY_NAME - 1);
- sh_css_isp_stage.binary_name[SH_CSS_MAX_BINARY_NAME - 1] = 0;
+ strscpy(sh_css_isp_stage.binary_name, binary_name, SH_CSS_MAX_BINARY_NAME);
sh_css_isp_stage.mem_initializers = *isp_mem_if;
/*
@@ -1011,38 +1022,19 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id, &queue_id);
sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf, queue_id, mmgr_EXCEPTION, IA_CSS_BUFFER_TYPE_METADATA);
#endif
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
#ifdef USE_INPUT_SYSTEM_VERSION_2401
-#ifndef ISP2401
- if (args->in_frame)
- {
- pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
- if (!pipe)
- return IA_CSS_ERR_INTERNAL_ERROR;
- ia_css_get_crop_offsets(pipe, &args->in_frame->info);
- } else if (&binary->in_frame_info)
- {
+ if (stage == 0) {
pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
if (!pipe)
- return IA_CSS_ERR_INTERNAL_ERROR;
- ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
-#else
- if (stage == 0)
- {
- if (args->in_frame) {
- pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
- if (!pipe)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
+
+ if (args->in_frame)
ia_css_get_crop_offsets(pipe, &args->in_frame->info);
- } else if (&binary->in_frame_info) {
- pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
- if (!pipe)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ else
ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
- }
-#endif
}
#else
(void)pipe; /*avoid build warning*/
@@ -1050,7 +1042,7 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
err = configure_isp_from_args(&sh_css_sp_group.pipe[thread_id],
binary, args, two_ppc, sh_css_sp_stage.deinterleaved);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
initialize_isp_states(binary);
@@ -1072,13 +1064,13 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
<<= binary->vf_downscale_log2;
}
err = copy_isp_mem_if_to_ddr(binary);
- if (err != IA_CSS_SUCCESS)
+ if (err)
return err;
- return IA_CSS_SUCCESS;
+ return 0;
}
-static enum ia_css_err
+static int
sp_init_stage(struct ia_css_pipeline_stage *stage,
unsigned int pipe_num,
bool xnr,
@@ -1110,7 +1102,7 @@ sp_init_stage(struct ia_css_pipeline_stage *stage,
*/
struct ia_css_isp_param_css_segments *mem_if = &isp_mem_if;
- enum ia_css_err err = IA_CSS_SUCCESS;
+ int err = 0;
assert(stage);
@@ -1155,7 +1147,7 @@ sp_init_stage(struct ia_css_pipeline_stage *stage,
These will be passed to sh_css_sp_init_stage
and dereferenced there, so passing a NULL
pointer is no good. return an error */
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
}
err = sh_css_sp_init_stage(binary,
@@ -1190,12 +1182,14 @@ sp_init_sp_stage(struct ia_css_pipeline_stage *stage,
break;
case IA_CSS_PIPELINE_BIN_COPY:
assert(false); /* TBI */
+ break;
case IA_CSS_PIPELINE_ISYS_COPY:
sh_css_sp_start_isys_copy(args->out_frame[0],
pipe_num, stage->max_input_width, if_config_index);
break;
case IA_CSS_PIPELINE_NO_FUNC:
assert(false);
+ break;
}
}
@@ -1347,7 +1341,7 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
}
#endif
- if (atomisp_hw_is_isp2401) {
+ if (IS_ISP2401) {
/* For the shading correction type 1 (the legacy shading table conversion in css is not used),
* the parameters are passed to the isp for the shading table centering.
*/
@@ -1608,7 +1602,7 @@ sh_css_event_init_irq_mask(void)
}
}
-enum ia_css_err
+int
ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
unsigned int or_mask,
unsigned int and_mask) {
@@ -1636,7 +1630,7 @@ ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
pipe_num = ia_css_pipe_get_pipe_num(pipe);
if (pipe_num >= IA_CSS_PIPE_ID_NUM)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
offset = (unsigned int)offsetof(struct host_sp_communication,
host2sp_event_irq_mask[pipe_num]);
assert(offset % HRT_BUS_BYTES == 0);
@@ -1644,10 +1638,10 @@ ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe,
(unsigned int)sp_address_of(host_sp_com) + offset,
&event_irq_mask, sizeof(event_irq_mask));
- return IA_CSS_SUCCESS;
+ return 0;
}
-enum ia_css_err
+int
ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
unsigned int *or_mask,
unsigned int *and_mask) {
@@ -1665,7 +1659,7 @@ ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
pipe_num = ia_css_pipe_get_pipe_num(pipe);
if (pipe_num >= IA_CSS_PIPE_ID_NUM)
- return IA_CSS_ERR_INTERNAL_ERROR;
+ return -EINVAL;
offset = (unsigned int)offsetof(struct host_sp_communication,
host2sp_event_irq_mask[pipe_num]);
assert(offset % HRT_BUS_BYTES == 0);
@@ -1679,7 +1673,7 @@ ia_css_event_get_irq_mask(const struct ia_css_pipe *pipe,
if (and_mask)
*and_mask = event_irq_mask.and_mask;
- return IA_CSS_SUCCESS;
+ return 0;
}
void
diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.h b/drivers/staging/media/atomisp/pci/sh_css_sp.h
index 7d4e13f1e038..153b005becda 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_sp.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_sp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_stream.c b/drivers/staging/media/atomisp/pci/sh_css_stream.c
index 60bddbb3d4c6..a768ce90f51c 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_stream.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_stream.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_stream_format.c b/drivers/staging/media/atomisp/pci/sh_css_stream_format.c
index 548d4a3567b2..a798f0537050 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_stream_format.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_stream_format.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_stream_format.h b/drivers/staging/media/atomisp/pci/sh_css_stream_format.h
index 32ebd6e0f344..84b7942147ad 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_stream_format.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_stream_format.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_struct.h b/drivers/staging/media/atomisp/pci/sh_css_struct.h
index 81b9598ef8b7..bd260252317a 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_struct.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_struct.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -24,7 +25,7 @@
*/
#include <type_support.h>
-#include <system_types.h>
+#include <system_local.h>
#include "ia_css_pipeline.h"
#include "ia_css_pipe_public.h"
#include "ia_css_frame_public.h"
@@ -64,8 +65,9 @@ struct sh_css {
mipi_sizes_for_check[N_CSI_PORTS][IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT];
unsigned int mipi_frame_size[N_CSI_PORTS];
#endif
- hrt_vaddress sp_bin_addr;
+ ia_css_ptr sp_bin_addr;
hrt_data page_table_base_index;
+
unsigned int
size_mem_words; /* \deprecated{Use ia_css_mipi_buffer_config instead.}*/
enum ia_css_irq_type irq_type;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_uds.h b/drivers/staging/media/atomisp/pci/sh_css_uds.h
index d9bcae6007bf..8d9c5c92b692 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_uds.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_uds.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/sh_css_version.c b/drivers/staging/media/atomisp/pci/sh_css_version.c
index eb986e15c7fa..fa6de61e4995 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_version.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_version.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
@@ -13,25 +14,26 @@
*/
#include "../../include/linux/atomisp.h"
+#include "../../include/linux/atomisp_platform.h"
#include "ia_css_version.h"
#include "ia_css_version_data.h"
#include "ia_css_err.h"
#include "sh_css_firmware.h"
-enum ia_css_err
+int
ia_css_get_version(char *version, int max_size) {
char *css_version;
- if (!atomisp_hw_is_isp2401)
+ if (!IS_ISP2401)
css_version = ISP2400_CSS_VERSION_STRING;
else
css_version = ISP2401_CSS_VERSION_STRING;
if (max_size <= (int)strlen(css_version) + (int)strlen(sh_css_get_fw_version()) + 5)
- return IA_CSS_ERR_INVALID_ARGUMENTS;
- strcpy(version, css_version);
+ return -EINVAL;
+ strscpy(version, css_version, max_size);
strcat(version, "FW:");
strcat(version, sh_css_get_fw_version());
strcat(version, "; ");
- return IA_CSS_SUCCESS;
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/str2mem_defs.h b/drivers/staging/media/atomisp/pci/str2mem_defs.h
index 1cb62444cf68..e8cb456ac9c7 100644
--- a/drivers/staging/media/atomisp/pci/str2mem_defs.h
+++ b/drivers/staging/media/atomisp/pci/str2mem_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/streaming_to_mipi_defs.h b/drivers/staging/media/atomisp/pci/streaming_to_mipi_defs.h
index 60143b8743a2..e0e3a6a66245 100644
--- a/drivers/staging/media/atomisp/pci/streaming_to_mipi_defs.h
+++ b/drivers/staging/media/atomisp/pci/streaming_to_mipi_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/system_global.h b/drivers/staging/media/atomisp/pci/system_global.h
index 7f833c15f3ce..16d0a2e9a4dc 100644
--- a/drivers/staging/media/atomisp/pci/system_global.h
+++ b/drivers/staging/media/atomisp/pci/system_global.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
diff --git a/drivers/staging/media/atomisp/pci/system_local.h b/drivers/staging/media/atomisp/pci/system_local.h
index fbb5daadac9f..dfcc4c2b8f16 100644
--- a/drivers/staging/media/atomisp/pci/system_local.h
+++ b/drivers/staging/media/atomisp/pci/system_local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
diff --git a/drivers/staging/media/atomisp/pci/timed_controller_defs.h b/drivers/staging/media/atomisp/pci/timed_controller_defs.h
index 75451e090f4f..9ddad87702de 100644
--- a/drivers/staging/media/atomisp/pci/timed_controller_defs.h
+++ b/drivers/staging/media/atomisp/pci/timed_controller_defs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/version.h b/drivers/staging/media/atomisp/pci/version.h
index bbc4948baea9..a74a7bbfdb0e 100644
--- a/drivers/staging/media/atomisp/pci/version.h
+++ b/drivers/staging/media/atomisp/pci/version.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c
index cd4980d06be7..7b66e2743a4f 100644
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c
+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c
@@ -18,11 +18,16 @@
/* Size with u32 units. */
#define RKV_CABAC_INIT_BUFFER_SIZE (3680 + 128)
#define RKV_RPS_SIZE ((128 + 128) / 4)
-#define RKV_SCALING_LIST_SIZE (6 * 16 + 6 * 64 + 128)
#define RKV_ERROR_INFO_SIZE (256 * 144 * 4)
#define RKVDEC_NUM_REFLIST 3
+struct rkvdec_h264_scaling_list {
+ u8 scaling_list_4x4[6][16];
+ u8 scaling_list_8x8[6][64];
+ u8 padding[128];
+};
+
struct rkvdec_sps_pps_packet {
u32 info[8];
};
@@ -86,7 +91,7 @@ struct rkvdec_ps_field {
/* Data structure describing auxiliary buffer format. */
struct rkvdec_h264_priv_tbl {
s8 cabac_table[4][464][2];
- u8 scaling_list[RKV_SCALING_LIST_SIZE];
+ struct rkvdec_h264_scaling_list scaling_list;
u32 rps[RKV_RPS_SIZE];
struct rkvdec_sps_pps_packet param_set[256];
u8 err_info[RKV_ERROR_INFO_SIZE];
@@ -785,56 +790,25 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
}
}
-/*
- * NOTE: The values in a scaling list are in zig-zag order, apply inverse
- * scanning process to get the values in matrix order.
- */
-static const u32 zig_zag_4x4[16] = {
- 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
-};
-
-static const u32 zig_zag_8x8[64] = {
- 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
- 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
- 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
- 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
-};
-
-static void reorder_scaling_list(struct rkvdec_ctx *ctx,
- struct rkvdec_h264_run *run)
+static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
+ struct rkvdec_h264_run *run)
{
const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix;
- const size_t num_list_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4);
- const size_t list_len_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4[0]);
- const size_t num_list_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8);
- const size_t list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[0]);
struct rkvdec_h264_ctx *h264_ctx = ctx->priv;
struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu;
- u8 *dst = tbl->scaling_list;
- const u8 *src;
- int i, j;
-
- BUILD_BUG_ON(ARRAY_SIZE(zig_zag_4x4) != list_len_4x4);
- BUILD_BUG_ON(ARRAY_SIZE(zig_zag_8x8) != list_len_8x8);
- BUILD_BUG_ON(ARRAY_SIZE(tbl->scaling_list) <
- num_list_4x4 * list_len_4x4 +
- num_list_8x8 * list_len_8x8);
-
- src = &scaling->scaling_list_4x4[0][0];
- for (i = 0; i < num_list_4x4; ++i) {
- for (j = 0; j < list_len_4x4; ++j)
- dst[zig_zag_4x4[j]] = src[j];
- src += list_len_4x4;
- dst += list_len_4x4;
- }
- src = &scaling->scaling_list_8x8[0][0];
- for (i = 0; i < num_list_8x8; ++i) {
- for (j = 0; j < list_len_8x8; ++j)
- dst[zig_zag_8x8[j]] = src[j];
- src += list_len_8x8;
- dst += list_len_8x8;
- }
+ BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_4x4) !=
+ sizeof(scaling->scaling_list_4x4));
+ BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_8x8) !=
+ sizeof(scaling->scaling_list_8x8));
+
+ memcpy(tbl->scaling_list.scaling_list_4x4,
+ scaling->scaling_list_4x4,
+ sizeof(scaling->scaling_list_4x4));
+
+ memcpy(tbl->scaling_list.scaling_list_8x8,
+ scaling->scaling_list_8x8,
+ sizeof(scaling->scaling_list_8x8));
}
/*
@@ -1126,7 +1100,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
h264_ctx->reflists.b1);
- reorder_scaling_list(ctx, &run);
+ assemble_hw_scaling_list(ctx, &run);
assemble_hw_pps(ctx, &run);
assemble_hw_rps(ctx, &run);
config_registers(ctx, &run);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 05a85517ff60..bc27f9430eeb 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pm.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
@@ -551,12 +552,18 @@ static const struct of_device_id cedrus_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, cedrus_dt_match);
+static const struct dev_pm_ops cedrus_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(cedrus_hw_suspend,
+ cedrus_hw_resume, NULL)
+};
+
static struct platform_driver cedrus_driver = {
.probe = cedrus_probe,
.remove = cedrus_remove,
.driver = {
.name = CEDRUS_NAME,
.of_match_table = of_match_ptr(cedrus_dt_match),
+ .pm = &cedrus_dev_pm_ops,
},
};
module_platform_driver(cedrus_driver);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index 4a2fc33a1d79..58c48e4fdfe9 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -74,6 +74,8 @@ void cedrus_device_run(void *priv)
v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
+ cedrus_dst_format_set(dev, &ctx->dst_fmt);
+
dev->dec_ops[ctx->current_codec]->setup(ctx, &run);
/* Complete request(s) controls if needed. */
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
index daf5f244f93b..1744e6fcc999 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
@@ -19,6 +19,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/soc/sunxi/sunxi_sram.h>
@@ -140,6 +141,64 @@ static irqreturn_t cedrus_irq(int irq, void *data)
return IRQ_HANDLED;
}
+int cedrus_hw_suspend(struct device *device)
+{
+ struct cedrus_dev *dev = dev_get_drvdata(device);
+
+ reset_control_assert(dev->rstc);
+
+ clk_disable_unprepare(dev->ram_clk);
+ clk_disable_unprepare(dev->mod_clk);
+ clk_disable_unprepare(dev->ahb_clk);
+
+ return 0;
+}
+
+int cedrus_hw_resume(struct device *device)
+{
+ struct cedrus_dev *dev = dev_get_drvdata(device);
+ int ret;
+
+ ret = clk_prepare_enable(dev->ahb_clk);
+ if (ret) {
+ dev_err(dev->dev, "Failed to enable AHB clock\n");
+
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dev->mod_clk);
+ if (ret) {
+ dev_err(dev->dev, "Failed to enable MOD clock\n");
+
+ goto err_ahb_clk;
+ }
+
+ ret = clk_prepare_enable(dev->ram_clk);
+ if (ret) {
+ dev_err(dev->dev, "Failed to enable RAM clock\n");
+
+ goto err_mod_clk;
+ }
+
+ ret = reset_control_reset(dev->rstc);
+ if (ret) {
+ dev_err(dev->dev, "Failed to apply reset\n");
+
+ goto err_ram_clk;
+ }
+
+ return 0;
+
+err_ram_clk:
+ clk_disable_unprepare(dev->ram_clk);
+err_mod_clk:
+ clk_disable_unprepare(dev->mod_clk);
+err_ahb_clk:
+ clk_disable_unprepare(dev->ahb_clk);
+
+ return ret;
+}
+
int cedrus_hw_probe(struct cedrus_dev *dev)
{
const struct cedrus_variant *variant;
@@ -236,42 +295,17 @@ int cedrus_hw_probe(struct cedrus_dev *dev)
goto err_sram;
}
- ret = clk_prepare_enable(dev->ahb_clk);
- if (ret) {
- dev_err(dev->dev, "Failed to enable AHB clock\n");
-
- goto err_sram;
- }
-
- ret = clk_prepare_enable(dev->mod_clk);
- if (ret) {
- dev_err(dev->dev, "Failed to enable MOD clock\n");
-
- goto err_ahb_clk;
- }
-
- ret = clk_prepare_enable(dev->ram_clk);
- if (ret) {
- dev_err(dev->dev, "Failed to enable RAM clock\n");
-
- goto err_mod_clk;
- }
-
- ret = reset_control_reset(dev->rstc);
- if (ret) {
- dev_err(dev->dev, "Failed to apply reset\n");
-
- goto err_ram_clk;
+ pm_runtime_enable(dev->dev);
+ if (!pm_runtime_enabled(dev->dev)) {
+ ret = cedrus_hw_resume(dev->dev);
+ if (ret)
+ goto err_pm;
}
return 0;
-err_ram_clk:
- clk_disable_unprepare(dev->ram_clk);
-err_mod_clk:
- clk_disable_unprepare(dev->mod_clk);
-err_ahb_clk:
- clk_disable_unprepare(dev->ahb_clk);
+err_pm:
+ pm_runtime_disable(dev->dev);
err_sram:
sunxi_sram_release(dev->dev);
err_mem:
@@ -282,11 +316,9 @@ err_mem:
void cedrus_hw_remove(struct cedrus_dev *dev)
{
- reset_control_assert(dev->rstc);
-
- clk_disable_unprepare(dev->ram_clk);
- clk_disable_unprepare(dev->mod_clk);
- clk_disable_unprepare(dev->ahb_clk);
+ pm_runtime_disable(dev->dev);
+ if (!pm_runtime_status_suspended(dev->dev))
+ cedrus_hw_suspend(dev->dev);
sunxi_sram_release(dev->dev);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
index 604ff932fbf5..45f641f0bfa2 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
@@ -22,6 +22,9 @@ void cedrus_engine_disable(struct cedrus_dev *dev);
void cedrus_dst_format_set(struct cedrus_dev *dev,
struct v4l2_pix_format *fmt);
+int cedrus_hw_suspend(struct device *device);
+int cedrus_hw_resume(struct device *device);
+
int cedrus_hw_probe(struct cedrus_dev *dev);
void cedrus_hw_remove(struct cedrus_dev *dev);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index 15cf1f10221b..16d82309e7b6 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -13,6 +13,8 @@
* Marek Szyprowski, <m.szyprowski@samsung.com>
*/
+#include <linux/pm_runtime.h>
+
#include <media/videobuf2-dma-contig.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
@@ -273,7 +275,6 @@ static int cedrus_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
- struct cedrus_dev *dev = ctx->dev;
struct vb2_queue *vq;
int ret;
@@ -287,8 +288,6 @@ static int cedrus_s_fmt_vid_cap(struct file *file, void *priv,
ctx->dst_fmt = f->fmt.pix;
- cedrus_dst_format_set(dev, &ctx->dst_fmt);
-
return 0;
}
@@ -453,12 +452,24 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
return -EINVAL;
}
- if (V4L2_TYPE_IS_OUTPUT(vq->type) &&
- dev->dec_ops[ctx->current_codec]->start)
- ret = dev->dec_ops[ctx->current_codec]->start(ctx);
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+ ret = pm_runtime_get_sync(dev->dev);
+ if (ret < 0)
+ goto err_cleanup;
- if (ret)
- cedrus_queue_cleanup(vq, VB2_BUF_STATE_QUEUED);
+ if (dev->dec_ops[ctx->current_codec]->start) {
+ ret = dev->dec_ops[ctx->current_codec]->start(ctx);
+ if (ret)
+ goto err_pm;
+ }
+ }
+
+ return 0;
+
+err_pm:
+ pm_runtime_put(dev->dev);
+err_cleanup:
+ cedrus_queue_cleanup(vq, VB2_BUF_STATE_QUEUED);
return ret;
}
@@ -468,9 +479,12 @@ static void cedrus_stop_streaming(struct vb2_queue *vq)
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
struct cedrus_dev *dev = ctx->dev;
- if (V4L2_TYPE_IS_OUTPUT(vq->type) &&
- dev->dec_ops[ctx->current_codec]->stop)
- dev->dec_ops[ctx->current_codec]->stop(ctx);
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+ if (dev->dec_ops[ctx->current_codec]->stop)
+ dev->dec_ops[ctx->current_codec]->stop(ctx);
+
+ pm_runtime_put(dev->dev);
+ }
cedrus_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
}
diff --git a/drivers/staging/most/cdev/Kconfig b/drivers/staging/most/cdev/Kconfig
index 330c95fe6550..dab99477858e 100644
--- a/drivers/staging/most/cdev/Kconfig
+++ b/drivers/staging/most/cdev/Kconfig
@@ -6,7 +6,7 @@
config MOST_CDEV
tristate "Cdev"
- ---help---
+ help
Say Y here if you want to commumicate via character devices.
To compile this driver as a module, choose M here: the
diff --git a/drivers/staging/most/dim2/Kconfig b/drivers/staging/most/dim2/Kconfig
index 22f6900187b5..c211f0d9139c 100644
--- a/drivers/staging/most/dim2/Kconfig
+++ b/drivers/staging/most/dim2/Kconfig
@@ -7,7 +7,7 @@ config MOST_DIM2
tristate "DIM2"
depends on HAS_IOMEM && OF
- ---help---
+ help
Say Y here if you want to connect via MediaLB to network transceiver.
This device driver is platform dependent and needs an additional
platform driver to be installed. For more information contact
diff --git a/drivers/target/iscsi/cxgbit/Kconfig b/drivers/target/iscsi/cxgbit/Kconfig
index 8686dbd1d2e7..bdeefa75f29e 100644
--- a/drivers/target/iscsi/cxgbit/Kconfig
+++ b/drivers/target/iscsi/cxgbit/Kconfig
@@ -3,6 +3,6 @@ config ISCSI_TARGET_CXGB4
tristate "Chelsio iSCSI target offload driver"
depends on ISCSI_TARGET && CHELSIO_T4 && INET
select CHELSIO_LIB
- ---help---
+ help
To compile this driver as module, choose M here: the module
will be called cxgbit.
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 59379d662626..c9689610e186 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1158,7 +1158,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops,
conn->sess->se_sess, be32_to_cpu(hdr->data_length),
cmd->data_direction, sam_task_attr,
- cmd->sense_buffer + 2);
+ cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun));
pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
@@ -1167,23 +1167,26 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
target_get_sess_cmd(&cmd->se_cmd, true);
- cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
- scsilun_to_int(&hdr->lun));
- if (cmd->sense_reason)
- goto attach_cmd;
-
- /* only used for printks or comparing with ->ref_task_tag */
- cmd->se_cmd.tag = (__force u32)cmd->init_task_tag;
- cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
+ cmd->sense_reason = target_cmd_init_cdb(&cmd->se_cmd, hdr->cdb);
if (cmd->sense_reason) {
if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
return iscsit_add_reject_cmd(cmd,
- ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+ ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
}
goto attach_cmd;
}
+ cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd);
+ if (cmd->sense_reason)
+ goto attach_cmd;
+
+ /* only used for printks or comparing with ->ref_task_tag */
+ cmd->se_cmd.tag = (__force u32)cmd->init_task_tag;
+ cmd->sense_reason = target_cmd_parse_cdb(&cmd->se_cmd);
+ if (cmd->sense_reason)
+ goto attach_cmd;
+
if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
@@ -2000,7 +2003,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops,
conn->sess->se_sess, 0, DMA_NONE,
- TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
+ TCM_SIMPLE_TAG, cmd->sense_buffer + 2,
+ scsilun_to_int(&hdr->lun));
target_get_sess_cmd(&cmd->se_cmd, true);
@@ -2038,8 +2042,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
* Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
*/
if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
- ret = transport_lookup_tmr_lun(&cmd->se_cmd,
- scsilun_to_int(&hdr->lun));
+ ret = transport_lookup_tmr_lun(&cmd->se_cmd);
if (ret < 0) {
se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
goto attach;
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 46b0e1ceb77f..405d82d44717 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -45,7 +45,7 @@ static struct se_hba *lun0_hba;
struct se_device *g_lun0_dev;
sense_reason_t
-transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
+transport_lookup_cmd_lun(struct se_cmd *se_cmd)
{
struct se_lun *se_lun = NULL;
struct se_session *se_sess = se_cmd->se_sess;
@@ -54,7 +54,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
sense_reason_t ret = TCM_NO_SENSE;
rcu_read_lock();
- deve = target_nacl_find_deve(nacl, unpacked_lun);
+ deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun);
if (deve) {
atomic_long_inc(&deve->total_cmds);
@@ -74,7 +74,6 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
se_cmd->se_lun = se_lun;
se_cmd->pr_res_key = deve->pr_res_key;
- se_cmd->orig_fe_lun = unpacked_lun;
se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
se_cmd->lun_ref_active = true;
@@ -83,7 +82,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN"
" Access for 0x%08llx\n",
se_cmd->se_tfo->fabric_name,
- unpacked_lun);
+ se_cmd->orig_fe_lun);
rcu_read_unlock();
ret = TCM_WRITE_PROTECTED;
goto ref_dev;
@@ -98,18 +97,17 @@ out_unlock:
* REPORT_LUNS, et al to be returned when no active
* MappedLUN=0 exists for this Initiator Port.
*/
- if (unpacked_lun != 0) {
+ if (se_cmd->orig_fe_lun != 0) {
pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN"
" Access for 0x%08llx from %s\n",
se_cmd->se_tfo->fabric_name,
- unpacked_lun,
+ se_cmd->orig_fe_lun,
nacl->initiatorname);
return TCM_NON_EXISTENT_LUN;
}
se_lun = se_sess->se_tpg->tpg_virt_lun0;
se_cmd->se_lun = se_sess->se_tpg->tpg_virt_lun0;
- se_cmd->orig_fe_lun = 0;
se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
percpu_ref_get(&se_lun->lun_ref);
@@ -145,7 +143,7 @@ ref_dev:
}
EXPORT_SYMBOL(transport_lookup_cmd_lun);
-int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
+int transport_lookup_tmr_lun(struct se_cmd *se_cmd)
{
struct se_dev_entry *deve;
struct se_lun *se_lun = NULL;
@@ -155,7 +153,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
unsigned long flags;
rcu_read_lock();
- deve = target_nacl_find_deve(nacl, unpacked_lun);
+ deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun);
if (deve) {
se_lun = rcu_dereference(deve->se_lun);
@@ -166,7 +164,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
se_cmd->se_lun = se_lun;
se_cmd->pr_res_key = deve->pr_res_key;
- se_cmd->orig_fe_lun = unpacked_lun;
se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
se_cmd->lun_ref_active = true;
}
@@ -177,7 +174,7 @@ out_unlock:
pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN"
" Access for 0x%08llx for %s\n",
se_cmd->se_tfo->fabric_name,
- unpacked_lun,
+ se_cmd->orig_fe_lun,
nacl->initiatorname);
return -ENODEV;
}
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index afbd492c76a9..89c84d472cd7 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -148,8 +148,8 @@ void core_tmr_abort_task(
* code.
*/
if (!tmr->tmr_dev)
- WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd,
- se_cmd->orig_fe_lun) < 0);
+ WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) <
+ 0);
target_put_cmd_and_wait(se_cmd);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index da37af9c3a5e..90ecdd706a01 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1364,7 +1364,7 @@ void transport_init_se_cmd(
u32 data_length,
int data_direction,
int task_attr,
- unsigned char *sense_buffer)
+ unsigned char *sense_buffer, u64 unpacked_lun)
{
INIT_LIST_HEAD(&cmd->se_delayed_node);
INIT_LIST_HEAD(&cmd->se_qf_node);
@@ -1383,6 +1383,7 @@ void transport_init_se_cmd(
cmd->data_direction = data_direction;
cmd->sam_task_attr = task_attr;
cmd->sense_buffer = sense_buffer;
+ cmd->orig_fe_lun = unpacked_lun;
cmd->state_active = false;
}
@@ -1410,11 +1411,11 @@ transport_check_alloc_task_attr(struct se_cmd *cmd)
}
sense_reason_t
-target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
+target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb)
{
- struct se_device *dev = cmd->se_dev;
sense_reason_t ret;
+ cmd->t_task_cdb = &cmd->__t_task_cdb[0];
/*
* Ensure that the received CDB is less than the max (252 + 8) bytes
* for VARIABLE_LENGTH_CMD
@@ -1423,7 +1424,8 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
pr_err("Received SCSI CDB with command_size: %d that"
" exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE);
- return TCM_INVALID_CDB_FIELD;
+ ret = TCM_INVALID_CDB_FIELD;
+ goto err;
}
/*
* If the received CDB is larger than TCM_MAX_COMMAND_SIZE,
@@ -1438,16 +1440,34 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
" %u > sizeof(cmd->__t_task_cdb): %lu ops\n",
scsi_command_size(cdb),
(unsigned long)sizeof(cmd->__t_task_cdb));
- return TCM_OUT_OF_RESOURCES;
+ ret = TCM_OUT_OF_RESOURCES;
+ goto err;
}
- } else
- cmd->t_task_cdb = &cmd->__t_task_cdb[0];
+ }
/*
* Copy the original CDB into cmd->
*/
memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb));
trace_target_sequencer_start(cmd);
+ return 0;
+
+err:
+ /*
+ * Copy the CDB here to allow trace_target_cmd_complete() to
+ * print the cdb to the trace buffers.
+ */
+ memcpy(cmd->t_task_cdb, cdb, min(scsi_command_size(cdb),
+ (unsigned int)TCM_MAX_COMMAND_SIZE));
+ return ret;
+}
+EXPORT_SYMBOL(target_cmd_init_cdb);
+
+sense_reason_t
+target_cmd_parse_cdb(struct se_cmd *cmd)
+{
+ struct se_device *dev = cmd->se_dev;
+ sense_reason_t ret;
ret = dev->transport->parse_cdb(cmd);
if (ret == TCM_UNSUPPORTED_SCSI_OPCODE)
@@ -1466,7 +1486,7 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
atomic_long_inc(&cmd->se_lun->lun_stats.cmd_pdus);
return 0;
}
-EXPORT_SYMBOL(target_setup_cmd_from_cdb);
+EXPORT_SYMBOL(target_cmd_parse_cdb);
/*
* Used by fabric module frontends to queue tasks directly.
@@ -1588,7 +1608,8 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
* target_core_fabric_ops->queue_status() callback
*/
transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
- data_length, data_dir, task_attr, sense);
+ data_length, data_dir, task_attr, sense,
+ unpacked_lun);
if (flags & TARGET_SCF_USE_CPUID)
se_cmd->se_cmd_flags |= SCF_USE_CPUID;
@@ -1611,17 +1632,25 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
*/
if (flags & TARGET_SCF_BIDI_OP)
se_cmd->se_cmd_flags |= SCF_BIDI;
+
+ rc = target_cmd_init_cdb(se_cmd, cdb);
+ if (rc) {
+ transport_send_check_condition_and_sense(se_cmd, rc, 0);
+ target_put_sess_cmd(se_cmd);
+ return 0;
+ }
+
/*
* Locate se_lun pointer and attach it to struct se_cmd
*/
- rc = transport_lookup_cmd_lun(se_cmd, unpacked_lun);
+ rc = transport_lookup_cmd_lun(se_cmd);
if (rc) {
transport_send_check_condition_and_sense(se_cmd, rc, 0);
target_put_sess_cmd(se_cmd);
return 0;
}
- rc = target_setup_cmd_from_cdb(se_cmd, cdb);
+ rc = target_cmd_parse_cdb(se_cmd);
if (rc != 0) {
transport_generic_request_failure(se_cmd, rc);
return 0;
@@ -1782,7 +1811,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
BUG_ON(!se_tpg);
transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
- 0, DMA_NONE, TCM_SIMPLE_TAG, sense);
+ 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun);
/*
* FIXME: Currently expect caller to handle se_cmd->se_tmr_req
* allocation failure.
@@ -1810,7 +1839,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
goto failure;
}
- ret = transport_lookup_tmr_lun(se_cmd, unpacked_lun);
+ ret = transport_lookup_tmr_lun(se_cmd);
if (ret)
goto failure;
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 28fb9441de7a..560bfec933bc 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1007,7 +1007,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err)
entry->hdr.cmd_id = 0; /* not used for PAD */
entry->hdr.kflags = 0;
entry->hdr.uflags = 0;
- tcmu_flush_dcache_range(entry, sizeof(*entry));
+ tcmu_flush_dcache_range(entry, sizeof(entry->hdr));
UPDATE_HEAD(mb->cmd_head, pad_size, udev->cmdr_size);
tcmu_flush_dcache_range(mb, sizeof(*mb));
@@ -1072,7 +1072,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err)
cdb_off = CMDR_OFF + cmd_head + base_command_size;
memcpy((void *) mb + cdb_off, se_cmd->t_task_cdb, scsi_command_size(se_cmd->t_task_cdb));
entry->req.cdb_off = cdb_off;
- tcmu_flush_dcache_range(entry, sizeof(*entry));
+ tcmu_flush_dcache_range(entry, command_size);
UPDATE_HEAD(mb->cmd_head, command_size, udev->cmdr_size);
tcmu_flush_dcache_range(mb, sizeof(*mb));
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
index bd3ed6ce7571..0d00ccbeb050 100644
--- a/drivers/target/target_core_xcopy.c
+++ b/drivers/target/target_core_xcopy.c
@@ -526,8 +526,11 @@ static int target_xcopy_setup_pt_cmd(
}
cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
+ if (target_cmd_init_cdb(cmd, cdb))
+ return -EINVAL;
+
cmd->tag = 0;
- if (target_setup_cmd_from_cdb(cmd, cdb))
+ if (target_cmd_parse_cdb(cmd))
return -EINVAL;
if (transport_generic_map_mem_to_cmd(cmd, xop->xop_data_sg,
@@ -585,7 +588,7 @@ static int target_xcopy_read_source(
(unsigned long long)src_lba, src_sectors, length);
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
- DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0]);
+ DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0);
rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, src_dev, &cdb[0],
remote_port);
@@ -630,7 +633,7 @@ static int target_xcopy_write_destination(
(unsigned long long)dst_lba, dst_sectors, length);
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
- DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0]);
+ DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0);
rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, dst_dev, &cdb[0],
remote_port);
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index dbed3f480dc0..20b6fd7383c5 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -565,10 +565,10 @@ static int check_mem_type(unsigned long start, size_t num_pages)
if (virt_addr_valid(start))
return 0;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
rc = __check_mem_type(find_vma(mm, start),
start + num_pages * PAGE_SIZE);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return rc;
}
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 91af271e9bb0..3eb2348e5242 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -273,6 +273,16 @@ config IMX8MM_THERMAL
cpufreq is used as the cooling device to throttle CPUs when the passive
trip is crossed.
+config K3_THERMAL
+ tristate "Texas Instruments K3 thermal support"
+ depends on ARCH_K3 || COMPILE_TEST
+ help
+ If you say yes here you get thermal support for the Texas Instruments
+ K3 SoC family. The current chip supported is:
+ - AM654
+
+ This includes temperature reading functionality.
+
config MAX77620_THERMAL
tristate "Temperature sensor driver for Maxim MAX77620 PMIC"
depends on MFD_MAX77620
@@ -285,8 +295,8 @@ config MAX77620_THERMAL
config QORIQ_THERMAL
tristate "QorIQ Thermal Monitoring Unit"
- depends on THERMAL_OF
- depends on HAS_IOMEM
+ depends on THERMAL_OF && HAS_IOMEM
+ depends on PPC_E500MC || SOC_LS1021A || ARCH_LAYERSCAPE || (ARCH_MXC && ARM64) || COMPILE_TEST
select REGMAP_MMIO
help
Support for Thermal Monitoring Unit (TMU) found on QorIQ platforms.
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 8c8ed7b79915..0c8b84a09b9a 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -9,14 +9,14 @@ thermal_sys-y += thermal_core.o thermal_sysfs.o \
# interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
-thermal_sys-$(CONFIG_THERMAL_OF) += of-thermal.o
+thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o
# governors
-thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
+thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += gov_fair_share.o
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o
-thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o
-thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o
-thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o
+thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += gov_step_wise.o
+thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += gov_user_space.o
+thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += gov_power_allocator.o
# cpufreq cooling
thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpufreq_cooling.o
@@ -28,6 +28,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
# devfreq cooling
thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
+obj-$(CONFIG_K3_THERMAL) += k3_bandgap.o
# platform thermal drivers
obj-y += broadcom/
obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
diff --git a/drivers/thermal/clock_cooling.c b/drivers/thermal/clock_cooling.c
index 7cb3ae4b44ee..56cb1f46a428 100644
--- a/drivers/thermal/clock_cooling.c
+++ b/drivers/thermal/clock_cooling.c
@@ -12,15 +12,16 @@
* Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
*/
#include <linux/clk.h>
+#include <linux/clock_cooling.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/export.h>
#include <linux/idr.h>
#include <linux/mutex.h>
#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/thermal.h>
-#include <linux/clock_cooling.h>
/**
* struct clock_cooling_device - data for cooling device with clock
diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
index e297e135c031..9e124020519f 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -10,17 +10,17 @@
* Viresh Kumar <viresh.kumar@linaro.org>
*
*/
-#include <linux/module.h>
-#include <linux/thermal.h>
+#include <linux/cpu.h>
#include <linux/cpufreq.h>
+#include <linux/cpu_cooling.h>
+#include <linux/energy_model.h>
#include <linux/err.h>
+#include <linux/export.h>
#include <linux/idr.h>
#include <linux/pm_opp.h>
#include <linux/pm_qos.h>
#include <linux/slab.h>
-#include <linux/cpu.h>
-#include <linux/cpu_cooling.h>
-#include <linux/energy_model.h>
+#include <linux/thermal.h>
#include <trace/events/thermal.h>
diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c
index 0bb843246f59..78e3e8238116 100644
--- a/drivers/thermal/cpuidle_cooling.c
+++ b/drivers/thermal/cpuidle_cooling.c
@@ -5,11 +5,14 @@
* Author: Daniel Lezcano <daniel.lezcano@linaro.org>
*
*/
+#define pr_fmt(fmt) "cpuidle cooling: " fmt
+
#include <linux/cpu_cooling.h>
#include <linux/cpuidle.h>
#include <linux/err.h>
#include <linux/idle_inject.h>
#include <linux/idr.h>
+#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/thermal.h>
@@ -154,22 +157,25 @@ static struct thermal_cooling_device_ops cpuidle_cooling_ops = {
};
/**
- * cpuidle_of_cooling_register - Idle cooling device initialization function
+ * __cpuidle_cooling_register: register the cooling device
* @drv: a cpuidle driver structure pointer
- * @np: a node pointer to a device tree cooling device node
+ * @np: a device node structure pointer used for the thermal binding
*
- * This function is in charge of creating a cooling device per cpuidle
- * driver and register it to thermal framework.
+ * This function is in charge of allocating the cpuidle cooling device
+ * structure, the idle injection, initialize them and register the
+ * cooling device to the thermal framework.
*
- * Return: zero on success, or negative value corresponding to the
- * error detected in the underlying subsystems.
+ * Return: zero on success, a negative value returned by one of the
+ * underlying subsystem in case of error
*/
-int cpuidle_of_cooling_register(struct device_node *np,
- struct cpuidle_driver *drv)
+static int __cpuidle_cooling_register(struct device_node *np,
+ struct cpuidle_driver *drv)
{
struct idle_inject_device *ii_dev;
struct cpuidle_cooling_device *idle_cdev;
struct thermal_cooling_device *cdev;
+ unsigned int idle_duration_us = TICK_USEC;
+ unsigned int latency_us = UINT_MAX;
char dev_name[THERMAL_NAME_LENGTH];
int id, ret;
@@ -191,7 +197,11 @@ int cpuidle_of_cooling_register(struct device_node *np,
goto out_id;
}
- idle_inject_set_duration(ii_dev, TICK_USEC, TICK_USEC);
+ of_property_read_u32(np, "duration-us", &idle_duration_us);
+ of_property_read_u32(np, "exit-latency-us", &latency_us);
+
+ idle_inject_set_duration(ii_dev, TICK_USEC, idle_duration_us);
+ idle_inject_set_latency(ii_dev, latency_us);
idle_cdev->ii_dev = ii_dev;
@@ -204,6 +214,9 @@ int cpuidle_of_cooling_register(struct device_node *np,
goto out_unregister;
}
+ pr_debug("%s: Idle injection set with idle duration=%u, latency=%u\n",
+ dev_name, idle_duration_us, latency_us);
+
return 0;
out_unregister:
@@ -221,12 +234,38 @@ out:
* @drv: a cpuidle driver structure pointer
*
* This function is in charge of creating a cooling device per cpuidle
- * driver and register it to thermal framework.
+ * driver and register it to the thermal framework.
*
* Return: zero on success, or negative value corresponding to the
* error detected in the underlying subsystems.
*/
-int cpuidle_cooling_register(struct cpuidle_driver *drv)
+void cpuidle_cooling_register(struct cpuidle_driver *drv)
{
- return cpuidle_of_cooling_register(NULL, drv);
+ struct device_node *cooling_node;
+ struct device_node *cpu_node;
+ int cpu, ret;
+
+ for_each_cpu(cpu, drv->cpumask) {
+
+ cpu_node = of_cpu_device_node_get(cpu);
+
+ cooling_node = of_get_child_by_name(cpu_node, "thermal-idle");
+
+ of_node_put(cpu_node);
+
+ if (!cooling_node) {
+ pr_debug("'thermal-idle' node not found for cpu%d\n", cpu);
+ continue;
+ }
+
+ ret = __cpuidle_cooling_register(cooling_node, drv);
+
+ of_node_put(cooling_node);
+
+ if (ret) {
+ pr_err("Failed to register the cpuidle cooling device" \
+ "for cpu%d: %d\n", cpu, ret);
+ break;
+ }
+ }
}
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c
index a87d4fa031c8..f7f32e98331b 100644
--- a/drivers/thermal/devfreq_cooling.c
+++ b/drivers/thermal/devfreq_cooling.c
@@ -24,11 +24,13 @@
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
#include <linux/thermal.h>
#include <trace/events/thermal.h>
-#define SCALE_ERROR_MITIGATION 100
+#define HZ_PER_KHZ 1000
+#define SCALE_ERROR_MITIGATION 100
static DEFINE_IDA(devfreq_ida);
@@ -54,6 +56,8 @@ static DEFINE_IDA(devfreq_ida);
* The 'res_util' range is from 100 to (power_table[state] * 100)
* for the corresponding 'state'.
* @capped_state: index to cooling state with in dynamic power budget
+ * @req_max_freq: PM QoS request for limiting the maximum frequency
+ * of the devfreq device.
*/
struct devfreq_cooling_device {
int id;
@@ -66,49 +70,9 @@ struct devfreq_cooling_device {
struct devfreq_cooling_power *power_ops;
u32 res_util;
int capped_state;
+ struct dev_pm_qos_request req_max_freq;
};
-/**
- * partition_enable_opps() - disable all opps above a given state
- * @dfc: Pointer to devfreq we are operating on
- * @cdev_state: cooling device state we're setting
- *
- * Go through the OPPs of the device, enabling all OPPs until
- * @cdev_state and disabling those frequencies above it.
- */
-static int partition_enable_opps(struct devfreq_cooling_device *dfc,
- unsigned long cdev_state)
-{
- int i;
- struct device *dev = dfc->devfreq->dev.parent;
-
- for (i = 0; i < dfc->freq_table_size; i++) {
- struct dev_pm_opp *opp;
- int ret = 0;
- unsigned int freq = dfc->freq_table[i];
- bool want_enable = i >= cdev_state ? true : false;
-
- opp = dev_pm_opp_find_freq_exact(dev, freq, !want_enable);
-
- if (PTR_ERR(opp) == -ERANGE)
- continue;
- else if (IS_ERR(opp))
- return PTR_ERR(opp);
-
- dev_pm_opp_put(opp);
-
- if (want_enable)
- ret = dev_pm_opp_enable(dev, freq);
- else
- ret = dev_pm_opp_disable(dev, freq);
-
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
@@ -135,7 +99,7 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
struct devfreq_cooling_device *dfc = cdev->devdata;
struct devfreq *df = dfc->devfreq;
struct device *dev = df->dev.parent;
- int ret;
+ unsigned long freq;
if (state == dfc->cooling_state)
return 0;
@@ -145,9 +109,10 @@ static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
if (state >= dfc->freq_table_size)
return -EINVAL;
- ret = partition_enable_opps(dfc, state);
- if (ret)
- return ret;
+ freq = dfc->freq_table[state];
+
+ dev_pm_qos_update_request(&dfc->req_max_freq,
+ DIV_ROUND_UP(freq, HZ_PER_KHZ));
dfc->cooling_state = state;
@@ -530,9 +495,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
if (err)
goto free_dfc;
- err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
+ err = dev_pm_qos_add_request(df->dev.parent, &dfc->req_max_freq,
+ DEV_PM_QOS_MAX_FREQUENCY,
+ PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
if (err < 0)
goto free_tables;
+
+ err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL);
+ if (err < 0)
+ goto remove_qos_req;
dfc->id = err;
snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id);
@@ -553,6 +524,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
release_ida:
ida_simple_remove(&devfreq_ida, dfc->id);
+
+remove_qos_req:
+ dev_pm_qos_remove_request(&dfc->req_max_freq);
+
free_tables:
kfree(dfc->power_table);
kfree(dfc->freq_table);
@@ -601,6 +576,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
thermal_cooling_device_unregister(dfc->cdev);
ida_simple_remove(&devfreq_ida, dfc->id);
+ dev_pm_qos_remove_request(&dfc->req_max_freq);
kfree(dfc->power_table);
kfree(dfc->freq_table);
diff --git a/drivers/thermal/fair_share.c b/drivers/thermal/gov_fair_share.c
index aaa07180ab48..aaa07180ab48 100644
--- a/drivers/thermal/fair_share.c
+++ b/drivers/thermal/gov_fair_share.c
diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/gov_power_allocator.c
index 44636475b2a3..44636475b2a3 100644
--- a/drivers/thermal/power_allocator.c
+++ b/drivers/thermal/gov_power_allocator.c
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/gov_step_wise.c
index 2ae7198d3067..2ae7198d3067 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/gov_step_wise.c
diff --git a/drivers/thermal/user_space.c b/drivers/thermal/gov_user_space.c
index 293cffd9c8ad..82a7198bbe71 100644
--- a/drivers/thermal/user_space.c
+++ b/drivers/thermal/gov_user_space.c
@@ -10,8 +10,8 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-#include <linux/thermal.h>
#include <linux/slab.h>
+#include <linux/thermal.h>
#include "thermal_core.h"
diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
index 0d60f8d7894f..e6061e26d4ac 100644
--- a/drivers/thermal/imx8mm_thermal.c
+++ b/drivers/thermal/imx8mm_thermal.c
@@ -54,7 +54,7 @@ struct imx8mm_tmu {
void __iomem *base;
struct clk *clk;
const struct thermal_soc_data *socdata;
- struct tmu_sensor sensors[0];
+ struct tmu_sensor sensors[];
};
static int imx8mm_tmu_get_temp(void *data, int *temp)
diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c
index 8938ea81a525..b01d28eca7ee 100644
--- a/drivers/thermal/imx_sc_thermal.c
+++ b/drivers/thermal/imx_sc_thermal.c
@@ -14,6 +14,7 @@
#include <linux/thermal.h>
#include "thermal_core.h"
+#include "thermal_hwmon.h"
#define IMX_SC_MISC_FUNC_GET_TEMP 13
@@ -115,6 +116,9 @@ static int imx_sc_thermal_probe(struct platform_device *pdev)
ret = PTR_ERR(sensor->tzd);
break;
}
+
+ if (devm_thermal_add_hwmon_sysfs(sensor->tzd))
+ dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
}
of_node_put(sensor_np);
diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
index ceef89c956bd..0b3a62655843 100644
--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
@@ -13,6 +13,7 @@
#include "acpi_thermal_rel.h"
#define INT3400_THERMAL_TABLE_CHANGED 0x83
+#define INT3400_ODVP_CHANGED 0x88
enum int3400_thermal_uuid {
INT3400_THERMAL_PASSIVE_1,
@@ -41,8 +42,11 @@ static char *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = {
"BE84BABF-C4D4-403D-B495-3128FD44dAC1",
};
+struct odvp_attr;
+
struct int3400_thermal_priv {
struct acpi_device *adev;
+ struct platform_device *pdev;
struct thermal_zone_device *thermal;
int mode;
int art_count;
@@ -52,6 +56,36 @@ struct int3400_thermal_priv {
u8 uuid_bitmap;
int rel_misc_dev_res;
int current_uuid_index;
+ char *data_vault;
+ int odvp_count;
+ int *odvp;
+ struct odvp_attr *odvp_attrs;
+};
+
+static int evaluate_odvp(struct int3400_thermal_priv *priv);
+
+struct odvp_attr {
+ int odvp;
+ struct int3400_thermal_priv *priv;
+ struct kobj_attribute attr;
+};
+
+static ssize_t data_vault_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t off, size_t count)
+{
+ memcpy(buf, attr->private + off, count);
+ return count;
+}
+
+static BIN_ATTR_RO(data_vault, 0);
+
+static struct bin_attribute *data_attributes[] = {
+ &bin_attr_data_vault,
+ NULL,
+};
+
+static const struct attribute_group data_attribute_group = {
+ .bin_attrs = data_attributes,
};
static ssize_t available_uuids_show(struct device *dev,
@@ -62,6 +96,9 @@ static ssize_t available_uuids_show(struct device *dev,
int i;
int length = 0;
+ if (!priv->uuid_bitmap)
+ return sprintf(buf, "UNKNOWN\n");
+
for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) {
if (priv->uuid_bitmap & (1 << i))
if (PAGE_SIZE - length > 0)
@@ -79,11 +116,11 @@ static ssize_t current_uuid_show(struct device *dev,
{
struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
- if (priv->uuid_bitmap & (1 << priv->current_uuid_index))
- return sprintf(buf, "%s\n",
- int3400_thermal_uuids[priv->current_uuid_index]);
- else
+ if (priv->current_uuid_index == -1)
return sprintf(buf, "INVALID\n");
+
+ return sprintf(buf, "%s\n",
+ int3400_thermal_uuids[priv->current_uuid_index]);
}
static ssize_t current_uuid_store(struct device *dev,
@@ -94,9 +131,16 @@ static ssize_t current_uuid_store(struct device *dev,
int i;
for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; ++i) {
- if ((priv->uuid_bitmap & (1 << i)) &&
- !(strncmp(buf, int3400_thermal_uuids[i],
- sizeof(int3400_thermal_uuids[i]) - 1))) {
+ if (!strncmp(buf, int3400_thermal_uuids[i],
+ sizeof(int3400_thermal_uuids[i]) - 1)) {
+ /*
+ * If we have a list of supported UUIDs, make sure
+ * this one is supported.
+ */
+ if (priv->uuid_bitmap &&
+ !(priv->uuid_bitmap & (1 << i)))
+ return -EINVAL;
+
priv->current_uuid_index = i;
return count;
}
@@ -191,9 +235,110 @@ static int int3400_thermal_run_osc(acpi_handle handle,
result = -EPERM;
kfree(context.ret.pointer);
+
return result;
}
+static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ struct odvp_attr *odvp_attr;
+
+ odvp_attr = container_of(attr, struct odvp_attr, attr);
+
+ return sprintf(buf, "%d\n", odvp_attr->priv->odvp[odvp_attr->odvp]);
+}
+
+static void cleanup_odvp(struct int3400_thermal_priv *priv)
+{
+ int i;
+
+ if (priv->odvp_attrs) {
+ for (i = 0; i < priv->odvp_count; i++) {
+ sysfs_remove_file(&priv->pdev->dev.kobj,
+ &priv->odvp_attrs[i].attr.attr);
+ kfree(priv->odvp_attrs[i].attr.attr.name);
+ }
+ kfree(priv->odvp_attrs);
+ }
+ kfree(priv->odvp);
+ priv->odvp_count = 0;
+}
+
+static int evaluate_odvp(struct int3400_thermal_priv *priv)
+{
+ struct acpi_buffer odvp = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj = NULL;
+ acpi_status status;
+ int i, ret;
+
+ status = acpi_evaluate_object(priv->adev->handle, "ODVP", NULL, &odvp);
+ if (ACPI_FAILURE(status)) {
+ ret = -EINVAL;
+ goto out_err;
+ }
+
+ obj = odvp.pointer;
+ if (obj->type != ACPI_TYPE_PACKAGE) {
+ ret = -EINVAL;
+ goto out_err;
+ }
+
+ if (priv->odvp == NULL) {
+ priv->odvp_count = obj->package.count;
+ priv->odvp = kmalloc_array(priv->odvp_count, sizeof(int),
+ GFP_KERNEL);
+ if (!priv->odvp) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+ }
+
+ if (priv->odvp_attrs == NULL) {
+ priv->odvp_attrs = kcalloc(priv->odvp_count,
+ sizeof(struct odvp_attr),
+ GFP_KERNEL);
+ if (!priv->odvp_attrs) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+ for (i = 0; i < priv->odvp_count; i++) {
+ struct odvp_attr *odvp = &priv->odvp_attrs[i];
+
+ sysfs_attr_init(&odvp->attr.attr);
+ odvp->priv = priv;
+ odvp->odvp = i;
+ odvp->attr.attr.name = kasprintf(GFP_KERNEL,
+ "odvp%d", i);
+
+ if (!odvp->attr.attr.name) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+ odvp->attr.attr.mode = 0444;
+ odvp->attr.show = odvp_show;
+ odvp->attr.store = NULL;
+ ret = sysfs_create_file(&priv->pdev->dev.kobj,
+ &odvp->attr.attr);
+ if (ret)
+ goto out_err;
+ }
+ }
+
+ for (i = 0; i < obj->package.count; i++) {
+ if (obj->package.elements[i].type == ACPI_TYPE_INTEGER)
+ priv->odvp[i] = obj->package.elements[i].integer.value;
+ }
+
+ kfree(obj);
+ return 0;
+
+out_err:
+ cleanup_odvp(priv);
+ kfree(obj);
+ return ret;
+}
+
static void int3400_notify(acpi_handle handle,
u32 event,
void *data)
@@ -217,6 +362,9 @@ static void int3400_notify(acpi_handle handle,
kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE,
thermal_prop);
break;
+ case INT3400_ODVP_CHANGED:
+ evaluate_odvp(priv);
+ break;
default:
/* Ignore unknown notification codes sent to INT3400 device */
break;
@@ -266,11 +414,16 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
priv->current_uuid_index,
enable);
}
+
+ evaluate_odvp(priv);
+
return result;
}
static struct thermal_zone_device_ops int3400_thermal_ops = {
.get_temp = int3400_thermal_get_temp,
+ .get_mode = int3400_thermal_get_mode,
+ .set_mode = int3400_thermal_set_mode,
};
static struct thermal_zone_params int3400_thermal_params = {
@@ -278,6 +431,32 @@ static struct thermal_zone_params int3400_thermal_params = {
.no_hwmon = true,
};
+static void int3400_setup_gddv(struct int3400_thermal_priv *priv)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+
+ status = acpi_evaluate_object(priv->adev->handle, "GDDV", NULL,
+ &buffer);
+ if (ACPI_FAILURE(status) || !buffer.length)
+ return;
+
+ obj = buffer.pointer;
+ if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 1
+ || obj->package.elements[0].type != ACPI_TYPE_BUFFER) {
+ kfree(buffer.pointer);
+ return;
+ }
+
+ priv->data_vault = kmemdup(obj->package.elements[0].buffer.pointer,
+ obj->package.elements[0].buffer.length,
+ GFP_KERNEL);
+ bin_attr_data_vault.private = priv->data_vault;
+ bin_attr_data_vault.size = obj->package.elements[0].buffer.length;
+ kfree(buffer.pointer);
+}
+
static int int3400_thermal_probe(struct platform_device *pdev)
{
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
@@ -291,12 +470,17 @@ static int int3400_thermal_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
+ priv->pdev = pdev;
priv->adev = adev;
result = int3400_thermal_get_uuids(priv);
- if (result)
+
+ /* Missing IDSP isn't fatal */
+ if (result && result != -ENODEV)
goto free_priv;
+ priv->current_uuid_index = -1;
+
result = acpi_parse_art(priv->adev->handle, &priv->art_count,
&priv->arts, true);
if (result)
@@ -309,8 +493,9 @@ static int int3400_thermal_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- int3400_thermal_ops.get_mode = int3400_thermal_get_mode;
- int3400_thermal_ops.set_mode = int3400_thermal_set_mode;
+ int3400_setup_gddv(priv);
+
+ evaluate_odvp(priv);
priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0,
priv, &int3400_thermal_ops,
@@ -327,6 +512,13 @@ static int int3400_thermal_probe(struct platform_device *pdev)
if (result)
goto free_rel_misc;
+ if (priv->data_vault) {
+ result = sysfs_create_group(&pdev->dev.kobj,
+ &data_attribute_group);
+ if (result)
+ goto free_uuid;
+ }
+
result = acpi_install_notify_handler(
priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify,
(void *)priv);
@@ -336,6 +528,12 @@ static int int3400_thermal_probe(struct platform_device *pdev)
return 0;
free_sysfs:
+ cleanup_odvp(priv);
+ if (priv->data_vault) {
+ sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
+ kfree(priv->data_vault);
+ }
+free_uuid:
sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
free_rel_misc:
if (!priv->rel_misc_dev_res)
@@ -357,11 +555,16 @@ static int int3400_thermal_remove(struct platform_device *pdev)
priv->adev->handle, ACPI_DEVICE_NOTIFY,
int3400_notify);
+ cleanup_odvp(priv);
+
if (!priv->rel_misc_dev_res)
acpi_thermal_rel_misc_device_remove(priv->adev->handle);
+ if (priv->data_vault)
+ sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
thermal_zone_device_unregister(priv->thermal);
+ kfree(priv->data_vault);
kfree(priv->trts);
kfree(priv->arts);
kfree(priv);
diff --git a/drivers/thermal/k3_bandgap.c b/drivers/thermal/k3_bandgap.c
new file mode 100644
index 000000000000..35f41e8a0b75
--- /dev/null
+++ b/drivers/thermal/k3_bandgap.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI Bandgap temperature sensor driver for K3 SoC Family
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/thermal.h>
+#include <linux/types.h>
+
+#define K3_VTM_DEVINFO_PWR0_OFFSET 0x4
+#define K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK 0xf0
+#define K3_VTM_TMPSENS0_CTRL_OFFSET 0x80
+#define K3_VTM_REGS_PER_TS 0x10
+#define K3_VTM_TS_STAT_DTEMP_MASK 0x3ff
+#define K3_VTM_TMPSENS_CTRL_CBIASSEL BIT(0)
+#define K3_VTM_TMPSENS_CTRL_SOC BIT(5)
+#define K3_VTM_TMPSENS_CTRL_CLRZ BIT(6)
+#define K3_VTM_TMPSENS_CTRL_CLKON_REQ BIT(7)
+
+#define K3_VTM_ADC_BEGIN_VAL 540
+#define K3_VTM_ADC_END_VAL 944
+
+static const int k3_adc_to_temp[] = {
+ -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
+ -37800, -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200,
+ -33800, -33400, -33000, -32600, -32200, -31800, -31400, -31000, -30600,
+ -30200, -29800, -29400, -29000, -28600, -28200, -27700, -27100, -26600,
+ -26200, -25800, -25400, -25000, -24600, -24200, -23800, -23400, -23000,
+ -22600, -22200, -21800, -21400, -21000, -20500, -19900, -19400, -19000,
+ -18600, -18200, -17800, -17400, -17000, -16600, -16200, -15800, -15400,
+ -15000, -14600, -14200, -13800, -13400, -13000, -12500, -11900, -11400,
+ -11000, -10600, -10200, -9800, -9400, -9000, -8600, -8200, -7800, -7400,
+ -7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900, -3400, -3000,
+ -2600, -2200, -1800, -1400, -1000, -600, -200, 200, 600, 1000, 1400,
+ 1800, 2200, 2600, 3000, 3400, 3900, 4500, 5000, 5400, 5800, 6200, 6600,
+ 7000, 7400, 7800, 8200, 8600, 9000, 9400, 9800, 10200, 10600, 11000,
+ 11400, 11800, 12200, 12700, 13300, 13800, 14200, 14600, 15000, 15400,
+ 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18600, 19000, 19400,
+ 19800, 20200, 20600, 21000, 21400, 21900, 22500, 23000, 23400, 23800,
+ 24200, 24600, 25000, 25400, 25800, 26200, 26600, 27000, 27400, 27800,
+ 28200, 28600, 29000, 29400, 29800, 30200, 30600, 31000, 31400, 31900,
+ 32500, 33000, 33400, 33800, 34200, 34600, 35000, 35400, 35800, 36200,
+ 36600, 37000, 37400, 37800, 38200, 38600, 39000, 39400, 39800, 40200,
+ 40600, 41000, 41400, 41800, 42200, 42600, 43100, 43700, 44200, 44600,
+ 45000, 45400, 45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600,
+ 49000, 49400, 49800, 50200, 50600, 51000, 51400, 51800, 52200, 52600,
+ 53000, 53400, 53800, 54200, 54600, 55000, 55400, 55900, 56500, 57000,
+ 57400, 57800, 58200, 58600, 59000, 59400, 59800, 60200, 60600, 61000,
+ 61400, 61800, 62200, 62600, 63000, 63400, 63800, 64200, 64600, 65000,
+ 65400, 65800, 66200, 66600, 67000, 67400, 67800, 68200, 68600, 69000,
+ 69400, 69800, 70200, 70600, 71000, 71500, 72100, 72600, 73000, 73400,
+ 73800, 74200, 74600, 75000, 75400, 75800, 76200, 76600, 77000, 77400,
+ 77800, 78200, 78600, 79000, 79400, 79800, 80200, 80600, 81000, 81400,
+ 81800, 82200, 82600, 83000, 83400, 83800, 84200, 84600, 85000, 85400,
+ 85800, 86200, 86600, 87000, 87400, 87800, 88200, 88600, 89000, 89400,
+ 89800, 90200, 90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400,
+ 93800, 94200, 94600, 95000, 95400, 95800, 96200, 96600, 97000, 97500,
+ 98100, 98600, 99000, 99400, 99800, 100200, 100600, 101000, 101400,
+ 101800, 102200, 102600, 103000, 103400, 103800, 104200, 104600, 105000,
+ 105400, 105800, 106200, 106600, 107000, 107400, 107800, 108200, 108600,
+ 109000, 109400, 109800, 110200, 110600, 111000, 111400, 111800, 112200,
+ 112600, 113000, 113400, 113800, 114200, 114600, 115000, 115400, 115800,
+ 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000, 119400,
+ 119800, 120200, 120600, 121000, 121400, 121800, 122200, 122600, 123000,
+ 123400, 123800, 124200, 124600, 124900, 125000,
+};
+
+struct k3_bandgap {
+ void __iomem *base;
+ const struct k3_bandgap_data *conf;
+};
+
+/* common data structures */
+struct k3_thermal_data {
+ struct thermal_zone_device *tzd;
+ struct k3_bandgap *bgp;
+ int sensor_id;
+ u32 ctrl_offset;
+ u32 stat_offset;
+};
+
+static unsigned int vtm_get_best_value(unsigned int s0, unsigned int s1,
+ unsigned int s2)
+{
+ int d01 = abs(s0 - s1);
+ int d02 = abs(s0 - s2);
+ int d12 = abs(s1 - s2);
+
+ if (d01 <= d02 && d01 <= d12)
+ return (s0 + s1) / 2;
+
+ if (d02 <= d01 && d02 <= d12)
+ return (s0 + s2) / 2;
+
+ return (s1 + s2) / 2;
+}
+
+static int k3_bgp_read_temp(struct k3_thermal_data *devdata,
+ int *temp)
+{
+ struct k3_bandgap *bgp;
+ unsigned int dtemp, s0, s1, s2;
+
+ bgp = devdata->bgp;
+
+ /*
+ * Errata is applicable for am654 pg 1.0 silicon. There
+ * is a variation of the order for 8-10 degree centigrade.
+ * Work around that by getting the average of two closest
+ * readings out of three readings everytime we want to
+ * report temperatures.
+ *
+ * Errata workaround.
+ */
+ s0 = readl(bgp->base + devdata->stat_offset) &
+ K3_VTM_TS_STAT_DTEMP_MASK;
+ s1 = readl(bgp->base + devdata->stat_offset) &
+ K3_VTM_TS_STAT_DTEMP_MASK;
+ s2 = readl(bgp->base + devdata->stat_offset) &
+ K3_VTM_TS_STAT_DTEMP_MASK;
+ dtemp = vtm_get_best_value(s0, s1, s2);
+
+ if (dtemp < K3_VTM_ADC_BEGIN_VAL || dtemp > K3_VTM_ADC_END_VAL)
+ return -EINVAL;
+
+ *temp = k3_adc_to_temp[dtemp - K3_VTM_ADC_BEGIN_VAL];
+
+ return 0;
+}
+
+static int k3_thermal_get_temp(void *devdata, int *temp)
+{
+ struct k3_thermal_data *data = devdata;
+ int ret = 0;
+
+ ret = k3_bgp_read_temp(data, temp);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static const struct thermal_zone_of_device_ops k3_of_thermal_ops = {
+ .get_temp = k3_thermal_get_temp,
+};
+
+static const struct of_device_id of_k3_bandgap_match[];
+
+static int k3_bandgap_probe(struct platform_device *pdev)
+{
+ int ret = 0, cnt, val, id;
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ struct k3_bandgap *bgp;
+ struct k3_thermal_data *data;
+
+ if (ARRAY_SIZE(k3_adc_to_temp) != (K3_VTM_ADC_END_VAL + 1 -
+ K3_VTM_ADC_BEGIN_VAL))
+ return -EINVAL;
+
+ bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
+ if (!bgp)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ bgp->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(bgp->base))
+ return PTR_ERR(bgp->base);
+
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ pm_runtime_disable(dev);
+ return ret;
+ }
+
+ /* Get the sensor count in the VTM */
+ val = readl(bgp->base + K3_VTM_DEVINFO_PWR0_OFFSET);
+ cnt = val & K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK;
+ cnt >>= __ffs(K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK);
+
+ data = devm_kcalloc(dev, cnt, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ /* Register the thermal sensors */
+ for (id = 0; id < cnt; id++) {
+ data[id].sensor_id = id;
+ data[id].bgp = bgp;
+ data[id].ctrl_offset = K3_VTM_TMPSENS0_CTRL_OFFSET +
+ id * K3_VTM_REGS_PER_TS;
+ data[id].stat_offset = data[id].ctrl_offset + 0x8;
+
+ val = readl(data[id].bgp->base + data[id].ctrl_offset);
+ val |= (K3_VTM_TMPSENS_CTRL_SOC |
+ K3_VTM_TMPSENS_CTRL_CLRZ |
+ K3_VTM_TMPSENS_CTRL_CLKON_REQ);
+ val &= ~K3_VTM_TMPSENS_CTRL_CBIASSEL;
+ writel(val, data[id].bgp->base + data[id].ctrl_offset);
+
+ data[id].tzd =
+ devm_thermal_zone_of_sensor_register(dev, id,
+ &data[id],
+ &k3_of_thermal_ops);
+ if (IS_ERR(data[id].tzd)) {
+ dev_err(dev, "thermal zone device is NULL\n");
+ ret = PTR_ERR(data[id].tzd);
+ goto err_alloc;
+ }
+ }
+
+ platform_set_drvdata(pdev, bgp);
+
+ return 0;
+
+err_alloc:
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+
+ return ret;
+}
+
+static int k3_bandgap_remove(struct platform_device *pdev)
+{
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id of_k3_bandgap_match[] = {
+ {
+ .compatible = "ti,am654-vtm",
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, of_k3_bandgap_match);
+
+static struct platform_driver k3_bandgap_sensor_driver = {
+ .probe = k3_bandgap_probe,
+ .remove = k3_bandgap_remove,
+ .driver = {
+ .name = "k3-soc-thermal",
+ .of_match_table = of_k3_bandgap_match,
+ },
+};
+
+module_platform_driver(k3_bandgap_sensor_driver);
+
+MODULE_DESCRIPTION("K3 bandgap temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 7c8dc6e36693..ec86eef7f6a6 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
-qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o \
- tsens-8960.o tsens-v2.o tsens-v1.o
+qcom_tsens-y += tsens.o tsens-v2.o tsens-v1.o tsens-v0_1.o \
+ tsens-8960.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
deleted file mode 100644
index 172545366636..000000000000
--- a/drivers/thermal/qcom/tsens-common.c
+++ /dev/null
@@ -1,843 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/debugfs.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/nvmem-consumer.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include "tsens.h"
-
-/**
- * struct tsens_irq_data - IRQ status and temperature violations
- * @up_viol: upper threshold violated
- * @up_thresh: upper threshold temperature value
- * @up_irq_mask: mask register for upper threshold irqs
- * @up_irq_clear: clear register for uppper threshold irqs
- * @low_viol: lower threshold violated
- * @low_thresh: lower threshold temperature value
- * @low_irq_mask: mask register for lower threshold irqs
- * @low_irq_clear: clear register for lower threshold irqs
- * @crit_viol: critical threshold violated
- * @crit_thresh: critical threshold temperature value
- * @crit_irq_mask: mask register for critical threshold irqs
- * @crit_irq_clear: clear register for critical threshold irqs
- *
- * Structure containing data about temperature threshold settings and
- * irq status if they were violated.
- */
-struct tsens_irq_data {
- u32 up_viol;
- int up_thresh;
- u32 up_irq_mask;
- u32 up_irq_clear;
- u32 low_viol;
- int low_thresh;
- u32 low_irq_mask;
- u32 low_irq_clear;
- u32 crit_viol;
- u32 crit_thresh;
- u32 crit_irq_mask;
- u32 crit_irq_clear;
-};
-
-char *qfprom_read(struct device *dev, const char *cname)
-{
- struct nvmem_cell *cell;
- ssize_t data;
- char *ret;
-
- cell = nvmem_cell_get(dev, cname);
- if (IS_ERR(cell))
- return ERR_CAST(cell);
-
- ret = nvmem_cell_read(cell, &data);
- nvmem_cell_put(cell);
-
- return ret;
-}
-
-/*
- * Use this function on devices where slope and offset calculations
- * depend on calibration data read from qfprom. On others the slope
- * and offset values are derived from tz->tzp->slope and tz->tzp->offset
- * resp.
- */
-void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
- u32 *p2, u32 mode)
-{
- int i;
- int num, den;
-
- for (i = 0; i < priv->num_sensors; i++) {
- dev_dbg(priv->dev,
- "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
- __func__, i, p1[i], p2[i]);
-
- priv->sensor[i].slope = SLOPE_DEFAULT;
- if (mode == TWO_PT_CALIB) {
- /*
- * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
- * temp_120_degc - temp_30_degc (x2 - x1)
- */
- num = p2[i] - p1[i];
- num *= SLOPE_FACTOR;
- den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
- priv->sensor[i].slope = num / den;
- }
-
- priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
- (CAL_DEGC_PT1 *
- priv->sensor[i].slope);
- dev_dbg(priv->dev, "%s: offset:%d\n", __func__, priv->sensor[i].offset);
- }
-}
-
-static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)
-{
- u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);
-
- pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
- return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
-}
-
-static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
-{
- int degc, num, den;
-
- num = (adc_code * SLOPE_FACTOR) - s->offset;
- den = s->slope;
-
- if (num > 0)
- degc = num + (den / 2);
- else if (num < 0)
- degc = num - (den / 2);
- else
- degc = num;
-
- degc /= den;
-
- return degc;
-}
-
-/**
- * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.
- * @s: Pointer to sensor struct
- * @field: Index into regmap_field array pointing to temperature data
- *
- * This function handles temperature returned in ADC code or deciCelsius
- * depending on IP version.
- *
- * Return: Temperature in milliCelsius on success, a negative errno will
- * be returned in error cases
- */
-static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)
-{
- struct tsens_priv *priv = s->priv;
- u32 resolution;
- u32 temp = 0;
- int ret;
-
- resolution = priv->fields[LAST_TEMP_0].msb -
- priv->fields[LAST_TEMP_0].lsb;
-
- ret = regmap_field_read(priv->rf[field], &temp);
- if (ret)
- return ret;
-
- /* Convert temperature from ADC code to milliCelsius */
- if (priv->feat->adc)
- return code_to_degc(temp, s) * 1000;
-
- /* deciCelsius -> milliCelsius along with sign extension */
- return sign_extend32(temp, resolution) * 100;
-}
-
-/**
- * tsens_mC_to_hw - Convert temperature to hardware register value
- * @s: Pointer to sensor struct
- * @temp: temperature in milliCelsius to be programmed to hardware
- *
- * This function outputs the value to be written to hardware in ADC code
- * or deciCelsius depending on IP version.
- *
- * Return: ADC code or temperature in deciCelsius.
- */
-static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)
-{
- struct tsens_priv *priv = s->priv;
-
- /* milliC to adc code */
- if (priv->feat->adc)
- return degc_to_code(temp / 1000, s);
-
- /* milliC to deciC */
- return temp / 100;
-}
-
-static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
-{
- return priv->feat->ver_major;
-}
-
-static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
- enum tsens_irq_type irq_type, bool enable)
-{
- u32 index = 0;
-
- switch (irq_type) {
- case UPPER:
- index = UP_INT_CLEAR_0 + hw_id;
- break;
- case LOWER:
- index = LOW_INT_CLEAR_0 + hw_id;
- break;
- case CRITICAL:
- /* No critical interrupts before v2 */
- return;
- }
- regmap_field_write(priv->rf[index], enable ? 0 : 1);
-}
-
-static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
- enum tsens_irq_type irq_type, bool enable)
-{
- u32 index_mask = 0, index_clear = 0;
-
- /*
- * To enable the interrupt flag for a sensor:
- * - clear the mask bit
- * To disable the interrupt flag for a sensor:
- * - Mask further interrupts for this sensor
- * - Write 1 followed by 0 to clear the interrupt
- */
- switch (irq_type) {
- case UPPER:
- index_mask = UP_INT_MASK_0 + hw_id;
- index_clear = UP_INT_CLEAR_0 + hw_id;
- break;
- case LOWER:
- index_mask = LOW_INT_MASK_0 + hw_id;
- index_clear = LOW_INT_CLEAR_0 + hw_id;
- break;
- case CRITICAL:
- index_mask = CRIT_INT_MASK_0 + hw_id;
- index_clear = CRIT_INT_CLEAR_0 + hw_id;
- break;
- }
-
- if (enable) {
- regmap_field_write(priv->rf[index_mask], 0);
- } else {
- regmap_field_write(priv->rf[index_mask], 1);
- regmap_field_write(priv->rf[index_clear], 1);
- regmap_field_write(priv->rf[index_clear], 0);
- }
-}
-
-/**
- * tsens_set_interrupt - Set state of an interrupt
- * @priv: Pointer to tsens controller private data
- * @hw_id: Hardware ID aka. sensor number
- * @irq_type: irq_type from enum tsens_irq_type
- * @enable: false = disable, true = enable
- *
- * Call IP-specific function to set state of an interrupt
- *
- * Return: void
- */
-static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
- enum tsens_irq_type irq_type, bool enable)
-{
- dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
- irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
- enable ? "en" : "dis");
- if (tsens_version(priv) > VER_1_X)
- tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
- else
- tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
-}
-
-/**
- * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold
- * @priv: Pointer to tsens controller private data
- * @hw_id: Hardware ID aka. sensor number
- * @d: Pointer to irq state data
- *
- * Return: 0 if threshold was not violated, 1 if it was violated and negative
- * errno in case of errors
- */
-static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,
- struct tsens_irq_data *d)
-{
- int ret;
-
- ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);
- if (ret)
- return ret;
-
- if (priv->feat->crit_int) {
- ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],
- &d->crit_viol);
- if (ret)
- return ret;
- }
-
- if (d->up_viol || d->low_viol || d->crit_viol)
- return 1;
-
- return 0;
-}
-
-static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
- const struct tsens_sensor *s,
- struct tsens_irq_data *d)
-{
- int ret;
-
- ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
- if (ret)
- return ret;
- if (tsens_version(priv) > VER_1_X) {
- ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
- &d->crit_irq_clear);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
- &d->crit_irq_mask);
- if (ret)
- return ret;
-
- d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
- } else {
- /* No mask register on older TSENS */
- d->up_irq_mask = 0;
- d->low_irq_mask = 0;
- d->crit_irq_clear = 0;
- d->crit_irq_mask = 0;
- d->crit_thresh = 0;
- }
-
- d->up_thresh = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);
- d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);
-
- dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",
- hw_id, __func__,
- (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
- d->low_viol, d->up_viol, d->crit_viol,
- d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,
- d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);
- dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,
- (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
- d->low_thresh, d->up_thresh, d->crit_thresh);
-
- return 0;
-}
-
-static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
-{
- if (ver > VER_1_X)
- return mask & (1 << hw_id);
-
- /* v1, v0.1 don't have a irq mask register */
- return 0;
-}
-
-/**
- * tsens_critical_irq_thread() - Threaded handler for critical interrupts
- * @irq: irq number
- * @data: tsens controller private data
- *
- * Check FSM watchdog bark status and clear if needed.
- * Check all sensors to find ones that violated their critical threshold limits.
- * Clear and then re-enable the interrupt.
- *
- * The level-triggered interrupt might deassert if the temperature returned to
- * within the threshold limits by the time the handler got scheduled. We
- * consider the irq to have been handled in that case.
- *
- * Return: IRQ_HANDLED
- */
-irqreturn_t tsens_critical_irq_thread(int irq, void *data)
-{
- struct tsens_priv *priv = data;
- struct tsens_irq_data d;
- int temp, ret, i;
- u32 wdog_status, wdog_count;
-
- if (priv->feat->has_watchdog) {
- ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],
- &wdog_status);
- if (ret)
- return ret;
-
- if (wdog_status) {
- /* Clear WDOG interrupt */
- regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);
- regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);
- ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],
- &wdog_count);
- if (ret)
- return ret;
- if (wdog_count)
- dev_dbg(priv->dev, "%s: watchdog count: %d\n",
- __func__, wdog_count);
-
- /* Fall through to handle critical interrupts if any */
- }
- }
-
- for (i = 0; i < priv->num_sensors; i++) {
- const struct tsens_sensor *s = &priv->sensor[i];
- u32 hw_id = s->hw_id;
-
- if (IS_ERR(s->tzd))
- continue;
- if (!tsens_threshold_violated(priv, hw_id, &d))
- continue;
- ret = get_temp_tsens_valid(s, &temp);
- if (ret) {
- dev_err(priv->dev, "[%u] %s: error reading sensor\n",
- hw_id, __func__);
- continue;
- }
-
- tsens_read_irq_state(priv, hw_id, s, &d);
- if (d.crit_viol &&
- !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {
- /* Mask critical interrupts, unused on Linux */
- tsens_set_interrupt(priv, hw_id, CRITICAL, false);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-/**
- * tsens_irq_thread - Threaded interrupt handler for uplow interrupts
- * @irq: irq number
- * @data: tsens controller private data
- *
- * Check all sensors to find ones that violated their threshold limits. If the
- * temperature is still outside the limits, call thermal_zone_device_update() to
- * update the thresholds, else re-enable the interrupts.
- *
- * The level-triggered interrupt might deassert if the temperature returned to
- * within the threshold limits by the time the handler got scheduled. We
- * consider the irq to have been handled in that case.
- *
- * Return: IRQ_HANDLED
- */
-irqreturn_t tsens_irq_thread(int irq, void *data)
-{
- struct tsens_priv *priv = data;
- struct tsens_irq_data d;
- bool enable = true, disable = false;
- unsigned long flags;
- int temp, ret, i;
-
- for (i = 0; i < priv->num_sensors; i++) {
- bool trigger = false;
- const struct tsens_sensor *s = &priv->sensor[i];
- u32 hw_id = s->hw_id;
-
- if (IS_ERR(s->tzd))
- continue;
- if (!tsens_threshold_violated(priv, hw_id, &d))
- continue;
- ret = get_temp_tsens_valid(s, &temp);
- if (ret) {
- dev_err(priv->dev, "[%u] %s: error reading sensor\n", hw_id, __func__);
- continue;
- }
-
- spin_lock_irqsave(&priv->ul_lock, flags);
-
- tsens_read_irq_state(priv, hw_id, s, &d);
-
- if (d.up_viol &&
- !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) {
- tsens_set_interrupt(priv, hw_id, UPPER, disable);
- if (d.up_thresh > temp) {
- dev_dbg(priv->dev, "[%u] %s: re-arm upper\n",
- hw_id, __func__);
- tsens_set_interrupt(priv, hw_id, UPPER, enable);
- } else {
- trigger = true;
- /* Keep irq masked */
- }
- } else if (d.low_viol &&
- !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) {
- tsens_set_interrupt(priv, hw_id, LOWER, disable);
- if (d.low_thresh < temp) {
- dev_dbg(priv->dev, "[%u] %s: re-arm low\n",
- hw_id, __func__);
- tsens_set_interrupt(priv, hw_id, LOWER, enable);
- } else {
- trigger = true;
- /* Keep irq masked */
- }
- }
-
- spin_unlock_irqrestore(&priv->ul_lock, flags);
-
- if (trigger) {
- dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n",
- hw_id, __func__, temp);
- thermal_zone_device_update(s->tzd,
- THERMAL_EVENT_UNSPECIFIED);
- } else {
- dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
- hw_id, __func__, temp);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-int tsens_set_trips(void *_sensor, int low, int high)
-{
- struct tsens_sensor *s = _sensor;
- struct tsens_priv *priv = s->priv;
- struct device *dev = priv->dev;
- struct tsens_irq_data d;
- unsigned long flags;
- int high_val, low_val, cl_high, cl_low;
- u32 hw_id = s->hw_id;
-
- dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
- hw_id, __func__, low, high);
-
- cl_high = clamp_val(high, -40000, 120000);
- cl_low = clamp_val(low, -40000, 120000);
-
- high_val = tsens_mC_to_hw(s, cl_high);
- low_val = tsens_mC_to_hw(s, cl_low);
-
- spin_lock_irqsave(&priv->ul_lock, flags);
-
- tsens_read_irq_state(priv, hw_id, s, &d);
-
- /* Write the new thresholds and clear the status */
- regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
- regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
- tsens_set_interrupt(priv, hw_id, LOWER, true);
- tsens_set_interrupt(priv, hw_id, UPPER, true);
-
- spin_unlock_irqrestore(&priv->ul_lock, flags);
-
- dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
- hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);
-
- return 0;
-}
-
-int tsens_enable_irq(struct tsens_priv *priv)
-{
- int ret;
- int val = tsens_version(priv) > VER_1_X ? 7 : 1;
-
- ret = regmap_field_write(priv->rf[INT_EN], val);
- if (ret < 0)
- dev_err(priv->dev, "%s: failed to enable interrupts\n", __func__);
-
- return ret;
-}
-
-void tsens_disable_irq(struct tsens_priv *priv)
-{
- regmap_field_write(priv->rf[INT_EN], 0);
-}
-
-int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
-{
- struct tsens_priv *priv = s->priv;
- int hw_id = s->hw_id;
- u32 temp_idx = LAST_TEMP_0 + hw_id;
- u32 valid_idx = VALID_0 + hw_id;
- u32 valid;
- int ret;
-
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- while (!valid) {
- /* Valid bit is 0 for 6 AHB clock cycles.
- * At 19.2MHz, 1 AHB clock is ~60ns.
- * We should enter this loop very, very rarely.
- */
- ndelay(400);
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- }
-
- /* Valid bit is set, OK to read the temperature */
- *temp = tsens_hw_to_mC(s, temp_idx);
-
- return 0;
-}
-
-int get_temp_common(const struct tsens_sensor *s, int *temp)
-{
- struct tsens_priv *priv = s->priv;
- int hw_id = s->hw_id;
- int last_temp = 0, ret;
-
- ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
- if (ret)
- return ret;
-
- *temp = code_to_degc(last_temp, s) * 1000;
-
- return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int dbg_sensors_show(struct seq_file *s, void *data)
-{
- struct platform_device *pdev = s->private;
- struct tsens_priv *priv = platform_get_drvdata(pdev);
- int i;
-
- seq_printf(s, "max: %2d\nnum: %2d\n\n",
- priv->feat->max_sensors, priv->num_sensors);
-
- seq_puts(s, " id slope offset\n--------------------------\n");
- for (i = 0; i < priv->num_sensors; i++) {
- seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
- priv->sensor[i].slope, priv->sensor[i].offset);
- }
-
- return 0;
-}
-
-static int dbg_version_show(struct seq_file *s, void *data)
-{
- struct platform_device *pdev = s->private;
- struct tsens_priv *priv = platform_get_drvdata(pdev);
- u32 maj_ver, min_ver, step_ver;
- int ret;
-
- if (tsens_version(priv) > VER_0_1) {
- ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
- if (ret)
- return ret;
- seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
- } else {
- seq_puts(s, "0.1.0\n");
- }
-
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(dbg_version);
-DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
-
-static void tsens_debug_init(struct platform_device *pdev)
-{
- struct tsens_priv *priv = platform_get_drvdata(pdev);
- struct dentry *root, *file;
-
- root = debugfs_lookup("tsens", NULL);
- if (!root)
- priv->debug_root = debugfs_create_dir("tsens", NULL);
- else
- priv->debug_root = root;
-
- file = debugfs_lookup("version", priv->debug_root);
- if (!file)
- debugfs_create_file("version", 0444, priv->debug_root,
- pdev, &dbg_version_fops);
-
- /* A directory for each instance of the TSENS IP */
- priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
- debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
-}
-#else
-static inline void tsens_debug_init(struct platform_device *pdev) {}
-#endif
-
-static const struct regmap_config tsens_config = {
- .name = "tm",
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
-};
-
-static const struct regmap_config tsens_srot_config = {
- .name = "srot",
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
-};
-
-int __init init_common(struct tsens_priv *priv)
-{
- void __iomem *tm_base, *srot_base;
- struct device *dev = priv->dev;
- u32 ver_minor;
- struct resource *res;
- u32 enabled;
- int ret, i, j;
- struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
-
- if (!op)
- return -EINVAL;
-
- if (op->num_resources > 1) {
- /* DT with separate SROT and TM address space */
- priv->tm_offset = 0;
- res = platform_get_resource(op, IORESOURCE_MEM, 1);
- srot_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(srot_base)) {
- ret = PTR_ERR(srot_base);
- goto err_put_device;
- }
-
- priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
- &tsens_srot_config);
- if (IS_ERR(priv->srot_map)) {
- ret = PTR_ERR(priv->srot_map);
- goto err_put_device;
- }
- } else {
- /* old DTs where SROT and TM were in a contiguous 2K block */
- priv->tm_offset = 0x1000;
- }
-
- res = platform_get_resource(op, IORESOURCE_MEM, 0);
- tm_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(tm_base)) {
- ret = PTR_ERR(tm_base);
- goto err_put_device;
- }
-
- priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
- if (IS_ERR(priv->tm_map)) {
- ret = PTR_ERR(priv->tm_map);
- goto err_put_device;
- }
-
- if (tsens_version(priv) > VER_0_1) {
- for (i = VER_MAJOR; i <= VER_STEP; i++) {
- priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
- priv->fields[i]);
- if (IS_ERR(priv->rf[i]))
- return PTR_ERR(priv->rf[i]);
- }
- ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
- if (ret)
- goto err_put_device;
- }
-
- priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
- priv->fields[TSENS_EN]);
- if (IS_ERR(priv->rf[TSENS_EN])) {
- ret = PTR_ERR(priv->rf[TSENS_EN]);
- goto err_put_device;
- }
- ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
- if (ret)
- goto err_put_device;
- if (!enabled) {
- dev_err(dev, "%s: device not enabled\n", __func__);
- ret = -ENODEV;
- goto err_put_device;
- }
-
- priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
- priv->fields[SENSOR_EN]);
- if (IS_ERR(priv->rf[SENSOR_EN])) {
- ret = PTR_ERR(priv->rf[SENSOR_EN]);
- goto err_put_device;
- }
- priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
- priv->fields[INT_EN]);
- if (IS_ERR(priv->rf[INT_EN])) {
- ret = PTR_ERR(priv->rf[INT_EN]);
- goto err_put_device;
- }
-
- /* This loop might need changes if enum regfield_ids is reordered */
- for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
- for (i = 0; i < priv->feat->max_sensors; i++) {
- int idx = j + i;
-
- priv->rf[idx] = devm_regmap_field_alloc(dev, priv->tm_map,
- priv->fields[idx]);
- if (IS_ERR(priv->rf[idx])) {
- ret = PTR_ERR(priv->rf[idx]);
- goto err_put_device;
- }
- }
- }
-
- if (priv->feat->crit_int) {
- /* Loop might need changes if enum regfield_ids is reordered */
- for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
- for (i = 0; i < priv->feat->max_sensors; i++) {
- int idx = j + i;
-
- priv->rf[idx] =
- devm_regmap_field_alloc(dev,
- priv->tm_map,
- priv->fields[idx]);
- if (IS_ERR(priv->rf[idx])) {
- ret = PTR_ERR(priv->rf[idx]);
- goto err_put_device;
- }
- }
- }
- }
-
- if (tsens_version(priv) > VER_1_X && ver_minor > 2) {
- /* Watchdog is present only on v2.3+ */
- priv->feat->has_watchdog = 1;
- for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
- priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,
- priv->fields[i]);
- if (IS_ERR(priv->rf[i])) {
- ret = PTR_ERR(priv->rf[i]);
- goto err_put_device;
- }
- }
- /*
- * Watchdog is already enabled, unmask the bark.
- * Disable cycle completion monitoring
- */
- regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);
- regmap_field_write(priv->rf[CC_MON_MASK], 1);
- }
-
- spin_lock_init(&priv->ul_lock);
- tsens_enable_irq(priv);
- tsens_debug_init(op);
-
-err_put_device:
- put_device(&op->dev);
- return ret;
-}
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 2f77d235cf73..8d3e94d2a9ed 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -1,19 +1,857 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, 2020, Linaro Ltd.
*/
#include <linux/debugfs.h>
#include <linux/err.h>
+#include <linux/io.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include "tsens.h"
+/**
+ * struct tsens_irq_data - IRQ status and temperature violations
+ * @up_viol: upper threshold violated
+ * @up_thresh: upper threshold temperature value
+ * @up_irq_mask: mask register for upper threshold irqs
+ * @up_irq_clear: clear register for uppper threshold irqs
+ * @low_viol: lower threshold violated
+ * @low_thresh: lower threshold temperature value
+ * @low_irq_mask: mask register for lower threshold irqs
+ * @low_irq_clear: clear register for lower threshold irqs
+ * @crit_viol: critical threshold violated
+ * @crit_thresh: critical threshold temperature value
+ * @crit_irq_mask: mask register for critical threshold irqs
+ * @crit_irq_clear: clear register for critical threshold irqs
+ *
+ * Structure containing data about temperature threshold settings and
+ * irq status if they were violated.
+ */
+struct tsens_irq_data {
+ u32 up_viol;
+ int up_thresh;
+ u32 up_irq_mask;
+ u32 up_irq_clear;
+ u32 low_viol;
+ int low_thresh;
+ u32 low_irq_mask;
+ u32 low_irq_clear;
+ u32 crit_viol;
+ u32 crit_thresh;
+ u32 crit_irq_mask;
+ u32 crit_irq_clear;
+};
+
+char *qfprom_read(struct device *dev, const char *cname)
+{
+ struct nvmem_cell *cell;
+ ssize_t data;
+ char *ret;
+
+ cell = nvmem_cell_get(dev, cname);
+ if (IS_ERR(cell))
+ return ERR_CAST(cell);
+
+ ret = nvmem_cell_read(cell, &data);
+ nvmem_cell_put(cell);
+
+ return ret;
+}
+
+/*
+ * Use this function on devices where slope and offset calculations
+ * depend on calibration data read from qfprom. On others the slope
+ * and offset values are derived from tz->tzp->slope and tz->tzp->offset
+ * resp.
+ */
+void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
+ u32 *p2, u32 mode)
+{
+ int i;
+ int num, den;
+
+ for (i = 0; i < priv->num_sensors; i++) {
+ dev_dbg(priv->dev,
+ "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
+ __func__, i, p1[i], p2[i]);
+
+ priv->sensor[i].slope = SLOPE_DEFAULT;
+ if (mode == TWO_PT_CALIB) {
+ /*
+ * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+ * temp_120_degc - temp_30_degc (x2 - x1)
+ */
+ num = p2[i] - p1[i];
+ num *= SLOPE_FACTOR;
+ den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
+ priv->sensor[i].slope = num / den;
+ }
+
+ priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
+ (CAL_DEGC_PT1 *
+ priv->sensor[i].slope);
+ dev_dbg(priv->dev, "%s: offset:%d\n", __func__,
+ priv->sensor[i].offset);
+ }
+}
+
+static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)
+{
+ u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);
+
+ pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
+ return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
+}
+
+static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
+{
+ int degc, num, den;
+
+ num = (adc_code * SLOPE_FACTOR) - s->offset;
+ den = s->slope;
+
+ if (num > 0)
+ degc = num + (den / 2);
+ else if (num < 0)
+ degc = num - (den / 2);
+ else
+ degc = num;
+
+ degc /= den;
+
+ return degc;
+}
+
+/**
+ * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.
+ * @s: Pointer to sensor struct
+ * @field: Index into regmap_field array pointing to temperature data
+ *
+ * This function handles temperature returned in ADC code or deciCelsius
+ * depending on IP version.
+ *
+ * Return: Temperature in milliCelsius on success, a negative errno will
+ * be returned in error cases
+ */
+static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)
+{
+ struct tsens_priv *priv = s->priv;
+ u32 resolution;
+ u32 temp = 0;
+ int ret;
+
+ resolution = priv->fields[LAST_TEMP_0].msb -
+ priv->fields[LAST_TEMP_0].lsb;
+
+ ret = regmap_field_read(priv->rf[field], &temp);
+ if (ret)
+ return ret;
+
+ /* Convert temperature from ADC code to milliCelsius */
+ if (priv->feat->adc)
+ return code_to_degc(temp, s) * 1000;
+
+ /* deciCelsius -> milliCelsius along with sign extension */
+ return sign_extend32(temp, resolution) * 100;
+}
+
+/**
+ * tsens_mC_to_hw - Convert temperature to hardware register value
+ * @s: Pointer to sensor struct
+ * @temp: temperature in milliCelsius to be programmed to hardware
+ *
+ * This function outputs the value to be written to hardware in ADC code
+ * or deciCelsius depending on IP version.
+ *
+ * Return: ADC code or temperature in deciCelsius.
+ */
+static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)
+{
+ struct tsens_priv *priv = s->priv;
+
+ /* milliC to adc code */
+ if (priv->feat->adc)
+ return degc_to_code(temp / 1000, s);
+
+ /* milliC to deciC */
+ return temp / 100;
+}
+
+static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
+{
+ return priv->feat->ver_major;
+}
+
+static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
+ enum tsens_irq_type irq_type, bool enable)
+{
+ u32 index = 0;
+
+ switch (irq_type) {
+ case UPPER:
+ index = UP_INT_CLEAR_0 + hw_id;
+ break;
+ case LOWER:
+ index = LOW_INT_CLEAR_0 + hw_id;
+ break;
+ case CRITICAL:
+ /* No critical interrupts before v2 */
+ return;
+ }
+ regmap_field_write(priv->rf[index], enable ? 0 : 1);
+}
+
+static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
+ enum tsens_irq_type irq_type, bool enable)
+{
+ u32 index_mask = 0, index_clear = 0;
+
+ /*
+ * To enable the interrupt flag for a sensor:
+ * - clear the mask bit
+ * To disable the interrupt flag for a sensor:
+ * - Mask further interrupts for this sensor
+ * - Write 1 followed by 0 to clear the interrupt
+ */
+ switch (irq_type) {
+ case UPPER:
+ index_mask = UP_INT_MASK_0 + hw_id;
+ index_clear = UP_INT_CLEAR_0 + hw_id;
+ break;
+ case LOWER:
+ index_mask = LOW_INT_MASK_0 + hw_id;
+ index_clear = LOW_INT_CLEAR_0 + hw_id;
+ break;
+ case CRITICAL:
+ index_mask = CRIT_INT_MASK_0 + hw_id;
+ index_clear = CRIT_INT_CLEAR_0 + hw_id;
+ break;
+ }
+
+ if (enable) {
+ regmap_field_write(priv->rf[index_mask], 0);
+ } else {
+ regmap_field_write(priv->rf[index_mask], 1);
+ regmap_field_write(priv->rf[index_clear], 1);
+ regmap_field_write(priv->rf[index_clear], 0);
+ }
+}
+
+/**
+ * tsens_set_interrupt - Set state of an interrupt
+ * @priv: Pointer to tsens controller private data
+ * @hw_id: Hardware ID aka. sensor number
+ * @irq_type: irq_type from enum tsens_irq_type
+ * @enable: false = disable, true = enable
+ *
+ * Call IP-specific function to set state of an interrupt
+ *
+ * Return: void
+ */
+static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
+ enum tsens_irq_type irq_type, bool enable)
+{
+ dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
+ irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
+ enable ? "en" : "dis");
+ if (tsens_version(priv) > VER_1_X)
+ tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
+ else
+ tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
+}
+
+/**
+ * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold
+ * @priv: Pointer to tsens controller private data
+ * @hw_id: Hardware ID aka. sensor number
+ * @d: Pointer to irq state data
+ *
+ * Return: 0 if threshold was not violated, 1 if it was violated and negative
+ * errno in case of errors
+ */
+static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,
+ struct tsens_irq_data *d)
+{
+ int ret;
+
+ ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);
+ if (ret)
+ return ret;
+
+ if (priv->feat->crit_int) {
+ ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],
+ &d->crit_viol);
+ if (ret)
+ return ret;
+ }
+
+ if (d->up_viol || d->low_viol || d->crit_viol)
+ return 1;
+
+ return 0;
+}
+
+static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
+ const struct tsens_sensor *s,
+ struct tsens_irq_data *d)
+{
+ int ret;
+
+ ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
+ if (ret)
+ return ret;
+ if (tsens_version(priv) > VER_1_X) {
+ ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
+ &d->crit_irq_clear);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
+ &d->crit_irq_mask);
+ if (ret)
+ return ret;
+
+ d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
+ } else {
+ /* No mask register on older TSENS */
+ d->up_irq_mask = 0;
+ d->low_irq_mask = 0;
+ d->crit_irq_clear = 0;
+ d->crit_irq_mask = 0;
+ d->crit_thresh = 0;
+ }
+
+ d->up_thresh = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);
+ d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);
+
+ dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",
+ hw_id, __func__,
+ (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
+ d->low_viol, d->up_viol, d->crit_viol,
+ d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,
+ d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);
+ dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,
+ (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
+ d->low_thresh, d->up_thresh, d->crit_thresh);
+
+ return 0;
+}
+
+static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
+{
+ if (ver > VER_1_X)
+ return mask & (1 << hw_id);
+
+ /* v1, v0.1 don't have a irq mask register */
+ return 0;
+}
+
+/**
+ * tsens_critical_irq_thread() - Threaded handler for critical interrupts
+ * @irq: irq number
+ * @data: tsens controller private data
+ *
+ * Check FSM watchdog bark status and clear if needed.
+ * Check all sensors to find ones that violated their critical threshold limits.
+ * Clear and then re-enable the interrupt.
+ *
+ * The level-triggered interrupt might deassert if the temperature returned to
+ * within the threshold limits by the time the handler got scheduled. We
+ * consider the irq to have been handled in that case.
+ *
+ * Return: IRQ_HANDLED
+ */
+irqreturn_t tsens_critical_irq_thread(int irq, void *data)
+{
+ struct tsens_priv *priv = data;
+ struct tsens_irq_data d;
+ int temp, ret, i;
+ u32 wdog_status, wdog_count;
+
+ if (priv->feat->has_watchdog) {
+ ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],
+ &wdog_status);
+ if (ret)
+ return ret;
+
+ if (wdog_status) {
+ /* Clear WDOG interrupt */
+ regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);
+ regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);
+ ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],
+ &wdog_count);
+ if (ret)
+ return ret;
+ if (wdog_count)
+ dev_dbg(priv->dev, "%s: watchdog count: %d\n",
+ __func__, wdog_count);
+
+ /* Fall through to handle critical interrupts if any */
+ }
+ }
+
+ for (i = 0; i < priv->num_sensors; i++) {
+ const struct tsens_sensor *s = &priv->sensor[i];
+ u32 hw_id = s->hw_id;
+
+ if (IS_ERR(s->tzd))
+ continue;
+ if (!tsens_threshold_violated(priv, hw_id, &d))
+ continue;
+ ret = get_temp_tsens_valid(s, &temp);
+ if (ret) {
+ dev_err(priv->dev, "[%u] %s: error reading sensor\n",
+ hw_id, __func__);
+ continue;
+ }
+
+ tsens_read_irq_state(priv, hw_id, s, &d);
+ if (d.crit_viol &&
+ !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {
+ /* Mask critical interrupts, unused on Linux */
+ tsens_set_interrupt(priv, hw_id, CRITICAL, false);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * tsens_irq_thread - Threaded interrupt handler for uplow interrupts
+ * @irq: irq number
+ * @data: tsens controller private data
+ *
+ * Check all sensors to find ones that violated their threshold limits. If the
+ * temperature is still outside the limits, call thermal_zone_device_update() to
+ * update the thresholds, else re-enable the interrupts.
+ *
+ * The level-triggered interrupt might deassert if the temperature returned to
+ * within the threshold limits by the time the handler got scheduled. We
+ * consider the irq to have been handled in that case.
+ *
+ * Return: IRQ_HANDLED
+ */
+irqreturn_t tsens_irq_thread(int irq, void *data)
+{
+ struct tsens_priv *priv = data;
+ struct tsens_irq_data d;
+ bool enable = true, disable = false;
+ unsigned long flags;
+ int temp, ret, i;
+
+ for (i = 0; i < priv->num_sensors; i++) {
+ bool trigger = false;
+ const struct tsens_sensor *s = &priv->sensor[i];
+ u32 hw_id = s->hw_id;
+
+ if (IS_ERR(s->tzd))
+ continue;
+ if (!tsens_threshold_violated(priv, hw_id, &d))
+ continue;
+ ret = get_temp_tsens_valid(s, &temp);
+ if (ret) {
+ dev_err(priv->dev, "[%u] %s: error reading sensor\n",
+ hw_id, __func__);
+ continue;
+ }
+
+ spin_lock_irqsave(&priv->ul_lock, flags);
+
+ tsens_read_irq_state(priv, hw_id, s, &d);
+
+ if (d.up_viol &&
+ !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) {
+ tsens_set_interrupt(priv, hw_id, UPPER, disable);
+ if (d.up_thresh > temp) {
+ dev_dbg(priv->dev, "[%u] %s: re-arm upper\n",
+ hw_id, __func__);
+ tsens_set_interrupt(priv, hw_id, UPPER, enable);
+ } else {
+ trigger = true;
+ /* Keep irq masked */
+ }
+ } else if (d.low_viol &&
+ !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) {
+ tsens_set_interrupt(priv, hw_id, LOWER, disable);
+ if (d.low_thresh < temp) {
+ dev_dbg(priv->dev, "[%u] %s: re-arm low\n",
+ hw_id, __func__);
+ tsens_set_interrupt(priv, hw_id, LOWER, enable);
+ } else {
+ trigger = true;
+ /* Keep irq masked */
+ }
+ }
+
+ spin_unlock_irqrestore(&priv->ul_lock, flags);
+
+ if (trigger) {
+ dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n",
+ hw_id, __func__, temp);
+ thermal_zone_device_update(s->tzd,
+ THERMAL_EVENT_UNSPECIFIED);
+ } else {
+ dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
+ hw_id, __func__, temp);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+int tsens_set_trips(void *_sensor, int low, int high)
+{
+ struct tsens_sensor *s = _sensor;
+ struct tsens_priv *priv = s->priv;
+ struct device *dev = priv->dev;
+ struct tsens_irq_data d;
+ unsigned long flags;
+ int high_val, low_val, cl_high, cl_low;
+ u32 hw_id = s->hw_id;
+
+ dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
+ hw_id, __func__, low, high);
+
+ cl_high = clamp_val(high, -40000, 120000);
+ cl_low = clamp_val(low, -40000, 120000);
+
+ high_val = tsens_mC_to_hw(s, cl_high);
+ low_val = tsens_mC_to_hw(s, cl_low);
+
+ spin_lock_irqsave(&priv->ul_lock, flags);
+
+ tsens_read_irq_state(priv, hw_id, s, &d);
+
+ /* Write the new thresholds and clear the status */
+ regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
+ regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
+ tsens_set_interrupt(priv, hw_id, LOWER, true);
+ tsens_set_interrupt(priv, hw_id, UPPER, true);
+
+ spin_unlock_irqrestore(&priv->ul_lock, flags);
+
+ dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
+ hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);
+
+ return 0;
+}
+
+int tsens_enable_irq(struct tsens_priv *priv)
+{
+ int ret;
+ int val = tsens_version(priv) > VER_1_X ? 7 : 1;
+
+ ret = regmap_field_write(priv->rf[INT_EN], val);
+ if (ret < 0)
+ dev_err(priv->dev, "%s: failed to enable interrupts\n",
+ __func__);
+
+ return ret;
+}
+
+void tsens_disable_irq(struct tsens_priv *priv)
+{
+ regmap_field_write(priv->rf[INT_EN], 0);
+}
+
+int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
+{
+ struct tsens_priv *priv = s->priv;
+ int hw_id = s->hw_id;
+ u32 temp_idx = LAST_TEMP_0 + hw_id;
+ u32 valid_idx = VALID_0 + hw_id;
+ u32 valid;
+ int ret;
+
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
+ while (!valid) {
+ /* Valid bit is 0 for 6 AHB clock cycles.
+ * At 19.2MHz, 1 AHB clock is ~60ns.
+ * We should enter this loop very, very rarely.
+ */
+ ndelay(400);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
+ }
+
+ /* Valid bit is set, OK to read the temperature */
+ *temp = tsens_hw_to_mC(s, temp_idx);
+
+ return 0;
+}
+
+int get_temp_common(const struct tsens_sensor *s, int *temp)
+{
+ struct tsens_priv *priv = s->priv;
+ int hw_id = s->hw_id;
+ int last_temp = 0, ret;
+
+ ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
+ if (ret)
+ return ret;
+
+ *temp = code_to_degc(last_temp, s) * 1000;
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int dbg_sensors_show(struct seq_file *s, void *data)
+{
+ struct platform_device *pdev = s->private;
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
+ int i;
+
+ seq_printf(s, "max: %2d\nnum: %2d\n\n",
+ priv->feat->max_sensors, priv->num_sensors);
+
+ seq_puts(s, " id slope offset\n--------------------------\n");
+ for (i = 0; i < priv->num_sensors; i++) {
+ seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
+ priv->sensor[i].slope, priv->sensor[i].offset);
+ }
+
+ return 0;
+}
+
+static int dbg_version_show(struct seq_file *s, void *data)
+{
+ struct platform_device *pdev = s->private;
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
+ u32 maj_ver, min_ver, step_ver;
+ int ret;
+
+ if (tsens_version(priv) > VER_0_1) {
+ ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
+ if (ret)
+ return ret;
+ seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
+ } else {
+ seq_puts(s, "0.1.0\n");
+ }
+
+ return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(dbg_version);
+DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
+
+static void tsens_debug_init(struct platform_device *pdev)
+{
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
+ struct dentry *root, *file;
+
+ root = debugfs_lookup("tsens", NULL);
+ if (!root)
+ priv->debug_root = debugfs_create_dir("tsens", NULL);
+ else
+ priv->debug_root = root;
+
+ file = debugfs_lookup("version", priv->debug_root);
+ if (!file)
+ debugfs_create_file("version", 0444, priv->debug_root,
+ pdev, &dbg_version_fops);
+
+ /* A directory for each instance of the TSENS IP */
+ priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
+ debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
+}
+#else
+static inline void tsens_debug_init(struct platform_device *pdev) {}
+#endif
+
+static const struct regmap_config tsens_config = {
+ .name = "tm",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static const struct regmap_config tsens_srot_config = {
+ .name = "srot",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+int __init init_common(struct tsens_priv *priv)
+{
+ void __iomem *tm_base, *srot_base;
+ struct device *dev = priv->dev;
+ u32 ver_minor;
+ struct resource *res;
+ u32 enabled;
+ int ret, i, j;
+ struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
+
+ if (!op)
+ return -EINVAL;
+
+ if (op->num_resources > 1) {
+ /* DT with separate SROT and TM address space */
+ priv->tm_offset = 0;
+ res = platform_get_resource(op, IORESOURCE_MEM, 1);
+ srot_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(srot_base)) {
+ ret = PTR_ERR(srot_base);
+ goto err_put_device;
+ }
+
+ priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
+ &tsens_srot_config);
+ if (IS_ERR(priv->srot_map)) {
+ ret = PTR_ERR(priv->srot_map);
+ goto err_put_device;
+ }
+ } else {
+ /* old DTs where SROT and TM were in a contiguous 2K block */
+ priv->tm_offset = 0x1000;
+ }
+
+ res = platform_get_resource(op, IORESOURCE_MEM, 0);
+ tm_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(tm_base)) {
+ ret = PTR_ERR(tm_base);
+ goto err_put_device;
+ }
+
+ priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
+ if (IS_ERR(priv->tm_map)) {
+ ret = PTR_ERR(priv->tm_map);
+ goto err_put_device;
+ }
+
+ if (tsens_version(priv) > VER_0_1) {
+ for (i = VER_MAJOR; i <= VER_STEP; i++) {
+ priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
+ priv->fields[i]);
+ if (IS_ERR(priv->rf[i]))
+ return PTR_ERR(priv->rf[i]);
+ }
+ ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
+ if (ret)
+ goto err_put_device;
+ }
+
+ priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
+ priv->fields[TSENS_EN]);
+ if (IS_ERR(priv->rf[TSENS_EN])) {
+ ret = PTR_ERR(priv->rf[TSENS_EN]);
+ goto err_put_device;
+ }
+ ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
+ if (ret)
+ goto err_put_device;
+ if (!enabled) {
+ dev_err(dev, "%s: device not enabled\n", __func__);
+ ret = -ENODEV;
+ goto err_put_device;
+ }
+
+ priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
+ priv->fields[SENSOR_EN]);
+ if (IS_ERR(priv->rf[SENSOR_EN])) {
+ ret = PTR_ERR(priv->rf[SENSOR_EN]);
+ goto err_put_device;
+ }
+ priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
+ priv->fields[INT_EN]);
+ if (IS_ERR(priv->rf[INT_EN])) {
+ ret = PTR_ERR(priv->rf[INT_EN]);
+ goto err_put_device;
+ }
+
+ /* This loop might need changes if enum regfield_ids is reordered */
+ for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
+ for (i = 0; i < priv->feat->max_sensors; i++) {
+ int idx = j + i;
+
+ priv->rf[idx] = devm_regmap_field_alloc(dev,
+ priv->tm_map,
+ priv->fields[idx]);
+ if (IS_ERR(priv->rf[idx])) {
+ ret = PTR_ERR(priv->rf[idx]);
+ goto err_put_device;
+ }
+ }
+ }
+
+ if (priv->feat->crit_int) {
+ /* Loop might need changes if enum regfield_ids is reordered */
+ for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
+ for (i = 0; i < priv->feat->max_sensors; i++) {
+ int idx = j + i;
+
+ priv->rf[idx] =
+ devm_regmap_field_alloc(dev,
+ priv->tm_map,
+ priv->fields[idx]);
+ if (IS_ERR(priv->rf[idx])) {
+ ret = PTR_ERR(priv->rf[idx]);
+ goto err_put_device;
+ }
+ }
+ }
+ }
+
+ if (tsens_version(priv) > VER_1_X && ver_minor > 2) {
+ /* Watchdog is present only on v2.3+ */
+ priv->feat->has_watchdog = 1;
+ for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
+ priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,
+ priv->fields[i]);
+ if (IS_ERR(priv->rf[i])) {
+ ret = PTR_ERR(priv->rf[i]);
+ goto err_put_device;
+ }
+ }
+ /*
+ * Watchdog is already enabled, unmask the bark.
+ * Disable cycle completion monitoring
+ */
+ regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);
+ regmap_field_write(priv->rf[CC_MON_MASK], 1);
+ }
+
+ spin_lock_init(&priv->ul_lock);
+ tsens_enable_irq(priv);
+ tsens_debug_init(op);
+
+err_put_device:
+ put_device(&op->dev);
+ return ret;
+}
+
static int tsens_get_temp(void *data, int *temp)
{
struct tsens_sensor *s = data;
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 502acf0e6828..59d01162c66a 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -580,11 +580,6 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo
int init_common(struct tsens_priv *priv);
int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp);
int get_temp_common(const struct tsens_sensor *s, int *temp);
-int tsens_enable_irq(struct tsens_priv *priv);
-void tsens_disable_irq(struct tsens_priv *priv);
-int tsens_set_trips(void *_sensor, int low, int high);
-irqreturn_t tsens_irq_thread(int irq, void *data);
-irqreturn_t tsens_critical_irq_thread(int irq, void *data);
/* TSENS target */
extern struct tsens_plat_data data_8960;
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c
index 028a6bbf75dc..73049f9bea25 100644
--- a/drivers/thermal/qoriq_thermal.c
+++ b/drivers/thermal/qoriq_thermal.c
@@ -11,6 +11,7 @@
#include <linux/regmap.h>
#include <linux/sizes.h>
#include <linux/thermal.h>
+#include <linux/units.h>
#include "thermal_core.h"
#include "thermal_hwmon.h"
@@ -23,6 +24,7 @@
#define TMTMIR_DEFAULT 0x0000000f
#define TIER_DISABLE 0x0
#define TEUMR0_V2 0x51009c00
+#define TMSARA_V2 0xe
#define TMU_VER1 0x1
#define TMU_VER2 0x2
@@ -50,6 +52,9 @@
* Site Register
*/
#define TRITSR_V BIT(31)
+#define REGS_V2_TMSAR(n) (0x304 + 16 * (n)) /* TMU monitoring
+ * site adjustment register
+ */
#define REGS_TTRnCR(n) (0xf10 + 4 * (n)) /* Temperature Range n
* Control Register
*/
@@ -85,12 +90,21 @@ static int tmu_get_temp(void *p, int *temp)
/*
* REGS_TRITSR(id) has the following layout:
*
+ * For TMU Rev1:
* 31 ... 7 6 5 4 3 2 1 0
* V TEMP
*
* Where V bit signifies if the measurement is ready and is
* within sensor range. TEMP is an 8 bit value representing
- * temperature in C.
+ * temperature in Celsius.
+
+ * For TMU Rev2:
+ * 31 ... 8 7 6 5 4 3 2 1 0
+ * V TEMP
+ *
+ * Where V bit signifies if the measurement is ready and is
+ * within sensor range. TEMP is an 9 bit value representing
+ * temperature in KelVin.
*/
if (regmap_read_poll_timeout(qdata->regmap,
REGS_TRITSR(qsensor->id),
@@ -100,7 +114,10 @@ static int tmu_get_temp(void *p, int *temp)
10 * USEC_PER_MSEC))
return -ENODATA;
- *temp = (val & 0xff) * 1000;
+ if (qdata->ver == TMU_VER1)
+ *temp = (val & GENMASK(7, 0)) * MILLIDEGREE_PER_DEGREE;
+ else
+ *temp = kelvin_to_millicelsius(val & GENMASK(8, 0));
return 0;
}
@@ -192,6 +209,8 @@ static int qoriq_tmu_calibration(struct device *dev,
static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
{
+ int i;
+
/* Disable interrupt, using polling instead */
regmap_write(data->regmap, REGS_TIER, TIER_DISABLE);
@@ -202,6 +221,8 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
} else {
regmap_write(data->regmap, REGS_V2_TMTMIR, TMTMIR_DEFAULT);
regmap_write(data->regmap, REGS_V2_TEUMR(0), TEUMR0_V2);
+ for (i = 0; i < SITES_MAX; i++)
+ regmap_write(data->regmap, REGS_V2_TMSAR(i), TMSARA_V2);
}
/* Disable monitoring */
@@ -212,6 +233,7 @@ static const struct regmap_range qoriq_yes_ranges[] = {
regmap_reg_range(REGS_TMR, REGS_TSCFGR),
regmap_reg_range(REGS_TTRnCR(0), REGS_TTRnCR(3)),
regmap_reg_range(REGS_V2_TEUMR(0), REGS_V2_TEUMR(2)),
+ regmap_reg_range(REGS_V2_TMSAR(0), REGS_V2_TMSAR(15)),
regmap_reg_range(REGS_IPBRR(0), REGS_IPBRR(1)),
/* Read only registers below */
regmap_reg_range(REGS_TRITSR(0), REGS_TRITSR(15)),
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index e0c1f2409035..46aeb28b4e90 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -198,8 +198,8 @@ static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
{
struct device *dev = rcar_priv_to_dev(priv);
- int i;
- u32 ctemp, old, new;
+ int old, new, ctemp = -EINVAL;
+ unsigned int i;
mutex_lock(&priv->lock);
@@ -209,7 +209,6 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
*/
rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL);
- ctemp = 0;
old = ~0;
for (i = 0; i < 128; i++) {
/*
@@ -227,7 +226,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
old = new;
}
- if (!ctemp) {
+ if (ctemp < 0) {
dev_err(dev, "thermal sensor was broken\n");
goto err_out_unlock;
}
@@ -248,7 +247,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
err_out_unlock:
mutex_unlock(&priv->lock);
- return ctemp ? ctemp : -EINVAL;
+ return ctemp;
}
static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv,
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 7c1a8bccdcba..15a71ecc916c 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -1241,10 +1241,8 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
return -ENXIO;
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no irq resource?\n");
+ if (irq < 0)
return -EINVAL;
- }
thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data),
GFP_KERNEL);
diff --git a/drivers/thermal/st/st_thermal_memmap.c b/drivers/thermal/st/st_thermal_memmap.c
index a824b78dabf8..a0114452d11f 100644
--- a/drivers/thermal/st/st_thermal_memmap.c
+++ b/drivers/thermal/st/st_thermal_memmap.c
@@ -94,10 +94,8 @@ static int st_mmap_register_enable_irq(struct st_thermal_sensor *sensor)
int ret;
sensor->irq = platform_get_irq(pdev, 0);
- if (sensor->irq < 0) {
- dev_err(dev, "failed to register IRQ\n");
+ if (sensor->irq < 0)
return sensor->irq;
- }
ret = devm_request_threaded_irq(dev, sensor->irq,
NULL, st_mmap_thermal_trip_handler,
diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c
index 9314e3df6a42..331e2b768df5 100644
--- a/drivers/thermal/st/stm_thermal.c
+++ b/drivers/thermal/st/stm_thermal.c
@@ -385,10 +385,8 @@ static int stm_register_irq(struct stm_thermal_sensor *sensor)
int ret;
sensor->irq = platform_get_irq(pdev, 0);
- if (sensor->irq < 0) {
- dev_err(dev, "%s: Unable to find IRQ\n", __func__);
+ if (sensor->irq < 0)
return sensor->irq;
- }
ret = devm_request_threaded_irq(dev, sensor->irq,
NULL,
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 9a321dc548c8..b71196eaf90e 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -9,9 +9,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/export.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
@@ -27,10 +27,6 @@
#include "thermal_core.h"
#include "thermal_hwmon.h"
-MODULE_AUTHOR("Zhang Rui");
-MODULE_DESCRIPTION("Generic thermal management sysfs support");
-MODULE_LICENSE("GPL v2");
-
static DEFINE_IDA(thermal_tz_ida);
static DEFINE_IDA(thermal_cdev_ida);
@@ -447,12 +443,6 @@ static void update_temperature(struct thermal_zone_device *tz)
mutex_unlock(&tz->lock);
trace_thermal_temperature(tz);
- if (tz->last_temperature == THERMAL_TEMP_INVALID)
- dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
- tz->temperature);
- else
- dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
- tz->last_temperature, tz->temperature);
}
static void thermal_zone_device_init(struct thermal_zone_device *tz)
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index a9bf00e91d64..c95689586e19 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -12,6 +12,17 @@
#include <linux/device.h>
#include <linux/thermal.h>
+/* Default Thermal Governor */
+#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
+#define DEFAULT_THERMAL_GOVERNOR "step_wise"
+#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
+#define DEFAULT_THERMAL_GOVERNOR "fair_share"
+#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
+#define DEFAULT_THERMAL_GOVERNOR "user_space"
+#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
+#define DEFAULT_THERMAL_GOVERNOR "power_allocator"
+#endif
+
/* Initial state of a cooling device during binding */
#define THERMAL_NO_TARGET -1UL
@@ -30,6 +41,44 @@ extern struct thermal_governor *__governor_thermal_table_end[];
__governor < __governor_thermal_table_end; \
__governor++)
+struct thermal_attr {
+ struct device_attribute attr;
+ char name[THERMAL_NAME_LENGTH];
+};
+
+static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
+{
+ return cdev->ops->get_requested_power && cdev->ops->state2power &&
+ cdev->ops->power2state;
+}
+
+int power_actor_get_max_power(struct thermal_cooling_device *cdev,
+ struct thermal_zone_device *tz, u32 *max_power);
+int power_actor_get_min_power(struct thermal_cooling_device *cdev,
+ struct thermal_zone_device *tz, u32 *min_power);
+int power_actor_set_power(struct thermal_cooling_device *cdev,
+ struct thermal_instance *ti, u32 power);
+/**
+ * struct thermal_trip - representation of a point in temperature domain
+ * @np: pointer to struct device_node that this trip point was created from
+ * @temperature: temperature value in miliCelsius
+ * @hysteresis: relative hysteresis in miliCelsius
+ * @type: trip point type
+ */
+struct thermal_trip {
+ struct device_node *np;
+ int temperature;
+ int hysteresis;
+ enum thermal_trip_type type;
+};
+
+int get_tz_trend(struct thermal_zone_device *tz, int trip);
+
+struct thermal_instance *
+get_thermal_instance(struct thermal_zone_device *tz,
+ struct thermal_cooling_device *cdev,
+ int trip);
+
/*
* This structure is used to describe the behavior of
* a certain cooling device on a certain trip point
@@ -69,6 +118,9 @@ void thermal_zone_device_unbind_exception(struct thermal_zone_device *,
int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
int thermal_build_list_of_policies(char *buf);
+/* Helpers */
+void thermal_zone_set_trips(struct thermal_zone_device *tz);
+
/* sysfs I/F */
int thermal_zone_create_device_groups(struct thermal_zone_device *, int);
void thermal_zone_destroy_device_groups(struct thermal_zone_device *);
diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index 2ba756af76b7..87b1256fa2f2 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -12,11 +12,12 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/export.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/sysfs.h>
#include <trace/events/thermal.h>
@@ -113,6 +114,18 @@ exit:
}
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
+/**
+ * thermal_zone_set_trips - Computes the next trip points for the driver
+ * @tz: a pointer to a thermal zone device structure
+ *
+ * The function computes the next temperature boundaries by browsing
+ * the trip points. The result is the closer low and high trip points
+ * to the current temperature. These values are passed to the backend
+ * driver to let it set its own notification mechanism (usually an
+ * interrupt).
+ *
+ * It does not return a value
+ */
void thermal_zone_set_trips(struct thermal_zone_device *tz)
{
int low = -INT_MAX;
@@ -161,7 +174,6 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
exit:
mutex_unlock(&tz->lock);
}
-EXPORT_SYMBOL_GPL(thermal_zone_set_trips);
void thermal_cdev_update(struct thermal_cooling_device *cdev)
{
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
index c8d2620f2e42..8b92e00ff236 100644
--- a/drivers/thermal/thermal_hwmon.c
+++ b/drivers/thermal/thermal_hwmon.c
@@ -10,10 +10,12 @@
* Copyright (C) 2013 Texas Instruments
* Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com>
*/
+#include <linux/err.h>
+#include <linux/export.h>
#include <linux/hwmon.h>
-#include <linux/thermal.h>
#include <linux/slab.h>
-#include <linux/err.h>
+#include <linux/thermal.h>
+
#include "thermal_hwmon.h"
/* hwmon sys I/F */
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/thermal_of.c
index 874a47d6923f..ddf88dbe7ba2 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/thermal_of.c
@@ -8,13 +8,13 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/thermal.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+#include <linux/types.h>
#include <linux/string.h>
#include "thermal_core.h"
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 263b0420fbe4..ab19ceff6e2a 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -772,10 +772,9 @@ static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
int ret;
bgp->irq = platform_get_irq(pdev, 0);
- if (bgp->irq < 0) {
- dev_err(&pdev->dev, "get_irq failed\n");
+ if (bgp->irq < 0)
return bgp->irq;
- }
+
ret = request_threaded_irq(bgp->irq, NULL,
ti_bandgap_talert_irq_handler,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index d3e959d01606..85776db4bf34 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -169,7 +169,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
data = ti_bandgap_get_sensor_data(bgp, id);
- if (!data || IS_ERR(data))
+ if (!IS_ERR_OR_NULL(data))
data = ti_thermal_build_data(bgp, id);
if (!data)
@@ -196,7 +196,7 @@ int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id)
data = ti_bandgap_get_sensor_data(bgp, id);
- if (data && data->ti_thermal) {
+ if (!IS_ERR_OR_NULL(data) && data->ti_thermal) {
if (data->our_zone)
thermal_zone_device_unregister(data->ti_thermal);
}
@@ -262,7 +262,7 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
data = ti_bandgap_get_sensor_data(bgp, id);
- if (data) {
+ if (!IS_ERR_OR_NULL(data)) {
cpufreq_cooling_unregister(data->cool_dev);
if (data->policy)
cpufreq_cpu_put(data->policy);
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index 2dff93d7a501..93fd984eb2f5 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -2,7 +2,7 @@
config TTY
bool "Enable TTY" if EXPERT
default y
- ---help---
+ help
Allows you to remove TTY support which can save space, and
blocks features that require TTY from inclusion in the kernel.
TTY is required for any text terminals or serial port
@@ -15,7 +15,7 @@ config VT
depends on !UML
select INPUT
default y
- ---help---
+ help
If you say Y here, you will get support for terminal devices with
display and keyboard devices. These are called "virtual" because you
can run several virtual terminals (also called virtual consoles) on
@@ -46,7 +46,7 @@ config CONSOLE_TRANSLATIONS
depends on VT
default y
bool "Enable character translations in console" if EXPERT
- ---help---
+ help
This enables support for font mapping and Unicode translation
on virtual consoles.
@@ -54,7 +54,7 @@ config VT_CONSOLE
bool "Support for console on virtual terminal" if EXPERT
depends on VT
default y
- ---help---
+ help
The system console is the device which receives all kernel messages
and warnings and which allows logins in single user mode. If you
answer Y here, a virtual terminal (the device used to interact with
@@ -84,7 +84,7 @@ config HW_CONSOLE
config VT_HW_CONSOLE_BINDING
bool "Support for binding and unbinding console drivers"
depends on HW_CONSOLE
- ---help---
+ help
The virtual terminal is the device that interacts with the physical
terminal through console drivers. On these systems, at least one
console driver is loaded. In other configurations, additional console
@@ -100,7 +100,7 @@ config VT_HW_CONSOLE_BINDING
config UNIX98_PTYS
bool "Unix98 PTY support" if EXPERT
default y
- ---help---
+ help
A pseudo terminal (PTY) is a software device consisting of two
halves: a master and a slave. The slave device behaves identical to
a physical terminal; the master device is used by a process to
@@ -123,7 +123,7 @@ config UNIX98_PTYS
config LEGACY_PTYS
bool "Legacy (BSD) PTY support"
default y
- ---help---
+ help
A pseudo terminal (PTY) is a software device consisting of two
halves: a master and a slave. The slave device behaves identical to
a physical terminal; the master device is used by a process to
@@ -142,7 +142,7 @@ config LEGACY_PTY_COUNT
depends on LEGACY_PTYS
range 0 256
default "256"
- ---help---
+ help
The maximum number of legacy PTYs that can be used at any one time.
The default is 256, and should be more than enough. Embedded
systems may want to reduce this to save memory.
@@ -178,7 +178,7 @@ source "drivers/tty/serial/Kconfig"
config SERIAL_NONSTANDARD
bool "Non-standard serial port support"
depends on HAS_IOMEM
- ---help---
+ help
Say Y here if you have any non-standard serial boards -- boards
which aren't supported using the standard "dumb" serial driver.
This includes intelligent serial boards such as Cyclades,
@@ -211,7 +211,7 @@ config CYCLADES
tristate "Cyclades async mux support"
depends on SERIAL_NONSTANDARD && (PCI || ISA)
select FW_LOADER
- ---help---
+ help
This driver supports Cyclades Z and Y multiserial boards.
You would need something like this to connect more than two modems to
your Linux box, for instance in order to become a dial-in server.
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 8195a31519ea..d2ae033aea40 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -9,7 +9,7 @@ config SERIAL_8250
depends on !S390
select SERIAL_CORE
select SERIAL_MCTRL_GPIO if GPIOLIB
- ---help---
+ help
This selects whether you want to include the driver for the standard
serial ports. The standard answer is Y. People who might say N
here are those that are setting up dedicated Ethernet WWW/FTP
@@ -39,7 +39,7 @@ config SERIAL_8250_DEPRECATED_OPTIONS
bool "Support 8250_core.* kernel options (DEPRECATED)"
depends on SERIAL_8250
default y
- ---help---
+ help
In 3.7 we renamed 8250 to 8250_core by mistake, so now we have to
accept kernel parameters in both forms like 8250_core.nr_uarts=4 and
8250.nr_uarts=4. We now renamed the module back to 8250, but if
@@ -56,7 +56,7 @@ config SERIAL_8250_PNP
bool "8250/16550 PNP device support" if EXPERT
depends on SERIAL_8250 && PNP
default y
- ---help---
+ help
This builds standard PNP serial support. You may be able to
disable this feature if you only need legacy serial support.
@@ -74,7 +74,7 @@ config SERIAL_8250_16550A_VARIANTS
config SERIAL_8250_FINTEK
bool "Support for Fintek F81216A LPC to 4 UART RS485 API"
depends on SERIAL_8250
- ---help---
+ help
Selecting this option will add support for the RS485 capabilities
of the Fintek F81216A LPC to 4 UART.
@@ -88,7 +88,7 @@ config SERIAL_8250_CONSOLE
depends on SERIAL_8250=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
- ---help---
+ help
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
@@ -158,7 +158,7 @@ config SERIAL_8250_HP300
config SERIAL_8250_CS
tristate "8250/16550 PCMCIA device support"
depends on PCMCIA && SERIAL_8250
- ---help---
+ help
Say Y here to enable support for 16-bit PCMCIA serial devices,
including serial port cards, modems, and the modem functions of
multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 0282ad9cdaa7..780908d43557 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -32,7 +32,7 @@ config SERIAL_AMBA_PL010_CONSOLE
bool "Support for console on AMBA serial port"
depends on SERIAL_AMBA_PL010=y
select SERIAL_CORE_CONSOLE
- ---help---
+ help
Say Y here if you wish to use an AMBA PrimeCell UART 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).
@@ -60,7 +60,7 @@ config SERIAL_AMBA_PL011_CONSOLE
depends on SERIAL_AMBA_PL011=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
- ---help---
+ help
Say Y here if you wish to use an AMBA PrimeCell UART 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).
@@ -101,7 +101,7 @@ config SERIAL_SB1250_DUART
depends on SIBYTE_SB1xxx_SOC=y
select SERIAL_CORE
default y
- ---help---
+ help
Support for the asynchronous serial interface (DUART) included in
the BCM1250 and derived System-On-a-Chip (SOC) devices. Note that
the letter D in DUART stands for "dual", which is how the device
@@ -116,7 +116,7 @@ config SERIAL_SB1250_DUART_CONSOLE
depends on SERIAL_SB1250_DUART=y
select SERIAL_CORE_CONSOLE
default y
- ---help---
+ help
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
@@ -322,7 +322,7 @@ config SERIAL_TEGRA_TCU_CONSOLE
depends on SERIAL_TEGRA_TCU=y
select SERIAL_CORE_CONSOLE
default y
- ---help---
+ help
If you say Y here, it will be possible to use a the Tegra TCU as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
@@ -355,7 +355,7 @@ config SERIAL_DZ
depends on MACH_DECSTATION && 32BIT
select SERIAL_CORE
default y
- ---help---
+ help
DZ11-family serial controllers for DECstations and VAXstations,
including the DC7085, M7814, and M7819.
@@ -364,7 +364,7 @@ config SERIAL_DZ_CONSOLE
depends on SERIAL_DZ=y
select SERIAL_CORE_CONSOLE
default y
- ---help---
+ help
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
@@ -380,7 +380,7 @@ config SERIAL_ZS
depends on MACH_DECSTATION
select SERIAL_CORE
default y
- ---help---
+ help
Support for the Zilog 85C350 serial communications controller used
for serial ports in newer DECstation systems. These include the
DECsystem 5900 and all models of the DECstation and DECsystem 5000
@@ -394,7 +394,7 @@ config SERIAL_ZS_CONSOLE
depends on SERIAL_ZS=y
select SERIAL_CORE_CONSOLE
default y
- ---help---
+ help
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
@@ -588,7 +588,7 @@ config SERIAL_MUX
depends on GSC
select SERIAL_CORE
default y
- ---help---
+ help
Saying Y here will enable the hardware MUX serial driver for
the Nova, K class systems and D class with a 'remote control card'.
The hardware MUX is not 8250/16550 compatible therefore the
@@ -1116,7 +1116,7 @@ config SERIAL_TIMBERDALE
tristate "Support for timberdale UART"
select SERIAL_CORE
depends on X86_32 || COMPILE_TEST
- ---help---
+ help
Add support for UART controller on timberdale.
config SERIAL_BCM63XX
@@ -1145,7 +1145,7 @@ config SERIAL_GRLIB_GAISLER_APBUART
tristate "GRLIB APBUART serial support"
depends on OF && SPARC
select SERIAL_CORE
- ---help---
+ help
Add support for the GRLIB APBUART serial port.
config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 477cdc1e9cf3..7c95afa905a0 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -235,7 +235,7 @@ static void showacpu(void *dummy)
raw_spin_lock_irqsave(&show_lock, flags);
pr_info("CPU%d:\n", smp_processor_id());
- show_stack(NULL, NULL);
+ show_stack(NULL, NULL, KERN_INFO);
raw_spin_unlock_irqrestore(&show_lock, flags);
}
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c
index b28aa0d289f8..c1be96bb3ecf 100644
--- a/drivers/tty/vt/consolemap.c
+++ b/drivers/tty/vt/consolemap.c
@@ -12,7 +12,7 @@
* Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
*
* In order to prevent the following circular lock dependency:
- * &mm->mmap_sem --> cpu_hotplug.lock --> console_lock --> &mm->mmap_sem
+ * &mm->mmap_lock --> cpu_hotplug.lock --> console_lock --> &mm->mmap_lock
*
* We cannot allow page fault to happen while holding the console_lock.
* Therefore, all the userspace copy operations have to be done outside
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 275568abc670..26475b409b53 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -30,7 +30,7 @@ menuconfig USB_SUPPORT
bool "USB support"
depends on HAS_IOMEM
default y
- ---help---
+ help
This option adds core support for Universal Serial Bus (USB).
You will also need drivers from the following menu to make use of it.
@@ -47,7 +47,7 @@ config USB
select GENERIC_ALLOCATOR
select USB_COMMON
select NLS # for UTF-8 strings
- ---help---
+ help
Universal Serial Bus (USB) is a specification for a serial bus
subsystem which offers higher speeds and more features than the
traditional PC serial port. The bus supplies power to peripherals
@@ -83,7 +83,7 @@ config USB_PCI
bool "PCI based USB host interface"
depends on PCI
default y
- ---help---
+ help
Many embedded system SOCs (e.g. freescale T2080) have both
PCI and USB modules with the USB module directly controlled by
registers and having no relationship to the PCI module.
@@ -133,7 +133,7 @@ config USB_USS720
tristate "USS720 parport driver"
depends on PARPORT
select PARPORT_NOT_PC
- ---help---
+ help
This driver is for USB parallel port adapters that use the Lucent
Technologies USS-720 chip. These cables are plugged into your USB
port and provide USB compatibility to peripherals designed with
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index f8a798900093..d3f5162bd67e 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -7,7 +7,7 @@ comment "USB Device Class drivers"
config USB_ACM
tristate "USB Modem (CDC ACM) support"
depends on TTY
- ---help---
+ help
This driver supports USB modems and ISDN adapters which support the
Communication Device Class Abstract Control Model interface.
Please read <file:Documentation/usb/acm.rst> for details.
@@ -30,7 +30,7 @@ config USB_PRINTER
config USB_WDM
tristate "USB Wireless Device Management support"
- ---help---
+ help
This driver supports the WMC Device Management functionality
of cell phones compliant to the CDC WMC specification. You can use
AT commands over this device.
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 494f853f2206..490d353d5fde 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -32,7 +32,7 @@
#include <linux/usb/functionfs.h>
#include <linux/aio.h>
-#include <linux/mmu_context.h>
+#include <linux/kthread.h>
#include <linux/poll.h>
#include <linux/eventfd.h>
@@ -824,13 +824,9 @@ static void ffs_user_copy_worker(struct work_struct *work)
bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
if (io_data->read && ret > 0) {
- mm_segment_t oldfs = get_fs();
-
- set_fs(USER_DS);
- use_mm(io_data->mm);
+ kthread_use_mm(io_data->mm);
ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
- unuse_mm(io_data->mm);
- set_fs(oldfs);
+ kthread_unuse_mm(io_data->mm);
}
io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 2979cbe4d95f..eaf556ceac32 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1052,7 +1052,8 @@ static void usbg_cmd_work(struct work_struct *work)
transport_init_se_cmd(se_cmd,
tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
- cmd->prio_attr, cmd->sense_iu.sense);
+ cmd->prio_attr, cmd->sense_iu.sense,
+ cmd->unpacked_lun);
goto out;
}
@@ -1182,7 +1183,8 @@ static void bot_cmd_work(struct work_struct *work)
transport_init_se_cmd(se_cmd,
tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
- cmd->prio_attr, cmd->sense_iu.sense);
+ cmd->prio_attr, cmd->sense_iu.sense,
+ cmd->unpacked_lun);
goto out;
}
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
index 3afddd3bea6e..9ee0bfe7bcda 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -21,7 +21,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
-#include <linux/mmu_context.h>
+#include <linux/kthread.h>
#include <linux/aio.h>
#include <linux/uio.h>
#include <linux/refcount.h>
@@ -462,9 +462,9 @@ static void ep_user_copy_worker(struct work_struct *work)
struct kiocb *iocb = priv->iocb;
size_t ret;
- use_mm(mm);
+ kthread_use_mm(mm);
ret = copy_to_iter(priv->buf, priv->actual, &priv->to);
- unuse_mm(mm);
+ kthread_unuse_mm(mm);
if (!ret)
ret = -EFAULT;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 62c348062e48..1cb3004ea7b2 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -20,7 +20,7 @@ config USB_C67X00_HCD
config USB_XHCI_HCD
tristate "xHCI HCD (USB 3.0) support"
depends on HAS_DMA && HAS_IOMEM
- ---help---
+ help
The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0
"SuperSpeed" host controller hardware.
@@ -31,7 +31,7 @@ if USB_XHCI_HCD
config USB_XHCI_DBGCAP
bool "xHCI support for debug capability"
depends on TTY
- ---help---
+ help
Say 'Y' to enable the support for the xHCI debug capability. Make
sure that your xHCI host supports the extended debug capability and
you want a TTY serial device based on the xHCI debug capability
@@ -45,7 +45,7 @@ config USB_XHCI_PCI
config USB_XHCI_PCI_RENESAS
tristate "Support for additional Renesas xHCI controller with firwmare"
- ---help---
+ help
Say 'Y' to enable the support for the Renesas xHCI controller with
firwmare. Make sure you have the firwmare for the device and
installed on your system for this device to work.
@@ -54,7 +54,7 @@ config USB_XHCI_PCI_RENESAS
config USB_XHCI_PLATFORM
tristate "Generic xHCI driver for a platform device"
select USB_XHCI_RCAR if ARCH_RENESAS
- ---help---
+ help
Adds an xHCI host driver for a generic platform device, which
provides a memory space and an irq.
It is also a prerequisite for platform specific drivers that
@@ -73,7 +73,7 @@ config USB_XHCI_MTK
tristate "xHCI support for MediaTek SoCs"
select MFD_SYSCON
depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST
- ---help---
+ help
Say 'Y' to enable the support for the xHCI host controller
found in MediaTek SoCs.
If unsure, say N.
@@ -83,7 +83,7 @@ config USB_XHCI_MVEBU
select USB_XHCI_PLATFORM
depends on HAS_IOMEM
depends on ARCH_MVEBU || COMPILE_TEST
- ---help---
+ help
Say 'Y' to enable the support for the xHCI host controller
found in Marvell Armada 375/38x/37xx ARM SOCs.
@@ -91,7 +91,7 @@ config USB_XHCI_RCAR
tristate "xHCI support for Renesas R-Car SoCs"
depends on USB_XHCI_PLATFORM
depends on ARCH_RENESAS || COMPILE_TEST
- ---help---
+ help
Say 'Y' to enable the support for the xHCI host controller
found in Renesas R-Car ARM SoCs.
@@ -100,7 +100,7 @@ config USB_XHCI_TEGRA
depends on PHY_TEGRA_XUSB
depends on RESET_CONTROLLER
select FW_LOADER
- ---help---
+ help
Say 'Y' to enable the support for the xHCI host controller
found in NVIDIA Tegra124 and later SoCs.
@@ -129,7 +129,7 @@ config USB_BRCMSTB
config USB_EHCI_HCD
tristate "EHCI HCD (USB 2.0) support"
depends on HAS_DMA && HAS_IOMEM
- ---help---
+ help
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
If your USB host controller supports USB 2.0, you will likely want to
@@ -151,7 +151,7 @@ config USB_EHCI_HCD
config USB_EHCI_ROOT_HUB_TT
bool "Root Hub Transaction Translators"
depends on USB_EHCI_HCD
- ---help---
+ help
Some EHCI chips have vendor-specific extensions to integrate
transaction translators, so that no OHCI or UHCI companion
controller is needed. It's safe to say "y" even if your
@@ -164,7 +164,7 @@ config USB_EHCI_TT_NEWSCHED
bool "Improved Transaction Translator scheduling"
depends on USB_EHCI_HCD
default y
- ---help---
+ help
This changes the periodic scheduling code to fill more of the low
and full speed bandwidth available from the Transaction Translator
(TT) in USB 2.0 hubs. Without this, only one transfer will be
@@ -192,7 +192,7 @@ config USB_EHCI_HCD_PMC_MSP
depends on MSP_HAS_USB
select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO
- ---help---
+ help
Enables support for the onchip USB controller on the PMC_MSP7100 Family SoC's.
If unsure, say N.
@@ -201,7 +201,7 @@ config XPS_USB_HCD_XILINX
depends on (PPC32 || MICROBLAZE)
select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO
- ---help---
+ help
Xilinx xps USB host controller core is EHCI compliant and has
transaction translator built-in. It can be configured to either
support both high speed and full speed devices, or high speed
@@ -210,14 +210,14 @@ config XPS_USB_HCD_XILINX
config USB_EHCI_FSL
tristate "Support for Freescale on-chip EHCI USB controller"
select USB_EHCI_ROOT_HUB_TT
- ---help---
+ help
Variation of ARC USB block used in some Freescale chips.
config USB_EHCI_MXC
tristate "Support for Freescale i.MX on-chip EHCI USB controller"
depends on ARCH_MXC || COMPILE_TEST
select USB_EHCI_ROOT_HUB_TT
- ---help---
+ help
Variation of ARC USB block used in some Freescale chips.
config USB_EHCI_HCD_NPCM7XX
@@ -233,7 +233,7 @@ config USB_EHCI_HCD_OMAP
depends on ARCH_OMAP
depends on NOP_USB_XCEIV
default y
- ---help---
+ help
Enables support for the on-chip EHCI controller on
OMAP3 and later chips.
@@ -241,7 +241,7 @@ config USB_EHCI_HCD_ORION
tristate "Support for Marvell EBU on-chip EHCI USB controller"
depends on USB_EHCI_HCD && (PLAT_ORION || ARCH_MVEBU || COMPILE_TEST)
default y if (PLAT_ORION || ARCH_MVEBU)
- ---help---
+ help
Enables support for the on-chip EHCI controller on Marvell's
embedded ARM SoCs, including Orion, Kirkwood, Dove, Armada XP,
Armada 370. This is different from the EHCI implementation
@@ -252,7 +252,7 @@ config USB_EHCI_HCD_SPEAR
tristate "Support for ST SPEAr on-chip EHCI USB controller"
depends on USB_EHCI_HCD && (PLAT_SPEAR || COMPILE_TEST)
default y if PLAT_SPEAR
- ---help---
+ help
Enables support for the on-chip EHCI controller on
ST SPEAr chips.
@@ -269,7 +269,7 @@ config USB_EHCI_HCD_AT91
tristate "Support for Atmel on-chip EHCI USB controller"
depends on USB_EHCI_HCD && (ARCH_AT91 || COMPILE_TEST)
default y if ARCH_AT91
- ---help---
+ help
Enables support for the on-chip EHCI controller on
Atmel chips.
@@ -286,14 +286,14 @@ config USB_EHCI_HCD_PPC_OF
bool "EHCI support for PPC USB controller on OF platform bus"
depends on PPC
default y
- ---help---
+ help
Enables support for the USB controller present on the PowerPC
OpenFirmware platform bus.
config USB_EHCI_SH
bool "EHCI support for SuperH USB controller"
depends on SUPERH || COMPILE_TEST
- ---help---
+ help
Enables support for the on-chip EHCI controller on the SuperH.
If you use the PCI EHCI controller, this option is not necessary.
@@ -307,7 +307,7 @@ config USB_EHCI_MV
tristate "EHCI support for Marvell PXA/MMP USB controller"
depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST
select USB_EHCI_ROOT_HUB_TT
- ---help---
+ help
Enables support for Marvell (including PXA and MMP series) on-chip
USB SPH and OTG controller. SPH is a single port host, and it can
only be EHCI host. OTG is controller that can switch to host mode.
@@ -320,7 +320,7 @@ config USB_CNS3XXX_EHCI
bool "Cavium CNS3XXX EHCI Module (DEPRECATED)"
depends on ARCH_CNS3XXX || COMPILE_TEST
select USB_EHCI_HCD_PLATFORM
- ---help---
+ help
This option is deprecated now and the driver was removed, use
USB_EHCI_HCD_PLATFORM instead.
@@ -330,7 +330,7 @@ config USB_CNS3XXX_EHCI
config USB_EHCI_HCD_PLATFORM
tristate "Generic EHCI driver for a platform device"
- ---help---
+ help
Adds an EHCI host driver for a generic platform device, which
provides a memory space and an irq.
@@ -355,7 +355,7 @@ endif # USB_EHCI_HCD
config USB_OXU210HP_HCD
tristate "OXU210HP HCD support"
depends on HAS_IOMEM
- ---help---
+ help
The OXU210HP is an USB host/OTG/device controller. Enable this
option if your board has this chip. If unsure, say N.
@@ -368,7 +368,7 @@ config USB_OXU210HP_HCD
config USB_ISP116X_HCD
tristate "ISP116X HCD support"
depends on HAS_IOMEM
- ---help---
+ help
The ISP1160 and ISP1161 chips are USB host controllers. Enable this
option if your board has this chip. If unsure, say N.
@@ -381,7 +381,7 @@ config USB_ISP1362_HCD
tristate "ISP1362 HCD support"
depends on HAS_IOMEM
depends on COMPILE_TEST # nothing uses this
- ---help---
+ help
Supports the Philips ISP1362 chip as a host controller
This driver does not support isochronous transfers.
@@ -392,7 +392,7 @@ config USB_ISP1362_HCD
config USB_FOTG210_HCD
tristate "FOTG210 HCD support"
depends on USB && HAS_DMA && HAS_IOMEM
- ---help---
+ help
Faraday FOTG210 is an OTG controller which can be configured as
an USB2.0 host. It is designed to meet USB2.0 EHCI specification
with minor modification.
@@ -403,7 +403,7 @@ config USB_FOTG210_HCD
config USB_MAX3421_HCD
tristate "MAX3421 HCD (USB-over-SPI) support"
depends on USB && SPI
- ---help---
+ help
The Maxim MAX3421E chip supports standard USB 2.0-compliant
full-speed devices either in host or peripheral mode. This
driver supports the host-mode of the MAX3421E only.
@@ -414,7 +414,7 @@ config USB_MAX3421_HCD
config USB_OHCI_HCD
tristate "OHCI HCD (USB 1.1) support"
depends on HAS_DMA && HAS_IOMEM
- ---help---
+ help
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
UHCI specification. If your USB host controller follows the OHCI spec,
@@ -434,14 +434,14 @@ config USB_OHCI_HCD_OMAP1
depends on ARCH_OMAP1
depends on ISP1301_OMAP || !(MACH_OMAP_H2 || MACH_OMAP_H3)
default y
- ---help---
+ help
Enables support for the OHCI controller on OMAP1/2 chips.
config USB_OHCI_HCD_SPEAR
tristate "Support for ST SPEAr on-chip OHCI USB controller"
depends on USB_OHCI_HCD && (PLAT_SPEAR || COMPILE_TEST)
default y if PLAT_SPEAR
- ---help---
+ help
Enables support for the on-chip OHCI controller on
ST SPEAr chips.
@@ -458,7 +458,7 @@ config USB_OHCI_HCD_S3C2410
tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX || COMPILE_TEST)
default y if (ARCH_S3C24XX || ARCH_S3C64XX)
- ---help---
+ help
Enables support for the on-chip OHCI controller on
S3C24xx/S3C64xx chips.
@@ -468,7 +468,7 @@ config USB_OHCI_HCD_LPC32XX
depends on ARCH_LPC32XX || COMPILE_TEST
depends on USB_ISP1301
default y
- ---help---
+ help
Enables support for the on-chip OHCI controller on
NXP chips.
@@ -476,7 +476,7 @@ config USB_OHCI_HCD_PXA27X
tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller"
depends on USB_OHCI_HCD && (PXA27x || PXA3xx)
default y
- ---help---
+ help
Enables support for the on-chip OHCI controller on
PXA27x/PXA3xx chips.
@@ -484,7 +484,7 @@ config USB_OHCI_HCD_AT91
tristate "Support for Atmel on-chip OHCI USB controller"
depends on USB_OHCI_HCD && (ARCH_AT91 || COMPILE_TEST) && OF
default y if ARCH_AT91
- ---help---
+ help
Enables support for the on-chip OHCI controller on
Atmel chips.
@@ -516,7 +516,7 @@ config USB_OHCI_HCD_PPC_OF_BE
depends on PPC
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
- ---help---
+ help
Enables support for big-endian USB controllers present on the
OpenFirmware platform bus.
@@ -524,7 +524,7 @@ config USB_OHCI_HCD_PPC_OF_LE
bool "OHCI support for OF platform bus (little endian)"
depends on PPC
select USB_OHCI_LITTLE_ENDIAN
- ---help---
+ help
Enables support for little-endian USB controllers present on the
OpenFirmware platform bus.
@@ -538,7 +538,7 @@ config USB_OHCI_HCD_PCI
depends on USB_PCI
default y
select USB_OHCI_LITTLE_ENDIAN
- ---help---
+ help
Enables support for PCI-bus plug-in USB controller cards.
If unsure, say Y.
@@ -547,7 +547,7 @@ config USB_OHCI_HCD_SSB
depends on (SSB = y || SSB = USB_OHCI_HCD)
select USB_HCD_SSB
select USB_OHCI_HCD_PLATFORM
- ---help---
+ help
This option is deprecated now and the driver was removed, use
USB_HCD_SSB and USB_OHCI_HCD_PLATFORM instead.
@@ -563,7 +563,7 @@ config USB_OHCI_SH
bool "OHCI support for SuperH USB controller (DEPRECATED)"
depends on SUPERH || COMPILE_TEST
select USB_OHCI_HCD_PLATFORM
- ---help---
+ help
This option is deprecated now and the driver was removed, use
USB_OHCI_HCD_PLATFORM instead.
@@ -580,7 +580,7 @@ config USB_CNS3XXX_OHCI
bool "Cavium CNS3XXX OHCI Module (DEPRECATED)"
depends on ARCH_CNS3XXX || COMPILE_TEST
select USB_OHCI_HCD_PLATFORM
- ---help---
+ help
This option is deprecated now and the driver was removed, use
USB_OHCI_HCD_PLATFORM instead.
@@ -589,7 +589,7 @@ config USB_CNS3XXX_OHCI
config USB_OHCI_HCD_PLATFORM
tristate "Generic OHCI driver for a platform device"
- ---help---
+ help
Adds an OHCI host driver for a generic platform device, which
provides a memory space and an irq.
@@ -615,7 +615,7 @@ endif # USB_OHCI_HCD
config USB_UHCI_HCD
tristate "UHCI HCD (most Intel and VIA) support"
depends on USB_PCI || USB_UHCI_SUPPORT_NON_PCI_HC
- ---help---
+ help
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
host controller). If your USB host controller conforms to this
@@ -777,7 +777,7 @@ config USB_HCD_SSB
config USB_HCD_TEST_MODE
bool "HCD test mode support"
- ---help---
+ help
Say 'Y' to enable additional software test modes that may be
supported by the host controller drivers.
diff --git a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig
index 26c75f309da9..a65c638e7fc1 100644
--- a/drivers/usb/image/Kconfig
+++ b/drivers/usb/image/Kconfig
@@ -6,7 +6,7 @@ comment "USB Imaging devices"
config USB_MDC800
tristate "USB Mustek MDC800 Digital Camera support"
- ---help---
+ help
Say Y here if you want to connect this type of still camera to
your computer's USB port. This driver can be used with gphoto 0.4.3
and higher (look at <http://www.gphoto.org/>).
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 833a460ee55a..4e48f8eed168 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -6,7 +6,7 @@ comment "USB Miscellaneous drivers"
config USB_EMI62
tristate "EMI 6|2m USB Audio interface support"
- ---help---
+ help
This driver loads firmware to Emagic EMI 6|2m low latency USB
Audio and Midi interface.
@@ -20,7 +20,7 @@ config USB_EMI62
config USB_EMI26
tristate "EMI 2|6 USB Audio interface support"
- ---help---
+ help
This driver loads firmware to Emagic EMI 2|6 low latency USB
Audio interface.
diff --git a/drivers/usb/misc/sisusbvga/Kconfig b/drivers/usb/misc/sisusbvga/Kconfig
index c16121276a21..655d9cb0651a 100644
--- a/drivers/usb/misc/sisusbvga/Kconfig
+++ b/drivers/usb/misc/sisusbvga/Kconfig
@@ -4,7 +4,7 @@ config USB_SISUSBVGA
tristate "USB 2.0 SVGA dongle support (Net2280/SiS315)"
depends on (USB_MUSB_HDRC || USB_EHCI_HCD)
select FONT_SUPPORT if USB_SISUSBVGA_CON
- ---help---
+ help
Say Y here if you intend to attach a USB2VGA dongle based on a
Net2280 and a SiS315 chip.
@@ -18,7 +18,7 @@ config USB_SISUSBVGA_CON
bool "Text console and mode switching support" if USB_SISUSBVGA
depends on VT
select FONT_8x16
- ---help---
+ help
Say Y here if you want a VGA text console via the USB dongle or
want to support userland applications that utilize the driver's
display mode switching capabilities.
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 25d7e0c36d38..4007fa25a8ff 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -6,7 +6,7 @@
menuconfig USB_SERIAL
tristate "USB Serial Converter support"
depends on TTY
- ---help---
+ help
Say Y here if you have a USB device that provides normal serial
ports, or acts like a serial device, and you want to connect it to
your USB bus.
@@ -23,7 +23,7 @@ if USB_SERIAL
config USB_SERIAL_CONSOLE
bool "USB Serial Console device support"
depends on USB_SERIAL=y
- ---help---
+ help
If you say Y here, it will be possible to use a USB to serial
converter port as the system console (the system console is the
device which receives all kernel messages and warnings and which
@@ -123,7 +123,7 @@ config USB_SERIAL_WHITEHEAT
config USB_SERIAL_DIGI_ACCELEPORT
tristate "USB Digi International AccelePort USB Serial Driver"
- ---help---
+ help
Say Y here if you want to use Digi AccelePort USB 2 or 4 devices,
2 port (plus parallel port) and 4 port USB serial converters. The
parallel port on the USB 2 appears as a third serial port on Linux.
@@ -168,7 +168,7 @@ config USB_SERIAL_EMPEG
config USB_SERIAL_FTDI_SIO
tristate "USB FTDI Single Port Serial Driver"
- ---help---
+ help
Say Y here if you want to use a FTDI SIO single port USB to serial
converter device. The implementation I have is called the USC-1000.
This driver has also been tested with the 245 and 232 devices.
@@ -213,7 +213,7 @@ config USB_SERIAL_IR
config USB_SERIAL_EDGEPORT
tristate "USB Inside Out Edgeport Serial Driver"
- ---help---
+ help
Say Y here if you want to use any of the following devices from
Inside Out Networks (Digi):
Edgeport/4
@@ -311,7 +311,7 @@ config USB_SERIAL_KEYSPAN_PDA
config USB_SERIAL_KEYSPAN
tristate "USB Keyspan USA-xxx Serial Driver"
select USB_EZUSB_FX2
- ---help---
+ help
Say Y here if you want to use Keyspan USB to serial converter
devices. This driver makes use of Keyspan's official firmware
and was developed with their support. You must also include
@@ -324,7 +324,7 @@ config USB_SERIAL_KEYSPAN
config USB_SERIAL_KLSI
tristate "USB KL5KUSB105 (Palmconnect) Driver"
- ---help---
+ help
Say Y here if you want to use a KL5KUSB105 - based single port
serial adapter. The most widely known -- and currently the only
tested -- device in this category is the PalmConnect USB Serial
@@ -339,7 +339,7 @@ config USB_SERIAL_KLSI
config USB_SERIAL_KOBIL_SCT
tristate "USB KOBIL chipcard reader"
- ---help---
+ help
Say Y here if you want to use one of the following KOBIL USB chipcard
readers:
@@ -356,7 +356,7 @@ config USB_SERIAL_KOBIL_SCT
config USB_SERIAL_MCT_U232
tristate "USB MCT Single Port Serial Driver"
- ---help---
+ help
Say Y here if you want to use a USB Serial single port adapter from
Magic Control Technology Corp. (U232 is one of the model numbers).
@@ -368,7 +368,7 @@ config USB_SERIAL_MCT_U232
config USB_SERIAL_METRO
tristate "USB Metrologic Instruments USB-POS Barcode Scanner Driver"
- ---help---
+ help
Say Y here if you want to use a USB POS Metrologic barcode scanner.
To compile this driver as a module, choose M here: the
@@ -376,7 +376,7 @@ config USB_SERIAL_METRO
config USB_SERIAL_MOS7720
tristate "USB Moschip 7720 Serial Driver"
- ---help---
+ help
Say Y here if you want to use USB Serial single and double
port adapters from Moschip Semiconductor Tech.
@@ -388,14 +388,14 @@ config USB_SERIAL_MOS7715_PARPORT
depends on USB_SERIAL_MOS7720
depends on PARPORT=y || PARPORT=USB_SERIAL_MOS7720
select PARPORT_NOT_PC
- ---help---
+ help
Say Y if you have a Moschip 7715 device and would like to use
the parallel port it provides. The port will register with
the parport subsystem as a low-level driver.
config USB_SERIAL_MOS7840
tristate "USB Moschip 7840/7820 USB Serial Driver"
- ---help---
+ help
Say Y here if you want to use a MCS7840 Quad-Serial or MCS7820
Dual-Serial port device from MosChip Semiconductor.
@@ -409,7 +409,7 @@ config USB_SERIAL_MOS7840
config USB_SERIAL_MXUPORT
tristate "USB Moxa UPORT Serial Driver"
- ---help---
+ help
Say Y here if you want to use a MOXA UPort Serial hub.
This driver supports:
@@ -528,7 +528,7 @@ config USB_SERIAL_TI
config USB_SERIAL_CYBERJACK
tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader"
- ---help---
+ help
Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard
reader. This is an interface to ISO 7816 compatible contact-based
chipcards, e.g. GSM SIMs.
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 59aad38b490a..5335a7ff5d14 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -9,7 +9,7 @@ comment "also be needed; see USB_STORAGE Help for more info"
config USB_STORAGE
tristate "USB Mass Storage support"
depends on SCSI
- ---help---
+ help
Say Y here if you want to connect USB mass storage devices to your
computer's USB port. This is the driver you need for USB
floppy drives, USB hard disks, USB tape drives, USB CD-ROMs,
@@ -63,7 +63,7 @@ config USB_STORAGE_FREECOM
config USB_STORAGE_ISD200
tristate "ISD-200 USB/ATA Bridge support"
- ---help---
+ help
Say Y here if you want to use USB Mass Store devices based
on the In-Systems Design ISD-200 USB/ATA bridge.
@@ -165,7 +165,7 @@ config USB_STORAGE_KARMA
config USB_STORAGE_CYPRESS_ATACB
tristate "SAT emulation on Cypress USB/ATA Bridge with ATACB"
- ---help---
+ help
Say Y here if you want to use SAT (ata pass through) on devices based
on the Cypress USB/ATA bridge supporting ATACB. This will allow you
to use tools to tune and monitor your drive (like hdparm or smartctl).
@@ -177,7 +177,7 @@ config USB_STORAGE_CYPRESS_ATACB
config USB_STORAGE_ENE_UB6250
tristate "USB ENE card reader support"
- ---help---
+ help
Say Y here if you wish to control a ENE SD/MS Card reader.
Note that this driver does not support SM cards.
diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig
index 7bbae7a08642..b9f94e2e278d 100644
--- a/drivers/usb/usbip/Kconfig
+++ b/drivers/usb/usbip/Kconfig
@@ -5,7 +5,7 @@ config USBIP_CORE
depends on NET
select USB_COMMON
select SGL_ALLOC
- ---help---
+ help
This enables pushing USB packets over IP to allow remote
machines direct access to USB devices. It provides the
USB/IP core that is required by both drivers.
@@ -21,7 +21,7 @@ config USBIP_CORE
config USBIP_VHCI_HCD
tristate "VHCI hcd"
depends on USBIP_CORE && USB
- ---help---
+ help
This enables the USB/IP virtual host controller driver,
which is run on the remote machine.
@@ -33,7 +33,7 @@ config USBIP_VHCI_HC_PORTS
range 1 15
default 8
depends on USBIP_VHCI_HCD
- ---help---
+ help
To increase number of ports available for USB/IP virtual
host controller driver, this defines number of ports per
USB/IP virtual host controller.
@@ -43,7 +43,7 @@ config USBIP_VHCI_NR_HCS
range 1 128
default 1
depends on USBIP_VHCI_HCD
- ---help---
+ help
To increase number of ports available for USB/IP virtual
host controller driver, this defines number of USB/IP
virtual host controllers as if adding physical host
@@ -52,7 +52,7 @@ config USBIP_VHCI_NR_HCS
config USBIP_HOST
tristate "Host driver"
depends on USBIP_CORE && USB
- ---help---
+ help
This enables the USB/IP host driver, which is run on the
machine that is sharing the USB devices.
@@ -62,7 +62,7 @@ config USBIP_HOST
config USBIP_VUDC
tristate "VUDC driver"
depends on USBIP_CORE && USB_GADGET
- ---help---
+ help
This enables the USB/IP virtual USB device controller
driver, which is run on the host machine, allowing the
machine itself to act as a device.
@@ -73,5 +73,5 @@ config USBIP_VUDC
config USBIP_DEBUG
bool "Debug messages for USB/IP"
depends on USBIP_CORE
- ---help---
+ help
This enables the debug messages from the USB/IP drivers.
diff --git a/drivers/vdpa/Kconfig b/drivers/vdpa/Kconfig
index e8140065c8a5..3e1ceb8e9f2b 100644
--- a/drivers/vdpa/Kconfig
+++ b/drivers/vdpa/Kconfig
@@ -10,7 +10,7 @@ if VDPA
config VDPA_SIM
tristate "vDPA device simulator"
- depends on RUNTIME_TESTING_MENU && HAS_DMA && VHOST_DPN
+ depends on RUNTIME_TESTING_MENU && HAS_DMA
select VHOST_RING
default n
help
diff --git a/drivers/vdpa/ifcvf/ifcvf_base.c b/drivers/vdpa/ifcvf/ifcvf_base.c
index e24371d644b5..94bf0328b68d 100644
--- a/drivers/vdpa/ifcvf/ifcvf_base.c
+++ b/drivers/vdpa/ifcvf/ifcvf_base.c
@@ -185,6 +185,9 @@ void ifcvf_set_status(struct ifcvf_hw *hw, u8 status)
void ifcvf_reset(struct ifcvf_hw *hw)
{
+ hw->config_cb.callback = NULL;
+ hw->config_cb.private = NULL;
+
ifcvf_set_status(hw, 0);
/* flush set_status, make sure VF is stopped, reset */
ifcvf_get_status(hw);
diff --git a/drivers/vdpa/ifcvf/ifcvf_base.h b/drivers/vdpa/ifcvf/ifcvf_base.h
index e80307092351..f4554412e607 100644
--- a/drivers/vdpa/ifcvf/ifcvf_base.h
+++ b/drivers/vdpa/ifcvf/ifcvf_base.h
@@ -27,6 +27,7 @@
((1ULL << VIRTIO_NET_F_MAC) | \
(1ULL << VIRTIO_F_ANY_LAYOUT) | \
(1ULL << VIRTIO_F_VERSION_1) | \
+ (1ULL << VIRTIO_NET_F_STATUS) | \
(1ULL << VIRTIO_F_ORDER_PLATFORM) | \
(1ULL << VIRTIO_F_IOMMU_PLATFORM) | \
(1ULL << VIRTIO_NET_F_MRG_RXBUF))
@@ -81,6 +82,9 @@ struct ifcvf_hw {
void __iomem *net_cfg;
struct vring_info vring[IFCVF_MAX_QUEUE_PAIRS * 2];
void __iomem * const *base;
+ char config_msix_name[256];
+ struct vdpa_callback config_cb;
+
};
struct ifcvf_adapter {
diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
index abf6a061cab6..f5a60c14b979 100644
--- a/drivers/vdpa/ifcvf/ifcvf_main.c
+++ b/drivers/vdpa/ifcvf/ifcvf_main.c
@@ -18,6 +18,16 @@
#define DRIVER_AUTHOR "Intel Corporation"
#define IFCVF_DRIVER_NAME "ifcvf"
+static irqreturn_t ifcvf_config_changed(int irq, void *arg)
+{
+ struct ifcvf_hw *vf = arg;
+
+ if (vf->config_cb.callback)
+ return vf->config_cb.callback(vf->config_cb.private);
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t ifcvf_intr_handler(int irq, void *arg)
{
struct vring_info *vring = arg;
@@ -28,6 +38,68 @@ static irqreturn_t ifcvf_intr_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+static void ifcvf_free_irq_vectors(void *data)
+{
+ pci_free_irq_vectors(data);
+}
+
+static void ifcvf_free_irq(struct ifcvf_adapter *adapter, int queues)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct ifcvf_hw *vf = &adapter->vf;
+ int i;
+
+
+ for (i = 0; i < queues; i++)
+ devm_free_irq(&pdev->dev, vf->vring[i].irq, &vf->vring[i]);
+
+ ifcvf_free_irq_vectors(pdev);
+}
+
+static int ifcvf_request_irq(struct ifcvf_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct ifcvf_hw *vf = &adapter->vf;
+ int vector, i, ret, irq;
+
+ ret = pci_alloc_irq_vectors(pdev, IFCVF_MAX_INTR,
+ IFCVF_MAX_INTR, PCI_IRQ_MSIX);
+ if (ret < 0) {
+ IFCVF_ERR(pdev, "Failed to alloc IRQ vectors\n");
+ return ret;
+ }
+
+ snprintf(vf->config_msix_name, 256, "ifcvf[%s]-config\n",
+ pci_name(pdev));
+ vector = 0;
+ irq = pci_irq_vector(pdev, vector);
+ ret = devm_request_irq(&pdev->dev, irq,
+ ifcvf_config_changed, 0,
+ vf->config_msix_name, vf);
+
+ for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) {
+ snprintf(vf->vring[i].msix_name, 256, "ifcvf[%s]-%d\n",
+ pci_name(pdev), i);
+ vector = i + IFCVF_MSI_QUEUE_OFF;
+ irq = pci_irq_vector(pdev, vector);
+ ret = devm_request_irq(&pdev->dev, irq,
+ ifcvf_intr_handler, 0,
+ vf->vring[i].msix_name,
+ &vf->vring[i]);
+ if (ret) {
+ IFCVF_ERR(pdev,
+ "Failed to request irq for vq %d\n", i);
+ ifcvf_free_irq(adapter, i);
+
+ return ret;
+ }
+
+ vf->vring[i].irq = irq;
+ }
+
+ return 0;
+}
+
static int ifcvf_start_datapath(void *private)
{
struct ifcvf_hw *vf = ifcvf_private_to_vf(private);
@@ -118,17 +190,37 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
{
struct ifcvf_adapter *adapter;
struct ifcvf_hw *vf;
+ u8 status_old;
+ int ret;
vf = vdpa_to_vf(vdpa_dev);
adapter = dev_get_drvdata(vdpa_dev->dev.parent);
+ status_old = ifcvf_get_status(vf);
- if (status == 0) {
+ if (status_old == status)
+ return;
+
+ if ((status_old & VIRTIO_CONFIG_S_DRIVER_OK) &&
+ !(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
ifcvf_stop_datapath(adapter);
+ ifcvf_free_irq(adapter, IFCVF_MAX_QUEUE_PAIRS * 2);
+ }
+
+ if (status == 0) {
ifcvf_reset_vring(adapter);
return;
}
- if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
+ if ((status & VIRTIO_CONFIG_S_DRIVER_OK) &&
+ !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) {
+ ret = ifcvf_request_irq(adapter);
+ if (ret) {
+ status = ifcvf_get_status(vf);
+ status |= VIRTIO_CONFIG_S_FAILED;
+ ifcvf_set_status(vf, status);
+ return;
+ }
+
if (ifcvf_start_datapath(adapter) < 0)
IFCVF_ERR(adapter->pdev,
"Failed to set ifcvf vdpa status %u\n",
@@ -254,7 +346,10 @@ static void ifcvf_vdpa_set_config(struct vdpa_device *vdpa_dev,
static void ifcvf_vdpa_set_config_cb(struct vdpa_device *vdpa_dev,
struct vdpa_callback *cb)
{
- /* We don't support config interrupt */
+ struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
+
+ vf->config_cb.callback = cb->callback;
+ vf->config_cb.private = cb->private;
}
/*
@@ -284,38 +379,6 @@ static const struct vdpa_config_ops ifc_vdpa_ops = {
.set_config_cb = ifcvf_vdpa_set_config_cb,
};
-static int ifcvf_request_irq(struct ifcvf_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- struct ifcvf_hw *vf = &adapter->vf;
- int vector, i, ret, irq;
-
-
- for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) {
- snprintf(vf->vring[i].msix_name, 256, "ifcvf[%s]-%d\n",
- pci_name(pdev), i);
- vector = i + IFCVF_MSI_QUEUE_OFF;
- irq = pci_irq_vector(pdev, vector);
- ret = devm_request_irq(&pdev->dev, irq,
- ifcvf_intr_handler, 0,
- vf->vring[i].msix_name,
- &vf->vring[i]);
- if (ret) {
- IFCVF_ERR(pdev,
- "Failed to request irq for vq %d\n", i);
- return ret;
- }
- vf->vring[i].irq = irq;
- }
-
- return 0;
-}
-
-static void ifcvf_free_irq_vectors(void *data)
-{
- pci_free_irq_vectors(data);
-}
-
static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct device *dev = &pdev->dev;
@@ -349,13 +412,6 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return ret;
}
- ret = pci_alloc_irq_vectors(pdev, IFCVF_MAX_INTR,
- IFCVF_MAX_INTR, PCI_IRQ_MSIX);
- if (ret < 0) {
- IFCVF_ERR(pdev, "Failed to alloc irq vectors\n");
- return ret;
- }
-
ret = devm_add_action_or_reset(dev, ifcvf_free_irq_vectors, pdev);
if (ret) {
IFCVF_ERR(pdev,
@@ -379,12 +435,6 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
adapter->pdev = pdev;
adapter->vdpa.dma_dev = &pdev->dev;
- ret = ifcvf_request_irq(adapter);
- if (ret) {
- IFCVF_ERR(pdev, "Failed to request MSI-X irq\n");
- goto err;
- }
-
ret = ifcvf_init_hw(vf, pdev);
if (ret) {
IFCVF_ERR(pdev, "Failed to init IFCVF hw\n");
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
index 01c456f7c1f7..c7334cc65bb2 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
@@ -101,7 +101,7 @@ static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
static void vdpasim_vq_reset(struct vdpasim_virtqueue *vq)
{
- vq->ready = 0;
+ vq->ready = false;
vq->desc_addr = 0;
vq->driver_addr = 0;
vq->device_addr = 0;
@@ -131,9 +131,10 @@ static void vdpasim_work(struct work_struct *work)
vdpasim, work);
struct vdpasim_virtqueue *txq = &vdpasim->vqs[1];
struct vdpasim_virtqueue *rxq = &vdpasim->vqs[0];
- size_t read, write, total_write;
- int err;
+ ssize_t read, write;
+ size_t total_write;
int pkts = 0;
+ int err;
spin_lock(&vdpasim->lock);
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 3fc198f3eeb5..7c0779018b1b 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -1185,7 +1185,7 @@ reset_info_exit:
/*
* We need to get memory_lock for each device, but devices
- * can share mmap_sem, therefore we need to zap and hold
+ * can share mmap_lock, therefore we need to zap and hold
* the vma_lock for each device, and only then get each
* memory_lock.
*/
@@ -1375,26 +1375,26 @@ static int vfio_pci_zap_and_vma_lock(struct vfio_pci_device *vdev, bool try)
/*
* Lock ordering:
- * vma_lock is nested under mmap_sem for vm_ops callback paths.
+ * vma_lock is nested under mmap_lock for vm_ops callback paths.
* The memory_lock semaphore is used by both code paths calling
* into this function to zap vmas and the vm_ops.fault callback
* to protect the memory enable state of the device.
*
- * When zapping vmas we need to maintain the mmap_sem => vma_lock
+ * When zapping vmas we need to maintain the mmap_lock => vma_lock
* ordering, which requires using vma_lock to walk vma_list to
- * acquire an mm, then dropping vma_lock to get the mmap_sem and
+ * acquire an mm, then dropping vma_lock to get the mmap_lock and
* reacquiring vma_lock. This logic is derived from similar
* requirements in uverbs_user_mmap_disassociate().
*
- * mmap_sem must always be the top-level lock when it is taken.
+ * mmap_lock must always be the top-level lock when it is taken.
* Therefore we can only hold the memory_lock write lock when
- * vma_list is empty, as we'd need to take mmap_sem to clear
+ * vma_list is empty, as we'd need to take mmap_lock to clear
* entries. vma_list can only be guaranteed empty when holding
* vma_lock, thus memory_lock is nested under vma_lock.
*
* This enables the vm_ops.fault callback to acquire vma_lock,
* followed by memory_lock read lock, while already holding
- * mmap_sem without risk of deadlock.
+ * mmap_lock without risk of deadlock.
*/
while (1) {
struct mm_struct *mm = NULL;
@@ -1422,17 +1422,17 @@ static int vfio_pci_zap_and_vma_lock(struct vfio_pci_device *vdev, bool try)
mutex_unlock(&vdev->vma_lock);
if (try) {
- if (!down_read_trylock(&mm->mmap_sem)) {
+ if (!mmap_read_trylock(mm)) {
mmput(mm);
return 0;
}
} else {
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
}
if (mmget_still_valid(mm)) {
if (try) {
if (!mutex_trylock(&vdev->vma_lock)) {
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
return 0;
}
@@ -1454,7 +1454,7 @@ static int vfio_pci_zap_and_vma_lock(struct vfio_pci_device *vdev, bool try)
}
mutex_unlock(&vdev->vma_lock);
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
mmput(mm);
}
}
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 391fafe82c5c..5e556ac9102a 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -27,7 +27,7 @@
#include <linux/iommu.h>
#include <linux/module.h>
#include <linux/mm.h>
-#include <linux/mmu_context.h>
+#include <linux/kthread.h>
#include <linux/rbtree.h>
#include <linux/sched/signal.h>
#include <linux/sched/mm.h>
@@ -376,11 +376,11 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async)
if (!mm)
return -ESRCH; /* process exited */
- ret = down_write_killable(&mm->mmap_sem);
+ ret = mmap_write_lock_killable(mm);
if (!ret) {
ret = __account_locked_vm(mm, abs(npage), npage > 0, dma->task,
dma->lock_cap);
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
}
if (async)
@@ -452,7 +452,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
if (prot & IOMMU_WRITE)
flags |= FOLL_WRITE;
- down_read(&mm->mmap_sem);
+ mmap_read_lock(mm);
ret = pin_user_pages_remote(NULL, mm, vaddr, 1, flags | FOLL_LONGTERM,
page, NULL, NULL);
if (ret == 1) {
@@ -475,7 +475,7 @@ retry:
ret = -EFAULT;
}
done:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return ret;
}
@@ -2817,7 +2817,7 @@ static int vfio_iommu_type1_dma_rw_chunk(struct vfio_iommu *iommu,
return -EPERM;
if (kthread)
- use_mm(mm);
+ kthread_use_mm(mm);
else if (current->mm != mm)
goto out;
@@ -2844,7 +2844,7 @@ static int vfio_iommu_type1_dma_rw_chunk(struct vfio_iommu *iommu,
*copied = copy_from_user(data, (void __user *)vaddr,
count) ? 0 : count;
if (kthread)
- unuse_mm(mm);
+ kthread_unuse_mm(mm);
out:
mmput(mm);
return *copied ? 0 : -EFAULT;
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index c4f273793595..d3688c6afb87 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -13,15 +13,6 @@ config VHOST_RING
This option is selected by any driver which needs to access
the host side of a virtio ring.
-config VHOST_DPN
- bool
- depends on !ARM || AEABI
- default y
- help
- Anything selecting VHOST or VHOST_RING must depend on VHOST_DPN.
- This excludes the deprecated ARM ABI since that forces a 4 byte
- alignment on all structs - incompatible with virtio spec requirements.
-
config VHOST
tristate
select VHOST_IOTLB
@@ -37,9 +28,9 @@ if VHOST_MENU
config VHOST_NET
tristate "Host kernel accelerator for virtio net"
- depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP) && VHOST_DPN
+ depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP)
select VHOST
- ---help---
+ help
This kernel module can be loaded in host kernel to accelerate
guest networking with virtio_net. Not to be confused with virtio_net
module itself which needs to be loaded in guest kernel.
@@ -49,20 +40,20 @@ config VHOST_NET
config VHOST_SCSI
tristate "VHOST_SCSI TCM fabric driver"
- depends on TARGET_CORE && EVENTFD && VHOST_DPN
+ depends on TARGET_CORE && EVENTFD
select VHOST
default n
- ---help---
+ help
Say M here to enable the vhost_scsi TCM fabric module
for use with virtio-scsi guests
config VHOST_VSOCK
tristate "vhost virtio-vsock driver"
- depends on VSOCKETS && EVENTFD && VHOST_DPN
+ depends on VSOCKETS && EVENTFD
select VHOST
select VIRTIO_VSOCKETS_COMMON
default n
- ---help---
+ help
This kernel module can be loaded in the host kernel to provide AF_VSOCK
sockets for communicating with guests. The guests must have the
virtio_transport.ko driver loaded to use the virtio-vsock device.
@@ -72,7 +63,7 @@ config VHOST_VSOCK
config VHOST_VDPA
tristate "Vhost driver for vDPA-based backend"
- depends on EVENTFD && VHOST_DPN
+ depends on EVENTFD
select VHOST
depends on VDPA
help
@@ -85,7 +76,7 @@ config VHOST_VDPA
config VHOST_CROSS_ENDIAN_LEGACY
bool "Cross-endian support for vhost"
default n
- ---help---
+ help
This option allows vhost to support guests with a different byte
ordering from host while using legacy virtio.
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 516519dcc8ff..e992decfec53 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1327,7 +1327,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
}
vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX,
UIO_MAXIOV + VHOST_NET_BATCH,
- VHOST_NET_PKT_WEIGHT, VHOST_NET_WEIGHT,
+ VHOST_NET_PKT_WEIGHT, VHOST_NET_WEIGHT, true,
NULL);
vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, EPOLLOUT, dev);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 8b104f76f324..6fb4d7ecfa19 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1628,7 +1628,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
}
vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV,
- VHOST_SCSI_WEIGHT, 0, NULL);
+ VHOST_SCSI_WEIGHT, 0, true, NULL);
vhost_scsi_init_inflight(vs, NULL);
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 9a3a09005e03..0466921f4772 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -120,7 +120,7 @@ static int vhost_test_open(struct inode *inode, struct file *f)
vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX, UIO_MAXIOV,
- VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT, NULL);
+ VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT, true, NULL);
f->private_data = n;
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 0968361e3b77..7580e34f76c1 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -15,12 +15,14 @@
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/mm.h>
#include <linux/iommu.h>
#include <linux/uuid.h>
#include <linux/vdpa.h>
#include <linux/nospec.h>
#include <linux/vhost.h>
#include <linux/virtio_net.h>
+#include <linux/kernel.h>
#include "vhost.h"
@@ -70,6 +72,7 @@ struct vhost_vdpa {
int nvqs;
int virtio_id;
int minor;
+ struct eventfd_ctx *config_ctx;
};
static DEFINE_IDA(vhost_vdpa_ida);
@@ -101,6 +104,17 @@ static irqreturn_t vhost_vdpa_virtqueue_cb(void *private)
return IRQ_HANDLED;
}
+static irqreturn_t vhost_vdpa_config_cb(void *private)
+{
+ struct vhost_vdpa *v = private;
+ struct eventfd_ctx *config_ctx = v->config_ctx;
+
+ if (config_ctx)
+ eventfd_signal(config_ctx, 1);
+
+ return IRQ_HANDLED;
+}
+
static void vhost_vdpa_reset(struct vhost_vdpa *v)
{
struct vdpa_device *vdpa = v->vdpa;
@@ -288,6 +302,36 @@ static long vhost_vdpa_get_vring_num(struct vhost_vdpa *v, u16 __user *argp)
return 0;
}
+static void vhost_vdpa_config_put(struct vhost_vdpa *v)
+{
+ if (v->config_ctx)
+ eventfd_ctx_put(v->config_ctx);
+}
+
+static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
+{
+ struct vdpa_callback cb;
+ int fd;
+ struct eventfd_ctx *ctx;
+
+ cb.callback = vhost_vdpa_config_cb;
+ cb.private = v->vdpa;
+ if (copy_from_user(&fd, argp, sizeof(fd)))
+ return -EFAULT;
+
+ ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
+ swap(ctx, v->config_ctx);
+
+ if (!IS_ERR_OR_NULL(ctx))
+ eventfd_ctx_put(ctx);
+
+ if (IS_ERR(v->config_ctx))
+ return PTR_ERR(v->config_ctx);
+
+ v->vdpa->config->set_config_cb(v->vdpa, &cb);
+
+ return 0;
+}
static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
void __user *argp)
{
@@ -395,6 +439,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
case VHOST_SET_LOG_FD:
r = -ENOIOCTLCMD;
break;
+ case VHOST_VDPA_SET_CONFIG_CALL:
+ r = vhost_vdpa_set_config_call(v, argp);
+ break;
default:
r = vhost_dev_ioctl(&v->vdev, cmd, argp);
if (r == -ENOIOCTLCMD)
@@ -527,7 +574,7 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
if (!npages)
return -EINVAL;
- down_read(&dev->mm->mmap_sem);
+ mmap_read_lock(dev->mm);
locked = atomic64_add_return(npages, &dev->mm->pinned_vm);
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
@@ -580,7 +627,7 @@ out:
vhost_vdpa_unmap(v, msg->iova, msg->size);
atomic64_sub(npages, &dev->mm->pinned_vm);
}
- up_read(&dev->mm->mmap_sem);
+ mmap_read_unlock(dev->mm);
free_page((unsigned long)page_list);
return ret;
}
@@ -694,7 +741,7 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
vqs[i] = &v->vqs[i];
vqs[i]->handle_kick = handle_vq_kick;
}
- vhost_dev_init(dev, vqs, nvqs, 0, 0, 0,
+ vhost_dev_init(dev, vqs, nvqs, 0, 0, 0, false,
vhost_vdpa_process_iotlb_msg);
dev->iotlb = vhost_iotlb_alloc(0, 0);
@@ -729,6 +776,7 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
vhost_dev_stop(&v->vdev);
vhost_vdpa_iotlb_free(v);
vhost_vdpa_free_domain(v);
+ vhost_vdpa_config_put(v);
vhost_dev_cleanup(&v->vdev);
kfree(v->vdev.vqs);
mutex_unlock(&d->mutex);
@@ -739,12 +787,74 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
return 0;
}
+#ifdef CONFIG_MMU
+static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf)
+{
+ struct vhost_vdpa *v = vmf->vma->vm_file->private_data;
+ struct vdpa_device *vdpa = v->vdpa;
+ const struct vdpa_config_ops *ops = vdpa->config;
+ struct vdpa_notification_area notify;
+ struct vm_area_struct *vma = vmf->vma;
+ u16 index = vma->vm_pgoff;
+
+ notify = ops->get_vq_notification(vdpa, index);
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (remap_pfn_range(vma, vmf->address & PAGE_MASK,
+ notify.addr >> PAGE_SHIFT, PAGE_SIZE,
+ vma->vm_page_prot))
+ return VM_FAULT_SIGBUS;
+
+ return VM_FAULT_NOPAGE;
+}
+
+static const struct vm_operations_struct vhost_vdpa_vm_ops = {
+ .fault = vhost_vdpa_fault,
+};
+
+static int vhost_vdpa_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct vhost_vdpa *v = vma->vm_file->private_data;
+ struct vdpa_device *vdpa = v->vdpa;
+ const struct vdpa_config_ops *ops = vdpa->config;
+ struct vdpa_notification_area notify;
+ int index = vma->vm_pgoff;
+
+ if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+ return -EINVAL;
+ if ((vma->vm_flags & VM_SHARED) == 0)
+ return -EINVAL;
+ if (vma->vm_flags & VM_READ)
+ return -EINVAL;
+ if (index > 65535)
+ return -EINVAL;
+ if (!ops->get_vq_notification)
+ return -ENOTSUPP;
+
+ /* To be safe and easily modelled by userspace, We only
+ * support the doorbell which sits on the page boundary and
+ * does not share the page with other registers.
+ */
+ notify = ops->get_vq_notification(vdpa, index);
+ if (notify.addr & (PAGE_SIZE - 1))
+ return -EINVAL;
+ if (vma->vm_end - vma->vm_start != notify.size)
+ return -ENOTSUPP;
+
+ vma->vm_ops = &vhost_vdpa_vm_ops;
+ return 0;
+}
+#endif /* CONFIG_MMU */
+
static const struct file_operations vhost_vdpa_fops = {
.owner = THIS_MODULE,
.open = vhost_vdpa_open,
.release = vhost_vdpa_release,
.write_iter = vhost_vdpa_chr_write_iter,
.unlocked_ioctl = vhost_vdpa_unlocked_ioctl,
+#ifdef CONFIG_MMU
+ .mmap = vhost_vdpa_mmap,
+#endif /* CONFIG_MMU */
.compat_ioctl = compat_ptr_ioctl,
};
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 21a59b598ed8..d7b8df3edffc 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -14,7 +14,6 @@
#include <linux/vhost.h>
#include <linux/uio.h>
#include <linux/mm.h>
-#include <linux/mmu_context.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <linux/poll.h>
@@ -166,11 +165,16 @@ static int vhost_poll_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync,
void *key)
{
struct vhost_poll *poll = container_of(wait, struct vhost_poll, wait);
+ struct vhost_work *work = &poll->work;
if (!(key_to_poll(key) & poll->mask))
return 0;
- vhost_poll_queue(poll);
+ if (!poll->dev->use_worker)
+ work->fn(work);
+ else
+ vhost_poll_queue(poll);
+
return 0;
}
@@ -330,10 +334,8 @@ static int vhost_worker(void *data)
struct vhost_dev *dev = data;
struct vhost_work *work, *work_next;
struct llist_node *node;
- mm_segment_t oldfs = get_fs();
- set_fs(USER_DS);
- use_mm(dev->mm);
+ kthread_use_mm(dev->mm);
for (;;) {
/* mb paired w/ kthread_stop */
@@ -361,8 +363,7 @@ static int vhost_worker(void *data)
schedule();
}
}
- unuse_mm(dev->mm);
- set_fs(oldfs);
+ kthread_unuse_mm(dev->mm);
return 0;
}
@@ -454,6 +455,7 @@ static size_t vhost_get_desc_size(struct vhost_virtqueue *vq,
void vhost_dev_init(struct vhost_dev *dev,
struct vhost_virtqueue **vqs, int nvqs,
int iov_limit, int weight, int byte_weight,
+ bool use_worker,
int (*msg_handler)(struct vhost_dev *dev,
struct vhost_iotlb_msg *msg))
{
@@ -471,6 +473,7 @@ void vhost_dev_init(struct vhost_dev *dev,
dev->iov_limit = iov_limit;
dev->weight = weight;
dev->byte_weight = byte_weight;
+ dev->use_worker = use_worker;
dev->msg_handler = msg_handler;
init_llist_head(&dev->work_list);
init_waitqueue_head(&dev->wait);
@@ -534,6 +537,36 @@ bool vhost_dev_has_owner(struct vhost_dev *dev)
}
EXPORT_SYMBOL_GPL(vhost_dev_has_owner);
+static void vhost_attach_mm(struct vhost_dev *dev)
+{
+ /* No owner, become one */
+ if (dev->use_worker) {
+ dev->mm = get_task_mm(current);
+ } else {
+ /* vDPA device does not use worker thead, so there's
+ * no need to hold the address space for mm. This help
+ * to avoid deadlock in the case of mmap() which may
+ * held the refcnt of the file and depends on release
+ * method to remove vma.
+ */
+ dev->mm = current->mm;
+ mmgrab(dev->mm);
+ }
+}
+
+static void vhost_detach_mm(struct vhost_dev *dev)
+{
+ if (!dev->mm)
+ return;
+
+ if (dev->use_worker)
+ mmput(dev->mm);
+ else
+ mmdrop(dev->mm);
+
+ dev->mm = NULL;
+}
+
/* Caller should have device mutex */
long vhost_dev_set_owner(struct vhost_dev *dev)
{
@@ -546,21 +579,24 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
goto err_mm;
}
- /* No owner, become one */
- dev->mm = get_task_mm(current);
+ vhost_attach_mm(dev);
+
dev->kcov_handle = kcov_common_handle();
- worker = kthread_create(vhost_worker, dev, "vhost-%d", current->pid);
- if (IS_ERR(worker)) {
- err = PTR_ERR(worker);
- goto err_worker;
- }
+ if (dev->use_worker) {
+ worker = kthread_create(vhost_worker, dev,
+ "vhost-%d", current->pid);
+ if (IS_ERR(worker)) {
+ err = PTR_ERR(worker);
+ goto err_worker;
+ }
- dev->worker = worker;
- wake_up_process(worker); /* avoid contributing to loadavg */
+ dev->worker = worker;
+ wake_up_process(worker); /* avoid contributing to loadavg */
- err = vhost_attach_cgroups(dev);
- if (err)
- goto err_cgroup;
+ err = vhost_attach_cgroups(dev);
+ if (err)
+ goto err_cgroup;
+ }
err = vhost_dev_alloc_iovecs(dev);
if (err)
@@ -568,12 +604,12 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
return 0;
err_cgroup:
- kthread_stop(worker);
- dev->worker = NULL;
+ if (dev->worker) {
+ kthread_stop(dev->worker);
+ dev->worker = NULL;
+ }
err_worker:
- if (dev->mm)
- mmput(dev->mm);
- dev->mm = NULL;
+ vhost_detach_mm(dev);
dev->kcov_handle = 0;
err_mm:
return err;
@@ -670,9 +706,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
dev->worker = NULL;
dev->kcov_handle = 0;
}
- if (dev->mm)
- mmput(dev->mm);
- dev->mm = NULL;
+ vhost_detach_mm(dev);
}
EXPORT_SYMBOL_GPL(vhost_dev_cleanup);
@@ -882,7 +916,7 @@ static inline void __user *__vhost_get_user(struct vhost_virtqueue *vq,
#define vhost_put_user(vq, x, ptr) \
({ \
- int ret = -EFAULT; \
+ int ret; \
if (!vq->iotlb) { \
ret = __put_user(x, ptr); \
} else { \
@@ -1244,9 +1278,9 @@ static int vhost_iotlb_miss(struct vhost_virtqueue *vq, u64 iova, int access)
}
static bool vq_access_ok(struct vhost_virtqueue *vq, unsigned int num,
- struct vring_desc __user *desc,
- struct vring_avail __user *avail,
- struct vring_used __user *used)
+ vring_desc_t __user *desc,
+ vring_avail_t __user *avail,
+ vring_used_t __user *used)
{
return access_ok(desc, vhost_get_desc_size(vq, num)) &&
@@ -1574,7 +1608,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
r = -EFAULT;
break;
}
- eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
+ eventfp = f.fd == VHOST_FILE_UNBIND ? NULL : eventfd_fget(f.fd);
if (IS_ERR(eventfp)) {
r = PTR_ERR(eventfp);
break;
@@ -1590,7 +1624,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
r = -EFAULT;
break;
}
- ctx = f.fd == -1 ? NULL : eventfd_ctx_fdget(f.fd);
+ ctx = f.fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(f.fd);
if (IS_ERR(ctx)) {
r = PTR_ERR(ctx);
break;
@@ -1602,7 +1636,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
r = -EFAULT;
break;
}
- ctx = f.fd == -1 ? NULL : eventfd_ctx_fdget(f.fd);
+ ctx = f.fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(f.fd);
if (IS_ERR(ctx)) {
r = PTR_ERR(ctx);
break;
@@ -1727,7 +1761,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
r = get_user(fd, (int __user *)argp);
if (r < 0)
break;
- ctx = fd == -1 ? NULL : eventfd_ctx_fdget(fd);
+ ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
if (IS_ERR(ctx)) {
r = PTR_ERR(ctx);
break;
@@ -1762,15 +1796,14 @@ static int set_bit_to_user(int nr, void __user *addr)
int bit = nr + (log % PAGE_SIZE) * 8;
int r;
- r = get_user_pages_fast(log, 1, FOLL_WRITE, &page);
+ r = pin_user_pages_fast(log, 1, FOLL_WRITE, &page);
if (r < 0)
return r;
BUG_ON(r != 1);
base = kmap_atomic(page);
set_bit(bit, base);
kunmap_atomic(base);
- set_page_dirty_lock(page);
- put_page(page);
+ unpin_user_pages_dirty_lock(&page, 1, true);
return 0;
}
@@ -2301,7 +2334,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq,
struct vring_used_elem *heads,
unsigned count)
{
- struct vring_used_elem __user *used;
+ vring_used_elem_t __user *used;
u16 old, new;
int start;
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index f8403bd46b85..c8e96a095d3b 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -67,9 +67,9 @@ struct vhost_virtqueue {
/* The actual ring of buffers. */
struct mutex mutex;
unsigned int num;
- struct vring_desc __user *desc;
- struct vring_avail __user *avail;
- struct vring_used __user *used;
+ vring_desc_t __user *desc;
+ vring_avail_t __user *avail;
+ vring_used_t __user *used;
const struct vhost_iotlb_map *meta_iotlb[VHOST_NUM_ADDRS];
struct file *kick;
struct eventfd_ctx *call_ctx;
@@ -154,6 +154,7 @@ struct vhost_dev {
int weight;
int byte_weight;
u64 kcov_handle;
+ bool use_worker;
int (*msg_handler)(struct vhost_dev *dev,
struct vhost_iotlb_msg *msg);
};
@@ -161,6 +162,7 @@ struct vhost_dev {
bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len);
void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs,
int nvqs, int iov_limit, int weight, int byte_weight,
+ bool use_worker,
int (*msg_handler)(struct vhost_dev *dev,
struct vhost_iotlb_msg *msg));
long vhost_dev_set_owner(struct vhost_dev *dev);
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index ba8e0d6cfd97..e059a9a47cdf 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -620,9 +620,9 @@ static inline int xfer_to_user(const struct vringh *vrh,
*/
int vringh_init_user(struct vringh *vrh, u64 features,
unsigned int num, bool weak_barriers,
- struct vring_desc __user *desc,
- struct vring_avail __user *avail,
- struct vring_used __user *used)
+ vring_desc_t __user *desc,
+ vring_avail_t __user *avail,
+ vring_used_t __user *used)
{
/* Sane power of 2 please! */
if (!num || num > 0xffff || (num & (num - 1))) {
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index fb4e944c4d0d..a483cec31d5c 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -632,7 +632,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
vhost_dev_init(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs),
UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT,
- VHOST_VSOCK_WEIGHT, NULL);
+ VHOST_VSOCK_WEIGHT, true, NULL);
file->private_data = vsock;
spin_lock_init(&vsock->send_pkt_list_lock);
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 3c01b0d2414f..5e850cc9f891 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -71,7 +71,7 @@ config VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
config MDA_CONSOLE
depends on !M68K && !PARISC && ISA
tristate "MDA text console (dual-headed)"
- ---help---
+ help
Say Y here if you have an old MDA or monochrome Hercules graphics
adapter in your system acting as a second head ( = video card). You
will then be able to use two monitors with your Linux system. Do not
@@ -128,7 +128,7 @@ config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
bool "Map the console to the primary display device"
depends on FRAMEBUFFER_CONSOLE
default n
- ---help---
+ help
If this option is selected, the framebuffer console will
automatically select the primary display device (if the architecture
supports this feature). Otherwise, the framebuffer console will
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 00dddf6e08b0..504cda38763e 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -24,7 +24,6 @@
#include <asm/io.h>
#include <linux/uaccess.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/gio_device.h>
#include <video/newport.h>
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 844ada978bb7..0f559aeaf469 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -13,7 +13,7 @@ menuconfig FB
tristate "Support for frame buffer devices"
select FB_CMDLINE
select FB_NOTIFY
- ---help---
+ help
The frame buffer device provides an abstraction for the graphics
hardware. It represents the frame buffer of some video hardware and
allows application software to access the graphics hardware through
@@ -48,7 +48,7 @@ menuconfig FB
config FIRMWARE_EDID
bool "Enable firmware EDID"
depends on FB
- ---help---
+ help
This enables access to the EDID transferred from the firmware.
On the i386, this is from the Video BIOS. Enable this if DDC/I2C
transfers do not work for your driver and if you are using
@@ -69,14 +69,14 @@ config FB_DDC
config FB_BOOT_VESA_SUPPORT
bool
depends on FB
- ---help---
+ help
If true, at least one selected framebuffer driver can take advantage
of VESA video modes set at an early boot stage via the vga= parameter.
config FB_CFB_FILLRECT
tristate
depends on FB
- ---help---
+ help
Include the cfb_fillrect function for generic software rectangle
filling. This is used by drivers that don't provide their own
(accelerated) version.
@@ -84,7 +84,7 @@ config FB_CFB_FILLRECT
config FB_CFB_COPYAREA
tristate
depends on FB
- ---help---
+ help
Include the cfb_copyarea function for generic software area copying.
This is used by drivers that don't provide their own (accelerated)
version.
@@ -92,7 +92,7 @@ config FB_CFB_COPYAREA
config FB_CFB_IMAGEBLIT
tristate
depends on FB
- ---help---
+ help
Include the cfb_imageblit function for generic software image
blitting. This is used by drivers that don't provide their own
(accelerated) version.
@@ -100,7 +100,7 @@ config FB_CFB_IMAGEBLIT
config FB_CFB_REV_PIXELS_IN_BYTE
bool
depends on FB
- ---help---
+ help
Allow generic frame-buffer functions to work on displays with 1, 2
and 4 bits per pixel depths which has opposite order of pixels in
byte order to bytes in long order.
@@ -108,7 +108,7 @@ config FB_CFB_REV_PIXELS_IN_BYTE
config FB_SYS_FILLRECT
tristate
depends on FB
- ---help---
+ help
Include the sys_fillrect function for generic software rectangle
filling. This is used by drivers that don't provide their own
(accelerated) version and the framebuffer is in system RAM.
@@ -116,7 +116,7 @@ config FB_SYS_FILLRECT
config FB_SYS_COPYAREA
tristate
depends on FB
- ---help---
+ help
Include the sys_copyarea function for generic software area copying.
This is used by drivers that don't provide their own (accelerated)
version and the framebuffer is in system RAM.
@@ -124,7 +124,7 @@ config FB_SYS_COPYAREA
config FB_SYS_IMAGEBLIT
tristate
depends on FB
- ---help---
+ help
Include the sys_imageblit function for generic software image
blitting. This is used by drivers that don't provide their own
(accelerated) version and the framebuffer is in system RAM.
@@ -132,14 +132,14 @@ config FB_SYS_IMAGEBLIT
config FB_PROVIDE_GET_FB_UNMAPPED_AREA
bool
depends on FB
- ---help---
+ help
Allow generic frame-buffer to provide get_fb_unmapped_area
function.
menuconfig FB_FOREIGN_ENDIAN
bool "Framebuffer foreign endianness support"
depends on FB
- ---help---
+ help
This menu will let you enable support for the framebuffers with
non-native endianness (e.g. Little-Endian framebuffer on a
Big-Endian machine). Most probably you don't have such hardware,
@@ -176,7 +176,7 @@ config FB_HECUBA
config FB_SVGALIB
tristate
depends on FB
- ---help---
+ help
Common utility functions useful to fbdev drivers of VGA-based
cards.
@@ -192,7 +192,7 @@ config FB_BACKLIGHT
config FB_MODE_HELPERS
bool "Enable Video Mode Handling Helpers"
depends on FB
- ---help---
+ help
This enables functions for handling video modes using the
Generalized Timing Formula and the EDID parser. A few drivers rely
on this feature such as the radeonfb, rivafb, and the i810fb. If
@@ -202,7 +202,7 @@ config FB_MODE_HELPERS
config FB_TILEBLITTING
bool "Enable Tile Blitting Support"
depends on FB
- ---help---
+ help
This enables tile blitting. Tile blitting is a drawing technique
where the screen is divided into rectangular sections (tiles), whereas
the standard blitting divides the screen into pixels. Because the
@@ -225,7 +225,7 @@ config FB_GRVGA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
config FB_CIRRUS
@@ -234,7 +234,7 @@ config FB_CIRRUS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
This enables support for Cirrus Logic GD542x/543x based boards on
Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -553,7 +553,7 @@ config FB_STI
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
default y
- ---help---
+ help
STI refers to the HP "Standard Text Interface" which is a set of
BIOS routines contained in a ROM chip in HP PA-RISC based machines.
Enabling this option will implement the linux framebuffer device
@@ -587,7 +587,7 @@ config FB_TGA
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
- ---help---
+ help
This is the frame buffer device driver for generic TGA and SFB+
graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
@@ -815,7 +815,7 @@ config FB_PVR2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Say Y here if you have a PowerVR 2 card in your box. If you plan to
run linux on your Dreamcast, you will have to say Y here.
This driver may or may not work on other PowerVR 2 cards, but is
@@ -1066,7 +1066,7 @@ config FB_INTEL
config FB_INTEL_DEBUG
bool "Intel driver Debug Messages"
depends on FB_INTEL
- ---help---
+ help
Say Y here if you want the Intel driver to output all sorts
of debugging information to provide to the maintainer when
something goes wrong.
@@ -1087,7 +1087,7 @@ config FB_MATROX
select FB_CFB_IMAGEBLIT
select FB_TILEBLITTING
select FB_MACMODES if PPC_PMAC
- ---help---
+ help
Say Y here if you have a Matrox Millennium, Matrox Millennium II,
Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
@@ -1123,7 +1123,7 @@ config FB_MATROX_MYSTIQUE
config FB_MATROX_G
bool "G100/G200/G400/G450/G550 support"
depends on FB_MATROX
- ---help---
+ help
Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
video card. If you select "Advanced lowlevel driver options", you
should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
@@ -1154,7 +1154,7 @@ config FB_MATROX_I2C
tristate "Matrox I2C support"
depends on FB_MATROX
select FB_DDC
- ---help---
+ help
This drivers creates I2C buses which are needed for accessing the
DDC (I2C) bus present on all Matroxes, an I2C bus which
interconnects Matrox optional devices, like MGA-TVO on G200 and
@@ -1170,7 +1170,7 @@ config FB_MATROX_I2C
config FB_MATROX_MAVEN
tristate "G400 second head support"
depends on FB_MATROX_G && FB_MATROX_I2C
- ---help---
+ help
WARNING !!! This support does not work with G450 !!!
Say Y or M here if you want to use a secondary head (meaning two
@@ -1321,7 +1321,7 @@ config FB_S3
select FB_SVGALIB
select VGASTATE
select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
+ help
Driver for graphics boards with S3 Trio / S3 Virge chip.
config FB_S3_DDC
@@ -1484,7 +1484,7 @@ config FB_3DFX
config FB_3DFX_ACCEL
bool "3Dfx Acceleration functions"
depends on FB_3DFX
- ---help---
+ help
This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
device driver with acceleration functions.
@@ -1502,7 +1502,7 @@ config FB_VOODOO1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
Voodoo2 (cvg) based graphics card.
@@ -1524,7 +1524,7 @@ config FB_VT8623
select FB_SVGALIB
select VGASTATE
select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
+ help
Driver for CastleRock integrated graphics core in the
VIA VT8623 [Apollo CLE266] chipset.
@@ -1536,7 +1536,7 @@ config FB_TRIDENT
select FB_CFB_IMAGEBLIT
select FB_DDC
select FB_MODE_HELPERS
- ---help---
+ help
This is the frame buffer device driver for Trident PCI/AGP chipsets.
Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
and Blade XP.
@@ -1560,7 +1560,7 @@ config FB_ARK
select FB_SVGALIB
select VGASTATE
select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
+ help
Driver for PCI graphics boards with ARK 2000PV chip
and ICS 5342 RAMDAC.
@@ -1738,7 +1738,7 @@ config FB_PXA168
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for the built-in LCD controller in the Marvell
MMP processor.
@@ -1750,7 +1750,7 @@ config FB_PXA
select FB_CFB_IMAGEBLIT
select VIDEOMODE_HELPERS if OF
select FB_MODE_HELPERS if OF
- ---help---
+ help
Frame buffer driver for the built-in LCD controller in the Intel
PXA2x0 processor.
@@ -1772,7 +1772,7 @@ config FB_PXA_SMARTPANEL
config FB_PXA_PARAMETERS
bool "PXA LCD command line parameters"
depends on FB_PXA
- ---help---
+ help
Enable the use of kernel command line or module parameters
to configure the physical properties of the LCD panel when
using the PXA LCD driver.
@@ -1801,14 +1801,14 @@ config FB_MBX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Framebuffer driver for the Intel 2700G (Marathon) Graphics
Accelerator
config FB_MBX_DEBUG
bool "Enable debugging info via debugfs"
depends on FB_MBX && DEBUG_FS
- ---help---
+ help
Enable this if you want debugging information using the debug
filesystem (debugfs)
@@ -1822,7 +1822,7 @@ config FB_FSL_DIU
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select PPC_LIB_RHEAP
- ---help---
+ help
Framebuffer driver for the Freescale SoC DIU
config FB_W100
@@ -1831,7 +1831,7 @@ config FB_W100
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
It can also drive the w3220 chip found on iPAQ hx4700.
@@ -1852,7 +1852,7 @@ config FB_SH_MOBILE_LCDC
select FB_SYS_FOPS
select FB_DEFERRED_IO
select FB_BACKLIGHT
- ---help---
+ help
Frame buffer driver for the on-chip SH-Mobile LCD controller.
config FB_TMIO
@@ -1861,7 +1861,7 @@ config FB_TMIO
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for the Toshiba Mobile IO integrated as found
on the Sharp SL-6000 series
@@ -1884,7 +1884,7 @@ config FB_S3C
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for the built-in FB controller in the Samsung
SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
and the S3C64XX series such as the S3C6400 and S3C6410.
@@ -1899,7 +1899,7 @@ config FB_S3C
config FB_S3C_DEBUG_REGWRITE
bool "Debug register writes"
depends on FB_S3C
- ---help---
+ help
Show all register writes via pr_debug()
config FB_S3C2410
@@ -1908,7 +1908,7 @@ config FB_S3C2410
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for the built-in LCD controller in the Samsung
S3C2410 processor.
@@ -1931,7 +1931,7 @@ config FB_SM501
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for the CRT and LCD controllers in the Silicon
Motion SM501.
@@ -1951,7 +1951,7 @@ config FB_SMSCUFX
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
select FB_DEFERRED_IO
- ---help---
+ help
This is a kernel framebuffer driver for SMSC UFX USB devices.
Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
@@ -1967,7 +1967,7 @@ config FB_UDL
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
select FB_DEFERRED_IO
- ---help---
+ help
This is a kernel framebuffer driver for DisplayLink USB devices.
Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
@@ -1979,7 +1979,7 @@ config FB_IBM_GXT4500
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Say Y here to enable support for the IBM GXT4000P/6000P and
GXT4500P/6500P display adaptor based on Raster Engine RC1000,
found on some IBM System P (pSeries) machines. This driver
@@ -1993,14 +1993,14 @@ config FB_PS3
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
- ---help---
+ help
Include support for the virtual frame buffer in the PS3 platform.
config FB_PS3_DEFAULT_SIZE_M
int "PS3 default frame buffer size (in MiB)"
depends on FB_PS3
default 9
- ---help---
+ help
This is the default size (in MiB) of the virtual frame buffer in
the PS3.
The default value can be overridden on the kernel command line
@@ -2012,7 +2012,7 @@ config FB_XILINX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Include support for the Xilinx ML300/ML403 reference design
framebuffer. ML300 carries a 640*480 LCD display on the board,
ML403 uses a standard DB15 VGA connector.
@@ -2024,7 +2024,7 @@ config FB_GOLDFISH
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Framebuffer driver for Goldfish Virtual Platform
config FB_COBALT
@@ -2038,7 +2038,7 @@ config FB_SH7760
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Support for the SH7760/SH7763/SH7720/SH7721 integrated
(D)STN/TFT LCD Controller.
Supports display resolutions up to 1024x1024 pixel, grayscale and
@@ -2056,7 +2056,7 @@ config FB_DA8XX
select FB_CFB_REV_PIXELS_IN_BYTE
select FB_MODE_HELPERS
select VIDEOMODE_HELPERS
- ---help---
+ help
This is the frame buffer device driver for the TI LCD controller
found on DA8xx/OMAP-L1xx/AM335x SoCs.
If unsure, say N.
@@ -2068,7 +2068,7 @@ config FB_VIRTUAL
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
- ---help---
+ help
This is a `virtual' frame buffer device. It operates on a chunk of
unswappable kernel memory instead of on the memory of a graphics
board. This means you cannot see any output sent to this frame
@@ -2119,7 +2119,7 @@ config FB_MB862XX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
choice
@@ -2129,7 +2129,7 @@ choice
config FB_MB862XX_PCI_GDC
bool "Carmine/Coral-P(A) GDC"
depends on PCI
- ---help---
+ help
This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
PCI graphics controller devices.
@@ -2138,7 +2138,7 @@ config FB_MB862XX_LIME
depends on OF && PPC
select FB_FOREIGN_ENDIAN
select FB_LITTLE_ENDIAN
- ---help---
+ help
Framebuffer support for Fujitsu Lime GDC on host CPU bus.
endchoice
@@ -2159,7 +2159,7 @@ config FB_EP93XX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Framebuffer driver for the Cirrus Logic EP93XX series of processors.
This driver is also available as a module. The module will be called
ep93xx-fb.
@@ -2167,7 +2167,7 @@ config FB_EP93XX
config FB_PRE_INIT_FB
bool "Don't reinitialize, use bootloader's GDC/Display configuration"
depends on FB && FB_MB862XX_LIME
- ---help---
+ help
Select this option if display contents should be inherited as set by
the bootloader.
diff --git a/drivers/video/fbdev/acornfb.c b/drivers/video/fbdev/acornfb.c
index a3af49529173..09a9ad901dad 100644
--- a/drivers/video/fbdev/acornfb.c
+++ b/drivers/video/fbdev/acornfb.c
@@ -30,7 +30,6 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/pgtable.h>
#include "acornfb.h"
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index 51f5d1c56fd9..f253daa05d9d 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -58,7 +58,6 @@
#include <asm/setup.h>
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index c3a3e344cee3..3df64a973194 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -42,7 +42,6 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <asm/pgtable.h>
#ifdef CONFIG_ZORRO
#include <linux/zorro.h>
diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index 513f58f28b0f..42d37bed518a 100644
--- a/drivers/video/fbdev/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
@@ -47,7 +47,6 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <asm/pgtable.h>
#ifdef __arm__
#include <asm/mach-types.h>
diff --git a/drivers/video/fbdev/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c
index 75df6aabac21..030e85c11a78 100644
--- a/drivers/video/fbdev/fb-puv3.c
+++ b/drivers/video/fbdev/fb-puv3.c
@@ -18,7 +18,6 @@
#include <linux/mm.h>
#include <linux/sizes.h>
-#include <asm/pgtable.h>
#include <mach/hardware.h>
/* Platform_data reserved for unifb registers. */
diff --git a/drivers/video/fbdev/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig
index b36b94b3ae43..ac9c860592aa 100644
--- a/drivers/video/fbdev/geode/Kconfig
+++ b/drivers/video/fbdev/geode/Kconfig
@@ -5,7 +5,7 @@
config FB_GEODE
bool "AMD Geode family framebuffer support"
depends on FB && PCI && (X86_32 || (X86 && COMPILE_TEST))
- ---help---
+ help
Say 'Y' here to allow you to select framebuffer drivers for
the AMD Geode family of processors.
@@ -15,7 +15,7 @@ config FB_GEODE_LX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Framebuffer driver for the display controller integrated into the
AMD Geode LX processors.
@@ -30,7 +30,7 @@ config FB_GEODE_GX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Framebuffer driver for the display controller integrated into the
AMD Geode GX processors.
@@ -45,7 +45,7 @@ config FB_GEODE_GX1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- ---help---
+ help
Framebuffer driver for the display controller integrated into the
AMD Geode GX1 processor.
diff --git a/drivers/video/fbdev/hitfb.c b/drivers/video/fbdev/hitfb.c
index 009e5d2aa100..bbb0f1d953cc 100644
--- a/drivers/video/fbdev/hitfb.c
+++ b/drivers/video/fbdev/hitfb.c
@@ -23,7 +23,6 @@
#include <asm/machvec.h>
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/hd64461.h>
#include <cpu/dac.h>
diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c
index e6ea853c1723..f5a676bfd67a 100644
--- a/drivers/video/fbdev/neofb.c
+++ b/drivers/video/fbdev/neofb.c
@@ -70,7 +70,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/pgtable.h>
#include <video/vga.h>
#include <video/neomagic.h>
diff --git a/drivers/video/fbdev/q40fb.c b/drivers/video/fbdev/q40fb.c
index 79ff14a35c85..079a2a7fb2c5 100644
--- a/drivers/video/fbdev/q40fb.c
+++ b/drivers/video/fbdev/q40fb.c
@@ -23,7 +23,6 @@
#include <asm/q40_master.h>
#include <linux/fb.h>
#include <linux/module.h>
-#include <asm/pgtable.h>
#define Q40_PHYS_SCREEN_ADDR 0xFE800000
diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index aab312a7d9da..3c8ae87f0ea7 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -55,7 +55,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/pgtable.h>
#include "savagefb.h"
diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index 363af2eaf2ba..cbc1f25c79ab 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -5,7 +5,7 @@
menuconfig VIRT_DRIVERS
bool "Virtualization drivers"
- ---help---
+ help
Say Y here to get to see options for device drivers that support
virtualization environments.
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 69a32dfc318a..5809e5f5b157 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config VIRTIO
tristate
- ---help---
+ help
This option is selected by any driver which implements the virtio
bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG
or CONFIG_S390_GUEST.
@@ -16,7 +16,7 @@ config VIRTIO_PCI
tristate "PCI driver for virtio devices"
depends on PCI
select VIRTIO
- ---help---
+ help
This driver provides support for virtio based paravirtual device
drivers over PCI. This requires that your VMM has appropriate PCI
virtio backends. Most QEMU based VMMs should support these devices
@@ -28,7 +28,7 @@ config VIRTIO_PCI_LEGACY
bool "Support for legacy virtio draft 0.9.X and older devices"
default y
depends on VIRTIO_PCI
- ---help---
+ help
Virtio PCI Card 0.9.X Draft (circa 2014) and older device support.
This option enables building a transitional driver, supporting
@@ -72,17 +72,34 @@ config VIRTIO_BALLOON
depends on VIRTIO
select MEMORY_BALLOON
select PAGE_REPORTING
- ---help---
+ help
This driver supports increasing and decreasing the amount
of memory within a KVM guest.
If unsure, say M.
+config VIRTIO_MEM
+ tristate "Virtio mem driver"
+ default m
+ depends on X86_64
+ depends on VIRTIO
+ depends on MEMORY_HOTPLUG_SPARSE
+ depends on MEMORY_HOTREMOVE
+ select CONTIG_ALLOC
+ help
+ This driver provides access to virtio-mem paravirtualized memory
+ devices, allowing to hotplug and hotunplug memory.
+
+ This driver was only tested under x86-64, but should theoretically
+ work on all architectures that support memory hotplug and hotremove.
+
+ If unsure, say M.
+
config VIRTIO_INPUT
tristate "Virtio input driver"
depends on VIRTIO
depends on INPUT
- ---help---
+ help
This driver supports virtio input devices such as
keyboards, mice and tablets.
@@ -92,7 +109,7 @@ config VIRTIO_MMIO
tristate "Platform bus driver for memory mapped virtio devices"
depends on HAS_IOMEM && HAS_DMA
select VIRTIO
- ---help---
+ help
This drivers provides support for memory mapped virtio
platform device driver.
@@ -101,7 +118,7 @@ config VIRTIO_MMIO
config VIRTIO_MMIO_CMDLINE_DEVICES
bool "Memory mapped virtio devices parameter parsing"
depends on VIRTIO_MMIO
- ---help---
+ help
Allow virtio-mmio devices instantiation via the kernel command line
or module parameters. Be aware that using incorrect parameters (base
address in particular) can crash your system - you have been warned.
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 29a1386ecc03..4d993791f2d7 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -7,3 +7,4 @@ virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
obj-$(CONFIG_VIRTIO_VDPA) += virtio_vdpa.o
+obj-$(CONFIG_VIRTIO_MEM) += virtio_mem.o
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 51086a5afdd4..1f157d2f4952 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -1107,11 +1107,18 @@ static int virtballoon_restore(struct virtio_device *vdev)
static int virtballoon_validate(struct virtio_device *vdev)
{
- /* Tell the host whether we care about poisoned pages. */
+ /*
+ * Inform the hypervisor that our pages are poisoned or
+ * initialized. If we cannot do that then we should disable
+ * page reporting as it could potentially change the contents
+ * of our free pages.
+ */
if (!want_init_on_free() &&
(IS_ENABLED(CONFIG_PAGE_POISONING_NO_SANITY) ||
!page_poisoning_enabled()))
__virtio_clear_bit(vdev, VIRTIO_BALLOON_F_PAGE_POISON);
+ else if (!virtio_has_feature(vdev, VIRTIO_BALLOON_F_PAGE_POISON))
+ __virtio_clear_bit(vdev, VIRTIO_BALLOON_F_REPORTING);
__virtio_clear_bit(vdev, VIRTIO_F_IOMMU_PLATFORM);
return 0;
diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
new file mode 100644
index 000000000000..50c689f25045
--- /dev/null
+++ b/drivers/virtio/virtio_mem.c
@@ -0,0 +1,1965 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Virtio-mem device driver.
+ *
+ * Copyright Red Hat, Inc. 2020
+ *
+ * Author(s): David Hildenbrand <david@redhat.com>
+ */
+
+#include <linux/virtio.h>
+#include <linux/virtio_mem.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/memory_hotplug.h>
+#include <linux/memory.h>
+#include <linux/hrtimer.h>
+#include <linux/crash_dump.h>
+#include <linux/mutex.h>
+#include <linux/bitmap.h>
+#include <linux/lockdep.h>
+
+#include <acpi/acpi_numa.h>
+
+static bool unplug_online = true;
+module_param(unplug_online, bool, 0644);
+MODULE_PARM_DESC(unplug_online, "Try to unplug online memory");
+
+enum virtio_mem_mb_state {
+ /* Unplugged, not added to Linux. Can be reused later. */
+ VIRTIO_MEM_MB_STATE_UNUSED = 0,
+ /* (Partially) plugged, not added to Linux. Error on add_memory(). */
+ VIRTIO_MEM_MB_STATE_PLUGGED,
+ /* Fully plugged, fully added to Linux, offline. */
+ VIRTIO_MEM_MB_STATE_OFFLINE,
+ /* Partially plugged, fully added to Linux, offline. */
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL,
+ /* Fully plugged, fully added to Linux, online (!ZONE_MOVABLE). */
+ VIRTIO_MEM_MB_STATE_ONLINE,
+ /* Partially plugged, fully added to Linux, online (!ZONE_MOVABLE). */
+ VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL,
+ /*
+ * Fully plugged, fully added to Linux, online (ZONE_MOVABLE).
+ * We are not allowed to allocate (unplug) parts of this block that
+ * are not movable (similar to gigantic pages). We will never allow
+ * to online OFFLINE_PARTIAL to ZONE_MOVABLE (as they would contain
+ * unmovable parts).
+ */
+ VIRTIO_MEM_MB_STATE_ONLINE_MOVABLE,
+ VIRTIO_MEM_MB_STATE_COUNT
+};
+
+struct virtio_mem {
+ struct virtio_device *vdev;
+
+ /* We might first have to unplug all memory when starting up. */
+ bool unplug_all_required;
+
+ /* Workqueue that processes the plug/unplug requests. */
+ struct work_struct wq;
+ atomic_t config_changed;
+
+ /* Virtqueue for guest->host requests. */
+ struct virtqueue *vq;
+
+ /* Wait for a host response to a guest request. */
+ wait_queue_head_t host_resp;
+
+ /* Space for one guest request and the host response. */
+ struct virtio_mem_req req;
+ struct virtio_mem_resp resp;
+
+ /* The current size of the device. */
+ uint64_t plugged_size;
+ /* The requested size of the device. */
+ uint64_t requested_size;
+
+ /* The device block size (for communicating with the device). */
+ uint64_t device_block_size;
+ /* The translated node id. NUMA_NO_NODE in case not specified. */
+ int nid;
+ /* Physical start address of the memory region. */
+ uint64_t addr;
+ /* Maximum region size in bytes. */
+ uint64_t region_size;
+
+ /* The subblock size. */
+ uint64_t subblock_size;
+ /* The number of subblocks per memory block. */
+ uint32_t nb_sb_per_mb;
+
+ /* Id of the first memory block of this device. */
+ unsigned long first_mb_id;
+ /* Id of the last memory block of this device. */
+ unsigned long last_mb_id;
+ /* Id of the last usable memory block of this device. */
+ unsigned long last_usable_mb_id;
+ /* Id of the next memory bock to prepare when needed. */
+ unsigned long next_mb_id;
+
+ /* The parent resource for all memory added via this device. */
+ struct resource *parent_resource;
+
+ /* Summary of all memory block states. */
+ unsigned long nb_mb_state[VIRTIO_MEM_MB_STATE_COUNT];
+#define VIRTIO_MEM_NB_OFFLINE_THRESHOLD 10
+
+ /*
+ * One byte state per memory block.
+ *
+ * Allocated via vmalloc(). When preparing new blocks, resized
+ * (alloc+copy+free) when needed (crossing pages with the next mb).
+ * (when crossing pages).
+ *
+ * With 128MB memory blocks, we have states for 512GB of memory in one
+ * page.
+ */
+ uint8_t *mb_state;
+
+ /*
+ * $nb_sb_per_mb bit per memory block. Handled similar to mb_state.
+ *
+ * With 4MB subblocks, we manage 128GB of memory in one page.
+ */
+ unsigned long *sb_bitmap;
+
+ /*
+ * Mutex that protects the nb_mb_state, mb_state, and sb_bitmap.
+ *
+ * When this lock is held the pointers can't change, ONLINE and
+ * OFFLINE blocks can't change the state and no subblocks will get
+ * plugged/unplugged.
+ */
+ struct mutex hotplug_mutex;
+ bool hotplug_active;
+
+ /* An error occurred we cannot handle - stop processing requests. */
+ bool broken;
+
+ /* The driver is being removed. */
+ spinlock_t removal_lock;
+ bool removing;
+
+ /* Timer for retrying to plug/unplug memory. */
+ struct hrtimer retry_timer;
+ unsigned int retry_timer_ms;
+#define VIRTIO_MEM_RETRY_TIMER_MIN_MS 50000
+#define VIRTIO_MEM_RETRY_TIMER_MAX_MS 300000
+
+ /* Memory notifier (online/offline events). */
+ struct notifier_block memory_notifier;
+
+ /* Next device in the list of virtio-mem devices. */
+ struct list_head next;
+};
+
+/*
+ * We have to share a single online_page callback among all virtio-mem
+ * devices. We use RCU to iterate the list in the callback.
+ */
+static DEFINE_MUTEX(virtio_mem_mutex);
+static LIST_HEAD(virtio_mem_devices);
+
+static void virtio_mem_online_page_cb(struct page *page, unsigned int order);
+
+/*
+ * Register a virtio-mem device so it will be considered for the online_page
+ * callback.
+ */
+static int register_virtio_mem_device(struct virtio_mem *vm)
+{
+ int rc = 0;
+
+ /* First device registers the callback. */
+ mutex_lock(&virtio_mem_mutex);
+ if (list_empty(&virtio_mem_devices))
+ rc = set_online_page_callback(&virtio_mem_online_page_cb);
+ if (!rc)
+ list_add_rcu(&vm->next, &virtio_mem_devices);
+ mutex_unlock(&virtio_mem_mutex);
+
+ return rc;
+}
+
+/*
+ * Unregister a virtio-mem device so it will no longer be considered for the
+ * online_page callback.
+ */
+static void unregister_virtio_mem_device(struct virtio_mem *vm)
+{
+ /* Last device unregisters the callback. */
+ mutex_lock(&virtio_mem_mutex);
+ list_del_rcu(&vm->next);
+ if (list_empty(&virtio_mem_devices))
+ restore_online_page_callback(&virtio_mem_online_page_cb);
+ mutex_unlock(&virtio_mem_mutex);
+
+ synchronize_rcu();
+}
+
+/*
+ * Calculate the memory block id of a given address.
+ */
+static unsigned long virtio_mem_phys_to_mb_id(unsigned long addr)
+{
+ return addr / memory_block_size_bytes();
+}
+
+/*
+ * Calculate the physical start address of a given memory block id.
+ */
+static unsigned long virtio_mem_mb_id_to_phys(unsigned long mb_id)
+{
+ return mb_id * memory_block_size_bytes();
+}
+
+/*
+ * Calculate the subblock id of a given address.
+ */
+static unsigned long virtio_mem_phys_to_sb_id(struct virtio_mem *vm,
+ unsigned long addr)
+{
+ const unsigned long mb_id = virtio_mem_phys_to_mb_id(addr);
+ const unsigned long mb_addr = virtio_mem_mb_id_to_phys(mb_id);
+
+ return (addr - mb_addr) / vm->subblock_size;
+}
+
+/*
+ * Set the state of a memory block, taking care of the state counter.
+ */
+static void virtio_mem_mb_set_state(struct virtio_mem *vm, unsigned long mb_id,
+ enum virtio_mem_mb_state state)
+{
+ const unsigned long idx = mb_id - vm->first_mb_id;
+ enum virtio_mem_mb_state old_state;
+
+ old_state = vm->mb_state[idx];
+ vm->mb_state[idx] = state;
+
+ BUG_ON(vm->nb_mb_state[old_state] == 0);
+ vm->nb_mb_state[old_state]--;
+ vm->nb_mb_state[state]++;
+}
+
+/*
+ * Get the state of a memory block.
+ */
+static enum virtio_mem_mb_state virtio_mem_mb_get_state(struct virtio_mem *vm,
+ unsigned long mb_id)
+{
+ const unsigned long idx = mb_id - vm->first_mb_id;
+
+ return vm->mb_state[idx];
+}
+
+/*
+ * Prepare the state array for the next memory block.
+ */
+static int virtio_mem_mb_state_prepare_next_mb(struct virtio_mem *vm)
+{
+ unsigned long old_bytes = vm->next_mb_id - vm->first_mb_id + 1;
+ unsigned long new_bytes = vm->next_mb_id - vm->first_mb_id + 2;
+ int old_pages = PFN_UP(old_bytes);
+ int new_pages = PFN_UP(new_bytes);
+ uint8_t *new_mb_state;
+
+ if (vm->mb_state && old_pages == new_pages)
+ return 0;
+
+ new_mb_state = vzalloc(new_pages * PAGE_SIZE);
+ if (!new_mb_state)
+ return -ENOMEM;
+
+ mutex_lock(&vm->hotplug_mutex);
+ if (vm->mb_state)
+ memcpy(new_mb_state, vm->mb_state, old_pages * PAGE_SIZE);
+ vfree(vm->mb_state);
+ vm->mb_state = new_mb_state;
+ mutex_unlock(&vm->hotplug_mutex);
+
+ return 0;
+}
+
+#define virtio_mem_for_each_mb_state(_vm, _mb_id, _state) \
+ for (_mb_id = _vm->first_mb_id; \
+ _mb_id < _vm->next_mb_id && _vm->nb_mb_state[_state]; \
+ _mb_id++) \
+ if (virtio_mem_mb_get_state(_vm, _mb_id) == _state)
+
+#define virtio_mem_for_each_mb_state_rev(_vm, _mb_id, _state) \
+ for (_mb_id = _vm->next_mb_id - 1; \
+ _mb_id >= _vm->first_mb_id && _vm->nb_mb_state[_state]; \
+ _mb_id--) \
+ if (virtio_mem_mb_get_state(_vm, _mb_id) == _state)
+
+/*
+ * Mark all selected subblocks plugged.
+ *
+ * Will not modify the state of the memory block.
+ */
+static void virtio_mem_mb_set_sb_plugged(struct virtio_mem *vm,
+ unsigned long mb_id, int sb_id,
+ int count)
+{
+ const int bit = (mb_id - vm->first_mb_id) * vm->nb_sb_per_mb + sb_id;
+
+ __bitmap_set(vm->sb_bitmap, bit, count);
+}
+
+/*
+ * Mark all selected subblocks unplugged.
+ *
+ * Will not modify the state of the memory block.
+ */
+static void virtio_mem_mb_set_sb_unplugged(struct virtio_mem *vm,
+ unsigned long mb_id, int sb_id,
+ int count)
+{
+ const int bit = (mb_id - vm->first_mb_id) * vm->nb_sb_per_mb + sb_id;
+
+ __bitmap_clear(vm->sb_bitmap, bit, count);
+}
+
+/*
+ * Test if all selected subblocks are plugged.
+ */
+static bool virtio_mem_mb_test_sb_plugged(struct virtio_mem *vm,
+ unsigned long mb_id, int sb_id,
+ int count)
+{
+ const int bit = (mb_id - vm->first_mb_id) * vm->nb_sb_per_mb + sb_id;
+
+ if (count == 1)
+ return test_bit(bit, vm->sb_bitmap);
+
+ /* TODO: Helper similar to bitmap_set() */
+ return find_next_zero_bit(vm->sb_bitmap, bit + count, bit) >=
+ bit + count;
+}
+
+/*
+ * Test if all selected subblocks are unplugged.
+ */
+static bool virtio_mem_mb_test_sb_unplugged(struct virtio_mem *vm,
+ unsigned long mb_id, int sb_id,
+ int count)
+{
+ const int bit = (mb_id - vm->first_mb_id) * vm->nb_sb_per_mb + sb_id;
+
+ /* TODO: Helper similar to bitmap_set() */
+ return find_next_bit(vm->sb_bitmap, bit + count, bit) >= bit + count;
+}
+
+/*
+ * Find the first unplugged subblock. Returns vm->nb_sb_per_mb in case there is
+ * none.
+ */
+static int virtio_mem_mb_first_unplugged_sb(struct virtio_mem *vm,
+ unsigned long mb_id)
+{
+ const int bit = (mb_id - vm->first_mb_id) * vm->nb_sb_per_mb;
+
+ return find_next_zero_bit(vm->sb_bitmap, bit + vm->nb_sb_per_mb, bit) -
+ bit;
+}
+
+/*
+ * Prepare the subblock bitmap for the next memory block.
+ */
+static int virtio_mem_sb_bitmap_prepare_next_mb(struct virtio_mem *vm)
+{
+ const unsigned long old_nb_mb = vm->next_mb_id - vm->first_mb_id;
+ const unsigned long old_nb_bits = old_nb_mb * vm->nb_sb_per_mb;
+ const unsigned long new_nb_bits = (old_nb_mb + 1) * vm->nb_sb_per_mb;
+ int old_pages = PFN_UP(BITS_TO_LONGS(old_nb_bits) * sizeof(long));
+ int new_pages = PFN_UP(BITS_TO_LONGS(new_nb_bits) * sizeof(long));
+ unsigned long *new_sb_bitmap, *old_sb_bitmap;
+
+ if (vm->sb_bitmap && old_pages == new_pages)
+ return 0;
+
+ new_sb_bitmap = vzalloc(new_pages * PAGE_SIZE);
+ if (!new_sb_bitmap)
+ return -ENOMEM;
+
+ mutex_lock(&vm->hotplug_mutex);
+ if (new_sb_bitmap)
+ memcpy(new_sb_bitmap, vm->sb_bitmap, old_pages * PAGE_SIZE);
+
+ old_sb_bitmap = vm->sb_bitmap;
+ vm->sb_bitmap = new_sb_bitmap;
+ mutex_unlock(&vm->hotplug_mutex);
+
+ vfree(old_sb_bitmap);
+ return 0;
+}
+
+/*
+ * Try to add a memory block to Linux. This will usually only fail
+ * if out of memory.
+ *
+ * Must not be called with the vm->hotplug_mutex held (possible deadlock with
+ * onlining code).
+ *
+ * Will not modify the state of the memory block.
+ */
+static int virtio_mem_mb_add(struct virtio_mem *vm, unsigned long mb_id)
+{
+ const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id);
+ int nid = vm->nid;
+
+ if (nid == NUMA_NO_NODE)
+ nid = memory_add_physaddr_to_nid(addr);
+
+ dev_dbg(&vm->vdev->dev, "adding memory block: %lu\n", mb_id);
+ return add_memory(nid, addr, memory_block_size_bytes());
+}
+
+/*
+ * Try to remove a memory block from Linux. Will only fail if the memory block
+ * is not offline.
+ *
+ * Must not be called with the vm->hotplug_mutex held (possible deadlock with
+ * onlining code).
+ *
+ * Will not modify the state of the memory block.
+ */
+static int virtio_mem_mb_remove(struct virtio_mem *vm, unsigned long mb_id)
+{
+ const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id);
+ int nid = vm->nid;
+
+ if (nid == NUMA_NO_NODE)
+ nid = memory_add_physaddr_to_nid(addr);
+
+ dev_dbg(&vm->vdev->dev, "removing memory block: %lu\n", mb_id);
+ return remove_memory(nid, addr, memory_block_size_bytes());
+}
+
+/*
+ * Try to offline and remove a memory block from Linux.
+ *
+ * Must not be called with the vm->hotplug_mutex held (possible deadlock with
+ * onlining code).
+ *
+ * Will not modify the state of the memory block.
+ */
+static int virtio_mem_mb_offline_and_remove(struct virtio_mem *vm,
+ unsigned long mb_id)
+{
+ const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id);
+ int nid = vm->nid;
+
+ if (nid == NUMA_NO_NODE)
+ nid = memory_add_physaddr_to_nid(addr);
+
+ dev_dbg(&vm->vdev->dev, "offlining and removing memory block: %lu\n",
+ mb_id);
+ return offline_and_remove_memory(nid, addr, memory_block_size_bytes());
+}
+
+/*
+ * Trigger the workqueue so the device can perform its magic.
+ */
+static void virtio_mem_retry(struct virtio_mem *vm)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vm->removal_lock, flags);
+ if (!vm->removing)
+ queue_work(system_freezable_wq, &vm->wq);
+ spin_unlock_irqrestore(&vm->removal_lock, flags);
+}
+
+static int virtio_mem_translate_node_id(struct virtio_mem *vm, uint16_t node_id)
+{
+ int node = NUMA_NO_NODE;
+
+#if defined(CONFIG_ACPI_NUMA)
+ if (virtio_has_feature(vm->vdev, VIRTIO_MEM_F_ACPI_PXM))
+ node = pxm_to_node(node_id);
+#endif
+ return node;
+}
+
+/*
+ * Test if a virtio-mem device overlaps with the given range. Can be called
+ * from (notifier) callbacks lockless.
+ */
+static bool virtio_mem_overlaps_range(struct virtio_mem *vm,
+ unsigned long start, unsigned long size)
+{
+ unsigned long dev_start = virtio_mem_mb_id_to_phys(vm->first_mb_id);
+ unsigned long dev_end = virtio_mem_mb_id_to_phys(vm->last_mb_id) +
+ memory_block_size_bytes();
+
+ return start < dev_end && dev_start < start + size;
+}
+
+/*
+ * Test if a virtio-mem device owns a memory block. Can be called from
+ * (notifier) callbacks lockless.
+ */
+static bool virtio_mem_owned_mb(struct virtio_mem *vm, unsigned long mb_id)
+{
+ return mb_id >= vm->first_mb_id && mb_id <= vm->last_mb_id;
+}
+
+static int virtio_mem_notify_going_online(struct virtio_mem *vm,
+ unsigned long mb_id,
+ enum zone_type zone)
+{
+ switch (virtio_mem_mb_get_state(vm, mb_id)) {
+ case VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL:
+ /*
+ * We won't allow to online a partially plugged memory block
+ * to the MOVABLE zone - it would contain unmovable parts.
+ */
+ if (zone == ZONE_MOVABLE) {
+ dev_warn_ratelimited(&vm->vdev->dev,
+ "memory block has holes, MOVABLE not supported\n");
+ return NOTIFY_BAD;
+ }
+ return NOTIFY_OK;
+ case VIRTIO_MEM_MB_STATE_OFFLINE:
+ return NOTIFY_OK;
+ default:
+ break;
+ }
+ dev_warn_ratelimited(&vm->vdev->dev,
+ "memory block onlining denied\n");
+ return NOTIFY_BAD;
+}
+
+static void virtio_mem_notify_offline(struct virtio_mem *vm,
+ unsigned long mb_id)
+{
+ switch (virtio_mem_mb_get_state(vm, mb_id)) {
+ case VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL:
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL);
+ break;
+ case VIRTIO_MEM_MB_STATE_ONLINE:
+ case VIRTIO_MEM_MB_STATE_ONLINE_MOVABLE:
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE);
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ /*
+ * Trigger the workqueue, maybe we can now unplug memory. Also,
+ * when we offline and remove a memory block, this will re-trigger
+ * us immediately - which is often nice because the removal of
+ * the memory block (e.g., memmap) might have freed up memory
+ * on other memory blocks we manage.
+ */
+ virtio_mem_retry(vm);
+}
+
+static void virtio_mem_notify_online(struct virtio_mem *vm, unsigned long mb_id,
+ enum zone_type zone)
+{
+ unsigned long nb_offline;
+
+ switch (virtio_mem_mb_get_state(vm, mb_id)) {
+ case VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL:
+ BUG_ON(zone == ZONE_MOVABLE);
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL);
+ break;
+ case VIRTIO_MEM_MB_STATE_OFFLINE:
+ if (zone == ZONE_MOVABLE)
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE_MOVABLE);
+ else
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ nb_offline = vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE] +
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL];
+
+ /* see if we can add new blocks now that we onlined one block */
+ if (nb_offline == VIRTIO_MEM_NB_OFFLINE_THRESHOLD - 1)
+ virtio_mem_retry(vm);
+}
+
+static void virtio_mem_notify_going_offline(struct virtio_mem *vm,
+ unsigned long mb_id)
+{
+ const unsigned long nr_pages = PFN_DOWN(vm->subblock_size);
+ struct page *page;
+ unsigned long pfn;
+ int sb_id, i;
+
+ for (sb_id = 0; sb_id < vm->nb_sb_per_mb; sb_id++) {
+ if (virtio_mem_mb_test_sb_plugged(vm, mb_id, sb_id, 1))
+ continue;
+ /*
+ * Drop our reference to the pages so the memory can get
+ * offlined and add the unplugged pages to the managed
+ * page counters (so offlining code can correctly subtract
+ * them again).
+ */
+ pfn = PFN_DOWN(virtio_mem_mb_id_to_phys(mb_id) +
+ sb_id * vm->subblock_size);
+ adjust_managed_page_count(pfn_to_page(pfn), nr_pages);
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(pfn + i);
+ if (WARN_ON(!page_ref_dec_and_test(page)))
+ dump_page(page, "unplugged page referenced");
+ }
+ }
+}
+
+static void virtio_mem_notify_cancel_offline(struct virtio_mem *vm,
+ unsigned long mb_id)
+{
+ const unsigned long nr_pages = PFN_DOWN(vm->subblock_size);
+ unsigned long pfn;
+ int sb_id, i;
+
+ for (sb_id = 0; sb_id < vm->nb_sb_per_mb; sb_id++) {
+ if (virtio_mem_mb_test_sb_plugged(vm, mb_id, sb_id, 1))
+ continue;
+ /*
+ * Get the reference we dropped when going offline and
+ * subtract the unplugged pages from the managed page
+ * counters.
+ */
+ pfn = PFN_DOWN(virtio_mem_mb_id_to_phys(mb_id) +
+ sb_id * vm->subblock_size);
+ adjust_managed_page_count(pfn_to_page(pfn), -nr_pages);
+ for (i = 0; i < nr_pages; i++)
+ page_ref_inc(pfn_to_page(pfn + i));
+ }
+}
+
+/*
+ * This callback will either be called synchronously from add_memory() or
+ * asynchronously (e.g., triggered via user space). We have to be careful
+ * with locking when calling add_memory().
+ */
+static int virtio_mem_memory_notifier_cb(struct notifier_block *nb,
+ unsigned long action, void *arg)
+{
+ struct virtio_mem *vm = container_of(nb, struct virtio_mem,
+ memory_notifier);
+ struct memory_notify *mhp = arg;
+ const unsigned long start = PFN_PHYS(mhp->start_pfn);
+ const unsigned long size = PFN_PHYS(mhp->nr_pages);
+ const unsigned long mb_id = virtio_mem_phys_to_mb_id(start);
+ enum zone_type zone;
+ int rc = NOTIFY_OK;
+
+ if (!virtio_mem_overlaps_range(vm, start, size))
+ return NOTIFY_DONE;
+
+ /*
+ * Memory is onlined/offlined in memory block granularity. We cannot
+ * cross virtio-mem device boundaries and memory block boundaries. Bail
+ * out if this ever changes.
+ */
+ if (WARN_ON_ONCE(size != memory_block_size_bytes() ||
+ !IS_ALIGNED(start, memory_block_size_bytes())))
+ return NOTIFY_BAD;
+
+ /*
+ * Avoid circular locking lockdep warnings. We lock the mutex
+ * e.g., in MEM_GOING_ONLINE and unlock it in MEM_ONLINE. The
+ * blocking_notifier_call_chain() has it's own lock, which gets unlocked
+ * between both notifier calls and will bail out. False positive.
+ */
+ lockdep_off();
+
+ switch (action) {
+ case MEM_GOING_OFFLINE:
+ mutex_lock(&vm->hotplug_mutex);
+ if (vm->removing) {
+ rc = notifier_from_errno(-EBUSY);
+ mutex_unlock(&vm->hotplug_mutex);
+ break;
+ }
+ vm->hotplug_active = true;
+ virtio_mem_notify_going_offline(vm, mb_id);
+ break;
+ case MEM_GOING_ONLINE:
+ mutex_lock(&vm->hotplug_mutex);
+ if (vm->removing) {
+ rc = notifier_from_errno(-EBUSY);
+ mutex_unlock(&vm->hotplug_mutex);
+ break;
+ }
+ vm->hotplug_active = true;
+ zone = page_zonenum(pfn_to_page(mhp->start_pfn));
+ rc = virtio_mem_notify_going_online(vm, mb_id, zone);
+ break;
+ case MEM_OFFLINE:
+ virtio_mem_notify_offline(vm, mb_id);
+ vm->hotplug_active = false;
+ mutex_unlock(&vm->hotplug_mutex);
+ break;
+ case MEM_ONLINE:
+ zone = page_zonenum(pfn_to_page(mhp->start_pfn));
+ virtio_mem_notify_online(vm, mb_id, zone);
+ vm->hotplug_active = false;
+ mutex_unlock(&vm->hotplug_mutex);
+ break;
+ case MEM_CANCEL_OFFLINE:
+ if (!vm->hotplug_active)
+ break;
+ virtio_mem_notify_cancel_offline(vm, mb_id);
+ vm->hotplug_active = false;
+ mutex_unlock(&vm->hotplug_mutex);
+ break;
+ case MEM_CANCEL_ONLINE:
+ if (!vm->hotplug_active)
+ break;
+ vm->hotplug_active = false;
+ mutex_unlock(&vm->hotplug_mutex);
+ break;
+ default:
+ break;
+ }
+
+ lockdep_on();
+
+ return rc;
+}
+
+/*
+ * Set a range of pages PG_offline. Remember pages that were never onlined
+ * (via generic_online_page()) using PageDirty().
+ */
+static void virtio_mem_set_fake_offline(unsigned long pfn,
+ unsigned int nr_pages, bool onlined)
+{
+ for (; nr_pages--; pfn++) {
+ struct page *page = pfn_to_page(pfn);
+
+ __SetPageOffline(page);
+ if (!onlined) {
+ SetPageDirty(page);
+ /* FIXME: remove after cleanups */
+ ClearPageReserved(page);
+ }
+ }
+}
+
+/*
+ * Clear PG_offline from a range of pages. If the pages were never onlined,
+ * (via generic_online_page()), clear PageDirty().
+ */
+static void virtio_mem_clear_fake_offline(unsigned long pfn,
+ unsigned int nr_pages, bool onlined)
+{
+ for (; nr_pages--; pfn++) {
+ struct page *page = pfn_to_page(pfn);
+
+ __ClearPageOffline(page);
+ if (!onlined)
+ ClearPageDirty(page);
+ }
+}
+
+/*
+ * Release a range of fake-offline pages to the buddy, effectively
+ * fake-onlining them.
+ */
+static void virtio_mem_fake_online(unsigned long pfn, unsigned int nr_pages)
+{
+ const int order = MAX_ORDER - 1;
+ int i;
+
+ /*
+ * We are always called with subblock granularity, which is at least
+ * aligned to MAX_ORDER - 1.
+ */
+ for (i = 0; i < nr_pages; i += 1 << order) {
+ struct page *page = pfn_to_page(pfn + i);
+
+ /*
+ * If the page is PageDirty(), it was kept fake-offline when
+ * onlining the memory block. Otherwise, it was allocated
+ * using alloc_contig_range(). All pages in a subblock are
+ * alike.
+ */
+ if (PageDirty(page)) {
+ virtio_mem_clear_fake_offline(pfn + i, 1 << order,
+ false);
+ generic_online_page(page, order);
+ } else {
+ virtio_mem_clear_fake_offline(pfn + i, 1 << order,
+ true);
+ free_contig_range(pfn + i, 1 << order);
+ adjust_managed_page_count(page, 1 << order);
+ }
+ }
+}
+
+static void virtio_mem_online_page_cb(struct page *page, unsigned int order)
+{
+ const unsigned long addr = page_to_phys(page);
+ const unsigned long mb_id = virtio_mem_phys_to_mb_id(addr);
+ struct virtio_mem *vm;
+ int sb_id;
+
+ /*
+ * We exploit here that subblocks have at least MAX_ORDER - 1
+ * size/alignment and that this callback is is called with such a
+ * size/alignment. So we cannot cross subblocks and therefore
+ * also not memory blocks.
+ */
+ rcu_read_lock();
+ list_for_each_entry_rcu(vm, &virtio_mem_devices, next) {
+ if (!virtio_mem_owned_mb(vm, mb_id))
+ continue;
+
+ sb_id = virtio_mem_phys_to_sb_id(vm, addr);
+ /*
+ * If plugged, online the pages, otherwise, set them fake
+ * offline (PageOffline).
+ */
+ if (virtio_mem_mb_test_sb_plugged(vm, mb_id, sb_id, 1))
+ generic_online_page(page, order);
+ else
+ virtio_mem_set_fake_offline(PFN_DOWN(addr), 1 << order,
+ false);
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+
+ /* not virtio-mem memory, but e.g., a DIMM. online it */
+ generic_online_page(page, order);
+}
+
+static uint64_t virtio_mem_send_request(struct virtio_mem *vm,
+ const struct virtio_mem_req *req)
+{
+ struct scatterlist *sgs[2], sg_req, sg_resp;
+ unsigned int len;
+ int rc;
+
+ /* don't use the request residing on the stack (vaddr) */
+ vm->req = *req;
+
+ /* out: buffer for request */
+ sg_init_one(&sg_req, &vm->req, sizeof(vm->req));
+ sgs[0] = &sg_req;
+
+ /* in: buffer for response */
+ sg_init_one(&sg_resp, &vm->resp, sizeof(vm->resp));
+ sgs[1] = &sg_resp;
+
+ rc = virtqueue_add_sgs(vm->vq, sgs, 1, 1, vm, GFP_KERNEL);
+ if (rc < 0)
+ return rc;
+
+ virtqueue_kick(vm->vq);
+
+ /* wait for a response */
+ wait_event(vm->host_resp, virtqueue_get_buf(vm->vq, &len));
+
+ return virtio16_to_cpu(vm->vdev, vm->resp.type);
+}
+
+static int virtio_mem_send_plug_request(struct virtio_mem *vm, uint64_t addr,
+ uint64_t size)
+{
+ const uint64_t nb_vm_blocks = size / vm->device_block_size;
+ const struct virtio_mem_req req = {
+ .type = cpu_to_virtio16(vm->vdev, VIRTIO_MEM_REQ_PLUG),
+ .u.plug.addr = cpu_to_virtio64(vm->vdev, addr),
+ .u.plug.nb_blocks = cpu_to_virtio16(vm->vdev, nb_vm_blocks),
+ };
+
+ if (atomic_read(&vm->config_changed))
+ return -EAGAIN;
+
+ switch (virtio_mem_send_request(vm, &req)) {
+ case VIRTIO_MEM_RESP_ACK:
+ vm->plugged_size += size;
+ return 0;
+ case VIRTIO_MEM_RESP_NACK:
+ return -EAGAIN;
+ case VIRTIO_MEM_RESP_BUSY:
+ return -ETXTBSY;
+ case VIRTIO_MEM_RESP_ERROR:
+ return -EINVAL;
+ default:
+ return -ENOMEM;
+ }
+}
+
+static int virtio_mem_send_unplug_request(struct virtio_mem *vm, uint64_t addr,
+ uint64_t size)
+{
+ const uint64_t nb_vm_blocks = size / vm->device_block_size;
+ const struct virtio_mem_req req = {
+ .type = cpu_to_virtio16(vm->vdev, VIRTIO_MEM_REQ_UNPLUG),
+ .u.unplug.addr = cpu_to_virtio64(vm->vdev, addr),
+ .u.unplug.nb_blocks = cpu_to_virtio16(vm->vdev, nb_vm_blocks),
+ };
+
+ if (atomic_read(&vm->config_changed))
+ return -EAGAIN;
+
+ switch (virtio_mem_send_request(vm, &req)) {
+ case VIRTIO_MEM_RESP_ACK:
+ vm->plugged_size -= size;
+ return 0;
+ case VIRTIO_MEM_RESP_BUSY:
+ return -ETXTBSY;
+ case VIRTIO_MEM_RESP_ERROR:
+ return -EINVAL;
+ default:
+ return -ENOMEM;
+ }
+}
+
+static int virtio_mem_send_unplug_all_request(struct virtio_mem *vm)
+{
+ const struct virtio_mem_req req = {
+ .type = cpu_to_virtio16(vm->vdev, VIRTIO_MEM_REQ_UNPLUG_ALL),
+ };
+
+ switch (virtio_mem_send_request(vm, &req)) {
+ case VIRTIO_MEM_RESP_ACK:
+ vm->unplug_all_required = false;
+ vm->plugged_size = 0;
+ /* usable region might have shrunk */
+ atomic_set(&vm->config_changed, 1);
+ return 0;
+ case VIRTIO_MEM_RESP_BUSY:
+ return -ETXTBSY;
+ default:
+ return -ENOMEM;
+ }
+}
+
+/*
+ * Plug selected subblocks. Updates the plugged state, but not the state
+ * of the memory block.
+ */
+static int virtio_mem_mb_plug_sb(struct virtio_mem *vm, unsigned long mb_id,
+ int sb_id, int count)
+{
+ const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id) +
+ sb_id * vm->subblock_size;
+ const uint64_t size = count * vm->subblock_size;
+ int rc;
+
+ dev_dbg(&vm->vdev->dev, "plugging memory block: %lu : %i - %i\n", mb_id,
+ sb_id, sb_id + count - 1);
+
+ rc = virtio_mem_send_plug_request(vm, addr, size);
+ if (!rc)
+ virtio_mem_mb_set_sb_plugged(vm, mb_id, sb_id, count);
+ return rc;
+}
+
+/*
+ * Unplug selected subblocks. Updates the plugged state, but not the state
+ * of the memory block.
+ */
+static int virtio_mem_mb_unplug_sb(struct virtio_mem *vm, unsigned long mb_id,
+ int sb_id, int count)
+{
+ const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id) +
+ sb_id * vm->subblock_size;
+ const uint64_t size = count * vm->subblock_size;
+ int rc;
+
+ dev_dbg(&vm->vdev->dev, "unplugging memory block: %lu : %i - %i\n",
+ mb_id, sb_id, sb_id + count - 1);
+
+ rc = virtio_mem_send_unplug_request(vm, addr, size);
+ if (!rc)
+ virtio_mem_mb_set_sb_unplugged(vm, mb_id, sb_id, count);
+ return rc;
+}
+
+/*
+ * Unplug the desired number of plugged subblocks of a offline or not-added
+ * memory block. Will fail if any subblock cannot get unplugged (instead of
+ * skipping it).
+ *
+ * Will not modify the state of the memory block.
+ *
+ * Note: can fail after some subblocks were unplugged.
+ */
+static int virtio_mem_mb_unplug_any_sb(struct virtio_mem *vm,
+ unsigned long mb_id, uint64_t *nb_sb)
+{
+ int sb_id, count;
+ int rc;
+
+ sb_id = vm->nb_sb_per_mb - 1;
+ while (*nb_sb) {
+ /* Find the next candidate subblock */
+ while (sb_id >= 0 &&
+ virtio_mem_mb_test_sb_unplugged(vm, mb_id, sb_id, 1))
+ sb_id--;
+ if (sb_id < 0)
+ break;
+ /* Try to unplug multiple subblocks at a time */
+ count = 1;
+ while (count < *nb_sb && sb_id > 0 &&
+ virtio_mem_mb_test_sb_plugged(vm, mb_id, sb_id - 1, 1)) {
+ count++;
+ sb_id--;
+ }
+
+ rc = virtio_mem_mb_unplug_sb(vm, mb_id, sb_id, count);
+ if (rc)
+ return rc;
+ *nb_sb -= count;
+ sb_id--;
+ }
+
+ return 0;
+}
+
+/*
+ * Unplug all plugged subblocks of an offline or not-added memory block.
+ *
+ * Will not modify the state of the memory block.
+ *
+ * Note: can fail after some subblocks were unplugged.
+ */
+static int virtio_mem_mb_unplug(struct virtio_mem *vm, unsigned long mb_id)
+{
+ uint64_t nb_sb = vm->nb_sb_per_mb;
+
+ return virtio_mem_mb_unplug_any_sb(vm, mb_id, &nb_sb);
+}
+
+/*
+ * Prepare tracking data for the next memory block.
+ */
+static int virtio_mem_prepare_next_mb(struct virtio_mem *vm,
+ unsigned long *mb_id)
+{
+ int rc;
+
+ if (vm->next_mb_id > vm->last_usable_mb_id)
+ return -ENOSPC;
+
+ /* Resize the state array if required. */
+ rc = virtio_mem_mb_state_prepare_next_mb(vm);
+ if (rc)
+ return rc;
+
+ /* Resize the subblock bitmap if required. */
+ rc = virtio_mem_sb_bitmap_prepare_next_mb(vm);
+ if (rc)
+ return rc;
+
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_UNUSED]++;
+ *mb_id = vm->next_mb_id++;
+ return 0;
+}
+
+/*
+ * Don't add too many blocks that are not onlined yet to avoid running OOM.
+ */
+static bool virtio_mem_too_many_mb_offline(struct virtio_mem *vm)
+{
+ unsigned long nb_offline;
+
+ nb_offline = vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE] +
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL];
+ return nb_offline >= VIRTIO_MEM_NB_OFFLINE_THRESHOLD;
+}
+
+/*
+ * Try to plug the desired number of subblocks and add the memory block
+ * to Linux.
+ *
+ * Will modify the state of the memory block.
+ */
+static int virtio_mem_mb_plug_and_add(struct virtio_mem *vm,
+ unsigned long mb_id,
+ uint64_t *nb_sb)
+{
+ const int count = min_t(int, *nb_sb, vm->nb_sb_per_mb);
+ int rc, rc2;
+
+ if (WARN_ON_ONCE(!count))
+ return -EINVAL;
+
+ /*
+ * Plug the requested number of subblocks before adding it to linux,
+ * so that onlining will directly online all plugged subblocks.
+ */
+ rc = virtio_mem_mb_plug_sb(vm, mb_id, 0, count);
+ if (rc)
+ return rc;
+
+ /*
+ * Mark the block properly offline before adding it to Linux,
+ * so the memory notifiers will find the block in the right state.
+ */
+ if (count == vm->nb_sb_per_mb)
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE);
+ else
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL);
+
+ /* Add the memory block to linux - if that fails, try to unplug. */
+ rc = virtio_mem_mb_add(vm, mb_id);
+ if (rc) {
+ enum virtio_mem_mb_state new_state = VIRTIO_MEM_MB_STATE_UNUSED;
+
+ dev_err(&vm->vdev->dev,
+ "adding memory block %lu failed with %d\n", mb_id, rc);
+ rc2 = virtio_mem_mb_unplug_sb(vm, mb_id, 0, count);
+
+ /*
+ * TODO: Linux MM does not properly clean up yet in all cases
+ * where adding of memory failed - especially on -ENOMEM.
+ */
+ if (rc2)
+ new_state = VIRTIO_MEM_MB_STATE_PLUGGED;
+ virtio_mem_mb_set_state(vm, mb_id, new_state);
+ return rc;
+ }
+
+ *nb_sb -= count;
+ return 0;
+}
+
+/*
+ * Try to plug the desired number of subblocks of a memory block that
+ * is already added to Linux.
+ *
+ * Will modify the state of the memory block.
+ *
+ * Note: Can fail after some subblocks were successfully plugged.
+ */
+static int virtio_mem_mb_plug_any_sb(struct virtio_mem *vm, unsigned long mb_id,
+ uint64_t *nb_sb, bool online)
+{
+ unsigned long pfn, nr_pages;
+ int sb_id, count;
+ int rc;
+
+ if (WARN_ON_ONCE(!*nb_sb))
+ return -EINVAL;
+
+ while (*nb_sb) {
+ sb_id = virtio_mem_mb_first_unplugged_sb(vm, mb_id);
+ if (sb_id >= vm->nb_sb_per_mb)
+ break;
+ count = 1;
+ while (count < *nb_sb &&
+ sb_id + count < vm->nb_sb_per_mb &&
+ !virtio_mem_mb_test_sb_plugged(vm, mb_id, sb_id + count,
+ 1))
+ count++;
+
+ rc = virtio_mem_mb_plug_sb(vm, mb_id, sb_id, count);
+ if (rc)
+ return rc;
+ *nb_sb -= count;
+ if (!online)
+ continue;
+
+ /* fake-online the pages if the memory block is online */
+ pfn = PFN_DOWN(virtio_mem_mb_id_to_phys(mb_id) +
+ sb_id * vm->subblock_size);
+ nr_pages = PFN_DOWN(count * vm->subblock_size);
+ virtio_mem_fake_online(pfn, nr_pages);
+ }
+
+ if (virtio_mem_mb_test_sb_plugged(vm, mb_id, 0, vm->nb_sb_per_mb)) {
+ if (online)
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE);
+ else
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE);
+ }
+
+ return rc;
+}
+
+/*
+ * Try to plug the requested amount of memory.
+ */
+static int virtio_mem_plug_request(struct virtio_mem *vm, uint64_t diff)
+{
+ uint64_t nb_sb = diff / vm->subblock_size;
+ unsigned long mb_id;
+ int rc;
+
+ if (!nb_sb)
+ return 0;
+
+ /* Don't race with onlining/offlining */
+ mutex_lock(&vm->hotplug_mutex);
+
+ /* Try to plug subblocks of partially plugged online blocks. */
+ virtio_mem_for_each_mb_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL) {
+ rc = virtio_mem_mb_plug_any_sb(vm, mb_id, &nb_sb, true);
+ if (rc || !nb_sb)
+ goto out_unlock;
+ cond_resched();
+ }
+
+ /* Try to plug subblocks of partially plugged offline blocks. */
+ virtio_mem_for_each_mb_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL) {
+ rc = virtio_mem_mb_plug_any_sb(vm, mb_id, &nb_sb, false);
+ if (rc || !nb_sb)
+ goto out_unlock;
+ cond_resched();
+ }
+
+ /*
+ * We won't be working on online/offline memory blocks from this point,
+ * so we can't race with memory onlining/offlining. Drop the mutex.
+ */
+ mutex_unlock(&vm->hotplug_mutex);
+
+ /* Try to plug and add unused blocks */
+ virtio_mem_for_each_mb_state(vm, mb_id, VIRTIO_MEM_MB_STATE_UNUSED) {
+ if (virtio_mem_too_many_mb_offline(vm))
+ return -ENOSPC;
+
+ rc = virtio_mem_mb_plug_and_add(vm, mb_id, &nb_sb);
+ if (rc || !nb_sb)
+ return rc;
+ cond_resched();
+ }
+
+ /* Try to prepare, plug and add new blocks */
+ while (nb_sb) {
+ if (virtio_mem_too_many_mb_offline(vm))
+ return -ENOSPC;
+
+ rc = virtio_mem_prepare_next_mb(vm, &mb_id);
+ if (rc)
+ return rc;
+ rc = virtio_mem_mb_plug_and_add(vm, mb_id, &nb_sb);
+ if (rc)
+ return rc;
+ cond_resched();
+ }
+
+ return 0;
+out_unlock:
+ mutex_unlock(&vm->hotplug_mutex);
+ return rc;
+}
+
+/*
+ * Unplug the desired number of plugged subblocks of an offline memory block.
+ * Will fail if any subblock cannot get unplugged (instead of skipping it).
+ *
+ * Will modify the state of the memory block. Might temporarily drop the
+ * hotplug_mutex.
+ *
+ * Note: Can fail after some subblocks were successfully unplugged.
+ */
+static int virtio_mem_mb_unplug_any_sb_offline(struct virtio_mem *vm,
+ unsigned long mb_id,
+ uint64_t *nb_sb)
+{
+ int rc;
+
+ rc = virtio_mem_mb_unplug_any_sb(vm, mb_id, nb_sb);
+
+ /* some subblocks might have been unplugged even on failure */
+ if (!virtio_mem_mb_test_sb_plugged(vm, mb_id, 0, vm->nb_sb_per_mb))
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL);
+ if (rc)
+ return rc;
+
+ if (virtio_mem_mb_test_sb_unplugged(vm, mb_id, 0, vm->nb_sb_per_mb)) {
+ /*
+ * Remove the block from Linux - this should never fail.
+ * Hinder the block from getting onlined by marking it
+ * unplugged. Temporarily drop the mutex, so
+ * any pending GOING_ONLINE requests can be serviced/rejected.
+ */
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_UNUSED);
+
+ mutex_unlock(&vm->hotplug_mutex);
+ rc = virtio_mem_mb_remove(vm, mb_id);
+ BUG_ON(rc);
+ mutex_lock(&vm->hotplug_mutex);
+ }
+ return 0;
+}
+
+/*
+ * Unplug the given plugged subblocks of an online memory block.
+ *
+ * Will modify the state of the memory block.
+ */
+static int virtio_mem_mb_unplug_sb_online(struct virtio_mem *vm,
+ unsigned long mb_id, int sb_id,
+ int count)
+{
+ const unsigned long nr_pages = PFN_DOWN(vm->subblock_size) * count;
+ unsigned long start_pfn;
+ int rc;
+
+ start_pfn = PFN_DOWN(virtio_mem_mb_id_to_phys(mb_id) +
+ sb_id * vm->subblock_size);
+ rc = alloc_contig_range(start_pfn, start_pfn + nr_pages,
+ MIGRATE_MOVABLE, GFP_KERNEL);
+ if (rc == -ENOMEM)
+ /* whoops, out of memory */
+ return rc;
+ if (rc)
+ return -EBUSY;
+
+ /* Mark it as fake-offline before unplugging it */
+ virtio_mem_set_fake_offline(start_pfn, nr_pages, true);
+ adjust_managed_page_count(pfn_to_page(start_pfn), -nr_pages);
+
+ /* Try to unplug the allocated memory */
+ rc = virtio_mem_mb_unplug_sb(vm, mb_id, sb_id, count);
+ if (rc) {
+ /* Return the memory to the buddy. */
+ virtio_mem_fake_online(start_pfn, nr_pages);
+ return rc;
+ }
+
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL);
+ return 0;
+}
+
+/*
+ * Unplug the desired number of plugged subblocks of an online memory block.
+ * Will skip subblock that are busy.
+ *
+ * Will modify the state of the memory block. Might temporarily drop the
+ * hotplug_mutex.
+ *
+ * Note: Can fail after some subblocks were successfully unplugged. Can
+ * return 0 even if subblocks were busy and could not get unplugged.
+ */
+static int virtio_mem_mb_unplug_any_sb_online(struct virtio_mem *vm,
+ unsigned long mb_id,
+ uint64_t *nb_sb)
+{
+ int rc, sb_id;
+
+ /* If possible, try to unplug the complete block in one shot. */
+ if (*nb_sb >= vm->nb_sb_per_mb &&
+ virtio_mem_mb_test_sb_plugged(vm, mb_id, 0, vm->nb_sb_per_mb)) {
+ rc = virtio_mem_mb_unplug_sb_online(vm, mb_id, 0,
+ vm->nb_sb_per_mb);
+ if (!rc) {
+ *nb_sb -= vm->nb_sb_per_mb;
+ goto unplugged;
+ } else if (rc != -EBUSY)
+ return rc;
+ }
+
+ /* Fallback to single subblocks. */
+ for (sb_id = vm->nb_sb_per_mb - 1; sb_id >= 0 && *nb_sb; sb_id--) {
+ /* Find the next candidate subblock */
+ while (sb_id >= 0 &&
+ !virtio_mem_mb_test_sb_plugged(vm, mb_id, sb_id, 1))
+ sb_id--;
+ if (sb_id < 0)
+ break;
+
+ rc = virtio_mem_mb_unplug_sb_online(vm, mb_id, sb_id, 1);
+ if (rc == -EBUSY)
+ continue;
+ else if (rc)
+ return rc;
+ *nb_sb -= 1;
+ }
+
+unplugged:
+ /*
+ * Once all subblocks of a memory block were unplugged, offline and
+ * remove it. This will usually not fail, as no memory is in use
+ * anymore - however some other notifiers might NACK the request.
+ */
+ if (virtio_mem_mb_test_sb_unplugged(vm, mb_id, 0, vm->nb_sb_per_mb)) {
+ mutex_unlock(&vm->hotplug_mutex);
+ rc = virtio_mem_mb_offline_and_remove(vm, mb_id);
+ mutex_lock(&vm->hotplug_mutex);
+ if (!rc)
+ virtio_mem_mb_set_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_UNUSED);
+ }
+
+ return 0;
+}
+
+/*
+ * Try to unplug the requested amount of memory.
+ */
+static int virtio_mem_unplug_request(struct virtio_mem *vm, uint64_t diff)
+{
+ uint64_t nb_sb = diff / vm->subblock_size;
+ unsigned long mb_id;
+ int rc;
+
+ if (!nb_sb)
+ return 0;
+
+ /*
+ * We'll drop the mutex a couple of times when it is safe to do so.
+ * This might result in some blocks switching the state (online/offline)
+ * and we could miss them in this run - we will retry again later.
+ */
+ mutex_lock(&vm->hotplug_mutex);
+
+ /* Try to unplug subblocks of partially plugged offline blocks. */
+ virtio_mem_for_each_mb_state_rev(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL) {
+ rc = virtio_mem_mb_unplug_any_sb_offline(vm, mb_id,
+ &nb_sb);
+ if (rc || !nb_sb)
+ goto out_unlock;
+ cond_resched();
+ }
+
+ /* Try to unplug subblocks of plugged offline blocks. */
+ virtio_mem_for_each_mb_state_rev(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE) {
+ rc = virtio_mem_mb_unplug_any_sb_offline(vm, mb_id,
+ &nb_sb);
+ if (rc || !nb_sb)
+ goto out_unlock;
+ cond_resched();
+ }
+
+ if (!unplug_online) {
+ mutex_unlock(&vm->hotplug_mutex);
+ return 0;
+ }
+
+ /* Try to unplug subblocks of partially plugged online blocks. */
+ virtio_mem_for_each_mb_state_rev(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL) {
+ rc = virtio_mem_mb_unplug_any_sb_online(vm, mb_id,
+ &nb_sb);
+ if (rc || !nb_sb)
+ goto out_unlock;
+ mutex_unlock(&vm->hotplug_mutex);
+ cond_resched();
+ mutex_lock(&vm->hotplug_mutex);
+ }
+
+ /* Try to unplug subblocks of plugged online blocks. */
+ virtio_mem_for_each_mb_state_rev(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_ONLINE) {
+ rc = virtio_mem_mb_unplug_any_sb_online(vm, mb_id,
+ &nb_sb);
+ if (rc || !nb_sb)
+ goto out_unlock;
+ mutex_unlock(&vm->hotplug_mutex);
+ cond_resched();
+ mutex_lock(&vm->hotplug_mutex);
+ }
+
+ mutex_unlock(&vm->hotplug_mutex);
+ return nb_sb ? -EBUSY : 0;
+out_unlock:
+ mutex_unlock(&vm->hotplug_mutex);
+ return rc;
+}
+
+/*
+ * Try to unplug all blocks that couldn't be unplugged before, for example,
+ * because the hypervisor was busy.
+ */
+static int virtio_mem_unplug_pending_mb(struct virtio_mem *vm)
+{
+ unsigned long mb_id;
+ int rc;
+
+ virtio_mem_for_each_mb_state(vm, mb_id, VIRTIO_MEM_MB_STATE_PLUGGED) {
+ rc = virtio_mem_mb_unplug(vm, mb_id);
+ if (rc)
+ return rc;
+ virtio_mem_mb_set_state(vm, mb_id, VIRTIO_MEM_MB_STATE_UNUSED);
+ }
+
+ return 0;
+}
+
+/*
+ * Update all parts of the config that could have changed.
+ */
+static void virtio_mem_refresh_config(struct virtio_mem *vm)
+{
+ const uint64_t phys_limit = 1UL << MAX_PHYSMEM_BITS;
+ uint64_t new_plugged_size, usable_region_size, end_addr;
+
+ /* the plugged_size is just a reflection of what _we_ did previously */
+ virtio_cread(vm->vdev, struct virtio_mem_config, plugged_size,
+ &new_plugged_size);
+ if (WARN_ON_ONCE(new_plugged_size != vm->plugged_size))
+ vm->plugged_size = new_plugged_size;
+
+ /* calculate the last usable memory block id */
+ virtio_cread(vm->vdev, struct virtio_mem_config,
+ usable_region_size, &usable_region_size);
+ end_addr = vm->addr + usable_region_size;
+ end_addr = min(end_addr, phys_limit);
+ vm->last_usable_mb_id = virtio_mem_phys_to_mb_id(end_addr) - 1;
+
+ /* see if there is a request to change the size */
+ virtio_cread(vm->vdev, struct virtio_mem_config, requested_size,
+ &vm->requested_size);
+
+ dev_info(&vm->vdev->dev, "plugged size: 0x%llx", vm->plugged_size);
+ dev_info(&vm->vdev->dev, "requested size: 0x%llx", vm->requested_size);
+}
+
+/*
+ * Workqueue function for handling plug/unplug requests and config updates.
+ */
+static void virtio_mem_run_wq(struct work_struct *work)
+{
+ struct virtio_mem *vm = container_of(work, struct virtio_mem, wq);
+ uint64_t diff;
+ int rc;
+
+ hrtimer_cancel(&vm->retry_timer);
+
+ if (vm->broken)
+ return;
+
+retry:
+ rc = 0;
+
+ /* Make sure we start with a clean state if there are leftovers. */
+ if (unlikely(vm->unplug_all_required))
+ rc = virtio_mem_send_unplug_all_request(vm);
+
+ if (atomic_read(&vm->config_changed)) {
+ atomic_set(&vm->config_changed, 0);
+ virtio_mem_refresh_config(vm);
+ }
+
+ /* Unplug any leftovers from previous runs */
+ if (!rc)
+ rc = virtio_mem_unplug_pending_mb(vm);
+
+ if (!rc && vm->requested_size != vm->plugged_size) {
+ if (vm->requested_size > vm->plugged_size) {
+ diff = vm->requested_size - vm->plugged_size;
+ rc = virtio_mem_plug_request(vm, diff);
+ } else {
+ diff = vm->plugged_size - vm->requested_size;
+ rc = virtio_mem_unplug_request(vm, diff);
+ }
+ }
+
+ switch (rc) {
+ case 0:
+ vm->retry_timer_ms = VIRTIO_MEM_RETRY_TIMER_MIN_MS;
+ break;
+ case -ENOSPC:
+ /*
+ * We cannot add any more memory (alignment, physical limit)
+ * or we have too many offline memory blocks.
+ */
+ break;
+ case -ETXTBSY:
+ /*
+ * The hypervisor cannot process our request right now
+ * (e.g., out of memory, migrating);
+ */
+ case -EBUSY:
+ /*
+ * We cannot free up any memory to unplug it (all plugged memory
+ * is busy).
+ */
+ case -ENOMEM:
+ /* Out of memory, try again later. */
+ hrtimer_start(&vm->retry_timer, ms_to_ktime(vm->retry_timer_ms),
+ HRTIMER_MODE_REL);
+ break;
+ case -EAGAIN:
+ /* Retry immediately (e.g., the config changed). */
+ goto retry;
+ default:
+ /* Unknown error, mark as broken */
+ dev_err(&vm->vdev->dev,
+ "unknown error, marking device broken: %d\n", rc);
+ vm->broken = true;
+ }
+}
+
+static enum hrtimer_restart virtio_mem_timer_expired(struct hrtimer *timer)
+{
+ struct virtio_mem *vm = container_of(timer, struct virtio_mem,
+ retry_timer);
+
+ virtio_mem_retry(vm);
+ vm->retry_timer_ms = min_t(unsigned int, vm->retry_timer_ms * 2,
+ VIRTIO_MEM_RETRY_TIMER_MAX_MS);
+ return HRTIMER_NORESTART;
+}
+
+static void virtio_mem_handle_response(struct virtqueue *vq)
+{
+ struct virtio_mem *vm = vq->vdev->priv;
+
+ wake_up(&vm->host_resp);
+}
+
+static int virtio_mem_init_vq(struct virtio_mem *vm)
+{
+ struct virtqueue *vq;
+
+ vq = virtio_find_single_vq(vm->vdev, virtio_mem_handle_response,
+ "guest-request");
+ if (IS_ERR(vq))
+ return PTR_ERR(vq);
+ vm->vq = vq;
+
+ return 0;
+}
+
+static int virtio_mem_init(struct virtio_mem *vm)
+{
+ const uint64_t phys_limit = 1UL << MAX_PHYSMEM_BITS;
+ uint16_t node_id;
+
+ if (!vm->vdev->config->get) {
+ dev_err(&vm->vdev->dev, "config access disabled\n");
+ return -EINVAL;
+ }
+
+ /*
+ * We don't want to (un)plug or reuse any memory when in kdump. The
+ * memory is still accessible (but not mapped).
+ */
+ if (is_kdump_kernel()) {
+ dev_warn(&vm->vdev->dev, "disabled in kdump kernel\n");
+ return -EBUSY;
+ }
+
+ /* Fetch all properties that can't change. */
+ virtio_cread(vm->vdev, struct virtio_mem_config, plugged_size,
+ &vm->plugged_size);
+ virtio_cread(vm->vdev, struct virtio_mem_config, block_size,
+ &vm->device_block_size);
+ virtio_cread(vm->vdev, struct virtio_mem_config, node_id,
+ &node_id);
+ vm->nid = virtio_mem_translate_node_id(vm, node_id);
+ virtio_cread(vm->vdev, struct virtio_mem_config, addr, &vm->addr);
+ virtio_cread(vm->vdev, struct virtio_mem_config, region_size,
+ &vm->region_size);
+
+ /*
+ * We always hotplug memory in memory block granularity. This way,
+ * we have to wait for exactly one memory block to online.
+ */
+ if (vm->device_block_size > memory_block_size_bytes()) {
+ dev_err(&vm->vdev->dev,
+ "The block size is not supported (too big).\n");
+ return -EINVAL;
+ }
+
+ /* bad device setup - warn only */
+ if (!IS_ALIGNED(vm->addr, memory_block_size_bytes()))
+ dev_warn(&vm->vdev->dev,
+ "The alignment of the physical start address can make some memory unusable.\n");
+ if (!IS_ALIGNED(vm->addr + vm->region_size, memory_block_size_bytes()))
+ dev_warn(&vm->vdev->dev,
+ "The alignment of the physical end address can make some memory unusable.\n");
+ if (vm->addr + vm->region_size > phys_limit)
+ dev_warn(&vm->vdev->dev,
+ "Some memory is not addressable. This can make some memory unusable.\n");
+
+ /*
+ * Calculate the subblock size:
+ * - At least MAX_ORDER - 1 / pageblock_order.
+ * - At least the device block size.
+ * In the worst case, a single subblock per memory block.
+ */
+ vm->subblock_size = PAGE_SIZE * 1ul << max_t(uint32_t, MAX_ORDER - 1,
+ pageblock_order);
+ vm->subblock_size = max_t(uint64_t, vm->device_block_size,
+ vm->subblock_size);
+ vm->nb_sb_per_mb = memory_block_size_bytes() / vm->subblock_size;
+
+ /* Round up to the next full memory block */
+ vm->first_mb_id = virtio_mem_phys_to_mb_id(vm->addr - 1 +
+ memory_block_size_bytes());
+ vm->next_mb_id = vm->first_mb_id;
+ vm->last_mb_id = virtio_mem_phys_to_mb_id(vm->addr +
+ vm->region_size) - 1;
+
+ dev_info(&vm->vdev->dev, "start address: 0x%llx", vm->addr);
+ dev_info(&vm->vdev->dev, "region size: 0x%llx", vm->region_size);
+ dev_info(&vm->vdev->dev, "device block size: 0x%llx",
+ (unsigned long long)vm->device_block_size);
+ dev_info(&vm->vdev->dev, "memory block size: 0x%lx",
+ memory_block_size_bytes());
+ dev_info(&vm->vdev->dev, "subblock size: 0x%llx",
+ (unsigned long long)vm->subblock_size);
+ if (vm->nid != NUMA_NO_NODE)
+ dev_info(&vm->vdev->dev, "nid: %d", vm->nid);
+
+ return 0;
+}
+
+static int virtio_mem_create_resource(struct virtio_mem *vm)
+{
+ /*
+ * When force-unloading the driver and removing the device, we
+ * could have a garbage pointer. Duplicate the string.
+ */
+ const char *name = kstrdup(dev_name(&vm->vdev->dev), GFP_KERNEL);
+
+ if (!name)
+ return -ENOMEM;
+
+ vm->parent_resource = __request_mem_region(vm->addr, vm->region_size,
+ name, IORESOURCE_SYSTEM_RAM);
+ if (!vm->parent_resource) {
+ kfree(name);
+ dev_warn(&vm->vdev->dev, "could not reserve device region\n");
+ dev_info(&vm->vdev->dev,
+ "reloading the driver is not supported\n");
+ return -EBUSY;
+ }
+
+ /* The memory is not actually busy - make add_memory() work. */
+ vm->parent_resource->flags &= ~IORESOURCE_BUSY;
+ return 0;
+}
+
+static void virtio_mem_delete_resource(struct virtio_mem *vm)
+{
+ const char *name;
+
+ if (!vm->parent_resource)
+ return;
+
+ name = vm->parent_resource->name;
+ release_resource(vm->parent_resource);
+ kfree(vm->parent_resource);
+ kfree(name);
+ vm->parent_resource = NULL;
+}
+
+static int virtio_mem_probe(struct virtio_device *vdev)
+{
+ struct virtio_mem *vm;
+ int rc;
+
+ BUILD_BUG_ON(sizeof(struct virtio_mem_req) != 24);
+ BUILD_BUG_ON(sizeof(struct virtio_mem_resp) != 10);
+
+ vdev->priv = vm = kzalloc(sizeof(*vm), GFP_KERNEL);
+ if (!vm)
+ return -ENOMEM;
+
+ init_waitqueue_head(&vm->host_resp);
+ vm->vdev = vdev;
+ INIT_WORK(&vm->wq, virtio_mem_run_wq);
+ mutex_init(&vm->hotplug_mutex);
+ INIT_LIST_HEAD(&vm->next);
+ spin_lock_init(&vm->removal_lock);
+ hrtimer_init(&vm->retry_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ vm->retry_timer.function = virtio_mem_timer_expired;
+ vm->retry_timer_ms = VIRTIO_MEM_RETRY_TIMER_MIN_MS;
+
+ /* register the virtqueue */
+ rc = virtio_mem_init_vq(vm);
+ if (rc)
+ goto out_free_vm;
+
+ /* initialize the device by querying the config */
+ rc = virtio_mem_init(vm);
+ if (rc)
+ goto out_del_vq;
+
+ /* create the parent resource for all memory */
+ rc = virtio_mem_create_resource(vm);
+ if (rc)
+ goto out_del_vq;
+
+ /*
+ * If we still have memory plugged, we have to unplug all memory first.
+ * Registering our parent resource makes sure that this memory isn't
+ * actually in use (e.g., trying to reload the driver).
+ */
+ if (vm->plugged_size) {
+ vm->unplug_all_required = 1;
+ dev_info(&vm->vdev->dev, "unplugging all memory is required\n");
+ }
+
+ /* register callbacks */
+ vm->memory_notifier.notifier_call = virtio_mem_memory_notifier_cb;
+ rc = register_memory_notifier(&vm->memory_notifier);
+ if (rc)
+ goto out_del_resource;
+ rc = register_virtio_mem_device(vm);
+ if (rc)
+ goto out_unreg_mem;
+
+ virtio_device_ready(vdev);
+
+ /* trigger a config update to start processing the requested_size */
+ atomic_set(&vm->config_changed, 1);
+ queue_work(system_freezable_wq, &vm->wq);
+
+ return 0;
+out_unreg_mem:
+ unregister_memory_notifier(&vm->memory_notifier);
+out_del_resource:
+ virtio_mem_delete_resource(vm);
+out_del_vq:
+ vdev->config->del_vqs(vdev);
+out_free_vm:
+ kfree(vm);
+ vdev->priv = NULL;
+
+ return rc;
+}
+
+static void virtio_mem_remove(struct virtio_device *vdev)
+{
+ struct virtio_mem *vm = vdev->priv;
+ unsigned long mb_id;
+ int rc;
+
+ /*
+ * Make sure the workqueue won't be triggered anymore and no memory
+ * blocks can be onlined/offlined until we're finished here.
+ */
+ mutex_lock(&vm->hotplug_mutex);
+ spin_lock_irq(&vm->removal_lock);
+ vm->removing = true;
+ spin_unlock_irq(&vm->removal_lock);
+ mutex_unlock(&vm->hotplug_mutex);
+
+ /* wait until the workqueue stopped */
+ cancel_work_sync(&vm->wq);
+ hrtimer_cancel(&vm->retry_timer);
+
+ /*
+ * After we unregistered our callbacks, user space can online partially
+ * plugged offline blocks. Make sure to remove them.
+ */
+ virtio_mem_for_each_mb_state(vm, mb_id,
+ VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL) {
+ rc = virtio_mem_mb_remove(vm, mb_id);
+ BUG_ON(rc);
+ virtio_mem_mb_set_state(vm, mb_id, VIRTIO_MEM_MB_STATE_UNUSED);
+ }
+ /*
+ * After we unregistered our callbacks, user space can no longer
+ * offline partially plugged online memory blocks. No need to worry
+ * about them.
+ */
+
+ /* unregister callbacks */
+ unregister_virtio_mem_device(vm);
+ unregister_memory_notifier(&vm->memory_notifier);
+
+ /*
+ * There is no way we could reliably remove all memory we have added to
+ * the system. And there is no way to stop the driver/device from going
+ * away. Warn at least.
+ */
+ if (vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE] ||
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_OFFLINE_PARTIAL] ||
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE] ||
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE_PARTIAL] ||
+ vm->nb_mb_state[VIRTIO_MEM_MB_STATE_ONLINE_MOVABLE])
+ dev_warn(&vdev->dev, "device still has system memory added\n");
+ else
+ virtio_mem_delete_resource(vm);
+
+ /* remove all tracking data - no locking needed */
+ vfree(vm->mb_state);
+ vfree(vm->sb_bitmap);
+
+ /* reset the device and cleanup the queues */
+ vdev->config->reset(vdev);
+ vdev->config->del_vqs(vdev);
+
+ kfree(vm);
+ vdev->priv = NULL;
+}
+
+static void virtio_mem_config_changed(struct virtio_device *vdev)
+{
+ struct virtio_mem *vm = vdev->priv;
+
+ atomic_set(&vm->config_changed, 1);
+ virtio_mem_retry(vm);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int virtio_mem_freeze(struct virtio_device *vdev)
+{
+ /*
+ * When restarting the VM, all memory is usually unplugged. Don't
+ * allow to suspend/hibernate.
+ */
+ dev_err(&vdev->dev, "save/restore not supported.\n");
+ return -EPERM;
+}
+
+static int virtio_mem_restore(struct virtio_device *vdev)
+{
+ return -EPERM;
+}
+#endif
+
+static unsigned int virtio_mem_features[] = {
+#if defined(CONFIG_NUMA) && defined(CONFIG_ACPI_NUMA)
+ VIRTIO_MEM_F_ACPI_PXM,
+#endif
+};
+
+static struct virtio_device_id virtio_mem_id_table[] = {
+ { VIRTIO_ID_MEM, VIRTIO_DEV_ANY_ID },
+ { 0 },
+};
+
+static struct virtio_driver virtio_mem_driver = {
+ .feature_table = virtio_mem_features,
+ .feature_table_size = ARRAY_SIZE(virtio_mem_features),
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = virtio_mem_id_table,
+ .probe = virtio_mem_probe,
+ .remove = virtio_mem_remove,
+ .config_changed = virtio_mem_config_changed,
+#ifdef CONFIG_PM_SLEEP
+ .freeze = virtio_mem_freeze,
+ .restore = virtio_mem_restore,
+#endif
+};
+
+module_virtio_driver(virtio_mem_driver);
+MODULE_DEVICE_TABLE(virtio, virtio_mem_id_table);
+MODULE_AUTHOR("David Hildenbrand <david@redhat.com>");
+MODULE_DESCRIPTION("Virtio-mem driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 97d5725fd9a2..9d16aaffca9d 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -466,10 +466,8 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
int irq = platform_get_irq(vm_dev->pdev, 0);
int i, err, queue_idx = 0;
- if (irq < 0) {
- dev_err(&vdev->dev, "Cannot get IRQ resource\n");
+ if (irq < 0)
return irq;
- }
err = request_irq(irq, vm_interrupt, IRQF_SHARED,
dev_name(&vdev->dev), vm_dev);
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 7abcc50838b8..db93cedd262f 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#define VIRTIO_PCI_NO_LEGACY
+#define VIRTIO_RING_NO_LEGACY
#include "virtio_pci_common.h"
/*
diff --git a/drivers/visorbus/Kconfig b/drivers/visorbus/Kconfig
index d702c44fb5d6..fa947a79b5cd 100644
--- a/drivers/visorbus/Kconfig
+++ b/drivers/visorbus/Kconfig
@@ -6,7 +6,7 @@
config UNISYS_VISORBUS
tristate "Unisys visorbus driver"
depends on X86_64 && ACPI
- ---help---
+ help
The visorbus driver is a virtualized bus for the Unisys s-Par firmware.
Virtualized devices allow Linux guests on a system to share disks and
network cards that do not have SR-IOV support, and to be accessed using
diff --git a/drivers/vme/Kconfig b/drivers/vme/Kconfig
index 7cb9ec6b6b41..936392ca3c8c 100644
--- a/drivers/vme/Kconfig
+++ b/drivers/vme/Kconfig
@@ -6,7 +6,7 @@
menuconfig VME_BUS
bool "VME bridge support"
depends on PCI
- ---help---
+ help
If you say Y here you get support for the VME bridge Framework.
if VME_BUS
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 3e7ad7b232fe..0d6f46702efb 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -2,7 +2,7 @@
menuconfig W1
tristate "Dallas's 1-wire support"
depends on HAS_IOMEM
- ---help---
+ help
Dallas' 1-wire bus is useful to connect slow 1-pin devices
such as iButtons and thermal sensors.
@@ -17,7 +17,7 @@ config W1_CON
depends on CONNECTOR
bool "Userspace communication over connector"
default y
- ---help---
+ help
This allows to communicate with userspace using connector. For more
information see <file:Documentation/driver-api/connector.rst>.
There are three types of messages between w1 core and userspace:
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 55b910c453da..4f4687c46d38 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -6,7 +6,7 @@
menuconfig WATCHDOG
bool "Watchdog Timer Support"
- ---help---
+ help
If you say Y here (and to one of the following options) and create a
character special file /dev/watchdog with major number 10 and minor
number 130 using mknod ("man mknod"), you will get a watchdog, i.e.:
@@ -32,7 +32,7 @@ if WATCHDOG
config WATCHDOG_CORE
tristate "WatchDog Timer Driver Core"
- ---help---
+ help
Say Y here if you want to use the new watchdog timer driver core.
This driver provides a framework for all watchdog timer drivers
and gives them the /dev/watchdog interface (and later also the
@@ -1009,7 +1009,7 @@ config PM8916_WATCHDOG
config ACQUIRE_WDT
tristate "Acquire SBC Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog on Single Board
Computers produced by Acquire Inc (and others). This watchdog
simply watches your kernel to make sure it doesn't freeze, and if
@@ -1032,7 +1032,7 @@ config ADVANTECH_WDT
config ALIM1535_WDT
tristate "ALi M1535 PMU Watchdog Timer"
depends on X86 && PCI
- ---help---
+ help
This is the driver for the hardware watchdog on the ALi M1535 PMU.
To compile this driver as a module, choose M here: the
@@ -1078,7 +1078,7 @@ config SP5100_TCO
tristate "AMD/ATI SP5100 TCO Timer/Watchdog"
depends on X86 && PCI
select WATCHDOG_CORE
- ---help---
+ help
Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO
(Total Cost of Ownership) timer is a watchdog timer that will reboot
the machine after its expiration. The expiration time can be
@@ -1116,7 +1116,7 @@ config SC520_WDT
config SBC_FITPC2_WATCHDOG
tristate "Compulab SBC-FITPC2 watchdog"
depends on X86
- ---help---
+ help
This is the driver for the built-in watchdog timer on the fit-PC2,
fit-PC2i, CM-iAM single-board computers made by Compulab.
@@ -1146,7 +1146,7 @@ config EUROTECH_WDT
config IB700_WDT
tristate "IB700 SBC Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog on the IB700 Single
Board Computer produced by TMC Technology (www.tmc-uk.com). This watchdog
simply watches your kernel to make sure it doesn't freeze, and if
@@ -1184,7 +1184,7 @@ config I6300ESB_WDT
tristate "Intel 6300ESB Timer/Watchdog"
depends on PCI
select WATCHDOG_CORE
- ---help---
+ help
Hardware driver for the watchdog timer built into the Intel
6300ESB controller hub.
@@ -1197,7 +1197,7 @@ config IE6XX_WDT
select WATCHDOG_CORE
select MFD_CORE
select LPC_SCH
- ---help---
+ help
Hardware driver for the watchdog timer built into the Intel
Atom E6XX (TunnelCreek) processor.
@@ -1207,7 +1207,7 @@ config IE6XX_WDT
config INTEL_SCU_WATCHDOG
bool "Intel SCU Watchdog for Mobile Platforms"
depends on X86_INTEL_MID
- ---help---
+ help
Hardware driver for the watchdog time built into the Intel SCU
for Intel Mobile Platforms.
@@ -1217,7 +1217,7 @@ config INTEL_MID_WATCHDOG
tristate "Intel MID Watchdog Timer"
depends on X86_INTEL_MID
select WATCHDOG_CORE
- ---help---
+ help
Watchdog timer driver built into the Intel SCU for Intel MID
Platforms.
@@ -1234,7 +1234,7 @@ config ITCO_WDT
depends on MFD_INTEL_PMC_BXT || !MFD_INTEL_PMC_BXT
select LPC_ICH if !EXPERT
select I2C_I801 if !EXPERT && I2C
- ---help---
+ help
Hardware driver for the intel TCO timer based watchdog devices.
These drivers are included in the Intel 82801 I/O Controller
Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB
@@ -1255,7 +1255,7 @@ config ITCO_WDT
config ITCO_VENDOR_SUPPORT
bool "Intel TCO Timer/Watchdog Specific Vendor Support"
depends on ITCO_WDT
- ---help---
+ help
Add vendor specific support to the intel TCO timer based watchdog
devices. At this moment we only have additional support for some
SuperMicro Inc. motherboards.
@@ -1263,7 +1263,7 @@ config ITCO_VENDOR_SUPPORT
config IT8712F_WDT
tristate "IT8712F (Smart Guardian) Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the built-in watchdog timer on the IT8712F
Super I/0 chipset used on many motherboards.
@@ -1277,7 +1277,7 @@ config IT87_WDT
tristate "IT87 Watchdog Timer"
depends on X86
select WATCHDOG_CORE
- ---help---
+ help
This is the driver for the hardware watchdog on the ITE IT8607,
IT8620, IT8622, IT8625, IT8628, IT8655, IT8665, IT8686, IT8702,
IT8712, IT8716, IT8718, IT8720, IT8721, IT8726, IT8728, and
@@ -1347,7 +1347,7 @@ config SCx200_WDT
config PC87413_WDT
tristate "NS PC87413 watchdog"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog on the PC87413 chipset
This watchdog simply watches your kernel to make sure it doesn't
freeze, and if it does, it reboots your computer after a certain
@@ -1361,7 +1361,7 @@ config PC87413_WDT
config NV_TCO
tristate "nVidia TCO Timer/Watchdog"
depends on X86 && PCI
- ---help---
+ help
Hardware driver for the TCO timer built into the nVidia Hub family
(such as the MCP51). The TCO (Total Cost of Ownership) timer is a
watchdog timer that will reboot the machine after its second
@@ -1404,7 +1404,7 @@ config 60XX_WDT
config SBC8360_WDT
tristate "SBC8360 Watchdog Timer"
depends on X86_32
- ---help---
+ help
This is the driver for the hardware watchdog on the SBC8360 Single
Board Computer produced by Axiomtek Co., Ltd. (www.axiomtek.com).
@@ -1417,7 +1417,7 @@ config SBC8360_WDT
config SBC7240_WDT
tristate "SBC Nano 7240 Watchdog Timer"
depends on X86_32 && !UML
- ---help---
+ help
This is the driver for the hardware watchdog found on the IEI
single board computers EPIC Nano 7240 (and likely others). This
watchdog simply watches your kernel to make sure it doesn't freeze,
@@ -1430,7 +1430,7 @@ config SBC7240_WDT
config CPU5_WDT
tristate "SMA CPU5 Watchdog"
depends on X86
- ---help---
+ help
TBD.
To compile this driver as a module, choose M here: the
module will be called cpu5wdt.
@@ -1438,7 +1438,7 @@ config CPU5_WDT
config SMSC_SCH311X_WDT
tristate "SMSC SCH311X Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog timer on the
SMSC SCH3112, SCH3114 and SCH3116 Super IO chipset
(LPC IO with 8042 KBC, Reset Generation, HWM and multiple
@@ -1450,7 +1450,7 @@ config SMSC_SCH311X_WDT
config SMSC37B787_WDT
tristate "Winbond SMsC37B787 Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog component on the
Winbond SMsC37B787 chipset as used on the NetRunner Mainboard
from Vision Systems and maybe others.
@@ -1484,7 +1484,7 @@ config VIA_WDT
tristate "VIA Watchdog Timer"
depends on X86 && PCI
select WATCHDOG_CORE
- ---help---
+ help
This is the driver for the hardware watchdog timer on VIA
southbridge chipset CX700, VX800/VX820 or VX855/VX875.
@@ -1497,7 +1497,7 @@ config W83627HF_WDT
tristate "Watchdog timer for W83627HF/W83627DHG and compatibles"
depends on X86
select WATCHDOG_CORE
- ---help---
+ help
This is the driver for the hardware watchdog on the following
Super I/O chips.
W83627DHG/DHG-P/EHF/EHG/F/G/HF/S/SF/THF/UHG/UG
@@ -1526,7 +1526,7 @@ config W83627HF_WDT
config W83877F_WDT
tristate "W83877F (EMACS) Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog on the W83877F chipset
as used in EMACS PC-104 motherboards (and likely others). This
watchdog simply watches your kernel to make sure it doesn't freeze,
@@ -1541,7 +1541,7 @@ config W83877F_WDT
config W83977F_WDT
tristate "W83977F (PCM-5335) Watchdog Timer"
depends on X86
- ---help---
+ help
This is the driver for the hardware watchdog on the W83977F I/O chip
as used in AAEON's PCM-5335 SBC (and likely others). This
watchdog simply watches your kernel to make sure it doesn't freeze,
@@ -1554,7 +1554,7 @@ config W83977F_WDT
config MACHZ_WDT
tristate "ZF MachZ Watchdog"
depends on X86
- ---help---
+ help
If you are using a ZF Micro MachZ processor, say Y here, otherwise
N. This is the driver for the watchdog timer built-in on that
processor using ZF-Logic interface. This watchdog simply watches
@@ -1567,7 +1567,7 @@ config MACHZ_WDT
config SBC_EPX_C3_WATCHDOG
tristate "Winsystems SBC EPX-C3 watchdog"
depends on X86
- ---help---
+ help
This is the driver for the built-in watchdog timer on the EPX-C3
Single-board computer made by Winsystems, Inc.
@@ -1589,7 +1589,7 @@ config INTEL_MEI_WDT
tristate "Intel MEI iAMT Watchdog"
depends on INTEL_MEI && X86
select WATCHDOG_CORE
- ---help---
+ help
A device driver for the Intel MEI iAMT watchdog.
The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
@@ -1604,7 +1604,7 @@ config NI903X_WDT
tristate "NI 903x/913x Watchdog"
depends on X86 && ACPI
select WATCHDOG_CORE
- ---help---
+ help
This is the driver for the watchdog timer on the National Instruments
903x/913x real-time controllers.
@@ -1615,7 +1615,7 @@ config NIC7018_WDT
tristate "NIC7018 Watchdog"
depends on X86 && ACPI
select WATCHDOG_CORE
- ---help---
+ help
Support for National Instruments NIC7018 Watchdog.
To compile this driver as a module, choose M here: the module will be
@@ -1865,7 +1865,7 @@ config PIC32_DMT
config GEF_WDT
tristate "GE Watchdog Timer"
depends on GE_FPGA
- ---help---
+ help
Watchdog timer found in a number of GE single board computers.
config MPC5200_WDT
@@ -1903,7 +1903,7 @@ config BOOKE_WDT
tristate "PowerPC Book-E Watchdog Timer"
depends on BOOKE || 4xx
select WATCHDOG_CORE
- ---help---
+ help
Watchdog driver for PowerPC Book-E chips, such as the Freescale
MPC85xx SOCs and the IBM PowerPC 440.
@@ -1994,7 +1994,7 @@ config SH_WDT
config WATCHDOG_CP1XXX
tristate "CP1XXX Hardware Watchdog support"
depends on SPARC64 && PCI
- ---help---
+ help
This is the driver for the hardware watchdog timers present on
Sun Microsystems CompactPCI models CP1400 and CP1500.
@@ -2051,7 +2051,7 @@ comment "ISA-based Watchdog Cards"
config PCWATCHDOG
tristate "Berkshire Products ISA-PC Watchdog"
depends on ISA
- ---help---
+ help
This is the driver for the Berkshire Products ISA-PC Watchdog card.
This card simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
@@ -2067,7 +2067,7 @@ config PCWATCHDOG
config MIXCOMWD
tristate "Mixcom Watchdog"
depends on ISA
- ---help---
+ help
This is a driver for the Mixcom hardware watchdog cards. This
watchdog simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
@@ -2081,7 +2081,7 @@ config MIXCOMWD
config WDT
tristate "WDT Watchdog timer"
depends on ISA
- ---help---
+ help
If you have a WDT500P or WDT501P watchdog board, say Y here,
otherwise N. It is not possible to probe for this board, which means
that you have to inform the kernel about the IO port and IRQ that
@@ -2100,7 +2100,7 @@ comment "PCI-based Watchdog Cards"
config PCIPCWATCHDOG
tristate "Berkshire Products PCI-PC Watchdog"
depends on PCI
- ---help---
+ help
This is the driver for the Berkshire Products PCI-PC Watchdog card.
This card simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
@@ -2115,7 +2115,7 @@ config PCIPCWATCHDOG
config WDTPCI
tristate "PCI-WDT500/501 Watchdog timer"
depends on PCI
- ---help---
+ help
If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N.
If you have a PCI-WDT501 watchdog board then you can enable the
@@ -2138,7 +2138,7 @@ comment "USB-based Watchdog Cards"
config USBPCWATCHDOG
tristate "Berkshire Products USB-PC Watchdog"
depends on USB
- ---help---
+ help
This is the driver for the Berkshire Products USB-PC Watchdog card.
This card simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 61212fc7f0c7..727f11eb46b2 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -13,12 +13,16 @@ config XEN_BALLOON
config XEN_BALLOON_MEMORY_HOTPLUG
bool "Memory hotplug support for Xen balloon driver"
depends on XEN_BALLOON && MEMORY_HOTPLUG
+ default y
help
Memory hotplug support for Xen balloon driver allows expanding memory
available for the system above limit declared at system startup.
It is very useful on critical systems which require long
run without rebooting.
+ It's also very useful for non PV domains to obtain unpopulated physical
+ memory ranges to use in order to map foreign memory or grants.
+
Memory could be hotplugged in following steps:
1) target domain: ensure that memory auto online policy is in
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0c4efa6fe450..0d322f3d90cd 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
-obj-y += grant-table.o features.o balloon.o manage.o preempt.o time.o
+obj-y += grant-table.o features.o balloon.o manage.o time.o
obj-y += mem-reservation.o
obj-y += events/
obj-y += xenbus/
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 0c142bcab79d..77c57568e5d7 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -59,7 +59,6 @@
#include <asm/page.h>
#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
#include <asm/tlb.h>
#include <asm/xen/hypervisor.h>
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index ec975decb5de..b96b11e2b571 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -93,10 +93,8 @@ static int setup_cpu_watcher(struct notifier_block *notifier,
(void)register_xenbus_watch(&cpu_watch);
for_each_possible_cpu(cpu) {
- if (vcpu_online(cpu) == 0) {
- device_offline(get_cpu_device(cpu));
- set_cpu_present(cpu, false);
- }
+ if (vcpu_online(cpu) == 0)
+ disable_hotplug_cpu(cpu);
}
return NOTIFY_DONE;
@@ -119,5 +117,5 @@ static int __init setup_vcpu_hotplug_event(void)
return 0;
}
-arch_initcall(setup_vcpu_hotplug_event);
+late_initcall(setup_vcpu_hotplug_event);
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 3a791c8485d0..140c7bf33a98 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -37,6 +37,7 @@
#ifdef CONFIG_X86
#include <asm/desc.h>
#include <asm/ptrace.h>
+#include <asm/idtentry.h>
#include <asm/irq.h>
#include <asm/io_apic.h>
#include <asm/i8259.h>
@@ -1236,9 +1237,6 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
struct pt_regs *old_regs = set_irq_regs(regs);
irq_enter();
-#ifdef CONFIG_X86
- inc_irq_stat(irq_hv_callback_count);
-#endif
__xen_evtchn_do_upcall();
@@ -1639,26 +1637,30 @@ EXPORT_SYMBOL_GPL(xen_set_callback_via);
/* Vector callbacks are better than PCI interrupts to receive event
* channel notifications because we can receive vector callbacks on any
* vcpu and we don't need PCI support or APIC interactions. */
-void xen_callback_vector(void)
+void xen_setup_callback_vector(void)
{
- int rc;
uint64_t callback_via;
if (xen_have_vector_callback) {
callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR);
- rc = xen_set_callback_via(callback_via);
- if (rc) {
+ if (xen_set_callback_via(callback_via)) {
pr_err("Request for Xen HVM callback vector failed\n");
xen_have_vector_callback = 0;
- return;
}
- pr_info_once("Xen HVM callback vector for event delivery is enabled\n");
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
- xen_hvm_callback_vector);
}
}
+
+static __init void xen_alloc_callback_vector(void)
+{
+ if (!xen_have_vector_callback)
+ return;
+
+ pr_info("Xen HVM callback vector for event delivery is enabled\n");
+ alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_xen_hvm_callback);
+}
#else
-void xen_callback_vector(void) {}
+void xen_setup_callback_vector(void) {}
+static inline void xen_alloc_callback_vector(void) {}
#endif
#undef MODULE_PARAM_PREFIX
@@ -1692,8 +1694,10 @@ void __init xen_init_IRQ(void)
if (xen_initial_domain())
pci_xen_initial_domain();
}
- if (xen_feature(XENFEAT_hvm_callback_vector))
- xen_callback_vector();
+ if (xen_feature(XENFEAT_hvm_callback_vector)) {
+ xen_setup_callback_vector();
+ xen_alloc_callback_vector();
+ }
if (xen_hvm_domain()) {
native_init_IRQ();
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 50651e566564..64a9025a87be 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -625,7 +625,7 @@ static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv,
return -EFAULT;
pr_debug("priv %p, offset for vaddr %lx\n", priv, (unsigned long)op.vaddr);
- down_read(&current->mm->mmap_sem);
+ mmap_read_lock(current->mm);
vma = find_vma(current->mm, op.vaddr);
if (!vma || vma->vm_ops != &gntdev_vmops)
goto out_unlock;
@@ -639,7 +639,7 @@ static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv,
rv = 0;
out_unlock:
- up_read(&current->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
if (rv == 0 && copy_to_user(u, &op, sizeof(op)) != 0)
return -EFAULT;
@@ -1014,7 +1014,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
* to the PTE from going stale.
*
* Since this vma's mappings can't be touched without the
- * mmap_sem, and we are holding it now, there is no need for
+ * mmap_lock, and we are holding it now, there is no need for
* the notifier_range locking pattern.
*/
mmu_interval_read_begin(&map->notifier);
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 7b36b51cdb9f..8d06bf1cc347 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -64,7 +64,6 @@
#include <asm/xen/hypercall.h>
#include <asm/xen/interface.h>
-#include <asm/pgtable.h>
#include <asm/sync_bitops.h>
/* External tools reserve first few grant table entries. */
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
index 59e85e408c23..dd911e1ff782 100644
--- a/drivers/xen/platform-pci.c
+++ b/drivers/xen/platform-pci.c
@@ -168,7 +168,7 @@ static const struct pci_device_id platform_pci_tbl[] = {
{0,}
};
-static struct dev_pm_ops platform_pm_ops = {
+static const struct dev_pm_ops platform_pm_ops = {
.resume_noirq = platform_pci_resume,
};
diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c
deleted file mode 100644
index 17240c5325a3..000000000000
--- a/drivers/xen/preempt.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Preemptible hypercalls
- *
- * Copyright (C) 2014 Citrix Systems R&D ltd.
- */
-
-#include <linux/sched.h>
-#include <xen/xen-ops.h>
-
-#ifndef CONFIG_PREEMPTION
-
-/*
- * Some hypercalls issued by the toolstack can take many 10s of
- * seconds. Allow tasks running hypercalls via the privcmd driver to
- * be voluntarily preempted even if full kernel preemption is
- * disabled.
- *
- * Such preemptible hypercalls are bracketed by
- * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end()
- * calls.
- */
-
-DEFINE_PER_CPU(bool, xen_in_preemptible_hcall);
-EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall);
-
-asmlinkage __visible void xen_maybe_preempt_hcall(void)
-{
- if (unlikely(__this_cpu_read(xen_in_preemptible_hcall)
- && need_resched())) {
- /*
- * Clear flag as we may be rescheduled on a different
- * cpu.
- */
- __this_cpu_write(xen_in_preemptible_hcall, false);
- local_irq_enable();
- cond_resched();
- local_irq_disable();
- __this_cpu_write(xen_in_preemptible_hcall, true);
- }
-}
-#endif /* CONFIG_PREEMPTION */
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index b8ccb8990bfd..a250d118144a 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -26,7 +26,6 @@
#include <linux/moduleparam.h>
#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
@@ -277,7 +276,7 @@ static long privcmd_ioctl_mmap(struct file *file, void __user *udata)
if (rc || list_empty(&pagelist))
goto out;
- down_write(&mm->mmap_sem);
+ mmap_write_lock(mm);
{
struct page *page = list_first_entry(&pagelist,
@@ -302,7 +301,7 @@ static long privcmd_ioctl_mmap(struct file *file, void __user *udata)
out_up:
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
out:
free_page_list(&pagelist);
@@ -498,7 +497,7 @@ static long privcmd_ioctl_mmap_batch(
}
}
- down_write(&mm->mmap_sem);
+ mmap_write_lock(mm);
vma = find_vma(mm, m.addr);
if (!vma ||
@@ -554,7 +553,7 @@ static long privcmd_ioctl_mmap_batch(
BUG_ON(traverse_pages_block(m.num, sizeof(xen_pfn_t),
&pagelist, mmap_batch_fn, &state));
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
if (state.global_error) {
/* Write back errors in second pass. */
@@ -575,7 +574,7 @@ out:
return ret;
out_unlock:
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
goto out;
}
@@ -740,7 +739,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, void __user *udata)
if (data->domid != DOMID_INVALID && data->domid != kdata.dom)
return -EPERM;
- down_write(&mm->mmap_sem);
+ mmap_write_lock(mm);
vma = find_vma(mm, kdata.addr);
if (!vma || vma->vm_ops != &privcmd_vm_ops) {
@@ -819,7 +818,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, void __user *udata)
}
out:
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
kfree(pfns);
return rc;
diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c
index cf4ce3e9358d..9eae1fceec1e 100644
--- a/drivers/xen/pvcalls-back.c
+++ b/drivers/xen/pvcalls-back.c
@@ -24,7 +24,7 @@
#define PVCALLS_VERSIONS "1"
#define MAX_RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
-struct pvcalls_back_global {
+static struct pvcalls_back_global {
struct list_head frontends;
struct semaphore frontends_lock;
} pvcalls_back_global;
@@ -1088,7 +1088,8 @@ static void set_backend_state(struct xenbus_device *dev,
case XenbusStateInitialised:
switch (state) {
case XenbusStateConnected:
- backend_connect(dev);
+ if (backend_connect(dev))
+ return;
xenbus_switch_state(dev, XenbusStateConnected);
break;
case XenbusStateClosing:
diff --git a/drivers/xen/time.c b/drivers/xen/time.c
index 0968859c29d0..108edbcbc040 100644
--- a/drivers/xen/time.c
+++ b/drivers/xen/time.c
@@ -64,7 +64,7 @@ static void xen_get_runstate_snapshot_cpu_delta(
do {
state_time = get64(&state->state_entry_time);
rmb(); /* Hypervisor might update data. */
- *res = READ_ONCE(*state);
+ *res = __READ_ONCE(*state);
rmb(); /* Hypervisor might update data. */
} while (get64(&state->state_entry_time) != state_time ||
(state_time & XEN_RUNSTATE_UPDATE));
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
index da51a5d34e6e..059de92aea7d 100644
--- a/drivers/xen/xen-pciback/conf_space.c
+++ b/drivers/xen/xen-pciback/conf_space.c
@@ -10,6 +10,8 @@
* Author: Ryan Wilson <hap9@epoch.ncsc.mil>
*/
+#define dev_fmt(fmt) DRV_NAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
@@ -154,9 +156,7 @@ int xen_pcibk_config_read(struct pci_dev *dev, int offset, int size,
* (as if device didn't respond) */
u32 value = 0, tmp_val;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: read %d bytes at 0x%x\n",
- pci_name(dev), size, offset);
+ dev_dbg(&dev->dev, "read %d bytes at 0x%x\n", size, offset);
if (!valid_request(offset, size)) {
err = XEN_PCI_ERR_invalid_offset;
@@ -195,9 +195,7 @@ int xen_pcibk_config_read(struct pci_dev *dev, int offset, int size,
}
out:
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: read %d bytes at 0x%x = %x\n",
- pci_name(dev), size, offset, value);
+ dev_dbg(&dev->dev, "read %d bytes at 0x%x = %x\n", size, offset, value);
*ret_val = value;
return xen_pcibios_err_to_errno(err);
@@ -212,10 +210,8 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value)
u32 tmp_val;
int field_start, field_end;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG
- DRV_NAME ": %s: write request %d bytes at 0x%x = %x\n",
- pci_name(dev), size, offset, value);
+ dev_dbg(&dev->dev, "write request %d bytes at 0x%x = %x\n",
+ size, offset, value);
if (!valid_request(offset, size))
return XEN_PCI_ERR_invalid_offset;
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c
index fb4fccb4aecc..ac45cdc38e85 100644
--- a/drivers/xen/xen-pciback/conf_space_header.c
+++ b/drivers/xen/xen-pciback/conf_space_header.c
@@ -6,6 +6,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -67,53 +68,39 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
dev_data = pci_get_drvdata(dev);
if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: enable\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "enable\n");
err = pci_enable_device(dev);
if (err)
return err;
if (dev_data)
dev_data->enable_intx = 1;
} else if (pci_is_enabled(dev) && !is_enable_cmd(value)) {
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: disable\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "disable\n");
pci_disable_device(dev);
if (dev_data)
dev_data->enable_intx = 0;
}
if (!dev->is_busmaster && is_master_cmd(value)) {
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: set bus master\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "set bus master\n");
pci_set_master(dev);
} else if (dev->is_busmaster && !is_master_cmd(value)) {
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: clear bus master\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "clear bus master\n");
pci_clear_master(dev);
}
if (!(cmd->val & PCI_COMMAND_INVALIDATE) &&
(value & PCI_COMMAND_INVALIDATE)) {
- if (unlikely(verbose_request))
- printk(KERN_DEBUG
- DRV_NAME ": %s: enable memory-write-invalidate\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "enable memory-write-invalidate\n");
err = pci_set_mwi(dev);
if (err) {
- pr_warn("%s: cannot enable memory-write-invalidate (%d)\n",
- pci_name(dev), err);
+ dev_warn(&dev->dev, "cannot enable memory-write-invalidate (%d)\n",
+ err);
value &= ~PCI_COMMAND_INVALIDATE;
}
} else if ((cmd->val & PCI_COMMAND_INVALIDATE) &&
!(value & PCI_COMMAND_INVALIDATE)) {
- if (unlikely(verbose_request))
- printk(KERN_DEBUG
- DRV_NAME ": %s: disable memory-write-invalidate\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "disable memory-write-invalidate\n");
pci_clear_mwi(dev);
}
@@ -157,8 +144,7 @@ static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data)
struct pci_bar_info *bar = data;
if (unlikely(!bar)) {
- pr_warn(DRV_NAME ": driver data not found for %s\n",
- pci_name(dev));
+ dev_warn(&dev->dev, "driver data not found\n");
return XEN_PCI_ERR_op_failed;
}
@@ -194,8 +180,7 @@ static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data)
u32 mask;
if (unlikely(!bar)) {
- pr_warn(DRV_NAME ": driver data not found for %s\n",
- pci_name(dev));
+ dev_warn(&dev->dev, "driver data not found\n");
return XEN_PCI_ERR_op_failed;
}
@@ -228,8 +213,7 @@ static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)
struct pci_bar_info *bar = data;
if (unlikely(!bar)) {
- pr_warn(DRV_NAME ": driver data not found for %s\n",
- pci_name(dev));
+ dev_warn(&dev->dev, "driver data not found\n");
return XEN_PCI_ERR_op_failed;
}
@@ -433,8 +417,8 @@ int xen_pcibk_config_header_add_fields(struct pci_dev *dev)
default:
err = -EINVAL;
- pr_err("%s: Unsupported header type %d!\n",
- pci_name(dev), dev->hdr_type);
+ dev_err(&dev->dev, "Unsupported header type %d!\n",
+ dev->hdr_type);
break;
}
diff --git a/drivers/xen/xen-pciback/conf_space_quirks.c b/drivers/xen/xen-pciback/conf_space_quirks.c
index ed593d1042a6..7dc281086302 100644
--- a/drivers/xen/xen-pciback/conf_space_quirks.c
+++ b/drivers/xen/xen-pciback/conf_space_quirks.c
@@ -6,6 +6,8 @@
* Author: Chris Bookholt <hap10@epoch.ncsc.mil>
*/
+#define dev_fmt(fmt) DRV_NAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/pci.h>
#include "pciback.h"
@@ -35,8 +37,8 @@ static struct xen_pcibk_config_quirk *xen_pcibk_find_quirk(struct pci_dev *dev)
if (match_one_device(&tmp_quirk->devid, dev) != NULL)
goto out;
tmp_quirk = NULL;
- printk(KERN_DEBUG DRV_NAME
- ": quirk didn't match any device known\n");
+ dev_printk(KERN_DEBUG, &dev->dev,
+ "quirk didn't match any device known\n");
out:
return tmp_quirk;
}
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 7af93d65ed51..e876c3d6dad1 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -6,6 +6,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
#include <linux/module.h>
#include <linux/init.h>
@@ -626,11 +627,11 @@ static void pcistub_remove(struct pci_dev *dev)
if (found_psdev->pdev) {
int domid = xen_find_device_domain_owner(dev);
- pr_warn("****** removing device %s while still in-use by domain %d! ******\n",
+ dev_warn(&dev->dev, "****** removing device %s while still in-use by domain %d! ******\n",
pci_name(found_psdev->dev), domid);
- pr_warn("****** driver domain may still access this device's i/o resources!\n");
- pr_warn("****** shutdown driver domain before binding device\n");
- pr_warn("****** to other drivers or domains\n");
+ dev_warn(&dev->dev, "****** driver domain may still access this device's i/o resources!\n");
+ dev_warn(&dev->dev, "****** shutdown driver domain before binding device\n");
+ dev_warn(&dev->dev, "****** to other drivers or domains\n");
/* N.B. This ends up calling pcistub_put_pci_dev which ends up
* doing the FLR. */
@@ -711,14 +712,12 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
ret = xen_pcibk_get_pcifront_dev(psdev->dev, psdev->pdev,
&aer_op->domain, &aer_op->bus, &aer_op->devfn);
if (!ret) {
- dev_err(&psdev->dev->dev,
- DRV_NAME ": failed to get pcifront device\n");
+ dev_err(&psdev->dev->dev, "failed to get pcifront device\n");
return PCI_ERS_RESULT_NONE;
}
wmb();
- dev_dbg(&psdev->dev->dev,
- DRV_NAME ": aer_op %x dom %x bus %x devfn %x\n",
+ dev_dbg(&psdev->dev->dev, "aer_op %x dom %x bus %x devfn %x\n",
aer_cmd, aer_op->domain, aer_op->bus, aer_op->devfn);
/*local flag to mark there's aer request, xen_pcibk callback will use
* this flag to judge whether we need to check pci-front give aer
@@ -754,8 +753,7 @@ static pci_ers_result_t common_process(struct pcistub_device *psdev,
if (test_bit(_XEN_PCIF_active,
(unsigned long *)&sh_info->flags)) {
- dev_dbg(&psdev->dev->dev,
- "schedule pci_conf service in " DRV_NAME "\n");
+ dev_dbg(&psdev->dev->dev, "schedule pci_conf service\n");
xen_pcibk_test_and_schedule_op(psdev->pdev);
}
@@ -786,13 +784,12 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
PCI_FUNC(dev->devfn));
if (!psdev || !psdev->pdev) {
- dev_err(&dev->dev,
- DRV_NAME " device is not found/assigned\n");
+ dev_err(&dev->dev, "device is not found/assigned\n");
goto end;
}
if (!psdev->pdev->sh_info) {
- dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
+ dev_err(&dev->dev, "device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
goto end;
@@ -844,13 +841,12 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
PCI_FUNC(dev->devfn));
if (!psdev || !psdev->pdev) {
- dev_err(&dev->dev,
- DRV_NAME " device is not found/assigned\n");
+ dev_err(&dev->dev, "device is not found/assigned\n");
goto end;
}
if (!psdev->pdev->sh_info) {
- dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
+ dev_err(&dev->dev, "device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
goto end;
@@ -902,13 +898,12 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
PCI_FUNC(dev->devfn));
if (!psdev || !psdev->pdev) {
- dev_err(&dev->dev,
- DRV_NAME " device is not found/assigned\n");
+ dev_err(&dev->dev, "device is not found/assigned\n");
goto end;
}
if (!psdev->pdev->sh_info) {
- dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
+ dev_err(&dev->dev, "device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
goto end;
@@ -956,13 +951,12 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
PCI_FUNC(dev->devfn));
if (!psdev || !psdev->pdev) {
- dev_err(&dev->dev,
- DRV_NAME " device is not found/assigned\n");
+ dev_err(&dev->dev, "device is not found/assigned\n");
goto end;
}
if (!psdev->pdev->sh_info) {
- dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
+ dev_err(&dev->dev, "device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
goto end;
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index 7c95516a860f..f1ed2dbf685c 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -186,8 +186,6 @@ void xen_pcibk_do_op(struct work_struct *data);
int xen_pcibk_xenbus_register(void);
void xen_pcibk_xenbus_unregister(void);
-extern int verbose_request;
-
void xen_pcibk_test_and_schedule_op(struct xen_pcibk_device *pdev);
#endif
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 787966f44589..e11a7438e1a2 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -6,6 +6,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
#include <linux/moduleparam.h>
#include <linux/wait.h>
@@ -14,9 +15,6 @@
#include <linux/sched.h>
#include "pciback.h"
-int verbose_request;
-module_param(verbose_request, int, 0644);
-
static irqreturn_t xen_pcibk_guest_interrupt(int irq, void *dev_id);
/* Ensure a device is has the fake IRQ handler "turned on/off" and is
@@ -147,9 +145,6 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
struct xen_pcibk_dev_data *dev_data;
int status;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: enable MSI\n", pci_name(dev));
-
if (dev->msi_enabled)
status = -EALREADY;
else if (dev->msix_enabled)
@@ -158,9 +153,8 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
status = pci_enable_msi(dev);
if (status) {
- pr_warn_ratelimited("%s: error enabling MSI for guest %u: err %d\n",
- pci_name(dev), pdev->xdev->otherend_id,
- status);
+ dev_warn_ratelimited(&dev->dev, "error enabling MSI for guest %u: err %d\n",
+ pdev->xdev->otherend_id, status);
op->value = 0;
return XEN_PCI_ERR_op_failed;
}
@@ -169,9 +163,8 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
* the local domain's IRQ number. */
op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev),
- op->value);
+
+ dev_dbg(&dev->dev, "MSI: %d\n", op->value);
dev_data = pci_get_drvdata(dev);
if (dev_data)
@@ -184,10 +177,6 @@ static
int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev,
struct pci_dev *dev, struct xen_pci_op *op)
{
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n",
- pci_name(dev));
-
if (dev->msi_enabled) {
struct xen_pcibk_dev_data *dev_data;
@@ -198,9 +187,9 @@ int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev,
dev_data->ack_intr = 1;
}
op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev),
- op->value);
+
+ dev_dbg(&dev->dev, "MSI: %d\n", op->value);
+
return 0;
}
@@ -213,9 +202,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
struct msix_entry *entries;
u16 cmd;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n",
- pci_name(dev));
+ dev_dbg(&dev->dev, "enable MSI-X\n");
if (op->value > SH_INFO_MAX_VEC)
return -EINVAL;
@@ -248,17 +235,13 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
if (entries[i].vector) {
op->msix_entries[i].vector =
xen_pirq_from_irq(entries[i].vector);
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: " \
- "MSI-X[%d]: %d\n",
- pci_name(dev), i,
- op->msix_entries[i].vector);
+ dev_dbg(&dev->dev, "MSI-X[%d]: %d\n", i,
+ op->msix_entries[i].vector);
}
}
} else
- pr_warn_ratelimited("%s: error enabling MSI-X for guest %u: err %d!\n",
- pci_name(dev), pdev->xdev->otherend_id,
- result);
+ dev_warn_ratelimited(&dev->dev, "error enabling MSI-X for guest %u: err %d!\n",
+ pdev->xdev->otherend_id, result);
kfree(entries);
op->value = result;
@@ -273,10 +256,6 @@ static
int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev,
struct pci_dev *dev, struct xen_pci_op *op)
{
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n",
- pci_name(dev));
-
if (dev->msix_enabled) {
struct xen_pcibk_dev_data *dev_data;
@@ -291,9 +270,9 @@ int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev,
* an undefined IRQ value of zero.
*/
op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
- if (unlikely(verbose_request))
- printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n",
- pci_name(dev), op->value);
+
+ dev_dbg(&dev->dev, "MSI-X: %d\n", op->value);
+
return 0;
}
#endif
@@ -424,7 +403,7 @@ static irqreturn_t xen_pcibk_guest_interrupt(int irq, void *dev_id)
dev_data->handled++;
if ((dev_data->handled % 1000) == 0) {
if (xen_test_irq_shared(irq)) {
- pr_info("%s IRQ line is not shared "
+ dev_info(&dev->dev, "%s IRQ line is not shared "
"with other domains. Turning ISR off\n",
dev_data->irq_name);
dev_data->ack_intr = 0;
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index f6ba18191c0f..5447b5ab7c76 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -7,6 +7,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
#include <linux/list.h>
#include <linux/slab.h>
@@ -105,9 +106,8 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
struct pci_dev_entry, list);
if (match_slot(dev, t->dev)) {
- pr_info("vpci: %s: assign to virtual slot %d func %d\n",
- pci_name(dev), slot,
- PCI_FUNC(dev->devfn));
+ dev_info(&dev->dev, "vpci: assign to virtual slot %d func %d\n",
+ slot, PCI_FUNC(dev->devfn));
list_add_tail(&dev_entry->list,
&vpci_dev->dev_list[slot]);
func = PCI_FUNC(dev->devfn);
@@ -119,8 +119,8 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
/* Assign to a new slot on the virtual PCI bus */
for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
if (list_empty(&vpci_dev->dev_list[slot])) {
- pr_info("vpci: %s: assign to virtual slot %d\n",
- pci_name(dev), slot);
+ dev_info(&dev->dev, "vpci: assign to virtual slot %d\n",
+ slot);
list_add_tail(&dev_entry->list,
&vpci_dev->dev_list[slot]);
func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn);
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 8c4d05b687b7..38725d97d909 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -31,6 +31,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define dev_fmt pr_fmt
#define DPRINTK(fmt, args...) \
pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \
@@ -51,7 +52,6 @@
#include <linux/module.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/xen/hypervisor.h>
#include <xen/xen.h>
@@ -608,7 +608,7 @@ int xenbus_dev_suspend(struct device *dev)
if (drv->suspend)
err = drv->suspend(xdev);
if (err)
- pr_warn("suspend %s failed: %i\n", dev_name(dev), err);
+ dev_warn(dev, "suspend failed: %i\n", err);
return 0;
}
EXPORT_SYMBOL_GPL(xenbus_dev_suspend);
@@ -627,8 +627,7 @@ int xenbus_dev_resume(struct device *dev)
drv = to_xenbus_driver(dev->driver);
err = talk_to_otherend(xdev);
if (err) {
- pr_warn("resume (talk_to_otherend) %s failed: %i\n",
- dev_name(dev), err);
+ dev_warn(dev, "resume (talk_to_otherend) failed: %i\n", err);
return err;
}
@@ -637,15 +636,14 @@ int xenbus_dev_resume(struct device *dev)
if (drv->resume) {
err = drv->resume(xdev);
if (err) {
- pr_warn("resume %s failed: %i\n", dev_name(dev), err);
+ dev_warn(dev, "resume failed: %i\n", err);
return err;
}
}
err = watch_otherend(xdev);
if (err) {
- pr_warn("resume (watch_otherend) %s failed: %d.\n",
- dev_name(dev), err);
+ dev_warn(dev, "resume (watch_otherend) failed: %d\n", err);
return err;
}
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
index 9b2fbe69bccc..2ba699897e6d 100644
--- a/drivers/xen/xenbus/xenbus_probe_backend.c
+++ b/drivers/xen/xenbus/xenbus_probe_backend.c
@@ -48,7 +48,6 @@
#include <linux/semaphore.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/xen/hypervisor.h>
#include <asm/hypervisor.h>
#include <xen/xenbus.h>
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index 8a1650bbe18f..15379089853b 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/xen/hypervisor.h>
#include <xen/xenbus.h>
#include <xen/events.h>
diff --git a/drivers/zorro/Kconfig b/drivers/zorro/Kconfig
index 2b6ed2936ce3..41475ad46e45 100644
--- a/drivers/zorro/Kconfig
+++ b/drivers/zorro/Kconfig
@@ -5,7 +5,7 @@
config ZORRO_NAMES
bool "Zorro device name database"
depends on ZORRO
- ---help---
+ help
By default, the kernel contains a database of all known Zorro device
names to make the information in /proc/iomem comprehensible to the
user. This database increases the size of the kernel image by about