diff options
196 files changed, 2205 insertions, 1089 deletions
diff --git a/Documentation/ABI/stable/sysfs-bus-mhi b/Documentation/ABI/stable/sysfs-bus-mhi index 1a47f9e0cc845c..8b9698fa0bebf3 100644 --- a/Documentation/ABI/stable/sysfs-bus-mhi +++ b/Documentation/ABI/stable/sysfs-bus-mhi @@ -29,3 +29,16 @@ Description: Initiates a SoC reset on the MHI controller. A SoC reset is This can be useful as a method of recovery if the device is non-responsive, or as a means of loading new firmware as a system administration task. + +What: /sys/bus/mhi/devices/.../trigger_edl +Date: April 2024 +KernelVersion: 6.10 +Contact: mhi@lists.linux.dev +Description: Writing a non-zero value to this file will force devices to + enter EDL (Emergency Download) mode. This entry only exists for + devices capable of entering the EDL mode using the standard EDL + triggering mechanism defined in the MHI spec v1.2. Once in EDL + mode, the flash programmer image can be downloaded to the + device to enter the flash programmer execution environment. + This can be useful if user wants to use QDL (Qualcomm Download, + which is used to download firmware over EDL) to update firmware. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm3x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm3x index 3acf7fc31659c7..271b57c571aa5c 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm3x +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm3x @@ -22,7 +22,7 @@ Contact: Mathieu Poirier <mathieu.poirier@linaro.org> Description: (RW) Used in conjunction with @addr_idx. Specifies characteristics about the address comparator being configure, for example the access type, the kind of instruction to trace, - processor contect ID to trigger on, etc. Individual fields in + processor context ID to trigger on, etc. Individual fields in the access type register may vary on the version of the trace entity. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc index 96aafa66b4a580..339cec3b2f1a69 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc @@ -97,7 +97,7 @@ Date: August 2023 KernelVersion: 6.7 Contact: Anshuman Khandual <anshuman.khandual@arm.com> Description: (Read) Shows all supported Coresight TMC-ETR buffer modes available - for the users to configure explicitly. This file is avaialble only + for the users to configure explicitly. This file is available only for TMC ETR devices. What: /sys/bus/coresight/devices/<memory_map>.tmc/buf_mode_preferred diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index b4d0fc8d319df7..bf710ea6e0efc5 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -244,7 +244,7 @@ KernelVersion 6.9 Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> Description: (RW) Read or write the status of timestamp upon all interface. - Only value 0 and 1 can be written to this node. Set this node to 1 to requeset + Only value 0 and 1 can be written to this node. Set this node to 1 to request timestamp to all trace packet. Accepts only one of the 2 values - 0 or 1. 0 : Disable the timestamp of all trace packets. diff --git a/Documentation/ABI/testing/sysfs-devices-hisi_ptt b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt index d7e206b4901c09..1119766564d7de 100644 --- a/Documentation/ABI/testing/sysfs-devices-hisi_ptt +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt @@ -1,4 +1,4 @@ -What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune +What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune Date: October 2022 KernelVersion: 6.1 Contact: Yicong Yang <yangyicong@hisilicon.com> @@ -8,7 +8,7 @@ Description: This directory contains files for tuning the PCIe link See Documentation/trace/hisi-ptt.rst for more information. -What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl +What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl Date: October 2022 KernelVersion: 6.1 Contact: Yicong Yang <yangyicong@hisilicon.com> @@ -18,7 +18,7 @@ Description: (RW) Controls the weight of Tx completion TLPs, which influence will return an error, and out of range values will be converted to 2. The value indicates a probable level of the event. -What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np +What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np Date: October 2022 KernelVersion: 6.1 Contact: Yicong Yang <yangyicong@hisilicon.com> @@ -28,7 +28,7 @@ Description: (RW) Controls the weight of Tx non-posted TLPs, which influence will return an error, and out of range values will be converted to 2. The value indicates a probable level of the event. -What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p +What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p Date: October 2022 KernelVersion: 6.1 Contact: Yicong Yang <yangyicong@hisilicon.com> @@ -38,7 +38,7 @@ Description: (RW) Controls the weight of Tx posted TLPs, which influence the will return an error, and out of range values will be converted to 2. The value indicates a probable level of the event. -What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level +What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level Date: October 2022 KernelVersion: 6.1 Contact: Yicong Yang <yangyicong@hisilicon.com> @@ -49,7 +49,7 @@ Description: (RW) Control the allocated buffer watermark for inbound packets. will return an error, and out of range values will be converted to 2. The value indicates a probable level of the event. -What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level +What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level Date: October 2022 KernelVersion: 6.1 Contact: Yicong Yang <yangyicong@hisilicon.com> diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml index ea3c5db6b52d2d..76163abed655a2 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml @@ -66,13 +66,11 @@ properties: - const: apb_pclk in-ports: - type: object description: | Input connections from TPDM to TPDA $ref: /schemas/graph.yaml#/properties/ports out-ports: - type: object description: | Output connections from the TPDA to legacy CoreSight trace bus. $ref: /schemas/graph.yaml#/properties/ports @@ -97,33 +95,31 @@ examples: # minimum tpda definition. - | tpda@6004000 { - compatible = "qcom,coresight-tpda", "arm,primecell"; - reg = <0x6004000 0x1000>; + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x6004000 0x1000>; - clocks = <&aoss_qmp>; - clock-names = "apb_pclk"; + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; - in-ports { - #address-cells = <1>; - #size-cells = <0>; + in-ports { + #address-cells = <1>; + #size-cells = <0>; port@0 { reg = <0>; tpda_qdss_0_in_tpdm_dcc: endpoint { - remote-endpoint = - <&tpdm_dcc_out_tpda_qdss_0>; - }; + remote-endpoint = <&tpdm_dcc_out_tpda_qdss_0>; + }; }; }; - out-ports { - port { - tpda_qdss_out_funnel_in0: endpoint { - remote-endpoint = - <&funnel_in0_in_tpda_qdss>; - }; + out-ports { + port { + tpda_qdss_out_funnel_in0: endpoint { + remote-endpoint = <&funnel_in0_in_tpda_qdss>; }; - }; + }; + }; }; ... diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml new file mode 100644 index 00000000000000..05775746fd7065 --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx SelectMAP FPGA interface + +maintainers: + - Charles Perry <charles.perry@savoirfairelinux.com> + +description: | + Xilinx 7 Series FPGAs support a method of loading the bitstream over a + parallel port named the SelectMAP interface in the documentation. Only + the x8 mode is supported where data is loaded at one byte per rising edge of + the clock, with the MSB of each byte presented to the D0 pin. + + Datasheets: + https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf + +allOf: + - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml# + +properties: + compatible: + enum: + - xlnx,fpga-xc7s-selectmap + - xlnx,fpga-xc7a-selectmap + - xlnx,fpga-xc7k-selectmap + - xlnx,fpga-xc7v-selectmap + + reg: + description: + At least 1 byte of memory mapped IO + maxItems: 1 + + prog-gpios: + description: + config pin (referred to as PROGRAM_B in the manual) + maxItems: 1 + + done-gpios: + description: + config status pin (referred to as DONE in the manual) + maxItems: 1 + + init-gpios: + description: + initialization status and configuration error pin + (referred to as INIT_B in the manual) + maxItems: 1 + + csi-gpios: + description: + chip select pin (referred to as CSI_B in the manual) + Optional gpio for if the bus controller does not provide a chip select. + maxItems: 1 + + rdwr-gpios: + description: + read/write select pin (referred to as RDWR_B in the manual) + Optional gpio for if the bus controller does not provide this pin. + maxItems: 1 + +required: + - compatible + - reg + - prog-gpios + - done-gpios + - init-gpios + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + fpga-mgr@8000000 { + compatible = "xlnx,fpga-xc7s-selectmap"; + reg = <0x8000000 0x4>; + prog-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>; + init-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; + done-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + csi-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; + rdwr-gpios = <&gpio3 10 GPIO_ACTIVE_LOW>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml index e1f450b80db278..9cad4c43904543 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml @@ -57,7 +57,7 @@ additionalProperties: false examples: - | - axi-adc@44a00000 { + phy@44a00000 { compatible = "adi,axi-adc-10.0.a"; reg = <0x44a00000 0x10000>; dmas = <&rx_dma 0>; diff --git a/Documentation/devicetree/bindings/iio/imu/bosch,bmi160.yaml b/Documentation/devicetree/bindings/iio/imu/bosch,bmi160.yaml index 47cfba939ca6ae..3b0a2d8b2e9183 100644 --- a/Documentation/devicetree/bindings/iio/imu/bosch,bmi160.yaml +++ b/Documentation/devicetree/bindings/iio/imu/bosch,bmi160.yaml @@ -16,7 +16,11 @@ description: | properties: compatible: - const: bosch,bmi160 + oneOf: + - const: bosch,bmi160 + - items: + - const: bosch,bmi120 + - const: bosch,bmi160 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml index 8c8f05d9eaf1e3..80845c722ae466 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml @@ -34,6 +34,7 @@ properties: - qcom,qcs404-qfprom - qcom,sc7180-qfprom - qcom,sc7280-qfprom + - qcom,sc8280xp-qfprom - qcom,sdm630-qfprom - qcom,sdm670-qfprom - qcom,sdm845-qfprom @@ -42,6 +43,9 @@ properties: - qcom,sm6375-qfprom - qcom,sm8150-qfprom - qcom,sm8250-qfprom + - qcom,sm8450-qfprom + - qcom,sm8550-qfprom + - qcom,sm8650-qfprom - const: qcom,qfprom reg: diff --git a/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml b/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml index 068bedf5dbc9b9..5d7be0b34536f7 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,spmi-sdam.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Technologies, Inc. SPMI SDAM maintainers: - - Shyam Kumar Thella <sthella@codeaurora.org> + - David Collins <quic_collinsd@quicinc.com> description: | The SDAM provides scratch register space for the PMIC clients. This diff --git a/Documentation/driver-api/fpga/fpga-bridge.rst b/Documentation/driver-api/fpga/fpga-bridge.rst index 60420853409533..833f68fb070089 100644 --- a/Documentation/driver-api/fpga/fpga-bridge.rst +++ b/Documentation/driver-api/fpga/fpga-bridge.rst @@ -6,9 +6,12 @@ API to implement a new FPGA bridge * struct fpga_bridge - The FPGA Bridge structure * struct fpga_bridge_ops - Low level Bridge driver ops -* fpga_bridge_register() - Create and register a bridge +* __fpga_bridge_register() - Create and register a bridge * fpga_bridge_unregister() - Unregister a bridge +The helper macro ``fpga_bridge_register()`` automatically sets +the module that registers the FPGA bridge as the owner. + .. kernel-doc:: include/linux/fpga/fpga-bridge.h :functions: fpga_bridge @@ -16,7 +19,7 @@ API to implement a new FPGA bridge :functions: fpga_bridge_ops .. kernel-doc:: drivers/fpga/fpga-bridge.c - :functions: fpga_bridge_register + :functions: __fpga_bridge_register .. kernel-doc:: drivers/fpga/fpga-bridge.c :functions: fpga_bridge_unregister diff --git a/Documentation/driver-api/fpga/fpga-mgr.rst b/Documentation/driver-api/fpga/fpga-mgr.rst index 49c0a951265320..8d2b79f696c1fb 100644 --- a/Documentation/driver-api/fpga/fpga-mgr.rst +++ b/Documentation/driver-api/fpga/fpga-mgr.rst @@ -24,7 +24,8 @@ How to support a new FPGA device -------------------------------- To add another FPGA manager, write a driver that implements a set of ops. The -probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as:: +probe function calls ``fpga_mgr_register()`` or ``fpga_mgr_register_full()``, +such as:: static const struct fpga_manager_ops socfpga_fpga_ops = { .write_init = socfpga_fpga_ops_configure_init, @@ -69,10 +70,11 @@ probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as:: } Alternatively, the probe function could call one of the resource managed -register functions, devm_fpga_mgr_register() or devm_fpga_mgr_register_full(). -When these functions are used, the parameter syntax is the same, but the call -to fpga_mgr_unregister() should be removed. In the above example, the -socfpga_fpga_remove() function would not be required. +register functions, ``devm_fpga_mgr_register()`` or +``devm_fpga_mgr_register_full()``. When these functions are used, the +parameter syntax is the same, but the call to ``fpga_mgr_unregister()`` should be +removed. In the above example, the ``socfpga_fpga_remove()`` function would not be +required. The ops will implement whatever device specific register writes are needed to do the programming sequence for this particular FPGA. These ops return 0 for @@ -125,15 +127,19 @@ API for implementing a new FPGA Manager driver * struct fpga_manager - the FPGA manager struct * struct fpga_manager_ops - Low level FPGA manager driver ops * struct fpga_manager_info - Parameter structure for fpga_mgr_register_full() -* fpga_mgr_register_full() - Create and register an FPGA manager using the +* __fpga_mgr_register_full() - Create and register an FPGA manager using the fpga_mgr_info structure to provide the full flexibility of options -* fpga_mgr_register() - Create and register an FPGA manager using standard +* __fpga_mgr_register() - Create and register an FPGA manager using standard arguments -* devm_fpga_mgr_register_full() - Resource managed version of - fpga_mgr_register_full() -* devm_fpga_mgr_register() - Resource managed version of fpga_mgr_register() +* __devm_fpga_mgr_register_full() - Resource managed version of + __fpga_mgr_register_full() +* __devm_fpga_mgr_register() - Resource managed version of __fpga_mgr_register() * fpga_mgr_unregister() - Unregister an FPGA manager +Helper macros ``fpga_mgr_register_full()``, ``fpga_mgr_register()``, +``devm_fpga_mgr_register_full()``, and ``devm_fpga_mgr_register()`` are available +to ease the registration. + .. kernel-doc:: include/linux/fpga/fpga-mgr.h :functions: fpga_mgr_states @@ -147,16 +153,16 @@ API for implementing a new FPGA Manager driver :functions: fpga_manager_info .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: fpga_mgr_register_full + :functions: __fpga_mgr_register_full .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: fpga_mgr_register + :functions: __fpga_mgr_register .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: devm_fpga_mgr_register_full + :functions: __devm_fpga_mgr_register_full .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: devm_fpga_mgr_register + :functions: __devm_fpga_mgr_register .. kernel-doc:: drivers/fpga/fpga-mgr.c :functions: fpga_mgr_unregister diff --git a/Documentation/driver-api/fpga/fpga-region.rst b/Documentation/driver-api/fpga/fpga-region.rst index dc55d60a0b4a51..2d03b5fb765755 100644 --- a/Documentation/driver-api/fpga/fpga-region.rst +++ b/Documentation/driver-api/fpga/fpga-region.rst @@ -46,13 +46,16 @@ API to add a new FPGA region ---------------------------- * struct fpga_region - The FPGA region struct -* struct fpga_region_info - Parameter structure for fpga_region_register_full() -* fpga_region_register_full() - Create and register an FPGA region using the +* struct fpga_region_info - Parameter structure for __fpga_region_register_full() +* __fpga_region_register_full() - Create and register an FPGA region using the fpga_region_info structure to provide the full flexibility of options -* fpga_region_register() - Create and register an FPGA region using standard +* __fpga_region_register() - Create and register an FPGA region using standard arguments * fpga_region_unregister() - Unregister an FPGA region +Helper macros ``fpga_region_register()`` and ``fpga_region_register_full()`` +automatically set the module that registers the FPGA region as the owner. + The FPGA region's probe function will need to get a reference to the FPGA Manager it will be using to do the programming. This usually would happen during the region's probe function. @@ -82,10 +85,10 @@ following APIs to handle building or tearing down that list. :functions: fpga_region_info .. kernel-doc:: drivers/fpga/fpga-region.c - :functions: fpga_region_register_full + :functions: __fpga_region_register_full .. kernel-doc:: drivers/fpga/fpga-region.c - :functions: fpga_region_register + :functions: __fpga_region_register .. kernel-doc:: drivers/fpga/fpga-region.c :functions: fpga_region_unregister diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst index 989255eb56221e..6eef28ebb0c7b9 100644 --- a/Documentation/trace/hisi-ptt.rst +++ b/Documentation/trace/hisi-ptt.rst @@ -40,7 +40,7 @@ IO dies (SICL, Super I/O Cluster), where there's one PCIe Root Complex for each SICL. :: - /sys/devices/hisi_ptt<sicl_id>_<core_id> + /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id> Tune ==== @@ -53,7 +53,7 @@ Each event is presented as a file under $(PTT PMU dir)/tune, and a simple open/read/write/close cycle will be used to tune the event. :: - $ cd /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune + $ cd /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune $ ls qos_tx_cpl qos_tx_np qos_tx_p tx_path_rx_req_alloc_buf_level diff --git a/MAINTAINERS b/MAINTAINERS index 758c202ec712c8..304429f9bfc64c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9816,7 +9816,7 @@ M: Yicong Yang <yangyicong@hisilicon.com> M: Jonathan Cameron <jonathan.cameron@huawei.com> L: linux-kernel@vger.kernel.org S: Maintained -F: Documentation/ABI/testing/sysfs-devices-hisi_ptt +F: Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt F: Documentation/trace/hisi-ptt.rst F: drivers/hwtracing/ptt/ F: tools/perf/arch/arm64/util/hisi-ptt.c diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c index 171b5c2c7edd65..e1f0bbb8f39388 100644 --- a/drivers/acpi/arm64/amba.c +++ b/drivers/acpi/arm64/amba.c @@ -22,14 +22,6 @@ static const struct acpi_device_id amba_id_list[] = { {"ARMH0061", 0}, /* PL061 GPIO Device */ {"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */ - {"ARMHC501", 0}, /* ARM CoreSight ETR */ - {"ARMHC502", 0}, /* ARM CoreSight STM */ - {"ARMHC503", 0}, /* ARM CoreSight Debug */ - {"ARMHC979", 0}, /* ARM CoreSight TPIU */ - {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ - {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */ - {"ARMHC9CA", 0}, /* ARM CoreSight CATU */ - {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */ {"", 0}, }; diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 44f934981de82a..173f79918741b6 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -127,6 +127,30 @@ static ssize_t soc_reset_store(struct device *dev, } static DEVICE_ATTR_WO(soc_reset); +static ssize_t trigger_edl_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_device *mhi_dev = to_mhi_device(dev); + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret < 0) + return ret; + + if (!val) + return -EINVAL; + + ret = mhi_cntrl->edl_trigger(mhi_cntrl); + if (ret) + return ret; + + return count; +} +static DEVICE_ATTR_WO(trigger_edl); + static struct attribute *mhi_dev_attrs[] = { &dev_attr_serial_number.attr, &dev_attr_oem_pk_hash.attr, @@ -517,11 +541,9 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) dev_dbg(dev, "Initializing MHI registers\n"); /* Read channel db offset */ - ret = mhi_read_reg(mhi_cntrl, base, CHDBOFF, &val); - if (ret) { - dev_err(dev, "Unable to read CHDBOFF register\n"); - return -EIO; - } + ret = mhi_get_channel_doorbell_offset(mhi_cntrl, &val); + if (ret) + return ret; if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) { dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n", @@ -1018,6 +1040,12 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl, if (ret) goto err_release_dev; + if (mhi_cntrl->edl_trigger) { + ret = sysfs_create_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr); + if (ret) + goto err_release_dev; + } + mhi_cntrl->mhi_dev = mhi_dev; mhi_create_debugfs(mhi_cntrl); @@ -1051,6 +1079,9 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl) mhi_deinit_free_irq(mhi_cntrl); mhi_destroy_debugfs(mhi_cntrl); + if (mhi_cntrl->edl_trigger) + sysfs_remove_file(&mhi_dev->dev.kobj, &dev_attr_trigger_edl.attr); + destroy_workqueue(mhi_cntrl->hiprio_wq); kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_event); diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 5fe49311b8eb46..aaad40a07f6925 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -80,6 +80,7 @@ enum dev_st_transition { DEV_ST_TRANSITION_FP, DEV_ST_TRANSITION_SYS_ERR, DEV_ST_TRANSITION_DISABLE, + DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE, DEV_ST_TRANSITION_MAX, }; @@ -90,7 +91,8 @@ enum dev_st_transition { dev_st_trans(MISSION_MODE, "MISSION MODE") \ dev_st_trans(FP, "FLASH PROGRAMMER") \ dev_st_trans(SYS_ERR, "SYS ERROR") \ - dev_st_trans_end(DISABLE, "DISABLE") + dev_st_trans(DISABLE, "DISABLE") \ + dev_st_trans_end(DISABLE_DESTROY_DEVICE, "DISABLE (DESTROY DEVICE)") extern const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX]; #define TO_DEV_STATE_TRANS_STR(state) (((state) >= DEV_ST_TRANSITION_MAX) ? \ diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 15d657af9b5b86..4de75674f19350 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1691,3 +1691,19 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) } } EXPORT_SYMBOL_GPL(mhi_unprepare_from_transfer); + +int mhi_get_channel_doorbell_offset(struct mhi_controller *mhi_cntrl, u32 *chdb_offset) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + void __iomem *base = mhi_cntrl->regs; + int ret; + + ret = mhi_read_reg(mhi_cntrl, base, CHDBOFF, chdb_offset); + if (ret) { + dev_err(dev, "Unable to read CHDBOFF register\n"); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(mhi_get_channel_doorbell_offset); diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index 51639bfcfec708..08844ee79654ae 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -27,12 +27,16 @@ #define PCI_VENDOR_ID_THALES 0x1269 #define PCI_VENDOR_ID_QUECTEL 0x1eac +#define MHI_EDL_DB 91 +#define MHI_EDL_COOKIE 0xEDEDEDED + /** * struct mhi_pci_dev_info - MHI PCI device specific information * @config: MHI controller configuration * @name: name of the PCI module * @fw: firmware path (if any) * @edl: emergency download mode firmware path (if any) + * @edl_trigger: capable of triggering EDL mode in the device (if supported) * @bar_num: PCI base address register to use for MHI MMIO register space * @dma_data_width: DMA transfer word size (32 or 64 bits) * @mru_default: default MRU size for MBIM network packets @@ -44,6 +48,7 @@ struct mhi_pci_dev_info { const char *name; const char *fw; const char *edl; + bool edl_trigger; unsigned int bar_num; unsigned int dma_data_width; unsigned int mru_default; @@ -292,6 +297,7 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx75_info = { .name = "qcom-sdx75m", .fw = "qcom/sdx75m/xbl.elf", .edl = "qcom/sdx75m/edl.mbn", + .edl_trigger = true, .config = &modem_qcom_v2_mhiv_config, .bar_num = MHI_PCI_DEFAULT_BAR_NUM, .dma_data_width = 32, @@ -302,6 +308,7 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx65_info = { .name = "qcom-sdx65m", .fw = "qcom/sdx65m/xbl.elf", .edl = "qcom/sdx65m/edl.mbn", + .edl_trigger = true, .config = &modem_qcom_v1_mhiv_config, .bar_num = MHI_PCI_DEFAULT_BAR_NUM, .dma_data_width = 32, @@ -312,6 +319,7 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = { .name = "qcom-sdx55m", .fw = "qcom/sdx55m/sbl1.mbn", .edl = "qcom/sdx55m/edl.mbn", + .edl_trigger = true, .config = &modem_qcom_v1_mhiv_config, .bar_num = MHI_PCI_DEFAULT_BAR_NUM, .dma_data_width = 32, @@ -928,6 +936,40 @@ static void health_check(struct timer_list *t) mod_timer(&mhi_pdev->health_check_timer, jiffies + HEALTH_CHECK_PERIOD); } +static int mhi_pci_generic_edl_trigger(struct mhi_controller *mhi_cntrl) +{ + void __iomem *base = mhi_cntrl->regs; + void __iomem *edl_db; + int ret; + u32 val; + + ret = mhi_device_get_sync(mhi_cntrl->mhi_dev); + if (ret) { + dev_err(mhi_cntrl->cntrl_dev, "Failed to wakeup the device\n"); + return ret; + } + + pm_wakeup_event(&mhi_cntrl->mhi_dev->dev, 0); + mhi_cntrl->runtime_get(mhi_cntrl); + + ret = mhi_get_channel_doorbell_offset(mhi_cntrl, &val); + if (ret) + goto err_get_chdb; + + edl_db = base + val + (8 * MHI_EDL_DB); + + mhi_cntrl->write_reg(mhi_cntrl, edl_db + 4, upper_32_bits(MHI_EDL_COOKIE)); + mhi_cntrl->write_reg(mhi_cntrl, edl_db, lower_32_bits(MHI_EDL_COOKIE)); + + mhi_soc_reset(mhi_cntrl); + +err_get_chdb: + mhi_cntrl->runtime_put(mhi_cntrl); + mhi_device_put(mhi_cntrl->mhi_dev); + + return ret; +} + static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { const struct mhi_pci_dev_info *info = (struct mhi_pci_dev_info *) id->driver_data; @@ -962,6 +1004,9 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) mhi_cntrl->runtime_put = mhi_pci_runtime_put; mhi_cntrl->mru = info->mru_default; + if (info->edl_trigger) + mhi_cntrl->edl_trigger = mhi_pci_generic_edl_trigger; + if (info->sideband_wake) { mhi_cntrl->wake_get = mhi_pci_wake_get_nop; mhi_cntrl->wake_put = mhi_pci_wake_put_nop; diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 8b40d3f01accda..11c0e751f22398 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -468,7 +468,8 @@ error_mission_mode: } /* Handle shutdown transitions */ -static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) +static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, + bool destroy_device) { enum mhi_pm_state cur_state; struct mhi_event *mhi_event; @@ -530,8 +531,16 @@ skip_mhi_reset: dev_dbg(dev, "Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); - dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); - device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); + /* + * Only destroy the 'struct device' for channels if indicated by the + * 'destroy_device' flag. Because, during system suspend or hibernation + * state, there is no need to destroy the 'struct device' as the endpoint + * device would still be physically attached to the machine. + */ + if (destroy_device) { + dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); + device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); + } mutex_lock(&mhi_cntrl->pm_mutex); @@ -821,7 +830,10 @@ void mhi_pm_st_worker(struct work_struct *work) mhi_pm_sys_error_transition(mhi_cntrl); break; case DEV_ST_TRANSITION_DISABLE: - mhi_pm_disable_transition(mhi_cntrl); + mhi_pm_disable_transition(mhi_cntrl, false); + break; + case DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE: + mhi_pm_disable_transition(mhi_cntrl, true); break; default: break; @@ -1175,7 +1187,8 @@ error_exit: } EXPORT_SYMBOL_GPL(mhi_async_power_up); -void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) +static void __mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful, + bool destroy_device) { enum mhi_pm_state cur_state, transition_state; struct device *dev = &mhi_cntrl->mhi_dev->dev; @@ -1211,15 +1224,32 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); - mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_DISABLE); + if (destroy_device) + mhi_queue_state_transition(mhi_cntrl, + DEV_ST_TRANSITION_DISABLE_DESTROY_DEVICE); + else + mhi_queue_state_transition(mhi_cntrl, + DEV_ST_TRANSITION_DISABLE); /* Wait for shutdown to complete */ flush_work(&mhi_cntrl->st_worker); disable_irq(mhi_cntrl->irq[0]); } + +void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) +{ + __mhi_power_down(mhi_cntrl, graceful, true); +} EXPORT_SYMBOL_GPL(mhi_power_down); +void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl, + bool graceful) +{ + __mhi_power_down(mhi_cntrl, graceful, false); +} +EXPORT_SYMBOL_GPL(mhi_power_down_keep_dev); + int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) { int ret = mhi_async_power_up(mhi_cntrl); diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 2f689ac4ba3a38..37b35f58f0dfb6 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -64,9 +64,21 @@ config FPGA_MGR_STRATIX10_SOC help FPGA manager driver support for the Intel Stratix10 SoC. +config FPGA_MGR_XILINX_CORE + tristate + +config FPGA_MGR_XILINX_SELECTMAP + tristate "Xilinx Configuration over SelectMAP" + depends on HAS_IOMEM + select FPGA_MGR_XILINX_CORE + help + FPGA manager driver support for Xilinx FPGA configuration + over SelectMAP interface. + config FPGA_MGR_XILINX_SPI tristate "Xilinx Configuration over Slave Serial (SPI)" depends on SPI + select FPGA_MGR_XILINX_CORE help FPGA manager driver support for Xilinx FPGA configuration over slave serial interface. diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 352a2612623e00..aeb89bb13517e4 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -15,6 +15,8 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC) += stratix10-soc.o obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o +obj-$(CONFIG_FPGA_MGR_XILINX_CORE) += xilinx-core.o +obj-$(CONFIG_FPGA_MGR_XILINX_SELECTMAP) += xilinx-selectmap.o obj-$(CONFIG_FPGA_MGR_XILINX_SPI) += xilinx-spi.o obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA) += zynqmp-fpga.o diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c index 4ffb9da537d82c..6b091443244530 100644 --- a/drivers/fpga/altera-cvp.c +++ b/drivers/fpga/altera-cvp.c @@ -72,7 +72,6 @@ static bool altera_cvp_chkcfg; struct cvp_priv; struct altera_cvp_conf { - struct fpga_manager *mgr; struct pci_dev *pci_dev; void __iomem *map; void (*write_data)(struct altera_cvp_conf *conf, diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c index 740980e7cef873..d0ec3539b31f77 100644 --- a/drivers/fpga/altera-ps-spi.c +++ b/drivers/fpga/altera-ps-spi.c @@ -284,7 +284,6 @@ MODULE_DEVICE_TABLE(spi, altera_ps_spi_ids); static struct spi_driver altera_ps_driver = { .driver = { .name = "altera-ps-spi", - .owner = THIS_MODULE, .of_match_table = of_ef_match, }, .id_table = altera_ps_spi_ids, diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index c0a75ca360d697..6b97c073849ea9 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -858,8 +858,6 @@ static int afu_dev_init(struct platform_device *pdev) if (!afu) return -ENOMEM; - afu->pdata = pdata; - mutex_lock(&pdata->lock); dfl_fpga_pdata_set_private(pdata, afu); afu_mmio_region_init(pdata); diff --git a/drivers/fpga/dfl-afu.h b/drivers/fpga/dfl-afu.h index 674e9772f0ea73..7bef3e300aa202 100644 --- a/drivers/fpga/dfl-afu.h +++ b/drivers/fpga/dfl-afu.h @@ -67,7 +67,6 @@ struct dfl_afu_dma_region { * @regions: the mmio region linked list of this afu feature device. * @dma_regions: root of dma regions rb tree. * @num_umsgs: num of umsgs. - * @pdata: afu platform device's pdata. */ struct dfl_afu { u64 region_cur_offset; @@ -75,8 +74,6 @@ struct dfl_afu { u8 num_umsgs; struct list_head regions; struct rb_root dma_regions; - - struct dfl_feature_platform_data *pdata; }; /* hold pdata->lock when call __afu_port_enable/disable */ diff --git a/drivers/fpga/dfl-fme-main.c b/drivers/fpga/dfl-fme-main.c index a2b5da0093dac7..864924f68f5e2c 100644 --- a/drivers/fpga/dfl-fme-main.c +++ b/drivers/fpga/dfl-fme-main.c @@ -679,8 +679,6 @@ static int fme_dev_init(struct platform_device *pdev) if (!fme) return -ENOMEM; - fme->pdata = pdata; - mutex_lock(&pdata->lock); dfl_fpga_pdata_set_private(pdata, fme); mutex_unlock(&pdata->lock); diff --git a/drivers/fpga/dfl-fme.h b/drivers/fpga/dfl-fme.h index 4195dd68193e77..a566dbc2b4857e 100644 --- a/drivers/fpga/dfl-fme.h +++ b/drivers/fpga/dfl-fme.h @@ -24,13 +24,11 @@ * @mgr: FME's FPGA manager platform device. * @region_list: linked list of FME's FPGA regions. * @bridge_list: linked list of FME's FPGA bridges. - * @pdata: fme platform device's pdata. */ struct dfl_fme { struct platform_device *mgr; struct list_head region_list; struct list_head bridge_list; - struct dfl_feature_platform_data *pdata; }; extern const struct dfl_feature_ops fme_pr_mgmt_ops; diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 1d724a28f00ad3..5063d73b0d82e7 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -437,11 +437,6 @@ void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u16 id) return NULL; } -static inline bool is_dfl_feature_present(struct device *dev, u16 id) -{ - return !!dfl_get_feature_ioaddr_by_id(dev, id); -} - static inline struct device *dfl_fpga_pdata_to_parent(struct dfl_feature_platform_data *pdata) { diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 79c473b3c7c3d5..8ef395b49bf8a5 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -55,33 +55,26 @@ int fpga_bridge_disable(struct fpga_bridge *bridge) } EXPORT_SYMBOL_GPL(fpga_bridge_disable); -static struct fpga_bridge *__fpga_bridge_get(struct device *dev, +static struct fpga_bridge *__fpga_bridge_get(struct device *bridge_dev, struct fpga_image_info *info) { struct fpga_bridge *bridge; - int ret = -ENODEV; - bridge = to_fpga_bridge(dev); + bridge = to_fpga_bridge(bridge_dev); bridge->info = info; - if (!mutex_trylock(&bridge->mutex)) { - ret = -EBUSY; - goto err_dev; - } + if (!mutex_trylock(&bridge->mutex)) + return ERR_PTR(-EBUSY); - if (!try_module_get(dev->parent->driver->owner)) - goto err_ll_mod; + if (!try_module_get(bridge->br_ops_owner)) { + mutex_unlock(&bridge->mutex); + return ERR_PTR(-ENODEV); + } dev_dbg(&bridge->dev, "get\n"); return bridge; - -err_ll_mod: - mutex_unlock(&bridge->mutex); -err_dev: - put_device(dev); - return ERR_PTR(ret); } /** @@ -98,13 +91,18 @@ err_dev: struct fpga_bridge *of_fpga_bridge_get(struct device_node *np, struct fpga_image_info *info) { - struct device *dev; + struct fpga_bridge *bridge; + struct device *bridge_dev; - dev = class_find_device_by_of_node(&fpga_bridge_class, np); - if (!dev) + bridge_dev = class_find_device_by_of_node(&fpga_bridge_class, np); + if (!bridge_dev) return ERR_PTR(-ENODEV); - return __fpga_bridge_get(dev, info); + bridge = __fpga_bridge_get(bridge_dev, info); + if (IS_ERR(bridge)) + put_device(bridge_dev); + + return bridge; } EXPORT_SYMBOL_GPL(of_fpga_bridge_get); @@ -125,6 +123,7 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data) struct fpga_bridge *fpga_bridge_get(struct device *dev, struct fpga_image_info *info) { + struct fpga_bridge *bridge; struct device *bridge_dev; bridge_dev = class_find_device(&fpga_bridge_class, NULL, dev, @@ -132,7 +131,11 @@ struct fpga_bridge *fpga_bridge_get(struct device *dev, if (!bridge_dev) return ERR_PTR(-ENODEV); - return __fpga_bridge_get(bridge_dev, info); + bridge = __fpga_bridge_get(bridge_dev, info); + if (IS_ERR(bridge)) + put_device(bridge_dev); + + return bridge; } EXPORT_SYMBOL_GPL(fpga_bridge_get); @@ -146,7 +149,7 @@ void fpga_bridge_put(struct fpga_bridge *bridge) dev_dbg(&bridge->dev, "put\n"); bridge->info = NULL; - module_put(bridge->dev.parent->driver->owner); + module_put(bridge->br_ops_owner); mutex_unlock(&bridge->mutex); put_device(&bridge->dev); } @@ -316,18 +319,19 @@ static struct attribute *fpga_bridge_attrs[] = { ATTRIBUTE_GROUPS(fpga_bridge); /** - * fpga_bridge_register - create and register an FPGA Bridge device + * __fpga_bridge_register - create and register an FPGA Bridge device * @parent: FPGA bridge device from pdev * @name: FPGA bridge name * @br_ops: pointer to structure of fpga bridge ops * @priv: FPGA bridge private data + * @owner: owner module containing the br_ops * * Return: struct fpga_bridge pointer or ERR_PTR() */ struct fpga_bridge * -fpga_bridge_register(struct device *parent, const char *name, - const struct fpga_bridge_ops *br_ops, - void *priv) +__fpga_bridge_register(struct device *parent, const char *name, + const struct fpga_bridge_ops *br_ops, + void *priv, struct module *owner) { struct fpga_bridge *bridge; int id, ret; @@ -357,6 +361,7 @@ fpga_bridge_register(struct device *parent, const char *name, bridge->name = name; bridge->br_ops = br_ops; + bridge->br_ops_owner = owner; bridge->priv = priv; bridge->dev.groups = br_ops->groups; @@ -386,7 +391,7 @@ error_kfree: return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(fpga_bridge_register); +EXPORT_SYMBOL_GPL(__fpga_bridge_register); /** * fpga_bridge_unregister - unregister an FPGA bridge diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 06651389c59262..0f4035b089a2ea 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -664,20 +664,16 @@ static struct attribute *fpga_mgr_attrs[] = { }; ATTRIBUTE_GROUPS(fpga_mgr); -static struct fpga_manager *__fpga_mgr_get(struct device *dev) +static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev) { struct fpga_manager *mgr; - mgr = to_fpga_manager(dev); + mgr = to_fpga_manager(mgr_dev); - if (!try_module_get(dev->parent->driver->owner)) - goto err_dev; + if (!try_module_get(mgr->mops_owner)) + mgr = ERR_PTR(-ENODEV); return mgr; - -err_dev: - put_device(dev); - return ERR_PTR(-ENODEV); } static int fpga_mgr_dev_match(struct device *dev, const void *data) @@ -693,12 +689,18 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data) */ struct fpga_manager *fpga_mgr_get(struct device *dev) { - struct device *mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, - fpga_mgr_dev_match); + struct fpga_manager *mgr; + struct device *mgr_dev; + + mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, fpga_mgr_dev_match); if (!mgr_dev) return ERR_PTR(-ENODEV); - return __fpga_mgr_get(mgr_dev); + mgr = __fpga_mgr_get(mgr_dev); + if (IS_ERR(mgr)) + put_device(mgr_dev); + + return mgr; } EXPORT_SYMBOL_GPL(fpga_mgr_get); @@ -711,13 +713,18 @@ EXPORT_SYMBOL_GPL(fpga_mgr_get); */ struct fpga_manager *of_fpga_mgr_get(struct device_node *node) { - struct device *dev; + struct fpga_manager *mgr; + struct device *mgr_dev; - dev = class_find_device_by_of_node(&fpga_mgr_class, node); - if (!dev) + mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node); + if (!mgr_dev) return ERR_PTR(-ENODEV); - return __fpga_mgr_get(dev); + mgr = __fpga_mgr_get(mgr_dev); + if (IS_ERR(mgr)) + put_device(mgr_dev); + + return mgr; } EXPORT_SYMBOL_GPL(of_fpga_mgr_get); @@ -727,7 +734,7 @@ EXPORT_SYMBOL_GPL(of_fpga_mgr_get); */ void fpga_mgr_put(struct fpga_manager *mgr) { - module_put(mgr->dev.parent->driver->owner); + module_put(mgr->mops_owner); put_device(&mgr->dev); } EXPORT_SYMBOL_GPL(fpga_mgr_put); @@ -766,9 +773,10 @@ void fpga_mgr_unlock(struct fpga_manager *mgr) EXPORT_SYMBOL_GPL(fpga_mgr_unlock); /** - * fpga_mgr_register_full - create and register an FPGA Manager device + * __fpga_mgr_register_full - create and register an FPGA Manager device * @parent: fpga manager device from pdev * @info: parameters for fpga manager + * @owner: owner module containing the ops * * The caller of this function is responsible for calling fpga_mgr_unregister(). * Using devm_fpga_mgr_register_full() instead is recommended. @@ -776,7 +784,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock); * Return: pointer to struct fpga_manager pointer or ERR_PTR() */ struct fpga_manager * -fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info) +__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, + struct module *owner) { const struct fpga_manager_ops *mops = info->mops; struct fpga_manager *mgr; @@ -804,6 +813,8 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in mutex_init(&mgr->ref_mutex); + mgr->mops_owner = owner; + mgr->name = info->name; mgr->mops = info->mops; mgr->priv = info->priv; @@ -841,14 +852,15 @@ error_kfree: return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(__fpga_mgr_register_full); /** - * fpga_mgr_register - create and register an FPGA Manager device + * __fpga_mgr_register - create and register an FPGA Manager device * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data + * @owner: owner module containing the ops * * The caller of this function is responsible for calling fpga_mgr_unregister(). * Using devm_fpga_mgr_register() instead is recommended. This simple @@ -859,8 +871,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_register_full); * Return: pointer to struct fpga_manager pointer or ERR_PTR() */ struct fpga_manager * -fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv) +__fpga_mgr_register(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, void *priv, struct module *owner) { struct fpga_manager_info info = { 0 }; @@ -868,9 +880,9 @@ fpga_mgr_register(struct device *parent, const char *name, info.mops = mops; info.priv = priv; - return fpga_mgr_register_full(parent, &info); + return __fpga_mgr_register_full(parent, &info, owner); } -EXPORT_SYMBOL_GPL(fpga_mgr_register); +EXPORT_SYMBOL_GPL(__fpga_mgr_register); /** * fpga_mgr_unregister - unregister an FPGA manager @@ -900,9 +912,10 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res) } /** - * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register() + * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register() * @parent: fpga manager device from pdev * @info: parameters for fpga manager + * @owner: owner module containing the ops * * Return: fpga manager pointer on success, negative error code otherwise. * @@ -910,7 +923,8 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res) * function will be called automatically when the managing device is detached. */ struct fpga_manager * -devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info) +__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, + struct module *owner) { struct fpga_mgr_devres *dr; struct fpga_manager *mgr; @@ -919,7 +933,7 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf if (!dr) return ERR_PTR(-ENOMEM); - mgr = fpga_mgr_register_full(parent, info); + mgr = __fpga_mgr_register_full(parent, info, owner); if (IS_ERR(mgr)) { devres_free(dr); return mgr; @@ -930,14 +944,15 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf return mgr; } -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full); /** - * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() + * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data + * @owner: owner module containing the ops * * Return: fpga manager pointer on success, negative error code otherwise. * @@ -946,8 +961,9 @@ EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full); * device is detached. */ struct fpga_manager * -devm_fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv) +__devm_fpga_mgr_register(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, void *priv, + struct module *owner) { struct fpga_manager_info info = { 0 }; @@ -955,9 +971,9 @@ devm_fpga_mgr_register(struct device *parent, const char *name, info.mops = mops; info.priv = priv; - return devm_fpga_mgr_register_full(parent, &info); + return __devm_fpga_mgr_register_full(parent, &info, owner); } -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register); +EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register); static void fpga_mgr_dev_release(struct device *dev) { diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index b364a929425ce9..753cd142503e0e 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -53,7 +53,7 @@ static struct fpga_region *fpga_region_get(struct fpga_region *region) } get_device(dev); - if (!try_module_get(dev->parent->driver->owner)) { + if (!try_module_get(region->ops_owner)) { put_device(dev); mutex_unlock(®ion->mutex); return ERR_PTR(-ENODEV); @@ -75,7 +75,7 @@ static void fpga_region_put(struct fpga_region *region) dev_dbg(dev, "put\n"); - module_put(dev->parent->driver->owner); + module_put(region->ops_owner); put_device(dev); mutex_unlock(®ion->mutex); } @@ -181,14 +181,16 @@ static struct attribute *fpga_region_attrs[] = { ATTRIBUTE_GROUPS(fpga_region); /** - * fpga_region_register_full - create and register an FPGA Region device + * __fpga_region_register_full - create and register an FPGA Region device * @parent: device parent * @info: parameters for FPGA Region + * @owner: module containing the get_bridges function * * Return: struct fpga_region or ERR_PTR() */ struct fpga_region * -fpga_region_register_full(struct device *parent, const struct fpga_region_info *info) +__fpga_region_register_full(struct device *parent, const struct fpga_region_info *info, + struct module *owner) { struct fpga_region *region; int id, ret = 0; @@ -213,6 +215,7 @@ fpga_region_register_full(struct device *parent, const struct fpga_region_info * region->compat_id = info->compat_id; region->priv = info->priv; region->get_bridges = info->get_bridges; + region->ops_owner = owner; mutex_init(®ion->mutex); INIT_LIST_HEAD(®ion->bridge_list); @@ -241,13 +244,14 @@ err_free: return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(fpga_region_register_full); +EXPORT_SYMBOL_GPL(__fpga_region_register_full); /** - * fpga_region_register - create and register an FPGA Region device + * __fpga_region_register - create and register an FPGA Region device * @parent: device parent * @mgr: manager that programs this region * @get_bridges: optional function to get bridges to a list + * @owner: module containing the get_bridges function * * This simple version of the register function should be sufficient for most users. * The fpga_region_register_full() function is available for users that need to @@ -256,17 +260,17 @@ EXPORT_SYMBOL_GPL(fpga_region_register_full); * Return: struct fpga_region or ERR_PTR() */ struct fpga_region * -fpga_region_register(struct device *parent, struct fpga_manager *mgr, - int (*get_bridges)(struct fpga_region *)) +__fpga_region_register(struct device *parent, struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *), struct module *owner) { struct fpga_region_info info = { 0 }; info.mgr = mgr; info.get_bridges = get_bridges; - return fpga_region_register_full(parent, &info); + return __fpga_region_register_full(parent, &info, owner); } -EXPORT_SYMBOL_GPL(fpga_region_register); +EXPORT_SYMBOL_GPL(__fpga_region_register); /** * fpga_region_unregister - unregister an FPGA region diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c index c0028ae4c5b761..62c30266130d4f 100644 --- a/drivers/fpga/ice40-spi.c +++ b/drivers/fpga/ice40-spi.c @@ -10,8 +10,8 @@ #include <linux/fpga/fpga-mgr.h> #include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_gpio.h> #include <linux/spi/spi.h> #include <linux/stringify.h> @@ -199,7 +199,7 @@ static struct spi_driver ice40_fpga_driver = { .probe = ice40_fpga_probe, .driver = { .name = "ice40spi", - .of_match_table = of_match_ptr(ice40_fpga_of_match), + .of_match_table = ice40_fpga_of_match, }, .id_table = ice40_fpga_spi_ids, }; diff --git a/drivers/fpga/tests/fpga-bridge-test.c b/drivers/fpga/tests/fpga-bridge-test.c index 1d258002cdd7b6..2f7a24f238083c 100644 --- a/drivers/fpga/tests/fpga-bridge-test.c +++ b/drivers/fpga/tests/fpga-bridge-test.c @@ -7,8 +7,8 @@ * Author: Marco Pagani <marpagan@redhat.com> */ +#include <kunit/device.h> #include <kunit/test.h> -#include <linux/device.h> #include <linux/fpga/fpga-bridge.h> #include <linux/module.h> #include <linux/types.h> @@ -19,7 +19,7 @@ struct bridge_stats { struct bridge_ctx { struct fpga_bridge *bridge; - struct platform_device *pdev; + struct device *dev; struct bridge_stats stats; }; @@ -43,30 +43,31 @@ static const struct fpga_bridge_ops fake_bridge_ops = { /** * register_test_bridge() - Register a fake FPGA bridge for testing. * @test: KUnit test context object. + * @dev_name: name of the kunit device to be registered * * Return: Context of the newly registered FPGA bridge. */ -static struct bridge_ctx *register_test_bridge(struct kunit *test) +static struct bridge_ctx *register_test_bridge(struct kunit *test, const char *dev_name) { struct bridge_ctx *ctx; ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - ctx->pdev = platform_device_register_simple("bridge_pdev", PLATFORM_DEVID_AUTO, NULL, 0); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->pdev); + ctx->dev = kunit_device_register(test, dev_name); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->dev); - ctx->bridge = fpga_bridge_register(&ctx->pdev->dev, "Fake FPGA bridge", &fake_bridge_ops, + ctx->bridge = fpga_bridge_register(ctx->dev, "Fake FPGA bridge", &fake_bridge_ops, &ctx->stats); KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->bridge)); return ctx; } -static void unregister_test_bridge(struct bridge_ctx *ctx) +static void unregister_test_bridge(struct kunit *test, struct bridge_ctx *ctx) { fpga_bridge_unregister(ctx->bridge); - platform_device_unregister(ctx->pdev); + kunit_device_unregister(test, ctx->dev); } static void fpga_bridge_test_get(struct kunit *test) @@ -74,10 +75,10 @@ static void fpga_bridge_test_get(struct kunit *test) struct bridge_ctx *ctx = test->priv; struct fpga_bridge *bridge; - bridge = fpga_bridge_get(&ctx->pdev->dev, NULL); + bridge = fpga_bridge_get(ctx->dev, NULL); KUNIT_EXPECT_PTR_EQ(test, bridge, ctx->bridge); - bridge = fpga_bridge_get(&ctx->pdev->dev, NULL); + bridge = fpga_bridge_get(ctx->dev, NULL); KUNIT_EXPECT_EQ(test, PTR_ERR(bridge), -EBUSY); fpga_bridge_put(ctx->bridge); @@ -105,19 +106,19 @@ static void fpga_bridge_test_get_put_list(struct kunit *test) int ret; ctx_0 = test->priv; - ctx_1 = register_test_bridge(test); + ctx_1 = register_test_bridge(test, "fpga-bridge-test-dev-1"); INIT_LIST_HEAD(&bridge_list); /* Get bridge 0 and add it to the list */ - ret = fpga_bridge_get_to_list(&ctx_0->pdev->dev, NULL, &bridge_list); + ret = fpga_bridge_get_to_list(ctx_0->dev, NULL, &bridge_list); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_PTR_EQ(test, ctx_0->bridge, list_first_entry_or_null(&bridge_list, struct fpga_bridge, node)); /* Get bridge 1 and add it to the list */ - ret = fpga_bridge_get_to_list(&ctx_1->pdev->dev, NULL, &bridge_list); + ret = fpga_bridge_get_to_list(ctx_1->dev, NULL, &bridge_list); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_PTR_EQ(test, ctx_1->bridge, @@ -141,19 +142,19 @@ static void fpga_bridge_test_get_put_list(struct kunit *test) KUNIT_EXPECT_TRUE(test, list_empty(&bridge_list)); - unregister_test_bridge(ctx_1); + unregister_test_bridge(test, ctx_1); } static int fpga_bridge_test_init(struct kunit *test) { - test->priv = register_test_bridge(test); + test->priv = register_test_bridge(test, "fpga-bridge-test-dev-0"); return 0; } static void fpga_bridge_test_exit(struct kunit *test) { - unregister_test_bridge(test->priv); + unregister_test_bridge(test, test->priv); } static struct kunit_case fpga_bridge_test_cases[] = { diff --git a/drivers/fpga/tests/fpga-mgr-test.c b/drivers/fpga/tests/fpga-mgr-test.c index 6acec55b60ce9a..125b3a4d43c6ab 100644 --- a/drivers/fpga/tests/fpga-mgr-test.c +++ b/drivers/fpga/tests/fpga-mgr-test.c @@ -7,8 +7,8 @@ * Author: Marco Pagani <marpagan@redhat.com> */ +#include <kunit/device.h> #include <kunit/test.h> -#include <linux/device.h> #include <linux/fpga/fpga-mgr.h> #include <linux/module.h> #include <linux/scatterlist.h> @@ -40,7 +40,7 @@ struct mgr_stats { struct mgr_ctx { struct fpga_image_info *img_info; struct fpga_manager *mgr; - struct platform_device *pdev; + struct device *dev; struct mgr_stats stats; }; @@ -194,7 +194,7 @@ static void fpga_mgr_test_get(struct kunit *test) struct mgr_ctx *ctx = test->priv; struct fpga_manager *mgr; - mgr = fpga_mgr_get(&ctx->pdev->dev); + mgr = fpga_mgr_get(ctx->dev); KUNIT_EXPECT_PTR_EQ(test, mgr, ctx->mgr); fpga_mgr_put(ctx->mgr); @@ -284,14 +284,14 @@ static int fpga_mgr_test_init(struct kunit *test) ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - ctx->pdev = platform_device_register_simple("mgr_pdev", PLATFORM_DEVID_AUTO, NULL, 0); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->pdev); + ctx->dev = kunit_device_register(test, "fpga-manager-test-dev"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->dev); - ctx->mgr = devm_fpga_mgr_register(&ctx->pdev->dev, "Fake FPGA Manager", &fake_mgr_ops, + ctx->mgr = devm_fpga_mgr_register(ctx->dev, "Fake FPGA Manager", &fake_mgr_ops, &ctx->stats); KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->mgr)); - ctx->img_info = fpga_image_info_alloc(&ctx->pdev->dev); + ctx->img_info = fpga_image_info_alloc(ctx->dev); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->img_info); test->priv = ctx; @@ -304,7 +304,7 @@ static void fpga_mgr_test_exit(struct kunit *test) struct mgr_ctx *ctx = test->priv; fpga_image_info_free(ctx->img_info); - platform_device_unregister(ctx->pdev); + kunit_device_unregister(test, ctx->dev); } static struct kunit_case fpga_mgr_test_cases[] = { diff --git a/drivers/fpga/tests/fpga-region-test.c b/drivers/fpga/tests/fpga-region-test.c index baab07e3fc5967..bcf0651df261e8 100644 --- a/drivers/fpga/tests/fpga-region-test.c +++ b/drivers/fpga/tests/fpga-region-test.c @@ -7,12 +7,12 @@ * Author: Marco Pagani <marpagan@redhat.com> */ +#include <kunit/device.h> #include <kunit/test.h> #include <linux/fpga/fpga-bridge.h> #include <linux/fpga/fpga-mgr.h> #include <linux/fpga/fpga-region.h> #include <linux/module.h> -#include <linux/platform_device.h> #include <linux/types.h> struct mgr_stats { @@ -26,11 +26,11 @@ struct bridge_stats { struct test_ctx { struct fpga_manager *mgr; - struct platform_device *mgr_pdev; + struct device *mgr_dev; struct fpga_bridge *bridge; - struct platform_device *bridge_pdev; + struct device *bridge_dev; struct fpga_region *region; - struct platform_device *region_pdev; + struct device *region_dev; struct bridge_stats bridge_stats; struct mgr_stats mgr_stats; }; @@ -91,7 +91,7 @@ static void fpga_region_test_class_find(struct kunit *test) struct test_ctx *ctx = test->priv; struct fpga_region *region; - region = fpga_region_class_find(NULL, &ctx->region_pdev->dev, fake_region_match); + region = fpga_region_class_find(NULL, ctx->region_dev, fake_region_match); KUNIT_EXPECT_PTR_EQ(test, region, ctx->region); put_device(®ion->dev); @@ -108,7 +108,7 @@ static void fpga_region_test_program_fpga(struct kunit *test) char img_buf[4]; int ret; - img_info = fpga_image_info_alloc(&ctx->mgr_pdev->dev); + img_info = fpga_image_info_alloc(ctx->mgr_dev); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, img_info); img_info->buf = img_buf; @@ -148,32 +148,30 @@ static int fpga_region_test_init(struct kunit *test) ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - ctx->mgr_pdev = platform_device_register_simple("mgr_pdev", PLATFORM_DEVID_AUTO, NULL, 0); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->mgr_pdev); + ctx->mgr_dev = kunit_device_register(test, "fpga-manager-test-dev"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->mgr_dev); - ctx->mgr = devm_fpga_mgr_register(&ctx->mgr_pdev->dev, "Fake FPGA Manager", &fake_mgr_ops, - &ctx->mgr_stats); + ctx->mgr = devm_fpga_mgr_register(ctx->mgr_dev, "Fake FPGA Manager", + &fake_mgr_ops, &ctx->mgr_stats); KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->mgr)); - ctx->bridge_pdev = platform_device_register_simple("bridge_pdev", PLATFORM_DEVID_AUTO, - NULL, 0); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->bridge_pdev); + ctx->bridge_dev = kunit_device_register(test, "fpga-bridge-test-dev"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->bridge_dev); - ctx->bridge = fpga_bridge_register(&ctx->bridge_pdev->dev, "Fake FPGA Bridge", + ctx->bridge = fpga_bridge_register(ctx->bridge_dev, "Fake FPGA Bridge", &fake_bridge_ops, &ctx->bridge_stats); KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->bridge)); ctx->bridge_stats.enable = true; - ctx->region_pdev = platform_device_register_simple("region_pdev", PLATFORM_DEVID_AUTO, - NULL, 0); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->region_pdev); + ctx->region_dev = kunit_device_register(test, "fpga-region-test-dev"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->region_dev); region_info.mgr = ctx->mgr; region_info.priv = ctx->bridge; region_info.get_bridges = fake_region_get_bridges; - ctx->region = fpga_region_register_full(&ctx->region_pdev->dev, ®ion_info); + ctx->region = fpga_region_register_full(ctx->region_dev, ®ion_info); KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->region)); test->priv = ctx; @@ -186,18 +184,17 @@ static void fpga_region_test_exit(struct kunit *test) struct test_ctx *ctx = test->priv; fpga_region_unregister(ctx->region); - platform_device_unregister(ctx->region_pdev); + kunit_device_unregister(test, ctx->region_dev); fpga_bridge_unregister(ctx->bridge); - platform_device_unregister(ctx->bridge_pdev); + kunit_device_unregister(test, ctx->bridge_dev); - platform_device_unregister(ctx->mgr_pdev); + kunit_device_unregister(test, ctx->mgr_dev); } static struct kunit_case fpga_region_test_cases[] = { KUNIT_CASE(fpga_region_test_class_find), KUNIT_CASE(fpga_region_test_program_fpga), - {} }; diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c new file mode 100644 index 00000000000000..39aeacf2e4f175 --- /dev/null +++ b/drivers/fpga/xilinx-core.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers. + * + * Copyright (C) 2017 DENX Software Engineering + * + * Anatolij Gustschin <agust@denx.de> + */ + +#include "xilinx-core.h" + +#include <linux/delay.h> +#include <linux/fpga/fpga-mgr.h> +#include <linux/gpio/consumer.h> +#include <linux/of.h> + +static int get_done_gpio(struct fpga_manager *mgr) +{ + struct xilinx_fpga_core *core = mgr->priv; + int ret; + + ret = gpiod_get_value(core->done); + if (ret < 0) + dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret); + + return ret; +} + +static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr) +{ + if (!get_done_gpio(mgr)) + return FPGA_MGR_STATE_RESET; + + return FPGA_MGR_STATE_UNKNOWN; +} + +/** + * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait + * a given delay if the pin is unavailable + * + * @mgr: The FPGA manager object + * @value: Value INIT_B to wait for (1 = asserted = low) + * @alt_udelay: Delay to wait if the INIT_B GPIO is not available + * + * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if + * too much time passed waiting for that. If no INIT_B GPIO is available + * then always return 0. + */ +static int wait_for_init_b(struct fpga_manager *mgr, int value, + unsigned long alt_udelay) +{ + struct xilinx_fpga_core *core = mgr->priv; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + if (core->init_b) { + while (time_before(jiffies, timeout)) { + int ret = gpiod_get_value(core->init_b); + + if (ret == value) + return 0; + + if (ret < 0) { + dev_err(&mgr->dev, + "Error reading INIT_B (%d)\n", ret); + return ret; + } + + usleep_range(100, 400); + } + + dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n", + value ? "assert" : "deassert"); + return -ETIMEDOUT; + } + + udelay(alt_udelay); + + return 0; +} + +static int xilinx_core_write_init(struct fpga_manager *mgr, + struct fpga_image_info *info, const char *buf, + size_t count) +{ + struct xilinx_fpga_core *core = mgr->priv; + int err; + + if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { + dev_err(&mgr->dev, "Partial reconfiguration not supported\n"); + return -EINVAL; + } + + gpiod_set_value(core->prog_b, 1); + + err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */ + if (err) { + gpiod_set_value(core->prog_b, 0); + return err; + } + + gpiod_set_value(core->prog_b, 0); + + err = wait_for_init_b(mgr, 0, 0); + if (err) + return err; + + if (get_done_gpio(mgr)) { + dev_err(&mgr->dev, "Unexpected DONE pin state...\n"); + return -EIO; + } + + /* program latency */ + usleep_range(7500, 7600); + return 0; +} + +static int xilinx_core_write(struct fpga_manager *mgr, const char *buf, + size_t count) +{ + struct xilinx_fpga_core *core = mgr->priv; + + return core->write(core, buf, count); +} + +static int xilinx_core_write_complete(struct fpga_manager *mgr, + struct fpga_image_info *info) +{ + struct xilinx_fpga_core *core = mgr->priv; + unsigned long timeout = + jiffies + usecs_to_jiffies(info->config_complete_timeout_us); + bool expired = false; + int done; + int ret; + const char padding[1] = { 0xff }; + + /* + * This loop is carefully written such that if the driver is + * scheduled out for more than 'timeout', we still check for DONE + * before giving up and we apply 8 extra CCLK cycles in all cases. + */ + while (!expired) { + expired = time_after(jiffies, timeout); + + done = get_done_gpio(mgr); + if (done < 0) + return done; + + ret = core->write(core, padding, sizeof(padding)); + if (ret) + return ret; + + if (done) + return 0; + } + + if (core->init_b) { + ret = gpiod_get_value(core->init_b); + + if (ret < 0) { + dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret); + return ret; + } + + dev_err(&mgr->dev, + ret ? "CRC error or invalid device\n" : + "Missing sync word or incomplete bitstream\n"); + } else { + dev_err(&mgr->dev, "Timeout after config data transfer\n"); + } + + return -ETIMEDOUT; +} + +static inline struct gpio_desc * +xilinx_core_devm_gpiod_get(struct device *dev, const char *con_id, + const char *legacy_con_id, enum gpiod_flags flags) +{ + struct gpio_desc *desc; + + desc = devm_gpiod_get(dev, con_id, flags); + if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT && + of_device_is_compatible(dev->of_node, "xlnx,fpga-slave-serial")) + desc = devm_gpiod_get(dev, legacy_con_id, flags); + + return desc; +} + +static const struct fpga_manager_ops xilinx_core_ops = { + .state = xilinx_core_state, + .write_init = xilinx_core_write_init, + .write = xilinx_core_write, + .write_complete = xilinx_core_write_complete, +}; + +int xilinx_core_probe(struct xilinx_fpga_core *core) +{ + struct fpga_manager *mgr; + + if (!core || !core->dev || !core->write) + return -EINVAL; + + /* PROGRAM_B is active low */ + core->prog_b = xilinx_core_devm_gpiod_get(core->dev, "prog", "prog_b", + GPIOD_OUT_LOW); + if (IS_ERR(core->prog_b)) + return dev_err_probe(core->dev, PTR_ERR(core->prog_b), + "Failed to get PROGRAM_B gpio\n"); + + core->init_b = xilinx_core_devm_gpiod_get(core->dev, "init", "init-b", + GPIOD_IN); + if (IS_ERR(core->init_b)) + return dev_err_probe(core->dev, PTR_ERR(core->init_b), + "Failed to get INIT_B gpio\n"); + + core->done = devm_gpiod_get(core->dev, "done", GPIOD_IN); + if (IS_ERR(core->done)) + return dev_err_probe(core->dev, PTR_ERR(core->done), + "Failed to get DONE gpio\n"); + + mgr = devm_fpga_mgr_register(core->dev, + "Xilinx Slave Serial FPGA Manager", + &xilinx_core_ops, core); + return PTR_ERR_OR_ZERO(mgr); +} +EXPORT_SYMBOL_GPL(xilinx_core_probe); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); +MODULE_DESCRIPTION("Xilinx 7 Series FPGA manager core"); diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h new file mode 100644 index 00000000000000..f02ac67fce7ba0 --- /dev/null +++ b/drivers/fpga/xilinx-core.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __XILINX_CORE_H +#define __XILINX_CORE_H + +#include <linux/device.h> + +/** + * struct xilinx_fpga_core - interface between the driver and the core manager + * of Xilinx 7 Series FPGA manager + * @dev: device node + * @write: write callback of the driver + */ +struct xilinx_fpga_core { +/* public: */ + struct device *dev; + int (*write)(struct xilinx_fpga_core *core, const char *buf, + size_t count); +/* private: handled by xilinx-core */ + struct gpio_desc *prog_b; + struct gpio_desc *init_b; + struct gpio_desc *done; +}; + +int xilinx_core_probe(struct xilinx_fpga_core *core); + +#endif /* __XILINX_CORE_H */ diff --git a/drivers/fpga/xilinx-selectmap.c b/drivers/fpga/xilinx-selectmap.c new file mode 100644 index 00000000000000..2cd87e7e913ff7 --- /dev/null +++ b/drivers/fpga/xilinx-selectmap.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Xilinx Spartan6 and 7 Series SelectMAP interface driver + * + * (C) 2024 Charles Perry <charles.perry@savoirfairelinux.com> + * + * Manage Xilinx FPGA firmware loaded over the SelectMAP configuration + * interface. + */ + +#include "xilinx-core.h" + +#include <linux/gpio/consumer.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +struct xilinx_selectmap_conf { + struct xilinx_fpga_core core; + void __iomem *base; +}; + +#define to_xilinx_selectmap_conf(obj) \ + container_of(obj, struct xilinx_selectmap_conf, core) + +static int xilinx_selectmap_write(struct xilinx_fpga_core *core, + const char *buf, size_t count) +{ + struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core); + size_t i; + + for (i = 0; i < count; ++i) + writeb(buf[i], conf->base); + + return 0; +} + +static int xilinx_selectmap_probe(struct platform_device *pdev) +{ + struct xilinx_selectmap_conf *conf; + struct gpio_desc *gpio; + void __iomem *base; + + conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL); + if (!conf) + return -ENOMEM; + + conf->core.dev = &pdev->dev; + conf->core.write = xilinx_selectmap_write; + + base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); + if (IS_ERR(base)) + return dev_err_probe(&pdev->dev, PTR_ERR(base), + "ioremap error\n"); + conf->base = base; + + /* CSI_B is active low */ + gpio = devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(gpio), + "Failed to get CSI_B gpio\n"); + + /* RDWR_B is active low */ + gpio = devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(gpio), + "Failed to get RDWR_B gpio\n"); + + return xilinx_core_probe(&conf->core); +} + +static const struct of_device_id xlnx_selectmap_of_match[] = { + { .compatible = "xlnx,fpga-xc7s-selectmap", }, // Spartan-7 + { .compatible = "xlnx,fpga-xc7a-selectmap", }, // Artix-7 + { .compatible = "xlnx,fpga-xc7k-selectmap", }, // Kintex-7 + { .compatible = "xlnx,fpga-xc7v-selectmap", }, // Virtex-7 + {}, +}; +MODULE_DEVICE_TABLE(of, xlnx_selectmap_of_match); + +static struct platform_driver xilinx_selectmap_driver = { + .driver = { + .name = "xilinx-selectmap", + .of_match_table = xlnx_selectmap_of_match, + }, + .probe = xilinx_selectmap_probe, +}; + +module_platform_driver(xilinx_selectmap_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Charles Perry <charles.perry@savoirfairelinux.com>"); +MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SelectMap"); diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c index e1a227e7ff2ae7..8756504340dedf 100644 --- a/drivers/fpga/xilinx-spi.c +++ b/drivers/fpga/xilinx-spi.c @@ -10,127 +10,17 @@ * the slave serial configuration interface. */ -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/fpga/fpga-mgr.h> -#include <linux/gpio/consumer.h> +#include "xilinx-core.h" + #include <linux/module.h> #include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/spi/spi.h> -#include <linux/sizes.h> - -struct xilinx_spi_conf { - struct spi_device *spi; - struct gpio_desc *prog_b; - struct gpio_desc *init_b; - struct gpio_desc *done; -}; - -static int get_done_gpio(struct fpga_manager *mgr) -{ - struct xilinx_spi_conf *conf = mgr->priv; - int ret; - - ret = gpiod_get_value(conf->done); - - if (ret < 0) - dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret); - - return ret; -} - -static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr) -{ - if (!get_done_gpio(mgr)) - return FPGA_MGR_STATE_RESET; - - return FPGA_MGR_STATE_UNKNOWN; -} - -/** - * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait - * a given delay if the pin is unavailable - * - * @mgr: The FPGA manager object - * @value: Value INIT_B to wait for (1 = asserted = low) - * @alt_udelay: Delay to wait if the INIT_B GPIO is not available - * - * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if - * too much time passed waiting for that. If no INIT_B GPIO is available - * then always return 0. - */ -static int wait_for_init_b(struct fpga_manager *mgr, int value, - unsigned long alt_udelay) -{ - struct xilinx_spi_conf *conf = mgr->priv; - unsigned long timeout = jiffies + msecs_to_jiffies(1000); - - if (conf->init_b) { - while (time_before(jiffies, timeout)) { - int ret = gpiod_get_value(conf->init_b); - - if (ret == value) - return 0; - - if (ret < 0) { - dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret); - return ret; - } - - usleep_range(100, 400); - } - - dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n", - value ? "assert" : "deassert"); - return -ETIMEDOUT; - } - - udelay(alt_udelay); - - return 0; -} - -static int xilinx_spi_write_init(struct fpga_manager *mgr, - struct fpga_image_info *info, - const char *buf, size_t count) -{ - struct xilinx_spi_conf *conf = mgr->priv; - int err; - - if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { - dev_err(&mgr->dev, "Partial reconfiguration not supported\n"); - return -EINVAL; - } - - gpiod_set_value(conf->prog_b, 1); - - err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */ - if (err) { - gpiod_set_value(conf->prog_b, 0); - return err; - } - - gpiod_set_value(conf->prog_b, 0); - - err = wait_for_init_b(mgr, 0, 0); - if (err) - return err; - - if (get_done_gpio(mgr)) { - dev_err(&mgr->dev, "Unexpected DONE pin state...\n"); - return -EIO; - } - /* program latency */ - usleep_range(7500, 7600); - return 0; -} - -static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf, +static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf, size_t count) { - struct xilinx_spi_conf *conf = mgr->priv; + struct spi_device *spi = to_spi_device(core->dev); const char *fw_data = buf; const char *fw_data_end = fw_data + count; @@ -141,9 +31,9 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf, remaining = fw_data_end - fw_data; stride = min_t(size_t, remaining, SZ_4K); - ret = spi_write(conf->spi, fw_data, stride); + ret = spi_write(spi, fw_data, stride); if (ret) { - dev_err(&mgr->dev, "SPI error in firmware write: %d\n", + dev_err(core->dev, "SPI error in firmware write: %d\n", ret); return ret; } @@ -153,109 +43,25 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf, return 0; } -static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf) -{ - struct spi_device *spi = conf->spi; - const u8 din_data[1] = { 0xff }; - int ret; - - ret = spi_write(conf->spi, din_data, sizeof(din_data)); - if (ret) - dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret); - - return ret; -} - -static int xilinx_spi_write_complete(struct fpga_manager *mgr, - struct fpga_image_info *info) -{ - struct xilinx_spi_conf *conf = mgr->priv; - unsigned long timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us); - bool expired = false; - int done; - int ret; - - /* - * This loop is carefully written such that if the driver is - * scheduled out for more than 'timeout', we still check for DONE - * before giving up and we apply 8 extra CCLK cycles in all cases. - */ - while (!expired) { - expired = time_after(jiffies, timeout); - - done = get_done_gpio(mgr); - if (done < 0) - return done; - - ret = xilinx_spi_apply_cclk_cycles(conf); - if (ret) - return ret; - - if (done) - return 0; - } - - if (conf->init_b) { - ret = gpiod_get_value(conf->init_b); - - if (ret < 0) { - dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret); - return ret; - } - - dev_err(&mgr->dev, - ret ? "CRC error or invalid device\n" - : "Missing sync word or incomplete bitstream\n"); - } else { - dev_err(&mgr->dev, "Timeout after config data transfer\n"); - } - - return -ETIMEDOUT; -} - -static const struct fpga_manager_ops xilinx_spi_ops = { - .state = xilinx_spi_state, - .write_init = xilinx_spi_write_init, - .write = xilinx_spi_write, - .write_complete = xilinx_spi_write_complete, -}; - static int xilinx_spi_probe(struct spi_device *spi) { - struct xilinx_spi_conf *conf; - struct fpga_manager *mgr; + struct xilinx_fpga_core *core; - conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); - if (!conf) + core = devm_kzalloc(&spi->dev, sizeof(*core), GFP_KERNEL); + if (!core) return -ENOMEM; - conf->spi = spi; + core->dev = &spi->dev; + core->write = xilinx_spi_write; - /* PROGRAM_B is active low */ - conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW); - if (IS_ERR(conf->prog_b)) - return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b), - "Failed to get PROGRAM_B gpio\n"); - - conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN); - if (IS_ERR(conf->init_b)) - return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b), - "Failed to get INIT_B gpio\n"); - - conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN); - if (IS_ERR(conf->done)) - return dev_err_probe(&spi->dev, PTR_ERR(conf->done), - "Failed to get DONE gpio\n"); - - mgr = devm_fpga_mgr_register(&spi->dev, - "Xilinx Slave Serial FPGA Manager", - &xilinx_spi_ops, conf); - return PTR_ERR_OR_ZERO(mgr); + return xilinx_core_probe(core); } #ifdef CONFIG_OF static const struct of_device_id xlnx_spi_of_match[] = { - { .compatible = "xlnx,fpga-slave-serial", }, + { + .compatible = "xlnx,fpga-slave-serial", + }, {} }; MODULE_DEVICE_TABLE(of, xlnx_spi_of_match); diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 3949ded0d4fa59..02d9daf265d6ee 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -7,11 +7,13 @@ * Author: Suzuki K Poulose <suzuki.poulose@arm.com> */ +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/platform_device.h> #include <linux/slab.h> #include "coresight-catu.h" @@ -502,28 +504,20 @@ static const struct coresight_ops catu_ops = { .helper_ops = &catu_helper_ops, }; -static int catu_probe(struct amba_device *adev, const struct amba_id *id) +static int __catu_probe(struct device *dev, struct resource *res) { int ret = 0; u32 dma_mask; - struct catu_drvdata *drvdata; + struct catu_drvdata *drvdata = dev_get_drvdata(dev); struct coresight_desc catu_desc; struct coresight_platform_data *pdata = NULL; - struct device *dev = &adev->dev; void __iomem *base; catu_desc.name = coresight_alloc_device_name(&catu_devs, dev); if (!catu_desc.name) return -ENOMEM; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) { - ret = -ENOMEM; - goto out; - } - - dev_set_drvdata(dev, drvdata); - base = devm_ioremap_resource(dev, &adev->res); + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) { ret = PTR_ERR(base); goto out; @@ -567,19 +561,39 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id) drvdata->csdev = coresight_register(&catu_desc); if (IS_ERR(drvdata->csdev)) ret = PTR_ERR(drvdata->csdev); - else - pm_runtime_put(&adev->dev); out: return ret; } -static void catu_remove(struct amba_device *adev) +static int catu_probe(struct amba_device *adev, const struct amba_id *id) { - struct catu_drvdata *drvdata = dev_get_drvdata(&adev->dev); + struct catu_drvdata *drvdata; + int ret; + + drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + amba_set_drvdata(adev, drvdata); + ret = __catu_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; +} + +static void __catu_remove(struct device *dev) +{ + struct catu_drvdata *drvdata = dev_get_drvdata(dev); coresight_unregister(drvdata->csdev); } +static void catu_remove(struct amba_device *adev) +{ + __catu_remove(&adev->dev); +} + static struct amba_id catu_ids[] = { CS_AMBA_ID(0x000bb9ee), {}, @@ -598,13 +612,98 @@ static struct amba_driver catu_driver = { .id_table = catu_ids, }; +static int catu_platform_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct catu_drvdata *drvdata; + int ret = 0; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; + + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + dev_set_drvdata(&pdev->dev, drvdata); + ret = __catu_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) { + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); + } + + return ret; +} + +static void catu_platform_remove(struct platform_device *pdev) +{ + struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + + __catu_remove(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); +} + +#ifdef CONFIG_PM +static int catu_runtime_suspend(struct device *dev) +{ + struct catu_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); + return 0; +} + +static int catu_runtime_resume(struct device *dev) +{ + struct catu_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); + return 0; +} +#endif + +static const struct dev_pm_ops catu_dev_pm_ops = { + SET_RUNTIME_PM_OPS(catu_runtime_suspend, catu_runtime_resume, NULL) +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id catu_acpi_ids[] = { + {"ARMHC9CA", 0, 0, 0}, /* ARM CoreSight CATU */ + {}, +}; + +MODULE_DEVICE_TABLE(acpi, catu_acpi_ids); +#endif + +static struct platform_driver catu_platform_driver = { + .probe = catu_platform_probe, + .remove_new = catu_platform_remove, + .driver = { + .name = "coresight-catu-platform", + .acpi_match_table = ACPI_PTR(catu_acpi_ids), + .suppress_bind_attrs = true, + .pm = &catu_dev_pm_ops, + }, +}; + static int __init catu_init(void) { int ret; - ret = amba_driver_register(&catu_driver); - if (ret) - pr_info("Error registering catu driver\n"); + ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver); tmc_etr_set_catu_ops(&etr_catu_buf_ops); return ret; } @@ -612,7 +711,7 @@ static int __init catu_init(void) static void __exit catu_exit(void) { tmc_etr_remove_catu_ops(); - amba_driver_unregister(&catu_driver); + coresight_remove_driver(&catu_driver, &catu_platform_driver); } module_init(catu_init); diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h index 442e034bbfbaf4..141feac1c14b08 100644 --- a/drivers/hwtracing/coresight/coresight-catu.h +++ b/drivers/hwtracing/coresight/coresight-catu.h @@ -61,6 +61,7 @@ #define CATU_IRQEN_OFF 0x0 struct catu_drvdata { + struct clk *pclk; void __iomem *base; struct coresight_device *csdev; int irq; diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index b83613e342891b..9fc6f6b863e04b 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1398,6 +1398,35 @@ static void __exit coresight_exit(void) module_init(coresight_init); module_exit(coresight_exit); +int coresight_init_driver(const char *drv, struct amba_driver *amba_drv, + struct platform_driver *pdev_drv) +{ + int ret; + + ret = amba_driver_register(amba_drv); + if (ret) { + pr_err("%s: error registering AMBA driver\n", drv); + return ret; + } + + ret = platform_driver_register(pdev_drv); + if (!ret) + return 0; + + pr_err("%s: error registering platform driver\n", drv); + amba_driver_unregister(amba_drv); + return ret; +} +EXPORT_SYMBOL_GPL(coresight_init_driver); + +void coresight_remove_driver(struct amba_driver *amba_drv, + struct platform_driver *pdev_drv) +{ + amba_driver_unregister(amba_drv); + platform_driver_unregister(pdev_drv); +} +EXPORT_SYMBOL_GPL(coresight_remove_driver); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>"); diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 1874df7c6a7369..75962dae9aa185 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -4,6 +4,7 @@ * * Author: Leo Yan <leo.yan@linaro.org> */ +#include <linux/acpi.h> #include <linux/amba/bus.h> #include <linux/coresight.h> #include <linux/cpu.h> @@ -18,6 +19,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/panic_notifier.h> +#include <linux/platform_device.h> #include <linux/pm_qos.h> #include <linux/slab.h> #include <linux/smp.h> @@ -84,6 +86,7 @@ #define DEBUG_WAIT_TIMEOUT 32000 struct debug_drvdata { + struct clk *pclk; void __iomem *base; struct device *dev; int cpu; @@ -557,18 +560,12 @@ static void debug_func_exit(void) debugfs_remove_recursive(debug_debugfs_dir); } -static int debug_probe(struct amba_device *adev, const struct amba_id *id) +static int __debug_probe(struct device *dev, struct resource *res) { + struct debug_drvdata *drvdata = dev_get_drvdata(dev); void __iomem *base; - struct device *dev = &adev->dev; - struct debug_drvdata *drvdata; - struct resource *res = &adev->res; int ret; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - drvdata->cpu = coresight_get_cpu(dev); if (drvdata->cpu < 0) return drvdata->cpu; @@ -579,10 +576,7 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id) return -EBUSY; } - drvdata->dev = &adev->dev; - amba_set_drvdata(adev, drvdata); - - /* Validity for the resource is already checked by the AMBA core */ + drvdata->dev = dev; base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); @@ -629,10 +623,21 @@ err: return ret; } -static void debug_remove(struct amba_device *adev) +static int debug_probe(struct amba_device *adev, const struct amba_id *id) { - struct device *dev = &adev->dev; - struct debug_drvdata *drvdata = amba_get_drvdata(adev); + struct debug_drvdata *drvdata; + + drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + amba_set_drvdata(adev, drvdata); + return __debug_probe(&adev->dev, &adev->res); +} + +static void __debug_remove(struct device *dev) +{ + struct debug_drvdata *drvdata = dev_get_drvdata(dev); per_cpu(debug_drvdata, drvdata->cpu) = NULL; @@ -646,6 +651,11 @@ static void debug_remove(struct amba_device *adev) debug_func_exit(); } +static void debug_remove(struct amba_device *adev) +{ + __debug_remove(&adev->dev); +} + static const struct amba_cs_uci_id uci_id_debug[] = { { /* CPU Debug UCI data */ @@ -677,7 +687,102 @@ static struct amba_driver debug_driver = { .id_table = debug_ids, }; -module_amba_driver(debug_driver); +static int debug_platform_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct debug_drvdata *drvdata; + int ret = 0; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; + + dev_set_drvdata(&pdev->dev, drvdata); + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = __debug_probe(&pdev->dev, res); + if (ret) { + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); + } + return ret; +} + +static void debug_platform_remove(struct platform_device *pdev) +{ + struct debug_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + + __debug_remove(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id debug_platform_ids[] = { + {"ARMHC503", 0, 0, 0}, /* ARM CoreSight Debug */ + {}, +}; +MODULE_DEVICE_TABLE(acpi, debug_platform_ids); +#endif + +#ifdef CONFIG_PM +static int debug_runtime_suspend(struct device *dev) +{ + struct debug_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); + return 0; +} + +static int debug_runtime_resume(struct device *dev) +{ + struct debug_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); + return 0; +} +#endif + +static const struct dev_pm_ops debug_dev_pm_ops = { + SET_RUNTIME_PM_OPS(debug_runtime_suspend, debug_runtime_resume, NULL) +}; + +static struct platform_driver debug_platform_driver = { + .probe = debug_platform_probe, + .remove_new = debug_platform_remove, + .driver = { + .name = "coresight-debug-platform", + .acpi_match_table = ACPI_PTR(debug_platform_ids), + .suppress_bind_attrs = true, + .pm = &debug_dev_pm_ops, + }, +}; + +static int __init debug_init(void) +{ + return coresight_init_driver("debug", &debug_driver, &debug_platform_driver); +} + +static void __exit debug_exit(void) +{ + coresight_remove_driver(&debug_driver, &debug_platform_driver); +} +module_init(debug_init); +module_exit(debug_exit); MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>"); MODULE_DESCRIPTION("ARM Coresight CPU Debug Driver"); diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index c2ca4a02dfce1f..a0bdfabddbc683 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1240,6 +1240,8 @@ static void etm4_init_arch_data(void *info) drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0); /* QSUPP, bits[16:15] Q element support field */ drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0); + if (drvdata->q_support) + drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT); /* TSSIZE, bits[28:24] Global timestamp size field */ drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0); @@ -1732,16 +1734,14 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) state->trcccctlr = etm4x_read32(csa, TRCCCCTLR); state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR); state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR); - state->trcqctlr = etm4x_read32(csa, TRCQCTLR); + if (drvdata->q_filt) + state->trcqctlr = etm4x_read32(csa, TRCQCTLR); state->trcvictlr = etm4x_read32(csa, TRCVICTLR); state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR); state->trcvissctlr = etm4x_read32(csa, TRCVISSCTLR); if (drvdata->nr_pe_cmp) state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR); - state->trcvdctlr = etm4x_read32(csa, TRCVDCTLR); - state->trcvdsacctlr = etm4x_read32(csa, TRCVDSACCTLR); - state->trcvdarcctlr = etm4x_read32(csa, TRCVDARCCTLR); for (i = 0; i < drvdata->nrseqstate - 1; i++) state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i)); @@ -1758,7 +1758,8 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) state->trccntvr[i] = etm4x_read32(csa, TRCCNTVRn(i)); } - for (i = 0; i < drvdata->nr_resource * 2; i++) + /* Resource selector pair 0 is reserved */ + for (i = 2; i < drvdata->nr_resource * 2; i++) state->trcrsctlr[i] = etm4x_read32(csa, TRCRSCTLRn(i)); for (i = 0; i < drvdata->nr_ss_cmp; i++) { @@ -1843,8 +1844,10 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) { int i; struct etmv4_save_state *state = drvdata->save_state; - struct csdev_access tmp_csa = CSDEV_ACCESS_IOMEM(drvdata->base); - struct csdev_access *csa = &tmp_csa; + struct csdev_access *csa = &drvdata->csdev->access; + + if (WARN_ON(!drvdata->csdev)) + return; etm4_cs_unlock(drvdata, csa); etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET); @@ -1863,16 +1866,14 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR); etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR); etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR); - etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR); + if (drvdata->q_filt) + etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR); etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR); etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR); etm4x_relaxed_write32(csa, state->trcvissctlr, TRCVISSCTLR); if (drvdata->nr_pe_cmp) etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR); - etm4x_relaxed_write32(csa, state->trcvdctlr, TRCVDCTLR); - etm4x_relaxed_write32(csa, state->trcvdsacctlr, TRCVDSACCTLR); - etm4x_relaxed_write32(csa, state->trcvdarcctlr, TRCVDARCCTLR); for (i = 0; i < drvdata->nrseqstate - 1; i++) etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i)); @@ -1889,7 +1890,8 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, state->trccntvr[i], TRCCNTVRn(i)); } - for (i = 0; i < drvdata->nr_resource * 2; i++) + /* Resource selector pair 0 is reserved */ + for (i = 2; i < drvdata->nr_resource * 2; i++) etm4x_relaxed_write32(csa, state->trcrsctlr[i], TRCRSCTLRn(i)); for (i = 0; i < drvdata->nr_ss_cmp; i++) { @@ -2213,6 +2215,9 @@ static int etm4_probe_platform_dev(struct platform_device *pdev) ret = etm4_probe(&pdev->dev); pm_runtime_put(&pdev->dev); + if (ret) + pm_runtime_disable(&pdev->dev); + return ret; } diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 9ea678bc2e8e55..9e9165f62e81fe 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -43,9 +43,6 @@ #define TRCVIIECTLR 0x084 #define TRCVISSCTLR 0x088 #define TRCVIPCSSCTLR 0x08C -#define TRCVDCTLR 0x0A0 -#define TRCVDSACCTLR 0x0A4 -#define TRCVDARCCTLR 0x0A8 /* Derived resources registers */ #define TRCSEQEVRn(n) (0x100 + (n * 4)) /* n = 0-2 */ #define TRCSEQRSTEVR 0x118 @@ -90,9 +87,6 @@ /* Address Comparator registers n = 0-15 */ #define TRCACVRn(n) (0x400 + (n * 8)) #define TRCACATRn(n) (0x480 + (n * 8)) -/* Data Value Comparator Value registers, n = 0-7 */ -#define TRCDVCVRn(n) (0x500 + (n * 16)) -#define TRCDVCMRn(n) (0x580 + (n * 16)) /* ContextID/Virtual ContextID comparators, n = 0-7 */ #define TRCCIDCVRn(n) (0x600 + (n * 8)) #define TRCVMIDCVRn(n) (0x640 + (n * 8)) @@ -141,6 +135,7 @@ #define TRCIDR0_TRCCCI BIT(7) #define TRCIDR0_RETSTACK BIT(9) #define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10) +#define TRCIDR0_QFILT BIT(14) #define TRCIDR0_QSUPP_MASK GENMASK(16, 15) #define TRCIDR0_TSSIZE_MASK GENMASK(28, 24) @@ -272,9 +267,6 @@ /* List of registers accessible via System instructions */ #define ETM4x_ONLY_SYSREG_LIST(op, val) \ CASE_##op((val), TRCPROCSELR) \ - CASE_##op((val), TRCVDCTLR) \ - CASE_##op((val), TRCVDSACCTLR) \ - CASE_##op((val), TRCVDARCCTLR) \ CASE_##op((val), TRCOSLAR) #define ETM_COMMON_SYSREG_LIST(op, val) \ @@ -422,22 +414,6 @@ CASE_##op((val), TRCACATRn(13)) \ CASE_##op((val), TRCACATRn(14)) \ CASE_##op((val), TRCACATRn(15)) \ - CASE_##op((val), TRCDVCVRn(0)) \ - CASE_##op((val), TRCDVCVRn(1)) \ - CASE_##op((val), TRCDVCVRn(2)) \ - CASE_##op((val), TRCDVCVRn(3)) \ - CASE_##op((val), TRCDVCVRn(4)) \ - CASE_##op((val), TRCDVCVRn(5)) \ - CASE_##op((val), TRCDVCVRn(6)) \ - CASE_##op((val), TRCDVCVRn(7)) \ - CASE_##op((val), TRCDVCMRn(0)) \ - CASE_##op((val), TRCDVCMRn(1)) \ - CASE_##op((val), TRCDVCMRn(2)) \ - CASE_##op((val), TRCDVCMRn(3)) \ - CASE_##op((val), TRCDVCMRn(4)) \ - CASE_##op((val), TRCDVCMRn(5)) \ - CASE_##op((val), TRCDVCMRn(6)) \ - CASE_##op((val), TRCDVCMRn(7)) \ CASE_##op((val), TRCCIDCVRn(0)) \ CASE_##op((val), TRCCIDCVRn(1)) \ CASE_##op((val), TRCCIDCVRn(2)) \ @@ -907,9 +883,6 @@ struct etmv4_save_state { u32 trcviiectlr; u32 trcvissctlr; u32 trcvipcssctlr; - u32 trcvdctlr; - u32 trcvdsacctlr; - u32 trcvdarcctlr; u32 trcseqevr[ETM_MAX_SEQ_STATES]; u32 trcseqrstevr; @@ -982,6 +955,7 @@ struct etmv4_save_state { * @os_unlock: True if access to management registers is allowed. * @instrp0: Tracing of load and store instructions * as P0 elements is supported. + * @q_filt: Q element filtering support, if Q elements are supported. * @trcbb: Indicates if the trace unit supports branch broadcast tracing. * @trccond: If the trace unit supports conditional * instruction tracing. @@ -1044,6 +1018,7 @@ struct etmv4_drvdata { bool boot_enable; bool os_unlock; bool instrp0; + bool q_filt; bool trcbb; bool trccond; bool retstack; diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index ef1a0abfee4e91..616735dc80a6d7 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -36,6 +36,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); * struct funnel_drvdata - specifics associated to a funnel component * @base: memory mapped base address for this component. * @atclk: optional clock for the core parts of the funnel. + * @pclk: APB clock if present, otherwise NULL * @csdev: component vitals needed by the framework. * @priority: port selection order. * @spinlock: serialize enable/disable operations. @@ -43,6 +44,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); struct funnel_drvdata { void __iomem *base; struct clk *atclk; + struct clk *pclk; struct coresight_device *csdev; unsigned long priority; spinlock_t spinlock; @@ -236,6 +238,10 @@ static int funnel_probe(struct device *dev, struct resource *res) return ret; } + drvdata->pclk = coresight_get_enable_apb_pclk(dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; + /* * Map the device base for dynamic-funnel, which has been * validated by AMBA core. @@ -272,12 +278,13 @@ static int funnel_probe(struct device *dev, struct resource *res) goto out_disable_clk; } - pm_runtime_put(dev); ret = 0; out_disable_clk: if (ret && !IS_ERR_OR_NULL(drvdata->atclk)) clk_disable_unprepare(drvdata->atclk); + if (ret && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); return ret; } @@ -298,6 +305,9 @@ static int funnel_runtime_suspend(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_disable_unprepare(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); + return 0; } @@ -308,6 +318,8 @@ static int funnel_runtime_resume(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_prepare_enable(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); return 0; } #endif @@ -316,55 +328,61 @@ static const struct dev_pm_ops funnel_dev_pm_ops = { SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL) }; -static int static_funnel_probe(struct platform_device *pdev) +static int funnel_platform_probe(struct platform_device *pdev) { + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); int ret; pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - /* Static funnel do not have programming base */ - ret = funnel_probe(&pdev->dev, NULL); - - if (ret) { - pm_runtime_put_noidle(&pdev->dev); + ret = funnel_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) pm_runtime_disable(&pdev->dev); - } return ret; } -static void static_funnel_remove(struct platform_device *pdev) +static void funnel_platform_remove(struct platform_device *pdev) { + struct funnel_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + funnel_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); } -static const struct of_device_id static_funnel_match[] = { +static const struct of_device_id funnel_match[] = { {.compatible = "arm,coresight-static-funnel"}, {} }; -MODULE_DEVICE_TABLE(of, static_funnel_match); +MODULE_DEVICE_TABLE(of, funnel_match); #ifdef CONFIG_ACPI -static const struct acpi_device_id static_funnel_ids[] = { - {"ARMHC9FE", 0, 0, 0}, +static const struct acpi_device_id funnel_acpi_ids[] = { + {"ARMHC9FE", 0, 0, 0}, /* ARM Coresight Static Funnel */ + {"ARMHC9FF", 0, 0, 0}, /* ARM CoreSight Dynamic Funnel */ {}, }; -MODULE_DEVICE_TABLE(acpi, static_funnel_ids); +MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids); #endif -static struct platform_driver static_funnel_driver = { - .probe = static_funnel_probe, - .remove_new = static_funnel_remove, - .driver = { - .name = "coresight-static-funnel", +static struct platform_driver funnel_driver = { + .probe = funnel_platform_probe, + .remove_new = funnel_platform_remove, + .driver = { + .name = "coresight-funnel", /* THIS_MODULE is taken care of by platform_driver_register() */ - .of_match_table = static_funnel_match, - .acpi_match_table = ACPI_PTR(static_funnel_ids), + .of_match_table = funnel_match, + .acpi_match_table = ACPI_PTR(funnel_acpi_ids), .pm = &funnel_dev_pm_ops, .suppress_bind_attrs = true, }, @@ -373,7 +391,13 @@ static struct platform_driver static_funnel_driver = { static int dynamic_funnel_probe(struct amba_device *adev, const struct amba_id *id) { - return funnel_probe(&adev->dev, &adev->res); + int ret; + + ret = funnel_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; } static void dynamic_funnel_remove(struct amba_device *adev) @@ -410,27 +434,12 @@ static struct amba_driver dynamic_funnel_driver = { static int __init funnel_init(void) { - int ret; - - ret = platform_driver_register(&static_funnel_driver); - if (ret) { - pr_info("Error registering platform driver\n"); - return ret; - } - - ret = amba_driver_register(&dynamic_funnel_driver); - if (ret) { - pr_info("Error registering amba driver\n"); - platform_driver_unregister(&static_funnel_driver); - } - - return ret; + return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver); } static void __exit funnel_exit(void) { - platform_driver_unregister(&static_funnel_driver); - amba_driver_unregister(&dynamic_funnel_driver); + coresight_remove_driver(&dynamic_funnel_driver, &funnel_driver); } module_init(funnel_init); diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index eb365236f9a976..fc3617642b0192 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -222,6 +222,16 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) return uci_id->data; } +static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid) +{ + while (table->mask) { + if ((pid & table->mask) == table->id) + return coresight_get_uci_data(table); + table++; + }; + return NULL; +} + void coresight_release_platform_data(struct coresight_device *csdev, struct device *dev, struct coresight_platform_data *pdata); diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 73452d9dc13b26..87e590cf16786b 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -31,6 +31,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); * @base: memory mapped base address for this component. Also indicates * whether this one is programmable or not. * @atclk: optional clock for the core parts of the replicator. + * @pclk: APB clock if present, otherwise NULL * @csdev: component vitals needed by the framework * @spinlock: serialize enable/disable operations. * @check_idfilter_val: check if the context is lost upon clock removal. @@ -38,6 +39,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); struct replicator_drvdata { void __iomem *base; struct clk *atclk; + struct clk *pclk; struct coresight_device *csdev; spinlock_t spinlock; bool check_idfilter_val; @@ -243,6 +245,10 @@ static int replicator_probe(struct device *dev, struct resource *res) return ret; } + drvdata->pclk = coresight_get_enable_apb_pclk(dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; + /* * Map the device base for dynamic-replicator, which has been * validated by AMBA core @@ -285,11 +291,12 @@ static int replicator_probe(struct device *dev, struct resource *res) } replicator_reset(drvdata); - pm_runtime_put(dev); out_disable_clk: if (ret && !IS_ERR_OR_NULL(drvdata->atclk)) clk_disable_unprepare(drvdata->atclk); + if (ret && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); return ret; } @@ -301,29 +308,34 @@ static int replicator_remove(struct device *dev) return 0; } -static int static_replicator_probe(struct platform_device *pdev) +static int replicator_platform_probe(struct platform_device *pdev) { + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); int ret; pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - /* Static replicators do not have programming base */ - ret = replicator_probe(&pdev->dev, NULL); - - if (ret) { - pm_runtime_put_noidle(&pdev->dev); + ret = replicator_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) pm_runtime_disable(&pdev->dev); - } return ret; } -static void static_replicator_remove(struct platform_device *pdev) +static void replicator_platform_remove(struct platform_device *pdev) { + struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + replicator_remove(&pdev->dev); pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); } #ifdef CONFIG_PM @@ -334,6 +346,8 @@ static int replicator_runtime_suspend(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_disable_unprepare(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); return 0; } @@ -344,6 +358,8 @@ static int replicator_runtime_resume(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_prepare_enable(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); return 0; } #endif @@ -353,31 +369,32 @@ static const struct dev_pm_ops replicator_dev_pm_ops = { replicator_runtime_resume, NULL) }; -static const struct of_device_id static_replicator_match[] = { +static const struct of_device_id replicator_match[] = { {.compatible = "arm,coresight-replicator"}, {.compatible = "arm,coresight-static-replicator"}, {} }; -MODULE_DEVICE_TABLE(of, static_replicator_match); +MODULE_DEVICE_TABLE(of, replicator_match); #ifdef CONFIG_ACPI -static const struct acpi_device_id static_replicator_acpi_ids[] = { +static const struct acpi_device_id replicator_acpi_ids[] = { {"ARMHC985", 0, 0, 0}, /* ARM CoreSight Static Replicator */ + {"ARMHC98D", 0, 0, 0}, /* ARM CoreSight Dynamic Replicator */ {} }; -MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids); +MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids); #endif -static struct platform_driver static_replicator_driver = { - .probe = static_replicator_probe, - .remove_new = static_replicator_remove, +static struct platform_driver replicator_driver = { + .probe = replicator_platform_probe, + .remove_new = replicator_platform_remove, .driver = { - .name = "coresight-static-replicator", + .name = "coresight-replicator", /* THIS_MODULE is taken care of by platform_driver_register() */ - .of_match_table = of_match_ptr(static_replicator_match), - .acpi_match_table = ACPI_PTR(static_replicator_acpi_ids), + .of_match_table = of_match_ptr(replicator_match), + .acpi_match_table = ACPI_PTR(replicator_acpi_ids), .pm = &replicator_dev_pm_ops, .suppress_bind_attrs = true, }, @@ -386,7 +403,13 @@ static struct platform_driver static_replicator_driver = { static int dynamic_replicator_probe(struct amba_device *adev, const struct amba_id *id) { - return replicator_probe(&adev->dev, &adev->res); + int ret; + + ret = replicator_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; } static void dynamic_replicator_remove(struct amba_device *adev) @@ -416,27 +439,12 @@ static struct amba_driver dynamic_replicator_driver = { static int __init replicator_init(void) { - int ret; - - ret = platform_driver_register(&static_replicator_driver); - if (ret) { - pr_info("Error registering platform driver\n"); - return ret; - } - - ret = amba_driver_register(&dynamic_replicator_driver); - if (ret) { - pr_info("Error registering amba driver\n"); - platform_driver_unregister(&static_replicator_driver); - } - - return ret; + return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver); } static void __exit replicator_exit(void) { - platform_driver_unregister(&static_replicator_driver); - amba_driver_unregister(&dynamic_replicator_driver); + coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver); } module_init(replicator_init); diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 974d37e5f94c02..e1c62820dfdaba 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -29,6 +29,7 @@ #include <linux/perf_event.h> #include <linux/pm_runtime.h> #include <linux/stm.h> +#include <linux/platform_device.h> #include "coresight-priv.h" #include "coresight-trace-id.h" @@ -115,6 +116,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm"); * struct stm_drvdata - specifics associated to an STM component * @base: memory mapped base address for this component. * @atclk: optional clock for the core parts of the STM. + * @pclk: APB clock if present, otherwise NULL * @csdev: component vitals needed by the framework. * @spinlock: only one at a time pls. * @chs: the channels accociated to this STM. @@ -131,6 +133,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm"); struct stm_drvdata { void __iomem *base; struct clk *atclk; + struct clk *pclk; struct coresight_device *csdev; spinlock_t spinlock; struct channel_space chs; @@ -800,14 +803,22 @@ static void stm_init_generic_data(struct stm_drvdata *drvdata, drvdata->stm.set_options = stm_generic_set_options; } -static int stm_probe(struct amba_device *adev, const struct amba_id *id) +static const struct amba_id stm_ids[]; + +static char *stm_csdev_name(struct coresight_device *csdev) +{ + u32 stm_pid = coresight_get_pid(&csdev->access); + void *uci_data = coresight_get_uci_data_from_amba(stm_ids, stm_pid); + + return uci_data ? (char *)uci_data : "STM"; +} + +static int __stm_probe(struct device *dev, struct resource *res) { int ret, trace_id; void __iomem *base; - struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL; struct stm_drvdata *drvdata; - struct resource *res = &adev->res; struct resource ch_res; struct coresight_desc desc = { 0 }; @@ -819,12 +830,16 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) if (!drvdata) return -ENOMEM; - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ + drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk); if (ret) return ret; } + + drvdata->pclk = coresight_get_enable_apb_pclk(dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; dev_set_drvdata(dev, drvdata); base = devm_ioremap_resource(dev, res); @@ -872,7 +887,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) ret = PTR_ERR(pdata); goto stm_unregister; } - adev->dev.platform_data = pdata; + dev->platform_data = pdata; desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE; @@ -893,10 +908,8 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) } drvdata->traceid = (u8)trace_id; - pm_runtime_put(&adev->dev); - dev_info(&drvdata->csdev->dev, "%s initialized\n", - (char *)coresight_get_uci_data(id)); + stm_csdev_name(drvdata->csdev)); return 0; cs_unregister: @@ -907,9 +920,20 @@ stm_unregister: return ret; } -static void stm_remove(struct amba_device *adev) +static int stm_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + + ret = __stm_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; +} + +static void __stm_remove(struct device *dev) { - struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev); + struct stm_drvdata *drvdata = dev_get_drvdata(dev); coresight_trace_id_put_system_id(drvdata->traceid); coresight_unregister(drvdata->csdev); @@ -917,6 +941,11 @@ static void stm_remove(struct amba_device *adev) stm_unregister_device(&drvdata->stm); } +static void stm_remove(struct amba_device *adev) +{ + __stm_remove(&adev->dev); +} + #ifdef CONFIG_PM static int stm_runtime_suspend(struct device *dev) { @@ -925,6 +954,8 @@ static int stm_runtime_suspend(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_disable_unprepare(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); return 0; } @@ -935,6 +966,8 @@ static int stm_runtime_resume(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_prepare_enable(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); return 0; } #endif @@ -963,7 +996,66 @@ static struct amba_driver stm_driver = { .id_table = stm_ids, }; -module_amba_driver(stm_driver); +static int stm_platform_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int ret = 0; + + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = __stm_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static void stm_platform_remove(struct platform_device *pdev) +{ + struct stm_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + + __stm_remove(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id stm_acpi_ids[] = { + {"ARMHC502", 0, 0, 0}, /* ARM CoreSight STM */ + {}, +}; +MODULE_DEVICE_TABLE(acpi, stm_acpi_ids); +#endif + +static struct platform_driver stm_platform_driver = { + .probe = stm_platform_probe, + .remove_new = stm_platform_remove, + .driver = { + .name = "coresight-stm-platform", + .acpi_match_table = ACPI_PTR(stm_acpi_ids), + .suppress_bind_attrs = true, + .pm = &stm_dev_pm_ops, + }, +}; + +static int __init stm_init(void) +{ + return coresight_init_driver("stm", &stm_driver, &stm_platform_driver); +} + +static void __exit stm_exit(void) +{ + coresight_remove_driver(&stm_driver, &stm_platform_driver); +} +module_init(stm_init); +module_exit(stm_exit); MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver"); diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index 72005b0c633e5c..741ce1748e759d 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -4,6 +4,7 @@ * Description: CoreSight Trace Memory Controller driver */ +#include <linux/acpi.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/types.h> @@ -24,6 +25,8 @@ #include <linux/of.h> #include <linux/coresight.h> #include <linux/amba/bus.h> +#include <linux/platform_device.h> +#include <linux/acpi.h> #include "coresight-priv.h" #include "coresight-tmc.h" @@ -360,7 +363,32 @@ static const struct attribute_group *coresight_etr_groups[] = { static inline bool tmc_etr_can_use_sg(struct device *dev) { - return fwnode_property_present(dev->fwnode, "arm,scatter-gather"); + int ret; + u8 val_u8; + + /* + * Presence of the property 'arm,scatter-gather' is checked + * on the platform for the feature support, rather than its + * value. + */ + if (is_of_node(dev->fwnode)) { + return fwnode_property_present(dev->fwnode, "arm,scatter-gather"); + } else if (is_acpi_device_node(dev->fwnode)) { + /* + * TMC_DEVID_NOSCAT test in tmc_etr_setup_caps(), has already ensured + * this property is only checked for Coresight SoC 400 TMC configured + * as ETR. + */ + ret = fwnode_property_read_u8(dev->fwnode, "arm-armhc97c-sg-enable", &val_u8); + if (!ret) + return !!val_u8; + + if (fwnode_property_present(dev->fwnode, "arm,scatter-gather")) { + pr_warn_once("Deprecated ACPI property - arm,scatter-gather\n"); + return true; + } + } + return false; } static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata) @@ -370,16 +398,23 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata) return (auth & TMC_AUTH_NSID_MASK) == 0x3; } +static const struct amba_id tmc_ids[]; + /* Detect and initialise the capabilities of a TMC ETR */ -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps) +static int tmc_etr_setup_caps(struct device *parent, u32 devid, + struct csdev_access *access) { int rc; - u32 dma_mask = 0; + u32 tmc_pid, dma_mask = 0; struct tmc_drvdata *drvdata = dev_get_drvdata(parent); + void *dev_caps; if (!tmc_etr_has_non_secure_access(drvdata)) return -EACCES; + tmc_pid = coresight_get_pid(access); + dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid); + /* Set the unadvertised capabilities */ tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps); @@ -437,24 +472,17 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev) return burst_size; } -static int tmc_probe(struct amba_device *adev, const struct amba_id *id) +static int __tmc_probe(struct device *dev, struct resource *res) { int ret = 0; u32 devid; void __iomem *base; - struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL; - struct tmc_drvdata *drvdata; - struct resource *res = &adev->res; + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); struct coresight_desc desc = { 0 }; struct coresight_dev_list *dev_list = NULL; ret = -ENOMEM; - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - goto out; - - dev_set_drvdata(dev, drvdata); /* Validity for the resource is already checked by the AMBA core */ base = devm_ioremap_resource(dev, res); @@ -497,8 +525,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM; desc.ops = &tmc_etr_cs_ops; - ret = tmc_etr_setup_caps(dev, devid, - coresight_get_uci_data(id)); + ret = tmc_etr_setup_caps(dev, devid, &desc.access); if (ret) goto out; idr_init(&drvdata->idr); @@ -530,7 +557,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) ret = PTR_ERR(pdata); goto out; } - adev->dev.platform_data = pdata; + dev->platform_data = pdata; desc.pdata = pdata; drvdata->csdev = coresight_register(&desc); @@ -545,12 +572,27 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) ret = misc_register(&drvdata->miscdev); if (ret) coresight_unregister(drvdata->csdev); - else - pm_runtime_put(&adev->dev); out: return ret; } +static int tmc_probe(struct amba_device *adev, const struct amba_id *id) +{ + struct tmc_drvdata *drvdata; + int ret; + + drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + amba_set_drvdata(adev, drvdata); + ret = __tmc_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; +} + static void tmc_shutdown(struct amba_device *adev) { unsigned long flags; @@ -573,9 +615,9 @@ out: spin_unlock_irqrestore(&drvdata->spinlock, flags); } -static void tmc_remove(struct amba_device *adev) +static void __tmc_remove(struct device *dev) { - struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev); + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); /* * Since misc_open() holds a refcount on the f_ops, which is @@ -586,6 +628,11 @@ static void tmc_remove(struct amba_device *adev) coresight_unregister(drvdata->csdev); } +static void tmc_remove(struct amba_device *adev) +{ + __tmc_remove(&adev->dev); +} + static const struct amba_id tmc_ids[] = { CS_AMBA_ID(0x000bb961), /* Coresight SoC 600 TMC-ETR/ETS */ @@ -611,7 +658,101 @@ static struct amba_driver tmc_driver = { .id_table = tmc_ids, }; -module_amba_driver(tmc_driver); +static int tmc_platform_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct tmc_drvdata *drvdata; + int ret = 0; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; + + dev_set_drvdata(&pdev->dev, drvdata); + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = __tmc_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static void tmc_platform_remove(struct platform_device *pdev) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + + __tmc_remove(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); +} + +#ifdef CONFIG_PM +static int tmc_runtime_suspend(struct device *dev) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); + return 0; +} + +static int tmc_runtime_resume(struct device *dev) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); + return 0; +} +#endif + +static const struct dev_pm_ops tmc_dev_pm_ops = { + SET_RUNTIME_PM_OPS(tmc_runtime_suspend, tmc_runtime_resume, NULL) +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id tmc_acpi_ids[] = { + {"ARMHC501", 0, 0, 0}, /* ARM CoreSight ETR */ + {"ARMHC97C", 0, 0, 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ + {}, +}; +MODULE_DEVICE_TABLE(acpi, tmc_acpi_ids); +#endif + +static struct platform_driver tmc_platform_driver = { + .probe = tmc_platform_probe, + .remove_new = tmc_platform_remove, + .driver = { + .name = "coresight-tmc-platform", + .acpi_match_table = ACPI_PTR(tmc_acpi_ids), + .suppress_bind_attrs = true, + .pm = &tmc_dev_pm_ops, + }, +}; + +static int __init tmc_init(void) +{ + return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver); +} + +static void __exit tmc_exit(void) +{ + coresight_remove_driver(&tmc_driver, &tmc_platform_driver); +} +module_init(tmc_init); +module_exit(tmc_exit); MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver"); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index cef979c897e62d..c77763b49de0c6 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -166,6 +166,7 @@ struct etr_buf { /** * struct tmc_drvdata - specifics associated to an TMC component + * @pclk: APB clock if present, otherwise NULL * @base: memory mapped base address for this component. * @csdev: component vitals needed by the framework. * @miscdev: specifics to handle "/dev/xyz.tmc" entry. @@ -189,6 +190,7 @@ struct etr_buf { * @perf_buf: PERF buffer for ETR. */ struct tmc_drvdata { + struct clk *pclk; void __iomem *base; struct coresight_device *csdev; struct miscdevice miscdev; diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 29024f880fda7a..6ecde7d4a25de4 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -5,17 +5,19 @@ * Description: CoreSight Trace Port Interface Unit driver */ +#include <linux/acpi.h> +#include <linux/amba/bus.h> #include <linux/atomic.h> -#include <linux/kernel.h> -#include <linux/init.h> +#include <linux/clk.h> +#include <linux/coresight.h> #include <linux/device.h> -#include <linux/io.h> #include <linux/err.h> -#include <linux/slab.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <linux/coresight.h> -#include <linux/amba/bus.h> -#include <linux/clk.h> +#include <linux/slab.h> #include "coresight-priv.h" @@ -52,11 +54,13 @@ DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu"); /* * @base: memory mapped base address for this component. * @atclk: optional clock for the core parts of the TPIU. + * @pclk: APB clock if present, otherwise NULL * @csdev: component vitals needed by the framework. */ struct tpiu_drvdata { void __iomem *base; struct clk *atclk; + struct clk *pclk; struct coresight_device *csdev; spinlock_t spinlock; }; @@ -122,14 +126,12 @@ static const struct coresight_ops tpiu_cs_ops = { .sink_ops = &tpiu_sink_ops, }; -static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) +static int __tpiu_probe(struct device *dev, struct resource *res) { int ret; void __iomem *base; - struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL; struct tpiu_drvdata *drvdata; - struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; desc.name = coresight_alloc_device_name(&tpiu_devs, dev); @@ -142,12 +144,16 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock); - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ + drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk); if (ret) return ret; } + + drvdata->pclk = coresight_get_enable_apb_pclk(dev); + if (IS_ERR(drvdata->pclk)) + return -ENODEV; dev_set_drvdata(dev, drvdata); /* Validity for the resource is already checked by the AMBA core */ @@ -173,21 +179,34 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) desc.dev = dev; drvdata->csdev = coresight_register(&desc); - if (!IS_ERR(drvdata->csdev)) { - pm_runtime_put(&adev->dev); + if (!IS_ERR(drvdata->csdev)) return 0; - } return PTR_ERR(drvdata->csdev); } -static void tpiu_remove(struct amba_device *adev) +static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) { - struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev); + int ret; + + ret = __tpiu_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + return ret; +} + +static void __tpiu_remove(struct device *dev) +{ + struct tpiu_drvdata *drvdata = dev_get_drvdata(dev); coresight_unregister(drvdata->csdev); } +static void tpiu_remove(struct amba_device *adev) +{ + __tpiu_remove(&adev->dev); +} + #ifdef CONFIG_PM static int tpiu_runtime_suspend(struct device *dev) { @@ -196,6 +215,8 @@ static int tpiu_runtime_suspend(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_disable_unprepare(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_disable_unprepare(drvdata->pclk); return 0; } @@ -206,6 +227,8 @@ static int tpiu_runtime_resume(struct device *dev) if (drvdata && !IS_ERR(drvdata->atclk)) clk_prepare_enable(drvdata->atclk); + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) + clk_prepare_enable(drvdata->pclk); return 0; } #endif @@ -245,7 +268,66 @@ static struct amba_driver tpiu_driver = { .id_table = tpiu_ids, }; -module_amba_driver(tpiu_driver); +static int tpiu_platform_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int ret; + + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = __tpiu_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static void tpiu_platform_remove(struct platform_device *pdev) +{ + struct tpiu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); + + if (WARN_ON(!drvdata)) + return; + + __tpiu_remove(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (!IS_ERR_OR_NULL(drvdata->pclk)) + clk_put(drvdata->pclk); +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id tpiu_acpi_ids[] = { + {"ARMHC979", 0, 0, 0}, /* ARM CoreSight TPIU */ + {} +}; +MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids); +#endif + +static struct platform_driver tpiu_platform_driver = { + .probe = tpiu_platform_probe, + .remove_new = tpiu_platform_remove, + .driver = { + .name = "coresight-tpiu-platform", + .acpi_match_table = ACPI_PTR(tpiu_acpi_ids), + .suppress_bind_attrs = true, + .pm = &tpiu_dev_pm_ops, + }, +}; + +static int __init tpiu_init(void) +{ + return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver); +} + +static void __exit tpiu_exit(void) +{ + coresight_remove_driver(&tpiu_driver, &tpiu_platform_driver); +} +module_init(tpiu_init); +module_exit(tpiu_exit); MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>"); diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c index 4bf04a9778407a..3090479a297988 100644 --- a/drivers/hwtracing/ptt/hisi_ptt.c +++ b/drivers/hwtracing/ptt/hisi_ptt.c @@ -1221,6 +1221,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt) hisi_ptt->hisi_ptt_pmu = (struct pmu) { .module = THIS_MODULE, + .parent = &hisi_ptt->pdev->dev, .capabilities = PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_NO_EXCLUDE, .task_ctx_nr = perf_sw_context, .attr_groups = hisi_ptt_pmu_groups, diff --git a/drivers/iio/accel/adxl367_i2c.c b/drivers/iio/accel/adxl367_i2c.c index 62c74bdc0d77bf..deb82a43ec36fb 100644 --- a/drivers/iio/accel/adxl367_i2c.c +++ b/drivers/iio/accel/adxl367_i2c.c @@ -61,8 +61,8 @@ static int adxl367_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id adxl367_i2c_id[] = { - { "adxl367", 0 }, - { }, + { "adxl367" }, + { } }; MODULE_DEVICE_TABLE(i2c, adxl367_i2c_id); diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c index d0690417fd36f2..3571cfde1c0e7c 100644 --- a/drivers/iio/accel/adxl372_i2c.c +++ b/drivers/iio/accel/adxl372_i2c.c @@ -42,7 +42,7 @@ static int adxl372_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id adxl372_i2c_id[] = { - { "adxl372", 0 }, + { "adxl372" }, {} }; MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id); diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index adf4e3fd2e1dff..c1c72f577295a8 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -28,7 +28,7 @@ static int bma400_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id bma400_i2c_ids[] = { - { "bma400", 0 }, + { "bma400" }, { } }; MODULE_DEVICE_TABLE(i2c, bma400_i2c_ids); diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c index 8f919920ced5d8..94f827acdd1c9f 100644 --- a/drivers/iio/accel/da311.c +++ b/drivers/iio/accel/da311.c @@ -268,7 +268,7 @@ static int da311_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume); static const struct i2c_device_id da311_i2c_id[] = { - {"da311", 0}, + { "da311" }, {} }; MODULE_DEVICE_TABLE(i2c, da311_i2c_id); diff --git a/drivers/iio/accel/dmard06.c b/drivers/iio/accel/dmard06.c index 2e719d60fff8a8..fb14894c66f953 100644 --- a/drivers/iio/accel/dmard06.c +++ b/drivers/iio/accel/dmard06.c @@ -201,9 +201,9 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend, dmard06_resume); static const struct i2c_device_id dmard06_id[] = { - { "dmard05", 0 }, - { "dmard06", 0 }, - { "dmard07", 0 }, + { "dmard05" }, + { "dmard06" }, + { "dmard07" }, { } }; MODULE_DEVICE_TABLE(i2c, dmard06_id); diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c index fa98623de579b9..6644c1fec3e691 100644 --- a/drivers/iio/accel/dmard09.c +++ b/drivers/iio/accel/dmard09.c @@ -125,8 +125,8 @@ static int dmard09_probe(struct i2c_client *client) } static const struct i2c_device_id dmard09_id[] = { - { "dmard09", 0 }, - { }, + { "dmard09" }, + { } }; MODULE_DEVICE_TABLE(i2c, dmard09_id); diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c index 7745b6ffd1ad56..35c0eefb741e99 100644 --- a/drivers/iio/accel/dmard10.c +++ b/drivers/iio/accel/dmard10.c @@ -231,7 +231,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend, dmard10_resume); static const struct i2c_device_id dmard10_i2c_id[] = { - {"dmard10", 0}, + { "dmard10" }, {} }; MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id); diff --git a/drivers/iio/accel/kxsd9-i2c.c b/drivers/iio/accel/kxsd9-i2c.c index 3bc9ee1f9db3a9..c4c7e2d4e98ad9 100644 --- a/drivers/iio/accel/kxsd9-i2c.c +++ b/drivers/iio/accel/kxsd9-i2c.c @@ -43,8 +43,8 @@ static const struct of_device_id kxsd9_of_match[] = { MODULE_DEVICE_TABLE(of, kxsd9_of_match); static const struct i2c_device_id kxsd9_i2c_id[] = { - {"kxsd9", 0}, - { }, + { "kxsd9" }, + { } }; MODULE_DEVICE_TABLE(i2c, kxsd9_i2c_id); diff --git a/drivers/iio/accel/mc3230.c b/drivers/iio/accel/mc3230.c index 6b87c2c9945ca9..caa40a14a6316a 100644 --- a/drivers/iio/accel/mc3230.c +++ b/drivers/iio/accel/mc3230.c @@ -180,7 +180,7 @@ static int mc3230_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(mc3230_pm_ops, mc3230_suspend, mc3230_resume); static const struct i2c_device_id mc3230_i2c_id[] = { - {"mc3230", 0}, + { "mc3230" }, {} }; MODULE_DEVICE_TABLE(i2c, mc3230_i2c_id); diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c index 14f7850a22f043..36a357c8e9ed59 100644 --- a/drivers/iio/accel/mma7455_i2c.c +++ b/drivers/iio/accel/mma7455_i2c.c @@ -32,8 +32,8 @@ static void mma7455_i2c_remove(struct i2c_client *i2c) } static const struct i2c_device_id mma7455_i2c_ids[] = { - { "mma7455", 0 }, - { "mma7456", 0 }, + { "mma7455" }, + { "mma7456" }, { } }; MODULE_DEVICE_TABLE(i2c, mma7455_i2c_ids); diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c index 260cbceaa15189..d3febc760c4c09 100644 --- a/drivers/iio/accel/mma7660.c +++ b/drivers/iio/accel/mma7660.c @@ -241,7 +241,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend, mma7660_resume); static const struct i2c_device_id mma7660_i2c_id[] = { - {"mma7660", 0}, + { "mma7660" }, {} }; MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id); diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c index 083c08f65bafe5..fa1799b0b0dff3 100644 --- a/drivers/iio/accel/mma9551.c +++ b/drivers/iio/accel/mma9551.c @@ -595,7 +595,7 @@ static const struct acpi_device_id mma9551_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match); static const struct i2c_device_id mma9551_id[] = { - {"mma9551", 0}, + { "mma9551" }, {} }; diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c index 3cbd0fd4e6240d..86543f34ef17cf 100644 --- a/drivers/iio/accel/mma9553.c +++ b/drivers/iio/accel/mma9553.c @@ -1234,8 +1234,8 @@ static const struct acpi_device_id mma9553_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, mma9553_acpi_match); static const struct i2c_device_id mma9553_id[] = { - {"mma9553", 0}, - {}, + { "mma9553" }, + {} }; MODULE_DEVICE_TABLE(i2c, mma9553_id); diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index 34d0f7f3f664a3..cae3985fe790b8 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -507,9 +507,9 @@ static const struct of_device_id mxc4005_of_match[] = { MODULE_DEVICE_TABLE(of, mxc4005_of_match); static const struct i2c_device_id mxc4005_id[] = { - {"mxc4005", 0}, - {"mxc6655", 0}, - { }, + { "mxc4005" }, + { "mxc6655" }, + { } }; MODULE_DEVICE_TABLE(i2c, mxc4005_id); diff --git a/drivers/iio/accel/mxc6255.c b/drivers/iio/accel/mxc6255.c index ac228128c4f9e4..a8abda7b2a6398 100644 --- a/drivers/iio/accel/mxc6255.c +++ b/drivers/iio/accel/mxc6255.c @@ -172,8 +172,8 @@ static const struct acpi_device_id mxc6255_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, mxc6255_acpi_match); static const struct i2c_device_id mxc6255_id[] = { - {"mxc6225", 0}, - {"mxc6255", 0}, + { "mxc6225" }, + { "mxc6255" }, { } }; MODULE_DEVICE_TABLE(i2c, mxc6255_id); diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index ef0ae76722538a..b3534d5751b951 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -633,8 +633,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend, static const struct i2c_device_id stk8312_i2c_id[] = { /* Deprecated in favour of lowercase form */ - { "STK8312", 0 }, - { "stk8312", 0 }, + { "STK8312" }, + { "stk8312" }, {} }; MODULE_DEVICE_TABLE(i2c, stk8312_i2c_id); diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 668edc88c89dc8..6d3c7f444d21d3 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -525,7 +525,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend, stk8ba50_resume); static const struct i2c_device_id stk8ba50_i2c_id[] = { - {"stk8ba50", 0}, + { "stk8ba50" }, {} }; MODULE_DEVICE_TABLE(i2c, stk8ba50_i2c_id); diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index 14d02b085d3bc8..b59b2a51623c39 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -536,7 +536,7 @@ static int ad7291_probe(struct i2c_client *client) } static const struct i2c_device_id ad7291_id[] = { - { "ad7291", 0 }, + { "ad7291" }, {} }; diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 1928d9ae5bcffd..3a417595294f78 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -174,17 +174,14 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_RAW: - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; - - ret = ad7606_scan_direct(indio_dev, chan->address); - iio_device_release_direct_mode(indio_dev); - - if (ret < 0) - return ret; - *val = (short)ret; - return IIO_VAL_INT; + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret = ad7606_scan_direct(indio_dev, chan->address); + if (ret < 0) + return ret; + *val = (short) ret; + return IIO_VAL_INT; + } + unreachable(); case IIO_CHAN_INFO_SCALE: if (st->sw_mode_en) ch = chan->address; diff --git a/drivers/iio/adc/ltc2485.c b/drivers/iio/adc/ltc2485.c index 859e4314cfa2d4..060651dd413061 100644 --- a/drivers/iio/adc/ltc2485.c +++ b/drivers/iio/adc/ltc2485.c @@ -124,7 +124,7 @@ static int ltc2485_probe(struct i2c_client *client) } static const struct i2c_device_id ltc2485_id[] = { - { "ltc2485", 0 }, + { "ltc2485" }, { } }; MODULE_DEVICE_TABLE(i2c, ltc2485_id); diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c index d9e1696df7ae45..600151a62f1fe3 100644 --- a/drivers/iio/adc/nau7802.c +++ b/drivers/iio/adc/nau7802.c @@ -532,7 +532,7 @@ static int nau7802_probe(struct i2c_client *client) } static const struct i2c_device_id nau7802_i2c_id[] = { - { "nau7802", 0 }, + { "nau7802" }, { } }; MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id); diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c index f751260605e4e1..456f12faa34807 100644 --- a/drivers/iio/adc/pac1934.c +++ b/drivers/iio/adc/pac1934.c @@ -787,6 +787,15 @@ static int pac1934_read_raw(struct iio_dev *indio_dev, s64 curr_energy; int ret, channel = chan->channel - 1; + /* + * For AVG the index should be between 5 to 8. + * To calculate PAC1934_CH_VOLTAGE_AVERAGE, + * respectively PAC1934_CH_CURRENT real index, we need + * to remove the added offset (PAC1934_MAX_NUM_CHANNELS). + */ + if (channel >= PAC1934_MAX_NUM_CHANNELS) + channel = channel - PAC1934_MAX_NUM_CHANNELS; + ret = pac1934_retrieve_data(info, PAC1934_MIN_UPDATE_WAIT_TIME_US); if (ret < 0) return ret; diff --git a/drivers/iio/adc/ti-ads7924.c b/drivers/iio/adc/ti-ads7924.c index afdbd04778a87e..4da78302359b45 100644 --- a/drivers/iio/adc/ti-ads7924.c +++ b/drivers/iio/adc/ti-ads7924.c @@ -447,7 +447,7 @@ static int ads7924_probe(struct i2c_client *client) } static const struct i2c_device_id ads7924_id[] = { - { "ads7924", 0 }, + { "ads7924" }, {} }; MODULE_DEVICE_TABLE(i2c, ads7924_id); diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index 164facac5db615..4d605c2b9750e6 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -163,7 +163,7 @@ static int ams_iaqcore_probe(struct i2c_client *client) } static const struct i2c_device_id ams_iaqcore_id[] = { - { "ams-iaq-core", 0 }, + { "ams-iaq-core" }, { } }; MODULE_DEVICE_TABLE(i2c, ams_iaqcore_id); diff --git a/drivers/iio/chemical/bme680_i2c.c b/drivers/iio/chemical/bme680_i2c.c index 1c7076cf91cafa..7c4224d75955f7 100644 --- a/drivers/iio/chemical/bme680_i2c.c +++ b/drivers/iio/chemical/bme680_i2c.c @@ -36,8 +36,8 @@ static int bme680_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id bme680_i2c_id[] = { - {"bme680", 0}, - {}, + { "bme680" }, + {} }; MODULE_DEVICE_TABLE(i2c, bme680_i2c_id); diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index 87741f155c32b6..17d1bc518bf208 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -551,7 +551,7 @@ static void ccs811_remove(struct i2c_client *client) } static const struct i2c_device_id ccs811_id[] = { - {"ccs811", 0}, + { "ccs811" }, { } }; MODULE_DEVICE_TABLE(i2c, ccs811_id); diff --git a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c index 3b0f9598a7c773..fa205f17bd905f 100644 --- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c +++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c @@ -70,13 +70,13 @@ int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts, } EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP); -static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period, uint32_t mult) +static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t period) { uint32_t period_min, period_max; /* check that period is acceptable */ - period_min = ts->min_period * mult; - period_max = ts->max_period * mult; + period_min = ts->min_period * ts->mult; + period_max = ts->max_period * ts->mult; if (period > period_min && period < period_max) return true; else @@ -84,15 +84,15 @@ static bool inv_validate_period(struct inv_sensors_timestamp *ts, uint32_t perio } static bool inv_update_chip_period(struct inv_sensors_timestamp *ts, - uint32_t mult, uint32_t period) + uint32_t period) { uint32_t new_chip_period; - if (!inv_validate_period(ts, period, mult)) + if (!inv_validate_period(ts, period)) return false; /* update chip internal period estimation */ - new_chip_period = period / mult; + new_chip_period = period / ts->mult; inv_update_acc(&ts->chip_period, new_chip_period); ts->period = ts->mult * ts->chip_period.val; @@ -101,6 +101,9 @@ static bool inv_update_chip_period(struct inv_sensors_timestamp *ts, static void inv_align_timestamp_it(struct inv_sensors_timestamp *ts) { + const int64_t period_min = ts->min_period * ts->mult; + const int64_t period_max = ts->max_period * ts->mult; + int64_t add_max, sub_max; int64_t delta, jitter; int64_t adjust; @@ -108,11 +111,13 @@ static void inv_align_timestamp_it(struct inv_sensors_timestamp *ts) delta = ts->it.lo - ts->timestamp; /* adjust timestamp while respecting jitter */ + add_max = period_max - (int64_t)ts->period; + sub_max = period_min - (int64_t)ts->period; jitter = INV_SENSORS_TIMESTAMP_JITTER((int64_t)ts->period, ts->chip.jitter); if (delta > jitter) - adjust = jitter; + adjust = add_max; else if (delta < -jitter) - adjust = -jitter; + adjust = sub_max; else adjust = 0; @@ -120,16 +125,14 @@ static void inv_align_timestamp_it(struct inv_sensors_timestamp *ts) } void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, - size_t sensor_nb, int64_t timestamp) + size_t sample_nb, int64_t timestamp) { struct inv_sensors_timestamp_interval *it; int64_t delta, interval; - const uint32_t fifo_mult = fifo_period / ts->chip.clock_period; uint32_t period; bool valid = false; - if (fifo_nb == 0) + if (sample_nb == 0) return; /* update interrupt timestamp and compute chip and sensor periods */ @@ -139,14 +142,14 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts, delta = it->up - it->lo; if (it->lo != 0) { /* compute period: delta time divided by number of samples */ - period = div_s64(delta, fifo_nb); - valid = inv_update_chip_period(ts, fifo_mult, period); + period = div_s64(delta, sample_nb); + valid = inv_update_chip_period(ts, period); } /* no previous data, compute theoritical value from interrupt */ if (ts->timestamp == 0) { /* elapsed time: sensor period * sensor samples number */ - interval = (int64_t)ts->period * (int64_t)sensor_nb; + interval = (int64_t)ts->period * (int64_t)sample_nb; ts->timestamp = it->up - interval; return; } diff --git a/drivers/iio/dac/ad9739a.c b/drivers/iio/dac/ad9739a.c index ff33120075bf60..f56eabe5372356 100644 --- a/drivers/iio/dac/ad9739a.c +++ b/drivers/iio/dac/ad9739a.c @@ -45,6 +45,7 @@ #define AD9739A_REG_MU_DUTY 0x25 #define AD9739A_REG_MU_CNT1 0x26 #define AD9739A_MU_EN_MASK BIT(0) +#define AD9739A_MU_GAIN_MASK BIT(1) #define AD9739A_REG_MU_CNT2 0x27 #define AD9739A_REG_MU_CNT3 0x28 #define AD9739A_REG_MU_CNT4 0x29 @@ -220,8 +221,8 @@ static int ad9739a_init(struct device *dev, const struct ad9739a_state *st) return ret; /* Enable the Mu controller search and track mode. */ - ret = regmap_set_bits(st->regmap, AD9739A_REG_MU_CNT1, - AD9739A_MU_EN_MASK); + ret = regmap_write(st->regmap, AD9739A_REG_MU_CNT1, + AD9739A_MU_EN_MASK | AD9739A_MU_GAIN_MASK); if (ret) return ret; diff --git a/drivers/iio/dac/mcp4728.c b/drivers/iio/dac/mcp4728.c index 5113f67ddc31ec..c449ca949465d3 100644 --- a/drivers/iio/dac/mcp4728.c +++ b/drivers/iio/dac/mcp4728.c @@ -591,7 +591,7 @@ static int mcp4728_probe(struct i2c_client *client) } static const struct i2c_device_id mcp4728_id[] = { - { "mcp4728", 0 }, + { "mcp4728" }, {} }; MODULE_DEVICE_TABLE(i2c, mcp4728_id); diff --git a/drivers/iio/gyro/bmg160_i2c.c b/drivers/iio/gyro/bmg160_i2c.c index 9c8e20c25e96bd..672d0b720f610a 100644 --- a/drivers/iio/gyro/bmg160_i2c.c +++ b/drivers/iio/gyro/bmg160_i2c.c @@ -47,9 +47,9 @@ static const struct acpi_device_id bmg160_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, bmg160_acpi_match); static const struct i2c_device_id bmg160_i2c_id[] = { - {"bmg160", 0}, - {"bmi055_gyro", 0}, - {"bmi088_gyro", 0}, + { "bmg160" }, + { "bmi055_gyro" }, + { "bmi088_gyro" }, {} }; diff --git a/drivers/iio/gyro/fxas21002c_i2c.c b/drivers/iio/gyro/fxas21002c_i2c.c index ee7f21b718e2db..b1318a1ea41bfc 100644 --- a/drivers/iio/gyro/fxas21002c_i2c.c +++ b/drivers/iio/gyro/fxas21002c_i2c.c @@ -39,7 +39,7 @@ static void fxas21002c_i2c_remove(struct i2c_client *i2c) } static const struct i2c_device_id fxas21002c_i2c_id[] = { - { "fxas21002c", 0 }, + { "fxas21002c" }, { } }; MODULE_DEVICE_TABLE(i2c, fxas21002c_i2c_id); diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 53fb92f0ac7ef9..cd8a2dae56cd90 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -387,7 +387,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(itg3200_pm_ops, itg3200_suspend, itg3200_resume); static const struct i2c_device_id itg3200_id[] = { - { "itg3200", 0 }, + { "itg3200" }, { } }; MODULE_DEVICE_TABLE(i2c, itg3200_id); diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 7768b07ef7a6f8..390fbb6effaf75 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -582,7 +582,7 @@ static int afe4404_probe(struct i2c_client *client) } static const struct i2c_device_id afe4404_ids[] = { - { "afe4404", 0 }, + { "afe4404" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, afe4404_ids); diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 6236b4d9613786..1dc0df21450d3b 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -483,7 +483,7 @@ static void max30100_remove(struct i2c_client *client) } static const struct i2c_device_id max30100_id[] = { - { "max30100", 0 }, + { "max30100" }, {} }; MODULE_DEVICE_TABLE(i2c, max30100_id); diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index 37a35d1153d502..a56474be5dd233 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c @@ -253,7 +253,7 @@ static int am2315_probe(struct i2c_client *client) } static const struct i2c_device_id am2315_i2c_id[] = { - {"am2315", 0}, + { "am2315" }, {} }; MODULE_DEVICE_TABLE(i2c, am2315_i2c_id); diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 202014da2785c7..9b355380c9bfb4 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -396,12 +396,12 @@ static int hdc100x_probe(struct i2c_client *client) } static const struct i2c_device_id hdc100x_id[] = { - { "hdc100x", 0 }, - { "hdc1000", 0 }, - { "hdc1008", 0 }, - { "hdc1010", 0 }, - { "hdc1050", 0 }, - { "hdc1080", 0 }, + { "hdc100x" }, + { "hdc1000" }, + { "hdc1008" }, + { "hdc1010" }, + { "hdc1050" }, + { "hdc1080" }, { } }; MODULE_DEVICE_TABLE(i2c, hdc100x_id); diff --git a/drivers/iio/humidity/si7005.c b/drivers/iio/humidity/si7005.c index 9465908cc65ed0..0797ece1fcba6d 100644 --- a/drivers/iio/humidity/si7005.c +++ b/drivers/iio/humidity/si7005.c @@ -163,8 +163,8 @@ static int si7005_probe(struct i2c_client *client) } static const struct i2c_device_id si7005_id[] = { - { "si7005", 0 }, - { "th02", 0 }, + { "si7005" }, + { "th02" }, { } }; MODULE_DEVICE_TABLE(i2c, si7005_id); diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index fb100664932888..d34a915e3d4a1d 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -138,8 +138,8 @@ static int si7020_probe(struct i2c_client *client) } static const struct i2c_device_id si7020_id[] = { - { "si7020", 0 }, - { "th06", 0 }, + { "si7020" }, + { "th06" }, { } }; MODULE_DEVICE_TABLE(i2c, si7020_id); diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index a77f1a8348ffcb..90aa04d94da542 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -26,6 +26,7 @@ #include "bmi160.h" #define BMI160_REG_CHIP_ID 0x00 +#define BMI120_CHIP_ID_VAL 0xD3 #define BMI160_CHIP_ID_VAL 0xD1 #define BMI160_REG_PMU_STATUS 0x03 @@ -112,6 +113,11 @@ .ext_info = bmi160_ext_info, \ } +static const u8 bmi_chip_ids[] = { + BMI120_CHIP_ID_VAL, + BMI160_CHIP_ID_VAL, +}; + /* scan indexes follow DATA register order */ enum bmi160_scan_axis { BMI160_SCAN_EXT_MAGN_X = 0, @@ -704,6 +710,16 @@ static int bmi160_setup_irq(struct iio_dev *indio_dev, int irq, return bmi160_probe_trigger(indio_dev, irq, irq_type); } +static int bmi160_check_chip_id(const u8 chip_id) +{ + for (int i = 0; i < ARRAY_SIZE(bmi_chip_ids); i++) { + if (chip_id == bmi_chip_ids[i]) + return 0; + } + + return -ENODEV; +} + static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) { int ret; @@ -737,12 +753,10 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) dev_err(dev, "Error reading chip id\n"); goto disable_regulator; } - if (val != BMI160_CHIP_ID_VAL) { - dev_err(dev, "Wrong chip id, got %x expected %x\n", - val, BMI160_CHIP_ID_VAL); - ret = -ENODEV; - goto disable_regulator; - } + + ret = bmi160_check_chip_id(val); + if (ret) + dev_warn(dev, "Chip id not found: %x\n", val); ret = bmi160_set_mode(data, BMI160_ACCEL, true); if (ret) diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index a081305254dbb5..3aa5d748f9b682 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -37,7 +37,8 @@ static int bmi160_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id bmi160_i2c_id[] = { - {"bmi160", 0}, + { "bmi120" }, + { "bmi160" }, {} }; MODULE_DEVICE_TABLE(i2c, bmi160_i2c_id); @@ -52,12 +53,14 @@ static const struct acpi_device_id bmi160_acpi_match[] = { * the affected devices are from 2021/2022. */ {"10EC5280", 0}, + {"BMI0120", 0}, {"BMI0160", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match); static const struct of_device_id bmi160_of_match[] = { + { .compatible = "bosch,bmi120" }, { .compatible = "bosch,bmi160" }, { }, }; diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c b/drivers/iio/imu/bmi160/bmi160_spi.c index 8b573ea99af235..9f40500132f7be 100644 --- a/drivers/iio/imu/bmi160/bmi160_spi.c +++ b/drivers/iio/imu/bmi160/bmi160_spi.c @@ -34,18 +34,21 @@ static int bmi160_spi_probe(struct spi_device *spi) } static const struct spi_device_id bmi160_spi_id[] = { + {"bmi120", 0}, {"bmi160", 0}, {} }; MODULE_DEVICE_TABLE(spi, bmi160_spi_id); static const struct acpi_device_id bmi160_acpi_match[] = { + {"BMI0120", 0}, {"BMI0160", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match); static const struct of_device_id bmi160_of_match[] = { + { .compatible = "bosch,bmi120" }, { .compatible = "bosch,bmi160" }, { }, }; diff --git a/drivers/iio/imu/bno055/bno055_i2c.c b/drivers/iio/imu/bno055/bno055_i2c.c index 6ecd750c6b7640..cf3dd62a83ba8a 100644 --- a/drivers/iio/imu/bno055/bno055_i2c.c +++ b/drivers/iio/imu/bno055/bno055_i2c.c @@ -30,7 +30,7 @@ static int bno055_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id bno055_i2c_id[] = { - {"bno055", 0}, + { "bno055" }, { } }; MODULE_DEVICE_TABLE(i2c, bno055_i2c_id); diff --git a/drivers/iio/imu/fxos8700_i2c.c b/drivers/iio/imu/fxos8700_i2c.c index e99677ad96a2f9..2cc4a27a4527d1 100644 --- a/drivers/iio/imu/fxos8700_i2c.c +++ b/drivers/iio/imu/fxos8700_i2c.c @@ -36,7 +36,7 @@ static int fxos8700_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id fxos8700_i2c_id[] = { - {"fxos8700", 0}, + { "fxos8700" }, { } }; MODULE_DEVICE_TABLE(i2c, fxos8700_i2c_id); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c index cfb4a41ab7c11e..63b85ec88c131f 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c @@ -512,20 +512,20 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st) return 0; /* handle gyroscope timestamp and FIFO data parsing */ - ts = &gyro_st->ts; - inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total, - st->fifo.nb.gyro, st->timestamp.gyro); if (st->fifo.nb.gyro > 0) { + ts = &gyro_st->ts; + inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro, + st->timestamp.gyro); ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); if (ret) return ret; } /* handle accelerometer timestamp and FIFO data parsing */ - ts = &accel_st->ts; - inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total, - st->fifo.nb.accel, st->timestamp.accel); if (st->fifo.nb.accel > 0) { + ts = &accel_st->ts; + inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel, + st->timestamp.accel); ret = inv_icm42600_accel_parse_fifo(st->indio_accel); if (ret) return ret; @@ -555,9 +555,7 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, if (st->fifo.nb.gyro > 0) { ts = &gyro_st->ts; - inv_sensors_timestamp_interrupt(ts, st->fifo.period, - st->fifo.nb.total, st->fifo.nb.gyro, - gyro_ts); + inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro, gyro_ts); ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); if (ret) return ret; @@ -565,9 +563,7 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, if (st->fifo.nb.accel > 0) { ts = &accel_st->ts; - inv_sensors_timestamp_interrupt(ts, st->fifo.period, - st->fifo.nb.total, st->fifo.nb.accel, - accel_ts); + inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel, accel_ts); ret = inv_icm42600_accel_parse_fifo(st->indio_accel); if (ret) return ret; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 86465226f7e106..0dc0f22a558279 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -100,7 +100,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) goto end_session; /* Each FIFO data contains all sensors, so same number for FIFO and sensor data */ fifo_period = NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider); - inv_sensors_timestamp_interrupt(&st->timestamp, fifo_period, nb, nb, pf->timestamp); + inv_sensors_timestamp_interrupt(&st->timestamp, nb, pf->timestamp); inv_sensors_timestamp_apply_odr(&st->timestamp, fifo_period, nb, 0); /* clear internal data buffer for avoiding kernel data leak */ diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c index 7d3e061f30463d..d37eca5ef761e3 100644 --- a/drivers/iio/imu/kmx61.c +++ b/drivers/iio/imu/kmx61.c @@ -1505,7 +1505,7 @@ static const struct acpi_device_id kmx61_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, kmx61_acpi_match); static const struct i2c_device_id kmx61_id[] = { - {"kmx611021", 0}, + { "kmx611021" }, {} }; diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c index b51eb6cb766f3f..59d7615c0f565c 100644 --- a/drivers/iio/industrialio-gts-helper.c +++ b/drivers/iio/industrialio-gts-helper.c @@ -362,17 +362,20 @@ static int iio_gts_build_avail_time_table(struct iio_gts *gts) for (i = gts->num_itime - 1; i >= 0; i--) { int new = gts->itime_table[i].time_us; - if (times[idx] < new) { + if (idx == 0 || times[idx - 1] < new) { times[idx++] = new; continue; } - for (j = 0; j <= idx; j++) { + for (j = 0; j < idx; j++) { + if (times[j] == new) + break; if (times[j] > new) { memmove(×[j + 1], ×[j], (idx - j) * sizeof(int)); times[j] = new; idx++; + break; } } } diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 5fd775a20176db..5169f12c3ebafd 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -261,7 +261,7 @@ static int adjd_s311_probe(struct i2c_client *client) } static const struct i2c_device_id adjd_s311_id[] = { - { "adjd_s311", 0 }, + { "adjd_s311" }, { } }; MODULE_DEVICE_TABLE(i2c, adjd_s311_id); diff --git a/drivers/iio/light/adux1020.c b/drivers/iio/light/adux1020.c index aa4a6c78f0aa86..d4eb938c3bf59d 100644 --- a/drivers/iio/light/adux1020.c +++ b/drivers/iio/light/adux1020.c @@ -821,7 +821,7 @@ static int adux1020_probe(struct i2c_client *client) } static const struct i2c_device_id adux1020_id[] = { - { "adux1020", 0 }, + { "adux1020" }, {} }; MODULE_DEVICE_TABLE(i2c, adux1020_id); diff --git a/drivers/iio/light/al3320a.c b/drivers/iio/light/al3320a.c index 105f379b9b414f..497ea3fe337775 100644 --- a/drivers/iio/light/al3320a.c +++ b/drivers/iio/light/al3320a.c @@ -236,7 +236,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(al3320a_pm_ops, al3320a_suspend, al3320a_resume); static const struct i2c_device_id al3320a_id[] = { - {"al3320a", 0}, + { "al3320a" }, {} }; MODULE_DEVICE_TABLE(i2c, al3320a_id); diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index 0f978b30a232ca..11f2ab4ca26181 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -493,7 +493,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume); static const struct i2c_device_id apds9300_id[] = { - { APDS9300_DRV_NAME, 0 }, + { APDS9300_DRV_NAME }, { } }; diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 1065a340b12bf9..e9e65130b6f911 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -1107,7 +1107,7 @@ static const struct dev_pm_ops apds9960_pm_ops = { }; static const struct i2c_device_id apds9960_id[] = { - { "apds9960", 0 }, + { "apds9960" }, {} }; MODULE_DEVICE_TABLE(i2c, apds9960_id); diff --git a/drivers/iio/light/bh1780.c b/drivers/iio/light/bh1780.c index b84166c5fa06ee..475f44954f6110 100644 --- a/drivers/iio/light/bh1780.c +++ b/drivers/iio/light/bh1780.c @@ -256,8 +256,8 @@ static DEFINE_RUNTIME_DEV_PM_OPS(bh1780_dev_pm_ops, bh1780_runtime_suspend, bh1780_runtime_resume, NULL); static const struct i2c_device_id bh1780_id[] = { - { "bh1780", 0 }, - { }, + { "bh1780" }, + { } }; MODULE_DEVICE_TABLE(i2c, bh1780_id); diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c index d48a70efca69ff..b6288dd25bbff3 100644 --- a/drivers/iio/light/cm3232.c +++ b/drivers/iio/light/cm3232.c @@ -368,7 +368,7 @@ static void cm3232_remove(struct i2c_client *client) } static const struct i2c_device_id cm3232_id[] = { - {"cm3232", 0}, + { "cm3232" }, {} }; diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c index 35d20207a6481a..79a64e2ff81246 100644 --- a/drivers/iio/light/cm3323.c +++ b/drivers/iio/light/cm3323.c @@ -250,7 +250,7 @@ static int cm3323_probe(struct i2c_client *client) } static const struct i2c_device_id cm3323_id[] = { - {"cm3323", 0}, + { "cm3323" }, {} }; MODULE_DEVICE_TABLE(i2c, cm3323_id); diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 97e559acba2b25..a4a1505534c015 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -713,7 +713,7 @@ static void cm36651_remove(struct i2c_client *client) } static const struct i2c_device_id cm36651_id[] = { - { "cm36651", 0 }, + { "cm36651" }, { } }; diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index fec10d5e037ec1..7125e011a38ae8 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -692,8 +692,8 @@ static DEFINE_RUNTIME_DEV_PM_OPS(gp2ap002_dev_pm_ops, gp2ap002_runtime_suspend, gp2ap002_runtime_resume, NULL); static const struct i2c_device_id gp2ap002_id_table[] = { - { "gp2ap002", 0 }, - { }, + { "gp2ap002" }, + { } }; MODULE_DEVICE_TABLE(i2c, gp2ap002_id_table); diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 9f41724819b612..757383456da699 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -237,7 +237,6 @@ enum gp2ap020a00f_thresh_val_id { }; struct gp2ap020a00f_data { - const struct gp2ap020a00f_platform_data *pdata; struct i2c_client *client; struct mutex lock; char *buffer; @@ -1592,7 +1591,7 @@ static void gp2ap020a00f_remove(struct i2c_client *client) } static const struct i2c_device_id gp2ap020a00f_id[] = { - { GP2A_I2C_NAME, 0 }, + { GP2A_I2C_NAME }, { } }; diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c index 5694683389bec1..95bfb3ffa519a1 100644 --- a/drivers/iio/light/isl29028.c +++ b/drivers/iio/light/isl29028.c @@ -678,8 +678,8 @@ static DEFINE_RUNTIME_DEV_PM_OPS(isl29028_pm_ops, isl29028_suspend, isl29028_resume, NULL); static const struct i2c_device_id isl29028_id[] = { - {"isl29028", 0}, - {"isl29030", 0}, + { "isl29028" }, + { "isl29030" }, {} }; MODULE_DEVICE_TABLE(i2c, isl29028_id); diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index f1d3356d33697a..59329546df58de 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -327,7 +327,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(isl29125_pm_ops, isl29125_suspend, isl29125_resume); static const struct i2c_device_id isl29125_id[] = { - { "isl29125", 0 }, + { "isl29125" }, { } }; MODULE_DEVICE_TABLE(i2c, isl29125_id); diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c index 869196746045e3..e7ba934c8e693d 100644 --- a/drivers/iio/light/jsa1212.c +++ b/drivers/iio/light/jsa1212.c @@ -429,7 +429,7 @@ static const struct acpi_device_id jsa1212_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, jsa1212_acpi_match); static const struct i2c_device_id jsa1212_id[] = { - { JSA1212_DRIVER_NAME, 0 }, + { JSA1212_DRIVER_NAME }, { } }; MODULE_DEVICE_TABLE(i2c, jsa1212_id); diff --git a/drivers/iio/light/lv0104cs.c b/drivers/iio/light/lv0104cs.c index a5445d58fddfc3..916109ec32177d 100644 --- a/drivers/iio/light/lv0104cs.c +++ b/drivers/iio/light/lv0104cs.c @@ -510,7 +510,7 @@ static int lv0104cs_probe(struct i2c_client *client) } static const struct i2c_device_id lv0104cs_id[] = { - { "lv0104cs", 0 }, + { "lv0104cs" }, { } }; MODULE_DEVICE_TABLE(i2c, lv0104cs_id); diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index 26b464b1b650ec..b935976871a6f0 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -598,7 +598,7 @@ static int max44000_probe(struct i2c_client *client) } static const struct i2c_device_id max44000_id[] = { - {"max44000", 0}, + { "max44000" }, { } }; MODULE_DEVICE_TABLE(i2c, max44000_id); diff --git a/drivers/iio/light/max44009.c b/drivers/iio/light/max44009.c index 61ce276e86f7c2..3b92362675dc96 100644 --- a/drivers/iio/light/max44009.c +++ b/drivers/iio/light/max44009.c @@ -534,7 +534,7 @@ static const struct of_device_id max44009_of_match[] = { MODULE_DEVICE_TABLE(of, max44009_of_match); static const struct i2c_device_id max44009_id[] = { - { "max44009", 0 }, + { "max44009" }, { } }; MODULE_DEVICE_TABLE(i2c, max44009_id); diff --git a/drivers/iio/light/noa1305.c b/drivers/iio/light/noa1305.c index 1574310020e3d5..596cc48c4c3415 100644 --- a/drivers/iio/light/noa1305.c +++ b/drivers/iio/light/noa1305.c @@ -268,7 +268,7 @@ static const struct of_device_id noa1305_of_match[] = { MODULE_DEVICE_TABLE(of, noa1305_of_match); static const struct i2c_device_id noa1305_ids[] = { - { "noa1305", 0 }, + { "noa1305" }, { } }; MODULE_DEVICE_TABLE(i2c, noa1305_ids); diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c index cb41e5ee8ec10b..887c4b776a8696 100644 --- a/drivers/iio/light/opt3001.c +++ b/drivers/iio/light/opt3001.c @@ -822,7 +822,7 @@ static void opt3001_remove(struct i2c_client *client) } static const struct i2c_device_id opt3001_id[] = { - { "opt3001", 0 }, + { "opt3001" }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(i2c, opt3001_id); diff --git a/drivers/iio/light/pa12203001.c b/drivers/iio/light/pa12203001.c index 636432c45651d2..b920bf82c10218 100644 --- a/drivers/iio/light/pa12203001.c +++ b/drivers/iio/light/pa12203001.c @@ -462,7 +462,7 @@ static const struct acpi_device_id pa12203001_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, pa12203001_acpi_match); static const struct i2c_device_id pa12203001_id[] = { - { "txcpa122", 0 }, + { "txcpa122" }, {} }; diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c index 40d5732b5e320e..78c08e0bd0776a 100644 --- a/drivers/iio/light/rpr0521.c +++ b/drivers/iio/light/rpr0521.c @@ -1109,7 +1109,7 @@ static const struct acpi_device_id rpr0521_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rpr0521_acpi_match); static const struct i2c_device_id rpr0521_id[] = { - {"rpr0521", 0}, + { "rpr0521" }, { } }; diff --git a/drivers/iio/light/si1133.c b/drivers/iio/light/si1133.c index ea2c437199c0fb..eeff6cc792f222 100644 --- a/drivers/iio/light/si1133.c +++ b/drivers/iio/light/si1133.c @@ -1055,7 +1055,7 @@ static int si1133_probe(struct i2c_client *client) } static const struct i2c_device_id si1133_ids[] = { - { "si1133", 0 }, + { "si1133" }, { } }; MODULE_DEVICE_TABLE(i2c, si1133_ids); diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 08d471438175eb..3a03823e488a90 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -683,9 +683,9 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend, stk3310_resume); static const struct i2c_device_id stk3310_i2c_id[] = { - {"STK3310", 0}, - {"STK3311", 0}, - {"STK3335", 0}, + { "STK3310" }, + { "STK3311" }, + { "STK3335" }, {} }; MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id); diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index dcdd85b006be0b..c9566615b96441 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -363,7 +363,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(tcs3414_pm_ops, tcs3414_suspend, tcs3414_resume); static const struct i2c_device_id tcs3414_id[] = { - { "tcs3414", 0 }, + { "tcs3414" }, { } }; MODULE_DEVICE_TABLE(i2c, tcs3414_id); diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index 75fcf2c93717b6..89384dba83dd11 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -599,7 +599,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume); static const struct i2c_device_id tcs3472_id[] = { - { "tcs3472", 0 }, + { "tcs3472" }, { } }; MODULE_DEVICE_TABLE(i2c, tcs3472_id); diff --git a/drivers/iio/light/tsl4531.c b/drivers/iio/light/tsl4531.c index 4da7d78906d4a3..a5788c09ad02fc 100644 --- a/drivers/iio/light/tsl4531.c +++ b/drivers/iio/light/tsl4531.c @@ -227,7 +227,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(tsl4531_pm_ops, tsl4531_suspend, tsl4531_resume); static const struct i2c_device_id tsl4531_id[] = { - { "tsl4531", 0 }, + { "tsl4531" }, { } }; MODULE_DEVICE_TABLE(i2c, tsl4531_id); diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 9189a1d4d7e1ab..de6967ac3b0b3b 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -955,7 +955,7 @@ static const struct acpi_device_id us5182d_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match); static const struct i2c_device_id us5182d_id[] = { - { "usd5182", 0 }, + { "usd5182" }, {} }; diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c index 56bbefbc0ae643..337a1332c2c64a 100644 --- a/drivers/iio/light/vcnl4035.c +++ b/drivers/iio/light/vcnl4035.c @@ -653,7 +653,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(vcnl4035_pm_ops, vcnl4035_runtime_suspend, vcnl4035_runtime_resume, NULL); static const struct i2c_device_id vcnl4035_id[] = { - { "vcnl4035", 0 }, + { "vcnl4035" }, { } }; MODULE_DEVICE_TABLE(i2c, vcnl4035_id); diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 043f233d9bdb06..4be15130857435 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -881,7 +881,7 @@ static const struct of_device_id veml6030_of_match[] = { MODULE_DEVICE_TABLE(of, veml6030_of_match); static const struct i2c_device_id veml6030_id[] = { - { "veml6030", 0 }, + { "veml6030" }, { } }; MODULE_DEVICE_TABLE(i2c, veml6030_id); diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c index d99bf3ae0fe8e9..f8321d346d7757 100644 --- a/drivers/iio/light/veml6070.c +++ b/drivers/iio/light/veml6070.c @@ -189,7 +189,7 @@ static void veml6070_remove(struct i2c_client *client) } static const struct i2c_device_id veml6070_id[] = { - { "veml6070", 0 }, + { "veml6070" }, { } }; MODULE_DEVICE_TABLE(i2c, veml6070_id); diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c index dcadf6428a87d2..a1b2b3c0b4c889 100644 --- a/drivers/iio/light/vl6180.c +++ b/drivers/iio/light/vl6180.c @@ -527,7 +527,7 @@ static const struct of_device_id vl6180_of_match[] = { MODULE_DEVICE_TABLE(of, vl6180_of_match); static const struct i2c_device_id vl6180_id[] = { - { "vl6180", 0 }, + { "vl6180" }, { } }; MODULE_DEVICE_TABLE(i2c, vl6180_id); diff --git a/drivers/iio/light/zopt2201.c b/drivers/iio/light/zopt2201.c index d370193a474234..327f94e447af49 100644 --- a/drivers/iio/light/zopt2201.c +++ b/drivers/iio/light/zopt2201.c @@ -545,7 +545,7 @@ static int zopt2201_probe(struct i2c_client *client) } static const struct i2c_device_id zopt2201_id[] = { - { "zopt2201", 0 }, + { "zopt2201" }, { } }; MODULE_DEVICE_TABLE(i2c, zopt2201_id); diff --git a/drivers/iio/magnetometer/af8133j.c b/drivers/iio/magnetometer/af8133j.c index 742bbdf25f08ca..d81d89af6283b7 100644 --- a/drivers/iio/magnetometer/af8133j.c +++ b/drivers/iio/magnetometer/af8133j.c @@ -505,7 +505,7 @@ static const struct of_device_id af8133j_of_match[] = { MODULE_DEVICE_TABLE(of, af8133j_of_match); static const struct i2c_device_id af8133j_id[] = { - { "af8133j", 0 }, + { "af8133j" }, { } }; MODULE_DEVICE_TABLE(i2c, af8133j_id); diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index c74d11943ec797..d802034c5402cc 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -1025,10 +1025,10 @@ static DEFINE_RUNTIME_DEV_PM_OPS(ak8974_dev_pm_ops, ak8974_runtime_suspend, ak8974_runtime_resume, NULL); static const struct i2c_device_id ak8974_id[] = { - {"ami305", 0 }, - {"ami306", 0 }, - {"ak8974", 0 }, - {"hscdtd008a", 0 }, + { "ami305" }, + { "ami306" }, + { "ak8974" }, + { "hscdtd008a" }, {} }; MODULE_DEVICE_TABLE(i2c, ak8974_id); diff --git a/drivers/iio/magnetometer/bmc150_magn_i2c.c b/drivers/iio/magnetometer/bmc150_magn_i2c.c index 48d9c698f520ea..a28d46d59875fa 100644 --- a/drivers/iio/magnetometer/bmc150_magn_i2c.c +++ b/drivers/iio/magnetometer/bmc150_magn_i2c.c @@ -47,9 +47,9 @@ static const struct acpi_device_id bmc150_magn_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, bmc150_magn_acpi_match); static const struct i2c_device_id bmc150_magn_i2c_id[] = { - {"bmc150_magn", 0}, - {"bmc156_magn", 0}, - {"bmm150_magn", 0}, + { "bmc150_magn" }, + { "bmc156_magn" }, + { "bmm150_magn" }, {} }; MODULE_DEVICE_TABLE(i2c, bmc150_magn_i2c_id); diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index deffe3ca90043b..5295dc0100e4c1 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -624,7 +624,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(mag3110_pm_ops, mag3110_suspend, mag3110_resume); static const struct i2c_device_id mag3110_id[] = { - { "mag3110", 0 }, + { "mag3110" }, { } }; MODULE_DEVICE_TABLE(i2c, mag3110_id); diff --git a/drivers/iio/magnetometer/mmc35240.c b/drivers/iio/magnetometer/mmc35240.c index 6b9f4b05619122..c57932db455fab 100644 --- a/drivers/iio/magnetometer/mmc35240.c +++ b/drivers/iio/magnetometer/mmc35240.c @@ -563,7 +563,7 @@ static const struct acpi_device_id mmc35240_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, mmc35240_acpi_match); static const struct i2c_device_id mmc35240_id[] = { - {"mmc35240", 0}, + { "mmc35240" }, {} }; MODULE_DEVICE_TABLE(i2c, mmc35240_id); diff --git a/drivers/iio/magnetometer/tmag5273.c b/drivers/iio/magnetometer/tmag5273.c index 218b1ce076c19d..4187abe12784d5 100644 --- a/drivers/iio/magnetometer/tmag5273.c +++ b/drivers/iio/magnetometer/tmag5273.c @@ -118,11 +118,9 @@ struct tmag5273_data { unsigned int version; char name[16]; unsigned int conv_avg; - unsigned int scale; enum tmag5273_scale_index scale_index; unsigned int angle_measurement; struct regmap *map; - struct regulator *vcc; /* * Locks the sensor for exclusive use during a measurement (which diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index edd8c69f6d2e1c..2953403bef53bb 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -30,7 +30,6 @@ struct mux { int cached_state; struct mux_control *control; struct iio_channel *parent; - struct iio_dev *indio_dev; struct iio_chan_spec *chan; struct iio_chan_spec_ext_info *ext_info; struct mux_child *child; diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index bd0f2c3bf2f2d0..c2c6b2b298675b 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -405,8 +405,8 @@ static const struct of_device_id lmp91000_of_match[] = { MODULE_DEVICE_TABLE(of, lmp91000_of_match); static const struct i2c_device_id lmp91000_id[] = { - { "lmp91000", 0 }, - { "lmp91002", 0 }, + { "lmp91000" }, + { "lmp91002" }, {} }; MODULE_DEVICE_TABLE(i2c, lmp91000_id); diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index 871b2214121b0f..c99635a442f830 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -52,7 +52,6 @@ */ enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD }; - enum bmp380_odr { BMP380_ODR_200HZ, BMP380_ODR_100HZ, @@ -181,18 +180,19 @@ static int bmp280_read_calib(struct bmp280_data *data) struct bmp280_calib *calib = &data->calib.bmp280; int ret; - /* Read temperature and pressure calibration values. */ ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START, - data->bmp280_cal_buf, sizeof(data->bmp280_cal_buf)); - if (ret < 0) { + data->bmp280_cal_buf, + sizeof(data->bmp280_cal_buf)); + if (ret) { dev_err(data->dev, - "failed to read temperature and pressure calibration parameters\n"); + "failed to read calibration parameters\n"); return ret; } - /* Toss the temperature and pressure calibration data into the entropy pool */ - add_device_randomness(data->bmp280_cal_buf, sizeof(data->bmp280_cal_buf)); + /* Toss calibration data into the entropy pool */ + add_device_randomness(data->bmp280_cal_buf, + sizeof(data->bmp280_cal_buf)); /* Parse temperature calibration values. */ calib->T1 = le16_to_cpu(data->bmp280_cal_buf[T1]); @@ -222,10 +222,8 @@ static int bme280_read_calib(struct bmp280_data *data) /* Load shared calibration params with bmp280 first */ ret = bmp280_read_calib(data); - if (ret < 0) { - dev_err(dev, "failed to read common bmp280 calibration parameters\n"); + if (ret) return ret; - } /* * Read humidity calibration values. @@ -235,47 +233,47 @@ static int bme280_read_calib(struct bmp280_data *data) * Humidity data is only available on BME280. */ - ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &tmp); - if (ret < 0) { + ret = regmap_read(data->regmap, BME280_REG_COMP_H1, &tmp); + if (ret) { dev_err(dev, "failed to read H1 comp value\n"); return ret; } calib->H1 = tmp; - ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, + ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H2, &data->le16, sizeof(data->le16)); - if (ret < 0) { + if (ret) { dev_err(dev, "failed to read H2 comp value\n"); return ret; } calib->H2 = sign_extend32(le16_to_cpu(data->le16), 15); - ret = regmap_read(data->regmap, BMP280_REG_COMP_H3, &tmp); - if (ret < 0) { + ret = regmap_read(data->regmap, BME280_REG_COMP_H3, &tmp); + if (ret) { dev_err(dev, "failed to read H3 comp value\n"); return ret; } calib->H3 = tmp; - ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, + ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H4, &data->be16, sizeof(data->be16)); - if (ret < 0) { + if (ret) { dev_err(dev, "failed to read H4 comp value\n"); return ret; } calib->H4 = sign_extend32(((be16_to_cpu(data->be16) >> 4) & 0xff0) | (be16_to_cpu(data->be16) & 0xf), 11); - ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, + ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H5, &data->le16, sizeof(data->le16)); - if (ret < 0) { + if (ret) { dev_err(dev, "failed to read H5 comp value\n"); return ret; } - calib->H5 = sign_extend32(FIELD_GET(BMP280_COMP_H5_MASK, le16_to_cpu(data->le16)), 11); + calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, le16_to_cpu(data->le16)), 11); - ret = regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp); - if (ret < 0) { + ret = regmap_read(data->regmap, BME280_REG_COMP_H6, &tmp); + if (ret) { dev_err(dev, "failed to read H6 comp value\n"); return ret; } @@ -283,20 +281,21 @@ static int bme280_read_calib(struct bmp280_data *data) return 0; } + /* * Returns humidity in percent, resolution is 0.01 percent. Output value of * "47445" represents 47445/1024 = 46.333 %RH. * * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula". */ -static u32 bmp280_compensate_humidity(struct bmp280_data *data, - s32 adc_humidity) +static u32 bme280_compensate_humidity(struct bmp280_data *data, + u16 adc_humidity) { struct bmp280_calib *calib = &data->calib.bmp280; s32 var; - var = ((s32)data->t_fine) - (s32)76800; - var = ((((adc_humidity << 14) - (calib->H4 << 20) - (calib->H5 * var)) + var = data->t_fine - (s32)76800; + var = (((((s32)adc_humidity << 14) - (calib->H4 << 20) - (calib->H5 * var)) + (s32)16384) >> 15) * (((((((var * calib->H6) >> 10) * (((var * (s32)calib->H3) >> 11) + (s32)32768)) >> 10) + (s32)2097152) * calib->H2 + 8192) >> 14); @@ -305,7 +304,7 @@ static u32 bmp280_compensate_humidity(struct bmp280_data *data, var = clamp_val(var, 0, 419430400); return var >> 12; -}; +} /* * Returns temperature in DegC, resolution is 0.01 DegC. Output value of @@ -315,16 +314,16 @@ static u32 bmp280_compensate_humidity(struct bmp280_data *data, * Taken from datasheet, Section 3.11.3, "Compensation formula". */ static s32 bmp280_compensate_temp(struct bmp280_data *data, - s32 adc_temp) + u32 adc_temp) { struct bmp280_calib *calib = &data->calib.bmp280; s32 var1, var2; - var1 = (((adc_temp >> 3) - ((s32)calib->T1 << 1)) * + var1 = (((((s32)adc_temp) >> 3) - ((s32)calib->T1 << 1)) * ((s32)calib->T2)) >> 11; - var2 = (((((adc_temp >> 4) - ((s32)calib->T1)) * - ((adc_temp >> 4) - ((s32)calib->T1))) >> 12) * - ((s32)calib->T3)) >> 14; + var2 = (((((((s32)adc_temp) >> 4) - ((s32)calib->T1)) * + ((((s32)adc_temp >> 4) - ((s32)calib->T1))) >> 12) * + ((s32)calib->T3))) >> 14; data->t_fine = var1 + var2; return (data->t_fine * 5 + 128) >> 8; @@ -338,7 +337,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data, * Taken from datasheet, Section 3.11.3, "Compensation formula". */ static u32 bmp280_compensate_press(struct bmp280_data *data, - s32 adc_press) + u32 adc_press) { struct bmp280_calib *calib = &data->calib.bmp280; s64 var1, var2, p; @@ -354,7 +353,7 @@ static u32 bmp280_compensate_press(struct bmp280_data *data, if (var1 == 0) return 0; - p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125; + p = ((((s64)1048576 - (s32)adc_press) << 31) - var2) * 3125; p = div64_s64(p, var1); var1 = (((s64)calib->P9) * (p >> 13) * (p >> 13)) >> 25; var2 = ((s64)(calib->P8) * p) >> 19; @@ -366,12 +365,13 @@ static u32 bmp280_compensate_press(struct bmp280_data *data, static int bmp280_read_temp(struct bmp280_data *data, int *val, int *val2) { - s32 adc_temp, comp_temp; + s32 comp_temp; + u32 adc_temp; int ret; ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, data->buf, sizeof(data->buf)); - if (ret < 0) { + if (ret) { dev_err(data->dev, "failed to read temperature\n"); return ret; } @@ -399,18 +399,17 @@ static int bmp280_read_temp(struct bmp280_data *data, static int bmp280_read_press(struct bmp280_data *data, int *val, int *val2) { - u32 comp_press; - s32 adc_press; + u32 comp_press, adc_press; int ret; /* Read and compensate temperature so we get a reading of t_fine. */ ret = bmp280_read_temp(data, NULL, NULL); - if (ret < 0) + if (ret) return ret; ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB, data->buf, sizeof(data->buf)); - if (ret < 0) { + if (ret) { dev_err(data->dev, "failed to read pressure\n"); return ret; } @@ -429,20 +428,20 @@ static int bmp280_read_press(struct bmp280_data *data, return IIO_VAL_FRACTIONAL; } -static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2) +static int bme280_read_humid(struct bmp280_data *data, int *val, int *val2) { u32 comp_humidity; - s32 adc_humidity; + u16 adc_humidity; int ret; /* Read and compensate temperature so we get a reading of t_fine. */ ret = bmp280_read_temp(data, NULL, NULL); - if (ret < 0) + if (ret) return ret; - ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB, + ret = regmap_bulk_read(data->regmap, BME280_REG_HUMIDITY_MSB, &data->be16, sizeof(data->be16)); - if (ret < 0) { + if (ret) { dev_err(data->dev, "failed to read humidity\n"); return ret; } @@ -453,7 +452,7 @@ static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2) dev_err(data->dev, "reading humidity skipped\n"); return -EIO; } - comp_humidity = bmp280_compensate_humidity(data, adc_humidity); + comp_humidity = bme280_compensate_humidity(data, adc_humidity); *val = comp_humidity * 1000 / 1024; @@ -537,8 +536,8 @@ static int bmp280_read_raw(struct iio_dev *indio_dev, return ret; } -static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data, - int val) +static int bme280_write_oversampling_ratio_humid(struct bmp280_data *data, + int val) { const int *avail = data->chip_info->oversampling_humid_avail; const int n = data->chip_info->num_oversampling_humid_avail; @@ -563,7 +562,7 @@ static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data, } static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data, - int val) + int val) { const int *avail = data->chip_info->oversampling_temp_avail; const int n = data->chip_info->num_oversampling_temp_avail; @@ -588,7 +587,7 @@ static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data, } static int bmp280_write_oversampling_ratio_press(struct bmp280_data *data, - int val) + int val) { const int *avail = data->chip_info->oversampling_press_avail; const int n = data->chip_info->num_oversampling_press_avail; @@ -681,7 +680,7 @@ static int bmp280_write_raw(struct iio_dev *indio_dev, mutex_lock(&data->lock); switch (chan->type) { case IIO_HUMIDITYRELATIVE: - ret = bmp280_write_oversampling_ratio_humid(data, val); + ret = bme280_write_oversampling_ratio_humid(data, val); break; case IIO_PRESSURE: ret = bmp280_write_oversampling_ratio_press(data, val); @@ -772,22 +771,20 @@ static int bmp280_chip_config(struct bmp280_data *data) int ret; ret = regmap_write_bits(data->regmap, BMP280_REG_CTRL_MEAS, - BMP280_OSRS_TEMP_MASK | - BMP280_OSRS_PRESS_MASK | - BMP280_MODE_MASK, - osrs | BMP280_MODE_NORMAL); - if (ret < 0) { - dev_err(data->dev, - "failed to write ctrl_meas register\n"); + BMP280_OSRS_TEMP_MASK | + BMP280_OSRS_PRESS_MASK | + BMP280_MODE_MASK, + osrs | BMP280_MODE_NORMAL); + if (ret) { + dev_err(data->dev, "failed to write ctrl_meas register\n"); return ret; } ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG, BMP280_FILTER_MASK, BMP280_FILTER_4X); - if (ret < 0) { - dev_err(data->dev, - "failed to write config register\n"); + if (ret) { + dev_err(data->dev, "failed to write config register\n"); return ret; } @@ -833,18 +830,19 @@ EXPORT_SYMBOL_NS(bmp280_chip_info, IIO_BMP280); static int bme280_chip_config(struct bmp280_data *data) { - u8 osrs = FIELD_PREP(BMP280_OSRS_HUMIDITY_MASK, data->oversampling_humid + 1); + u8 osrs = FIELD_PREP(BME280_OSRS_HUMIDITY_MASK, data->oversampling_humid + 1); int ret; /* * Oversampling of humidity must be set before oversampling of * temperature/pressure is set to become effective. */ - ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_HUMIDITY, - BMP280_OSRS_HUMIDITY_MASK, osrs); - - if (ret < 0) + ret = regmap_update_bits(data->regmap, BME280_REG_CTRL_HUMIDITY, + BME280_OSRS_HUMIDITY_MASK, osrs); + if (ret) { + dev_err(data->dev, "failed to set humidity oversampling"); return ret; + } return bmp280_chip_config(data); } @@ -870,12 +868,12 @@ const struct bmp280_chip_info bme280_chip_info = { .oversampling_humid_avail = bmp280_oversampling_avail, .num_oversampling_humid_avail = ARRAY_SIZE(bmp280_oversampling_avail), - .oversampling_humid_default = BMP280_OSRS_HUMIDITY_16X - 1, + .oversampling_humid_default = BME280_OSRS_HUMIDITY_16X - 1, .chip_config = bme280_chip_config, .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, - .read_humid = bmp280_read_humid, + .read_humid = bme280_read_humid, .read_calib = bme280_read_calib, }; EXPORT_SYMBOL_NS(bme280_chip_info, IIO_BMP280); @@ -926,8 +924,8 @@ static int bmp380_cmd(struct bmp280_data *data, u8 cmd) } /* - * Returns temperature in Celsius degrees, resolution is 0.01º C. Output value of - * "5123" equals 51.2º C. t_fine carries fine temperature as global value. + * Returns temperature in Celsius degrees, resolution is 0.01º C. Output value + * of "5123" equals 51.2º C. t_fine carries fine temperature as global value. * * Taken from datasheet, Section Appendix 9, "Compensation formula" and repo * https://github.com/BoschSensortec/BMP3-Sensor-API. @@ -1032,8 +1030,7 @@ static int bmp380_read_temp(struct bmp280_data *data, int *val, int *val2) static int bmp380_read_press(struct bmp280_data *data, int *val, int *val2) { - s32 comp_press; - u32 adc_press; + u32 adc_press, comp_press; int ret; /* Read and compensate for temperature so we get a reading of t_fine */ @@ -1069,15 +1066,17 @@ static int bmp380_read_calib(struct bmp280_data *data) /* Read temperature and pressure calibration data */ ret = regmap_bulk_read(data->regmap, BMP380_REG_CALIB_TEMP_START, - data->bmp380_cal_buf, sizeof(data->bmp380_cal_buf)); + data->bmp380_cal_buf, + sizeof(data->bmp380_cal_buf)); if (ret) { dev_err(data->dev, - "failed to read temperature calibration parameters\n"); + "failed to read calibration parameters\n"); return ret; } /* Toss the temperature calibration data into the entropy pool */ - add_device_randomness(data->bmp380_cal_buf, sizeof(data->bmp380_cal_buf)); + add_device_randomness(data->bmp380_cal_buf, + sizeof(data->bmp380_cal_buf)); /* Parse calibration values */ calib->T1 = get_unaligned_le16(&data->bmp380_cal_buf[BMP380_T1]); @@ -1159,7 +1158,8 @@ static int bmp380_chip_config(struct bmp280_data *data) /* Configure output data rate */ ret = regmap_update_bits_check(data->regmap, BMP380_REG_ODR, - BMP380_ODRS_MASK, data->sampling_freq, &aux); + BMP380_ODRS_MASK, data->sampling_freq, + &aux); if (ret) { dev_err(data->dev, "failed to write ODR selection register\n"); return ret; @@ -1178,12 +1178,13 @@ static int bmp380_chip_config(struct bmp280_data *data) if (change) { /* - * The configurations errors are detected on the fly during a measurement - * cycle. If the sampling frequency is too low, it's faster to reset - * the measurement loop than wait until the next measurement is due. + * The configurations errors are detected on the fly during a + * measurement cycle. If the sampling frequency is too low, it's + * faster to reset the measurement loop than wait until the next + * measurement is due. * - * Resets sensor measurement loop toggling between sleep and normal - * operating modes. + * Resets sensor measurement loop toggling between sleep and + * normal operating modes. */ ret = regmap_write_bits(data->regmap, BMP380_REG_POWER_CONTROL, BMP380_MODE_MASK, @@ -1201,22 +1202,21 @@ static int bmp380_chip_config(struct bmp280_data *data) return ret; } /* - * Waits for measurement before checking configuration error flag. - * Selected longest measure time indicated in section 3.9.1 - * in the datasheet. + * Waits for measurement before checking configuration error + * flag. Selected longest measure time indicated in + * section 3.9.1 in the datasheet. */ msleep(80); /* Check config error flag */ ret = regmap_read(data->regmap, BMP380_REG_ERROR, &tmp); if (ret) { - dev_err(data->dev, - "failed to read error register\n"); + dev_err(data->dev, "failed to read error register\n"); return ret; } if (tmp & BMP380_ERR_CONF_MASK) { dev_warn(data->dev, - "sensor flagged configuration as incompatible\n"); + "sensor flagged configuration as incompatible\n"); return -EINVAL; } } @@ -1316,9 +1316,11 @@ static int bmp580_nvm_operation(struct bmp280_data *data, bool is_write) } /* Start NVM operation sequence */ - ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_OP_SEQ_0); + ret = regmap_write(data->regmap, BMP580_REG_CMD, + BMP580_CMD_NVM_OP_SEQ_0); if (ret) { - dev_err(data->dev, "failed to send nvm operation's first sequence\n"); + dev_err(data->dev, + "failed to send nvm operation's first sequence\n"); return ret; } if (is_write) { @@ -1326,7 +1328,8 @@ static int bmp580_nvm_operation(struct bmp280_data *data, bool is_write) ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_WRITE_SEQ_1); if (ret) { - dev_err(data->dev, "failed to send nvm write sequence\n"); + dev_err(data->dev, + "failed to send nvm write sequence\n"); return ret; } /* Datasheet says on 4.8.1.2 it takes approximately 10ms */ @@ -1337,17 +1340,14 @@ static int bmp580_nvm_operation(struct bmp280_data *data, bool is_write) ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_READ_SEQ_1); if (ret) { - dev_err(data->dev, "failed to send nvm read sequence\n"); + dev_err(data->dev, + "failed to send nvm read sequence\n"); return ret; } /* Datasheet says on 4.8.1.1 it takes approximately 200us */ poll = 50; timeout = 400; } - if (ret) { - dev_err(data->dev, "failed to write command sequence\n"); - return -EIO; - } /* Wait until NVM is ready again */ ret = regmap_read_poll_timeout(data->regmap, BMP580_REG_STATUS, reg, @@ -1500,8 +1500,8 @@ static int bmp580_nvmem_read(void *priv, unsigned int offset, void *val, if (ret) goto exit; - ret = regmap_bulk_read(data->regmap, BMP580_REG_NVM_DATA_LSB, &data->le16, - sizeof(data->le16)); + ret = regmap_bulk_read(data->regmap, BMP580_REG_NVM_DATA_LSB, + &data->le16, sizeof(data->le16)); if (ret) { dev_err(data->dev, "error reading nvm data regs\n"); goto exit; @@ -1545,7 +1545,8 @@ static int bmp580_nvmem_write(void *priv, unsigned int offset, void *val, while (bytes >= sizeof(*buf)) { addr = bmp580_nvmem_addrs[offset / sizeof(*buf)]; - ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR, BMP580_NVM_PROG_EN | + ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR, + BMP580_NVM_PROG_EN | FIELD_PREP(BMP580_NVM_ROW_ADDR_MASK, addr)); if (ret) { dev_err(data->dev, "error writing nvm address\n"); @@ -1553,8 +1554,8 @@ static int bmp580_nvmem_write(void *priv, unsigned int offset, void *val, } data->le16 = cpu_to_le16(*buf++); - ret = regmap_bulk_write(data->regmap, BMP580_REG_NVM_DATA_LSB, &data->le16, - sizeof(data->le16)); + ret = regmap_bulk_write(data->regmap, BMP580_REG_NVM_DATA_LSB, + &data->le16, sizeof(data->le16)); if (ret) { dev_err(data->dev, "error writing LSB NVM data regs\n"); goto exit; @@ -1606,20 +1607,24 @@ static int bmp580_preinit(struct bmp280_data *data) /* Post powerup sequence */ ret = regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); - if (ret) + if (ret) { + dev_err(data->dev, "failed to establish comms with the chip\n"); return ret; + } /* Print warn message if we don't know the chip id */ if (reg != BMP580_CHIP_ID && reg != BMP580_CHIP_ID_ALT) - dev_warn(data->dev, "preinit: unexpected chip_id\n"); + dev_warn(data->dev, "unexpected chip_id\n"); ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); - if (ret) + if (ret) { + dev_err(data->dev, "failed to read nvm status\n"); return ret; + } /* Check nvm status */ if (!(reg & BMP580_STATUS_NVM_RDY_MASK) || (reg & BMP580_STATUS_NVM_ERR_MASK)) { - dev_err(data->dev, "preinit: nvm error on powerup sequence\n"); + dev_err(data->dev, "nvm error on powerup sequence\n"); return -EIO; } @@ -1654,6 +1659,10 @@ static int bmp580_chip_config(struct bmp280_data *data) BMP580_DSP_COMP_MASK | BMP580_DSP_SHDW_IIR_TEMP_EN | BMP580_DSP_SHDW_IIR_PRESS_EN, reg_val); + if (ret) { + dev_err(data->dev, "failed to change DSP mode settings\n"); + return ret; + } /* Configure oversampling */ reg_val = FIELD_PREP(BMP580_OSR_TEMP_MASK, data->oversampling_temp) | @@ -1661,7 +1670,8 @@ static int bmp580_chip_config(struct bmp280_data *data) BMP580_OSR_PRESS_EN; ret = regmap_update_bits_check(data->regmap, BMP580_REG_OSR_CONFIG, - BMP580_OSR_TEMP_MASK | BMP580_OSR_PRESS_MASK | + BMP580_OSR_TEMP_MASK | + BMP580_OSR_PRESS_MASK | BMP580_OSR_PRESS_EN, reg_val, &aux); if (ret) { @@ -1712,7 +1722,8 @@ static int bmp580_chip_config(struct bmp280_data *data) */ ret = regmap_read(data->regmap, BMP580_REG_EFF_OSR, &tmp); if (ret) { - dev_err(data->dev, "error reading effective OSR register\n"); + dev_err(data->dev, + "error reading effective OSR register\n"); return ret; } if (!(tmp & BMP580_EFF_OSR_VALID_ODR)) { @@ -1762,7 +1773,7 @@ const struct bmp280_chip_info bmp580_chip_info = { }; EXPORT_SYMBOL_NS(bmp580_chip_info, IIO_BMP280); -static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas) +static int bmp180_wait_for_eoc(struct bmp280_data *data, u8 ctrl_meas) { const int conversion_time_max[] = { 4500, 7500, 13500, 25500 }; unsigned int delay_us; @@ -1773,8 +1784,10 @@ static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas) reinit_completion(&data->done); ret = regmap_write(data->regmap, BMP280_REG_CTRL_MEAS, ctrl_meas); - if (ret) + if (ret) { + dev_err(data->dev, "failed to write crtl_meas register\n"); return ret; + } if (data->use_eoc) { /* @@ -1797,12 +1810,16 @@ static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas) } ret = regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl); - if (ret) + if (ret) { + dev_err(data->dev, "failed to read ctrl_meas register\n"); return ret; + } /* The value of this bit reset to "0" after conversion is complete */ - if (ctrl & BMP180_MEAS_SCO) + if (ctrl & BMP180_MEAS_SCO) { + dev_err(data->dev, "conversion didn't complete\n"); return -EIO; + } return 0; } @@ -1811,16 +1828,18 @@ static int bmp180_read_adc_temp(struct bmp280_data *data, int *val) { int ret; - ret = bmp180_measure(data, - FIELD_PREP(BMP180_MEAS_CTRL_MASK, BMP180_MEAS_TEMP) | - BMP180_MEAS_SCO); + ret = bmp180_wait_for_eoc(data, + FIELD_PREP(BMP180_MEAS_CTRL_MASK, BMP180_MEAS_TEMP) | + BMP180_MEAS_SCO); if (ret) return ret; ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, &data->be16, sizeof(data->be16)); - if (ret) + if (ret) { + dev_err(data->dev, "failed to read temperature\n"); return ret; + } *val = be16_to_cpu(data->be16); @@ -1835,9 +1854,10 @@ static int bmp180_read_calib(struct bmp280_data *data) ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, data->bmp180_cal_buf, sizeof(data->bmp180_cal_buf)); - - if (ret < 0) + if (ret) { + dev_err(data->dev, "failed to read calibration parameters\n"); return ret; + } /* None of the words has the value 0 or 0xFFFF */ for (i = 0; i < ARRAY_SIZE(data->bmp180_cal_buf); i++) { @@ -1847,7 +1867,8 @@ static int bmp180_read_calib(struct bmp280_data *data) } /* Toss the calibration data into the entropy pool */ - add_device_randomness(data->bmp180_cal_buf, sizeof(data->bmp180_cal_buf)); + add_device_randomness(data->bmp180_cal_buf, + sizeof(data->bmp180_cal_buf)); calib->AC1 = be16_to_cpu(data->bmp180_cal_buf[AC1]); calib->AC2 = be16_to_cpu(data->bmp180_cal_buf[AC2]); @@ -1870,12 +1891,12 @@ static int bmp180_read_calib(struct bmp280_data *data) * * Taken from datasheet, Section 3.5, "Calculating pressure and temperature". */ -static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp) +static s32 bmp180_compensate_temp(struct bmp280_data *data, u32 adc_temp) { struct bmp180_calib *calib = &data->calib.bmp180; s32 x1, x2; - x1 = ((adc_temp - calib->AC6) * calib->AC5) >> 15; + x1 = ((((s32)adc_temp) - calib->AC6) * calib->AC5) >> 15; x2 = (calib->MC << 11) / (x1 + calib->MD); data->t_fine = x1 + x2; @@ -1884,7 +1905,8 @@ static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp) static int bmp180_read_temp(struct bmp280_data *data, int *val, int *val2) { - s32 adc_temp, comp_temp; + s32 comp_temp; + u32 adc_temp; int ret; ret = bmp180_read_adc_temp(data, &adc_temp); @@ -1910,17 +1932,19 @@ static int bmp180_read_adc_press(struct bmp280_data *data, int *val) u8 oss = data->oversampling_press; int ret; - ret = bmp180_measure(data, - FIELD_PREP(BMP180_MEAS_CTRL_MASK, BMP180_MEAS_PRESS) | - FIELD_PREP(BMP180_OSRS_PRESS_MASK, oss) | - BMP180_MEAS_SCO); + ret = bmp180_wait_for_eoc(data, + FIELD_PREP(BMP180_MEAS_CTRL_MASK, BMP180_MEAS_PRESS) | + FIELD_PREP(BMP180_OSRS_PRESS_MASK, oss) | + BMP180_MEAS_SCO); if (ret) return ret; ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, data->buf, sizeof(data->buf)); - if (ret) + if (ret) { + dev_err(data->dev, "failed to read pressure\n"); return ret; + } *val = get_unaligned_be24(data->buf) >> (8 - oss); @@ -1932,7 +1956,7 @@ static int bmp180_read_adc_press(struct bmp280_data *data, int *val) * * Taken from datasheet, Section 3.5, "Calculating pressure and temperature". */ -static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press) +static u32 bmp180_compensate_press(struct bmp280_data *data, u32 adc_press) { struct bmp180_calib *calib = &data->calib.bmp180; s32 oss = data->oversampling_press; @@ -1949,7 +1973,7 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press) x2 = (calib->B1 * ((b6 * b6) >> 12)) >> 16; x3 = (x1 + x2 + 2) >> 2; b4 = calib->AC4 * (u32)(x3 + 32768) >> 15; - b7 = ((u32)adc_press - b3) * (50000 >> oss); + b7 = (adc_press - b3) * (50000 >> oss); if (b7 < 0x80000000) p = (b7 * 2) / b4; else @@ -1962,11 +1986,9 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press) return p + ((x1 + x2 + 3791) >> 4); } -static int bmp180_read_press(struct bmp280_data *data, - int *val, int *val2) +static int bmp180_read_press(struct bmp280_data *data, int *val, int *val2) { - u32 comp_press; - s32 adc_press; + u32 comp_press, adc_press; int ret; /* Read and compensate temperature so we get a reading of t_fine. */ @@ -2153,8 +2175,10 @@ int bmp280_common_probe(struct device *dev, data->regmap = regmap; ret = regmap_read(regmap, data->chip_info->id_reg, &chip_id); - if (ret < 0) + if (ret) { + dev_err(data->dev, "failed to read chip id\n"); return ret; + } for (i = 0; i < data->chip_info->num_chip_id; i++) { if (chip_id == data->chip_info->chip_id[i]) { @@ -2174,7 +2198,7 @@ int bmp280_common_probe(struct device *dev, } ret = data->chip_info->chip_config(data); - if (ret < 0) + if (ret) return ret; dev_set_drvdata(dev, indio_dev); @@ -2187,7 +2211,7 @@ int bmp280_common_probe(struct device *dev, if (data->chip_info->read_calib) { ret = data->chip_info->read_calib(data); - if (ret < 0) + if (ret) return dev_err_probe(data->dev, ret, "failed to read calibration coefficients\n"); } @@ -2240,6 +2264,7 @@ static int bmp280_runtime_resume(struct device *dev) ret = regulator_bulk_enable(BMP280_NUM_SUPPLIES, data->supplies); if (ret) return ret; + usleep_range(data->start_up_time, data->start_up_time + 100); return data->chip_info->chip_config(data); } diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c index 3ee56720428c5d..fa52839474b18b 100644 --- a/drivers/iio/pressure/bmp280-regmap.c +++ b/drivers/iio/pressure/bmp280-regmap.c @@ -45,7 +45,7 @@ static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { case BMP280_REG_CONFIG: - case BMP280_REG_CTRL_HUMIDITY: + case BME280_REG_CTRL_HUMIDITY: case BMP280_REG_CTRL_MEAS: case BMP280_REG_RESET: return true; @@ -57,8 +57,8 @@ static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg) static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { - case BMP280_REG_HUMIDITY_LSB: - case BMP280_REG_HUMIDITY_MSB: + case BME280_REG_HUMIDITY_LSB: + case BME280_REG_HUMIDITY_MSB: case BMP280_REG_TEMP_XLSB: case BMP280_REG_TEMP_LSB: case BMP280_REG_TEMP_MSB: @@ -167,7 +167,7 @@ const struct regmap_config bmp280_regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = BMP280_REG_HUMIDITY_LSB, + .max_register = BME280_REG_HUMIDITY_LSB, .cache_type = REGCACHE_RBTREE, .writeable_reg = bmp280_is_writeable_reg, diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index a444d4b2978b58..cabe9c66aa34ad 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -13,7 +13,7 @@ #include "bmp280.h" static int bmp280_regmap_spi_write(void *context, const void *data, - size_t count) + size_t count) { struct spi_device *spi = to_spi_device(context); u8 buf[2]; @@ -29,7 +29,7 @@ static int bmp280_regmap_spi_write(void *context, const void *data, } static int bmp280_regmap_spi_read(void *context, const void *reg, - size_t reg_size, void *val, size_t val_size) + size_t reg_size, void *val, size_t val_size) { struct spi_device *spi = to_spi_device(context); diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index 4012387d795656..51fbd451ecbeb3 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -192,8 +192,6 @@ #define BMP380_PRESS_SKIPPED 0x800000 /* BMP280 specific registers */ -#define BMP280_REG_HUMIDITY_LSB 0xFE -#define BMP280_REG_HUMIDITY_MSB 0xFD #define BMP280_REG_TEMP_XLSB 0xFC #define BMP280_REG_TEMP_LSB 0xFB #define BMP280_REG_TEMP_MSB 0xFA @@ -207,15 +205,6 @@ #define BMP280_REG_CONFIG 0xF5 #define BMP280_REG_CTRL_MEAS 0xF4 #define BMP280_REG_STATUS 0xF3 -#define BMP280_REG_CTRL_HUMIDITY 0xF2 - -/* Due to non linear mapping, and data sizes we can't do a bulk read */ -#define BMP280_REG_COMP_H1 0xA1 -#define BMP280_REG_COMP_H2 0xE1 -#define BMP280_REG_COMP_H3 0xE3 -#define BMP280_REG_COMP_H4 0xE4 -#define BMP280_REG_COMP_H5 0xE5 -#define BMP280_REG_COMP_H6 0xE7 #define BMP280_REG_COMP_TEMP_START 0x88 #define BMP280_COMP_TEMP_REG_COUNT 6 @@ -223,8 +212,6 @@ #define BMP280_REG_COMP_PRESS_START 0x8E #define BMP280_COMP_PRESS_REG_COUNT 18 -#define BMP280_COMP_H5_MASK GENMASK(15, 4) - #define BMP280_CONTIGUOUS_CALIB_REGS (BMP280_COMP_TEMP_REG_COUNT + \ BMP280_COMP_PRESS_REG_COUNT) @@ -235,14 +222,6 @@ #define BMP280_FILTER_8X 3 #define BMP280_FILTER_16X 4 -#define BMP280_OSRS_HUMIDITY_MASK GENMASK(2, 0) -#define BMP280_OSRS_HUMIDITY_SKIP 0 -#define BMP280_OSRS_HUMIDITY_1X 1 -#define BMP280_OSRS_HUMIDITY_2X 2 -#define BMP280_OSRS_HUMIDITY_4X 3 -#define BMP280_OSRS_HUMIDITY_8X 4 -#define BMP280_OSRS_HUMIDITY_16X 5 - #define BMP280_OSRS_TEMP_MASK GENMASK(7, 5) #define BMP280_OSRS_TEMP_SKIP 0 #define BMP280_OSRS_TEMP_1X 1 @@ -264,6 +243,30 @@ #define BMP280_MODE_FORCED 1 #define BMP280_MODE_NORMAL 3 +/* BME280 specific registers */ +#define BME280_REG_HUMIDITY_LSB 0xFE +#define BME280_REG_HUMIDITY_MSB 0xFD + +#define BME280_REG_CTRL_HUMIDITY 0xF2 + +/* Due to non linear mapping, and data sizes we can't do a bulk read */ +#define BME280_REG_COMP_H1 0xA1 +#define BME280_REG_COMP_H2 0xE1 +#define BME280_REG_COMP_H3 0xE3 +#define BME280_REG_COMP_H4 0xE4 +#define BME280_REG_COMP_H5 0xE5 +#define BME280_REG_COMP_H6 0xE7 + +#define BME280_COMP_H5_MASK GENMASK(15, 4) + +#define BME280_OSRS_HUMIDITY_MASK GENMASK(2, 0) +#define BME280_OSRS_HUMIDITY_SKIP 0 +#define BME280_OSRS_HUMIDITY_1X 1 +#define BME280_OSRS_HUMIDITY_2X 2 +#define BME280_OSRS_HUMIDITY_4X 3 +#define BME280_OSRS_HUMIDITY_8X 4 +#define BME280_OSRS_HUMIDITY_16X 5 + /* BMP180 specific registers */ #define BMP180_REG_OUT_XLSB 0xF8 #define BMP180_REG_OUT_LSB 0xF7 @@ -448,12 +451,12 @@ struct bmp280_chip_info { int num_sampling_freq_avail; int sampling_freq_default; - int (*chip_config)(struct bmp280_data *); - int (*read_temp)(struct bmp280_data *, int *, int *); - int (*read_press)(struct bmp280_data *, int *, int *); - int (*read_humid)(struct bmp280_data *, int *, int *); - int (*read_calib)(struct bmp280_data *); - int (*preinit)(struct bmp280_data *); + int (*chip_config)(struct bmp280_data *data); + int (*read_temp)(struct bmp280_data *data, int *val, int *val2); + int (*read_press)(struct bmp280_data *data, int *val, int *val2); + int (*read_humid)(struct bmp280_data *data, int *val, int *val2); + int (*read_calib)(struct bmp280_data *data); + int (*preinit)(struct bmp280_data *data); }; /* Chip infos for each variant */ @@ -472,7 +475,7 @@ extern const struct regmap_config bmp580_regmap_config; /* Probe called from different transports */ int bmp280_common_probe(struct device *dev, struct regmap *regmap, - const struct bmp280_chip_info *, + const struct bmp280_chip_info *chip_info, const char *name, int irq); diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 7d882e15e5564a..c6f44f0f4d2e63 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -887,7 +887,7 @@ static int dps310_probe(struct i2c_client *client) } static const struct i2c_device_id dps310_id[] = { - { DPS310_DEV_NAME, 0 }, + { DPS310_DEV_NAME }, {} }; MODULE_DEVICE_TABLE(i2c, dps310_id); diff --git a/drivers/iio/pressure/hp03.c b/drivers/iio/pressure/hp03.c index 8bdb279129fa21..6f7a16787143ce 100644 --- a/drivers/iio/pressure/hp03.c +++ b/drivers/iio/pressure/hp03.c @@ -266,8 +266,8 @@ static int hp03_probe(struct i2c_client *client) } static const struct i2c_device_id hp03_id[] = { - { "hp03", 0 }, - { }, + { "hp03" }, + { } }; MODULE_DEVICE_TABLE(i2c, hp03_id); diff --git a/drivers/iio/pressure/icp10100.c b/drivers/iio/pressure/icp10100.c index 2086f3ef338fef..3e0bf5d31ad7a4 100644 --- a/drivers/iio/pressure/icp10100.c +++ b/drivers/iio/pressure/icp10100.c @@ -637,7 +637,7 @@ static const struct of_device_id icp10100_of_match[] = { MODULE_DEVICE_TABLE(of, icp10100_of_match); static const struct i2c_device_id icp10100_id[] = { - { "icp10100", 0 }, + { "icp10100" }, { } }; MODULE_DEVICE_TABLE(i2c, icp10100_id); diff --git a/drivers/iio/pressure/mpl115_i2c.c b/drivers/iio/pressure/mpl115_i2c.c index fcbdadf4a51189..0c51dc02478e21 100644 --- a/drivers/iio/pressure/mpl115_i2c.c +++ b/drivers/iio/pressure/mpl115_i2c.c @@ -45,7 +45,7 @@ static int mpl115_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id mpl115_i2c_id[] = { - { "mpl115", 0 }, + { "mpl115" }, { } }; MODULE_DEVICE_TABLE(i2c, mpl115_i2c_id); diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c index 7aa19584c340c1..71ded2eee060f8 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -318,7 +318,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume); static const struct i2c_device_id mpl3115_id[] = { - { "mpl3115", 0 }, + { "mpl3115" }, { } }; MODULE_DEVICE_TABLE(i2c, mpl3115_id); diff --git a/drivers/iio/pressure/t5403.c b/drivers/iio/pressure/t5403.c index a6463c06975eb5..c7cb0fd816d3c5 100644 --- a/drivers/iio/pressure/t5403.c +++ b/drivers/iio/pressure/t5403.c @@ -251,7 +251,7 @@ static int t5403_probe(struct i2c_client *client) } static const struct i2c_device_id t5403_id[] = { - { "t5403", 0 }, + { "t5403" }, { } }; MODULE_DEVICE_TABLE(i2c, t5403_id); diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c index c7fffbe7c788ab..4833e525c39357 100644 --- a/drivers/iio/pressure/zpa2326_i2c.c +++ b/drivers/iio/pressure/zpa2326_i2c.c @@ -59,8 +59,8 @@ static void zpa2326_remove_i2c(struct i2c_client *client) } static const struct i2c_device_id zpa2326_i2c_ids[] = { - { "zpa2326", 0 }, - { }, + { "zpa2326" }, + { } }; MODULE_DEVICE_TABLE(i2c, zpa2326_i2c_ids); diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c index 4982686fb4c309..dc66ca9bba6b46 100644 --- a/drivers/iio/proximity/isl29501.c +++ b/drivers/iio/proximity/isl29501.c @@ -989,7 +989,7 @@ static int isl29501_probe(struct i2c_client *client) } static const struct i2c_device_id isl29501_id[] = { - {"isl29501", 0}, + { "isl29501" }, {} }; diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 2913d5e0fe4f99..5c959730aecd85 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -322,9 +322,9 @@ static void lidar_remove(struct i2c_client *client) } static const struct i2c_device_id lidar_id[] = { - {"lidar-lite-v2", 0}, - {"lidar-lite-v3", 0}, - { }, + { "lidar-lite-v2" }, + { "lidar-lite-v3" }, + { } }; MODULE_DEVICE_TABLE(i2c, lidar_id); diff --git a/drivers/iio/proximity/rfd77402.c b/drivers/iio/proximity/rfd77402.c index f02e83e3f15f34..aff60a3c1a6f04 100644 --- a/drivers/iio/proximity/rfd77402.c +++ b/drivers/iio/proximity/rfd77402.c @@ -308,7 +308,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, rfd77402_resume); static const struct i2c_device_id rfd77402_id[] = { - { "rfd77402", 0 }, + { "rfd77402" }, { } }; MODULE_DEVICE_TABLE(i2c, rfd77402_id); diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c index 550e7d3cd5ee5e..b89d49defd7a34 100644 --- a/drivers/iio/proximity/sx9500.c +++ b/drivers/iio/proximity/sx9500.c @@ -1043,8 +1043,8 @@ static const struct of_device_id sx9500_of_match[] = { MODULE_DEVICE_TABLE(of, sx9500_of_match); static const struct i2c_device_id sx9500_id[] = { - {"sx9500", 0}, - { }, + { "sx9500" }, + { } }; MODULE_DEVICE_TABLE(i2c, sx9500_id); diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c index 2cea64bea90986..8d4f3f849fe246 100644 --- a/drivers/iio/proximity/vl53l0x-i2c.c +++ b/drivers/iio/proximity/vl53l0x-i2c.c @@ -278,7 +278,7 @@ static int vl53l0x_probe(struct i2c_client *client) } static const struct i2c_device_id vl53l0x_id[] = { - { "vl53l0x", 0 }, + { "vl53l0x" }, { } }; MODULE_DEVICE_TABLE(i2c, vl53l0x_id); diff --git a/drivers/iio/temperature/max30208.c b/drivers/iio/temperature/max30208.c index 48be03852cd8df..720469f9dc36fb 100644 --- a/drivers/iio/temperature/max30208.c +++ b/drivers/iio/temperature/max30208.c @@ -34,7 +34,6 @@ struct max30208_data { struct i2c_client *client; - struct iio_dev *indio_dev; struct mutex lock; /* Lock to prevent concurrent reads of temperature readings */ }; diff --git a/drivers/iio/temperature/mcp9600.c b/drivers/iio/temperature/mcp9600.c index 46845804292bf0..7a3eef5d5e752a 100644 --- a/drivers/iio/temperature/mcp9600.c +++ b/drivers/iio/temperature/mcp9600.c @@ -52,7 +52,8 @@ static int mcp9600_read(struct mcp9600_data *data, if (ret < 0) return ret; - *val = ret; + + *val = sign_extend32(ret, 15); return 0; } diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 8a57be108620af..4676e0edde4a73 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -1279,7 +1279,7 @@ static int mlx90632_probe(struct i2c_client *client) } static const struct i2c_device_id mlx90632_id[] = { - { "mlx90632", 0 }, + { "mlx90632" }, { } }; MODULE_DEVICE_TABLE(i2c, mlx90632_id); diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 3a3904fe138c11..6d8d661f0c82aa 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -280,7 +280,7 @@ static const struct of_device_id tmp006_of_match[] = { MODULE_DEVICE_TABLE(of, tmp006_of_match); static const struct i2c_device_id tmp006_id[] = { - { "tmp006", 0 }, + { "tmp006" }, { } }; MODULE_DEVICE_TABLE(i2c, tmp006_id); diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index decef689636238..9bdfa94234929c 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -563,7 +563,7 @@ static const struct of_device_id tmp007_of_match[] = { MODULE_DEVICE_TABLE(of, tmp007_of_match); static const struct i2c_device_id tmp007_id[] = { - { "tmp007", 0 }, + { "tmp007" }, { } }; MODULE_DEVICE_TABLE(i2c, tmp007_id); diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 53ef56fbfe1def..9213761c5d18a4 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -206,7 +206,7 @@ static int tsys01_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id tsys01_id[] = { - {"tsys01", 0}, + { "tsys01" }, {} }; MODULE_DEVICE_TABLE(i2c, tsys01_id); diff --git a/drivers/iio/temperature/tsys02d.c b/drivers/iio/temperature/tsys02d.c index 6191db92ef9a53..2b4959d6e46761 100644 --- a/drivers/iio/temperature/tsys02d.c +++ b/drivers/iio/temperature/tsys02d.c @@ -168,7 +168,7 @@ static int tsys02d_probe(struct i2c_client *client) } static const struct i2c_device_id tsys02d_id[] = { - {"tsys02d", 0}, + { "tsys02d" }, {} }; MODULE_DEVICE_TABLE(i2c, tsys02d_id); diff --git a/drivers/iio/test/iio-test-gts.c b/drivers/iio/test/iio-test-gts.c index cf7ab773ea0b15..5f16a7b5e6d411 100644 --- a/drivers/iio/test/iio-test-gts.c +++ b/drivers/iio/test/iio-test-gts.c @@ -70,6 +70,7 @@ */ static struct iio_gts gts; +/* Keep the gain and time tables unsorted to test the sorting */ static const struct iio_gain_sel_pair gts_test_gains[] = { GAIN_SCALE_GAIN(1, TEST_GSEL_1), GAIN_SCALE_GAIN(4, TEST_GSEL_4), @@ -79,16 +80,17 @@ static const struct iio_gain_sel_pair gts_test_gains[] = { GAIN_SCALE_GAIN(256, TEST_GSEL_256), GAIN_SCALE_GAIN(512, TEST_GSEL_512), GAIN_SCALE_GAIN(1024, TEST_GSEL_1024), - GAIN_SCALE_GAIN(2048, TEST_GSEL_2048), GAIN_SCALE_GAIN(4096, TEST_GSEL_4096), + GAIN_SCALE_GAIN(2048, TEST_GSEL_2048), #define HWGAIN_MAX 4096 }; static const struct iio_itime_sel_mul gts_test_itimes[] = { - GAIN_SCALE_ITIME_US(400 * 1000, TEST_TSEL_400, 8), - GAIN_SCALE_ITIME_US(200 * 1000, TEST_TSEL_200, 4), GAIN_SCALE_ITIME_US(100 * 1000, TEST_TSEL_100, 2), + GAIN_SCALE_ITIME_US(400 * 1000, TEST_TSEL_400, 8), + GAIN_SCALE_ITIME_US(400 * 1000, TEST_TSEL_400, 8), GAIN_SCALE_ITIME_US(50 * 1000, TEST_TSEL_50, 1), + GAIN_SCALE_ITIME_US(200 * 1000, TEST_TSEL_200, 4), #define TIMEGAIN_MAX 8 }; #define TOTAL_GAIN_MAX (HWGAIN_MAX * TIMEGAIN_MAX) diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c index 96735800b13c09..ba4cc08684d638 100644 --- a/drivers/interconnect/qcom/qcm2290.c +++ b/drivers/interconnect/qcom/qcm2290.c @@ -164,7 +164,7 @@ static struct qcom_icc_node mas_snoc_bimc = { .name = "mas_snoc_bimc", .buswidth = 16, .qos.ap_owned = true, - .qos.qos_port = 2, + .qos.qos_port = 6, .qos.qos_mode = NOC_QOS_MODE_BYPASS, .mas_rpm_id = 164, .slv_rpm_id = -1, diff --git a/drivers/interconnect/qcom/sm6115.c b/drivers/interconnect/qcom/sm6115.c index 7e15ddf0a80a9c..271b07c74862d2 100644 --- a/drivers/interconnect/qcom/sm6115.c +++ b/drivers/interconnect/qcom/sm6115.c @@ -242,7 +242,7 @@ static struct qcom_icc_node crypto_c0 = { .id = SM6115_MASTER_CRYPTO_CORE0, .channels = 1, .buswidth = 8, - .qos.qos_port = 43, + .qos.qos_port = 22, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 23, @@ -332,7 +332,7 @@ static struct qcom_icc_node qnm_camera_nrt = { .id = SM6115_MASTER_CAMNOC_SF, .channels = 1, .buswidth = 32, - .qos.qos_port = 25, + .qos.qos_port = 4, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 3, .mas_rpm_id = -1, @@ -346,7 +346,7 @@ static struct qcom_icc_node qxm_venus0 = { .id = SM6115_MASTER_VIDEO_P0, .channels = 1, .buswidth = 16, - .qos.qos_port = 30, + .qos.qos_port = 9, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 3, .qos.urg_fwd_en = true, @@ -361,7 +361,7 @@ static struct qcom_icc_node qxm_venus_cpu = { .id = SM6115_MASTER_VIDEO_PROC, .channels = 1, .buswidth = 8, - .qos.qos_port = 34, + .qos.qos_port = 13, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 4, .mas_rpm_id = -1, @@ -379,7 +379,7 @@ static struct qcom_icc_node qnm_camera_rt = { .id = SM6115_MASTER_CAMNOC_HF, .channels = 1, .buswidth = 32, - .qos.qos_port = 31, + .qos.qos_port = 10, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 3, .qos.urg_fwd_en = true, @@ -394,7 +394,7 @@ static struct qcom_icc_node qxm_mdp0 = { .id = SM6115_MASTER_MDP_PORT0, .channels = 1, .buswidth = 16, - .qos.qos_port = 26, + .qos.qos_port = 5, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 3, .qos.urg_fwd_en = true, @@ -434,7 +434,7 @@ static struct qcom_icc_node qhm_tic = { .id = SM6115_MASTER_TIC, .channels = 1, .buswidth = 4, - .qos.qos_port = 29, + .qos.qos_port = 8, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, @@ -484,7 +484,7 @@ static struct qcom_icc_node qxm_pimem = { .id = SM6115_MASTER_PIMEM, .channels = 1, .buswidth = 8, - .qos.qos_port = 41, + .qos.qos_port = 20, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, @@ -498,7 +498,7 @@ static struct qcom_icc_node qhm_qdss_bam = { .id = SM6115_MASTER_QDSS_BAM, .channels = 1, .buswidth = 4, - .qos.qos_port = 23, + .qos.qos_port = 2, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, @@ -523,7 +523,7 @@ static struct qcom_icc_node qhm_qup0 = { .id = SM6115_MASTER_QUP_0, .channels = 1, .buswidth = 4, - .qos.qos_port = 21, + .qos.qos_port = 0, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 166, @@ -537,7 +537,7 @@ static struct qcom_icc_node qxm_ipa = { .id = SM6115_MASTER_IPA, .channels = 1, .buswidth = 8, - .qos.qos_port = 24, + .qos.qos_port = 3, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 59, @@ -551,7 +551,7 @@ static struct qcom_icc_node xm_qdss_etr = { .id = SM6115_MASTER_QDSS_ETR, .channels = 1, .buswidth = 8, - .qos.qos_port = 33, + .qos.qos_port = 12, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, @@ -565,7 +565,7 @@ static struct qcom_icc_node xm_sdc1 = { .id = SM6115_MASTER_SDCC_1, .channels = 1, .buswidth = 8, - .qos.qos_port = 38, + .qos.qos_port = 17, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 33, @@ -579,7 +579,7 @@ static struct qcom_icc_node xm_sdc2 = { .id = SM6115_MASTER_SDCC_2, .channels = 1, .buswidth = 8, - .qos.qos_port = 44, + .qos.qos_port = 23, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 35, @@ -593,7 +593,7 @@ static struct qcom_icc_node xm_usb3_0 = { .id = SM6115_MASTER_USB3, .channels = 1, .buswidth = 8, - .qos.qos_port = 45, + .qos.qos_port = 24, .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, @@ -1336,6 +1336,7 @@ static const struct qcom_icc_desc sm6115_sys_noc = { .intf_clocks = snoc_intf_clocks, .num_intf_clocks = ARRAY_SIZE(snoc_intf_clocks), .bus_clk_desc = &bus_2_clk, + .qos_offset = 0x15000, .keep_alive = true, }; @@ -1367,6 +1368,7 @@ static const struct qcom_icc_desc sm6115_mmnrt_virt = { .regmap_cfg = &sys_noc_regmap_config, .bus_clk_desc = &mmaxi_0_clk, .keep_alive = true, + .qos_offset = 0x15000, .ab_coeff = 142, }; @@ -1383,6 +1385,7 @@ static const struct qcom_icc_desc sm6115_mmrt_virt = { .regmap_cfg = &sys_noc_regmap_config, .bus_clk_desc = &mmaxi_1_clk, .keep_alive = true, + .qos_offset = 0x15000, .ab_coeff = 139, }; diff --git a/drivers/mcb/mcb-lpc.c b/drivers/mcb/mcb-lpc.c index a851e02364642d..2bec2086ee1719 100644 --- a/drivers/mcb/mcb-lpc.c +++ b/drivers/mcb/mcb-lpc.c @@ -97,13 +97,11 @@ out_mcb_bus: return ret; } -static int mcb_lpc_remove(struct platform_device *pdev) +static void mcb_lpc_remove(struct platform_device *pdev) { struct priv *priv = platform_get_drvdata(pdev); mcb_release_bus(priv->bus); - - return 0; } static struct platform_device *mcb_lpc_pdev; @@ -140,7 +138,7 @@ static struct platform_driver mcb_lpc_driver = { .name = "mcb-lpc", }, .probe = mcb_lpc_probe, - .remove = mcb_lpc_remove, + .remove_new = mcb_lpc_remove, }; static const struct dmi_system_id mcb_lpc_dmi_table[] = { diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 801ed229ed7dc1..2907b5c23368d6 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -293,21 +293,21 @@ config SGI_GRU depends on X86_UV && SMP select MMU_NOTIFIER 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, - scatter/gather, bcopy, AMOs, etc. The GRU is directly accessed by user - instructions using user virtual addresses. GRU instructions (ex., bcopy) use - user virtual addresses for operands. + 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, scatter/gather, bcopy, AMOs, etc. The GRU is + directly accessed by user instructions using user virtual addresses. + GRU instructions (ex., bcopy) use user virtual addresses for operands. - If you are not running on a SGI UV system, say N. + If you are not running on a SGI UV system, say N. config SGI_GRU_DEBUG bool "SGI GRU driver debug" depends on SGI_GRU help - This option enables additional debugging code for the SGI GRU driver. - If you are unsure, say N. + This option enables additional debugging code for the SGI GRU driver. + If you are unsure, say N. config APDS9802ALS tristate "Medfield Avago APDS9802 ALS Sensor module" @@ -428,7 +428,6 @@ config LATTICE_ECP3_CONFIG tristate "Lattice ECP3 FPGA bitstream configuration via SPI" depends on SPI && SYSFS select FW_LOADER - default n help This option enables support for bitstream configuration (programming or loading) of the Lattice ECP3 FPGA family via SPI. diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 65d49a6de1a7a1..595ceb9a712617 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -529,4 +529,3 @@ module_spi_driver(at25_driver); MODULE_DESCRIPTION("Driver for most SPI EEPROMs"); MODULE_AUTHOR("David Brownell"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:at25"); diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index e78a76d74ff4fd..45c8ae0db8f902 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -578,5 +578,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs"); MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); MODULE_ALIAS("spi:93xx46"); -MODULE_ALIAS("spi:eeprom-93xx46"); -MODULE_ALIAS("spi:93lc46b"); diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index f9bcff19761512..99393f610cdf6d 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -1327,7 +1327,7 @@ static int mei_cl_device_uevent(const struct device *dev, struct kobj_uevent_env return 0; } -static struct bus_type mei_cl_bus_type = { +static const struct bus_type mei_cl_bus_type = { .name = "mei", .dev_groups = mei_cldev_groups, .match = mei_cl_device_match, diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c index df3457ce1cb146..17c0eb54946336 100644 --- a/drivers/misc/pvpanic/pvpanic.c +++ b/drivers/misc/pvpanic/pvpanic.c @@ -19,6 +19,7 @@ #include <linux/module.h> #include <linux/panic_notifier.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/spinlock.h> #include <linux/sysfs.h> #include <linux/types.h> @@ -35,6 +36,7 @@ struct pvpanic_instance { void __iomem *base; unsigned int capability; unsigned int events; + struct sys_off_handler *sys_off; struct list_head list; }; @@ -78,6 +80,39 @@ static struct notifier_block pvpanic_panic_nb = { .priority = INT_MAX, }; +static int pvpanic_sys_off(struct sys_off_data *data) +{ + pvpanic_send_event(PVPANIC_SHUTDOWN); + + return NOTIFY_DONE; +} + +static void pvpanic_synchronize_sys_off_handler(struct device *dev, struct pvpanic_instance *pi) +{ + /* The kernel core has logic to fall back to system halt if no + * sys_off_handler is registered. + * When the pvpanic sys_off_handler is disabled via sysfs the kernel + * should use that fallback logic, so the handler needs to be unregistered. + */ + + struct sys_off_handler *sys_off; + + if (!(pi->events & PVPANIC_SHUTDOWN) == !pi->sys_off) + return; + + if (!pi->sys_off) { + sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_LOW, + pvpanic_sys_off, NULL); + if (IS_ERR(sys_off)) + dev_warn(dev, "Could not register sys_off_handler: %pe\n", sys_off); + else + pi->sys_off = sys_off; + } else { + unregister_sys_off_handler(pi->sys_off); + pi->sys_off = NULL; + } +} + static void pvpanic_remove(void *param) { struct pvpanic_instance *pi_cur, *pi_next; @@ -91,6 +126,8 @@ static void pvpanic_remove(void *param) } } spin_unlock(&pvpanic_lock); + + unregister_sys_off_handler(pi->sys_off); } static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -123,6 +160,7 @@ static ssize_t events_store(struct device *dev, struct device_attribute *attr, return -EINVAL; pi->events = tmp; + pvpanic_synchronize_sys_off_handler(dev, pi); return count; } @@ -156,12 +194,15 @@ int devm_pvpanic_probe(struct device *dev, void __iomem *base) return -ENOMEM; pi->base = base; - pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; + pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED | PVPANIC_SHUTDOWN; /* initlize capability by RDPT */ pi->capability &= ioread8(base); pi->events = pi->capability; + pi->sys_off = NULL; + pvpanic_synchronize_sys_off_handler(dev, pi); + spin_lock(&pvpanic_lock); list_add(&pi->list, &pvpanic_list); spin_unlock(&pvpanic_lock); diff --git a/drivers/misc/vmw_vmci/vmci_event.c b/drivers/misc/vmw_vmci/vmci_event.c index 5d7ac07623c273..9a41ab65378de0 100644 --- a/drivers/misc/vmw_vmci/vmci_event.c +++ b/drivers/misc/vmw_vmci/vmci_event.c @@ -9,6 +9,7 @@ #include <linux/vmw_vmci_api.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/nospec.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/rculist.h> @@ -86,9 +87,12 @@ static void event_deliver(struct vmci_event_msg *event_msg) { struct vmci_subscription *cur; struct list_head *subscriber_list; + u32 sanitized_event, max_vmci_event; rcu_read_lock(); - subscriber_list = &subscriber_array[event_msg->event_data.event]; + max_vmci_event = ARRAY_SIZE(subscriber_array); + sanitized_event = array_index_nospec(event_msg->event_data.event, max_vmci_event); + subscriber_list = &subscriber_array[sanitized_event]; list_for_each_entry_rcu(cur, subscriber_list, node) { cur->callback(cur->id, &event_msg->event_data, cur->callback_data); diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index 4f8d962bb5b2a3..1300ccab3d21b1 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -625,7 +625,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, if (!vmci_dev) { dev_err(&pdev->dev, "Can't allocate memory for VMCI device\n"); - return -ENOMEM; + error = -ENOMEM; + goto err_unmap_mmio_base; } vmci_dev->dev = &pdev->dev; @@ -642,7 +643,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, if (!vmci_dev->tx_buffer) { dev_err(&pdev->dev, "Can't allocate memory for datagram tx buffer\n"); - return -ENOMEM; + error = -ENOMEM; + goto err_unmap_mmio_base; } vmci_dev->data_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE, @@ -893,6 +895,10 @@ err_free_notification_bitmap: err_free_data_buffers: vmci_free_dg_buffers(vmci_dev); +err_unmap_mmio_base: + if (mmio_base != NULL) + pci_iounmap(pdev, mmio_base); + /* The rest are managed resources and will be freed by PCI core */ return error; } diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 2c6b99402df8a7..e1ec3b7200d7b4 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -478,7 +478,7 @@ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) nvmem_cells_group.bin_attrs = cells_attrs; - ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups); + ret = device_add_groups(&nvmem->dev, nvmem_cells_groups); if (ret) goto unlock_mutex; diff --git a/drivers/nvmem/layouts.c b/drivers/nvmem/layouts.c index 8b5e2de138eb51..64dc7013a09844 100644 --- a/drivers/nvmem/layouts.c +++ b/drivers/nvmem/layouts.c @@ -52,13 +52,15 @@ static const struct bus_type nvmem_layout_bus_type = { .remove = nvmem_layout_bus_remove, }; -int nvmem_layout_driver_register(struct nvmem_layout_driver *drv) +int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, + struct module *owner) { drv->driver.bus = &nvmem_layout_bus_type; + drv->driver.owner = owner; return driver_register(&drv->driver); } -EXPORT_SYMBOL_GPL(nvmem_layout_driver_register); +EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register); void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv) { diff --git a/drivers/nvmem/layouts/onie-tlv.c b/drivers/nvmem/layouts/onie-tlv.c index 9d2ad5f2dc1012..0967a32319a288 100644 --- a/drivers/nvmem/layouts/onie-tlv.c +++ b/drivers/nvmem/layouts/onie-tlv.c @@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); static struct nvmem_layout_driver onie_tlv_layout = { .driver = { - .owner = THIS_MODULE, .name = "onie-tlv-layout", .of_match_table = onie_tlv_of_match_table, }, diff --git a/drivers/nvmem/layouts/sl28vpd.c b/drivers/nvmem/layouts/sl28vpd.c index 53fa50f17dcaf7..e93b020b08369d 100644 --- a/drivers/nvmem/layouts/sl28vpd.c +++ b/drivers/nvmem/layouts/sl28vpd.c @@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); static struct nvmem_layout_driver sl28vpd_layout = { .driver = { - .owner = THIS_MODULE, .name = "kontron-sl28vpd-layout", .of_match_table = sl28vpd_of_match_table, }, diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c index a0275b29afd5b9..a73acc7377d251 100644 --- a/drivers/nvmem/lpc18xx_eeprom.c +++ b/drivers/nvmem/lpc18xx_eeprom.c @@ -249,13 +249,11 @@ err_clk: return ret; } -static int lpc18xx_eeprom_remove(struct platform_device *pdev) +static void lpc18xx_eeprom_remove(struct platform_device *pdev) { struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev); clk_disable_unprepare(eeprom->clk); - - return 0; } static const struct of_device_id lpc18xx_eeprom_of_match[] = { @@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_of_match); static struct platform_driver lpc18xx_eeprom_driver = { .probe = lpc18xx_eeprom_probe, - .remove = lpc18xx_eeprom_remove, + .remove_new = lpc18xx_eeprom_remove, .driver = { .name = "lpc18xx-eeprom", .of_match_table = lpc18xx_eeprom_of_match, diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c index 3ff04d5ca8f854..8a16f5f0265790 100644 --- a/drivers/nvmem/meson-mx-efuse.c +++ b/drivers/nvmem/meson-mx-efuse.c @@ -43,7 +43,6 @@ struct meson_mx_efuse_platform_data { struct meson_mx_efuse { void __iomem *base; struct clk *core_clk; - struct nvmem_device *nvmem; struct nvmem_config config; }; @@ -193,6 +192,7 @@ static int meson_mx_efuse_probe(struct platform_device *pdev) { const struct meson_mx_efuse_platform_data *drvdata; struct meson_mx_efuse *efuse; + struct nvmem_device *nvmem; drvdata = of_device_get_match_data(&pdev->dev); if (!drvdata) @@ -223,9 +223,9 @@ static int meson_mx_efuse_probe(struct platform_device *pdev) return PTR_ERR(efuse->core_clk); } - efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config); + nvmem = devm_nvmem_register(&pdev->dev, &efuse->config); - return PTR_ERR_OR_ZERO(efuse->nvmem); + return PTR_ERR_OR_ZERO(nvmem); } static struct platform_driver meson_mx_efuse_driver = { diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c index bff27011f4ff28..4e2ffefac96c91 100644 --- a/drivers/nvmem/sc27xx-efuse.c +++ b/drivers/nvmem/sc27xx-efuse.c @@ -262,6 +262,7 @@ static const struct of_device_id sc27xx_efuse_of_match[] = { { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata}, { } }; +MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match); static struct platform_driver sc27xx_efuse_driver = { .probe = sc27xx_efuse_probe, diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c index bb3105f3291fcf..1a7e4e5d8b86c6 100644 --- a/drivers/nvmem/sprd-efuse.c +++ b/drivers/nvmem/sprd-efuse.c @@ -426,6 +426,7 @@ static const struct of_device_id sprd_efuse_of_match[] = { { .compatible = "sprd,ums312-efuse", .data = &ums312_data }, { } }; +MODULE_DEVICE_TABLE(of, sprd_efuse_of_match); static struct platform_driver sprd_efuse_driver = { .probe = sprd_efuse_probe, diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c index 400b7b385a443e..0274bc285b6018 100644 --- a/drivers/slimbus/qcom-ctrl.c +++ b/drivers/slimbus/qcom-ctrl.c @@ -626,7 +626,7 @@ err_request_irq_failed: return ret; } -static int qcom_slim_remove(struct platform_device *pdev) +static void qcom_slim_remove(struct platform_device *pdev) { struct qcom_slim_ctrl *ctrl = platform_get_drvdata(pdev); @@ -635,7 +635,6 @@ static int qcom_slim_remove(struct platform_device *pdev) clk_disable_unprepare(ctrl->rclk); clk_disable_unprepare(ctrl->hclk); destroy_workqueue(ctrl->rxwq); - return 0; } /* @@ -718,10 +717,11 @@ static const struct of_device_id qcom_slim_dt_match[] = { { .compatible = "qcom,slim", }, {} }; +MODULE_DEVICE_TABLE(of, qcom_slim_dt_match); static struct platform_driver qcom_slim_driver = { .probe = qcom_slim_probe, - .remove = qcom_slim_remove, + .remove_new = qcom_slim_remove, .driver = { .name = "qcom_slim_ctrl", .of_match_table = qcom_slim_dt_match, diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index efeba8275a6691..a33b5f9090fe2a 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -81,7 +81,6 @@ #define SLIM_USR_MC_DISCONNECT_PORT 0x2E #define SLIM_USR_MC_REPEAT_CHANGE_VALUE 0x0 -#define QCOM_SLIM_NGD_AUTOSUSPEND MSEC_PER_SEC #define SLIM_RX_MSGQ_TIMEOUT_VAL 0x10000 #define SLIM_LA_MGR 0xFF @@ -1571,7 +1570,7 @@ static int qcom_slim_ngd_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctrl); pm_runtime_use_autosuspend(dev); - pm_runtime_set_autosuspend_delay(dev, QCOM_SLIM_NGD_AUTOSUSPEND); + pm_runtime_set_autosuspend_delay(dev, 100); pm_runtime_set_suspended(dev); pm_runtime_enable(dev); pm_runtime_get_noresume(dev); @@ -1675,14 +1674,12 @@ err_pdr_lookup: return ret; } -static int qcom_slim_ngd_ctrl_remove(struct platform_device *pdev) +static void qcom_slim_ngd_ctrl_remove(struct platform_device *pdev) { platform_driver_unregister(&qcom_slim_ngd_driver); - - return 0; } -static int qcom_slim_ngd_remove(struct platform_device *pdev) +static void qcom_slim_ngd_remove(struct platform_device *pdev) { struct qcom_slim_ngd_ctrl *ctrl = platform_get_drvdata(pdev); @@ -1697,7 +1694,6 @@ static int qcom_slim_ngd_remove(struct platform_device *pdev) kfree(ctrl->ngd); ctrl->ngd = NULL; - return 0; } static int __maybe_unused qcom_slim_ngd_runtime_idle(struct device *dev) @@ -1740,7 +1736,7 @@ static const struct dev_pm_ops qcom_slim_ngd_dev_pm_ops = { static struct platform_driver qcom_slim_ngd_ctrl_driver = { .probe = qcom_slim_ngd_ctrl_probe, - .remove = qcom_slim_ngd_ctrl_remove, + .remove_new = qcom_slim_ngd_ctrl_remove, .driver = { .name = "qcom,slim-ngd-ctrl", .of_match_table = qcom_slim_ngd_dt_match, @@ -1749,7 +1745,7 @@ static struct platform_driver qcom_slim_ngd_ctrl_driver = { static struct platform_driver qcom_slim_ngd_driver = { .probe = qcom_slim_ngd_probe, - .remove = qcom_slim_ngd_remove, + .remove_new = qcom_slim_ngd_remove, .driver = { .name = QCOM_SLIM_NGD_DRV_NAME, .pm = &qcom_slim_ngd_dev_pm_ops, diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index 34128e6bbbfaf6..a39fa8bf866ae3 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -5,15 +5,15 @@ * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi> */ -#include <linux/init.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/gpio/consumer.h> -#include <linux/of_platform.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/delay.h> +#include <linux/property.h> +#include <linux/types.h> #include <linux/w1.h> @@ -63,20 +63,11 @@ static u8 w1_gpio_read_bit(void *data) return gpiod_get_value(ddata->gpiod) ? 1 : 0; } -#if defined(CONFIG_OF) -static const struct of_device_id w1_gpio_dt_ids[] = { - { .compatible = "w1-gpio" }, - {} -}; -MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids); -#endif - static int w1_gpio_probe(struct platform_device *pdev) { struct w1_bus_master *master; struct w1_gpio_ddata *ddata; struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; /* Enforce open drain mode by default */ enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN; int err; @@ -91,27 +82,22 @@ static int w1_gpio_probe(struct platform_device *pdev) * driver it high/low like we are in full control of the line and * open drain will happen transparently. */ - if (of_property_present(np, "linux,open-drain")) + if (device_property_present(dev, "linux,open-drain")) gflags = GPIOD_OUT_LOW; - master = devm_kzalloc(dev, sizeof(struct w1_bus_master), - GFP_KERNEL); + master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL); if (!master) return -ENOMEM; ddata->gpiod = devm_gpiod_get_index(dev, NULL, 0, gflags); - if (IS_ERR(ddata->gpiod)) { - dev_err(dev, "gpio_request (pin) failed\n"); - return PTR_ERR(ddata->gpiod); - } + if (IS_ERR(ddata->gpiod)) + return dev_err_probe(dev, PTR_ERR(ddata->gpiod), "gpio_request (pin) failed\n"); ddata->pullup_gpiod = devm_gpiod_get_index_optional(dev, NULL, 1, GPIOD_OUT_LOW); - if (IS_ERR(ddata->pullup_gpiod)) { - dev_err(dev, "gpio_request_one " - "(ext_pullup_enable_pin) failed\n"); - return PTR_ERR(ddata->pullup_gpiod); - } + if (IS_ERR(ddata->pullup_gpiod)) + return dev_err_probe(dev, PTR_ERR(ddata->pullup_gpiod), + "gpio_request (ext_pullup_enable_pin) failed\n"); master->data = ddata; master->read_bit = w1_gpio_read_bit; @@ -128,13 +114,10 @@ static int w1_gpio_probe(struct platform_device *pdev) master->set_pullup = w1_gpio_set_pullup; err = w1_add_master_device(master); - if (err) { - dev_err(dev, "w1_add_master device failed\n"); - return err; - } + if (err) + return dev_err_probe(dev, err, "w1_add_master device failed\n"); - if (ddata->pullup_gpiod) - gpiod_set_value(ddata->pullup_gpiod, 1); + gpiod_set_value(ddata->pullup_gpiod, 1); platform_set_drvdata(pdev, master); @@ -146,16 +129,21 @@ static void w1_gpio_remove(struct platform_device *pdev) struct w1_bus_master *master = platform_get_drvdata(pdev); struct w1_gpio_ddata *ddata = master->data; - if (ddata->pullup_gpiod) - gpiod_set_value(ddata->pullup_gpiod, 0); + gpiod_set_value(ddata->pullup_gpiod, 0); w1_remove_master_device(master); } +static const struct of_device_id w1_gpio_dt_ids[] = { + { .compatible = "w1-gpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids); + static struct platform_driver w1_gpio_driver = { .driver = { .name = "w1-gpio", - .of_match_table = of_match_ptr(w1_gpio_dt_ids), + .of_match_table = w1_gpio_dt_ids, }, .probe = w1_gpio_probe, .remove_new = w1_gpio_remove, diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 5f288d475490c9..f09ace92176e23 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -12,6 +12,7 @@ #include <linux/io.h> #include <linux/perf_event.h> #include <linux/sched.h> +#include <linux/platform_device.h> /* Peripheral id registers (0xFD0-0xFEC) */ #define CORESIGHT_PERIPHIDR4 0xfd0 @@ -658,4 +659,9 @@ coresight_find_output_type(struct coresight_platform_data *pdata, enum coresight_dev_type type, union coresight_dev_subtype subtype); +int coresight_init_driver(const char *drv, struct amba_driver *amba_drv, + struct platform_driver *pdev_drv); + +void coresight_remove_driver(struct amba_driver *amba_drv, + struct platform_driver *pdev_drv); #endif /* _LINUX_COREISGHT_H */ diff --git a/include/linux/counter.h b/include/linux/counter.h index cd35d8574ee219..426b7d58a438d5 100644 --- a/include/linux/counter.h +++ b/include/linux/counter.h @@ -6,14 +6,15 @@ #ifndef _COUNTER_H_ #define _COUNTER_H_ +#include <linux/array_size.h> #include <linux/cdev.h> #include <linux/device.h> -#include <linux/kernel.h> #include <linux/kfifo.h> #include <linux/mutex.h> #include <linux/spinlock_types.h> #include <linux/types.h> #include <linux/wait.h> + #include <uapi/linux/counter.h> struct counter_device; diff --git a/include/linux/fpga/fpga-bridge.h b/include/linux/fpga/fpga-bridge.h index 223da48a6d18b5..94c4edd047e54f 100644 --- a/include/linux/fpga/fpga-bridge.h +++ b/include/linux/fpga/fpga-bridge.h @@ -45,6 +45,7 @@ struct fpga_bridge_info { * @dev: FPGA bridge device * @mutex: enforces exclusive reference to bridge * @br_ops: pointer to struct of FPGA bridge ops + * @br_ops_owner: module containing the br_ops * @info: fpga image specific information * @node: FPGA bridge list node * @priv: low level driver private date @@ -54,6 +55,7 @@ struct fpga_bridge { struct device dev; struct mutex mutex; /* for exclusive reference to bridge */ const struct fpga_bridge_ops *br_ops; + struct module *br_ops_owner; struct fpga_image_info *info; struct list_head node; void *priv; @@ -79,10 +81,12 @@ int of_fpga_bridge_get_to_list(struct device_node *np, struct fpga_image_info *info, struct list_head *bridge_list); +#define fpga_bridge_register(parent, name, br_ops, priv) \ + __fpga_bridge_register(parent, name, br_ops, priv, THIS_MODULE) struct fpga_bridge * -fpga_bridge_register(struct device *parent, const char *name, - const struct fpga_bridge_ops *br_ops, - void *priv); +__fpga_bridge_register(struct device *parent, const char *name, + const struct fpga_bridge_ops *br_ops, void *priv, + struct module *owner); void fpga_bridge_unregister(struct fpga_bridge *br); #endif /* _LINUX_FPGA_BRIDGE_H */ diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index 54f63459efd6e2..0d4fe068f3d8af 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h @@ -201,6 +201,7 @@ struct fpga_manager_ops { * @state: state of fpga manager * @compat_id: FPGA manager id for compatibility check. * @mops: pointer to struct of fpga manager ops + * @mops_owner: module containing the mops * @priv: low level driver private date */ struct fpga_manager { @@ -210,6 +211,7 @@ struct fpga_manager { enum fpga_mgr_states state; struct fpga_compat_id *compat_id; const struct fpga_manager_ops *mops; + struct module *mops_owner; void *priv; }; @@ -230,18 +232,30 @@ struct fpga_manager *fpga_mgr_get(struct device *dev); void fpga_mgr_put(struct fpga_manager *mgr); +#define fpga_mgr_register_full(parent, info) \ + __fpga_mgr_register_full(parent, info, THIS_MODULE) struct fpga_manager * -fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info); +__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, + struct module *owner); +#define fpga_mgr_register(parent, name, mops, priv) \ + __fpga_mgr_register(parent, name, mops, priv, THIS_MODULE) struct fpga_manager * -fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv); +__fpga_mgr_register(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, void *priv, struct module *owner); + void fpga_mgr_unregister(struct fpga_manager *mgr); +#define devm_fpga_mgr_register_full(parent, info) \ + __devm_fpga_mgr_register_full(parent, info, THIS_MODULE) struct fpga_manager * -devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info); +__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, + struct module *owner); +#define devm_fpga_mgr_register(parent, name, mops, priv) \ + __devm_fpga_mgr_register(parent, name, mops, priv, THIS_MODULE) struct fpga_manager * -devm_fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv); +__devm_fpga_mgr_register(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, void *priv, + struct module *owner); #endif /*_LINUX_FPGA_MGR_H */ diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h index 9d4d32909340ab..5fbc05fe70a6b7 100644 --- a/include/linux/fpga/fpga-region.h +++ b/include/linux/fpga/fpga-region.h @@ -36,6 +36,7 @@ struct fpga_region_info { * @mgr: FPGA manager * @info: FPGA image info * @compat_id: FPGA region id for compatibility check. + * @ops_owner: module containing the get_bridges function * @priv: private data * @get_bridges: optional function to get bridges to a list */ @@ -46,6 +47,7 @@ struct fpga_region { struct fpga_manager *mgr; struct fpga_image_info *info; struct fpga_compat_id *compat_id; + struct module *ops_owner; void *priv; int (*get_bridges)(struct fpga_region *region); }; @@ -58,12 +60,17 @@ fpga_region_class_find(struct device *start, const void *data, int fpga_region_program_fpga(struct fpga_region *region); +#define fpga_region_register_full(parent, info) \ + __fpga_region_register_full(parent, info, THIS_MODULE) struct fpga_region * -fpga_region_register_full(struct device *parent, const struct fpga_region_info *info); +__fpga_region_register_full(struct device *parent, const struct fpga_region_info *info, + struct module *owner); +#define fpga_region_register(parent, mgr, get_bridges) \ + __fpga_region_register(parent, mgr, get_bridges, THIS_MODULE) struct fpga_region * -fpga_region_register(struct device *parent, struct fpga_manager *mgr, - int (*get_bridges)(struct fpga_region *)); +__fpga_region_register(struct device *parent, struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *), struct module *owner); void fpga_region_unregister(struct fpga_region *region); #endif /* _FPGA_REGION_H */ diff --git a/include/linux/iio/common/inv_sensors_timestamp.h b/include/linux/iio/common/inv_sensors_timestamp.h index a47d304d1ba7c4..8d506f1e9df292 100644 --- a/include/linux/iio/common/inv_sensors_timestamp.h +++ b/include/linux/iio/common/inv_sensors_timestamp.h @@ -71,8 +71,7 @@ int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts, uint32_t period, bool fifo); void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, - size_t sensor_nb, int64_t timestamp); + size_t sample_nb, int64_t timestamp); static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts) { diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 77b8c0a26674fd..b573f15762f85a 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -353,6 +353,7 @@ struct mhi_controller_config { * @read_reg: Read a MHI register via the physical link (required) * @write_reg: Write a MHI register via the physical link (required) * @reset: Controller specific reset function (optional) + * @edl_trigger: CB function to trigger EDL mode (optional) * @buffer_len: Bounce buffer length * @index: Index of the MHI controller instance * @bounce_buf: Use of bounce buffer @@ -435,6 +436,7 @@ struct mhi_controller { void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val); void (*reset)(struct mhi_controller *mhi_cntrl); + int (*edl_trigger)(struct mhi_controller *mhi_cntrl); size_t buffer_len; int index; @@ -630,13 +632,29 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl); int mhi_sync_power_up(struct mhi_controller *mhi_cntrl); /** - * mhi_power_down - Start MHI power down sequence + * mhi_power_down - Power down the MHI device and also destroy the + * 'struct device' for the channels associated with it. + * See also mhi_power_down_keep_dev() which is a variant + * of this API that keeps the 'struct device' for channels + * (useful during suspend/hibernation). * @mhi_cntrl: MHI controller * @graceful: Link is still accessible, so do a graceful shutdown process */ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful); /** + * mhi_power_down_keep_dev - Power down the MHI device but keep the 'struct + * device' for the channels associated with it. + * This is a variant of 'mhi_power_down()' and + * useful in scenarios such as suspend/hibernation + * where destroying of the 'struct device' is not + * needed. + * @mhi_cntrl: MHI controller + * @graceful: Link is still accessible, so do a graceful shutdown process + */ +void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl, bool graceful); + +/** * mhi_unprepare_after_power_down - Free any allocated memory after power down * @mhi_cntrl: MHI controller */ @@ -798,4 +816,13 @@ int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir, */ bool mhi_queue_is_full(struct mhi_device *mhi_dev, enum dma_data_direction dir); +/** + * mhi_get_channel_doorbell_offset - Get the channel doorbell offset + * @mhi_cntrl: MHI controller + * @chdb_offset: Read channel doorbell offset + * + * Return: 0 if the read succeeds, a negative error code otherwise + */ +int mhi_get_channel_doorbell_offset(struct mhi_controller *mhi_cntrl, u32 *chdb_offset); + #endif /* _MHI_H_ */ diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index f0ba0e03218f96..3ebeaa0ded00c8 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_device *nvmem, int nvmem_layout_register(struct nvmem_layout *layout); void nvmem_layout_unregister(struct nvmem_layout *layout); -int nvmem_layout_driver_register(struct nvmem_layout_driver *drv); +#define nvmem_layout_driver_register(drv) \ + __nvmem_layout_driver_register(drv, THIS_MODULE) +int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, + struct module *owner); void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv); #define module_nvmem_layout_driver(__nvmem_layout_driver) \ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ |